Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@ name: release
# Nothing is uploaded before them: the build job refuses every dispatch
# until both environments exist and are limited so. Then, for each release:
# 1. The release commit passes `tests` ON ITSELF, in a push or dispatch
# run of tests.yml. On main, the push run that landed it does that
# when that run finished green; one that failed does not, nor one
# that a later landing cancelled (each landing cancelled the one
# before until #593). Otherwise, and always on a `release/v<X.Y>`
# branch, which no push run tests: BEFORE TAGGING, dispatch tests.yml
# on a branch that points at the release commit, and wait for it:
# run of tests.yml. The push run that landed it on main, or that its
# push to a `release/v<X.Y>` branch started (once the branch holds
# #850's tests.yml, which runs on both), does that when that run
# finished green; one that failed does not, nor one that a later
# landing cancelled (each landing cancelled the one before until
# #593). A commit that came to a release branch by fast-forward
# already has main's push run. Once the branch holds #850's tests.yml,
# the fast-forward also starts the branch's own push run on that
# commit, and that newer run decides. Tag once it has finished green.
# Otherwise, for a commit that no finished green run tested: BEFORE
# TAGGING, dispatch tests.yml on a branch that points at the release
# commit, and wait for it:
# git push origin <release-commit>:refs/heads/<branch>
# gh workflow run tests.yml --ref <branch> -R opensoft/openRepoShape
# A `release/v<X.Y>` branch serves while it is still at that commit.
Expand All @@ -55,6 +61,27 @@ name: release
# A version is uploaded once. A bad upload is fixed by the next patch, never
# by moving a tag (decision 4).
#
# RELEASE BRANCHES AND BACK-PORTS (#850), on Brett Heap's ruling at
# 2026-10-17T19:52:26Z, "back-port to release/v1.1 as 1.1.1, open the issue":
# - main stays the trunk, and every change lands there first; a release
# is its annotated tag, never a branch;
# - `release/v<X.Y>` is cut at the tag `v<X.Y>.0`, and each patch
# `v<X.Y>.<Z>` is tagged on it;
# - a fix for a patch lands on main first, through its own review, CI and
# gate, and is then back-ported to `release/v<X.Y>`: by a fast-forward
# to main while main holds only the patch's work, and otherwise by a
# pull request to `release/v<X.Y>` of `git cherry-pick -x <squash>`,
# the squash commit main landed. The fast-forward stands unless a
# `release/*` ruleset requires a pull request (that ruleset waits on
# Brett Heap's word, #850); then every back-port is the cherry-pick;
# - a push runs the tests.yml its own commit holds, so a release branch
# runs it only once it holds #850's change: `release/v1.1` from its
# first fast-forward past it, or a cherry-pick of it; `release/v1.0`
# never has, and still needs a dispatch (step 1);
# - the patch is tagged on `release/v<X.Y>` once step 1 holds for that
# commit (its tests.yml runs have all finished and the newest is green),
# then released by steps 2 to 5.
#
# DISPATCH ONLY. Nothing here runs on a push, a tag or a pull request: an
# upload is an act Brett Heap approves. The version is the tag's (decision
# 4): `v1.1.0` gives `1.1.0`, which the build writes into the stamp,
Expand Down
61 changes: 42 additions & 19 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,61 @@ name: tests
# clones them over the filesystem. It never calls `gh`, never touches the
# network, and must never create a real repository.
#
# The FULL suite runs on LINUX ONLY, on every trigger: a push to `main`, a pull
# request and a manual run all use the one ubuntu job below. Brett Heap decided
# on 2026-10-15, for the whole estate, to drop the macOS and Windows test jobs.
# The FULL suite runs on LINUX ONLY, on every trigger: a push to `main` or to a
# release branch (`release/v<major>.<minor>`), a pull request and a manual run
# all use the one ubuntu job below. Brett Heap decided on 2026-10-15, for the
# whole estate, to drop the macOS and Windows test jobs.
# One exception, on Brett Heap's word at 2026-10-15T18:20:35Z,
# "Option 1: keep a small Git Bash job for #596": the `tests-git-bash` job
# below runs the launcher's and the installer's suites, and nothing else, on
# Windows under Git Bash.
#
# A RELEASE BRANCH'S PUSHES RUN IT TOO (#850). A patch is tagged on its
# `release/v<major>.<minor>` branch, and `release.yml` releases a commit only
# once a push or dispatch run of this workflow passed `tests` on it, so a
# commit a release branch takes gets that run from its own push, with no
# dispatch by hand. `release/v*` takes each of them, and any other name of one
# segment that starts `release/v`: in a branch filter `*` matches no `/`.
# A push runs the tests.yml its own commit holds, so a release branch runs it
# only once it holds this change: `release/v1.1` from its first fast-forward
# past it, or a cherry-pick of it; `release/v1.0` never has, and still needs a
# dispatch.
#
# The `package` job at the end runs no pytest. It builds the openreposhape
# wheel and installs it with pipx, so what it checks needs PyPI (the build
# backend, git-filter-repo; #563). The other jobs take only test tools there.

on:
push:
branches: [main]
branches: [main, 'release/v*']
pull_request:
workflow_dispatch:

# A RUN IS CANCELLED ONLY BY A NEWER RUN IN ITS OWN GROUP: a newer push to the
# same pull request, or a second dispatch on the same commit. A pull request's
# group is its number. A `push` run on main has no number, and the old fallback
# `github.ref` put every one of them in the one group `tests-refs/heads/main`,
# so each landing cancelled the run on the main before it: on 2026-10-15 every
# push run from #561 (7d9bec9) to #580 (dd3f23a) ended `cancelled` and nine PRs
# landed with no Linux run over their combination (#592). `github.sha` gives a
# push run a group of its own commit, so no later landing cancels it and each
# landing keeps its own Linux result. `github.event_name` keeps a push run and
# a dispatch apart, so a dispatch on main, which runs on whatever commit main
# is at, never cancels that commit's push run; a second dispatch on the same
# commit still replaces the first.
# same pull request, or a second dispatch of the same ref at the same commit.
# A pull request's group is its ref and its number. A `push` run on main has
# no number, and the old fallback `github.ref` put every one of them in the
# one group `tests-refs/heads/main`, so each landing cancelled the run on the
# main before it: on 2026-10-15 every push run from #561 (7d9bec9) to #580
# (dd3f23a) ended `cancelled` and nine PRs landed with no Linux run over their
# combination (#592). `github.sha` gives a push run a group of its own commit,
# so no later landing cancels it and each landing keeps its own Linux result.
# `github.event_name` keeps a push run and a dispatch apart, so a dispatch on
# main, which runs on whatever commit main is at, never cancels that commit's
# push run; a second dispatch of the same ref at the same commit still
# replaces the first.
#
# `github.ref` KEEPS TWO BRANCHES APART AT ONE COMMIT (#850). A group spans
# the repository, not a branch, and a push run's `github.sha` is the commit
# the push left its branch at. Without the ref, a fast-forward of
# `release/v1.1` to main's commit shares the group of main's push run on that
# commit and cancels it while it is still running, as #592's landings did.
# The ref sits beside the commit, never in its place as #592's fallback did.
# A pull request's ref, `refs/pull/<number>/merge`, is its own, so a pull
# request still has one group, and a newer push to it still cancels the older
# run.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.sha }}
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true

jobs:
Expand Down Expand Up @@ -158,9 +181,9 @@ jobs:
# Git's real `curl` ahead of the suites' fake. conftest's comment there
# has the rest.
#
# ON EVERY TRIGGER, a push to `main` included: a squash lands a tree no
# pull-request run tested (#122), and these two suites are the only run
# of the one-line install on Windows.
# ON EVERY TRIGGER, a push to `main` or to a release branch included: a
# squash lands a tree no pull-request run tested (#122), and these two
# suites are the only run of the one-line install on Windows.
tests-git-bash:
runs-on: windows-latest
timeout-minutes: 15
Expand Down
8 changes: 8 additions & 0 deletions tests/test_release_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,14 @@ def test_the_header_says_how_to_release(workflow):
assert "# ACCEPTED LIMITS, carried over from openDox-code's release.yml" \
in text
assert "lane\n# sessions act as brettheap" in text
# #850's section, and the two sentences RV852 asked it to carry: a push
# runs the tests.yml its own commit holds, and the branch's newer push run
# decides after a fast-forward.
assert "# RELEASE BRANCHES AND BACK-PORTS (#850)" in text
assert "# - a push runs the tests.yml its own commit holds, so a release" \
in text
assert "and that newer run decides. Tag once it has finished green." \
in text


# --- RV599, SHOULD 2: the commit is on main or its release branch -------------------
Expand Down
Loading
Loading