Uh oh!
There was an error while loading. Please reload this page.
ci: consolidate workflow templates into lint and php - #148
Draft
turegjorup wants to merge 5 commits into
Draft
Conversation
A runner job is billed a whole minute however little it does, and pays for its own checkout and image pull. Eleven templates meant up to eleven jobs per commit, most of them finishing in well under a minute. Group the checks by what they need rather than by tool: - <type>/lint.yaml replaces changelog, markdown, yaml, styles and javascript. Nothing here needs the project's dependencies. - <type>/php.yaml absorbs composer and twig, so composer install runs once and every check reuses the result. Every check keeps running when an earlier one fails, so a pull request still reports all problems at once rather than stopping at the first. Use --no-deps throughout: none of these checks touch the database or cache services, so there is no reason to start or pull them. Cache the vendor directory keyed on composer.lock and docker-compose.yml to avoid re-downloading dependencies on every run. github-actions-link now maps a workflow to several configuration folders, since a consolidated workflow needs the configuration of every topic it covers. Linking the generic folder before the project type specific one also means the specific one wins where both exist.
The install step had no guard, so a failing composer validate skipped it and left the checks that need vendor to fail for the wrong reason. Guard it too, and skip the vendor-dependent checks when the install itself fails so they report as skipped rather than failed. composer audit --locked and composer validate --strict read the lock and manifest, so they keep running regardless.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft. Groups the workflow templates by what a check needs instead of by which tool runs it, so a commit pays for two runner jobs rather than up to eleven.
Measured on
itk-devfor August 2026: the eight private repos billed 1,828 Actions minutes, of which 1,399 werereferenceregisteralone. Actual compute was 1,167 minutes — 700 of the billed minutes were the per-job round-up, because 953 of 1,287 jobs finished in under 60 seconds. This PR targets that, not runtime.Changes
github/workflows/<type>/lint.yaml— replaceschangelog.yaml,markdown.yaml,yaml.yaml,<type>/styles.yamland<type>/javascript.yaml. Nothing in it needs the project's dependencies, so it runsmarkdownlintandprettieronly.composer.yamlandtwig.yamlintogithub/workflows/<type>/php.yaml—composer installruns once and validate, normalize, audit, coding standards and Twig all reuse it.task/scripts/github-actions-link— a workflow can now map to several configuration folders (php.yaml→php+twig,lint.yaml→markdown+yaml). The generic folder is linked before the project type specific one, so the specific one wins where both exist.docs/regenerated, and the naming-convention prose updated (it referencedmarkdown.yaml, which no longer exists).Estimated saving
Top ten repositories by Actions minutes in August 2026, taken from the org usage dashboard, with the model applied to each. Minutes are metered per job including GitHub's whole-minute round-up. Only private repositories are billed — public-repo minutes on standard runners are free, so they are runner time saved, not money.
Of that 1,092, 470 minutes are billable (the four private repos) and 622 are free runner time.
Across all fourteen repositories that ran template workflows in August: 5,008 → 3,858, saving 1,150 minutes — 528 of them billable, 26% of the 2,000-minute quota. At a more conservative 15 s per eliminated job the total is 1,063.
Method and exclusions
openid-connect-bundle803 vs 803,selvbetjening271 vs 272,itk-projects66 vs 67,os2loop58 vs 56 — exceptdeltag.aarhus.dk, which measures 1,482 against the dashboard's 1,377.docker composewarmup).changelog,markdown,yaml,styles,javascript,composer,php,twig. Repo-local workflows such asreferenceregister'scode-analysis.yaml,docs.yamlanduser-manual.yamlare left out.openid-connect-bundle/php.yamlis excluded. It is not the template but a nine-job PHP-version matrix (unit tests across 8.3/8.4/8.5 × prefer-lowest/prefer-stable, mutation tests, PHPStan, coding standards). Consolidating that would defeat the matrix. Its 474 minutes stay as they are. Itscomposer.yamlis counted, and is worth a look on its own: four jobs, two of which are aprefer-lowest/prefer-stablematrix that no step ever reads.openid-connect-bundle/php.yamltriggers that.Relation to the open PRs
docker compose pull) — not adopted. @rimi-itk's review suggested--no-depsinstead, which is better: with--no-depsthe database and cache images are never pulled or started for checks that do not touch them, and there is no extra step to maintain. Everydocker compose runhere uses it.actions/cache@v6onvendor, keyed oncomposer.lockanddocker-compose.yml, so we stop re-downloading dependencies and hitting registry rate limits.actions/checkout@v7andactions/cache@v6are both the current latest (checkout v7.0.1, cache v6.1.0).Open questions
php.yamlcovering Composer and Twig is defensible;lint.yamlis more of a how. Better name welcome.Markdown,YAML,Composer,Twigetc. disappear andLint/PHPappear. Every repo with branch protection needs its required checks updated in step with the template update, or merges will block on checks that can never report.paths:filters meantstyles.yamlonly ran when CSS changed.lint.yamlruns on every pull request, so long-standing violations in untouched files appear immediately. Worth running each linter across the affected repos once before rolling this out.Test plan
Not yet run against a real project — that is what keeps this a draft.
Done so far:
task github-actions:linkregenerates every symlink; each project template resolves tolint.yaml,php.yaml(+site.yamlfor Drupal) plus the right config files —.markdownlint.jsonc,.markdownlintignore,.prettierrc.yaml,.phpcs.xml.dist/.php-cs-fixer.dist.php,.twig-cs-fixer.dist.phptask github-actions:template-headers:updateleaves the headers unchangedtask github-actions:documentation:updateregenerates cleanly andtask lint:markdownpassestask lint:yamlpassesStill to do:
--no-depsis safe for every check in all three project typesvendorcache actually hits, and that a restoredvendordoes not upsetcomposer validate --strict