CI / Tests (PHP 8.2) (pull_request) Successful in 25s
CI / Tests (PHP 8.1) (pull_request) Successful in 26s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.3) (pull_request) Successful in 32s
CI / Coding Standards & Static Analysis (pull_request) Successful in 42s
CI / Tests (PHP 8.5) (pull_request) Successful in 32s
CI / Build Plugin Zip (pull_request) Skipped
composer.lock was gitignored, so `composer install` resolved the graph afresh on every job. CI could quietly start testing different dependency versions than it did the day before, and two builds of the same tag could ship different vendor trees — the run that produces the zip is the same run that picks the versions. Track the lock, and make the two places that consume it use it: - the Composer cache keys hash composer.lock rather than composer.json, since the lock is now what actually fingerprints the dependency set; - bin/build-zip.sh stages the lock alongside composer.json, so the --no-dev production install resolves to the locked versions. It already deleted both from the staging directory before zipping, so the shipped plugin is unchanged. The current lock installs cleanly on 8.1: nothing in it requires a PHP newer than the >=8.1 composer.json declares. Closes #187 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01D9acV1mHktGAb1uyvNmrR2
127 lines
4.1 KiB
YAML
127 lines
4.1 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- develop
|
|
pull_request:
|
|
|
|
# Every job that needs PHP runs inside a prebuilt image from the Gitea
|
|
# container registry (see docs/ci.md). Nothing installs PHP at job time:
|
|
# setup-php's apt path for 8.3+ was a ~145s floor against ~35s for 8.1/8.2,
|
|
# with a tail that twice ran past the step timeout and failed the run
|
|
# (#178, #187). The images are published by ci-images.yml; the org is public,
|
|
# so they pull without credentials.
|
|
#
|
|
# The registry path is spelled out in full at each use because
|
|
# jobs.<id>.container.image cannot read the `env` context.
|
|
|
|
jobs:
|
|
# PHPCS and PHPStan share a job so the two of them install dependencies
|
|
# once rather than twice. They run as separate steps, and PHPCS failing
|
|
# stops the job before PHPStan reports.
|
|
quality:
|
|
name: Coding Standards & Static Analysis
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: git.unsupervised.ca/unsupervised/ci-php:8.3
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# COMPOSER_HOME is /composer in the CI image.
|
|
- name: Cache Composer packages
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: /composer/cache
|
|
key: composer-${{ hashFiles('composer.lock') }}
|
|
|
|
- name: Install dependencies
|
|
run: composer install --prefer-dist --no-progress --no-interaction
|
|
|
|
- name: Run PHPCS
|
|
run: composer cs
|
|
|
|
- name: Run PHPStan
|
|
run: composer lint
|
|
|
|
test:
|
|
name: Tests (PHP ${{ matrix.php }})
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: git.unsupervised.ca/unsupervised/ci-php:${{ matrix.php }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# Adding a version here needs the matching image published first —
|
|
# see docs/ci.md.
|
|
php:
|
|
- '8.1'
|
|
- '8.2'
|
|
- '8.3'
|
|
- '8.5'
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Cache Composer packages
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: /composer/cache
|
|
key: ${{ matrix.php }}-composer-${{ hashFiles('composer.lock') }}
|
|
|
|
- name: Install dependencies
|
|
run: composer install --prefer-dist --no-progress --no-interaction
|
|
|
|
- name: Run PHPUnit
|
|
run: composer test
|
|
|
|
# No PHP needed, so this one stays on the runner image — and it wants GNU
|
|
# grep's --include, which the runner has.
|
|
no-debug:
|
|
name: No Debug Code
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Check for debug statements
|
|
run: |
|
|
# \b keeps method calls like DateTimeImmutable::add() from matching dd(.
|
|
if grep -rn --include="*.php" -E "\b(var_dump|var_export|print_r|error_log|dd|dump)\s*\(" src/; then
|
|
echo "Debug code found in src/ — please remove before merging."
|
|
exit 1
|
|
fi
|
|
|
|
build:
|
|
name: Build Plugin Zip
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: git.unsupervised.ca/unsupervised/ci-php:8.3
|
|
# Only build a shippable artifact once changes land on main, and only
|
|
# after the quality gates pass.
|
|
needs: [quality, test, no-debug]
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Build plugin zip
|
|
run: composer build
|
|
|
|
- name: Read plugin version
|
|
id: meta
|
|
run: |
|
|
version="$(sed -nE 's/^[[:space:]]*\*?[[:space:]]*Version:[[:space:]]*([^[:space:]]+).*/\1/p' unsupervised-schedular.php | head -1)"
|
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
|
|
|
# Gitea/Actions re-zips artifacts on download. Upload the unpacked plugin
|
|
# folder (not the built zip) so the downloaded archive's top level is
|
|
# unsupervised-schedular/ and installs directly in WordPress. Uploading
|
|
# the zip instead double-wraps it ("No valid plugins were found").
|
|
- name: Unpack plugin for artifact
|
|
run: unzip -q "dist/unsupervised-schedular-${{ steps.meta.outputs.version }}.zip" -d artifact
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: unsupervised-schedular-${{ steps.meta.outputs.version }}
|
|
path: artifact/
|
|
if-no-files-found: error
|