Reduce CI pipeline runtime #46
Labels
No labels
bug
duplicate
enhancement
good first issue
help wanted
question
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lvl0/incr#46
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
CI runs are taking longer than necessary. Investigate and apply optimisations to bring down total pipeline time.
Areas to investigate
composer.locknode_moduleskeyed onpackage-lock.jsonsetup-phpreinstalls extensions on every run; check if a pre-built image with extensions baked in would be fasterncwait loop adds up to 60s worst-case; check if a healthcheck-based approach is faster in practiceStays in v0.4.0, which has been repurposed as the simplification milestone.
#57 is the concrete implementation of this: prebuilt CI image +
images.yml, mirroring ffr's approach. This ticket holds the goal and the before/after timing; #57 holds the method.Cheapest to do after #52 — once React is gone the
npm ci+npm run buildjob largely disappears, which changes what the CI image needs to contain.Implementation landed in #57 (
1fecc2b) — this ticket now holds the measurementci.ymlruns in a prebuiltincr-ci:php8.3-1image. Removed from every run:setup-phpinstalling PHP 8.3 with 8 extensions plus pcov, from scratchKept deliberately: the
mysql:8.0service and its readiness loop. The migration tests queryinformation_schemaand exercise MySQL-specific DDL, so SQLite would weaken real coverage.Also from #52, which shrank the other job: the frontend build went from 2264 modules and 311 kB of JS to 2 modules and CSS only, so
npm cinow installs 4 packages and the build takes ~140ms.To close this ticket
The before/after numbers cannot be taken until the image exists, which happens when v0.4.0 merges to
mainandimages.ymlfires.After the first green run on
main:cijob1fecc2brun for the baselineExpect the saving to come almost entirely from the vanished
setup-phpstep. The MySQL wait loop is unchanged and will still dominate the remaining startup cost — if it turns out to be the bulk of what is left, replacing the 30×2s poll with a proper service healthcheck is the obvious follow-up.Done — CI is green and fast
Runs #38 and #39, both jobs passing twice consecutively:
ci(lint, PHPStan, tests, coverage)build(npm ci, vite build)Before / after
cijobThe worst historical runs (
41m47s,32m23s,29m27s) were dominated bysetup-phpand MySQL startup. Both are gone.What actually delivered the win
Not the prebuilt image alone. In order of impact:
setup-phpno longer installs PHP and eight extensions on every run.~/.composer/cache; the image uses~/.cache/composer, so nothing was ever cached.The road here
The service container was never going to work. Runner-level
docker eventsshowed MySQL starting cleanly and running 102 seconds before being SIGKILLed at cleanup — it was healthy the whole time. The job container simply could not route to it: service and job containers land on differently-truncatedWORKFLOW-*networks. Runner-internal, and not worth changing global runner config that every other project depends on.Four workflow-level theories were tried and disproved along the way (networking, startup timing, registry qualification, missing Docker CLI). The lesson recorded for next time: when a service container is unreachable, check
docker eventson the runner first — it distinguishes "never created", "crashed" and "running but unreachable" in one shot, and each has a completely different fix.Also fixed en route
withoutVite()inTestCase— the page-render test needed a Vite manifest thecijob never buildsgitandca-certificatesin thebuildjob —checkout@v4without git falls back to a REST tarball Forgejo does not serve (404), and without CA certs cannot verify the forge's TLS certificateCost
CI no longer exercises MySQL; dev and production still do. For a single-table app with no raw SQL that is an acceptable trade, but it is a real reduction — an engine-specific bug could now reach production unseen.