agentleFS
AnyOrgNameAnyOrgName/php-skills/skills/devops/ci-github-actions/SKILL.md

ci-github-actions

Skill4 starsChanged 4 months agoMITView on GitHub

Build a fast, reliable GitHub Actions pipeline for PHP — version matrix, Composer caching, and PHPStan plus Pest quality gates. Use when the user wants to run their test suite against several PHP versions in a build matrix; the user wants a GitHub Actions workflow that installs, tests, and statically analyzes a PHP project on every push or pull request; the user wants to cache Composer dependencies and parallelize steps to make a slow PHP CI run faster. Keywords: ci, github-actions, matrix, phpstan, pest, composer-cache.

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not apply this skill's GitHub Actions YAML when the project's CI system is GitLab CI, Jenkins, or CircleCI.

    line 65
  2. Distinctive:

    Do not use this skill for zero-downtime release mechanics or rollback logic.

    line 66
  3. Very specific:

    Create .github/workflows/ci.yml triggered on push and pull_request, with a strategy.matrix.php listing the supported versions and …

    line 79
  4. Very specific:

    Add shivammathur/setup-php with the matrix version and required extensions, then install dependencies with a cache keyed on the …

    line 81
  5. Very specific:

    Add a PHPStan step at a pinned level and a pest step (coverage on one cell), neither using continue-on-error, so a regression blocks the …

    line 83
  6. Very specific:

    Run ./vendor/bin/pest (with --coverage on one matrix cell only) and fail the job on any failing test or a coverage drop below the threshold

    line 88
  7. Very specific:

    Add a dedicated PHPStan step with a pinned level and no continue-on-error, so static-analysis regressions block the merge

    line 90
  8. Distinctive:

    Not applicable — no I/O, auth, or untrusted input.

    line 121

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- generated: do not edit — source: knowledge/atoms/devops/ci-github-actions/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->

PHP CI with GitHub Actions

When to use

  • The user wants to run their test suite against several PHP versions in a build matrix.
  • The user wants a GitHub Actions workflow that installs, tests, and statically analyzes a PHP project on every push or pull request.
  • The user wants to cache Composer dependencies and parallelize steps to make a slow PHP CI run faster.

When NOT to use

  • Do not apply this skill's GitHub Actions YAML when the project's CI system is GitLab CI, Jenkins, or CircleCI.
  • Do not use this skill for zero-downtime release mechanics or rollback logic; those belong to the deployment skill.

Core guidance

  • Cache the Composer cache dir keyed by composer.lock — Cache Composer's global cache directory with a key derived from a hash of composer.lock, and use the ramsey/composer-install action or an explicit restore.
  • Test the versions you actually support in a matrix — Declare a strategy.matrix.php listing exactly the PHP versions in your support policy, and set fail-fast: false so one version's failure is visible.
  • Use shivammathur/setup-php to provision the runtime — Provision PHP with the shivammathur/setup-php action, declaring the exact php-version, required extensions, and coverage driver per job.

Quick recipe

  1. Create .github/workflows/ci.yml triggered on push and pull_request, with a strategy.matrix.php listing the supported versions and fail-fast: false. (verify: The workflow shows one job per PHP version on the next pull request)
  2. Add shivammathur/setup-php with the matrix version and required extensions, then install dependencies with a cache keyed on the composer.lock hash. (verify: A second run reports a cache hit and finishes install in seconds)
  3. Add a PHPStan step at a pinned level and a pest step (coverage on one cell), neither using continue-on-error, so a regression blocks the merge. (verify: Introducing a type error or failing test turns the required check red)

Best practices

  • Run ./vendor/bin/pest (with --coverage on one matrix cell only) and fail the job on any failing test or a coverage drop below the threshold
  • Add a dedicated PHPStan step with a pinned level and no continue-on-error, so static-analysis regressions block the merge
  • Reference third-party actions by a pinned major tag (or a full commit SHA for security-sensitive pipelines) rather than a floating branch

Anti-patterns

Anti-patternWhy it failsDo instead
Quality gates marked continue-on-errorThe pipeline reports success while real failures accumulate, so the gate protects nothing.Let the analysis and test steps fail the job; fix or explicitly baseline the errors instead of masking them.
Referencing actions by a floating branchAn upstream push can change or compromise your pipeline with no commit in your repository, a supply-chain risk.Pin to a released major tag, or a full commit SHA for security-critical pipelines, and update deliberately.
Running composer install with no dependency cacheEvery run re-downloads the full dependency tree, wasting minutes and CI budget on unchanged dependencies.Cache the Composer cache directory keyed on the lockfile hash and install with --prefer-dist --no-progress.

See references/anti-patterns.md.

Common mistakes

  1. Cache key not tied to the lockfile serves stale dependencies — A Composer cache key that omits the composer.lock hash keeps restoring old packages after a dependency bump. Fix: Key the cache on hashFiles('**/composer.lock') so any dependency change produces a fresh cache while unchanged runs stay fast.
  2. pull_request from a fork cannot read secrets — Jobs triggered by pull_request from a fork run without access to repository secrets, so secret-dependent steps fail. Fix: Keep secret-free checks on pull_request, and move steps needing secrets to a gated pull_request_target or a post-merge workflow with explicit review.
  3. Tests fail in CI because an extension is missing — Forgetting to list required extensions in setup-php makes CI fail with a missing-driver error even though local tests pass. Fix: Declare every runtime and test extension in the extensions input of setup-php, mirroring what the Docker image installs.

Version notes

  • setup-php spans PHP 7.4 through 8.4 (PHP >=7.4) — shivammathur/setup-php provisions every PHP from 7.4 to 8.4, so the same matrix job template covers a legacy 7.4 target and a modern 8.4 target.

Security

  • Not applicable — no I/O, auth, or untrusted input.

Testing

  • Activation and decision behavior are verified in eval/scenarios/devops/ci-github-actions.yaml.
  • Run ./vendor/bin/pest (with --coverage on one matrix cell only) and fail the job on any failing test or a coverage drop below the threshold.

Additional resources

  • references/anti-patterns.md
  • references/core.md
  • references/examples.md
  • references/pitfalls.md
  • references/recipes.md
  • references/version-differences.md

Knowledge graph

Related: devops/deployment-strategies, devops/docker-php, phpstan/getting-started, testing/pest-basics

<!-- graph-fragment: graph/fragments/devops/ci-github-actions.yaml -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.