diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 66f94e8..ef5b6df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -113,7 +113,7 @@ jobs: Install it from the marketplace: \`\`\`sh - termcade add aviorstudio/$GAME@$VERSION + termcade add aviorstudio/$GAME \`\`\` \`\`\` @@ -128,3 +128,38 @@ jobs: "$GAME/build/$GAME.tcade" \ "$GAME/build/$GAME.tcade.sha256" \ --target "$GITHUB_SHA" --title "$GAME $VERSION" --notes-file notes.md + + # Tell the marketplace the release exists. + # + # After the GitHub release, not before: publishing is a claim that a + # package is at these coordinates, and the registry verifies it by + # fetching. Claiming first would have it fetch something that is not + # there yet. + # + # A scoped publish key rather than a password. It publishes as + # aviorstudio and can do nothing else — not read a library, not mint + # another key, not touch an account — so what a leak costs is bounded by + # this one handle. + # + # Skipped when the secret is absent, so a release still cuts on a fork or + # before the key exists. The registry can always be told later; a release + # that failed after tagging is much harder to unpick. + # + # The secret is read into the environment and the step decides from + # there, rather than through a step-level `if` on the secrets context — + # that is the kind of expression that evaluates to something unhelpful + # instead of failing loudly, and a publish step which silently never ran + # would leave the marketplace quietly out of date. + - name: Publish to the marketplace + env: + TERMCADE_TOKEN: ${{ secrets.TERMCADE_TOKEN }} + GAME: ${{ inputs.game }} + TAG: ${{ steps.version.outputs.tag }} + run: | + set -euo pipefail + if [ -z "${TERMCADE_TOKEN:-}" ]; then + echo "::warning::TERMCADE_TOKEN is not set — the release exists on GitHub, but the marketplace has not been told about it. Publish it by hand with: termcade publish https://github.com/$GITHUB_REPOSITORY $TAG $GAME.tcade" + exit 0 + fi + go run github.com/aviorstudio/termcade@v0.0.4 publish \ + "https://github.com/$GITHUB_REPOSITORY" "$TAG" "$GAME.tcade" diff --git a/README.md b/README.md index ff5516d..e51bad0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ before it has an account or a network. They install the ordinary way too: ```sh termcade add aviorstudio/asteroid termcade add aviorstudio/tetris -termcade add aviorstudio/brickough@0.0.1 # or pin a version +termcade add aviorstudio/brickough ``` The source stays here rather than in the arcade so the two move separately — @@ -26,6 +26,21 @@ these three happening to use it. To refresh the vendored packs after changing a game, from a termcade checkout beside this one: `go generate ./internal/starter`. +## Releasing + +`release.yml` builds a game, tags it, cuts a GitHub release, and tells the +marketplace about it — in that order, because publishing is a claim the +registry verifies by fetching, so the asset has to exist first. + +That last step needs a `TERMCADE_TOKEN` secret: a publish key scoped to the +`aviorstudio` handle, made with `termcade keys new`. It publishes and nothing +else — it cannot read a library, mint another key, or touch an account — so a +leak is bounded by this one handle. + +Without the secret the release still cuts and the workflow warns, with the +command to publish by hand. A release that failed after tagging is much harder +to unpick than one the registry has not heard about yet. + ## The games | Game | What it is |