From 84cbd16fedab67cc700d8f495aed2657eefa3976 Mon Sep 17 00:00:00 2001 From: UncleCat Date: Thu, 15 Oct 2026 21:19:22 +0700 Subject: [PATCH] ci: trunk-based releases, semver policy and release notes with PR links - Drop the staging branch: feature branches open PRs straight into master, and the Changesets "version packages" PR is the batching step. CI no longer runs on pushes to staging. - The auto-changeset step ignores docs- and test-only changes, so users only get a new version when shipped code or dependencies change. - Changelogs and GitHub Releases come from @changesets/changelog-github and link each entry to its PR. - CONTRIBUTING documents the semver policy (patch/minor/major) and the plan to cut 1.0.0 together with the Odoo refactor. --- .changeset/config.json | 7 ++++++- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 ++ CONTRIBUTING.md | 28 +++++++++++++++++++++------- README.md | 8 +++++--- package.json | 1 + pnpm-lock.yaml | 31 +++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 12 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index dcd3d8b..273fe8e 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,6 +1,11 @@ { "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": "@changesets/cli/changelog", + "changelog": [ + "@changesets/changelog-github", + { + "repo": "unclecatvn/mcp" + } + ], "commit": false, "fixed": [], "linked": [], diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0203f2..296b301 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: CI on: pull_request: push: - branches: [master, staging] + branches: [master] concurrency: group: ci-${{ github.ref }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eaf1b04..508a75f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -78,9 +78,11 @@ jobs: # Detect changed workspace packages between this commit and its first parent # Package dirs come from pnpm-workspace.yaml (root excluded), so new packages are picked up automatically + # Docs and tests alone never trigger a release: users only get a new version when shipped code or deps change base=$(git rev-parse HEAD^1) pkgs=$(pnpm -r exec pwd | xargs -n1 basename) changed_dirs=$(git diff --name-only "$base" HEAD \ + | grep -Ev '\.md$|/test/|/vitest\.config\.js$|/\.prettierignore$' \ | cut -d/ -f1 \ | grep -Fx "$pkgs" \ | sort -u || true) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 91b95c2..af7183d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,10 +29,10 @@ This is a pnpm monorepo. Each MCP server is its own package directory at the rep ## Branches -- **`master`** — default branch. Release workflow triggers on push here. Always green. -- **`staging`** — integration branch used to assemble multiple feature branches before opening a PR into `master`. CI runs on push to `staging` too. +- **`master`** is the only long-lived branch. It must always be green, and the release workflow runs on every push to it. +- All work happens on short-lived feature branches (`feat/...`, `fix/...`, `docs/...`, `ci/...`) that are merged into `master` through a PR. -Direct pushes to `master` are not allowed. The normal flow is: feature branch → PR into `staging` → PR from `staging` into `master`. +Do not push to `master` directly. There is no integration branch: the **version packages** PR described below already collects every merged change until a maintainer decides to release. ## Common commands @@ -55,20 +55,34 @@ pnpm --filter @unclecat/mcp-multi-db test:watch ## Pull-request flow -1. Branch from `staging` (or `master` for hotfix). +1. Branch from `master`. 2. Make your changes in the relevant package directory. -3. **Run `pnpm changeset`** and pick the package(s), bump type (patch/minor/major), and write a clear summary. Commit the generated `.changeset/.md`. -4. Push and open a PR. +3. **Run `pnpm changeset`**, pick the package(s) and the bump type (see [Versioning](#versioning)), and write the summary for users: what changed for them, not how. Commit the generated `.changeset/.md`. Docs- or test-only changes need no changeset and never publish a release. +4. Push and open a PR into `master`. 5. CI runs lint, format, tests, and audit across all packages on Node 20/22. The aggregate check `ci-success` must pass. 6. After review and merge into `master`, the Release workflow opens (or updates) a **"chore(release): version packages"** PR aggregating pending changesets. 7. A maintainer merging the Version PR triggers automatic publish to npm (with provenance) and creates a GitHub Release for each package — tags use Changesets' scoped form, e.g. `@unclecat/mcp-multi-db@1.2.3`. +## Versioning + +Packages follow [semantic versioning](https://semver.org), so users can pin a major version (`npx -y @unclecat/mcp-odoo@1`) and still receive every fix and feature safely: + +| Bump | Use it for | +|---|---| +| `patch` | Bug fixes, dependency updates, performance | +| `minor` | New tools, new options, new output fields, all backward compatible | +| `major` | Removed or renamed tools, arguments, error codes or env vars, and changed defaults | + +If a PR changes shipped code but has no changeset, the release workflow adds a `patch` changeset from the commit subject, so Dependabot updates still get released. Breaking changes always need a hand-written `major` changeset. + +All packages are still `0.0.x`. `1.0.0` is planned together with the Odoo refactor, and from then on the table above applies strictly. + ## Releasing manually (maintainer) In the rare case the bot is unavailable: ```bash -pnpm changeset version # bumps versions, updates CHANGELOG +GITHUB_TOKEN=$(gh auth token) pnpm changeset version # bumps versions, writes CHANGELOG with PR links pnpm install --no-frozen-lockfile git commit -am "chore(release): version packages" git push diff --git a/README.md b/README.md index 5be69e8..8f4aef2 100644 --- a/README.md +++ b/README.md @@ -74,9 +74,11 @@ Work on one package with `pnpm --filter