mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-06 04:23:15 -05:00
ci: cancel superseded master runs of test workflows
Many pushes to master left over a hundred runs queued, because every push used its own concurrency group. Group push runs by ref and cancel the in-flight run on master for the test, lint and E2E workflows. PR, tag, schedule and dispatch runs keep groups that a master push cannot cancel. The intel cache job pushes one fixed tag, so it now keeps at most one pending run per event and never cancels a running build. image.yml and backend.yml are unchanged: they build from the diff of a single push, so replacing a queued run could skip a code commit. Document the policy in .agents/ci-caching.md. Assisted-by: Claude:claude-sonnet-5-5 python3
This commit is contained in:
12 files changed
+109
-20
No files matched your search
@@ -289,6 +289,26 @@ concurrency:
|
||||
- **PR events** group by PR number → newer pushes to the same PR cancel old runs (intended).
|
||||
- **Push events** group by `github.sha` → each master commit gets its own run; rapid-fire merges don't cancel each other (this was a real issue prior — two master pushes 11 seconds apart would cancel the first's CI).
|
||||
|
||||
### Test, lint and E2E workflows cancel superseded master runs
|
||||
|
||||
`test.yml`, `lint.yml`, `build-test.yaml`, `test-extra.yml`, `tests-e2e.yml`, `tests-ui-e2e.yml`, `tests-aio.yml`, `tests-pii-ner-e2e.yml`, `realtime-conformance.yml` and `ci-tools-tests.yaml` use this instead:
|
||||
|
||||
```yaml
|
||||
concurrency:
|
||||
group: ci-<workflow>-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
```
|
||||
|
||||
- A newer push to master cancels the older in-flight run of the same workflow. Tests are cumulative, so the newest commit is the one worth testing. This stops a burst of merges from leaving hundreds of queued runs.
|
||||
- Tag pushes group by their own tag ref, and schedule and `workflow_dispatch` runs group by SHA, so a master push never cancels them.
|
||||
- The cost: the run of an older commit shows as cancelled, so a failure that the newer commit also contains is reported by the newer run, not the older one.
|
||||
|
||||
### Image workflows are deliberately not cancelled
|
||||
|
||||
`image.yml` and `backend.yml` keep the per-SHA group. Both decide what to build from the diff of one push (`event.before` to `sha`): the `changes` job in `image.yml`, `scripts/changed-backends.js` in `backend.yml`. If a queued run were replaced by a newer one, the newer run would only see its own diff. A code commit followed by a gallery-only commit would then build nothing. Do not add a pending-replacement group to them until the diff base is the last commit that was actually built.
|
||||
|
||||
`generate_intel_image.yaml` pushes one fixed tag, so its group is `intel-cache-<event>-<repo>` with `cancel-in-progress: false`: a running build finishes, and a newer pending run replaces an older pending one.
|
||||
|
||||
## Self-warming, no separate populator
|
||||
|
||||
There is no cron job that pre-warms the BuildKit cache for individual backends. The production builds *are* the populators. The first master build of a given matrix entry pays the cold cost; subsequent same-entry master builds reuse everything that hasn't changed (apt installs, gRPC compile in the variant `builder-fromsource` stage or skipped entirely when consuming `base-grpc-*`, Python wheel installs, etc.). The base-images workflow's weekly cron is the closest thing to a populator and only refreshes the prebuilt builder bases.
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: Build test
|
||||
|
||||
on:
|
||||
@@ -44,8 +50,8 @@ on:
|
||||
- 'Entitlements.plist'
|
||||
|
||||
concurrency:
|
||||
group: ci-build-test-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-build-test-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
build-test:
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
---
|
||||
# The packages under .github/ci/ are invisible to `go list ./...`, so neither
|
||||
# `make lint` nor the repository test run ever touches them. Their specs are
|
||||
@@ -13,6 +19,10 @@ on:
|
||||
- master
|
||||
paths:
|
||||
- '.github/ci/**'
|
||||
concurrency:
|
||||
group: ci-tools-tests-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
ci-tools:
|
||||
name: 'Test the .github/ci generators'
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
# Concurrency policy: this job pushes one fixed tag, so only the newest build
|
||||
# matters. A running build is never cancelled (cancel-in-progress is false);
|
||||
# GitHub keeps at most one pending run per group and replaces an older pending
|
||||
# run with a newer one. Push and workflow_dispatch use separate groups, so a
|
||||
# manual run is never replaced by a push.
|
||||
name: 'generate and publish intel docker caches'
|
||||
|
||||
on:
|
||||
@@ -7,8 +12,8 @@ on:
|
||||
- master
|
||||
|
||||
concurrency:
|
||||
group: intel-cache-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: intel-cache-${{ github.event_name }}-${{ github.repository }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
generate_caches:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'lint'
|
||||
|
||||
on:
|
||||
@@ -16,8 +22,8 @@ on:
|
||||
- master
|
||||
|
||||
concurrency:
|
||||
group: ci-lint-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-lint-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
golangci-lint:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'realtime-conformance'
|
||||
|
||||
# Verifies the realtime state-machine implementations conform to their formal
|
||||
@@ -36,8 +42,8 @@ on:
|
||||
- 'scripts/realtime-conformance.sh'
|
||||
|
||||
concurrency:
|
||||
group: realtime-conformance-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: realtime-conformance-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
conformance:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'Tests extras backends'
|
||||
|
||||
on:
|
||||
@@ -10,8 +16,8 @@ on:
|
||||
- '*'
|
||||
|
||||
concurrency:
|
||||
group: ci-tests-extra-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-tests-extra-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
detect-changes:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'tests'
|
||||
|
||||
on:
|
||||
@@ -67,8 +73,8 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ci-tests-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-tests-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
tests-linux:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'tests-aio'
|
||||
|
||||
# Runs the all-in-one (AIO) Docker image with real backends + real models.
|
||||
@@ -22,8 +28,8 @@ on:
|
||||
- '*'
|
||||
|
||||
concurrency:
|
||||
group: ci-tests-aio-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-tests-aio-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
tests-aio:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'E2E Backend Tests'
|
||||
|
||||
on:
|
||||
@@ -46,8 +52,8 @@ on:
|
||||
- '.github/workflows/tests-e2e.yml'
|
||||
|
||||
concurrency:
|
||||
group: ci-tests-e2e-backend-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-tests-e2e-backend-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
tests-e2e-backend:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'PII NER tier E2E (live GGUF, CPU)'
|
||||
|
||||
# Runs the real privacy-filter GGUF NER tier end-to-end on CPU — the gap the
|
||||
@@ -46,8 +52,8 @@ on:
|
||||
- '.github/workflows/tests-pii-ner-e2e.yml'
|
||||
|
||||
concurrency:
|
||||
group: ci-tests-pii-ner-e2e-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-tests-pii-ner-e2e-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
tests-pii-ner-e2e:
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
---
|
||||
# Concurrency policy: a newer push to master cancels the in-flight run of this
|
||||
# workflow on master, because the newer commit contains the older one and the
|
||||
# result that matters is the newest. PR runs group by PR number (as before),
|
||||
# tag pushes group by their own tag ref, and schedule/dispatch runs group by
|
||||
# commit SHA, so none of those is ever cancelled by a master push.
|
||||
# See .agents/ci-caching.md, section "Concurrency".
|
||||
name: 'UI E2E Tests'
|
||||
|
||||
on:
|
||||
@@ -45,8 +51,8 @@ on:
|
||||
- '.github/actions/**'
|
||||
|
||||
concurrency:
|
||||
group: ci-tests-ui-e2e-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
group: ci-tests-ui-e2e-${{ github.event.pull_request.number || (github.event_name == 'push' && github.ref) || github.sha }}-${{ github.repository }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') }}
|
||||
|
||||
jobs:
|
||||
tests-ui-e2e:
|
||||
|
||||
Reference in new issue
Block a user