diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 16667f5e..dfaa0eb2 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,10 +1,19 @@ name: 'CI' + on: # Build any PRs and main branch changes workflow_dispatch: # Allows to run the workflow manually from the Actions tab pull_request: types: - opened - synchronize + paths-ignore: + # In case of updates to those workflows, they must be pre-checked by `pre-check-CI-updates.yml` rather than this workflow ! + # Any updates on those workflows are expected to be restricted to those workflows only ! (no update on code for instance) + - '.github/workflows/pre-check-CI-updates.yml' + - '.github/workflows/CI.yml' + - '.github/workflows/coverage-upload.yml' + - '.github/workflows/reusable-CI-workflow.yml' + - '.github/workflows/reusable-coverage-upload-workflow.yml' push: branches: [ master ] schedule: @@ -20,171 +29,7 @@ env: jobs: tests: - name: UTs & FTs - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - env: - COVERAGE_TYPE: xdebug - COVERAGE_OUTPUT_STYLE: clover - strategy: - fail-fast: true - max-parallel: 4 - matrix: - include: - # Bare minimum => Lowest versions allowed by composer config - - php-version: '8.0' - composer-flag: --prefer-lowest - # Up-to-date versions => Latest versions allowed by composer config - - php-version: '8.2' - steps: - - name: Check out code - uses: actions/checkout@v4 - -# @TODO Figure out if coverage for every version is actually useful or not -# - name: Enable coverage -# if: ${{ matrix.php-version == '8.2' }} -# run: | -# echo "COVERAGE_OUTPUT_STYLE=clover" >> $GITHUB_ENV -# echo "COVERAGE_TYPE=xdebug" >> $GITHUB_ENV - - - name: Setup PHP ${{ matrix.php-version }} - uses: shivammathur/setup-php@v2 - env: - update: true # Always use latest available patch for the version - fail-fast: true # step will fail if an extension or tool fails to set up - with: - php-version: '${{ matrix.php-version }}' - tools: composer - coverage: ${{ env.COVERAGE_TYPE }} - - - name: Setup cache - id: cache - uses: actions/cache@v4 - with: - path: | - ~/.composer - ./vendor - # Clear the cache if composer json (as composer.lock is in the repo) has been updated - key: tests-${{ matrix.php-version }}-${{ matrix.composer-flag }}-${{ hashFiles('composer.json') }} - - - name: Build - run: | - make build - - - name: Tests - run: make test-unit && make test-functional - - - name: Create "unit tests" reports directory - if: ${{ env.COVERAGE_TYPE == 'xdebug' }} - id: unit-tests-coverage-group - uses: yoanm/temp-reports-group-workspace/.github/actions/create-action@develop - with: - name: unit-tests - format: clover - files: build/coverage-phpunit/unit.clover - flags: | - unit-tests - php-${{ matrix.php-version }} - path: build/coverage-groups - - - name: Create "functional tests" coverage group - if: ${{ env.COVERAGE_TYPE == 'xdebug' }} - id: functional-tests-coverage-group - uses: yoanm/temp-reports-group-workspace/.github/actions/create-action@develop - with: - name: functional-tests - format: clover - files: | - build/coverage-phpunit/functional.clover - build/coverage-behat/clover.xml - flags: | - functional-tests - php-${{ matrix.php-version }} - path: build/coverage-groups - - - name: Upload coverage reports - if: ${{ env.COVERAGE_TYPE == 'xdebug' }} - uses: actions/upload-artifact@v4 - with: - name: coverage-groups-php${{ matrix.php-version }} - path: build/coverage-groups - if-no-files-found: error - - static-checks: - name: Static checks - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup PHP 8.2 - uses: shivammathur/setup-php@v2 - with: - php-version: 8.2 # Latest supported - tools: composer - coverage: none - env: - # Always use latest available patch for the version - update: true - - - name: Setup cache - id: cache - uses: actions/cache@v4 - with: - path: | - ~/.composer - # Clear the cache if composer json (as composer.lock is in the repo) has been updated - key: tests-${{ env.PHP_VERSION }}-${{ hashFiles('composer.json') }} - - - name: Build - run: make build - - - name: ComposerRequireChecker - uses: docker://webfactory/composer-require-checker:4.5.0 - - - name: Dependencies check - if: ${{ github.event_name == 'pull_request' }} - uses: actions/dependency-review-action@v4 - - nightly-tests: - name: Nightly - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - env: - COMPOSER_OPTIONS: '--optimize-autoloader --ignore-platform-req=php+' - continue-on-error: true - needs: [ static-checks, tests ] - strategy: - fail-fast: false - max-parallel: 4 - matrix: - php-version: - - '8.3' # Current php dev version - - steps: - - name: Check out code - uses: actions/checkout@v4 - - - name: Setup PHP ${{ matrix.php-version }} - uses: shivammathur/setup-php@v2 - with: - php-version: '${{ matrix.php-version }}' - tools: composer - coverage: none - env: - # Always use latest available patch for the version - update: true - - - name: Setup cache - id: cache - uses: actions/cache@v4 - with: - path: | - ~/.composer - ./vendor - # Clear the cache if composer json (as composer.lock is in the repo) has been updated - key: tests-${{ matrix.php-version }}-${{ hashFiles('composer.json') }} - - - name: Build - run: | - make build - - - name: Test - run: make test-unit && make test-functional + name: Tests + permissions: + contents: read + uses: ./.github/workflows/reusable-CI-workflow.yml diff --git a/.github/workflows/coverage-upload.yml b/.github/workflows/coverage-upload.yml index 8a6c8956..9428e0d1 100644 --- a/.github/workflows/coverage-upload.yml +++ b/.github/workflows/coverage-upload.yml @@ -1,105 +1,16 @@ -name: 'Coverage upload' +name: 'Coverage' on: workflow_run: workflows: ["CI"] types: [completed] jobs: - fetch-info: - name: Fetch triggering workflow metadata - runs-on: ubuntu-latest - permissions: - contents: read - checks: write # For the check run creation ! - steps: - - name: 'Check run ○' - uses: yoanm/temp-reports-group-workspace/.github/actions/attach-check-run-to-triggering-workflow-action@develop - with: - name: 'Fetch coverage info' - fails-on-triggering-workflow-failure: true - - - uses: yoanm/temp-reports-group-workspace/.github/actions/fetch-workflow-metadata-action@develop - id: fetch-workflow-metadata - - outputs: - commit-sha: ${{ steps.fetch-workflow-metadata.outputs.commit-sha }} - run-id: ${{ steps.fetch-workflow-metadata.outputs.run-id }} - - codacy-uploader: - name: Codacy - needs: [fetch-info] - uses: yoanm/temp-reports-group-workspace/.github/workflows/codacy-upload-from-artifacts.yml@develop + upload: + name: Upload permissions: contents: read checks: write # For the check run creation ! secrets: - PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} - with: - artifacts-pattern: coverage-groups-* - run-id: ${{ needs.fetch-info.outputs.run-id }} - - codecov-uploader: - name: Codecov - needs: [fetch-info] - uses: yoanm/temp-reports-group-workspace/.github/workflows/codecov-upload-from-artifacts.yml@develop - permissions: - contents: read - checks: write # For the check run creation ! - secrets: - TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - artifacts-pattern: coverage-groups-* - run-id: ${{ needs.fetch-info.outputs.run-id }} - override-commit: ${{ needs.fetch-info.outputs.commit-sha }} - override-branch: ${{ needs.fetch-info.outputs.branch }} - override-pr: ${{ needs.fetch-info.outputs.pr-number }} - override-build: ${{ needs.fetch-info.outputs.run-id }} - override-build-url: ${{ needs.fetch-info.outputs.run-url }} - - debug-context: - name: DEBUG - context - runs-on: ubuntu-latest - steps: - - run: | - echo '{' - echo '"github.action": ${{ toJson(github.action) }},' - echo '"github.action_path": ${{ toJson(github.action_path) }},' - echo '"github.action_ref": ${{ toJson(github.action_ref) }},' - echo '"github.action_repository": ${{ toJson(github.action_repository) }},' - echo '"github.action_status": ${{ toJson(github.action_status) }},' - echo '"github.actor": ${{ toJson(github.actor) }},' - echo '"github.actor_id": ${{ toJson(github.actor_id) }},' - echo '"github.base_ref": ${{ toJson(github.base_ref) }},' - echo '"github.event": ${{ toJson(github.event) }},' - echo '"github.event_name": ${{ toJson(github.event_name) }},' - echo '"github.event_path": ${{ toJson(github.event_path) }},' - echo '"github.head_ref": ${{ toJson(github.head_ref) }},' - echo '"github.job": ${{ toJson(github.job) }},' - echo '"github.path": ${{ toJson(github.path) }},' - echo '"github.ref": ${{ toJson(github.ref) }},' - echo '"github.ref_name": ${{ toJson(github.ref_name) }},' - echo '"github.ref_protected": ${{ toJson(github.ref_protected) }},' - echo '"github.ref_type": ${{ toJson(github.ref_type) }},' - echo '"github.repository": ${{ toJson(github.repository) }},' - echo '"github.repository_id": ${{ toJson(github.repository_id) }},' - echo '"github.repository_owner": ${{ toJson(github.repository_owner) }},' - echo '"github.repository_owner_id": ${{ toJson(github.repository_owner_id) }},' - echo '"github.repositoryUrl": ${{ toJson(github.repositoryUrl) }},' - echo '"github.run_id": ${{ toJson(github.run_id) }},' - echo '"github.run_number": ${{ toJson(github.run_number) }},' - echo '"github.run_attempt": ${{ toJson(github.run_attempt) }},' - echo '"github.sha": ${{ toJson(github.sha) }},' - echo '"github.triggering_actor": ${{ toJson(github.triggering_actor) }},' - echo '"github.workflow": ${{ toJson(github.workflow) }},' - echo '"github.workflow_ref": ${{ toJson(github.workflow_ref) }},' - echo '"github.workflow_sha": ${{ toJson(github.workflow_sha) }},' - echo '"github.workspace": ${{ toJson(github.workspace) }}' - echo '}' - - debug-uploads: - name: DEBUG - Uploaders - runs-on: ubuntu-latest - needs: [ codacy-uploader, codecov-uploader ] - steps: - - run: echo 'codecov='"'"'${{ toJson(needs.codecov-uploader) }}'"'" - - run: echo 'codacy='"'"'${{ toJson(needs.codacy-uploader) }}'"'" + CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + uses: ./.github/workflows/reusable-coverage-upload-workflow.yml diff --git a/.github/workflows/pre-check-CI-updates.yml b/.github/workflows/pre-check-CI-updates.yml new file mode 100644 index 00000000..701bf0cb --- /dev/null +++ b/.github/workflows/pre-check-CI-updates.yml @@ -0,0 +1,40 @@ +name: 'Test CI updates' +# [DESCRIPTION] +# As CI workflow relies on `workflow_run` trigger for upload, this workflow is used in order to ease updates made on +# CI workflow (or linked workflows/actions). It's kind of pre-check to ensure once updates are merged on main branch, +# the `workflow_run` workflow execution will behave as expected. + +on: + pull_request: + types: + - opened + - synchronize + branches: [master] # Only for PR targeting master branch + paths: # /!\ Duplicate the same list as `on.pull_request.paths-ignore` property value for CI workflow ! + - '.github/workflows/pre-check-CI-updates.yml' # This workflow + - '.github/workflows/CI.yml' + - '.github/workflows/coverage-upload.yml' + - '.github/workflows/reusable-CI-workflow.yml' + - '.github/workflows/reusable-coverage-upload-workflow.yml' + +concurrency: + group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}" + cancel-in-progress: true + +jobs: + tests: + name: Tests + permissions: + contents: read + uses: ./.github/workflows/reusable-CI-workflow.yml + + upload: + name: Upload + needs: [tests] + permissions: + contents: read + checks: write # For the check run creation ! + secrets: + CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + uses: ./.github/workflows/reusable-coverage-upload-workflow.yml diff --git a/.github/workflows/reusable-CI-workflow.yml b/.github/workflows/reusable-CI-workflow.yml new file mode 100644 index 00000000..cbc7d372 --- /dev/null +++ b/.github/workflows/reusable-CI-workflow.yml @@ -0,0 +1,180 @@ +name: 'CI reusable workflow' + +on: + workflow_call: + + +env: + TEST_OUTPUT_STYLE: pretty + COMPOSER_OPTIONS: --optimize-autoloader + +jobs: + tests: + name: PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + env: + COVERAGE_TYPE: xdebug + COVERAGE_OUTPUT_STYLE: clover + strategy: + fail-fast: true + max-parallel: 4 + matrix: + include: + # Bare minimum => Lowest versions allowed by composer config + - php-version: '8.0' + composer-flag: --prefer-lowest + # Up-to-date versions => Latest versions allowed by composer config + - php-version: '8.2' + steps: + - name: Check out code + uses: actions/checkout@v4 + +# @TODO Figure out if coverage for every version is actually useful or not +# - name: Enable coverage +# if: ${{ matrix.php-version == '8.2' }} +# run: | +# echo "COVERAGE_OUTPUT_STYLE=clover" >> $GITHUB_ENV +# echo "COVERAGE_TYPE=xdebug" >> $GITHUB_ENV + + - name: Setup PHP ${{ matrix.php-version }} + uses: shivammathur/setup-php@v2 + env: + update: true # Always use latest available patch for the version + fail-fast: true # step will fail if an extension or tool fails to set up + with: + php-version: '${{ matrix.php-version }}' + tools: composer + coverage: ${{ env.COVERAGE_TYPE }} + + - name: Setup cache + id: cache + uses: actions/cache@v4 + with: + path: | + ~/.composer + ./vendor + # Clear the cache if composer json (as composer.lock is in the repo) has been updated + key: tests-${{ matrix.php-version }}-${{ matrix.composer-flag }}-${{ hashFiles('composer.json') }} + + - name: Build + run: | + make build + + - name: Tests + run: make test-unit && make test-functional + + - name: Create "unit tests" reports directory + if: ${{ env.COVERAGE_TYPE == 'xdebug' }} + id: unit-tests-coverage-group + uses: yoanm/temp-reports-group-workspace/gha-create@improve + with: + name: unit-tests + format: clover + files: build/coverage-phpunit/unit.clover + flags: | + unit-tests + php-${{ matrix.php-version }} + path: build/coverage-groups + + - name: Create "functional tests" coverage group + if: ${{ env.COVERAGE_TYPE == 'xdebug' }} + id: functional-tests-coverage-group + uses: yoanm/temp-reports-group-workspace/gha-create@improve + with: + name: functional-tests + format: clover + files: | + build/coverage-phpunit/functional.clover + build/coverage-behat/clover.xml + flags: | + functional-tests + php-${{ matrix.php-version }} + path: build/coverage-groups + + - name: Upload coverage reports + if: ${{ env.COVERAGE_TYPE == 'xdebug' }} + uses: actions/upload-artifact@v4 + with: + name: coverage-groups-php${{ matrix.php-version }} + path: build/coverage-groups + if-no-files-found: error + + static-checks: + name: Static analysis + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP 8.2 + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 # Latest supported + tools: composer + coverage: none + env: + # Always use latest available patch for the version + update: true + + - name: Setup cache + id: cache + uses: actions/cache@v4 + with: + path: | + ~/.composer + # Clear the cache if composer json (as composer.lock is in the repo) has been updated + key: tests-${{ env.PHP_VERSION }}-${{ hashFiles('composer.json') }} + + - name: Build + run: make build + + - name: ComposerRequireChecker + uses: docker://webfactory/composer-require-checker:4.5.0 + + - name: Dependencies check + if: ${{ github.event_name == 'pull_request' }} + uses: actions/dependency-review-action@v4 + + nightly-tests: + name: Nightly - PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + env: + COMPOSER_OPTIONS: '--optimize-autoloader --ignore-platform-req=php+' + continue-on-error: true + needs: [ static-checks, tests ] + strategy: + fail-fast: false + max-parallel: 4 + matrix: + php-version: + - '8.3' # Current php dev version + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Setup PHP ${{ matrix.php-version }} + uses: shivammathur/setup-php@v2 + with: + php-version: '${{ matrix.php-version }}' + tools: composer + coverage: none + env: + # Always use latest available patch for the version + update: true + + - name: Setup cache + id: cache + uses: actions/cache@v4 + with: + path: | + ~/.composer + ./vendor + # Clear the cache if composer json (as composer.lock is in the repo) has been updated + key: tests-${{ matrix.php-version }}-${{ hashFiles('composer.json') }} + + - name: Build + run: | + make build + + - name: Test + run: make test-unit && make test-functional diff --git a/.github/workflows/reusable-coverage-upload-workflow.yml b/.github/workflows/reusable-coverage-upload-workflow.yml new file mode 100644 index 00000000..8476349d --- /dev/null +++ b/.github/workflows/reusable-coverage-upload-workflow.yml @@ -0,0 +1,115 @@ +name: 'Coverage upload reusable workflow' + +on: + workflow_call: + secrets: + CODACY_PROJECT_TOKEN: + required: true + CODECOV_TOKEN: + required: true + +jobs: + fetch-info: + name: Fetch triggering workflow metadata + runs-on: ubuntu-latest + permissions: + contents: read + checks: write # For the check run creation ! + steps: + - name: 'Check run ○' + uses: yoanm/temp-reports-group-workspace/gha-attach-check-run-to-triggering-workflow@improve + with: + name: 'Fetch coverage info' + fails-on-triggering-workflow-failure: true + + - uses: yoanm/temp-reports-group-workspace/gha-fetch-workflow-metadata@improve + id: fetch-workflow-metadata + + outputs: + commit-sha: ${{ steps.fetch-workflow-metadata.outputs.commit-sha }} + run-id: ${{ steps.fetch-workflow-metadata.outputs.run-id }} + + codacy-uploader: + name: Codacy + needs: [fetch-info] + uses: yoanm/temp-reports-group-workspace/.github/workflows/codacy-upload-from-artifacts.yml@improve + permissions: + contents: read + checks: write # For the check run creation ! + secrets: + PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + with: + artifacts-pattern: coverage-groups-* + run-id: ${{ needs.fetch-info.outputs.run-id }} + override-job-name: "Codacy title" + force-git-commit: ${{ needs.fetch-info.outputs.commit-sha }} + # force-uploader-language: ... + # force-uploader-coverage-parser: ... + # force-uploader-cli-version: ... + + codecov-uploader: + name: Codecov + needs: [fetch-info] + uses: yoanm/temp-reports-group-workspace/.github/workflows/codecov-upload-from-artifacts.yml@improve + permissions: + contents: read + checks: write # For the check run creation ! + secrets: + TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + artifacts-pattern: coverage-groups-* + run-id: ${{ needs.fetch-info.outputs.run-id }} + override-job-name: "Codecov title" + force-git-commit: ${{ needs.fetch-info.outputs.commit-sha }} + force-git-branch: ${{ needs.fetch-info.outputs.branch }} + force-gh-pr: ${{ needs.fetch-info.outputs.pr-number }} + force-uploader-build: ${{ needs.fetch-info.outputs.run-id }} + force-uploader-build-url: ${{ needs.fetch-info.outputs.run-url }} + + debug-context: + name: DEBUG - context + runs-on: ubuntu-latest + steps: + - run: | + echo '{' + echo '"github.action": ${{ toJson(github.action) }},' + echo '"github.action_path": ${{ toJson(github.action_path) }},' + echo '"github.action_ref": ${{ toJson(github.action_ref) }},' + echo '"github.action_repository": ${{ toJson(github.action_repository) }},' + echo '"github.action_status": ${{ toJson(github.action_status) }},' + echo '"github.actor": ${{ toJson(github.actor) }},' + echo '"github.actor_id": ${{ toJson(github.actor_id) }},' + echo '"github.base_ref": ${{ toJson(github.base_ref) }},' + echo '"github.event": ${{ toJson(github.event) }},' + echo '"github.event_name": ${{ toJson(github.event_name) }},' + echo '"github.event_path": ${{ toJson(github.event_path) }},' + echo '"github.head_ref": ${{ toJson(github.head_ref) }},' + echo '"github.job": ${{ toJson(github.job) }},' + echo '"github.path": ${{ toJson(github.path) }},' + echo '"github.ref": ${{ toJson(github.ref) }},' + echo '"github.ref_name": ${{ toJson(github.ref_name) }},' + echo '"github.ref_protected": ${{ toJson(github.ref_protected) }},' + echo '"github.ref_type": ${{ toJson(github.ref_type) }},' + echo '"github.repository": ${{ toJson(github.repository) }},' + echo '"github.repository_id": ${{ toJson(github.repository_id) }},' + echo '"github.repository_owner": ${{ toJson(github.repository_owner) }},' + echo '"github.repository_owner_id": ${{ toJson(github.repository_owner_id) }},' + echo '"github.repositoryUrl": ${{ toJson(github.repositoryUrl) }},' + echo '"github.run_id": ${{ toJson(github.run_id) }},' + echo '"github.run_number": ${{ toJson(github.run_number) }},' + echo '"github.run_attempt": ${{ toJson(github.run_attempt) }},' + echo '"github.sha": ${{ toJson(github.sha) }},' + echo '"github.triggering_actor": ${{ toJson(github.triggering_actor) }},' + echo '"github.workflow": ${{ toJson(github.workflow) }},' + echo '"github.workflow_ref": ${{ toJson(github.workflow_ref) }},' + echo '"github.workflow_sha": ${{ toJson(github.workflow_sha) }},' + echo '"github.workspace": ${{ toJson(github.workspace) }}' + echo '}' + + debug-uploads: + name: DEBUG - Uploaders + runs-on: ubuntu-latest + needs: [ codacy-uploader, codecov-uploader ] + steps: + - run: echo 'codecov='"'"'${{ toJson(needs.codecov-uploader) }}'"'" + - run: echo 'codacy='"'"'${{ toJson(needs.codacy-uploader) }}'"'"