From b88d58a3fc922cad1ab3c44f7e053c6dbf13c8c3 Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Mon, 10 Aug 2026 19:25:16 +0200 Subject: [PATCH 1/5] fix(ci): tag the version bump and survive a push race in the release workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port the release-workflow fixes from e2b-dev/E2B (#1463, #1469, #1484, #1589, #1619). Every release tag here points at the commit *before* its own version bump (`@e2b/code-interpreter@2.7.0` contains `"version": "2.6.1"`), because `changesets/action` tags whatever HEAD it publishes from and the commit came afterwards. `changeset version` leaves `pnpm-lock.yaml` untouched in this repo — no workspace package depends on a sibling — so the release commit is already complete before anything is uploaded, and it can simply move ahead of the publish. That also drops the `Update lock file` step. The push is now gated on `git tag --points-at HEAD` rather than on whether publish succeeded: the tags are what has to end up reachable, and `changeset publish` pushes them before propagating a partial failure. A non-fast-forward is reconciled with a merge, not a rebase, which would strand those tags — run 30018789653 died on exactly that race with the versions already published. `git add -A` replaces `commit -am`, which cannot stage the CHANGELOG.md files `changeset version` writes fresh. Also: Slack start/success notifications with a release itinerary, `is_release` + `changes` collapsed into one `preflight` job, `always()` -> `!cancelled()` so the workflow can be cancelled, pnpm from `packageManager` and Node from `.tool-versions` instead of drifting pins, and `::set-output` replaced with `$GITHUB_OUTPUT`. Two latent bugs fixed on the way: `build-template` and `release` read `needs.changes.outputs.*` without depending on `changes`, and `release`'s `!contains(needs.*.result, 'failure')` could not see a template or docker failure, since a failed upstream makes the test jobs *skip* and skipped is not failure — so a broken template build could publish. All upstream jobs are now listed in `needs`. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 240 ++++++++++++++++++++++------------ .tool-versions | 1 + 2 files changed, 157 insertions(+), 84 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84b5d3a6..1c1c1c55 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,9 @@ on: push: branches: - main + # A release that publishes nothing leaves the changesets intact, so it can be + # re-dispatched by hand without another push to main. + workflow_dispatch: {} concurrency: Release-${{ github.ref }}-foxtrot @@ -12,25 +15,35 @@ permissions: contents: write jobs: - is_release: - name: Is release? + preflight: + name: Release preflight runs-on: ubuntu-latest outputs: release: ${{ steps.version.outputs.release }} + js: ${{ steps.js.outputs.release }} + python: ${{ steps.python.outputs.release }} + charts: ${{ steps.charts.outputs.release }} + template: ${{ steps.template.outputs.release }} + itinerary: ${{ steps.itinerary.outputs.itinerary }} steps: - name: Checkout Repo uses: actions/checkout@v4 + - name: Parse .tool-versions + uses: wistia/parse-tool-versions@v2.1.1 + with: + filename: '.tool-versions' + uppercase: 'true' + prefix: 'tool_version_' + - name: Install pnpm - uses: pnpm/action-setup@v3 + uses: pnpm/action-setup@v4 id: pnpm-install - with: - version: 9.5 - name: Setup Node uses: actions/setup-node@v6 with: - node-version: "22.x" + node-version: '${{ env.TOOL_VERSION_NODEJS }}' registry-url: "https://registry.npmjs.org" cache: pnpm cache-dependency-path: pnpm-lock.yaml @@ -49,70 +62,63 @@ jobs: IS_RELEASE=$(./.github/scripts/is_release.sh) echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT" - changes: - name: Repository changes - needs: [is_release] - if: needs.is_release.outputs.release == 'true' - runs-on: ubuntu-latest - outputs: - js: ${{ steps.js.outputs.release }} - python: ${{ steps.python.outputs.release }} - charts: ${{ steps.charts.outputs.release }} - template: ${{ steps.template.outputs.release }} - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v3 - id: pnpm-install - with: - version: 9.5 - - - name: Setup Node - uses: actions/setup-node@v6 - with: - node-version: "22.x" - registry-url: "https://registry.npmjs.org" - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - - - name: Configure pnpm - run: | - pnpm config set auto-install-peers true - pnpm config set exclude-links-from-lockfile true - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check JavasScript SDK Release + - name: Check JavaScript SDK Release id: js + if: steps.version.outputs.release == 'true' run: | IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/code-interpreter") echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT" - name: Check Python SDK Release id: python + if: steps.version.outputs.release == 'true' run: | IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/code-interpreter-python") echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT" - name: Check Charts SDK Release id: charts + if: steps.version.outputs.release == 'true' run: | IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/data-extractor") echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT" - name: Check Template SDK Release id: template + if: steps.version.outputs.release == 'true' run: | IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/code-interpreter-template") echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT" + - name: Build release itinerary + id: itinerary + if: steps.version.outputs.release == 'true' + run: | + pnpm changeset status --output=.cs-status.json + ITINERARY=$(node -e ' + const data = require("./.cs-status.json"); + const labels = { + "@e2b/code-interpreter": "JS SDK (@e2b/code-interpreter)", + "@e2b/code-interpreter-python": "Python SDK (e2b-code-interpreter)", + "@e2b/data-extractor": "Charts (e2b-charts)", + "@e2b/code-interpreter-template": "Sandbox template (code-interpreter)", + }; + const order = Object.keys(labels); + const byName = Object.fromEntries(data.releases.map(r => [r.name, r])); + const lines = order.filter(n => byName[n]).map(n => `• ${labels[n]} v${byName[n].newVersion}`); + process.stdout.write(lines.join("\n") || "• No packages were published"); + ') + rm -f .cs-status.json + { + echo "itinerary<> "$GITHUB_OUTPUT" + charts-release: name: Charts release - needs: [changes] - if: needs.changes.outputs.charts == 'true' + needs: [preflight] + if: needs.preflight.outputs.charts == 'true' runs-on: ubuntu-latest outputs: version: ${{ steps.output_version.outputs.version }} @@ -128,10 +134,8 @@ jobs: prefix: 'tool_version_' - name: Install pnpm - uses: pnpm/action-setup@v3 + uses: pnpm/action-setup@v4 id: pnpm-install - with: - version: 9.5 - name: Set up Python uses: actions/setup-python@v6 @@ -173,16 +177,15 @@ jobs: id: output_version working-directory: ./chart_data_extractor run: | - echo "::set-output name=version::$(pnpm pkg get version --workspaces=false | tr -d \\\")" + echo "version=$(pnpm pkg get version --workspaces=false | tr -d \\\")" >> "$GITHUB_OUTPUT" build-docker-image: name: Build Docker Image runs-on: ubuntu-latest - needs: [changes, charts-release] - if: always() && + needs: [preflight, charts-release] + if: (!cancelled()) && !contains(needs.*.result, 'failure') && - !contains(needs.*.result, 'cancelled') && - (needs.changes.outputs.template == 'true' || needs.changes.outputs.charts == 'true') + (needs.preflight.outputs.template == 'true' || needs.preflight.outputs.charts == 'true') steps: - name: Checkout repository uses: actions/checkout@v4 @@ -234,11 +237,10 @@ jobs: build-template: name: Build E2B template runs-on: ubuntu-latest - needs: [build-docker-image] - if: always() && + needs: [preflight, build-docker-image] + if: (!cancelled()) && !contains(needs.*.result, 'failure') && - !contains(needs.*.result, 'cancelled') && - (needs.changes.outputs.template == 'true' || needs.changes.outputs.charts == 'true') + (needs.preflight.outputs.template == 'true' || needs.preflight.outputs.charts == 'true') steps: - name: Checkout repository uses: actions/checkout@v4 @@ -269,30 +271,30 @@ jobs: python-tests: name: Python Tests - needs: [changes, build-template] - if: always() && + needs: [preflight, build-template] + if: (!cancelled()) && !contains(needs.*.result, 'failure') && - !contains(needs.*.result, 'cancelled') && - needs.changes.outputs.template == 'true' + needs.preflight.outputs.template == 'true' uses: ./.github/workflows/python_tests.yml secrets: inherit js-tests: name: JS Tests - needs: [changes, build-template] - if: always() && + needs: [preflight, build-template] + if: (!cancelled()) && !contains(needs.*.result, 'failure') && - !contains(needs.*.result, 'cancelled') && - needs.changes.outputs.template == 'true' + needs.preflight.outputs.template == 'true' uses: ./.github/workflows/js_tests.yml secrets: inherit release: - needs: [python-tests, js-tests] - if: always() && + # Every upstream job is listed, not just the tests: a job that fails makes its + # dependents *skip*, and a skipped test job is not a failure — so gating on + # `needs.*.result` only works for the jobs this one depends on directly. + needs: [preflight, charts-release, build-docker-image, build-template, python-tests, js-tests] + if: (!cancelled()) && !contains(needs.*.result, 'failure') && - !contains(needs.*.result, 'cancelled') && - (needs.changes.outputs.js == 'true' || needs.changes.outputs.python == 'true' || needs.changes.outputs.charts == 'true' || needs.changes.outputs.template == 'true') + needs.preflight.outputs.release == 'true' name: Release runs-on: ubuntu-latest steps: @@ -327,14 +329,12 @@ jobs: virtualenvs-in-project: true installer-parallel: true - - uses: pnpm/action-setup@v3 - with: - version: 9.5 + - uses: pnpm/action-setup@v4 - - name: Setup Node.js 24 + - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: "24.x" + node-version: '${{ env.TOOL_VERSION_NODEJS }}' registry-url: 'https://registry.npmjs.org' cache: pnpm @@ -351,6 +351,29 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Commit new versions + # Commit before publishing, because `changeset publish` tags whatever HEAD + # it publishes from — tagging afterwards is what left every tag on the + # commit before its own version bump (SDK-298). Nothing in the tree + # references the artifacts about to be uploaded — `changeset version` + # leaves `pnpm-lock.yaml` untouched here, since no workspace package + # depends on another — so the commit is already complete. It stays local + # until something is actually published, so a publish that uploads + # nothing leaves the branch untouched and the changesets intact for a + # re-run. + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # `add -A`, not `commit -a`: `changeset version` writes each package's + # CHANGELOG.md as a new file the first time, which `-a` would drop. + git add -A + if git diff --cached --quiet; then + echo "::error::'changeset version' produced no changes, so there is no version bump to publish or tag." + exit 1 + fi + git commit -m "[skip ci] Release new versions" + - name: Release new versions uses: changesets/action@v1 with: @@ -361,29 +384,78 @@ jobs: NPM_TOKEN: "" # See https://github.com/changesets/changesets/issues/1152#issuecomment-3190884868 PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - - name: Update lock file - run: pnpm i --no-link --no-frozen-lockfile - - - name: Commit new versions + - name: Push new versions + # Gate on the tags rather than on whether the publish step succeeded: they + # are what has to end up reachable. `changeset publish` tags at HEAD and the + # step above pushes them to origin, so if any exist — even from a publish + # that then failed partway — the commit they point at has to land, or they + # hang off no branch, which is the SDK-298 breakage this change prevents. + if: always() run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git commit -am "[skip ci] Release new versions" || exit 0 - git push + if [ -z "$(git tag --points-at HEAD)" ]; then + echo "Nothing was published; the version bump stays local and the changesets are intact for a re-run." + exit 0 + fi + + if ! git push; then + # A PR merged mid-release. Merge rather than rebase: the tags already + # point at this commit and rewriting it would strand them off the branch. + git fetch origin "${GITHUB_REF_NAME}" + git merge --no-edit FETCH_HEAD + git push + fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + report-start: + needs: [preflight] + if: needs.preflight.outputs.release == 'true' + name: Code Interpreter Release Started - Slack Notification + runs-on: ubuntu-latest + steps: + - name: Release Started - Slack Notification + uses: rtCamp/action-slack-notify@33ca3be66c6f378fe1610fd1d5258632dbed5e58 # v2.4.0 + env: + SLACK_COLOR: "#3aa3e3" + SLACK_MESSAGE: | + :rocket: A new release has been triggered :hourglass_flowing_sand: + + *Releasing:* + ${{ needs.preflight.outputs.itinerary }} + SLACK_TITLE: Code Interpreter Release Started + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_CHANNEL: "monitoring-releases" + report-failure: - needs: [python-tests, js-tests, release] + needs: [charts-release, build-docker-image, build-template, python-tests, js-tests, release] if: failure() name: Code Interpreter Release Failed - Slack Notification runs-on: ubuntu-latest steps: - name: Release Failed - Slack Notification - uses: rtCamp/action-slack-notify@v2 + uses: rtCamp/action-slack-notify@33ca3be66c6f378fe1610fd1d5258632dbed5e58 # v2.4.0 env: SLACK_COLOR: "#ff0000" SLACK_MESSAGE: ":here-we-go-again: :bob-the-destroyer: We need :fix-parrot: ASAP :pray:" SLACK_TITLE: Code Interpreter Release Failed SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} SLACK_CHANNEL: "monitoring-releases" + + report-success: + needs: [preflight, release] + if: (!cancelled()) && needs.release.result == 'success' + name: Code Interpreter Release Succeeded - Slack Notification + runs-on: ubuntu-latest + steps: + - name: Release Succeeded - Slack Notification + uses: rtCamp/action-slack-notify@33ca3be66c6f378fe1610fd1d5258632dbed5e58 # v2.4.0 + env: + SLACK_COLOR: "#36a64f" + SLACK_MESSAGE: | + :tada: A new version has been released successfully! :ship-it-parrot: + + *Released:* + ${{ needs.preflight.outputs.itinerary }} + SLACK_TITLE: Code Interpreter Release Succeeded + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_CHANNEL: "monitoring-releases" diff --git a/.tool-versions b/.tool-versions index 0c2d9665..58826e3d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,3 @@ +nodejs 24 python 3.10 poetry 2.1.1 From 6dc0e1fec11353a9efdcdd650b6adc911a16ebcf Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:58:06 +0200 Subject: [PATCH 2/5] fix(ci): guard manual dispatch, push stray tags, extract the itinerary script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses the bot review on #327. `workflow_dispatch` offers every branch in the picker, so a feature branch carrying changesets could publish real packages and push the version bump to that branch; preflight now fails fast unless the run is on main. `changesets/action` runs the publish script with `ignoreReturnCode: true` and pushes each tag it can parse out of the output before it fails the step, so a partial publish does get its tags to origin — but only the ones that appear as `New tag:` lines. `git push --tags` after the branch lands covers anything else sitting at the release commit; the checkout is shallow and fetches no tags, so the only local tags are this run's, and re-pushing the rest is a no-op. The itinerary transform moves to `.github/scripts/`, next to `is_release.sh`, where it can be run against fixture JSON instead of only during a release; a package missing from the label map now shows up under its workspace name rather than vanishing. The step is `continue-on-error` and the messages fall back to a placeholder — it feeds a Slack notification and should never be what blocks a release. Co-Authored-By: Claude Opus 5 (1M context) --- .github/scripts/build_release_itinerary.cjs | 37 +++++++++++++++++++ .github/workflows/release.yml | 39 +++++++++++++-------- 2 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 .github/scripts/build_release_itinerary.cjs diff --git a/.github/scripts/build_release_itinerary.cjs b/.github/scripts/build_release_itinerary.cjs new file mode 100644 index 00000000..dfd57d18 --- /dev/null +++ b/.github/scripts/build_release_itinerary.cjs @@ -0,0 +1,37 @@ +#!/usr/bin/env node + +// This script formats the JSON written by `changeset status --output=` +// as the package list that goes into the release's Slack notifications. + +const path = require('path') + +// Packages are listed in this order; anything not named here still shows up, +// under its workspace name, after the ones that are. +const labels = { + '@e2b/code-interpreter': 'JS SDK (@e2b/code-interpreter)', + '@e2b/code-interpreter-python': 'Python SDK (e2b-code-interpreter)', + '@e2b/data-extractor': 'Charts (e2b-charts)', + '@e2b/code-interpreter-template': 'Sandbox template (code-interpreter)', +} + +const statusFile = process.argv[2] +if (!statusFile) { + console.error('Usage: build_release_itinerary.cjs ') + process.exit(1) +} + +const order = Object.keys(labels) +const rank = (release) => { + const index = order.indexOf(release.name) + return index === -1 ? order.length : index +} + +const { releases } = require(path.resolve(statusFile)) +const lines = [...releases] + .sort((a, b) => rank(a) - rank(b)) + .map( + (release) => + `• ${labels[release.name] ?? release.name} v${release.newVersion}` + ) + +process.stdout.write(lines.join('\n') || '• No packages were published') diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c1c1c55..e65c885d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,6 +26,17 @@ jobs: template: ${{ steps.template.outputs.release }} itinerary: ${{ steps.itinerary.outputs.itinerary }} steps: + - name: Check the ref + # `workflow_dispatch` offers every branch in the picker, and a feature + # branch carrying changesets would otherwise publish real packages and + # push the version bump to that branch. + if: github.ref != 'refs/heads/main' + env: + REF: ${{ github.ref }} + run: | + echo "::error::Releases must run on main; this run is on ${REF}." + exit 1 + - name: Checkout Repo uses: actions/checkout@v4 @@ -93,21 +104,12 @@ jobs: - name: Build release itinerary id: itinerary if: steps.version.outputs.release == 'true' + # This only feeds the Slack notifications, so it must never be the thing + # that blocks a release; the messages fall back to a placeholder. + continue-on-error: true run: | pnpm changeset status --output=.cs-status.json - ITINERARY=$(node -e ' - const data = require("./.cs-status.json"); - const labels = { - "@e2b/code-interpreter": "JS SDK (@e2b/code-interpreter)", - "@e2b/code-interpreter-python": "Python SDK (e2b-code-interpreter)", - "@e2b/data-extractor": "Charts (e2b-charts)", - "@e2b/code-interpreter-template": "Sandbox template (code-interpreter)", - }; - const order = Object.keys(labels); - const byName = Object.fromEntries(data.releases.map(r => [r.name, r])); - const lines = order.filter(n => byName[n]).map(n => `• ${labels[n]} v${byName[n].newVersion}`); - process.stdout.write(lines.join("\n") || "• No packages were published"); - ') + ITINERARY=$(node ./.github/scripts/build_release_itinerary.cjs .cs-status.json) rm -f .cs-status.json { echo "itinerary< Date: Tue, 11 Aug 2026 15:48:47 +0200 Subject: [PATCH 3/5] ci: cut releases by dispatch only, as in e2b-dev/E2B MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merging a changeset to main no longer publishes on its own; changesets accumulate until someone dispatches the workflow. Nothing else depended on the push trigger — no workflow here uses `workflow_run`, and every other workflow fires on `pull_request` — so this is only a change to who decides when a release happens. The ref check added for the dispatch path now guards the only path there is, which E2B's own release workflow does not do: with production releases dispatchable from any branch in the picker, a feature branch carrying changesets would publish for real and push the version bump to itself. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e65c885d..9eec9b23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,11 +1,10 @@ name: Release on: - push: - branches: - - main - # A release that publishes nothing leaves the changesets intact, so it can be - # re-dispatched by hand without another push to main. + # Releases are cut by hand, as in e2b-dev/E2B: merging a changeset to main no + # longer publishes on its own, so changesets accumulate until someone + # dispatches this. A release that publishes nothing leaves them intact, which + # makes a re-dispatch the recovery path too. workflow_dispatch: {} concurrency: Release-${{ github.ref }}-foxtrot From 6bafc58d6c04cf6291abee42c1df37d210456d3e Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:51:33 +0200 Subject: [PATCH 4/5] ci: report a preflight failure to Slack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `report-failure` did not list `preflight`, so whether a broken preflight — a failed install, an erroring `is_release.sh`, a dispatch off `main` — pings the release channel depended on `failure()` looking past this job's direct dependencies. Listing it removes the doubt. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9eec9b23..4d285070 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -435,7 +435,9 @@ jobs: SLACK_CHANNEL: "monitoring-releases" report-failure: - needs: [charts-release, build-docker-image, build-template, python-tests, js-tests, release] + # `preflight` included so a failure there is reported too, whether or not + # `failure()` looks past this job's direct dependencies. + needs: [preflight, charts-release, build-docker-image, build-template, python-tests, js-tests, release] if: failure() name: Code Interpreter Release Failed - Slack Notification runs-on: ubuntu-latest From a14d9c369b919dbff04aed8fa28ef61d2ae5d224 Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:53:36 +0200 Subject: [PATCH 5/5] ci: drop the redundant tag push `changesets/action` runs the publish script with `ignoreReturnCode: true` and pushes every tag it parses out of the output before failing the step, including the ones for private packages: in e2b-dev/E2B the private `@e2b/python-sdk` tags all reach origin with no such step. So there is nothing left at the release commit for `git push --tags` to catch. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d285070..3fc14573 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -405,13 +405,6 @@ jobs: git merge --no-edit FETCH_HEAD git push fi - - # `changesets/action` only pushes the tags it can parse out of - # `changeset publish`'s output, so push whatever else ended up at the - # release commit. The checkout is shallow and fetches no tags, so the - # only local tags are the ones this run created, and re-pushing the - # ones the action already sent is a no-op. - git push --tags env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}