# SPDX-FileCopyrightText: 2021-2026 Nextcloud GmbH and Nextcloud contributors # SPDX-License-Identifier: MIT name: PHP on: pull_request permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: changes: runs-on: selfhosted permissions: contents: read pull-requests: read outputs: src: ${{ steps.changes.outputs.src}} steps: - uses: https://github.com/dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: changes continue-on-error: true with: filters: | src: - '.github/workflows/**' - 'appinfo/**' - 'lib/**' - 'templates/**' - 'tests/**' - 'vendor/**' - 'vendor-bin/**' - '.php-cs-fixer.dist.php' - 'composer.json' - 'composer.lock' - 'openapi*.json' - '**.php' versions: runs-on: selfhosted needs: changes if: needs.changes.outputs.src != 'false' outputs: php-min: ${{ steps.versions.outputs.php-min }} php-max: ${{ steps.versions.outputs.php-max }} php-list: ${{ steps.php-list.outputs.php-list }} steps: - name: Checkout app uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Get version matrix id: versions uses: https://github.com/icewind1991/nextcloud-version-matrix@8a7bac6300b2f0f3100088b297995a229558ddba # v1.3.2 - name: Check enforcement of minimum PHP version ${{ steps.versions.outputs.php-min }} in psalm.xml run: grep 'phpVersion="${{ steps.versions.outputs.php-min }}' psalm.xml - name: Build PHP version list id: php-list run: echo 'php-list=["${{ steps.versions.outputs.php-min }}", "${{ steps.versions.outputs.php-max }}"]' >> "$GITHUB_OUTPUT" php: runs-on: selfhosted needs: [changes, versions] if: needs.changes.outputs.src != 'false' container: image: docker.io/setupphp/node:php-${{ matrix.php-version }}-bookworm strategy: fail-fast: false matrix: php-version: ${{ fromJson(needs.versions.outputs.php-list) }} name: PHP ${{ matrix.php-version }} steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Restore composer binary uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 id: composer-bin-cache with: path: .ci-bin/composer key: composer-2-${{ runner.os }}-php-${{ matrix.php-version }}-bookworm - name: Install composer if: steps.composer-bin-cache.outputs.cache-hit != 'true' run: | mkdir -p .ci-bin curl -sS https://getcomposer.org/installer | php -- --install-dir=.ci-bin --filename=composer - name: Save composer binary if: steps.composer-bin-cache.outputs.cache-hit != 'true' uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: .ci-bin/composer key: ${{ steps.composer-bin-cache.outputs.cache-primary-key }} - name: Add composer to PATH run: | chmod +x .ci-bin/composer echo "$GITHUB_WORKSPACE/.ci-bin" >> "$GITHUB_PATH" - name: Restore composer vendor cache uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 id: vendor-cache with: path: | vendor vendor-bin/*/vendor key: ${{ runner.os }}-composer-vendor-${{ matrix.php-version }}-ocp-none-${{ hashFiles('composer.lock', 'vendor-bin/*/composer.lock') }} restore-keys: | ${{ runner.os }}-composer-vendor-${{ matrix.php-version }}-ocp-none- - name: Install dependencies if: steps.vendor-cache.outputs.cache-hit != 'true' run: composer i --prefer-dist - name: Save composer vendor cache if: steps.vendor-cache.outputs.cache-hit != 'true' uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | vendor vendor-bin/*/vendor key: ${{ steps.vendor-cache.outputs.cache-primary-key }} - name: PHP syntax lint id: phplint continue-on-error: true run: composer run lint - name: PHP-CS id: phpcs continue-on-error: true run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 ) - name: Regenerate OpenAPI id: openapi continue-on-error: true run: | composer run openapi bash -c "[[ ! \"\`git status --porcelain\`\" ]] || (echo 'Please run \"composer run openapi\" and commit the openapi*.json files' && git status && git --no-pager diff && exit 1)" - name: Fail if any PHP check failed if: >- steps.phplint.outcome == 'failure' || steps.phpcs.outcome == 'failure' || steps.openapi.outcome == 'failure' || steps.advisories.outcome == 'failure' run: exit 1 summary: permissions: contents: none runs-on: selfhosted needs: [changes, php] if: always() name: php-summary steps: - name: Summary status run: if ${{ needs.changes.outputs.src != 'false' && needs.php.result != 'success' }}; then exit 1; fi