Skip to content

Commit 9134ba1

Browse files
soerennbsoeren
andauthored
Streamline CI validation gates
* Streamline CI validation gates * Use current change filter runtime --------- Co-authored-by: soeren <soeren@sefoto.de>
1 parent 3162eda commit 9134ba1

5 files changed

Lines changed: 194 additions & 9 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Change classification
2+
3+
on:
4+
workflow_call:
5+
outputs:
6+
automation:
7+
description: GitHub Actions workflows changed
8+
value: ${{ jobs.classify.outputs.automation }}
9+
backend:
10+
description: Laravel runtime or tests changed
11+
value: ${{ jobs.classify.outputs.backend }}
12+
dependencies:
13+
description: Composer or npm dependencies changed
14+
value: ${{ jobs.classify.outputs.dependencies }}
15+
frontend:
16+
description: Frontend sources or build configuration changed
17+
value: ${{ jobs.classify.outputs.frontend }}
18+
infrastructure:
19+
description: Container or deployment configuration changed
20+
value: ${{ jobs.classify.outputs.infrastructure }}
21+
source:
22+
description: Application source code changed
23+
value: ${{ jobs.classify.outputs.source }}
24+
25+
permissions:
26+
contents: read
27+
pull-requests: read
28+
29+
jobs:
30+
classify:
31+
name: Classify changed files
32+
runs-on: ubuntu-latest
33+
outputs:
34+
automation: ${{ steps.filter.outputs.automation }}
35+
backend: ${{ steps.filter.outputs.backend }}
36+
dependencies: ${{ steps.filter.outputs.dependencies }}
37+
frontend: ${{ steps.filter.outputs.frontend }}
38+
infrastructure: ${{ steps.filter.outputs.infrastructure }}
39+
source: ${{ steps.filter.outputs.source }}
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@v7
43+
44+
- name: Classify changes
45+
id: filter
46+
uses: dorny/paths-filter@v4
47+
with:
48+
filters: |
49+
automation:
50+
- '.github/workflows/**'
51+
backend:
52+
- 'app/**'
53+
- 'artisan'
54+
- 'bootstrap/**'
55+
- 'composer.json'
56+
- 'composer.lock'
57+
- 'config/**'
58+
- 'database/**'
59+
- 'phpunit.xml'
60+
- 'resources/lang/**'
61+
- 'resources/views/**'
62+
- 'routes/**'
63+
- 'tests/**'
64+
dependencies:
65+
- 'composer.json'
66+
- 'composer.lock'
67+
- 'package.json'
68+
- 'package-lock.json'
69+
frontend:
70+
- 'package.json'
71+
- 'package-lock.json'
72+
- 'resources/css/**'
73+
- 'resources/js/**'
74+
- 'vite.config.*'
75+
infrastructure:
76+
- '.env.docker.example'
77+
- 'Caddyfile'
78+
- 'Dockerfile'
79+
- 'compose*.yml'
80+
- 'install.sh'
81+
source:
82+
- 'app/**'
83+
- 'bootstrap/**'
84+
- 'config/**'
85+
- 'database/**'
86+
- 'resources/css/**'
87+
- 'resources/js/**'
88+
- 'resources/lang/**'
89+
- 'resources/views/**'
90+
- 'routes/**'

.github/workflows/ci.yml

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,27 @@ on:
99

1010
permissions:
1111
contents: read
12+
pull-requests: read
1213

1314
concurrency:
1415
group: ci-${{ github.workflow }}-${{ github.ref }}
1516
cancel-in-progress: true
1617

1718
jobs:
18-
release_validation:
19-
name: Release-ready validation
20-
uses: ./.github/workflows/release-validation.yml
19+
changes:
20+
name: Change classification
21+
uses: ./.github/workflows/change-classification.yml
2122

2223
php:
2324
name: PHP quality and tests
2425
runs-on: ubuntu-latest
25-
needs: frontend
26+
needs:
27+
- changes
28+
- frontend
29+
if: >-
30+
github.event_name == 'workflow_dispatch' ||
31+
needs.changes.outputs.backend == 'true' ||
32+
needs.changes.outputs.automation == 'true'
2633
steps:
2734
- name: Checkout
2835
uses: actions/checkout@v7
@@ -63,6 +70,12 @@ jobs:
6370
frontend:
6471
name: Frontend build
6572
runs-on: ubuntu-latest
73+
needs: changes
74+
if: >-
75+
github.event_name == 'workflow_dispatch' ||
76+
needs.changes.outputs.backend == 'true' ||
77+
needs.changes.outputs.frontend == 'true' ||
78+
needs.changes.outputs.automation == 'true'
6679
steps:
6780
- name: Checkout
6881
uses: actions/checkout@v7
@@ -97,7 +110,13 @@ jobs:
97110
mariadb:
98111
name: MariaDB integration tests
99112
runs-on: ubuntu-latest
100-
needs: frontend
113+
needs:
114+
- changes
115+
- frontend
116+
if: >-
117+
github.event_name == 'workflow_dispatch' ||
118+
needs.changes.outputs.backend == 'true' ||
119+
needs.changes.outputs.automation == 'true'
101120
services:
102121
db:
103122
image: mariadb:11
@@ -147,6 +166,11 @@ jobs:
147166
container:
148167
name: Container integration test
149168
runs-on: ubuntu-latest
169+
needs: changes
170+
if: >-
171+
github.event_name == 'workflow_dispatch' ||
172+
needs.changes.outputs.infrastructure == 'true' ||
173+
needs.changes.outputs.automation == 'true'
150174
steps:
151175
- name: Checkout
152176
uses: actions/checkout@v7
@@ -244,6 +268,11 @@ jobs:
244268
compose:
245269
name: Compose configuration
246270
runs-on: ubuntu-latest
271+
needs: changes
272+
if: >-
273+
github.event_name == 'workflow_dispatch' ||
274+
needs.changes.outputs.infrastructure == 'true' ||
275+
needs.changes.outputs.automation == 'true'
247276
steps:
248277
- name: Checkout
249278
uses: actions/checkout@v7
@@ -261,6 +290,11 @@ jobs:
261290
shell:
262291
name: Installer script
263292
runs-on: ubuntu-latest
293+
needs: changes
294+
if: >-
295+
github.event_name == 'workflow_dispatch' ||
296+
needs.changes.outputs.infrastructure == 'true' ||
297+
needs.changes.outputs.automation == 'true'
264298
steps:
265299
- name: Checkout
266300
uses: actions/checkout@v7
@@ -272,3 +306,22 @@ jobs:
272306
run: |
273307
test -x install.sh
274308
shellcheck install.sh
309+
310+
gate:
311+
name: CI gate
312+
runs-on: ubuntu-latest
313+
if: always()
314+
needs:
315+
- changes
316+
- php
317+
- frontend
318+
- mariadb
319+
- container
320+
- compose
321+
- shell
322+
steps:
323+
- name: Require successful executed checks
324+
if: >-
325+
contains(needs.*.result, 'failure') ||
326+
contains(needs.*.result, 'cancelled')
327+
run: exit 1

.github/workflows/security-audit.yml

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,34 @@ on:
44
pull_request:
55
push:
66
branches:
7-
- main
87
- master
98
schedule:
109
- cron: "0 5 * * 1"
1110

11+
permissions:
12+
contents: read
13+
pull-requests: read
14+
15+
concurrency:
16+
group: security-${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: true
18+
1219
jobs:
20+
changes:
21+
name: Change classification
22+
if: github.event_name != 'schedule'
23+
uses: ./.github/workflows/change-classification.yml
24+
1325
dependency-audit:
1426
name: Dependency Audit
1527
runs-on: ubuntu-latest
28+
needs: changes
29+
if: >-
30+
always() && (
31+
github.event_name == 'schedule' ||
32+
needs.changes.outputs.dependencies == 'true' ||
33+
needs.changes.outputs.automation == 'true'
34+
)
1635
steps:
1736
- name: Checkout
1837
uses: actions/checkout@v7
@@ -59,6 +78,12 @@ jobs:
5978
sast:
6079
name: SAST
6180
runs-on: ubuntu-latest
81+
needs: changes
82+
if: >-
83+
always() && (
84+
github.event_name == 'schedule' ||
85+
(github.ref == 'refs/heads/master' && needs.changes.outputs.source == 'true')
86+
)
6287
steps:
6388
- name: Checkout
6489
uses: actions/checkout@v7
@@ -70,3 +95,19 @@ jobs:
7095
p/php
7196
p/owasp-top-ten
7297
p/secrets
98+
99+
gate:
100+
name: Security gate
101+
runs-on: ubuntu-latest
102+
if: always()
103+
needs:
104+
- changes
105+
- dependency-audit
106+
- secret-scan
107+
- sast
108+
steps:
109+
- name: Require successful executed checks
110+
if: >-
111+
contains(needs.*.result, 'failure') ||
112+
contains(needs.*.result, 'cancelled')
113+
run: exit 1

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ protected function isAccessible(User $user, ?string $path = null): bool
259259
260260
## GitHub Actions CI
261261
262-
- Continuous Integration runs on pull requests and pushes to `master`; it checks PHP formatting, PHPUnit, the Vite production build, MariaDB compatibility, Compose-based container initialization, deployment configuration, and the installer shell script.
262+
- Continuous Integration runs on pull requests and pushes to `master`. It classifies changed files and runs only the relevant checks: backend changes receive the Vite build plus PHP and MariaDB tests; frontend changes receive the Vite build; infrastructure changes receive Compose, installer, and container backup/restore checks. Workflow changes run the full CI suite.
263+
- Security Audit runs a secret scan on every pull request and `master` push. Dependency audits run for dependency or workflow changes; SAST runs for source changes on `master` and in the scheduled weekly audit. The required merge checks are `CI gate` and `Security gate`.
263264
- CI is validation-only: do not add deployment steps, repository write permissions, or secrets without explicit approval.
264265
- The frontend workflows use Node.js 24; local frontend checks require Node.js 22.18 or later.
265266
- Tags matching `v0.*.*` validate the release again, publish a GHCR container image with provenance and an SBOM, smoke-test its digest, and generate GitHub release notes; they must not deploy the application.

docs/releasing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Releasing
22

3-
Releases are deliberately tag-driven. A maintainer creates a concrete `v0.x.y` tag only after the `master` branch CI is green.
3+
Releases are deliberately tag-driven. A maintainer creates a concrete `v0.x.y` tag only after the `master` branch `CI gate` and `Security gate` are green.
44

55
## Publish a release
66

@@ -13,7 +13,7 @@ Releases are deliberately tag-driven. A maintainer creates a concrete `v0.x.y` t
1313
git push origin v0.1.0
1414
```
1515

16-
4. Verify the Release workflow. It repeats application validation, builds and publishes the container with provenance and an SBOM, smoke-tests the published image by digest, and creates the GitHub Release.
16+
4. Verify the Release workflow. It repeats the complete release validation (frontend build, application tests, and dependency audits) for the immutable tag, builds and publishes the container with provenance and an SBOM, smoke-tests the published image by digest, and creates the GitHub Release.
1717
5. Check the generated release notes. Add a concise **Upgrade notes** section that calls out migrations, changed environment variables, deprecations, and any manual operator action.
1818

1919
## Published images

0 commit comments

Comments
 (0)