Archived
Move releases to GitHub, with one bridge release on Gitea
GitHub has no generic package registry, so releases become GitHub release assets. The updater and install.sh read releases/latest/download and releases/download/<v>/, plain redirects with no API rate limit. make release publishes a draft with all assets, then makes it latest. make release-gitea publishes the same version to the old Gitea registry for binaries that still update from there, and refuses until GitHub serves it. See D33. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
---
|
||||
name: release
|
||||
description: Prepare and publish a submarine release. Finds the latest release, picks the next semver from the changes since, runs a release check, creates and pushes the git tag, hands over to the developer for `make release`, then creates the Gitea release with MCP. Use only when the user asks to release.
|
||||
description: Prepare and publish a submarine release. Finds the latest release, picks the next semver from the changes since, runs a release check, creates and pushes the git tag, writes the release notes, hands over to the developer for `make release`, then verifies the GitHub release. Use only when the user asks to release.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Release submarine
|
||||
|
||||
A release is built on the developer's machine (`make release`, see
|
||||
`docs/architecture.md#distribution`). `make release` publishes the binaries
|
||||
of the **clean `vX.Y.Z` tag at HEAD** to the Gitea package registry. This
|
||||
skill does everything around it. The developer runs `make release`
|
||||
themselves, in the middle: you never run it and never read or print `.env`
|
||||
or `GITEA_TOKEN`.
|
||||
`docs/architecture.md#distribution`). `make release` creates the GitHub
|
||||
release of the **clean `vX.Y.Z` tag at HEAD**, with the binaries as assets.
|
||||
This skill does everything around it. The developer runs `make release`
|
||||
themselves, in the middle: you never run it and never read or print `.env`,
|
||||
`GH_TOKEN` or `GITEA_TOKEN`.
|
||||
|
||||
Pushing a tag and creating a release are outward-facing and hard to undo.
|
||||
Do them only after the confirmation in step 5, and never force-push, move or
|
||||
delete a tag without asking.
|
||||
|
||||
Gitea: owner `simonfranken`, repo `submarine`, `https://git.simon-franken.de`.
|
||||
GitHub: owner `simonfranken`, repo `submarine`, remote `origin`.
|
||||
|
||||
## 1. Preconditions
|
||||
|
||||
@@ -29,7 +29,7 @@ git branch --show-current # main
|
||||
git status --porcelain # empty: make release refuses a dirty tree
|
||||
git rev-parse HEAD origin/main # equal: HEAD is pushed, nothing to release from a local-only commit
|
||||
git tag --points-at HEAD # empty: HEAD is not released yet
|
||||
grep -q '^GITEA_TOKEN=.\+' .env # exists: only test it, never print it
|
||||
gh auth status >/dev/null 2>&1 || grep -q '^GH_TOKEN=.\+' .env # one holds: only test, never print
|
||||
```
|
||||
|
||||
## 2. Latest release
|
||||
@@ -38,11 +38,12 @@ grep -q '^GITEA_TOKEN=.\+' .env # exists: only test it, never print i
|
||||
git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -1
|
||||
```
|
||||
|
||||
Cross-check with the `mcp__gitea__get_latest_release` MCP tool (load it with
|
||||
ToolSearch first). If the tag and the Gitea release differ (a tag without a
|
||||
Cross-check with the `mcp__github__get_latest_release` MCP tool (load it with
|
||||
ToolSearch first). If the tag and the GitHub release differ (a tag without a
|
||||
release is normal for the one in progress, a release without a tag is not),
|
||||
tell the user and ask before going on. With no tag at all, the first release
|
||||
is `v0.1.0`.
|
||||
is `v0.1.0`. While the Makefile has `release-gitea` (step 10), GitHub has
|
||||
no releases yet: cross-check with `mcp__gitea__get_latest_release` instead.
|
||||
|
||||
## 3. Changes since
|
||||
|
||||
@@ -55,7 +56,7 @@ No commits since the last tag: stop, there is nothing to release. Read the
|
||||
commits, and where a subject is not clear, the diff. Sort each change as:
|
||||
|
||||
- **breaking**: removes or changes a key, a command or flag, the on-disk or
|
||||
registry contract (`install.sh`, asset names, `submarine-latest/latest/VERSION`,
|
||||
release contract (`install.sh`, asset names, `latest/download/VERSION`,
|
||||
`submarine update`), or behavior users rely on;
|
||||
- **feature**: a new key, action, view or option, or a visible behavior;
|
||||
- **fix / other**: bug fixes, docs, refactoring, tests, performance.
|
||||
@@ -108,51 +109,64 @@ git ls-remote --tags origin vX.Y.Z # the tag is on the remote
|
||||
If the push fails, report git's message. Do not retry with force. If the tag
|
||||
is wrong after it was pushed, ask before deleting it.
|
||||
|
||||
## 7. Hand over: the developer runs `make release`
|
||||
## 7. Write the release notes
|
||||
|
||||
Write them to `/tmp/submarine-vX.Y.Z-notes.md` (outside the repository:
|
||||
`make release` refuses a dirty tree). They are for users of the tool, not a
|
||||
commit dump: short, grouped under **Breaking changes** (only if any),
|
||||
**New**, **Fixes** (leave out empty groups and pure refactoring/tests), each
|
||||
item one line naming the key or behavior (`b` switches the branch of a
|
||||
repository...). End with:
|
||||
|
||||
```
|
||||
Install or update: `curl -fsSL https://raw.githubusercontent.com/simonfranken/submarine/main/install.sh | sh`, or `submarine update`.
|
||||
|
||||
Full changelog: https://github.com/simonfranken/submarine/compare/<last>...vX.Y.Z
|
||||
```
|
||||
|
||||
Show the notes to the user; they can change them before the next step.
|
||||
|
||||
## 8. Hand over: the developer runs `make release`
|
||||
|
||||
HEAD is now the clean tag, which is what `make release` needs. Tell the
|
||||
developer to run, in the repository:
|
||||
|
||||
```sh
|
||||
make release
|
||||
make release NOTES=/tmp/submarine-vX.Y.Z-notes.md
|
||||
```
|
||||
|
||||
(it reads `GITEA_TOKEN` from `.env`, tests, builds, uploads, and points
|
||||
`submarine-latest` at the version last). **Stop here and wait** until they
|
||||
say it finished. If it failed, help with the output; do not run it yourself.
|
||||
(it uses `gh`, tests, builds, creates the release as a draft with all
|
||||
assets and publishes it last). **Stop here and wait** until they say it
|
||||
finished. If it failed, help with the output; do not run it yourself. A
|
||||
leftover draft from a failed run must be deleted (ask first) before a retry.
|
||||
|
||||
## 8. Verify the upload, create the Gitea release
|
||||
## 9. Verify the release
|
||||
|
||||
Once the developer reports success:
|
||||
|
||||
```sh
|
||||
curl -fsSL https://github.com/simonfranken/submarine/releases/latest/download/VERSION
|
||||
```
|
||||
|
||||
must print `vX.Y.Z` (this is what `install.sh` and `submarine update`
|
||||
read). Check with `mcp__github__get_release_by_tag` that it is not a draft
|
||||
and has the assets `submarine_{linux,darwin}_{amd64,arm64}`,
|
||||
`checksums.txt` and `VERSION`. If anything is missing, report it. Finish
|
||||
with the link to the release and the version.
|
||||
|
||||
## 10. Bridge release (only while the Makefile has `release-gitea`)
|
||||
|
||||
The first GitHub release is also published to the old Gitea registry, so
|
||||
binaries that still update from Gitea pick it up (D33). After step 9, and
|
||||
after asking the user, push the tag to the `gitea` remote and hand over
|
||||
again:
|
||||
|
||||
```sh
|
||||
git push gitea main vX.Y.Z
|
||||
make release-gitea # run by the developer, needs GITEA_TOKEN
|
||||
curl -fsS https://git.simon-franken.de/api/packages/simonfranken/generic/submarine-latest/latest/VERSION
|
||||
```
|
||||
|
||||
must print `vX.Y.Z` (the registry is public; `install.sh` reads it the same
|
||||
way). If it doesn't, the upload did not complete: do not create the release,
|
||||
report it.
|
||||
|
||||
Then create the release with `mcp__gitea__create_release` (load it with
|
||||
ToolSearch first):
|
||||
|
||||
- `owner`: `simonfranken`, `repo`: `submarine`
|
||||
- `tag_name`: `vX.Y.Z`
|
||||
- `target`: the tag's commit, `git rev-parse vX.Y.Z^{commit}`
|
||||
- `title`: `vX.Y.Z`
|
||||
- `is_draft`: false, `is_pre_release`: false
|
||||
- `body`: release notes, see below
|
||||
|
||||
Release notes are for users of the tool, not a commit dump: short, grouped
|
||||
under **Breaking changes** (only if any), **New**, **Fixes** (leave out empty
|
||||
groups and pure refactoring/tests), each item one line naming the key or
|
||||
behavior (`b` switches the branch of a repository...). End with:
|
||||
|
||||
```
|
||||
Install or update: `curl -fsSL https://git.simon-franken.de/simonfranken/submarine/raw/branch/main/install.sh | sh`, or `submarine update`.
|
||||
|
||||
Full changelog: https://git.simon-franken.de/simonfranken/submarine/compare/<last>...vX.Y.Z
|
||||
```
|
||||
|
||||
The binaries live in the package registry, not on the release: attach
|
||||
nothing. Finish with the link to the release and the version.
|
||||
The last command must print `vX.Y.Z`. Then create a Gitea release for the
|
||||
tag with `mcp__gitea__create_release`, its body saying that submarine moved
|
||||
to https://github.com/simonfranken/submarine.
|
||||
|
||||
Reference in New Issue
Block a user