From 19d6e69b2e24e7a18c7d4c8600b029eb4ba44235 Mon Sep 17 00:00:00 2001 From: Elijah Ben Izzy Date: Mon, 11 May 2026 09:24:41 -0700 Subject: [PATCH 1/2] ci: gate merging on a single Release Validation summary job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a "summary" job to release-validation.yml that depends on check-paths, build-artifacts, and install-and-smoke and runs with if: always(). It translates the upstream conclusions into a single binary verdict — success/skipped → pass, failure or cancelled → fail — so the required check has a stable name and a definite state regardless of whether upstream jobs ran or were path-filtered out. In .asf.yaml the required contexts drop from two matrix-suffixed names ("Release Validation / build-artifacts", "Release Validation / install-and-smoke (3.12)") to one: "Release Validation / summary". Why this is needed: - PRs that only touch docs/ or website/ trigger check-paths to set should_run=false, which skips the heavy jobs. - GitHub treats SKIPPED jobs as non-passing for required-status- checks, so those PRs were stuck in BLOCKED state forever (see commit a655edf2 for the previous attempt that didn't work for this exact reason). - The summary job sidesteps the SKIPPED ambiguity because it always runs and always produces a definite SUCCESS or FAILURE. Real code PRs are unaffected: if any release-validation job fails, the summary fails, and merging is blocked. --- .asf.yaml | 9 ++++--- .github/workflows/release-validation.yml | 30 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.asf.yaml b/.asf.yaml index 1c342d43..344bbcf6 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -62,10 +62,13 @@ github: required_status_checks: # strict means "Require branches to be up to date before merging". strict: false - # contexts are the names of checks that must pass + # The Release Validation workflow ends in a single "summary" job that + # runs with if: always() and translates upstream SUCCESS or SKIPPED + # into a definite SUCCESS, FAILURE into FAILURE. That gives us one + # stable required check name regardless of whether the upstream jobs + # ran (real code PR) or were path-filtered out (docs/website PR). contexts: - - "Release Validation / build-artifacts" - - "Release Validation / install-and-smoke (3.12)" + - "Release Validation / summary" required_pull_request_reviews: dismiss_stale_reviews: false require_code_owner_reviews: false diff --git a/.github/workflows/release-validation.yml b/.github/workflows/release-validation.yml index 6271cd80..a1872db3 100644 --- a/.github/workflows/release-validation.yml +++ b/.github/workflows/release-validation.yml @@ -193,3 +193,33 @@ jobs: path: /tmp/burr-smoke-* retention-days: 7 if-no-files-found: ignore + + # Single stable required-check name. Always runs (if: always()) so it produces + # a definite SUCCESS or FAILURE — never SKIPPED. Branch protection in + # .asf.yaml requires this context, not the underlying jobs, so path-filtered + # docs/website PRs (where the upstream jobs are skipped) still go green here. + summary: + name: "Release Validation / summary" + needs: [check-paths, build-artifacts, install-and-smoke] + if: always() + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Verdict + env: + CHECK_PATHS: ${{ needs.check-paths.result }} + BUILD_ARTIFACTS: ${{ needs.build-artifacts.result }} + INSTALL_AND_SMOKE: ${{ needs.install-and-smoke.result }} + run: | + echo "check-paths: $CHECK_PATHS" + echo "build-artifacts: $BUILD_ARTIFACTS" + echo "install-and-smoke: $INSTALL_AND_SMOKE" + # Pass if every needed job is success or skipped; fail if any + # failed or was cancelled. + for r in "$CHECK_PATHS" "$BUILD_ARTIFACTS" "$INSTALL_AND_SMOKE"; do + case "$r" in + success|skipped) ;; + *) echo "::error::Release Validation failed (one or more jobs not success/skipped)"; exit 1 ;; + esac + done + echo "Release Validation: all upstream jobs success or skipped." From cfc77a58aca16d02ed097c214b65578c9185d196 Mon Sep 17 00:00:00 2001 From: Elijah Ben Izzy Date: Mon, 11 May 2026 11:10:03 -0700 Subject: [PATCH 2/2] style: run black on burr/core/graph.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drive-by fix — `f7a1750d` (rename shadowed `format` builtin) left this file black-non-compliant for line-length=100. Caught by pre-commit on this branch. --- burr/core/graph.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/burr/core/graph.py b/burr/core/graph.py index b31e1cab..c5c4dfaa 100644 --- a/burr/core/graph.py +++ b/burr/core/graph.py @@ -107,9 +107,7 @@ def _render_graphviz( graphviz_obj.render(path_without_suffix, format=fmt, view=view) else: # `.pipe()` doesn't append the format to the filename, so we do it explicitly - pathlib.Path(f"{path_without_suffix}.{fmt}").write_bytes( - graphviz_obj.pipe(format=fmt) - ) + pathlib.Path(f"{path_without_suffix}.{fmt}").write_bytes(graphviz_obj.pipe(format=fmt)) @dataclasses.dataclass