Skip to content

Commit e7f72cd

Browse files
authored
chore(release): automate release PR + npm publish (#10)
* chore(release): automate release PR + npm publish Adopt release-please for tagged releases and CI publishing; document the contributor/release workflow. * chore: add CODEOWNERS for maintainer approval Require @PatrickSys review for external PRs while allowing maintainers to self-merge when needed.
1 parent 3da3439 commit e7f72cd

File tree

8 files changed

+172
-2
lines changed

8 files changed

+172
-2
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @PatrickSys

.github/pull_request_template.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## What / Why
2+
3+
Explain the change briefly.
4+
5+
## Release notes
6+
7+
This repo uses an automated release flow.
8+
9+
- Please use a Conventional-Commits style PR title (we squash-merge): `feat: ...`, `fix: ...`, `docs: ...`, `chore: ...`, `refactor: ...`
10+
- If this should not appear in release notes, say so here

.github/workflows/publish.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Publish
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
npm:
13+
name: Publish to npm
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 1
19+
20+
- uses: pnpm/action-setup@v2
21+
with:
22+
version: 10
23+
24+
- uses: actions/setup-node@v4
25+
with:
26+
node-version: '20'
27+
registry-url: 'https://registry.npmjs.org'
28+
cache: 'pnpm'
29+
30+
- name: Install
31+
run: pnpm install --frozen-lockfile
32+
33+
- name: Verify tag matches package.json version
34+
run: node scripts/ci/ensure-tag-matches-package.mjs
35+
env:
36+
GITHUB_REF_NAME: ${{ github.ref_name }}
37+
38+
- name: Quality gates
39+
run: |
40+
pnpm lint
41+
pnpm format:check
42+
pnpm type-check
43+
pnpm test
44+
pnpm build
45+
46+
- name: Publish
47+
run: pnpm publish --access public --no-git-checks
48+
env:
49+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Release Please
2+
3+
on:
4+
push:
5+
branches: [master]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
release-please:
13+
name: Create/Update Release PR
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: googleapis/release-please-action@v4
17+
with:
18+
release-type: node
19+
package-name: codebase-context

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"trailingComma": "none",
44
"singleQuote": true,
55
"printWidth": 100,
6-
"tabWidth": 2
6+
"tabWidth": 2,
7+
"endOfLine": "auto"
78
}

CONTRIBUTING.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ src/
4242

4343
**Tests** - Run `pnpm test`. We use Vitest for unit and smoke testing.
4444

45-
4645
## Adding a Framework Analyzer
4746

4847
1. Create `src/analyzers/react/index.ts`
@@ -77,3 +76,23 @@ The server logs to stderr, so you can see what it's doing.
7776
- Open PR with what you changed and why
7877

7978
No strict commit format, just be clear about what you're doing.
79+
80+
## Release Notes (PR titles)
81+
82+
This repo publishes to npm via an automated Release PR flow.
83+
84+
To keep releases predictable and human-readable, please use a Conventional-Commits style **PR title** (we usually squash-merge, and the PR title becomes the commit message):
85+
86+
- `feat: ...` (new feature)
87+
- `fix: ...` (bug fix)
88+
- `docs: ...` (docs-only)
89+
- `chore: ...` (maintenance)
90+
- `refactor: ...` (refactor)
91+
92+
Examples:
93+
94+
- `feat: add memory store for team conventions`
95+
- `fix: avoid creating directories on invalid ROOT_PATH`
96+
- `docs: clarify MCP client config and npx --yes`
97+
98+
Maintainers: release steps are documented in `RELEASING.md`.

RELEASING.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Releasing
2+
3+
This repo publishes an npm package: `codebase-context`.
4+
5+
We use a clean OSS-style flow:
6+
7+
- PRs merge into `master` (nothing publishes on merge)
8+
- A release is created by a dedicated **Release PR** opened/updated automatically
9+
- When the Release PR is merged, CI creates a git tag like `v1.2.3`
10+
- Tag pushes trigger CI to publish to npm
11+
12+
## One-time setup (maintainers)
13+
14+
1. Add a repository secret: `NPM_TOKEN`
15+
- Create an npm access token with publish rights for `codebase-context`
16+
- Add it in GitHub: Settings > Secrets and variables > Actions > New repository secret
17+
- If your npm tokens expire (for example after 90 days), rotate the token and update this secret before it expires
18+
19+
2. (Recommended) Protect `master`
20+
- Require PRs (no direct pushes)
21+
- Require the `Tests` workflow to pass
22+
23+
This repo also uses `CODEOWNERS` so PRs from non-owners require an approval from `@PatrickSys`.
24+
25+
## Normal release flow
26+
27+
1. Merge changes into `master` via PRs.
28+
- Recommended: use **Squash and merge** so the PR title becomes the commit message.
29+
- Release automation relies on Conventional-Commits style messages like `feat: ...` / `fix: ...`.
30+
31+
2. Wait for the bot PR named like `release-please--branches--master`.
32+
- It bumps `package.json` and updates `CHANGELOG.md`
33+
- If it already exists, it gets updated automatically as new PRs merge
34+
35+
3. When you're ready to ship, merge the Release PR.
36+
- This creates a git tag `vX.Y.Z` and a GitHub Release
37+
- The `Publish` workflow runs on the tag and publishes to npm
38+
39+
## Notes
40+
41+
- Publishing is triggered only by `v*` tags.
42+
- The publish workflow verifies `tag == v${package.json.version}` and fails fast if they don't match.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import fs from 'node:fs';
2+
3+
const tag = process.env.GITHUB_REF_NAME;
4+
if (!tag) {
5+
console.error('Missing GITHUB_REF_NAME');
6+
process.exit(1);
7+
}
8+
9+
if (!tag.startsWith('v')) {
10+
console.error(`Expected tag like v1.2.3, got: ${tag}`);
11+
process.exit(1);
12+
}
13+
14+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
15+
const version = pkg?.version;
16+
if (!version || typeof version !== 'string') {
17+
console.error('Missing package.json version');
18+
process.exit(1);
19+
}
20+
21+
const expectedTag = `v${version}`;
22+
if (tag !== expectedTag) {
23+
console.error(
24+
`Tag/package.json version mismatch. Tag is ${tag}, but package.json is ${version} (expected ${expectedTag}).`
25+
);
26+
process.exit(1);
27+
}
28+
29+
console.log(`OK: ${tag} matches package.json version ${version}`);

0 commit comments

Comments
 (0)