Skip to content

CI cleanup: cache vendor + node_modules, --no-deps, doc each workflow, rework apispec#419

Merged
turegjorup merged 8 commits into
feature/update-infrastructure-for-mono-repofrom
feature/ci-cleanup
May 1, 2026
Merged

CI cleanup: cache vendor + node_modules, --no-deps, doc each workflow, rework apispec#419
turegjorup merged 8 commits into
feature/update-infrastructure-for-mono-repofrom
feature/ci-cleanup

Conversation

@turegjorup

@turegjorup turegjorup commented May 1, 2026

Copy link
Copy Markdown
Contributor

Description

Stacks on top of #323. Independent cleanups, each in its own commit. No docker-compose.yml changes.

  1. Cache vendor/ across PHP workflows (actions/cache@v5 keyed on composer.lock). Wall-time saving is small (Symfony auto-scripts run on every install regardless), but the cache avoids hitting Packagist on every CI run — kept as good citizenship.
  2. Skip mariadb on database-less workflows--no-deps on docker compose run for code-analysis, rector, twig-cs, php-cs-fixer, composer normalize/validate, and the prod composer-install validator. Compose file unchanged; phpunit/doctrine/playwright keep depends_on.
  3. Cache node_modules/ in JS workflowsactions/cache@v5 keyed on package-lock.json for vitest.yaml and playwright.yaml.
  4. Drop no-op strategy.fail-fast from seven non-matrix workflows.
  5. Drop the itk-dev tooling header, document every workflow uniformly — eight workflows carried a stale "do not edit" header pointing at itk-dev/devops_itkdev-docker. The remaining eleven workflows had no header documentation; they get the same ### ### Title / Description / Assumptions shape.
  6. Rework apispec.yaml — adapts itksites' two-job api-spec workflow with one behaviour change: stay quiet when the spec is unchanged. Posts a single edited-in-place comment on (a) drift, (b) non-breaking changes (changelog), or (c) breaking changes (changelog + failure). Pinned oasdiff-action to v0.0.44, added a paths: filter, breaking-changes job depends on the export job. Excluded from the benchmark below — its scope changed.

Measured timings

Two CI runs back-to-back: the first populated caches; the second is the cache-hot baseline this PR's caching gives going forward.

Workflow Baseline (#323) Cold (this PR) Hot (this PR) Hot vs Baseline
Test (phpunit) 187s 193s 172s −15s
Code Analysis 57s 52s 45s −12s
Rector 56s 53s 44s −12s
Composer (audit) 51s 43s 40s −11s
Composer install 45s 38s 40s −5s
Doctrine 45s 47s 50s within variance
Symfony PHP 46s 45s 57s within variance
Twig 44s 35s 55s within variance
Unit tests (vitest) 34s 48s 39s +5s (cache overhead)

The wins are driven by --no-deps (mariadb skip) on database-less workflows, not by vendor caching itself — Symfony's auto-scripts (cache:clear, assets:install) run on every composer install, swamping any package-download saving. Vendor cache is kept anyway because every CI run otherwise pulls the same packages from Packagist.

node_modules/ cache trims npm install from 32s to 19s on the install step, but ~3s cache save/restore overhead and runner variance net out a modest delta on the wall-time.

CI runner variance is ~10-15s for these workflows; single-run benchmarks at this scale are noisy.

Net

Per-PR savings on the slowest workflow (phpunit, the gating one): ~15s. Less than the original estimate, but consistent across runs.

Notes

  • actions/cache@v5.0.5, oasdiff-action@v0.0.44.
  • Targets feature/update-infrastructure-for-mono-repo so the diff stays scoped.
  • Possible follow-up (out of scope for this PR): composer install --no-scripts on static-analysis-only workflows would shave ~15s off each by skipping the auto-scripts. Needs a check that PHPStan etc. don't need the container dump.

Checklist

  • My code is covered by test cases. (CI itself is the test.)
  • My code passes our test (all our tests).
  • My code passes our static analysis suite.
  • My code passes our continuous integration process.

turegjorup and others added 6 commits May 1, 2026 08:12
Each PHP workflow currently spends ~30s on a cold composer install for
the same composer.lock — across nine workflows that's roughly four
minutes of duplicated work per push. actions/cache keyed on
composer.lock makes the install a near no-op when the lockfile is
unchanged. Dev installs share one key (vendor-php8.4-…); the doctrine
workflow's --no-dev install gets its own (vendor-prod-php8.4-…) so
prod and dev caches don't clobber each other. composer_install.yaml
intentionally stays uncached: its purpose is validating that a fresh
prod-mode install works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
phpfpm declares depends_on: mariadb (service_healthy), so every
docker compose run on it pulls and boots mariadb plus waits for the
healthcheck — wasted work for code-analysis, rector, twig-cs,
php-cs-fixer, composer normalize/validate, and the prod-mode
composer-install validator. --no-deps starts only the requested
service. The compose file is unchanged; doctrine, phpunit, and
playwright still pull mariadb because they actually need it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vitest spends ~31s of its ~34s wall time on a cold npm install;
Playwright pays the same toll. actions/cache keyed on package-lock.json
turns the install into a near no-op when the lockfile is unchanged.
node_modules lives at the repo root and is bind-mounted into the node
service via .:/app, so the docker compose setup is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fail-fast only applies to matrix-strategy jobs; declaring it on a
single-job workflow is dead config that adds reading overhead and
implies a matrix where there is none. Stripping it from the seven
workflows that carry it without any matrix:.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight workflows carried an itk-dev/devops_itkdev-docker "do not edit"
header that no longer applies in this repo. Stripping the three-line
header preserves the existing ### ### Title / Description /
Assumptions docs that follow it. The remaining eleven workflows had no
header documentation; they get the same shape (title, one-paragraph
purpose, Assumptions list) so a reader can land on any workflow file
and learn what it does and what it relies on without leaving the file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adapts itk-dev/devops_itksites's two-job api-spec workflow to this
repo's v2 spec layout, with one behaviour change: stay quiet when the
spec is unchanged. itksites' "no changes detected" comment lands on
every PR that touches src/, which is most of them; suppressing that
branch removes the noise while keeping the signal — the workflow now
only posts on (a) committed spec out of date with the source,
(b) non-breaking spec changes (changelog), or (c) breaking spec
changes (changelog + failure). --edit-last keeps the PR to one
in-place comment across pushes.

Pinned oasdiff-action to v0.0.44 instead of @main; path filters
restrict the run to PRs that could plausibly affect the spec; the
breaking-changes job depends on the export job so a drifting spec
isn't compared against the base.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@turegjorup turegjorup self-assigned this May 1, 2026
turegjorup and others added 2 commits May 1, 2026 09:00
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@turegjorup
turegjorup requested a review from tuj May 1, 2026 07:23

@tuj tuj left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with comment


- name: Check for changes in specifications (json)
run: git diff --diff-filter=ACMRT --exit-code public/api-spec-v2.json
- name: Fail if breaking changes detected

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we handle if we want to merge breaking changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With comment on PR explaining motivation/reasoning.

@turegjorup
turegjorup merged commit 3eb1659 into feature/update-infrastructure-for-mono-repo May 1, 2026
16 of 17 checks passed
@turegjorup
turegjorup deleted the feature/ci-cleanup branch May 1, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants