Skip to content

feat(boxel-cli): auto-publish unstable per merge, repurpose manual workflow as stable promoter#4804

Draft
FadhlanR wants to merge 2 commits into
mainfrom
cs-11112-auto-publish-boxel-cli-unstable-per-merge-and-unblock
Draft

feat(boxel-cli): auto-publish unstable per merge, repurpose manual workflow as stable promoter#4804
FadhlanR wants to merge 2 commits into
mainfrom
cs-11112-auto-publish-boxel-cli-unstable-per-merge-and-unblock

Conversation

@FadhlanR
Copy link
Copy Markdown
Contributor

Summary

Closes CS-11112.

PR-time enforcement for boxel-cli shrinks to "write a conventional PR title." Every merge to main touching packages/boxel-cli/** auto-publishes @cardstack/boxel-cli@<v>-unstable.<n> to npm under dist-tag unstable (Ember canary pattern). Stable releases stay deliberate via the repurposed manual workflow, which promotes the latest unstable to latest.

What changes

  • PR-time: .github/workflows/boxel-cli-pr-title.yml (new) validates the PR title via amannn/action-semantic-pull-request, path-scoped to packages/boxel-cli/**. Four old CI gates in ci-lint.yaml (lines 128-224) are removed — no more local regen, no more hand-bumping plugin.json.
  • Merge-time: .github/workflows/boxel-cli-on-main.yml (new) regenerates plugin/skills/, fetches the merged PR's title via gh api repos/.../commits/<sha>/pulls, classifies the bump, applies per-surface version updates, commits back with [skip ci], tags, and publishes to npm. Concurrency-serialized to prevent prerelease-counter collisions.
  • Stable promotion: .github/workflows/manual-boxel-cli-publish.yml repurposed — strips -unstable.N, publishes under latest, tags, creates a non-prerelease GitHub Release. Input is now a confirm: 'promote' typed string.
  • Logic: packages/boxel-cli/scripts/compute-release.ts (new) is the pure decision engine. Maps PR-title prefix → bump level, checks per-surface (src/ vs plugin/), handles prerelease base escalation (e.g. 0.1.5-unstable.X + breaking change → 1.0.0-unstable.<n>). 29 vitest cases.
  • Docs: plugin/README.md Versioning + Releasing rewritten for the new flow, including the BOXEL_SKILLS_VERSION fix(skills): caveat. AGENTS.md gains a "boxel-cli commit prefixes" subsection.
  • Seed: package.json bumped 0.1.40.1.5-unstable.0 so the first auto-publish after this merges has a clean starting state.

Test plan

  • pnpm test:unit covers compute-release logic — 29 / 29 passing.
  • pnpm lint clean.
  • Dry-run: PR_TITLE='feat: test' pnpm exec ts-node --transpileOnly scripts/compute-release.ts emits valid JSON.
  • Post-merge (will happen automatically): this PR's own merge fires boxel-cli-on-main.yml. Expected behavior:
    • PR title feat(boxel-cli): … → minor bump.
    • npm surface touched (scripts/compute-release.ts, tests/scripts/, package.json) → 0.1.5-unstable.0 escalates to 0.2.0-unstable.<n>, publishes to npm under unstable.
    • plugin surface touched (plugin/README.md) → plugin.json 0.1.40.2.0.
  • Follow-up validation: open a tiny fix: PR touching src/ once this lands; verify it publishes 0.2.0-unstable.<n+1>.
  • Follow-up validation: trigger manual-boxel-cli-publish.yml with confirm: promote; verify it strips the suffix and publishes latest.

Notes for reviewer

  • The PR-title check is not marked as a required status check on main. Required path-filtered checks would leave non-boxel-cli PRs pending forever — discussed in the plan doc.
  • Loop safety is belt + suspenders: bot commit ends [skip ci] AND the workflow job guards if: github.actor != 'github-actions[bot]'.
  • Concurrency group boxel-cli-release is shared with the manual workflow so a stable promotion can't race an auto unstable publish.
  • See docs/cs-11112-auto-publish-boxel-cli-unstable-plan.md for the implementation plan; ~/.claude/plans/let-s-work-on-cs-11112-floofy-hippo.md (local) has the design rationale and decision log.

FadhlanR added 2 commits May 13, 2026 11:25
…rkflow as stable promoter

Closes CS-11112.

PR-time enforcement shrinks to "conventional PR title" — no more local
regen, no more hand-bumping plugin.json, no more four-gate CI block.
On every merge to main that touches packages/boxel-cli/**, a new on-main
workflow regenerates plugin/skills/, computes per-surface bumps from the
merged PR title (fetched via gh api), commits back to main, and publishes
@cardstack/boxel-cli@<v>-unstable.<n> under npm dist-tag `unstable`.
Stable releases stay deliberate — the renamed manual workflow promotes
the latest unstable to `latest` rather than cutting fresh.

- .github/workflows/boxel-cli-pr-title.yml — new; amannn/action-semantic-pull-request, path-scoped to boxel-cli
- .github/workflows/boxel-cli-on-main.yml — new; regen + compute-release + bump + tag + publish, concurrency-serialized
- .github/workflows/manual-boxel-cli-publish.yml — repurposed: strip -unstable.N, publish under latest
- .github/workflows/ci-lint.yaml — drop the four boxel-cli verification gates (lines 128-224); plain pnpm run lint stays
- packages/boxel-cli/scripts/compute-release.ts — new; pure function + I/O wrapper. Handles prerelease base escalation.
- packages/boxel-cli/tests/scripts/compute-release.test.ts — 29 vitest cases
- packages/boxel-cli/plugin/README.md — rewrite Versioning + Releasing for the new flow
- AGENTS.md — add "boxel-cli commit prefixes" subsection
- packages/boxel-cli/package.json — seed 0.1.4 → 0.1.5-unstable.0
- docs/cs-11112-auto-publish-boxel-cli-unstable-plan.md — implementation plan doc
The seed bump to 0.1.5-unstable.0 (and subsequent auto-unstable versions
like 0.2.0-unstable.7) broke the strict /^\d+\.\d+\.\d+$/ regex. Accept
optional semver prerelease tail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant