Skip to content

Commit 3eb1659

Browse files
authored
Merge pull request #419 from os2display/feature/ci-cleanup
CI cleanup: cache vendor + node_modules, --no-deps, doc each workflow, rework apispec
2 parents 393cb3d + cb3d3df commit 3eb1659

20 files changed

Lines changed: 337 additions & 78 deletions

.github/workflows/apispec.yaml

Lines changed: 138 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,160 @@
1-
on: pull_request
1+
### ### Api Spec
2+
###
3+
### Re-exports the OpenAPI spec (`public/api-spec-v2.{yaml,json}`) from the
4+
### API Platform configuration. Posts a PR comment **only** when something
5+
### needs attention — spec drift, non-breaking changes, or breaking changes —
6+
### and stays quiet otherwise. The comment is edited in place across runs
7+
### so a PR carries at most one comment from this workflow.
8+
###
9+
### #### Assumptions
10+
###
11+
### 1. A docker compose service named `phpfpm` can be run and `bin/console`
12+
### can be run inside the `phpfpm` service.
13+
### 2. The committed `public/api-spec-v2.{yaml,json}` are kept in sync with
14+
### the API Platform configuration via `composer update-api-spec`.
15+
16+
on:
17+
pull_request:
18+
paths:
19+
- "src/**/*.php"
20+
- "config/**"
21+
- "composer.json"
22+
- "composer.lock"
23+
- "public/api-spec-v2.yaml"
24+
- "public/api-spec-v2.json"
25+
- "docker-compose.yml"
226

327
name: Api Spec
428

529
env:
630
COMPOSE_USER: runner
731

832
jobs:
9-
apispec:
33+
api-spec-export:
34+
name: Ensure API specification is up to date
1035
runs-on: ubuntu-latest
11-
name: API Specification validation
36+
permissions:
37+
contents: read
38+
pull-requests: write
1239
steps:
1340
- name: Checkout
1441
uses: actions/checkout@v6
42+
43+
- name: Cache vendor
44+
uses: actions/cache@v5
1545
with:
16-
fetch-depth: 2
46+
path: vendor
47+
key: vendor-php8.4-${{ hashFiles('composer.lock') }}
48+
restore-keys: vendor-php8.4-
1749

1850
- name: Setup network
1951
run: docker network create frontend
2052

2153
- name: Install Dependencies
2254
run: docker compose run --rm phpfpm composer install
2355

24-
- name: Export specifications (yaml)
25-
run: docker compose run --rm phpfpm bin/console api:openapi:export --yaml --output=public/api-spec-v2.yaml --no-interaction
56+
- name: Export specifications
57+
run: |
58+
docker compose run --rm phpfpm bin/console api:openapi:export --yaml --output=public/api-spec-v2.yaml --no-interaction
59+
docker compose run --rm phpfpm bin/console api:openapi:export --output=public/api-spec-v2.json --no-interaction
60+
61+
- name: Check for uncommitted changes
62+
id: git-diff-spec
63+
continue-on-error: true
64+
run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.yaml public/api-spec-v2.json
65+
66+
- name: Comment PR if spec is outdated
67+
if: steps.git-diff-spec.outcome == 'failure'
68+
env:
69+
GH_TOKEN: ${{ github.token }}
70+
run: |
71+
gh pr comment ${{ github.event.pull_request.number }} \
72+
--body "$(cat <<'EOF'
73+
## API specification not up to date
74+
75+
The committed API specification files do not match the exported output.
76+
77+
Please run the following command, then commit and push the changes:
78+
79+
```shell
80+
docker compose exec phpfpm composer update-api-spec
81+
```
82+
EOF
83+
)" \
84+
--create-if-none --edit-last
85+
86+
- name: Fail if spec is outdated
87+
if: steps.git-diff-spec.outcome == 'failure'
88+
run: exit 1
89+
90+
api-spec-breaking-changes:
91+
name: Detect breaking changes in API specification
92+
runs-on: ubuntu-latest
93+
needs: [api-spec-export]
94+
permissions:
95+
contents: read
96+
pull-requests: write
97+
steps:
98+
- name: Checkout
99+
uses: actions/checkout@v6
100+
101+
- name: Fetch base branch for comparison
102+
run: git fetch --depth=1 origin ${{ github.base_ref }}
103+
104+
- name: Detect breaking changes
105+
id: breaking
106+
continue-on-error: true
107+
uses: oasdiff/oasdiff-action/breaking@v0.0.44
108+
with:
109+
base: "origin/${{ github.base_ref }}:public/api-spec-v2.yaml"
110+
revision: "public/api-spec-v2.yaml"
111+
fail-on: ERR
112+
113+
- name: Generate changelog
114+
id: changelog
115+
continue-on-error: true
116+
uses: oasdiff/oasdiff-action/changelog@v0.0.44
117+
with:
118+
base: "origin/${{ github.base_ref }}:public/api-spec-v2.yaml"
119+
revision: "public/api-spec-v2.yaml"
120+
format: markdown
121+
output-to-file: changelog.md
122+
123+
# Stay quiet when nothing changed — neither breaking nor non-breaking.
124+
# Comments only fire on the two branches below.
26125

27-
- name: Check for changes in specifications (yaml)
28-
run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.yaml
126+
- name: Comment PR - non-breaking changes
127+
if: steps.breaking.outcome == 'success' && hashFiles('changelog.md') != ''
128+
env:
129+
GH_TOKEN: ${{ github.token }}
130+
run: |
131+
{
132+
echo "## API Specification - Non-breaking changes"
133+
echo ""
134+
cat changelog.md
135+
} > comment.md
136+
gh pr comment ${{ github.event.pull_request.number }} \
137+
--body-file comment.md \
138+
--create-if-none --edit-last
29139
30-
- name: Export specifications (json)
31-
run: docker compose run --rm phpfpm bin/console api:openapi:export --output=public/api-spec-v2.json --no-interaction
140+
- name: Comment PR - breaking changes
141+
if: steps.breaking.outcome == 'failure'
142+
env:
143+
GH_TOKEN: ${{ github.token }}
144+
run: |
145+
{
146+
echo "## API Specification - Breaking changes detected"
147+
echo ""
148+
if [ -s changelog.md ]; then
149+
cat changelog.md
150+
else
151+
echo "The breaking changes action detected incompatible changes. Review the action logs for details."
152+
fi
153+
} > comment.md
154+
gh pr comment ${{ github.event.pull_request.number }} \
155+
--body-file comment.md \
156+
--create-if-none --edit-last
32157
33-
- name: Check for changes in specifications (json)
34-
run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.json
158+
- name: Fail if breaking changes detected
159+
if: steps.breaking.outcome == 'failure'
160+
run: exit 1

.github/workflows/build-images.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
### ### Build docker images
2+
###
3+
### Builds and pushes the API and Nginx images to GHCR. Triggers on push to
4+
### `develop` (image tag `develop`) and on git tag pushes (image tag = git
5+
### tag). The Nginx image layers on the API image, so the API build runs
6+
### first in the same job.
7+
###
8+
### #### Assumptions
9+
###
10+
### 1. The `os2display` GHCR namespace exists and `GITHUB_TOKEN` carries
11+
### `packages: write`.
12+
### 2. `infrastructure/build-n-push.sh` mirrors the build for local use.
13+
114
---
215
name: Build docker images
316

.github/workflows/changelog.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Do not edit this file! Make a pull request on changing
2-
# github/workflows/changelog.yaml in
3-
# https://github.com/itk-dev/devops_itkdev-docker if need be.
4-
51
### ### Changelog
62
###
73
### Checks that changelog has been updated
@@ -14,8 +10,6 @@ on:
1410
jobs:
1511
changelog:
1612
runs-on: ubuntu-latest
17-
strategy:
18-
fail-fast: false
1913
steps:
2014
- name: Checkout
2115
uses: actions/checkout@v6

.github/workflows/code-analysis.yaml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
### ### Code Analysis
2+
###
3+
### Runs PHPStan static analysis against the project.
4+
###
5+
### #### Assumptions
6+
###
7+
### 1. A docker compose service named `phpfpm` can be run and `composer` can
8+
### be run inside the `phpfpm` service.
9+
### 2. [phpstan/phpstan](https://phpstan.org/) is a dev requirement in
10+
### `composer.json`.
11+
### 3. `phpstan.dist.neon` configures the analyser.
12+
113
on: pull_request
214

315
name: Code Analysis
@@ -13,11 +25,18 @@ jobs:
1325
- name: Checkout
1426
uses: actions/checkout@v6
1527

28+
- name: Cache vendor
29+
uses: actions/cache@v5
30+
with:
31+
path: vendor
32+
key: vendor-php8.4-${{ hashFiles('composer.lock') }}
33+
restore-keys: vendor-php8.4-
34+
1635
- name: Setup network
1736
run: docker network create frontend
1837

1938
- name: Install Dependencies
20-
run: docker compose run --rm phpfpm composer install
39+
run: docker compose run --rm --no-deps phpfpm composer install
2140

2241
- name: PHPStan
23-
run: docker compose run --rm phpfpm vendor/bin/phpstan analyse --no-progress
42+
run: docker compose run --rm --no-deps phpfpm vendor/bin/phpstan analyse --no-progress

.github/workflows/composer.yaml

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Do not edit this file! Make a pull request on changing
2-
# github/workflows/composer.yaml in
3-
# https://github.com/itk-dev/devops_itkdev-docker if need be.
4-
51
### ### Composer
62
###
73
### Validates composer.json and checks that it's normalized.
@@ -14,13 +10,13 @@
1410
### is a dev requirement in `composer.json`:
1511
###
1612
### ``` shell
17-
### docker compose run --rm phpfpm composer require --dev ergebnis/composer-normalize
13+
### docker compose run --rm --no-deps phpfpm composer require --dev ergebnis/composer-normalize
1814
### ```
1915
###
2016
### Normalize `composer.json` by running
2117
###
2218
### ``` shell
23-
### docker compose run --rm phpfpm composer normalize
19+
### docker compose run --rm --no-deps phpfpm composer normalize
2420
### ```
2521

2622
name: Composer
@@ -38,21 +34,23 @@ on:
3834
jobs:
3935
composer-validate:
4036
runs-on: ubuntu-latest
41-
strategy:
42-
fail-fast: false
4337
steps:
4438
- uses: actions/checkout@v6
4539
- run: |
4640
docker network create frontend
47-
docker compose run --rm phpfpm composer validate --strict
41+
docker compose run --rm --no-deps phpfpm composer validate --strict
4842
4943
composer-normalized:
5044
runs-on: ubuntu-latest
51-
strategy:
52-
fail-fast: false
5345
steps:
5446
- uses: actions/checkout@v6
47+
- name: Cache vendor
48+
uses: actions/cache@v5
49+
with:
50+
path: vendor
51+
key: vendor-php8.4-${{ hashFiles('composer.lock') }}
52+
restore-keys: vendor-php8.4-
5553
- run: |
5654
docker network create frontend
57-
docker compose run --rm phpfpm composer install
58-
docker compose run --rm phpfpm composer normalize --dry-run
55+
docker compose run --rm --no-deps phpfpm composer install
56+
docker compose run --rm --no-deps phpfpm composer normalize --dry-run

.github/workflows/composer_install.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
### ### Composer install
2+
###
3+
### Verifies that `composer install --no-dev -o` succeeds in prod mode against
4+
### the committed lockfile.
5+
###
6+
### #### Assumptions
7+
###
8+
### 1. A docker compose service named `phpfpm` can be run and `composer` can
9+
### be run inside the `phpfpm` service.
10+
111
on: pull_request
212

313
name: Composer install
@@ -17,4 +27,4 @@ jobs:
1727
run: docker network create frontend
1828

1929
- name: "[prod] Composer install"
20-
run: docker compose run --rm -e APP_ENV=prod phpfpm composer install --no-dev -o
30+
run: docker compose run --rm --no-deps -e APP_ENV=prod phpfpm composer install --no-dev -o

.github/workflows/doctrine.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
### ### Doctrine
2+
###
3+
### Runs pending Doctrine migrations and validates the resulting schema
4+
### against the entity metadata.
5+
###
6+
### #### Assumptions
7+
###
8+
### 1. A docker compose service named `phpfpm` can be run and `bin/console`
9+
### can be run inside the `phpfpm` service.
10+
### 2. A `mariadb` service is reachable from `phpfpm`.
11+
112
on: pull_request
213

314
name: Doctrine
@@ -13,6 +24,13 @@ jobs:
1324
- name: Checkout
1425
uses: actions/checkout@v6
1526

27+
- name: Cache vendor (prod)
28+
uses: actions/cache@v5
29+
with:
30+
path: vendor
31+
key: vendor-prod-php8.4-${{ hashFiles('composer.lock') }}
32+
restore-keys: vendor-prod-php8.4-
33+
1634
- name: Setup network
1735
run: docker network create frontend
1836

.github/workflows/env_coverage.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
### ### Env coverage
2+
###
3+
### Validates that every Symfony env variable read via `%env(...)%` in
4+
### `config/` is documented in `.env`, and that every variable in `.env`
5+
### carries a preceding description comment.
6+
###
7+
### #### Assumptions
8+
###
9+
### 1. `scripts/check-env-coverage.sh` is executable.
10+
### 2. The Taskfile target `coding-standards:env:check` invokes it.
111
---
212
on:
313
push:

.github/workflows/github_build_release.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
### ### Create Github Release
2+
###
3+
### On a semver tag push (`*.*.*`): builds the production tarball, writes
4+
### `release.json`, and creates a GitHub release. Tags containing a `-`
5+
### (e.g. `3.0.0-RC1`) are flagged as pre-releases.
6+
###
7+
### #### Assumptions
8+
###
9+
### 1. The `phpfpm` and `node` compose services can run on the runner.
10+
### 2. The tagged commit passes the regular CI suite.
11+
112
on:
213
push:
314
tags:

.github/workflows/javascript.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Do not edit this file! Make a pull request on changing
2-
# github/workflows/symfony/javascript.yaml in
3-
# https://github.com/itk-dev/devops_itkdev-docker if need be.
4-
51
### ### Symfony JavaScript (and TypeScript)
62
###
73
### Validates JavaScript files.
@@ -23,8 +19,6 @@ on:
2319
jobs:
2420
javascript-lint:
2521
runs-on: ubuntu-latest
26-
strategy:
27-
fail-fast: false
2822
steps:
2923
- name: Checkout
3024
uses: actions/checkout@v6

0 commit comments

Comments
 (0)