From 90441cdaf02917ec1e932d687defa28a51378891 Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Mon, 25 Aug 2025 15:00:42 +0300 Subject: [PATCH 1/6] chore: split unit tests from the main CI workflow and report combined coverage to Coveralls --- .github/workflows/ci.yml | 81 ++-------------- .github/workflows/coveralls-finish.yml | 23 +++++ .github/workflows/integration-tests.yml | 10 ++ .github/workflows/unit-tests.yml | 118 ++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 75 deletions(-) create mode 100644 .github/workflows/coveralls-finish.yml create mode 100644 .github/workflows/unit-tests.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3086ed0b..7fc9c94f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,39 +30,19 @@ jobs: echo "::notice::CI checks will execute - the actor is not the release-please bot" fi - tests: + code-quality: needs: should-run if: needs.should-run.outputs.run == 'true' runs-on: ubuntu-latest - name: "PHP ${{ matrix.php }} + Doctrine ORM ${{ matrix.doctrine-orm }} + Doctrine Lexer ${{ matrix.doctrine-lexer }}" - strategy: - fail-fast: false - matrix: - php: ['8.1', '8.2', '8.3', '8.4'] - doctrine-lexer: ['2.1', '3.0', 'latest'] - doctrine-orm: ['2.14', '2.18', '3.0', 'latest'] - include: - - php: '8.1' - doctrine-orm: '2.14' - doctrine-lexer: '1.2' - - php: '8.4' # Run coverage report only based on the latest dependencies - doctrine-lexer: 'latest' - doctrine-orm: 'latest' - calculate-code-coverage: true - exclude: - - doctrine-orm: '2.14' - doctrine-lexer: '3.0' - - doctrine-orm: '3.0' - doctrine-lexer: '2.1' + name: "Code Quality" steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - - name: Set up PHP with PECL extension + - name: Set up PHP uses: shivammathur/setup-php@20529878ed81ef8e78ddf08b480401e6101a850f # v2 with: - php-version: ${{ matrix.php }} - coverage: xdebug + php-version: '8.4' extensions: ctype, json, mbstring tools: composer @@ -78,60 +58,11 @@ jobs: restore-keys: | ${{ runner.os }}-php- - - name: Install Doctrine Lexer dependency - run: | - if [ "${{ matrix.doctrine-lexer }}" = "1.2" ]; then - composer require doctrine/lexer "~1.2" --dev --prefer-dist --no-interaction --no-progress - elif [ "${{ matrix.doctrine-lexer }}" = "2.1" ]; then - composer require doctrine/lexer "~2.1" --dev --prefer-dist --no-interaction --no-progress - elif [ "${{ matrix.doctrine-lexer }}" = "3.0" ]; then - composer require doctrine/lexer "~3.0" --dev --prefer-dist --no-interaction --no-progress - else - composer update --prefer-dist --no-interaction --no-progress - fi - - - name: Install Doctrine ORM dependency - run: | - if [ "${{ matrix.doctrine-orm }}" = "2.14" ]; then - composer require doctrine/orm "~2.14" --prefer-dist --no-interaction --no-progress --with-all-dependencies - elif [ "${{ matrix.doctrine-orm }}" = "2.18" ]; then - composer require doctrine/orm "~2.18" --prefer-dist --no-interaction --no-progress --with-all-dependencies - elif [ "${{ matrix.doctrine-orm }}" = "3.0" ]; then - composer require doctrine/orm "~3.0" --prefer-dist --no-interaction --no-progress --with-all-dependencies - else - composer update --prefer-dist --no-interaction --no-progress - fi - - - name: Run static analysis - run: composer run-static-analysis - continue-on-error: ${{ matrix.continue-on-error || false }} + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-progress - name: Check code style run: composer check-code-style - name: Check for security vulnerabilities in 3rd party dependencies run: composer audit - - - name: Run unit test suite - run: composer run-unit-tests - - - name: Upload coverage results to Coveralls - if: matrix.calculate-code-coverage == true - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - file: ./var/logs/test-coverage/unit/clover.xml - parallel: true - flag-name: "Unit" - fail-on-error: false - - coveralls-finish: - needs: tests - if: always() - runs-on: ubuntu-latest - steps: - - name: Finalize Coveralls parallel run - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - parallel-finished: true diff --git a/.github/workflows/coveralls-finish.yml b/.github/workflows/coveralls-finish.yml new file mode 100644 index 00000000..53596805 --- /dev/null +++ b/.github/workflows/coveralls-finish.yml @@ -0,0 +1,23 @@ +name: Coveralls Finish + +on: + workflow_run: + workflows: ["Unit Tests", "Integrations"] + types: + - completed + +permissions: + contents: read + +jobs: + coveralls-finish: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.conclusion == 'success' || + github.event.workflow_run.conclusion == 'failure' + steps: + - name: Finalize Coveralls parallel run + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 27ee045a..ea1d8420 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -114,3 +114,13 @@ jobs: POSTGRES_DB: postgres_doctrine_test POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres + + - name: Upload coverage results to Coveralls + if: matrix.calculate-code-coverage == true + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + file: ./var/logs/test-coverage/integration/clover.xml + parallel: true + flag-name: "Integration" + fail-on-error: false diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 00000000..ac1df675 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,118 @@ +name: Unit Tests + +on: + push: + branches: + - main + paths-ignore: + - '.github/actions/release-please/**' + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + should-run: + runs-on: ubuntu-latest + outputs: + run: ${{ steps.check.outputs.run }} + steps: + - name: Skip for release-please + id: check + run: | + if [ "${{ github.event.pull_request.user.id }}" = "41898282" ]; then + echo "run=false" >> $GITHUB_OUTPUT + echo "::notice::Skipping unit tests - this a release-please bot's interaction" + else + echo "run=true" >> $GITHUB_OUTPUT + echo "::notice::Unit tests will execute - the actor is not the release-please bot" + fi + + unit-tests: + needs: should-run + if: needs.should-run.outputs.run == 'true' + runs-on: ubuntu-latest + name: "PHP ${{ matrix.php }} + Doctrine ORM ${{ matrix.doctrine-orm }} + Doctrine Lexer ${{ matrix.doctrine-lexer }}" + + strategy: + fail-fast: false + matrix: + php: ['8.1', '8.2', '8.3', '8.4'] + doctrine-lexer: ['2.1', '3.0', 'latest'] + doctrine-orm: ['2.14', '2.18', '3.0', 'latest'] + include: + - php: '8.1' + doctrine-orm: '2.14' + doctrine-lexer: '1.2' + - php: '8.4' # Run coverage report only based on the latest dependencies + doctrine-lexer: 'latest' + doctrine-orm: 'latest' + calculate-code-coverage: true + exclude: + - doctrine-orm: '2.14' + doctrine-lexer: '3.0' + - doctrine-orm: '3.0' + doctrine-lexer: '2.1' + + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 + + - name: Set up PHP with PECL extension + uses: shivammathur/setup-php@20529878ed81ef8e78ddf08b480401e6101a850f # v2 + with: + php-version: ${{ matrix.php }} + coverage: xdebug + extensions: ctype, json, mbstring + tools: composer + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install Doctrine Lexer dependency + run: | + if [ "${{ matrix.doctrine-lexer }}" = "1.2" ]; then + composer require doctrine/lexer "~1.2" --dev --prefer-dist --no-interaction --no-progress + elif [ "${{ matrix.doctrine-lexer }}" = "2.1" ]; then + composer require doctrine/lexer "~2.1" --dev --prefer-dist --no-interaction --no-progress + elif [ "${{ matrix.doctrine-lexer }}" = "3.0" ]; then + composer require doctrine/lexer "~3.0" --dev --prefer-dist --no-interaction --no-progress + else + composer update --prefer-dist --no-interaction --no-progress + fi + + - name: Install Doctrine ORM dependency + run: | + if [ "${{ matrix.doctrine-orm }}" = "2.14" ]; then + composer require doctrine/orm "~2.14" --prefer-dist --no-interaction --no-progress --with-all-dependencies + elif [ "${{ matrix.doctrine-orm }}" = "2.18" ]; then + composer require doctrine/orm "~2.18" --prefer-dist --no-interaction --no-progress --with-all-dependencies + elif [ "${{ matrix.doctrine-orm }}" = "3.0" ]; then + composer require doctrine/orm "~3.0" --prefer-dist --no-interaction --no-progress --with-all-dependencies + else + composer update --prefer-dist --no-interaction --no-progress + fi + + - name: Run static analysis + run: composer run-static-analysis + continue-on-error: ${{ matrix.continue-on-error || false }} + + - name: Run unit test suite + run: composer run-unit-tests + + - name: Upload coverage results to Coveralls + if: matrix.calculate-code-coverage == true + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + file: ./var/logs/test-coverage/unit/clover.xml + parallel: true + flag-name: "Unit" + fail-on-error: false From 4a1ce29fa5fb8c6ef8f6594de6710ffed4f86e7b Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Mon, 25 Aug 2025 15:16:49 +0300 Subject: [PATCH 2/6] no message --- .github/workflows/coveralls-finish.yml | 23 ----------------------- .github/workflows/integration-tests.yml | 4 ++++ 2 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 .github/workflows/coveralls-finish.yml diff --git a/.github/workflows/coveralls-finish.yml b/.github/workflows/coveralls-finish.yml deleted file mode 100644 index 53596805..00000000 --- a/.github/workflows/coveralls-finish.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Coveralls Finish - -on: - workflow_run: - workflows: ["Unit Tests", "Integrations"] - types: - - completed - -permissions: - contents: read - -jobs: - coveralls-finish: - runs-on: ubuntu-latest - if: > - github.event.workflow_run.conclusion == 'success' || - github.event.workflow_run.conclusion == 'failure' - steps: - - name: Finalize Coveralls parallel run - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - parallel-finished: true diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ea1d8420..d5d287de 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -41,6 +41,10 @@ jobs: matrix: php: ['8.1', '8.2', '8.3', '8.4'] postgres: ['16', '17'] + include: + - php: '8.4' + postgres: '17' + calculate-code-coverage: true services: postgres: From c38de963f985d71dfe0320457381695982b254ea Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Mon, 25 Aug 2025 17:39:13 +0300 Subject: [PATCH 3/6] no message --- .github/workflows/coverage.yml | 34 +++++++++++++++++++++++++ .github/workflows/integration-tests.yml | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..4c39f5df --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,34 @@ +name: Coverage + +on: + workflow_run: + workflows: ["Integration Tests", "Unit Tests"] + types: [completed] + +jobs: + finalize: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v7 + with: + script: | + const workflows = await github.rest.actions.listWorkflowRunsForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + head_sha: context.payload.workflow_run.head_sha, + status: 'completed' + }); + + const bothComplete = ['Integrations Tests', 'Integration Tests'].every(name => + workflows.data.workflow_runs.some(run => run.name === name) + ); + + if (!bothComplete) { + core.info('Waiting for other workflow to complete'); + process.exit(0); + } + + - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d5d287de..beea2a2a 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1,4 +1,4 @@ -name: Integrations +name: Integration Tests on: push: From 432d7e3fd9bd9a548fa5036de0f47bc36e3b4ff1 Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Mon, 25 Aug 2025 15:41:07 +0100 Subject: [PATCH 4/6] Update .github/workflows/coverage.yml --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4c39f5df..33bc08d3 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -19,7 +19,7 @@ jobs: status: 'completed' }); - const bothComplete = ['Integrations Tests', 'Integration Tests'].every(name => + const bothComplete = ['Integration Tests', 'Unit Tests'].every(name => workflows.data.workflow_runs.some(run => run.name === name) ); From 887da00a68a1a7289be56c2c68a5af096febeaef Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Mon, 25 Aug 2025 17:58:15 +0300 Subject: [PATCH 5/6] no message --- .github/workflows/coverage.yml | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 33bc08d3..6722d26a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -8,27 +8,40 @@ on: jobs: finalize: runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_sha == github.sha }} + # Needed for listWorkflowRunsForRepo and safe defaults for token scope + permissions: + actions: read + contents: read + workflows: write + # Prevent multiple concurrent finalizers for the same commit + concurrency: + group: coverage-${{ github.event.workflow_run.head_sha }} + cancel-in-progress: true steps: - - uses: actions/github-script@v7 + - id: check + uses: actions/github-script@v7 with: script: | const workflows = await github.rest.actions.listWorkflowRunsForRepo({ owner: context.repo.owner, repo: context.repo.repo, head_sha: context.payload.workflow_run.head_sha, - status: 'completed' + status: 'completed', + per_page: 100 }); const bothComplete = ['Integration Tests', 'Unit Tests'].every(name => - workflows.data.workflow_runs.some(run => run.name === name) + workflows.data.workflow_runs.some( + run => run.name === name && run.conclusion === 'success' + ) ); - if (!bothComplete) { - core.info('Waiting for other workflow to complete'); - process.exit(0); - } + core.info(bothComplete ? 'Both workflows completed successfully.' : 'Waiting for other workflow to complete.'); + core.setOutput('ready', String(bothComplete)); - - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b + - if: ${{ steps.check.outputs.ready == 'true' }} + uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true From 9827dd333c9d067f12b5fdb1708c2fd5f49a449a Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Mon, 25 Aug 2025 18:07:10 +0300 Subject: [PATCH 6/6] no message --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6722d26a..2a8d0582 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -13,7 +13,7 @@ jobs: permissions: actions: read contents: read - workflows: write + statuses: write # Prevent multiple concurrent finalizers for the same commit concurrency: group: coverage-${{ github.event.workflow_run.head_sha }}