Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @PatrickSys
10 changes: 10 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## What / Why

Explain the change briefly.

## Release notes

This repo uses an automated release flow.

- Please use a Conventional-Commits style PR title (we squash-merge): `feat: ...`, `fix: ...`, `docs: ...`, `chore: ...`, `refactor: ...`
- If this should not appear in release notes, say so here
49 changes: 49 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Publish

on:
push:
tags:
- 'v*'

permissions:
contents: read

jobs:
npm:
name: Publish to npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1

- uses: pnpm/action-setup@v2
with:
version: 10

- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'

- name: Install
run: pnpm install --frozen-lockfile

- name: Verify tag matches package.json version
run: node scripts/ci/ensure-tag-matches-package.mjs
env:
GITHUB_REF_NAME: ${{ github.ref_name }}

- name: Quality gates
run: |
pnpm lint
pnpm format:check
pnpm type-check
pnpm test
pnpm build

- name: Publish
run: pnpm publish --access public --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
19 changes: 19 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release Please

on:
push:
branches: [master]

permissions:
contents: write
pull-requests: write

jobs:
release-please:
name: Create/Update Release PR
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
release-type: node
package-name: codebase-context
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"trailingComma": "none",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
"tabWidth": 2,
"endOfLine": "auto"
}
21 changes: 20 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ src/

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


## Adding a Framework Analyzer

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

No strict commit format, just be clear about what you're doing.

## Release Notes (PR titles)

This repo publishes to npm via an automated Release PR flow.

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):

- `feat: ...` (new feature)
- `fix: ...` (bug fix)
- `docs: ...` (docs-only)
- `chore: ...` (maintenance)
- `refactor: ...` (refactor)

Examples:

- `feat: add memory store for team conventions`
- `fix: avoid creating directories on invalid ROOT_PATH`
- `docs: clarify MCP client config and npx --yes`

Maintainers: release steps are documented in `RELEASING.md`.
42 changes: 42 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Releasing

This repo publishes an npm package: `codebase-context`.

We use a clean OSS-style flow:

- PRs merge into `master` (nothing publishes on merge)
- A release is created by a dedicated **Release PR** opened/updated automatically
- When the Release PR is merged, CI creates a git tag like `v1.2.3`
- Tag pushes trigger CI to publish to npm

## One-time setup (maintainers)

1. Add a repository secret: `NPM_TOKEN`
- Create an npm access token with publish rights for `codebase-context`
- Add it in GitHub: Settings > Secrets and variables > Actions > New repository secret
- If your npm tokens expire (for example after 90 days), rotate the token and update this secret before it expires

2. (Recommended) Protect `master`
- Require PRs (no direct pushes)
- Require the `Tests` workflow to pass

This repo also uses `CODEOWNERS` so PRs from non-owners require an approval from `@PatrickSys`.

## Normal release flow

1. Merge changes into `master` via PRs.
- Recommended: use **Squash and merge** so the PR title becomes the commit message.
- Release automation relies on Conventional-Commits style messages like `feat: ...` / `fix: ...`.

2. Wait for the bot PR named like `release-please--branches--master`.
- It bumps `package.json` and updates `CHANGELOG.md`
- If it already exists, it gets updated automatically as new PRs merge

3. When you're ready to ship, merge the Release PR.
- This creates a git tag `vX.Y.Z` and a GitHub Release
- The `Publish` workflow runs on the tag and publishes to npm

## Notes

- Publishing is triggered only by `v*` tags.
- The publish workflow verifies `tag == v${package.json.version}` and fails fast if they don't match.
29 changes: 29 additions & 0 deletions scripts/ci/ensure-tag-matches-package.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import fs from 'node:fs';

const tag = process.env.GITHUB_REF_NAME;
if (!tag) {
console.error('Missing GITHUB_REF_NAME');
process.exit(1);
}

if (!tag.startsWith('v')) {
console.error(`Expected tag like v1.2.3, got: ${tag}`);
process.exit(1);
}

const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const version = pkg?.version;
if (!version || typeof version !== 'string') {
console.error('Missing package.json version');
process.exit(1);
}

const expectedTag = `v${version}`;
if (tag !== expectedTag) {
console.error(
`Tag/package.json version mismatch. Tag is ${tag}, but package.json is ${version} (expected ${expectedTag}).`
);
process.exit(1);
}

console.log(`OK: ${tag} matches package.json version ${version}`);
Loading