Skip to content

Commit 52f4ffd

Browse files
committed
docs: add CONTRIBUTING.md and trim README contributing section
Moves development setup, branching model, pre-commit hooks, and maintainer workflows (advance-main, release, hotfix) into a dedicated CONTRIBUTING.md so GitHub surfaces it as a banner when opening PRs. README contributing section is replaced with a 3-line pointer.
1 parent cd4ec86 commit 52f4ffd

2 files changed

Lines changed: 116 additions & 48 deletions

File tree

CONTRIBUTING.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Contributing
2+
3+
## Development setup
4+
5+
1. Fork and clone
6+
2. Install the git hooks (one-time setup):
7+
8+
```bash
9+
pip install pre-commit
10+
pre-commit install # runs on git commit
11+
pre-commit install --hook-type pre-push # runs on git push
12+
```
13+
14+
If you open the repo in the devcontainer, this runs automatically.
15+
16+
3. Changes live in `src/claude-code/install.sh` and `test/claude-code/`
17+
4. Open a pull request against `develop`
18+
19+
## Branching model
20+
21+
| Branch pattern | Purpose | PR target |
22+
| -------------- | ------------------------- | --------- |
23+
| `feat/*` | New features | `develop` |
24+
| `fix/*` | Bug fixes | `develop` |
25+
| `hotfix/*` | Critical production fixes | `main` |
26+
27+
- All feature and fix PRs target `develop`. Use squash merges to keep history clean.
28+
- `hotfix/*` branches are the only branches (besides `develop`) allowed to open PRs
29+
directly to `main`. This is enforced by CI (`source-branch-check.yml`).
30+
- Direct commits to `main` and `develop` are blocked by pre-commit hooks and branch
31+
protection rules.
32+
33+
## Pre-commit hooks
34+
35+
The following checks run automatically on every `git commit` and `git push`:
36+
37+
| Hook | What it checks |
38+
| --------------------- | --------------------------------------------- |
39+
| `shellcheck` | Shell script correctness (warnings and above) |
40+
| `shfmt` | Shell script formatting (`-i 4 -ci`) |
41+
| `prettier` | JSON, YAML, and Markdown formatting |
42+
| `markdownlint` | Markdown style rules |
43+
| `check-json` | JSON syntax validity |
44+
| `check-yaml` | YAML syntax validity |
45+
| `trailing-whitespace` | No trailing whitespace |
46+
| `detect-private-key` | No accidentally committed secrets |
47+
| `no-commit-to-branch` | Blocks direct commits to `main` and `develop` |
48+
49+
**Running manually:**
50+
51+
```bash
52+
pre-commit run --all-files # check everything
53+
pre-commit run prettier # check one hook
54+
pre-commit run --files src/claude-code/install.sh # check one file
55+
```
56+
57+
**If a hook fails:** fix the flagged issue and `git add` the changes before retrying.
58+
Prettier and shfmt auto-fix in place — just stage the result. ShellCheck and markdownlint
59+
report what to fix but won't rewrite your code.
60+
61+
## Maintainers
62+
63+
### Advancing main
64+
65+
When `develop` is ready for release, use the **Advance main** workflow:
66+
67+
1. Go to **Actions****Advance main****Run workflow**
68+
2. The workflow fast-forwards `main` to the current tip of `develop` via the GitHub API
69+
(no merge commit is created)
70+
3. It verifies that `main` and `develop` point to the same SHA before completing
71+
72+
### Releasing a version
73+
74+
1. Update the `version` field in `src/claude-code/devcontainer-feature.json` as part of
75+
the work merged to `develop` — this must be done **before** tagging, as the release
76+
workflow validates that the tag version matches the JSON
77+
2. Advance `main` using the workflow above
78+
3. Tag the release from the updated `main`:
79+
80+
```bash
81+
git checkout main
82+
git pull origin main
83+
git tag v<VERSION>
84+
git push origin v<VERSION>
85+
```
86+
87+
4. The `v*` tag push triggers the **Release** workflow, which:
88+
- Runs ShellCheck validation
89+
- Smoke-tests against 3 representative base images
90+
- Verifies the tag version matches `devcontainer-feature.json`
91+
- Publishes the feature to `ghcr.io/pkramek/claude-devcontainer/claude-code`
92+
- Verifies the published feature is accessible
93+
94+
Tags are protected — no deletion or force-push.
95+
96+
### Hotfix workflow
97+
98+
For critical fixes that cannot wait for the normal `develop` cycle:
99+
100+
1. Create a `hotfix/*` branch from `main`
101+
2. Make the fix and open a PR targeting `main` — the source-branch-check CI allows
102+
`hotfix/*` to bypass the `develop`-only gate
103+
3. After the hotfix merges to `main`, tag and release as described above
104+
4. Open a second PR from `hotfix/*` (or from `main`) to `develop` to keep the branches
105+
in sync
106+
107+
### First release: GHCR visibility
108+
109+
After the first tag push, the GHCR package is created as **private**. To make it public:
110+
111+
1. Go to the repository's **Packages** tab
112+
2. Click the `claude-code` package → **Package settings**
113+
3. Under **Danger Zone**, change visibility to **Public**

README.md

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -154,55 +154,10 @@ before a musl-compatible build is published. Check the CI badge before upgrading
154154

155155
## Contributing
156156

157-
1. Fork and clone
158-
2. Install the git hooks (one-time setup):
159-
160-
```bash
161-
pip install pre-commit
162-
pre-commit install # runs on git commit
163-
pre-commit install --hook-type pre-push # runs on git push
164-
```
165-
166-
If you open the repo in the devcontainer, this runs automatically.
167-
168-
3. Changes live in `src/claude-code/install.sh` and `test/claude-code/`
169-
4. Open a pull request against `develop`
170-
171-
### Pre-commit hooks
172-
173-
The following checks run automatically on every `git commit` and `git push`:
174-
175-
| Hook | What it checks |
176-
| --------------------- | --------------------------------------------- |
177-
| `shellcheck` | Shell script correctness (warnings and above) |
178-
| `shfmt` | Shell script formatting (`-i 4 -ci`) |
179-
| `prettier` | JSON, YAML, and Markdown formatting |
180-
| `markdownlint` | Markdown style rules |
181-
| `check-json` | JSON syntax validity |
182-
| `check-yaml` | YAML syntax validity |
183-
| `trailing-whitespace` | No trailing whitespace |
184-
| `detect-private-key` | No accidentally committed secrets |
185-
| `no-commit-to-branch` | Blocks direct commits to `main` and `develop` |
186-
187-
**Running manually:**
188-
189-
```bash
190-
pre-commit run --all-files # check everything
191-
pre-commit run prettier # check one hook
192-
pre-commit run --files src/claude-code/install.sh # check one file
193-
```
194-
195-
**If a hook fails:** fix the flagged issue and `git add` the changes before retrying. Prettier and
196-
shfmt auto-fix in place — just stage the result. ShellCheck and markdownlint report what to fix but
197-
won't rewrite your code.
198-
199-
## Publishing (Maintainers)
200-
201-
After the first release tag push, the GHCR package is created as **private**. To make it public:
157+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, branching model, pre-commit hooks,
158+
and the release process.
202159

203-
1. Go to the repository's **Packages** tab
204-
2. Click the `claude-code` package → **Package settings**
205-
3. Under **Danger Zone**, change visibility to **Public**
160+
Short version: fork, clone, install pre-commit hooks, open a PR against `develop`.
206161

207162
## License
208163

0 commit comments

Comments
 (0)