Skip to content

ci: guard production releases to main, harden the itinerary step - #1662

Merged
mishushakov merged 1 commit into
mainfrom
ci/guard-release-ref-and-itinerary
Aug 12, 2026
Merged

mishushakov merged 1 commit into
mainfrom
ci/guard-release-ref-and-itinerary

Conversation

@mishushakov

Copy link
Copy Markdown
Member

Three fixes found while porting this workflow to e2b-dev/code-interpreter (#327).

release.yml can be dispatched from any branch. It is dispatch-only and workflow_dispatch offers every branch in the picker, so a feature branch carrying changesets would publish real packages to npm and PyPI and push the version bump to itself. preflight now fails fast unless the run is on main; candidates cut from a branch already go through release-candidate.yml.

The itinerary step can block a release. It only feeds the Slack messages, but a changeset status hiccup — or a typo in a future edit to that inline node -e block, which no YAML validation catches — fails preflight and stops the release. It is now continue-on-error with a placeholder fallback in both messages, and the transform moved to .github/scripts/build_release_itinerary.cjs next to is_release.sh, where it can be run against fixture JSON. A package missing from the label map now shows under its workspace name instead of being dropped by order.filter, so a fourth publishable package would not silently vanish from the notification.

report-failure did not list preflight, so whether a broken preflight pings #monitoring-releases rested on failure() looking past the job's direct dependencies — not documented either way, so the job now depends on it explicitly.

Verified: the extracted script reproduces the current output exactly for e2b / @e2b/python-sdk / @e2b/cli, in the same order, and handles the empty and unlabeled-package cases; workflow validated against the Actions schema; the script matches the repo's prettier config.

🤖 Generated with Claude Code

Three fixes found while porting this workflow to e2b-dev/code-interpreter.

`release.yml` is dispatch-only and `workflow_dispatch` offers every branch
in the picker, so a feature branch carrying changesets could publish real
packages to npm and PyPI and push the version bump to itself. Preflight now
fails fast off `main`; candidates cut from a branch already have
release-candidate.yml.

The itinerary step could block a release. It only feeds the Slack messages,
but a `changeset status` hiccup — or a typo in a future edit to an inline
`node -e` block, which no YAML validation catches — failed preflight and
stopped the release. It is now `continue-on-error` with a placeholder
fallback in the messages, and the transform moved to `.github/scripts/`
next to `is_release.sh`, where it can be run against fixture JSON. A
package missing from the label map now appears under its workspace name
instead of being dropped by `order.filter`.

`report-failure` did not list `preflight`, so whether a broken preflight
pinged the release channel rested on `failure()` looking past the job's
direct dependencies, which is not documented either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cla-bot cla-bot Bot added the cla-signed label Aug 11, 2026
@cursor

cursor Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

PR Summary

Low Risk
CI workflow guardrails and notification-only step hardening; no application runtime or publish logic changes beyond blocking accidental off-main releases.

Overview
Production release workflow could be started from a non-main branch via workflow_dispatch, which would publish real packages and push version bumps to that branch. Preflight now errors unless the ref is main.

The Slack itinerary step ran inline in YAML and could fail preflight on changeset status or script errors even though it only affects notifications. That step is continue-on-error, Slack messages use a placeholder when the itinerary is missing, and formatting moved to build_release_itinerary.cjs, which lists unknown packages by workspace name instead of omitting them.

report-failure did not declare preflight as a dependency, so preflight failures might not trigger the failure Slack job reliably; preflight is now in needs.

Reviewed by Cursor Bugbot for commit 2c5403b. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2c5403b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Package Artifacts

Built from ef1b411. Download artifacts from this workflow run.

JS SDK (e2b@2.38.4-ci-guard-release-ref-and-itinerary.0):

npm install ./e2b-2.38.4-ci-guard-release-ref-and-itinerary.0.tgz

CLI (@e2b/cli@2.16.2-ci-guard-release-ref-and-itinerary.0):

npm install ./e2b-cli-2.16.2-ci-guard-release-ref-and-itinerary.0.tgz

Python SDK (e2b==2.38.0+ci.guard.release.ref.and.itinerary):

pip install ./e2b-2.38.0+ci.guard.release.ref.and.itinerary-py3-none-any.whl

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — small, well-verified CI hardening change with no application code touched.

What was reviewed: the extracted build_release_itinerary.cjs script (verified its output matches the original inline transform for known packages, and correctly promotes previously-dropped unlabeled packages instead of silently omitting them); the main-branch guard placement and its interaction with continue-on-error/job-level failure semantics; the report-failure needs/failure() wiring; confirmed the script passes the repo's prettier check.

Extended reasoning...

Overview

This PR touches only .github/workflows/release.yml and a new helper script .github/scripts/build_release_itinerary.cjs. It adds a preflight guard that fails the release workflow unless triggered on main, makes the Slack itinerary-building step continue-on-error with a placeholder fallback, extracts the itinerary transform from inline YAML into a testable script, and adds preflight to report-failure's needs so preflight failures reliably trigger the failure notification.

Security risks

No auth, crypto, or data-handling logic is touched. If anything, the main change (guarding workflow_dispatch against non-main refs) reduces risk by preventing an accidental publish of real packages from a feature branch. The only theoretical downside — that a rejected wrong-branch dispatch will now also page #monitoring-releases via report-failure — was already raised and investigated by the bug-hunting pass and reasonably concluded to be intended/benign rather than a bug.

Level of scrutiny

This warrants light scrutiny: it's a CI-only workflow change with no impact on runtime/application code, and the repo has a single blanket CODEOWNER with no special CI ownership. I independently verified the extracted script's behavior against the original inline node -e logic using fixture data (known packages, an unlabeled package, and the empty case) and confirmed the output matches what the PR description claims, including the fix for previously-dropped unlabeled packages. I also confirmed release.yml is not invoked via workflow_call elsewhere, so the new ref guard cannot break any other workflow, and that release-candidate.yml (the referenced alternate path for branch-based candidates) does exist.

Other factors

The bug-hunting pass found no bugs, and the one candidate issue it raised (report-failure paging on benign wrong-branch guard rejections) was examined and ruled out as intentional. No outstanding review comments require action — only bot summaries (Cursor, changeset-bot) are present, and no changeset is needed for a CI-only change.

@mishushakov
mishushakov merged commit 034c503 into main Aug 12, 2026
25 checks passed
@mishushakov
mishushakov deleted the ci/guard-release-ref-and-itinerary branch August 12, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants