From 26bbd5f01ef4fe0166aa67824400887a3906dd01 Mon Sep 17 00:00:00 2001 From: Igor Kantor Date: Tue, 25 Aug 2026 16:37:49 -0400 Subject: [PATCH 1/3] Run dist artifact builds on pull requests --- dist-workspace.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dist-workspace.toml b/dist-workspace.toml index dd42d86..2542e67 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -7,6 +7,8 @@ members = ["cargo:."] cargo-dist-version = "0.32.0" # CI backends to support ci = "github" +# Whether to run full artifact builds on PRs (plan-only is the default) +pr-run-mode = "upload" # The installers to generate for each app installers = ["shell"] # Target platforms to build apps for (Rust target-triple syntax) From f55bad4698a40614daa200399490b444fd89c6a8 Mon Sep 17 00:00:00 2001 From: Igor Kantor Date: Tue, 25 Aug 2026 16:39:16 -0400 Subject: [PATCH 2/3] Add dist cargo cache step for PR builds --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1dfcd0f..7f15188 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -127,6 +127,10 @@ jobs: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y echo "$HOME/.cargo/bin" >> $GITHUB_PATH fi + - uses: swatinem/rust-cache@v2 + with: + key: ${{ join(matrix.targets, '-') }} + cache-provider: ${{ matrix.cache_provider }} - name: Install dist run: ${{ matrix.install_dist.run }} # Get the dist-manifest From 8e4bb65faed827f186e8d2b0357a484020130a1b Mon Sep 17 00:00:00 2001 From: Igor Kantor Date: Tue, 25 Aug 2026 16:41:36 -0400 Subject: [PATCH 3/3] Document release process --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 31c46b2..556add9 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,27 @@ cargo test # tools, scope, limiter, and gate-middleware tests cargo clippy --all-targets -- -D warnings ``` +## Releasing + +Releases are cut by pushing a tag — [cargo-dist](https://github.com/axodotdev/cargo-dist) does the rest. + +1. Bump `version` in `Cargo.toml` (the tag must match it exactly) and merge to `main`. +2. `git tag vX.Y.Z && git push origin vX.Y.Z` — the tag pattern triggers two workflows: + - **`release.yml`** builds the 6-target matrix (`*-apple-darwin`, `*-unknown-linux-gnu`, `x86_64-unknown-linux-musl`, `x86_64-pc-windows-msvc`) and publishes a GitHub Release with per-target archives, SHA-256 checksums, and a shell installer. + - **`docker.yml`** builds and pushes multi-arch (`linux/amd64`, `linux/arm64`) images to `ghcr.io/devfire/code-mcp`, tagged `X.Y.Z`, `X.Y`, `X`. +3. That's it — the release goes live with generated notes. End users install via: + +```sh +curl --proto '=https' --tlsv1.2 -LsSf \ + https://github.com/devfire/code-mcp/releases/download/vX.Y.Z/code-mcp-installer.sh | sh +``` + +Notes: + +- Prerelease: tag with a semver suffix (`v0.5.0-rc.1`) — the GitHub Release is marked prerelease automatically. +- Every PR runs the full artifact build matrix as a release smoke test (`pr-run-mode = "upload"` in `dist-workspace.toml`); artifacts attach to the workflow run, nothing is published from a PR. +- After changing `dist-workspace.toml`, regenerate the workflow (`dist generate-ci`) and commit both together — `dist plan` fails CI when the config and the workflow drift out of sync. + ## Notes & non-goals - **No auth** — by design (LAN deployment). For path scoping, use `--project`.