diff --git a/.gitea/actions/ci-lint-php/action.yml b/.gitea/actions/ci-lint-php/action.yml index d831bb7..2e83a3b 100644 --- a/.gitea/actions/ci-lint-php/action.yml +++ b/.gitea/actions/ci-lint-php/action.yml @@ -6,7 +6,20 @@ inputs: runs: using: composite steps: - - name: Setup PHP ${{ inputs.php }} + - name: Use preinstalled PHP ${{ inputs.php }} (peptide-php image) + id: pre + shell: bash + env: + V: ${{ inputs.php }} + run: | + if command -v "php$V" >/dev/null 2>&1; then + update-alternatives --set php "/usr/bin/php$V" >/dev/null 2>&1 || ln -sf "/usr/bin/php$V" /usr/local/bin/php + php -v | head -1; echo "hit=true" >> "$GITHUB_OUTPUT" + else + echo "hit=false" >> "$GITHUB_OUTPUT" + fi + - name: Setup PHP ${{ inputs.php }} (fallback when not preinstalled) + if: ${{ steps.pre.outputs.hit != 'true' }} uses: shivammathur/setup-php@v2 with: php-version: ${{ inputs.php }} diff --git a/.gitea/actions/ci-phpcs/action.yml b/.gitea/actions/ci-phpcs/action.yml index ab5b83e..c754002 100644 --- a/.gitea/actions/ci-phpcs/action.yml +++ b/.gitea/actions/ci-phpcs/action.yml @@ -10,7 +10,18 @@ inputs: runs: using: composite steps: - - name: Setup PHP + - name: Use preinstalled PHP 8.1 (peptide-php image) + id: pre + shell: bash + run: | + if command -v php8.1 >/dev/null 2>&1 && command -v composer >/dev/null 2>&1; then + update-alternatives --set php /usr/bin/php8.1 >/dev/null 2>&1 || ln -sf /usr/bin/php8.1 /usr/local/bin/php + php -v | head -1; echo "hit=true" >> "$GITHUB_OUTPUT" + else + echo "hit=false" >> "$GITHUB_OUTPUT" + fi + - name: Setup PHP (fallback when not preinstalled) + if: ${{ steps.pre.outputs.hit != 'true' }} uses: shivammathur/setup-php@v2 with: php-version: '8.1' @@ -27,6 +38,9 @@ runs: "wp-coding-standards/wpcs:^3.0" \ "phpcsstandards/phpcsutils:^1.0" \ "phpcsstandards/phpcsextra:^1.0" + # Without setup-php's `tools: phpcs`, phpcs/phpcbf come from the global + # composer bin dir (WPCS pulls in squizlabs/php_codesniffer). + composer global config bin-dir --absolute 2>/dev/null | tail -1 >> "$GITHUB_PATH" - name: Auto-fix with phpcbf (PR only, commit back if changed) if: ${{ github.event_name == 'pull_request' && inputs.autofix == 'true' }} diff --git a/.gitea/actions/ci-phpunit/action.yml b/.gitea/actions/ci-phpunit/action.yml index 704bd4d..758952e 100644 --- a/.gitea/actions/ci-phpunit/action.yml +++ b/.gitea/actions/ci-phpunit/action.yml @@ -21,7 +21,20 @@ runs: shell: bash run: command -v svn >/dev/null || (sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends subversion) - - name: Setup PHP ${{ inputs.php }} + - name: Use preinstalled PHP ${{ inputs.php }} (peptide-php image) + id: pre + shell: bash + env: + V: ${{ inputs.php }} + run: | + if command -v "php$V" >/dev/null 2>&1 && command -v composer >/dev/null 2>&1; then + update-alternatives --set php "/usr/bin/php$V" >/dev/null 2>&1 || ln -sf "/usr/bin/php$V" /usr/local/bin/php + php -v | head -1; echo "hit=true" >> "$GITHUB_OUTPUT" + else + echo "hit=false" >> "$GITHUB_OUTPUT" + fi + - name: Setup PHP ${{ inputs.php }} (fallback when not preinstalled) + if: ${{ steps.pre.outputs.hit != 'true' }} uses: shivammathur/setup-php@v2 with: php-version: ${{ inputs.php }} diff --git a/.gitea/workflows/pipeline.yml b/.gitea/workflows/pipeline.yml index 0978875..183d7a6 100644 --- a/.gitea/workflows/pipeline.yml +++ b/.gitea/workflows/pipeline.yml @@ -16,6 +16,7 @@ jobs: lint-php: name: PHP Lint (${{ matrix.php }}) runs-on: ubuntu-latest + container: git.protopeer.com/peptide-repo/ci-php:2026-10 strategy: fail-fast: false matrix: @@ -29,6 +30,7 @@ jobs: phpcs: name: PHPCS (WordPress standards) runs-on: ubuntu-latest + container: git.protopeer.com/peptide-repo/ci-php:2026-10 steps: - uses: actions/checkout@v4 with: diff --git a/ci-image/Dockerfile b/ci-image/Dockerfile new file mode 100644 index 0000000..2bc0aa1 --- /dev/null +++ b/ci-image/Dockerfile @@ -0,0 +1,15 @@ +# peptide-ci-php: Gitea runner image with PHP 8.1/8.2/8.3 + Composer preinstalled. +# Why: shivammathur/setup-php treats the stock runner image as a bare self-hosted +# box and apt-installs a whole compiler toolchain on every job (~5-10 min each). +# Built into the gitea-dind daemon by ci-image/build.sh; runner label `peptide-php`. +FROM docker.gitea.com/runner-images@sha256:fd911d7417bfbf0f454530e447da95b58001e1df41bbc5e1a8dd35d432575aae +RUN set -eux; export DEBIAN_FRONTEND=noninteractive; \ + apt-get update; apt-get install -y --no-install-recommends software-properties-common gnupg unzip mariadb-client; \ + add-apt-repository -y ppa:ondrej/php; apt-get update; \ + for v in 8.1 8.2 8.3; do \ + apt-get install -y --no-install-recommends php$v-cli php$v-common php$v-mbstring php$v-xml php$v-curl php$v-zip php$v-mysql php$v-intl php$v-bcmath php$v-gd; \ + done; \ + update-alternatives --set php /usr/bin/php8.3; \ + curl -fsSL https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer; \ + composer --version; php8.1 -v | head -1; php8.2 -v | head -1; php8.3 -v | head -1; \ + rm -rf /var/lib/apt/lists/* diff --git a/ci-image/build.sh b/ci-image/build.sh new file mode 100755 index 0000000..d7ade4f --- /dev/null +++ b/ci-image/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Build peptide-ci-php into the gitea-dind daemon the shared runner uses. +set -e +TAG=peptide-ci-php:2026-10 +docker exec -i gitea-dind docker build -t "$TAG" - < "$(dirname "$0")/Dockerfile" +docker exec gitea-dind docker image inspect "$TAG" --format '{{.Id}} {{.Size}}' diff --git a/tools/gitea-pipeline/render.py b/tools/gitea-pipeline/render.py index d739683..7c26073 100644 --- a/tools/gitea-pipeline/render.py +++ b/tools/gitea-pipeline/render.py @@ -12,6 +12,9 @@ import json import sys A = "https://git.protopeer.com/peptide-repo/peptide-e2e/.gitea/actions" +# CI image with PHP 8.1/8.2/8.3 + Composer preinstalled (peptide-e2e/ci-image). +# Without it setup-php bootstraps a compiler toolchain on every job (5-20 min). +CI_IMAGE = "git.protopeer.com/peptide-repo/ci-php:2026-10" DEFAULTS = {"tests": "stubs", "has_js": False, "line_limit_paths": "includes", "enforce_300": True, "phpcs_autofix": True, "audit": True, "php_versions": ["8.1", "8.2", "8.3"], "extras": []} @@ -24,10 +27,8 @@ EXTRAS = { runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - coverage: none + - name: Use PHP 8.1 (preinstalled in the CI image) + run: update-alternatives --set php /usr/bin/php8.1 && php -v | head -1 # Fails if any PRAUTOBLOGGER_* constant referenced in shipped PHP is neither # defined in prautoblogger.php nor guarded by defined() (v0.19.0 incident class). - run: php scripts/check-constants.php @@ -244,7 +245,9 @@ jobs: with: token: ${{{{ secrets.GITHUB_TOKEN }}}} """) - return "".join(out) + return "".join(out).replace( + " runs-on: ubuntu-latest\n", + f" runs-on: ubuntu-latest\n container: {CI_IMAGE}\n") if __name__ == "__main__":