refactor: skill v2 — thinking frameworks, NEVER list, fallbacks
Evaluated via skill-judge: 106/120 (B grade). - Thinking framework before analysis - Prioritization criteria (what's worth digging into) - 10-item NEVER list from 5-repo experience - Commands externalized to references/commands.md - Fallbacks for edge cases (no PRs, private repos, young repos) - Each phase teaches what matters, not how to grep
This commit is contained in:
@@ -16,178 +16,235 @@ description: >-
|
|||||||
|
|
||||||
# Codebase Analysis
|
# Codebase Analysis
|
||||||
|
|
||||||
Extract architectural conventions from open source repositories through
|
Extract architectural conventions from open source repositories.
|
||||||
a structured multi-phase process. Output goes to Gitea convention repos.
|
Output: Gitea repos under `rodin/<project>-conventions`.
|
||||||
|
|
||||||
## Naming Convention
|
## Naming
|
||||||
|
|
||||||
- **Language patterns** (`go-patterns`, `elixir-patterns`): stdlib/language
|
- `*-patterns` = language-level (go-patterns, elixir-patterns)
|
||||||
idioms verified from source
|
- `*-conventions` = project-specific (temporal-conventions, etc.)
|
||||||
- **Project conventions** (`<project>-conventions`): how a specific codebase
|
|
||||||
does things — e.g., `temporal-conventions`, `cockroachdb-conventions`
|
## Thinking Framework
|
||||||
|
|
||||||
|
Before starting any analysis, ask:
|
||||||
|
|
||||||
|
1. **What is this project's essence?** A trading system is a state
|
||||||
|
machine where the state is money. A workflow engine is a tree of
|
||||||
|
state machines. Name the essence — the patterns follow from it.
|
||||||
|
2. **What forces shaped it?** Team size, age, performance constraints,
|
||||||
|
backward compatibility obligations. These predict WHERE conventions
|
||||||
|
will be strict vs relaxed.
|
||||||
|
3. **What would surprise me?** The interesting findings are never "they
|
||||||
|
use interfaces" — it's "they have 566 dynamic config settings" or
|
||||||
|
"zero TODOs in 3.8M of code." Surprise = insight.
|
||||||
|
|
||||||
|
## Prioritization: What to Dig Into
|
||||||
|
|
||||||
|
Not everything is interesting. Focus on patterns that:
|
||||||
|
|
||||||
|
- **Appear >50 times** — this is a conscious convention, not a one-off
|
||||||
|
- **Have a dedicated package** — someone thought it was important enough
|
||||||
|
to abstract
|
||||||
|
- **Other projects solve differently** — reveals a real design tradeoff
|
||||||
|
- **Have a surprising name** — indicates the team had to invent
|
||||||
|
vocabulary for a novel concept
|
||||||
|
- **Were introduced recently with many PR comments** — active design
|
||||||
|
decisions with recorded rationale
|
||||||
|
|
||||||
|
Skip patterns that are:
|
||||||
|
- Standard library usage (unless the project wraps/extends it)
|
||||||
|
- Single-use internal helpers
|
||||||
|
- Generated code
|
||||||
|
- Exact copies of well-known open-source patterns without modification
|
||||||
|
|
||||||
## Phases
|
## Phases
|
||||||
|
|
||||||
Execute in order. Each phase builds on the previous.
|
### Phase 1: Shape (5 min)
|
||||||
|
|
||||||
### Phase 1: Clone & Shape
|
Clone on forge (`~/src/analysis/<name>`). Full clone — never shallow.
|
||||||
|
|
||||||
Clone the repo on forge (`~/src/analysis/<name>`). Measure:
|
Measure: size, files, commits, contributors, top-level dirs.
|
||||||
|
|
||||||
```
|
**What matters here:** The ratio of test files to production files.
|
||||||
- Total size, file count, commit count, contributor count
|
The presence/absence of `internal/` vs flat structure. Whether there's
|
||||||
- Top-level directory structure
|
a single `pkg/` or many top-level packages. These reveal organizational
|
||||||
- Language breakdown (if polyglot)
|
philosophy before you read a single line.
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 2: Import Hierarchy
|
### Phase 2: What the Codebase Values (10 min)
|
||||||
|
|
||||||
Find the most-depended-upon packages. This reveals what the codebase
|
Find the most-imported internal packages. The top 5 are the
|
||||||
considers foundational:
|
project's definition of "foundational."
|
||||||
|
|
||||||
```bash
|
**Ask:** Why these? What do they share? Usually: logging, errors,
|
||||||
# Go: grep imports, extract internal packages, count
|
config, and one domain-specific abstraction that IS the project.
|
||||||
grep -rh '"<module>/' --include="*.go" | sed ... | sort | uniq -c | sort -rn
|
That domain-specific one is where the real conventions live.
|
||||||
|
|
||||||
# Elixir: grep aliases/imports
|
See `references/commands.md` for grep patterns by language.
|
||||||
grep -rh "alias\|import\|use" --include="*.ex" | ...
|
|
||||||
```
|
|
||||||
|
|
||||||
The top 5-10 packages are where architectural decisions live.
|
### Phase 3: Interface Contracts (10 min)
|
||||||
|
|
||||||
### Phase 3: Interface Contracts
|
Find interfaces/behaviours/protocols — but don't list them all.
|
||||||
|
|
||||||
Find the key abstractions:
|
**Focus on:** Interfaces with >3 implementations (these are real
|
||||||
|
extension points). Interfaces in constructor signatures (these are
|
||||||
|
dependency injection boundaries). Interfaces that appear in BOTH
|
||||||
|
production and test code (these are the testability seams).
|
||||||
|
|
||||||
```bash
|
**Skip:** One-method interfaces (usually just for mocking). Interfaces
|
||||||
# Go
|
only used in one place (not yet conventions).
|
||||||
grep -rn "type.*interface {" --include="*.go" | grep -v test | grep -v mock
|
|
||||||
|
|
||||||
# Elixir
|
### Phase 4: Quality Fingerprint (5 min)
|
||||||
grep -rn "@callback\|@behaviour\|defprotocol" --include="*.ex"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 4: Error Handling & Quality Markers
|
Measure: TODO count, FIXME count, HACK count, test count, mock count.
|
||||||
|
|
||||||
```bash
|
**What to notice:**
|
||||||
# Error style
|
- TODO format reveals discipline: `TODO(owner):` = accountability,
|
||||||
grep -rh "fmt.Errorf.*%w" | wc -l # wrapping
|
`TODO:` = aspirational, version-gated = systematic cleanup
|
||||||
grep -rh "errors.New\|errors.Wrap" | wc -l # sentinel/pkg
|
- Zero TODOs in a large codebase means active cleanup culture
|
||||||
|
- High mock count relative to test count suggests heavy DI
|
||||||
|
- HACK count > 0 is honest; HACK count = 0 in a large project is
|
||||||
|
suspicious (they probably use different words)
|
||||||
|
|
||||||
# Quality markers
|
### Phase 5: Unique Patterns (15 min)
|
||||||
grep -rn "TODO\|FIXME\|HACK" --include="*.go" | grep -v test | wc -l
|
|
||||||
```
|
|
||||||
|
|
||||||
Note TODO format — does the project use `TODO(owner):`? Plain `TODO:`?
|
Look for infrastructure NOT in stdlib. Categories:
|
||||||
Version-gated TODOs?
|
|
||||||
|
|
||||||
### Phase 5: Unique Patterns
|
- **Concurrency:** goroutine handles, schedulers, shutdown primitives
|
||||||
|
- **Testing:** custom assertions, fake registries, golden file systems
|
||||||
|
- **Configuration:** dynamic config, feature flags, runtime toggles
|
||||||
|
- **Error handling:** custom error types, assertion systems, panic
|
||||||
|
recovery patterns
|
||||||
|
- **Extension:** plugin registration, hook systems, middleware chains
|
||||||
|
|
||||||
Look for project-specific infrastructure that's NOT in stdlib:
|
**The test for uniqueness:** Would you be surprised to find this in
|
||||||
- Custom concurrency primitives (handles, schedulers, pools)
|
another project of similar size? If yes → convention worth documenting.
|
||||||
- Testing infrastructure (custom assertions, harnesses)
|
If no → standard practice, skip.
|
||||||
- Configuration systems (dynamic config, feature flags)
|
|
||||||
- Plugin/extension systems
|
|
||||||
|
|
||||||
### Phase 6: Git Archaeology (requires full clone)
|
### Phase 6: Git Archaeology (20 min)
|
||||||
|
|
||||||
This is where the real insight lives. For each interesting pattern:
|
For each unique pattern found in Phase 5:
|
||||||
|
|
||||||
```bash
|
1. Find the commit that introduced it (`git log --diff-filter=A`)
|
||||||
# When was it introduced?
|
2. Read the commit message — the "why" is usually there
|
||||||
git log --all --oneline --diff-filter=A -- path/to/pattern
|
3. Check if it replaced something (`git log -S "old_name"`)
|
||||||
|
4. Note the date and author — context for why shortcuts were taken
|
||||||
|
|
||||||
# Who wrote it and why?
|
**The insight is always WHY, not WHAT.** A bare goroutine with a
|
||||||
git log --format="%an%n%ad%n%s%n%b" <commit> -1
|
TODO is uninteresting as a listing. A bare goroutine introduced during
|
||||||
|
a complex 20-file admission control feature, tagged by the author in
|
||||||
|
the same commit, that survived 3 years because nobody touched the
|
||||||
|
function — that's a lesson about how real codebases evolve.
|
||||||
|
|
||||||
# What did it replace?
|
See `references/commands.md` for git archaeology patterns.
|
||||||
git log -p -S "old_pattern_name" -- relevant/path
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 7: PR Discussions
|
**If the repo is on a forge without PR history** (self-hosted, mailing
|
||||||
|
list-based): Fall back to commit messages and CHANGELOG. The commit
|
||||||
|
body IS the PR description for these projects. Look for "Reviewed-by"
|
||||||
|
trailers and linked issues.
|
||||||
|
|
||||||
Find the PR where a key pattern was introduced:
|
### Phase 7: PR Discussions (20 min)
|
||||||
|
|
||||||
```bash
|
Find PRs where key patterns were introduced. Read:
|
||||||
gh api "search/issues?q=repo:<org>/<repo>+<search>+type:pr" \
|
- The PR body (author's motivation)
|
||||||
--jq '.items[] | {number, title}'
|
|
||||||
```
|
|
||||||
|
|
||||||
Then read:
|
|
||||||
- PR body (the "why" from the author)
|
|
||||||
- Review comments (the debate)
|
- Review comments (the debate)
|
||||||
- Issue comments (the resolution)
|
- The resolution
|
||||||
|
|
||||||
Key questions to answer:
|
**What to extract from discussions:**
|
||||||
1. What problem motivated this pattern?
|
- What the author was defending (= where the real insight is)
|
||||||
2. What alternatives were considered?
|
- What reviewers pushed back on (= non-obvious tradeoffs)
|
||||||
3. What did reviewers push back on?
|
- Whether it was "merge and iterate" vs "perfect before merge"
|
||||||
4. How was it migrated in (big-bang vs gradual)?
|
- Whether external validation was cited (benchmarks, user feedback)
|
||||||
|
- The migration strategy (big-bang vs gradual coexistence)
|
||||||
|
|
||||||
### Phase 8: Synthesis & Output
|
**The highest-value finding:** When a reviewer says "I wish we'd done
|
||||||
|
X instead" and the author explains why X doesn't work. That tradeoff
|
||||||
|
reasoning is pure expert knowledge.
|
||||||
|
|
||||||
Produce two artifacts:
|
### Phase 8: Synthesis
|
||||||
|
|
||||||
**1. `analysis.md`** — Full architectural analysis:
|
Produce two files. Push to Gitea.
|
||||||
- Repository shape and import hierarchy
|
|
||||||
- Key patterns with code examples
|
|
||||||
- PR discussion summaries
|
|
||||||
- Cross-ecosystem comparisons
|
|
||||||
- Code quality metrics
|
|
||||||
|
|
||||||
**2. `conventions.md`** — Extracted patterns with:
|
**`analysis.md`** — the full story:
|
||||||
- Pattern name
|
1. Repo shape and organizational philosophy
|
||||||
- Location in source
|
2. Import hierarchy (what it values)
|
||||||
- Code example
|
3. Key patterns with code examples + origin stories
|
||||||
- When to use / when NOT to use
|
4. PR discussion excerpts (attributed quotes)
|
||||||
- Origin story (from PR discussion if available)
|
5. Cross-ecosystem comparisons (prior art, independent invention)
|
||||||
|
6. Quality metrics in context (not bare numbers)
|
||||||
|
|
||||||
## Output Repos
|
**`conventions.md`** — the reference:
|
||||||
|
For each pattern:
|
||||||
|
- Name and location in source
|
||||||
|
- Code example (real, not simplified)
|
||||||
|
- When to use / When NOT to use
|
||||||
|
- Origin (commit date, author, PR# if available)
|
||||||
|
|
||||||
Push to Gitea under `rodin/<project>-conventions`:
|
End both files with `<!-- PATTERN_COMPLETE -->` sentinel.
|
||||||
|
|
||||||
```bash
|
|
||||||
GITEA_TOKEN=$(cat ~/.openclaw/credentials/gitea-rodin)
|
|
||||||
# Create repo if needed:
|
|
||||||
curl -s -X POST "https://gitea.weiker.me/api/v1/user/repos" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"name": "<project>-conventions", "auto_init": true, "default_branch": "master", "license": "MIT"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Quality Criteria
|
|
||||||
|
|
||||||
Before pushing, verify:
|
|
||||||
- Each pattern has a real code example from the repo
|
|
||||||
- "When to use / when NOT to use" sections exist
|
|
||||||
- PR discussion quotes are attributed
|
|
||||||
- Cross-ecosystem comparisons note prior art
|
|
||||||
- Files end with `<!-- PATTERN_COMPLETE -->` sentinel
|
|
||||||
|
|
||||||
## Cross-Ecosystem Observations
|
## Cross-Ecosystem Observations
|
||||||
|
|
||||||
Always note when a pattern exists in multiple repos. Example: Temporal's
|
Always note when a pattern exists in multiple repos. These
|
||||||
`goro.Handle` (2021) predates CockroachDB's `stop.Handle` (2025) —
|
independent inventions reveal forces that transcend project context:
|
||||||
same solution, invented independently. These connections are the most
|
- Temporal goro.Handle (2021) ↔ CockroachDB stop.Handle (2025)
|
||||||
valuable findings.
|
- Ecto zero TODOs (version-gated) ↔ Oban zero TODOs (2-week cleanup)
|
||||||
|
- Prometheus init() plugins ↔ Temporal init() plugins
|
||||||
|
|
||||||
## The 4 Categories of Pattern Breaks
|
## The 4 Categories of Pattern Breaks
|
||||||
|
|
||||||
When you find impurity (pattern violations), classify them:
|
When you find convention violations, classify:
|
||||||
|
|
||||||
1. **Ship behavior, fix plumbing later** — time pressure, author knows it's
|
1. **Ship behavior, fix plumbing later** — tagged with TODO same commit
|
||||||
wrong (tagged with TODO)
|
2. **Better tooling exposed limitation** — observability, not correctness
|
||||||
2. **Better tooling exposed the limitation** — old pattern worked but was
|
3. **Removal cost > carrying cost** — zero-interest debt
|
||||||
invisible to profiling/tracing
|
|
||||||
3. **Removal cost > carrying cost** — technically debt but zero interest rate
|
|
||||||
4. **Context needs different pattern** — not actually a break
|
4. **Context needs different pattern** — not actually a break
|
||||||
|
|
||||||
See `references/pattern-breaks.md` for detailed examples.
|
See `references/pattern-breaks.md` for real examples with git history.
|
||||||
|
|
||||||
|
## NEVER
|
||||||
|
|
||||||
|
- **NEVER analyze with a shallow clone** and assume full picture —
|
||||||
|
archaeology requires full history
|
||||||
|
- **NEVER present patterns from one file as repo-wide conventions** —
|
||||||
|
verify frequency across the codebase first
|
||||||
|
- **NEVER skip PR discussions** — code without context is just syntax;
|
||||||
|
the discussion IS the insight
|
||||||
|
- **NEVER report bare numbers** ("738 TODOs") — always contextualize
|
||||||
|
(per 1000 files, vs comparable projects, trending up/down)
|
||||||
|
- **NEVER confuse "the maintainer likes X" with "X is the right
|
||||||
|
pattern"** — solo-maintained projects reflect one person's taste;
|
||||||
|
team projects reflect negotiated conventions
|
||||||
|
- **NEVER present a pattern as "unique" without checking** if stdlib
|
||||||
|
has it or if it's a well-known library pattern
|
||||||
|
- **NEVER list patterns without when-NOT-to-use** — that's where the
|
||||||
|
expertise actually lives
|
||||||
|
- **NEVER quote PR discussions without attribution** — who said it
|
||||||
|
matters (maintainer vs drive-by contributor)
|
||||||
|
- **NEVER analyze repos <1000 commits** — not enough history for
|
||||||
|
meaningful archaeology
|
||||||
|
- **NEVER conflate language patterns with project conventions** — `go-
|
||||||
|
patterns` is stdlib idiom; `temporal-conventions` is project choice
|
||||||
|
|
||||||
|
## Output Repos
|
||||||
|
|
||||||
|
Push to Gitea under `rodin/<project>-conventions`. See
|
||||||
|
`references/commands.md` for repo creation and push commands.
|
||||||
|
|
||||||
|
## Fallbacks
|
||||||
|
|
||||||
|
- **No PR discussions?** Use commit messages as primary source.
|
||||||
|
Many projects (Linux, PostgreSQL) do all review in commit messages
|
||||||
|
and mailing lists.
|
||||||
|
- **Repo too large to clone fully?** Clone shallow first, do Phase
|
||||||
|
1-5, then `git fetch --unshallow` only if Phase 6-7 are needed.
|
||||||
|
- **Private repo / no GitHub API?** Skip Phase 7. Phase 6 (local git
|
||||||
|
history) still works.
|
||||||
|
- **<3000 commits?** Reduce Phase 6-7 expectations. Younger projects
|
||||||
|
have less archaeology to mine — focus on Phase 5 (unique patterns)
|
||||||
|
and the project's README/docs for rationale.
|
||||||
|
|
||||||
## Execution Notes
|
## Execution Notes
|
||||||
|
|
||||||
- Clone on **forge** (`host="node", node="forge"`) — has disk space
|
- Clone on **forge** (`host="node", node="forge"`)
|
||||||
- Use full clones (not `--depth 1`) for archaeology
|
|
||||||
- `gh api` for GitHub PR lookups (authenticated on all nodes)
|
- `gh api` for GitHub PR lookups (authenticated on all nodes)
|
||||||
- One repo at a time for focused analysis
|
- One repo at a time for focused analysis
|
||||||
- Markdownlint all output before pushing
|
- Markdownlint all output before pushing
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# Commands Reference
|
||||||
|
|
||||||
|
Shell patterns for each phase. Load only when you need the exact
|
||||||
|
syntax — the SKILL.md tells you WHAT to look for; this tells you HOW.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Shape
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone (always full — never --depth 1)
|
||||||
|
cd ~/src/analysis && git clone <url>
|
||||||
|
|
||||||
|
# Dimensions
|
||||||
|
du -sh <repo>
|
||||||
|
find . -name "*.go" | grep -v vendor | wc -l # Go files
|
||||||
|
git log --oneline | wc -l # commits
|
||||||
|
git log --format="%an" | sort -u | wc -l # contributors
|
||||||
|
ls -d */ # top-level dirs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 2: Import Hierarchy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Go: most-imported internal packages
|
||||||
|
grep -rh '"<module>/' --include="*.go" \
|
||||||
|
| sed 's/.*"<module>\///' | sed 's/".*//' \
|
||||||
|
| cut -d/ -f1 | sort | uniq -c | sort -rn | head -15
|
||||||
|
|
||||||
|
# Elixir: most-aliased modules
|
||||||
|
grep -rh "alias " --include="*.ex" \
|
||||||
|
| sed 's/.*alias //' | cut -d. -f1-2 \
|
||||||
|
| sort | uniq -c | sort -rn | head -15
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 3: Interfaces
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Go interfaces (skip test/mock/generated)
|
||||||
|
grep -rn "type.*interface {" --include="*.go" \
|
||||||
|
| grep -v test | grep -v mock | grep -v _gen.go
|
||||||
|
|
||||||
|
# Elixir behaviours/protocols
|
||||||
|
grep -rn "@callback\|@behaviour\|defprotocol" --include="*.ex"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 4: Quality Markers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# TODOs (non-test, note format)
|
||||||
|
grep -rn "TODO" --include="*.go" | grep -v test | wc -l
|
||||||
|
grep -rh "// TODO" --include="*.go" | head -5 # check format
|
||||||
|
|
||||||
|
# Other markers
|
||||||
|
grep -rn "FIXME\|HACK" --include="*.go" | grep -v test | wc -l
|
||||||
|
|
||||||
|
# Test ratio
|
||||||
|
find . -name "*_test.go" | wc -l # test files
|
||||||
|
find . -name "*mock*" | wc -l # mock files
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 6: Git Archaeology
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# When was a file/pattern introduced?
|
||||||
|
git log --all --oneline --diff-filter=A -- path/to/file
|
||||||
|
|
||||||
|
# Who wrote it and why?
|
||||||
|
git log --format="%an%n%ad%n%s%n%b" <commit> -1
|
||||||
|
|
||||||
|
# When was a string added/removed (pickaxe search)?
|
||||||
|
git log -p -S "pattern_string" -- relevant/path/
|
||||||
|
|
||||||
|
# TODOs added with context
|
||||||
|
git log --all -p -S "TODO" -- lib/ \
|
||||||
|
| grep "^commit\|^+.*TODO\|^-.*TODO" | head -20
|
||||||
|
|
||||||
|
# Find if full clone or shallow
|
||||||
|
git rev-parse --is-shallow-repository
|
||||||
|
# Unshallow if needed
|
||||||
|
git fetch --unshallow
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 7: PR Lookup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find PR by title/content
|
||||||
|
gh api "search/issues?q=repo:<org>/<repo>+<keywords>+type:pr" \
|
||||||
|
--jq '.items[] | {number: .number, title: .title}'
|
||||||
|
|
||||||
|
# Read PR metadata
|
||||||
|
gh api repos/<org>/<repo>/pulls/<num> \
|
||||||
|
--jq '{title, body: (.body | split("\n") | .[0:30] | join("\n")), comments, review_comments, created_at, merged_at}'
|
||||||
|
|
||||||
|
# Read review comments (the debate)
|
||||||
|
gh api "repos/<org>/<repo>/pulls/<num>/comments?per_page=30" \
|
||||||
|
--jq '.[] | select(.body | length > 50) | {user: .user.login, body: (.body | split("\n") | .[0:5] | join("\n"))}'
|
||||||
|
|
||||||
|
# Read issue comments
|
||||||
|
gh api repos/<org>/<repo>/issues/<num>/comments \
|
||||||
|
--jq '.[] | {user: .user.login, body: (.body | split("\n") | .[0:6] | join("\n"))}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Output: Repo Creation & Push
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GITEA_TOKEN=$(cat ~/.openclaw/credentials/gitea-rodin)
|
||||||
|
|
||||||
|
# Create repo
|
||||||
|
curl -s -X POST "https://gitea.weiker.me/api/v1/user/repos" \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"name": "<project>-conventions", "auto_init": true, "default_branch": "master", "license": "MIT"}'
|
||||||
|
|
||||||
|
# Clone, add content, push
|
||||||
|
git clone "https://rodin:${GITEA_TOKEN}@gitea.weiker.me/rodin/<project>-conventions.git"
|
||||||
|
cd <project>-conventions
|
||||||
|
git config user.name "Rodin"
|
||||||
|
git config user.email "rodin@forgedthought.ai"
|
||||||
|
# ... add files ...
|
||||||
|
git add -A && git commit -m "docs: initial conventions from <org>/<project>" && git push
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user