diff --git a/.changeset/config.json b/.changeset/config.json index d2b5c44143..5160b1aae0 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -11,5 +11,8 @@ "version": false, "tag": false }, + "snapshot": { + "useCalculatedVersion": true + }, "ignore": [] } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 878fe386db..117d0e4e4b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,15 +5,15 @@ on: branches: [main] workflow_dispatch: -# Queue runs instead of cancelling: aborting a run mid-`changeset publish` -# can leave npm with only some of the packages published. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false - jobs: release: runs-on: ubuntu-latest + # Do not abort an in-flight `changeset publish`: npm could be left with only + # some packages published. Keep this scoped to stable releases so every + # commit can run its continuous release independently. + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-stable + cancel-in-progress: false permissions: contents: write pull-requests: write @@ -71,3 +71,72 @@ jobs: if [[ -n "$version" ]]; then gh release edit "eve@$version" --latest fi + + # Runs stay independent so every commit gets a snapshot. When pushes overlap, + # `canary` follows publish completion order and may briefly point to an older + # commit; immutable snapshot versions remain the reproducible install path. + continuous-release: + if: github.event_name == 'push' + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup pnpm + uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version-file: .nvmrc + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Version continuous release + env: + COMMIT_SHA: ${{ github.sha }} + run: | + # Authored changesets belong to the stable release plan. Remove them + # from this ephemeral checkout so only eve receives a snapshot. + for changeset in .changeset/*.md; do + if [[ "$changeset" != ".changeset/README.md" ]]; then + rm -f "$changeset" + fi + done + cat > .changeset/continuous-release.md <> "$GITHUB_STEP_SUMMARY" + echo "Install the latest continuous release with \`npm install eve@canary\`." >> "$GITHUB_STEP_SUMMARY" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9e5f60c77..ff2eae9878 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -212,7 +212,25 @@ on when one exists. Do not create an issue solely to accompany a pull request. 5. Make sure `pnpm lint`, `pnpm typecheck`, and `pnpm test` pass. 6. Open the PR with a clear description of the problem and solution. -Releases are managed with [Changesets](https://github.com/changesets/changesets) by the maintainers. +Stable releases are managed with [Changesets](https://github.com/changesets/changesets) by the maintainers. +Every commit pushed to `main` also publishes an immutable +[Changesets snapshot](https://changesets.dev/guide/snapshot-releases) of the +`eve` package. The continuous release excludes authored stable-release +changesets, so it does not publish snapshots of the other public packages. +Install the most recently published snapshot with: + +```bash +npm install eve@canary +``` + +The release workflow summary includes the exact +`-g` version for its commit. This version advances +from the current stable release and does not predict the bump in the pending +stable release plan. Use the exact version when you need a reproducible install +instead of the moving `canary` tag. Continuous releases do not create a GitHub +release or change npm's `latest` tag. Runs are independent so every commit gets +a snapshot; when pushes overlap, `canary` follows publish completion order +rather than commit order. ## Developer Certificate of Origin (DCO)