* feat(ci): add release-candidate publish pipeline
Auto-publishes gitnexus@rc on every merge to main. Version scheme is
canonical semver X.Y.Z-rc.N where the base is the current npm 'latest'
bumped by the 'bump' input (default patch) and N auto-increments by
querying existing rc versions on the registry. First rc for a new base
is rc.1; the counter resets naturally when the base advances after a
stable release.
- Reuses ci.yml via workflow_call so tests must pass before publish
- SHA-pinned actions, per-job permission scoping, provenance enabled
- Guard job dedupes duplicate dispatches against HEAD via v*-rc.* tags
- Docs-only pushes skipped via paths-ignore
- workflow_dispatch inputs: bump (patch/minor/major), force (override guard)
- Publishes under the 'rc' dist-tag so 'latest' is never moved
- Tags commits as v<rc-version> and creates GitHub prereleases
* fix(ci): address release-candidate review feedback
- Sort rc tags by creatordate (handles out-of-order pushes correctly)
- Fail fast on npm registry errors; only fall back to package.json on E404
- Drop unused pull-requests: write permission on the reused CI job
- Add secrets: inherit so any future CI secrets are available to sub-jobs
- Remove unused reltag step output
* fix(ci): address Copilot review comments
- Correct concurrency comment (runs serialize on same ref, not overlap)
- Apply E404-only fallback to 'npm view versions' query, matching the
pattern used for the 'npm view version' query
- README: clarify that docs-only merges don't trigger rc publish
- CONTRIBUTING: drop 'from main' claim for publish.yml; the tag-push
trigger does not enforce branch reachability
* fix(ci): address adversarial review — idempotency, cycle continuity, tag integrity
Codex adversarial review flagged three release-safety issues in the rc
pipeline. Fixes:
1. Cycle continuity (H). Non-patch rc trains no longer collapse back to
patch on the next push. 'bump' input accepts a new 'auto' value
(default) that infers the active rc base from the registry: if any
X.Y.Z-rc.* exists with X.Y.Z > latest, continue that base; otherwise
patch-bump. Explicit patch/minor/major still forces a cycle reset and
now also bypasses the dedup guard so an explicit dispatch on a
tagged HEAD is honored.
2. Idempotency across post-publish failures (H). The guard marker
('rc/<HEAD_SHA>' lightweight tag) and the release tag ('v<RC>'
annotated) are now pushed atomically *before* 'npm publish'. A
publish failure leaves the marker in place and the guard refuses to
re-publish. Added a defensive 'npm view <pkg>@<rc> version' check
before publish to catch registry-level races. Recovery path
documented in CONTRIBUTING.md.
3. Tag ↔ package integrity (M). 'v<RC>' now points at a detached
release commit whose tree contains the rewritten package.json, so
the tag's source archive matches the npm tarball exactly. 'main'
stays pristine; the release commit is reachable only via the tag.
* fix(ci): surface registry errors on defensive version check; drop actions: read
- npm view <pkg>@<rc> version now distinguishes E404 (safe) from network
failures (abort) via the same mktemp+grep pattern used for the other
two npm view calls
- Dropped actions: read on the ci workflow_call — no sub-workflow uses
the Actions API
3.9 KiB
Contributing to GitNexus
How to propose changes, run checks locally, and open pull requests.
License
This project uses the PolyForm Noncommercial License 1.0.0. By contributing, you agree your contributions are licensed under the same terms unless stated otherwise.
Where to discuss
- Issues & feature ideas: use GitHub Issues for the upstream repo, or your fork’s tracker if you work from a fork.
- Community: see the Discord link in the root README.md.
Development setup
- Clone the repository.
- CLI / MCP package:
cd gitnexus && npm install && npm run build - Web UI (if needed):
cd gitnexus-web && npm install - Run tests as described in TESTING.md.
Branch and pull requests
-
Use short-lived branches off the default branch of the repo you are targeting.
-
Prefer conventional commits (short prefix + description), for example:
feat: add graph export option fix: correct MCP tool schema for query test: cover cluster merge edge case docs: clarify analyze flags -
PR title:
[area] Short description(e.g.[cli] Fix index refresh race). -
PR description: what changed, why, how to verify (commands), and any risk or rollback notes.
Before you open a PR
- Tests pass for the packages you touched (
gitnexusand/orgitnexus-web). - Typecheck passes:
npx tsc --noEmitingitnexus/andnpx tsc -b --noEmitingitnexus-web/. - No secrets, tokens, or machine-specific paths committed.
- Documentation updated if behavior or public CLI/MCP contract changes.
- Pre-commit hook runs clean (
.husky/pre-commit— typecheck + unit tests for staged packages).
Code review
Maintainers may request changes for correctness, tests, performance, or consistency with existing patterns. Keeping diffs focused makes review faster.
AI-assisted contributions
If you use coding agents, follow project context files (e.g. AGENTS.md, CLAUDE.md) and avoid drive-by refactors unrelated to the issue. Prefer incremental, test-backed changes.
Releases
Two publish workflows ship gitnexus to npm:
-
Stable (
.github/workflows/publish.yml) — triggered by pushing anyv*tag. Publishes to thelatestdist-tag with a changelog-backed GitHub release. Maintainers are expected to tag frommainas a convention; the workflow itself does not enforce branch reachability. -
Release Candidate (
.github/workflows/release-candidate.yml) — runs on every push tomain(typically a merged PR) plus manual dispatch. Docs-only changes are skipped viapaths-ignore. Publishes to thercdist-tag with versionX.Y.Z-rc.Nand a GitHub prerelease, where:X.Y.Zis selected automatically. On push (and on dispatch withbump: auto, the default) the workflow continues the active rc cycle: if the registry already hasX.Y.Z-rc.*versions withX.Y.Z> currentlatest, it reuses the highest such base; otherwise it patch-bumps fromlatest. Dispatching withbump: patch|minor|majorresets the cycle fromlatest.Nis auto-incremented against existingX.Y.Z-rc.*entries on the registry. First rc for a given base isrc.1.
Idempotency: the workflow pushes an
rc/<HEAD_SHA>marker tag and av<RC>release tag atomically, before callingnpm publish. The guard refuses to re-run once the marker exists, so a post-publish failure will not mint a duplicate rc for the same commit. Thev<RC>tag points at a detached release commit whosepackage.jsonmatches the npm tarball exactly (traceable releases). Recovery after a partial failure:git push --delete origin rc/<HEAD_SHA> v<RC> # then redispatch the workflow with force: true
The rc workflow never moves latest. To verify after a change, inspect dist-tags:
npm view gitnexus dist-tags