A twelve-minute pipeline that reports a lint failure at minute eleven trains people to push and switch tasks, which is the opposite of what CI is for.
stages: [check, test, build, deploy]
lint:
stage: check # 40 seconds
script: [vendor/bin/phpcs --report=summary, vendor/bin/phpstan]
unit:
stage: test # 2 minutes
integration:
stage: test # 6 minutes, in parallel with unit
# cheapest and most likely to fail, first.
Ordering by cost-to-run rather than by conceptual grouping is the whole technique, and it is free. The measure worth tracking is time-to-first-failure rather than total pipeline duration — a pipeline that takes twelve minutes to succeed and forty seconds to fail is a good pipeline. Running the two test suites in parallel within a stage costs nothing extra when the runners are there and is the other easy win.