Skip to content
Draft
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
18 changes: 18 additions & 0 deletions .github/path-filters/aws-ci.paths
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# The build paths for .github/workflows/aws-ci.yml. Moved out of that
# workflow's trigger blocks so the gate job is reported on every pull
# request - see scripts/changed_paths.py and issue #632.

deploy/aws/template.yaml
deploy/aws/lightsail-template.yaml
docs/index.html
docs/vendor/**
scripts/ws_smoke.py
scripts/check_lightsail_userdata.py
scripts/check_docs_vendor.py
bin/agentbox
tests/test_agentbox.py
tests/native/**
.github/path-filters/aws-ci.paths
scripts/changed_paths.py
.github/workflows/aws-ci.yml
.github/workflows/deploy-test.yml
9 changes: 9 additions & 0 deletions .github/path-filters/azure-ci.paths
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# The build paths for .github/workflows/azure-ci.yml. Moved out of that
# workflow's trigger blocks so the gate job is reported on every pull
# request - see scripts/changed_paths.py and issue #632.

deploy/azure/**
scripts/check_azure_template.py
.github/path-filters/azure-ci.paths
scripts/changed_paths.py
.github/workflows/azure-ci.yml
69 changes: 69 additions & 0 deletions .github/path-filters/ci.paths
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# The build paths for .github/workflows/ci.yml.
#
# This list used to be the workflow's own `on: push/pull_request: paths:`
# block. It moved here because a trigger-level filter reports NO check run
# on a pull request it does not match, which makes the check unrequireable
# (issue #632) - see scripts/changed_paths.py for the whole reasoning. The
# workflow's `changes` job reads this file; its `gate` job reports either
# way.
#
# Blank lines and `#` comments are ignored. The dialect is GitHub's own
# `paths` glob, so an entry moved here from a trigger block needs no
# rewriting.

**.nix

# Sources of the generated modules/agent-box.nix (issue #140): a change
# here can reassemble to the same bytes (a pure refactor), so it would
# not touch a *.nix file - match them explicitly so the module-generated-
# up-to-date guard (and the rest of CI) still runs.
modules/agent-box.nix.in
modules/src/**
bin/assemble-module.py
tests/test-assemble-module.py

# The vendored third-party assets under modules/src/vendor are matched
# by 'modules/src/**' above; this is the checker that verifies them.
scripts/check_vendor.py

# Every workflow, not just this one: CI validates no other workflow's
# YAML, so a file that cannot parse is simply never run and nothing
# says so. PR #483 shipped exactly that - vendor-updates.yml had a
# heredoc dedented out of its `run: |` block scalar, CI stayed green,
# and the weekly job would have silently never fired.
.github/workflows/**

# The path filters themselves, and the matcher that reads them. Editing
# one of these decides which jobs run at all, so it has to run the jobs
# (issue #632).
.github/path-filters/**
scripts/changed_paths.py
tests/test-changed-paths.py

tests/test-envstore.py

# The native-render fixture (issue #154 Phase 4): the renderer under
# test, the test itself, and its committed expected/ snapshot must all
# re-run agentbox-render when any one changes, or a stale fixture only
# surfaces via a manual dispatch (as it did for PR #381).
bin/agentbox
tests/test_agentbox.py
tests/native/**

# The mascot mark (issue #185) is embedded into the settings daemon at
# assemble time, so it is a module source as much as a website asset.
docs/potato.svg

# The golden behavior snapshot (issue #154): the fixture and its
# renderer must re-run the golden-snapshot check when either changes.
bin/golden-snapshot.py
tests/golden/**

# The release manifest (issue #632) is what promotion records and what
# publish-template.yml consumes instead of re-resolving anything, so its
# builder and its tests are build paths like any other checked script.
scripts/release_manifest.py
tests/test-release-manifest.py

flake.lock
.github/workflows/ci.yml
94 changes: 80 additions & 14 deletions .github/workflows/aws-ci.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
name: AWS template CI

on:
# No `paths:` filter here, on purpose (issue #632): a
# trigger-level filter means the workflow never STARTS on a
# change it does not match, and a workflow that never starts
# reports no check run at all - so the check cannot be
# required without leaving unrelated pull requests pending
# forever. The filter lives in .github/path-filters/aws-ci.paths,
# read by the `changes` job; the `gate` job reports either
# way and is the check to require.
push:
branches: [ master ]
paths: &aws-ci-paths
- 'deploy/aws/template.yaml'
- 'deploy/aws/lightsail-template.yaml'
- 'docs/index.html'
- 'docs/vendor/**'
- 'scripts/ws_smoke.py'
- 'scripts/check_lightsail_userdata.py'
- 'scripts/check_docs_vendor.py'
- 'bin/agentbox'
- 'tests/test_agentbox.py'
- 'tests/native/**'
- '.github/workflows/aws-ci.yml'
- '.github/workflows/deploy-test.yml'
pull_request:
paths: *aws-ci-paths
workflow_dispatch:

concurrency:
Expand All @@ -28,8 +22,41 @@ permissions:
contents: read

jobs:
# Cheap, always runs, and decides for the expensive job below (issue
# #632). Its own failure is a gate failure: "we could not work out
# whether the checks were needed" must never read as "they passed".
changes:
name: Decide whether AWS template CI's build paths changed
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
build: ${{ steps.filter.outputs.build }}
steps:
- uses: actions/checkout@v5
with:
# Both ends of the range have to be IN the clone; the default
# depth-1 checkout has neither a pull request's base nor a
# push's `before`.
fetch-depth: 0

- name: Match the changed paths against the filter
id: filter
env:
# HEAD for both events: on a pull request actions/checkout leaves
# the MERGE commit checked out, whose merge base with base.sha is
# base.sha itself, so `base...HEAD` is exactly the pull request's
# own diff.
BASE: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
run: |
answer=$(python3 scripts/changed_paths.py \
.github/path-filters/aws-ci.paths --base "$BASE" --head HEAD)
echo "build=$answer" >> "$GITHUB_OUTPUT"
echo "::notice::AWS template CI build paths changed: $answer"

validate:
name: Validate AWS template and smoke helper
needs: changes
if: needs.changes.outputs.build == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -66,3 +93,42 @@ jobs:
# loads would otherwise ship to the public site with nothing to catch it.
- name: Check docs/vendor pins
run: python3 scripts/check_docs_vendor.py

# THE check to require in the branch ruleset (issue #632): reported on
# every push and every pull request, whatever paths they touch, so it
# can never be the required-but-never-reported check that leaves a pull
# request permanently unmergeable.
gate:
name: AWS template gate
needs: [ changes, validate ]
if: always()
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Report the aggregate result
env:
CHANGES: ${{ needs.changes.result }}
VALIDATE: ${{ needs.validate.result }}
BUILD: ${{ needs.changes.outputs.build }}
run: |
echo "changes=$CHANGES build=$BUILD validate=$VALIDATE"
if [ "$CHANGES" != "success" ]; then
echo "::error::the changes job did not succeed ($CHANGES), so nothing here knows whether the checks were needed."
exit 1
fi
case "$VALIDATE" in
success)
echo "AWS template CI passed."
;;
skipped)
if [ "$BUILD" = "true" ]; then
echo "::error::the build paths changed but validate was skipped - the guard expression on that job is wrong."
exit 1
fi
echo "No relevant path changed; AWS template CI had nothing to run."
;;
*)
echo "::error::validate did not pass ($VALIDATE)."
exit 1
;;
esac
85 changes: 80 additions & 5 deletions .github/workflows/azure-ci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
name: Azure template CI

on:
# No `paths:` filter here, on purpose (issue #632): a
# trigger-level filter means the workflow never STARTS on a
# change it does not match, and a workflow that never starts
# reports no check run at all - so the check cannot be
# required without leaving unrelated pull requests pending
# forever. The filter lives in .github/path-filters/azure-ci.paths,
# read by the `changes` job; the `gate` job reports either
# way and is the check to require.
push:
branches: [ master ]
paths: &azure-ci-paths
- 'deploy/azure/**'
- 'scripts/check_azure_template.py'
- '.github/workflows/azure-ci.yml'
pull_request:
paths: *azure-ci-paths
workflow_dispatch:

concurrency:
Expand All @@ -19,8 +22,41 @@ permissions:
contents: read

jobs:
# Cheap, always runs, and decides for the expensive job below (issue
# #632). Its own failure is a gate failure: "we could not work out
# whether the checks were needed" must never read as "they passed".
changes:
name: Decide whether Azure template CI's build paths changed
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
build: ${{ steps.filter.outputs.build }}
steps:
- uses: actions/checkout@v5
with:
# Both ends of the range have to be IN the clone; the default
# depth-1 checkout has neither a pull request's base nor a
# push's `before`.
fetch-depth: 0

- name: Match the changed paths against the filter
id: filter
env:
# HEAD for both events: on a pull request actions/checkout leaves
# the MERGE commit checked out, whose merge base with base.sha is
# base.sha itself, so `base...HEAD` is exactly the pull request's
# own diff.
BASE: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
run: |
answer=$(python3 scripts/changed_paths.py \
.github/path-filters/azure-ci.paths --base "$BASE" --head HEAD)
echo "build=$answer" >> "$GITHUB_OUTPUT"
echo "::notice::Azure template CI build paths changed: $answer"

validate:
name: Validate the Azure Bicep template
needs: changes
if: needs.changes.outputs.build == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -48,3 +84,42 @@ jobs:
# leaves the extension's protectedSettings.
- name: Check the compiled template and the bootstrap it carries
run: python3 scripts/check_azure_template.py

# THE check to require in the branch ruleset (issue #632): reported on
# every push and every pull request, whatever paths they touch, so it
# can never be the required-but-never-reported check that leaves a pull
# request permanently unmergeable.
gate:
name: Azure template gate
needs: [ changes, validate ]
if: always()
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Report the aggregate result
env:
CHANGES: ${{ needs.changes.result }}
VALIDATE: ${{ needs.validate.result }}
BUILD: ${{ needs.changes.outputs.build }}
run: |
echo "changes=$CHANGES build=$BUILD validate=$VALIDATE"
if [ "$CHANGES" != "success" ]; then
echo "::error::the changes job did not succeed ($CHANGES), so nothing here knows whether the checks were needed."
exit 1
fi
case "$VALIDATE" in
success)
echo "Azure template CI passed."
;;
skipped)
if [ "$BUILD" = "true" ]; then
echo "::error::the build paths changed but validate was skipped - the guard expression on that job is wrong."
exit 1
fi
echo "No relevant path changed; Azure template CI had nothing to run."
;;
*)
echo "::error::validate did not pass ($VALIDATE)."
exit 1
;;
esac
Loading
Loading