release
Lanzar una nueva versión de Remotion
npx skills add https://github.com/remotion-dev/remotion --skill release-
Kill any
turboprocesses that might be running with SIGKILL -
Before beginning the release, verify that gcloud is logged in by running
gcloud auth print-access-token >/dev/null. If it fails, rungcloud auth login, then repeat the check. Do not continue with the release until the check succeeds. -
Codex-specific: Before running release commands, make sure rbenv wins over the macOS system Ruby. Codex may start non-interactive shells with
/usr/binbefore~/.rbenv/shims, causing Ruby 2.6 to be used even though the user's terminal uses Ruby 3.3.x. Run release commands that may invoke Ruby/Bundler with:PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH" <command>Verify withPATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH" ruby --version; it should use the user's rbenv Ruby, not/usr/bin/ruby. This matters because the lambda Ruby package currently resolves gems such asjsonthat require Ruby >= 2.7. -
Check
npm whoami. Only if it fails, runnpm login(I will manually do 2FA in the browser) -
Use
op item get "Npmjs" --fields password --reveal --account remotiondev.1password.comto get the password for NPM. -
Use
op item get "Npmjs" --otp --account remotiondev.1password.comto get a one-time password for 2FA. -
Run
npm token create --name="PublishRemotionXXXXXX" --packages "remotion" --packages "create-video" --packages-and-scopes-permission read-write --bypass-2fa --scopes "@remotion" --otp=<otp>. Replace XXXXXX with a random string so we have a unique name. Useop item get "Npmjs" --otp --account remotiondev.1password.comto get the OTP and pass it via--otp=. It will ask for a password, pipe in the password usingecho "$PASSWORD" |.- Do not pass
--json: npm masks the token asnpm_***in JSON output, making it unusable. Redirect the plain output to a file in the scratchpad and extract the token withgrep -oE 'npm_[A-Za-z0-9]{20,}'into a scratchpad file (e.g.$SP/npm_token). Never print the token. If a token turned out unusable, revoke it withnpm token revoke <id> --otp=<otp>(find the id withnpm token list).
- Do not pass
-
Run
bun i -
Run
bun run build -
Run
npm view remotion versionto get the current version number -
Run
bun set-version.ts <version>, where is the current version plus 1. If the exit code is not 0, abort the entire release process immediately. Do not pipe its output (e.g. intotail): the shell is zsh, so$PIPESTATUSis unavailable and the exit code gets lost. Redirect to a log file instead, then confirm thev<version>commit and tag exist. -
Run
cd packages/example && sh runlambda.sh && cd ../... If this fails, abort the release. -
Publish the public packages under a temporary npm dist-tag, then promote
latestonly after every package is installable.validatingis npm's automatic scan for ordinary publishes, not a reason to usenpm stage. Do not runbun run release: its current script publishes directly tolatestand starts private publishing and Git pushes before the availability gate.-
From the repository root, after
set-version.ts, run:releaseVersion=$(node -p "require('./packages/core/package.json').version") releaseTag="remotion-release-$(printf '%s' "$releaseVersion" | tr . -)" releaseManifest="/tmp/remotion-release-${releaseVersion}-packages.txt" bun publish.ts --list > "$releaseManifest"The manifest is the exact package list to check and promote. Record each package's previous
latesttag so a partial promotion can be rolled back. -
Check whether any package in the manifest is being published to npm for the first time. Bun adds
latestto a package's initial publish even with--tag. If there are new packages, stop before the bulk publish and plan their first publication separately; this flow cannot keep their first version offlatest. -
Run
NPM_CONFIG_TOKEN=<token> bun publish.ts --tag="$releaseTag"with the token created above. Bun still packs the packages and rewritesworkspace:andcatalog:dependencies. This tagged path does not tolerate republish errors. A successful upload is not proof that npm's scan is finished: check the manifest, exact package versions, and temporary tags. Do not upload the same version again while its scan is pending. If a publish attempt failed and the version is confirmed absent, resume that package alone withbun publish.ts --tag="$releaseTag" --only=<package>using the same token; never rerun the entire manifest blindly. -
For each package in the manifest, require
npm view <package>@<version> version --jsonand a successfulnpm pack <package>@<version> --pack-destination <temporary-directory>before promotion. The pack check confirms the tarball can actually be fetched. Run the per-package checks with awhile read -r p; do ( ... ) & done < "$releaseManifest"; waitloop (notxargs -I, which fails with "command line cannot be assembled"). Right after publishing, expect roughly a third of the packages to still bevalidating; this has taken ~15 minutes. Write the polling loop as a script and run it in the background, and draft the changelog meanwhile. Poll unresolved packages about once per minute; use the npm lifecycle status API where available:GET https://registry.npmjs.org/-/package/<encoded-package-name>/version/<version>/status, authenticated with publish access. URL-encode scoped names, such as@remotion%2Fwhisper-web, and keep credentials out of logs. If a package remainsvalidatingafter an hour, report the release as pending and leave everylatesttag on the prior release. Blocked, rejected, manual-review, missing, and unknown states also stop promotion; investigate them rather than treating them as scanning delays. -
Once all packages are installable, use the release token to run
npm dist-tag add <package>@<version> latestfor every package in the manifest. The npm CLI ignoresNPM_CONFIG_TOKEN(onlybun publishrespects it) and falls back to the login session, failing withEOTP. Pass the token like this instead:env "npm_config_//registry.npmjs.org/:_authToken=$TOKEN" npm dist-tag add .... This is one registry operation per package; npm has no atomic multi-package promotion. Verify thatnpm view <package> dist-tags.latest --prefer-onlineequals the release version for every package. Parallel checks can return stale cached tags for a few packages; recheck mismatches sequentially before treating them as failures. If promotion fails partway, restore the recorded previouslatesttags for packages already changed and report the incomplete release. After a successful promotion, remove the temporary tag from each package and verify the final tags. The release token getsE403ondist-tag rm, so use the logged-in session with a fresh OTP per call:npm dist-tag rm <package> <releaseTag> --otp=$(op item get "Npmjs" --otp --account remotiondev.1password.com). If a call fails because the OTP rolled over, wait 30 seconds and retry once. -
If npm explicitly returns
E_STAGE_REQUIRED, direct publishing is unavailable for that package. Stop this release and assess a staged workflow separately; staged approval requires a 2FA action per package. Do not silently mix a staged package into this direct-publish flow.
-
-
Only after all public
latesttags are verified, runbunx turbo run publishprivate --concurrency=1, thengit push --tagsandgit pushfrom the repository root. If any step fails, stop and report the affected release state. -
Run
bun run publishtemplatesfrom the repository root to republish every template after the public packages have been promoted. If any template fails to publish, stop the release workflow and report the failure. -
Generate a changelog in markdown and save it to
/tmp/release-<version>.md:- Run
git log v<previous_version>..v<new_version> --onelineto get all commits - Extract PR numbers from merge commits
- For each PR, run
gh pr view <number> --json title,author,number,url --jq '"* \(.title) by @\(.author.login) in \(.url)"' - Categorize PRs into sections: "What's Changed", "Templates", "Docs", "Internal"
- Also use the "Elements" and "Internal and Experimental" sections when previous releases do
- In "What's Changed", put headline features (especially ones with new docs pages) first, then sort items so that entries for the same package are adjacent (no subheadings, just sorted order). Changes to the
remotioncore package should appear first - Strip redundant prefixes from PR titles (e.g. remove "Docs:" from items in the Docs section)
- Linkify items whose PR added a new documentation page: run
git diff --diff-filter=A --name-only v<previous_version>..v<new_version> -- 'packages/docs/docs/**/*.mdx' 'packages/docs/docs/**/*.md'to list added docs pages, map each added page to the PR that introduced it, and wrap that item's title in a markdown link to the page (e.g.* [<title>](https://remotion.dev/docs/<slug>) by @author in <url>). Determine the URL from the page'sslug:frontmatter if present, otherwise from its file path relative topackages/docs/docs/. Leave items without a new docs page unlinked. - "Templates" is a separate section for any template-* changes
- Check for genuinely new contributors by running
gh api repos/remotion-dev/remotion/contributors --paginate --jq '.[].login'and comparing against PR authors. Only add a "New Contributors" section for authors not in that list - Add
**Full Changelog**: https://github.com/remotion-dev/remotion/compare/v<previous_version>...v<new_version>at the bottom - Use the same format as previous GitHub releases (check with
gh release view v<previous_version>) - Don't release until you get approval. Allow me to edit it before. This does not block the npm steps: draft the changelog while npm scans packages, and continue with promotion, private publishing, pushes and templates without waiting.
- After approval, re-read
/tmp/release-<version>.md(I may have edited it) and rungh release create v<version> --title v<version> --notes-file /tmp/release-<version>.md --verify-tag.
- Run
-
Finally, delete the local copies of the npm token from the scratchpad. It expires by itself after 7 days.