From 492710bfa59ed629e91518ef6070de0843021f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Wed, 26 Aug 2026 15:27:21 +0200 Subject: [PATCH] Build a revision once, not once per repository A push to master here fires the announcement, and autobuilds describes that revision, builds the lock through this repository's own reusable workflow, and publishes what comes out. Since the hand-written matrix went, the build this workflow runs on such a push is the same lock, the same ten legs and the same code -- done twice, at the same time, in two repositories. It was worth having when the two were different paths, because two paths give two signals. They are one path now, so the second run is only cost: four full builds were in flight at once this afternoon, half of them copies. The build stays on every pull request, which is where it is the signal that decides whether something merges. On master the signal is the autobuilds run, and that one also says whether the revision is releasable, which this one never could. --- .github/workflows/build.yml | 6 ++++ tests/ci/test-single-matrix.sh | 57 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c5b2c6..29e9207 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,6 +76,12 @@ jobs: # because its macOS leg had never run the code that publishes one. build: needs: describe + # Not on a push to master: that push is announced to autobuilds, which + # describes the same revision, builds the same lock through the same + # reusable workflow, and publishes what comes out. Building it here as + # well is the same ten legs twice, and the copy that says whether the + # revision is releasable is the one over there. + if: github.event_name != 'push' || github.ref != 'refs/heads/master' uses: ./.github/workflows/build-sdk.yml with: lock: ${{ needs.describe.outputs.lock }} diff --git a/tests/ci/test-single-matrix.sh b/tests/ci/test-single-matrix.sh index f037209..c4a3821 100755 --- a/tests/ci/test-single-matrix.sh +++ b/tests/ci/test-single-matrix.sh @@ -67,6 +67,63 @@ for runner in sorted({host["runner"] for host in hosts} - {"ubuntu-24.04"}): print(f"build.yml names the runner {runner!r}; cmake/hosts.json is where runners are declared") if "cmake/toolchains/" in text: print("build.yml names a cross toolchain file; build-host.sh is where a host is built") + +# And it must not run that one path twice. A push to master is announced to +# autobuilds, which describes the same revision and builds the same lock, so +# building it here too is the same legs over again. +def evaluate(expression, context): + tokens = re.findall(r"'[^']*'|\|\||&&|==|!=|[A-Za-z0-9_.-]+", expression) + position = 0 + + def take(): + nonlocal position + position += 1 + return tokens[position - 1] + + def primary(): + token = take() + if token.startswith("'"): + return token[1:-1] + value = context + for part in token.split("."): + value = value.get(part, "") if isinstance(value, dict) else "" + return value + + def comparison(): + left = primary() + if position < len(tokens) and tokens[position] in ("==", "!="): + operator = take() + right = primary() + return left == right if operator == "==" else left != right + return left + + def conjunction(): + value = comparison() + while position < len(tokens) and tokens[position] == "&&": + take() + right = comparison() + value = right if value else value + return value + + value = conjunction() + while position < len(tokens) and tokens[position] == "||": + take() + right = conjunction() + value = value if value else right + return value + + +def runs_on(event_name, ref): + condition = str(jobs[caller].get("if", "")).strip() + if not condition: + return True + return bool(evaluate(condition, {"github": {"event_name": event_name, "ref": ref}})) + + +if runs_on("push", "refs/heads/master"): + print("a push to master builds here as well as in autobuilds; that is the same lock twice") +if not runs_on("pull_request", "refs/pull/1/merge"): + print("a pull request no longer builds, which is the only place this build is the signal") PYEOF )