Skip to content

Release from a ref and tag it from package.json - #215

Merged
frolic merged 2 commits into
mainfrom
frolic/release-from-ref
Jul 29, 2026
Merged

Release from a ref and tag it from package.json#215
frolic merged 2 commits into
mainfrom
frolic/release-from-ref

Conversation

@frolic

@frolic frolic commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Releasing took two steps: tag and push by hand, then run the workflow with a tag it checked already existed. This takes a ref instead — main by default — and creates the tag itself, so a release is one click from the Actions tab.

The tag now comes from that ref's package.json rather than being typed in. The two could previously disagree: you could tag 1.29.0 on a tree whose package.json said 1.28.0 and get a release whose contents don't match its name. That's what the "manifest.json matches the tag" check existed to catch, and deriving the version removes the failure mode rather than detecting it.

It refuses to run if the tag already exists, pointing at the version bump instead.

One knock-on worth reviewing: the push of the updated manifest.json and versions.json after a non-prerelease now names its branch explicitly, because the checkout is detached whenever ref isn't one. A bare git push would fail there anyway; naming it means the error says what to do. Releasing a real version from a tag or a commit now fails at that point, which seems right — those files have to land somewhere.

On changesets

Worth saying why this isn't that. Changesets solves version bookkeeping and changelogs; this solves release mechanics, which is what was actually awkward. Its publish step is also npm-shaped, while this plugin ships GitHub release assets consumed by Obsidian's registry plus a versions.json cascade — all of that bespoke logic would stay, with changesets bolted on for the version bump. Neither this repo nor the tldraw monorepo uses it today. Still a reasonable thing to want for the changelog, just a separate question from this.

Test plan

Can't be exercised without publishing, so it wants a careful read instead. The intended first run is the 1.30.0-alpha.1 prerelease already sitting on main:

  1. Actions → Manual Release → Run workflow, leave ref as main.
  2. Expect it to tag 1.30.0-alpha.1, build, and publish a prerelease.
  3. Expect no commit back to the repo and no versions.json entry, since it's a prerelease.
  4. Re-running it should fail early with "Tag 1.30.0-alpha.1 already exists".

Releasing took two steps: tag and push by hand, then run the workflow
with a tag it verified already existed. Now it takes a ref (main by
default), reads the version from that ref's package.json, and creates
the tag itself.

Deriving the tag from package.json means the two can't disagree — the
old flow could tag a release with a version the build wouldn't produce,
which is what the manifest-matches-tag check existed to catch.

The push of the updated manifest.json and versions.json now names its
branch, since the checkout is detached whenever ref isn't one. A real
release has to land those somewhere, so doing it from a tag or a bare
commit fails here instead of silently dropping them.
@frolic
frolic marked this pull request as ready for review July 29, 2026 10:43
A run that fails after tagging leaves the tag behind with nothing
released, and telling that person to bump the version is the wrong
advice. Cover both cases in the message.
@frolic
frolic merged commit cf445a1 into main Jul 29, 2026
1 check passed
@frolic
frolic deleted the frolic/release-from-ref branch July 29, 2026 10:46
@frolic frolic mentioned this pull request Jul 29, 2026
frolic added a commit that referenced this pull request Jul 29, 2026
Bumps the version so 1.30.0 can be released to everyone, rather than
only to BRAT users as `1.30.0-alpha.1` was.

What ships in it:

- **tldraw 5.2.5** (#212), so `.tldr` files saved by a current version
of tldraw open instead of failing with `Incompatible schema?` and an
empty tab — likely closing #184, #138, and the "corrupted file" report
on #193
- **`.tldraw` messaging** (#211): opening one from tldraw offline
explains why it can't be opened yet and links to the export
instructions, rather than landing on Obsidian's unknown-file screen
- the e2e suite now running in CI (#214) and a one-click release (#215)

`npm version` cascades the version into `release/manifest.json` and
`release/versions.json` on its own — the repo has a `version` lifecycle
script — so those changes are mechanical.

### One thing that isn't mechanical

This drops a `"1.29.1"` entry from `release/versions.json`. That version
was staged in b48442c and never released — there's no tag and no GitHub
release for it. It matters here because releasing a non-prerelease
copies `release/versions.json` over the root `versions.json`, which is
the file the plugin registry reads, so the phantom entry would have been
published. Everything in that file shares the same `minAppVersion`, so
it was unlikely to misresolve anyone's install, but it shouldn't go out
either way.

After this, `release/versions.json` matches the published file exactly
apart from the new `1.30.0` line.

### Release plan

Merge, then Actions → Manual Release → Run workflow with `ref: main`.
Unlike the alpha, this path adds the `versions.json` entry and pushes
the manifest commit back, which is what makes it visible to everyone on
the community plugin list.

### Worth knowing before merging

`1.30.0-alpha.1` was published but, as far as I know, never installed
and exercised through BRAT. So the evidence behind this release is the
CI suite (8 behaviours, including opening a current `.tldr`, the theme,
the edit round trip, view mode and embeds) plus manual checks in a
scratch vault — not a soak on a real vault. Mobile is untested by
anything.
frolic added a commit that referenced this pull request Jul 29, 2026
Release notes came from the tagged commit, and since #215 the workflow
creates that tag itself — so the notes ended up being whatever landed
last. The alpha shipped carrying #215's own description, which had
nothing to do with what was in the release.

This generates them instead, from the pull requests merged since the
last full release.

The start tag comes from `repos/{repo}/releases/latest`, which skips
prereleases and drafts. That matters here: without it, 1.30.0's notes
would be computed against `1.30.0-alpha.1` and come out nearly empty,
rather than listing everything since 1.29.0 — the version people are
actually on.

Generated notes are a floor, not a ceiling. They list merged PRs by
title, which is a reasonable default; a release worth describing still
wants a hand-written top, via `gh release edit` or the GitHub UI.

## Test plan

Can't be exercised without publishing. Next release should open with a
"What's Changed" list of the PRs merged since 1.29.0, rather than a copy
of the previous PR's description.
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