|
| 1 | +--- |
| 2 | +description: 'Maintain Plate''s latest and beta release lanes end-to-end with an autogoal plan: promote next to main, sync main directly back into next, repair release metadata conflicts, re-enter beta, and verify npm/GitHub release state.' |
| 3 | +argument-hint: '[status | sync | promote | verify | full]' |
| 4 | +--- |
| 5 | + |
| 6 | +# Release Lanes |
| 7 | + |
| 8 | +Use this when the user asks to maintain Plate `latest` and `beta`, promote beta |
| 9 | +to stable, sync `main` into `next`, recover release lane drift, verify npm |
| 10 | +dist-tags, or run the release lane after a stable release. |
| 11 | + |
| 12 | +## Core Take |
| 13 | + |
| 14 | +CI owns publishing. This skill owns lane maintenance. |
| 15 | + |
| 16 | +Do not create a routine `main -> next` sync PR. That path creates review churn |
| 17 | +for deterministic release metadata conflicts. Sync directly with a merge commit, |
| 18 | +repair known release metadata automatically, push `next`, then let `release.yml` |
| 19 | +publish beta. |
| 20 | + |
| 21 | +One invocation is permission to run the lane until completion. Ask again only |
| 22 | +for hard stops. |
| 23 | + |
| 24 | +## Autogoal Contract |
| 25 | + |
| 26 | +This is a derived autogoal skill. |
| 27 | + |
| 28 | +Default flow mode: one-shot execution. |
| 29 | + |
| 30 | +Use: |
| 31 | + |
| 32 | +```bash |
| 33 | +node .agents/skills/autogoal/scripts/create-goal-scratchpad.mjs \ |
| 34 | + --template release-lanes \ |
| 35 | + --title "release lane maintenance" |
| 36 | +``` |
| 37 | + |
| 38 | +Create or continue a goal before mutating remote release branches. The goal is |
| 39 | +complete only when the requested lane state is true and the template gates pass. |
| 40 | + |
| 41 | +## Lanes |
| 42 | + |
| 43 | +- `main` publishes stable packages with npm tag `latest`. |
| 44 | +- `next` publishes prerelease packages with npm tag `beta`. |
| 45 | +- `.changeset/pre.json` belongs on `next` only. |
| 46 | +- `main` must never publish while `.changeset/pre.json` exists. |
| 47 | +- Major changesets target `next` for beta before stable promotion. |
| 48 | +- Minor changesets target `main`, not `next`. |
| 49 | +- Patch changes may target `main`; use `next` patch changes only for active |
| 50 | + beta-lane fixes or direct-sync beta metadata. |
| 51 | + |
| 52 | +## Modes |
| 53 | + |
| 54 | +### Status |
| 55 | + |
| 56 | +Read state only: |
| 57 | + |
| 58 | +```bash |
| 59 | +git fetch origin main next |
| 60 | +gh pr list --base main --head next --state open --json number,title,url,state |
| 61 | +gh run list --workflow release.yml --branch main --limit 5 \ |
| 62 | + --json databaseId,status,conclusion,createdAt,url |
| 63 | +gh run list --workflow release.yml --branch next --limit 5 \ |
| 64 | + --json databaseId,status,conclusion,createdAt,url |
| 65 | +npm view platejs dist-tags --json |
| 66 | +``` |
| 67 | + |
| 68 | +Record: |
| 69 | + |
| 70 | +- `origin/main` SHA |
| 71 | +- `origin/next` SHA |
| 72 | +- whether `origin/next:.changeset/pre.json` exists and has tag `beta` |
| 73 | +- latest GitHub release |
| 74 | +- npm `platejs` dist-tags for `latest` and `beta` |
| 75 | +- open promote PR, if any |
| 76 | +- stale `sync/main-to-next` PRs, if any |
| 77 | + |
| 78 | +### Sync Main To Next |
| 79 | + |
| 80 | +Run after a stable release, after merging a promote PR, or whenever `main` has |
| 81 | +commits missing from `next`. |
| 82 | + |
| 83 | +Dry run first: |
| 84 | + |
| 85 | +```bash |
| 86 | +node tooling/scripts/release-branch-prs.mjs sync-main-to-next --dry-run |
| 87 | +``` |
| 88 | + |
| 89 | +Then run the direct sync: |
| 90 | + |
| 91 | +```bash |
| 92 | +node tooling/scripts/release-branch-prs.mjs sync-main-to-next --push |
| 93 | +``` |
| 94 | + |
| 95 | +The script must: |
| 96 | + |
| 97 | +- fetch `main` and `next` |
| 98 | +- refuse real direct sync when the checkout has local tracked or untracked |
| 99 | + changes |
| 100 | +- create a merge commit on `next` |
| 101 | +- keep `next` beta package versions over `main` stable versions |
| 102 | +- keep `.changeset/pre.json` from `next`, or create beta pre mode in the same |
| 103 | + sync commit when `next` is out of pre mode after promotion |
| 104 | +- insert or refresh stable changelog sections from `main` |
| 105 | +- create patch changesets for public packages changed by the synced `main` |
| 106 | + commits so the beta lane can publish those fixes |
| 107 | +- run `pnpm ci:version` before committing when beta changesets are generated, |
| 108 | + so `next` receives versioned beta package metadata instead of a pending |
| 109 | + Version Packages PR |
| 110 | +- use a `[skip release]` sync commit only when no beta changesets were generated |
| 111 | +- verify the merge commit with `verify-main-to-next-sync` |
| 112 | +- push directly to `origin/next` |
| 113 | + |
| 114 | +If the script stops on files outside known release metadata, do not guess. |
| 115 | +Resolve only when source ownership is obvious; otherwise stop with exact files. |
| 116 | + |
| 117 | +### Re-Enter Beta |
| 118 | + |
| 119 | +After a beta-to-stable promotion, `next` may be out of prerelease mode. The |
| 120 | +direct `main -> next` sync restores beta pre mode in the same unskipped merge |
| 121 | +commit, so the next release workflow can publish the generated beta changesets. |
| 122 | + |
| 123 | +Use a standalone beta re-entry commit only when no direct sync is needed and no |
| 124 | +beta changesets need publication: |
| 125 | + |
| 126 | +```bash |
| 127 | +git switch next |
| 128 | +git pull --ff-only origin next |
| 129 | +pnpm changeset pre enter beta |
| 130 | +git add .changeset/pre.json |
| 131 | +git commit -m "chore: enter beta pre-release mode [skip release]" |
| 132 | +git push origin next |
| 133 | +``` |
| 134 | + |
| 135 | +If `.changeset/pre.json` already exists with `{ "mode": "pre", "tag": "beta" }`, |
| 136 | +record N/A and do not create a duplicate commit. |
| 137 | + |
| 138 | +### Promote Beta To Stable |
| 139 | + |
| 140 | +Run dry first unless the user explicitly asks for the real promotion: |
| 141 | + |
| 142 | +```bash |
| 143 | +gh workflow run promote.yml --ref next -f dry_run=true |
| 144 | +gh run watch <run-id> --exit-status |
| 145 | +``` |
| 146 | + |
| 147 | +For a real promotion: |
| 148 | + |
| 149 | +```bash |
| 150 | +gh workflow run promote.yml --ref next -f dry_run=false |
| 151 | +gh run watch <run-id> --exit-status |
| 152 | +``` |
| 153 | + |
| 154 | +Then review the generated `next -> main` PR: |
| 155 | + |
| 156 | +- base `main` |
| 157 | +- head `next` |
| 158 | +- no `.changeset/pre.json` |
| 159 | +- package versions are stable, not `-beta.*` |
| 160 | +- body tells maintainers to use **Create a merge commit** |
| 161 | + |
| 162 | +Merging the promote PR is allowed when the user asked for full automation or |
| 163 | +merge. Use a merge commit, not squash or rebase. |
| 164 | + |
| 165 | +### Verify Releases |
| 166 | + |
| 167 | +Watch release workflows: |
| 168 | + |
| 169 | +```bash |
| 170 | +gh run list --workflow release.yml --branch main --limit 5 \ |
| 171 | + --json databaseId,status,conclusion,createdAt,url |
| 172 | +gh run list --workflow release.yml --branch next --limit 5 \ |
| 173 | + --json databaseId,status,conclusion,createdAt,url |
| 174 | +``` |
| 175 | + |
| 176 | +Verify npm: |
| 177 | + |
| 178 | +```bash |
| 179 | +npm view platejs dist-tags --json |
| 180 | +npm view platejs@latest version |
| 181 | +npm view platejs@beta version |
| 182 | +``` |
| 183 | + |
| 184 | +Verify GitHub releases: |
| 185 | + |
| 186 | +```bash |
| 187 | +gh release list --limit 10 |
| 188 | +``` |
| 189 | + |
| 190 | +## Stale PR Cleanup |
| 191 | + |
| 192 | +Close stale `sync/main-to-next` PRs after direct sync succeeds: |
| 193 | + |
| 194 | +```bash |
| 195 | +gh pr list --base next --head sync/main-to-next --state open --json number,url |
| 196 | +gh pr close <number> --comment "Closing because release-lanes synced main directly into next." |
| 197 | +``` |
| 198 | + |
| 199 | +Do this only after direct sync and verification pass. |
| 200 | + |
| 201 | +## Hard Stops |
| 202 | + |
| 203 | +Stop only for: |
| 204 | + |
| 205 | +- missing GitHub or npm auth needed for the requested live action |
| 206 | +- real source conflicts outside package manifests, changelogs, and |
| 207 | + `.changeset/pre.json` |
| 208 | +- release workflow failure after one clear retry or repair attempt |
| 209 | +- npm `latest` or `beta` points at an unexpected version after publication |
| 210 | +- branch protection rejects the required merge or push |
| 211 | +- local tracked or untracked changes are present before a real direct sync |
| 212 | + |
| 213 | +Do not stop to ask whether to run the next obvious lane step. The goal plan is |
| 214 | +the authorization boundary. |
| 215 | + |
| 216 | +## Handoff |
| 217 | + |
| 218 | +Report: |
| 219 | + |
| 220 | +- `main` SHA and `next` SHA |
| 221 | +- promote PR URL or N/A |
| 222 | +- direct sync result and pushed commit |
| 223 | +- beta pre mode state |
| 224 | +- release run URLs |
| 225 | +- npm `latest` and `beta` versions |
| 226 | +- stale PR cleanup |
| 227 | +- residual risk or `none` |
0 commit comments