fix(ci): use native workflow path filters (#13037)

* ci: select affected checks and share add-on builds

Keep validation check identities present while omitting expensive steps
when explicit dependency rules prove they are unaffected. Unknown inputs
and diff failures retain broad validation.

Select add-on package legs on PRs and master without weakening catalog
checks or changing release publishing. Manual package runs validate only,
including their reusable Sandbox guest image dependency.

Share bounded, same-run production fixtures across the five add-on test
groups. Verify checkout identity, tools, paths, modes and checksums before
using them. Keep instrumented coverage builds separate.

Assisted-by: nib:gpt-6.1-sol
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(ci): validate documentation test contracts

Documentation is executable input to Tables, recovery, diagnostics,
gallery and other add-on tests. Select all domains for docs changes
instead of treating the whole directory as inert. Cover known readers,
unfamiliar paths and deleted guides in classifier regression fixtures.

Assisted-by: nib:gpt-6.1-sol
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(ci): gate affected jobs before allocation

Classify each workflow once and gate whole expensive jobs. Limit add-on
matrices to affected packages and host groups instead of allocating all
runners before deciding whether their steps should run.

Select documentation readers explicitly and derive host consumers from
local Go imports. Keep unknown source inputs conservative. Preserve
coverage, production fixtures, publish locks and manual full validation.
Remove the unrequested weekly schedules.

Reject classifier failures and unexpected dependency skips in stable
aggregate checks. Document required-check migration without claiming
access to protected-branch settings. Test actual YAML job and matrix
eligibility against representative paths and the original triggers.

Assisted-by: nib:gpt-6.1-sol
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(ci): validate executable and fixture seams

Include executed fixture binaries and their production imports in host
selection. Lexical Go imports alone miss the mock backend started by
the UI test server and add-on suites.

Rebase restored artifact timestamps only after identity and checksum
validation. Preserve the existing stale-source checks across a later
consumer checkout and reject subsequent source edits.

Validate package plan outputs before allowing dependency skips. Missing
or malformed plans must not turn failed publication preparation green.
Cover all three review findings with before-fix reproductions and
actual workflow eligibility regressions.

Assisted-by: nib:gpt-6.1-sol
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix(ci): use native workflow path filters

Replace calculated dependencies with visible PR and master path lists.
Run complete area suites without classifier runners or result plumbing.
Restore original packaging validation and publication dependencies.

Keep one production fixture build for the five original add-on groups.
Verify artifact identity and freshness without changing suite inventories.
Document allowlist maintenance and required-check migration limits.

Assisted-by: nib:gpt-6.1-sol
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
mudler-agentandEttore Di Giacinto authored and GitHub committed 2026-11-02 21:16:37 +01:00
1 parent 74e293ef38
commit 8b4f3c35e8
14 files changed
+699 -111

No files matched your search

+31 -17
View File
@@ -47,27 +47,10 @@ name: 'add-on packages'
# local-check build.
on:
push:
branches: ['**']
tags: ['v*']
paths:
- 'addons/**'
- 'pkg/addons/**'
- 'scripts/addons/**'
- 'gallery/addons/**'
- 'tests/addons/packaging/**'
- 'core/services/addons/**'
- 'core/http/react-ui/package.json'
- 'core/http/react-ui/package-lock.json'
- 'go.mod'
- 'go.sum'
- '.github/workflows/addons-package.yml'
- '.github/workflows/sandbox-images.yml'
pull_request:
paths:
- 'addons/**'
- 'pkg/addons/**'
- 'scripts/addons/**'
- 'gallery/addons/**'
- 'tests/addons/packaging/**'
- 'core/services/addons/**'
@@ -77,9 +60,40 @@ on:
- 'go.sum'
- '.github/workflows/addons-package.yml'
- '.github/workflows/sandbox-images.yml'
- 'Makefile'
- 'scripts/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'docs/content/features/addons.md'
- '.github/actions/**'
push:
branches: [master]
tags: ['v*']
paths:
- 'addons/**'
- 'pkg/addons/**'
- 'gallery/addons/**'
- 'tests/addons/packaging/**'
- 'core/services/addons/**'
- 'core/http/react-ui/package.json'
- 'core/http/react-ui/package-lock.json'
- 'go.mod'
- 'go.sum'
- '.github/workflows/addons-package.yml'
- '.github/workflows/sandbox-images.yml'
- 'Makefile'
- 'scripts/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'docs/content/features/addons.md'
- '.github/actions/**'
release:
types: [published]
concurrency:
group: ci-addons-package-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
+95 -15
View File
@@ -15,23 +15,50 @@ on:
pull_request:
paths:
- 'addons/**'
- 'tests/addons/**'
- 'tests/e2e-ui/**'
- 'tests/e2e/mock-backend/**'
- 'pkg/addons/**'
- 'core/services/addons/**'
- 'core/http/endpoints/addons/**'
- 'core/http/auth/addons*.go'
- 'core/application/**'
- 'core/library/**'
- 'core/http/react-ui/**'
- 'scripts/addons/**'
- 'go.mod'
- 'go.sum'
- '.github/workflows/addons-tests.yml'
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'gallery/addons/**'
- 'docs/content/features/addons.md'
- 'docs/content/features/tables.md'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
push:
branches:
- master
branches: [master]
paths:
- 'addons/**'
- 'go.mod'
- 'go.sum'
- '.github/workflows/addons-tests.yml'
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'gallery/addons/**'
- 'docs/content/features/addons.md'
- 'docs/content/features/tables.md'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
concurrency:
group: ci-addons-tests-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
@@ -41,7 +68,54 @@ permissions:
contents: read
jobs:
prepare:
name: prepare shared production fixtures
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- name: Clone
uses: actions/checkout@v7
with:
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@v6
with:
# prepare.sh accepts Go 1.26.x only and runs with GOTOOLCHAIN=local.
go-version: '1.26.x'
cache: false
- name: Setup Node.js
uses: actions/setup-node@v7
with:
# prepare.sh accepts Node 22.12 or later within Node 22.
node-version: '22'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libopus-dev unzip curl
- name: Install protoc
# prepare.sh requires exactly libprotoc 26.1.
run: |
curl -L -s https://github.com/protocolbuffers/protobuf/releases/download/v26.1/protoc-26.1-linux-x86_64.zip -o protoc.zip
sudo unzip -j -d /usr/local/bin protoc.zip bin/protoc
rm protoc.zip
protoc --version
- name: Prepare the build toolchain
# The producer installs build inputs only; consumers install Chromium.
run: sh scripts/addons/prepare.sh --prepare-build
- name: Build the UI, the mock backend and the UI test server
run: COVERAGE=false COVERAGE_V8=false sh scripts/addons/prepare.sh --integration
- name: Archive production fixtures
run: |
python3 scripts/ci/fixtures.py pack
- uses: actions/upload-artifact@v7
with:
name: addon-production-fixtures
path: ${{ runner.temp }}/addon-fixtures.tgz
if-no-files-found: error
retention-days: 1
suites:
needs: prepare
name: ${{ matrix.group }}
runs-on: ubuntu-24.04
timeout-minutes: 60
@@ -98,8 +172,14 @@ jobs:
run: sh scripts/addons/prepare.sh --prepare
- name: Install the browser's system libraries
run: sudo env "PATH=$PATH" core/http/react-ui/node_modules/.bin/playwright install-deps chromium
- name: Build the UI, the mock backend and the UI test server
run: sh scripts/addons/prepare.sh --integration
- uses: actions/download-artifact@v8
with:
name: addon-production-fixtures
path: ${{ runner.temp }}
- name: Restore and check production fixtures
run: |
python3 scripts/ci/fixtures.py unpack
sh scripts/addons/prepare.sh --check
- name: Run the suites
env:
SUITES: ${{ matrix.suites }}
+42 -27
View File
@@ -1,33 +1,48 @@
name: Build test
on:
push:
branches:
- master
pull_request:
# GoReleaser and the darwin launcher take no gallery, docs or markdown
# input, so a diff confined to these paths cannot change either binary.
# The darwin job matters here: macOS is the scarcest runner class.
#
# backend/{cpp,go,python}/**: GoReleaser builds ./cmd/local-ai and the
# launcher builds ./cmd/launcher; neither compiles a backend. The
# before-hooks still matter, but their input is backend/backend.proto
# (protogen-go) and go.mod/go.sum (go mod tidy), none of which live under
# these prefixes, so a change to any of those still triggers a full run.
# See .agents/ci-caching.md.
paths-ignore:
- 'gallery/**'
- 'docs/**'
- 'examples/**'
- '**/*.md'
- 'backend/cpp/**'
- 'backend/go/**'
- 'backend/python/**'
paths:
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'addons/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- '.goreleaser*'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
- '.github/workflows/build-test.yaml'
- 'Entitlements.plist'
push:
branches: [master]
paths:
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'addons/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- '.goreleaser*'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
- '.github/workflows/build-test.yaml'
- 'Entitlements.plist'
# Supersede an in-flight run when a PR gets a new push. Keyed on the PR number
# so every push to the same PR shares a group; on a master push the key falls
# back to github.sha (unique per commit) and cancel-in-progress is false, so
# master runs never cancel each other -- each commit is built on its own.
concurrency:
group: ci-build-test-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
@@ -74,7 +89,7 @@ jobs:
name: launcher-macos
path: dist/
retention-days: 30
launcher-build-linux:
runs-on: ubuntu-latest
steps:
@@ -98,4 +113,4 @@ jobs:
with:
name: launcher-linux
path: local-ai-launcher-linux.tar.xz
retention-days: 30
retention-days: 30
+61 -4
View File
@@ -3,11 +3,68 @@ name: 'tests'
on:
pull_request:
paths:
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'addons/**'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'backend/cpp/**'
- 'gallery/**'
- 'docs/content/features/addons.md'
- 'docs/content/features/tables.md'
- 'docs/content/features/image-generation.md'
- 'docs/content/features/diagnostics.md'
- 'docs/content/reference/cli-reference.md'
- 'docs/content/getting-started/troubleshooting.md'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
- '.github/workflows/test.yml'
- 'backend/index.yaml'
- 'coverage-baseline.txt'
push:
branches:
- master
tags:
- '*'
branches: [master]
tags: ['*']
paths:
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'addons/**'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'backend/cpp/**'
- 'gallery/**'
- 'docs/content/features/addons.md'
- 'docs/content/features/tables.md'
- 'docs/content/features/image-generation.md'
- 'docs/content/features/diagnostics.md'
- 'docs/content/reference/cli-reference.md'
- 'docs/content/getting-started/troubleshooting.md'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
- '.github/workflows/test.yml'
- 'backend/index.yaml'
- 'coverage-baseline.txt'
workflow_dispatch:
concurrency:
group: ci-tests-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
+30 -18
View File
@@ -10,28 +10,40 @@ on:
pull_request:
paths:
- 'tests/e2e/distributed/**'
- 'core/services/nodes/**'
- 'core/services/messaging/**'
- 'core/services/testutil/**'
- 'core/services/studio/**'
- 'core/services/collections/**'
- 'core/services/syncstate/**'
- 'core/services/advisorylock/**'
- 'core/services/galleryop/**'
- 'core/services/modeladmin/**'
- 'core/services/failover/**'
- 'core/services/storage/**'
- 'core/application/distributed*.go'
- 'core/cli/**'
- 'pkg/natsauth/**'
- 'scripts/nats-auth-setup.sh'
- 'Makefile'
- '.github/workflows/tests-e2e-distributed.yml'
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'configuration/**'
- 'go.mod'
- 'go.sum'
- 'scripts/**'
- '.github/actions/**'
push:
branches:
- master
branches: [master]
paths:
- 'tests/e2e/distributed/**'
- 'Makefile'
- '.github/workflows/tests-e2e-distributed.yml'
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'configuration/**'
- 'go.mod'
- 'go.sum'
- 'scripts/**'
- '.github/actions/**'
schedule:
# Nightly, so a regression that the path filter missed shows within a day.
# Pre-existing nightly coverage of the distributed suites.
- cron: '17 3 * * *'
workflow_dispatch:
+40 -12
View File
@@ -3,19 +3,47 @@ name: 'E2E Backend Tests'
on:
pull_request:
# The e2e suite drives backends over gRPC directly and reads none of these
# paths, so a diff confined to them cannot move it.
# See .agents/ci-caching.md.
paths-ignore:
- 'gallery/**'
- 'docs/**'
- 'examples/**'
- '**/*.md'
paths:
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'addons/**'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
- '.github/workflows/tests-e2e.yml'
push:
branches:
- master
tags:
- '*'
branches: [master]
tags: ['*']
paths:
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'addons/**'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
- '.github/workflows/tests-e2e.yml'
concurrency:
group: ci-tests-e2e-backend-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}
+36 -15
View File
@@ -3,25 +3,46 @@ name: 'UI E2E Tests'
on:
pull_request:
# The suite builds the add-on UI bundles from addons/<id>/ui (global-setup)
# and drives the real chats service, the add-on host and the studio
# services through the test server, so a change to any of them can break a
# spec without touching core/http.
paths:
- 'core/http/**'
- 'core/application/**'
- 'core/services/studio/**'
- 'core/services/addons/**'
- 'pkg/addons/**'
- 'addons/**'
- 'tests/e2e-ui/**'
- 'tests/e2e/mock-backend/**'
- 'tests/addons/fixture/**'
- 'scripts/ensure-playwright-browser.sh'
- '.github/workflows/tests-ui-e2e.yml'
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
push:
branches:
- master
branches: [master]
paths:
- 'addons/**'
- '.github/workflows/tests-ui-e2e.yml'
- 'core/**'
- 'pkg/**'
- 'cmd/**'
- 'internal/**'
- 'backend/go/**'
- 'backend/*.proto'
- 'backend/*/*.proto'
- 'tests/**'
- 'configuration/**'
- 'swagger/**'
- 'prompt-templates/**'
- 'go.mod'
- 'go.sum'
- 'Makefile'
- 'scripts/**'
- '.github/actions/**'
concurrency:
group: ci-tests-ui-e2e-${{ github.event.pull_request.number || github.sha }}-${{ github.repository }}