ci: require --tag for releases, route v3 template PRs to 3.x#16360
Merged
ci: require --tag for releases, route v3 template PRs to 3.x#16360
Conversation
- tools/releaser/src/release.ts: abort if --tag is missing; abort if --tag=latest (disallowed during v4 beta phase so v4 cannot displace v3 on npm latest). - .github/workflows/post-release-templates.yml: route by release tag prefix. v3.* releases check out 3.x and target base: 3.x; v4+ releases continue to use main. Prior behavior regenerated templates from main's v4 source for any release, which would produce a wrong PR for v3 patches published from 3.x.
- Pass github.event.release.tag_name via env, not shell interpolation
- Validate the tag against a semver regex before fanning out into outputs
- Pass tag as $RELEASE_TAG to downstream shell steps instead of ${{ … }}
Hardcode --tag beta in package.json release script and add guards in tools/releaser/src/release.ts: require main branch, require 4.x root version, require prerelease identifier matching --tag. Print branch in the pre-release summary.
Contributor
📦 esbuild Bundle Analysis for payloadThis analysis was generated by esbuild-bundle-analyzer. 🤖
Largest pathsThese visualization shows top 20 largest paths in the bundle.Meta file: packages/next/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js
Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js
DetailsNext to the size is how much the size has increased or decreased compared with the base branch of this PR.
|
Member
Author
|
Template failure are expected and can be ignored. |
DanRibbens
approved these changes
Apr 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Main-side tooling for the v4 beta phase. Harden
pnpm releaseagainst accidentally publishing tolatest, pin the script to v4-on-main, route the post-release templates workflow by release major so v3 patches (published from3.x) produce the right PR on the right branch, and close script-injection patterns in that workflow.Companion to the pending
3.xcutover. No functional changes to Payload itself.Key Changes
tools/releaser/src/release.ts— v4 beta release guards--tagis missing. Previously an omitted tag flowed intopnpm publish --tag undefinedand published to a literalundefineddist-tag.--tag latestis passed. During the v4 beta phase, v4 must publish tobetaso it cannot displace v3 onlatest.main.package.jsonversion is4.x.--tagdisagree (e.g.,-beta.Nwith--tag canary).package.json— pinreleasescript to--tag betapnpm releasenow passes--tag betadirectly. The releaser still enforces the guards above; this removes the foot-gun at the call site..github/workflows/post-release-templates.yml— route by release tagtarget_branchfrom the release tag:v3.*→3.x, everything else →main.update_templateschecks outtarget_branch, so templates are regenerated from the source that corresponds to the released major.basetargetstarget_branchinstead of hardcodedmain. A v3 patch produces a templates PR against3.x; a v4 release produces one againstmain.workflow_dispatchstill works; it usesgit describeto pick the latest non-v2 tag and routes the same way..github/workflows/post-release-templates.yml— harden release-tag handlinggithub.event.release.tag_namethroughenv:rather than interpolating${{ … }}directly intorun:blocks (closes the classic GHA script-injection pattern).${{ … release_tag }}shell interpolations with$RELEASE_TAGfromenv:.Design Decisions
package.jsonscript pins--tag beta; the releaser enforces branch, major, and version/tag coherence on top. Either layer alone catches the common mistake; together they cover directtsx src/release.tsinvocations, stale local checkouts, and copy-pasted commands.latestrather than default tobetainside the script. Explicit caller intent; Phase 2 revert is a small deletion. No branch-detection or magic defaults inside the releaser.mainand4.x, not a generic "active branch" check. v3 releases have moved offmain. The guards describe the current phase rather than infer it.latest. Prevents the symmetric foot-gun (-beta.N+--tag canary, or-canary.N+--tag beta) without a separate list of invalid combinations.mainonly.release: publishedevents run the workflow from the repo default branch regardless, so the file does not need to exist on3.x. It only needs to check out3.xwhen handling a v3 release.determine_tagstep means all downstream outputs, branch names, and PR inputs inherit a safe character set without repeating validation.post-release.yml,publish-prerelease.yml,main.yml,templates.ts, or docs. The release-commenter's existingtag-filter: 'v\d'already partitions v3/v4. Nightly canary cron is disabled in a separate prior commit and is expected to be re-enabled when v4 dev ramps up.Overall Flow
flowchart TD A[pnpm release --bump X] --> B{--tag provided?} B -- no --> X1[abort] B -- yes --> C{tag == latest?} C -- yes --> X2[abort] C -- no --> D{branch == main?} D -- no --> X3[abort] D -- yes --> E{version matches 4.x with prerelease?} E -- no --> X4[abort] E -- yes --> F{prerelease id == tag?} F -- no --> X5[abort] F -- yes --> G[publish to specified dist-tag] R[GitHub release published] --> V{tag matches semver?} V -- no --> X6[abort] V -- yes --> W{tag starts with v3?} W -- yes --> H[checkout 3.x, regen templates, PR base=3.x] W -- no --> I[checkout main, regen templates, PR base=main]