Skip to content

ci: release with sem instead of legacy semantic-release - #19

Merged
spacedevin merged 1 commit into
mainfrom
ci/sem-release
Aug 27, 2026
Merged

ci: release with sem instead of legacy semantic-release#19
spacedevin merged 1 commit into
mainfrom
ci/sem-release

Conversation

@spacedevin

Copy link
Copy Markdown
Owner

Every other repo that cuts releases this way runs tishlang/sem; deck was the odd one out, still on semantic-release with the whole prerelease flow written by hand.

The git workflow is unchanged — a green main cuts a prerelease carrying the tarballs, and promoting it fires npm-release.yml and crates-release.yml. Only the machinery moves.

What this deletes

Most of the value. The old release job hand-rolled:

  • a release/vX branch, force-pushed each run
  • a changelog built by git log against the last tag
  • raw curl calls to the releases API, including a "422 means it already exists, go fetch its id and PATCH it" retry path
  • two more curls to upload the tarballs as assets

@sem/github does all of that, so ~190 lines of workflow collapse into plugin config. Net: 288 lines changed in ci.yml, and package-lock.json sheds ~6,300 lines as the semantic-release toolchain leaves devDependencies (the action carries its own).

Two things carried over from chuggie-engine, because they aren't obvious

  • git identity is configured before sem runs. A tag is a commit-shaped object and actions/checkout sets none, so sem fails with Committer identity unknown. That exact failure is why chuggie-engine had zero releases for months despite green builds.
  • issues: write@sem/github opens an issue when a release throws, and without the permission the real error is buried under a 403 from the issues API.

Licence gate

I also brought over that repo's licence gate — which was written about this repo:

crates.io has no delete — only yank — and npm unpublish is a 72-hour window, so an artifact published under the wrong licence is effectively permanent. (This is not hypothetical: @spacedevin/deck shipped two versions under the wrong licence and both had to be yanked.)

It now refuses to build an artifact unless both LICENSE and packages/player/LICENSE are present. The second of those only started existing in #18 — before that the player tarball asserted a licence it didn't ship.

Config

.releaserc.json.semrc.json, @semantic-release/*@sem/*. The two-package lockstep packing is unchanged: same version on both, player's dependency stamped to ^<version> before packing.

Verification

npm ci from a clean node_modules succeeds without the semantic-release packages, and npm test is green (100% coverage, 13 conformance cases, 14 example blocks, Tish VM suite, JS smoke). Both inline sem configs and the workflow itself parse as YAML, with release still gated on [test, rust_crate, release_check].

The release path itself can only really be exercised on a main push — worth watching the first run after merge.

Every other repo that cuts releases this way runs tishlang/sem; deck was the
odd one out, still on semantic-release with the whole prerelease flow written by
hand. Same git workflow either way — green main cuts a prerelease carrying the
tarballs, promoting it fires npm-release.yml and crates-release.yml — but the
machinery is now the shared one.

What that deletes is most of the point. The release job had been hand-rolling a
`release/vX` branch, a `git log` changelog, and raw curl calls to the releases
API with a 422-means-it-exists retry path and separate asset uploads. `@sem/github`
does all of it, so ~190 lines of workflow become a plugin config.

Two things carried over from chuggie-engine's setup because they are not obvious:

- git identity is configured before sem runs. A tag is a commit-shaped object and
  actions/checkout sets no identity, so sem dies on "Committer identity unknown".
  That failure is why chuggie-engine had zero releases for months.
- `issues: write`, because @sem/github opens an issue when a release throws.
  Without it the real error is buried under a 403 from the issues API.

Also added the licence gate from that repo, since this is the repo whose two
mispublished versions it was written about — it now refuses to build an artifact
unless both LICENSE files are present.

.releaserc.json becomes .semrc.json, and the semantic-release toolchain leaves
devDependencies entirely: the action carries its own, so npm ci drops ~500
transitive packages.
@spacedevin
spacedevin merged commit 187923e into main Aug 27, 2026
5 checks passed
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