From 2b4faea87b2905145ba89a7c1473e7ffc0477c33 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Mon, 2 Nov 2026 10:57:23 +0100 Subject: [PATCH] ci: every push to master is a release, the metainfo's newest A push to master published the build as the rolling `beta` branch and refreshed a `latest` prerelease; a tag cut the stable release. Now every push to master is the release: CI takes the version from the metainfo's newest , publishes `stable`, tags the pushed commit and creates the release with that entry's notes. A version that is released already fails the job before anything is built or published, and so does a lookup that cannot tell, so a push to master adds a new . Publishing is master's alone: a manual run on another branch builds and tests and cuts nothing. Tags are no longer a trigger, and the rolling `beta` and `latest` steps are gone. The README and AGENTS say so, and the first release's entry, 1.0.0, takes the date of its push and names what it ships. --- .forgejo/workflows/ci.yaml | 86 ++++++++----------- AGENTS.md | 2 +- README.md | 2 +- .../net.catcrafts.CrafterReview.metainfo.xml | 14 ++- 4 files changed, 47 insertions(+), 57 deletions(-) diff --git a/.forgejo/workflows/ci.yaml b/.forgejo/workflows/ci.yaml index 3665414..56b6970 100644 --- a/.forgejo/workflows/ci.yaml +++ b/.forgejo/workflows/ci.yaml @@ -2,11 +2,14 @@ # SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® name: Flatpak -# Crafter.Build's workflow, for this app. One job, three outcomes: +# Crafter.Build's workflow, for this app, with one change: every push to +# master is a release (2026-11-02: no rolling `beta` or `latest` builds). +# One job, two outcomes: # pull request -> build the Flatpak, run the suite inside it, smoke-test it -# push master -> also publish it as the `beta` branch of the Catcrafts -# repo and refresh the rolling `latest` release -# tag X.Y.Z -> publish it as `stable` and create release X.Y.Z +# push master -> also publish it as `stable` and cut release X.Y.Z, the +# metainfo's newest : its tag at the pushed commit +# and its notes. A version that is released already fails +# the job before anything is built or published. # # It builds on the Crafter.Build Flatpak (`base:` in the manifest), whose # crafter-build and LLVM compile this project, so the runner installs that @@ -27,7 +30,6 @@ on: branches: [master] push: branches: [master] - tags: ['[0-9]*.[0-9]*.[0-9]*'] workflow_dispatch: env: @@ -79,29 +81,22 @@ jobs: id: meta run: | set -eu - if [ "${GITHUB_REF_TYPE}" = tag ]; then - version="$GITHUB_REF_NAME" - branch=stable - # The metainfo's newest release is the release notes and must be - # the version being tagged. - top=$(grep -m1 -oP '&2 - exit 1 - fi - else - # Named after the release it follows, as a checkout describes - # itself: 1.0.0-3-g21746b1 is three commits past 1.0.0. - described=$(git describe --tags --always --exclude=latest) - case "$described" in - [0-9]*.[0-9]*.[0-9]*) version="$described" ;; - *) version="0.0.0-dev+$described" ;; + # The metainfo's newest release is the version and its notes. On + # master it must be new: its tag must not exist yet, and a lookup + # that cannot tell stops the job as well. + version=$(grep -m1 -oP ' /dev/null || code=$? + case "$code" in + 0) echo "the metainfo's newest release, $version, is released already: a push to master names a new in $METAINFO" >&2; exit 1 ;; + 2) ;; + *) echo "git ls-remote exited $code: cannot tell whether $version is released" >&2; exit 1 ;; esac - branch=beta fi echo "version=$version" >> "$GITHUB_OUTPUT" - echo "branch=$branch" >> "$GITHUB_OUTPUT" - echo "version $version, flatpak branch $branch" + echo "branch=stable" >> "$GITHUB_OUTPUT" + echo "version $version, flatpak branch stable" - name: Build # The manifest is rewritten beside the original so its relative @@ -163,9 +158,9 @@ jobs: if [ "$code" != 2 ]; then echo "the dry run exited $code, not 2" >&2; exit 1; fi ls scratch/*-dry/prompts | head -3' - # Everything below publishes and only runs on master and on tags. + # Everything below publishes and only runs on master. - name: Bundle - if: github.event_name != 'pull_request' + if: github.ref == 'refs/heads/master' run: | mkdir -p dist flatpak build-bundle repo "dist/crafter-review-${{ steps.meta.outputs.version }}.flatpak" "$APP_ID" "${{ steps.meta.outputs.branch }}" @@ -174,7 +169,7 @@ jobs: ls -la dist - name: Upload bundle - if: github.event_name != 'pull_request' + if: github.ref == 'refs/heads/master' uses: actions/upload-artifact@v3 with: name: crafter-review-${{ steps.meta.outputs.version }} @@ -182,7 +177,7 @@ jobs: if-no-files-found: error - name: Publish to the Catcrafts repo - if: github.event_name != 'pull_request' + if: github.ref == 'refs/heads/master' run: | set -eu if [ ! -s /run/crafter-flatpak/signing-key.asc ] || [ ! -s /run/crafter-flatpak/key-id ]; then @@ -208,29 +203,16 @@ jobs: sed "s|GPGKey=.*|GPGKey=$key|" packaging/flatpak/net.catcrafts.CrafterReview.flatpakref > "$WEB_DIR/net.catcrafts.CrafterReview.flatpakref" flock -u 9 - - name: Rolling 'latest' release - if: github.event_name != 'pull_request' && github.ref_type != 'tag' + - name: Tag the release + if: github.ref == 'refs/heads/master' run: | - git config user.email "ci@catcrafts.net" - git config user.name "Crafter Review CI" - git tag -f latest - git push origin latest --force - - name: Publish rolling 'latest' release - if: github.event_name != 'pull_request' && github.ref_type != 'tag' - uses: https://code.forgejo.org/actions/forgejo-release@v2 - with: - direction: upload - url: ${{ github.server_url }} - repo: ${{ github.repository }} - tag: latest - title: Latest master build - prerelease: true - override: true - release-dir: dist - token: ${{ secrets.GITHUB_TOKEN }} + # The release's tag at the pushed commit. Never forced: a tag that + # appeared since the version check fails the push. + git tag "${{ steps.meta.outputs.version }}" "$GITHUB_SHA" + git push origin "refs/tags/${{ steps.meta.outputs.version }}" - name: Release notes - if: github.ref_type == 'tag' + if: github.ref == 'refs/heads/master' run: | # The newest block's description as Markdown, the way # Crafter.Build's workflow writes its notes. @@ -261,14 +243,14 @@ jobs: print("\nInstall:\n\n flatpak remote-add --if-not-exists catcrafts https://flatpak.catcrafts.net/catcrafts.flatpakrepo\n flatpak install catcrafts net.catcrafts.CrafterReview\n") EOF - name: Publish release - if: github.ref_type == 'tag' + if: github.ref == 'refs/heads/master' uses: https://code.forgejo.org/actions/forgejo-release@v2 with: direction: upload url: ${{ github.server_url }} repo: ${{ github.repository }} - tag: ${{ github.ref_name }} - title: crafter-review ${{ github.ref_name }} + tag: ${{ steps.meta.outputs.version }} + title: crafter-review ${{ steps.meta.outputs.version }} release-notes-file: release-notes.md release-dir: dist token: ${{ secrets.GITHUB_TOKEN }} diff --git a/AGENTS.md b/AGENTS.md index ad16778..2f3cafb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -239,7 +239,7 @@ Runs and Commands drop every `REVIEW_GATES_*`, `CRAFTER_REVIEW_*`, `SEATS_ENV_FI `.forgejo/workflows/ci.yaml` is Crafter.Build's workflow for this app. - **Builds.** A pull request builds the Flatpak, runs the suite inside it and smoke-tests the app as it ships: the version and home, every library resolved and no RUNPATH outside `/app`, the bundled tools, and a freeze and a dry run on a scratch repository. -- **Publishing.** A push to master also publishes `beta`, and a tag `X.Y.Z` publishes `stable` and creates the release. The tag must equal the metainfo's newest ``. +- **Publishing.** Every push to master is a release (2026-11-02, Jorijn: no rolling `beta` or `latest` builds): CI publishes `stable`, tags the pushed commit with the version of the metainfo's newest `` and creates the release with its notes. A push to master therefore adds a new ``; one whose version is released already fails the job before anything is built or published. - **The runner.** It runs on the `crafter-flatpak` runner, registered to Crafter.Build alone today: until this repository has such a runner, the workflow does not run, and it is unverified on the forge. Its smoke test passes when run by hand against a local build. - **The shared repo.** Both apps publish into one repo. The publish step holds `/srv/flatpak/.publish.lock`, which protects anything only once Crafter.Build's workflow takes the same lock. This one writes its own flatpakref and never the shared `catcrafts.flatpakrepo`. diff --git a/README.md b/README.md index e65dc36..ac77d4f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ flatpak install catcrafts net.catcrafts.CrafterReview alias crafter-review='flatpak run net.catcrafts.CrafterReview' ``` -`master` builds are the `beta` branch (`net.catcrafts.CrafterReview//beta`). The alias is for people: the `/prepush` skill spells every command as `flatpak run net.catcrafts.CrafterReview …`, because Claude's Bash tool sees no aliases. +Every push to `master` is a release, published as `stable`. The alias is for people: the `/prepush` skill spells every command as `flatpak run net.catcrafts.CrafterReview …`, because Claude's Bash tool sees no aliases. What the machine provides: diff --git a/packaging/flatpak/net.catcrafts.CrafterReview.metainfo.xml b/packaging/flatpak/net.catcrafts.CrafterReview.metainfo.xml index d508e8b..9013fdf 100644 --- a/packaging/flatpak/net.catcrafts.CrafterReview.metainfo.xml +++ b/packaging/flatpak/net.catcrafts.CrafterReview.metainfo.xml @@ -27,10 +27,18 @@ - + -

First release: the pre-push review gates in C++26, shipped as a Flatpak.

-

Every lens is off until the repository's config turns it on. The commit-truth lens, repo-facts, reads the commit messages and the documentation of the range as Gate 4.

+

New

+
    +
  • Pre-push review gates for a commit range: Claude processes review the approach, the running application, a bug proof, security and the commit messages, and a range is send-ready only when every gate passes on its exact frozen hash.
  • +
  • crafter-review init sets a repository up: its config and the /prepush skill.
  • +
  • Modes in the repository's config (modes.<name>): the kind of artifact, the lenses it runs and their effort. Every lens is off until a mode lists it.
  • +
  • Seats from a dotenv file - --env-file, $SEATS_ENV_FILE, the working directory's .env or the machine's own ~/.config/crafter-review/env - over the environment's, on one seat board for every driver on a machine.
  • +
  • A repository's own section appended to a lens's charter (lenses.<name>.section).
  • +
  • Pre-send review of a kernel patch series or a mailing-list reply (--mode series, --mode reply).
  • +
  • Shipped as a Flatpak with its own git, Node and ripgrep.
  • +