Compare commits

...
6 Commits
Author SHA1 Message Date
dev-agent d0fde2f136 Merge pull request 'CI: a newer run cancels the one it supersedes' (#126) from ci-concurrency into main
CI / checks (push) Successful in 2m16s
CI / e2e (push) Skipped
2026-10-08 03:48:08 +00:00
dongarandClaude Opus 5.5 8840facceb CI: drop the temporary event job
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m50s
CI / e2e (pull_request) Successful in 4m33s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
2026-10-08 03:41:17 +00:00
dongarandClaude Opus 5.5 b80225d821 CI: tell e2e:full label events by the PR's labels
CI / checks (push) Skipped
CI / event (pull_request) Successful in 3s
CI / checks (pull_request) Skipped
CI / e2e (pull_request) Skipped
Gitea leaves github.event.label empty.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
2026-10-08 03:40:36 +00:00
dongarandClaude Opus 5.5 8bfc1e5f24 CI: Gitea's label events are label_updated in the payload
CI / checks (push) Skipped
CI / e2e (pull_request) Canceled after 27s
CI / event (pull_request) Successful in 2s
CI / checks (pull_request) Successful in 1m50s
Temporarily prints the event, to check what Gitea sends.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
2026-10-08 03:38:05 +00:00
dongarandClaude Opus 5.5 9c181d973a Development Plan: superseded runs are cancelled by CI now
CI / checks (push) Skipped
CI / e2e (pull_request) Canceled after 0s
CI / checks (pull_request) Canceled after 1m33s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
2026-10-08 03:36:19 +00:00
dongarandClaude Opus 5.5 ef29a1271e CI: a newer run cancels the one it supersedes
CI / checks (push) Skipped
CI / e2e (pull_request) Canceled after 0s
CI / checks (pull_request) Canceled after 23s
Workflow-level concurrency, per PR or branch, with cancel-in-progress.
The earlier attempt (job-level, on the e2e job) didn't cancel anything;
Gitea documents the workflow-level form. A label other than e2e:full
starts a run whose jobs all skip, so it gets a group of its own and
can't cancel the real run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
2026-10-08 03:36:02 +00:00
2 changed files with 28 additions and 8 deletions

No files matched your search

+26 -6
View File
@@ -18,13 +18,33 @@ on:
# Manual re-run, e.g. after rotating a credential or raising a budget cap. # Manual re-run, e.g. after rotating a credential or raising a budget cap.
workflow_dispatch: workflow_dispatch:
# A newer run for the same PR or branch cancels the one it supersedes: there
# is one runner, so a stale run would hold it (and the GPU) to the end. Adding
# a label other than e2e:full starts a run whose jobs all skip; it gets a
# group of its own, so it can't cancel the real one.
#
# Gitea triggers on `labeled` but hands the workflow its own name for the
# action, `label_updated` (and `synchronized` for a push), so each check
# below accepts both. Nor does it say which label was added
# (`github.event.label` is empty), so a label event counts when the PR now
# has e2e:full; adding another label to an e2e:full PR restarts its run.
concurrency:
group: >-
${{ github.workflow }}-${{ github.head_ref || github.ref }}${{
((github.event.action == 'labeled' || github.event.action == 'label_updated')
&& !contains(github.event.pull_request.labels.*.name, 'e2e:full'))
&& format('-label-{0}', github.run_id) || '' }}
cancel-in-progress: true
env: env:
# Full on e2e:full, and outside PRs. # Full on e2e:full, and outside PRs.
FULL: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'e2e:full') }} FULL: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'e2e:full') }}
jobs: jobs:
checks: checks:
if: github.event.action != 'labeled' || github.event.label.name == 'e2e:full' if: >-
(github.event.action != 'labeled' && github.event.action != 'label_updated')
|| contains(github.event.pull_request.labels.*.name, 'e2e:full')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -76,13 +96,13 @@ jobs:
# services, every role on a local model, so it spends nothing but keeps # services, every role on a local model, so it spends nothing but keeps
# the RTX 4090 busy: ~10 minutes for the smoke tests, ~25+ for all. On # the RTX 4090 busy: ~10 minutes for the smoke tests, ~25+ for all. On
# PRs and manual runs, and only after the checks pass: a PR that's red # PRs and manual runs, and only after the checks pass: a PR that's red
# already doesn't spend the GPU. There is one runner and Gitea doesn't # already doesn't spend the GPU. A newer push cancels a run it supersedes
# honour cancel-in-progress, so a run a newer push supersedes holds the # (concurrency, above). Locally, run only what you're writing (-k) or
# runner until it's cancelled by hand. Locally, run only what you're # diagnosing (--lf).
# writing (-k) or diagnosing (--lf).
if: >- if: >-
github.event_name != 'push' github.event_name != 'push'
&& (github.event.action != 'labeled' || github.event.label.name == 'e2e:full') && ((github.event.action != 'labeled' && github.event.action != 'label_updated')
|| contains(github.event.pull_request.labels.*.name, 'e2e:full'))
needs: checks needs: checks
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 90 timeout-minutes: 90
+2 -2
View File
@@ -81,8 +81,8 @@ Only `nisse-dev` has real code; `nisse-core` and `nisse-ops` are placeholders.
runs that full set before its image is built. The end-to-end tests drive the runs that full set before its image is built. The end-to-end tests drive the
real agent, every role on a local model (so they cost nothing per call), in a real agent, every role on a local model (so they cost nothing per call), in a
repository of the run's own, with a scripted operator; CI runs them after the repository of the run's own, with a scripted operator; CI runs them after the
checks pass. There is one runner, and a run a newer push checks pass. There is one runner, so a newer run for a
supersedes has to be cancelled by hand. Locally only the tests being written PR or branch cancels the one it supersedes (#126). Locally only the tests being written
(`-k`) or diagnosed (`--lf`); `scripts/e2e.sh` reports what a run spent. Manual (`-k`) or diagnosed (`--lf`); `scripts/e2e.sh` reports what a run spent. Manual
live runs are for the new loop's first runs and phase ends. Findings are filed as live runs are for the new loop's first runs and phase ends. Findings are filed as
issues and either fixed before moving on or deliberately deferred. issues and either fixed before moving on or deliberately deferred.