From c9eeb81ebce6193691e65ba2d9d7c79000333e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 19 Feb 2026 19:27:26 +0100 Subject: [PATCH 1/8] Add RSpec test reporter to CI workflows Publishes a consolidated RSpec test report as a GitHub Check Run after all parallel spec jobs complete. Each specs job uploads its JUnit XML as an artifact; the finalize job aggregates them via dorny/test-reporter. The non-parallel workflow publishes the report inline in the test job. Services need rspec_junit_formatter in their Gemfile and RSpec configured to write XML to tmp/rspec-results*.xml. --- .github/workflows/test-nonparallel.yml | 12 ++++++++++++ .github/workflows/test-parallel.yml | 27 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/.github/workflows/test-nonparallel.yml b/.github/workflows/test-nonparallel.yml index ffc5e7e..ce32ee3 100644 --- a/.github/workflows/test-nonparallel.yml +++ b/.github/workflows/test-nonparallel.yml @@ -36,6 +36,9 @@ jobs: name: Application runs-on: ubuntu-24.04 timeout-minutes: 20 + permissions: + checks: write + pull-requests: write steps: - name: Prepare the environment uses: hausgold/actions/ci@v2 @@ -58,6 +61,15 @@ jobs: run: coverage working-directory: '${{ inputs.base_path }}' + - name: Publish RSpec test report + if: always() + uses: dorny/test-reporter@v1 + with: + name: RSpec Tests + path: '${{ inputs.base_path }}/tmp/rspec-results*.xml' + reporter: java-junit + fail-on-error: false + - name: Build and upload application documentation run: api-docs --skip-upload && coverage --docs-only if: github.ref == 'refs/heads/master' diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index 3365c39..3534862 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -72,6 +72,14 @@ jobs: run: coverage part working-directory: '${{ inputs.base_path }}' + - name: Upload RSpec test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: rspec-junit-${{ strategy.job-index }} + path: '${{ inputs.base_path }}/tmp/rspec-results*.xml' + if-no-files-found: ignore + targets: name: Targets runs-on: ubuntu-24.04 @@ -109,6 +117,10 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 5 needs: [specs, targets] + if: always() + permissions: + checks: write + pull-requests: write steps: - name: Prepare the environment uses: hausgold/actions/ci@v2 @@ -121,3 +133,18 @@ jobs: - name: Upload the code coverage report run: coverage merge working-directory: '${{ inputs.base_path }}' + + - name: Download RSpec test results + uses: actions/download-artifact@v4 + with: + pattern: rspec-junit-* + path: rspec-junit/ + merge-multiple: true + + - name: Publish RSpec test report + uses: dorny/test-reporter@v1 + with: + name: RSpec Tests + path: rspec-junit/**/*.xml + reporter: java-junit + fail-on-error: false From b919ef355d71609f2feab17d9e3390fb41c579dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 19 Feb 2026 23:23:05 +0100 Subject: [PATCH 2/8] Remove job-level permissions that were skipping all steps Setting permissions at the job level in a reusable workflow implicitly sets everything else to none, including contents: read, causing the hausgold/actions/ci@v2 checkout to be skipped and all subsequent steps to follow. Use the inherited GITHUB_TOKEN permissions instead; if checks: write is unavailable, fail-on-error: false prevents breakage. --- .github/workflows/test-nonparallel.yml | 3 --- .github/workflows/test-parallel.yml | 3 --- 2 files changed, 6 deletions(-) diff --git a/.github/workflows/test-nonparallel.yml b/.github/workflows/test-nonparallel.yml index ce32ee3..0721167 100644 --- a/.github/workflows/test-nonparallel.yml +++ b/.github/workflows/test-nonparallel.yml @@ -36,9 +36,6 @@ jobs: name: Application runs-on: ubuntu-24.04 timeout-minutes: 20 - permissions: - checks: write - pull-requests: write steps: - name: Prepare the environment uses: hausgold/actions/ci@v2 diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index 3534862..248f47c 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -118,9 +118,6 @@ jobs: timeout-minutes: 5 needs: [specs, targets] if: always() - permissions: - checks: write - pull-requests: write steps: - name: Prepare the environment uses: hausgold/actions/ci@v2 From 781fc653eed9bb0fd1f8489a30485e5723090d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 19 Feb 2026 23:29:32 +0100 Subject: [PATCH 3/8] Make report steps idempotent in finalize job Download step gets continue-on-error so a missing artifact (repo with no rspec_junit_formatter) does not skip the publish step. Both download and publish run with if: always() so a coverage merge failure cannot prevent the report from being attempted. --- .github/workflows/test-parallel.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index 248f47c..e4008de 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -132,6 +132,8 @@ jobs: working-directory: '${{ inputs.base_path }}' - name: Download RSpec test results + if: always() + continue-on-error: true uses: actions/download-artifact@v4 with: pattern: rspec-junit-* @@ -139,6 +141,7 @@ jobs: merge-multiple: true - name: Publish RSpec test report + if: always() uses: dorny/test-reporter@v1 with: name: RSpec Tests From e0d4207f517c500518291366d16c7dac10894030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 19 Feb 2026 23:36:15 +0100 Subject: [PATCH 4/8] Show all tests in report, not just failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit list-tests: all makes every test case appear in the Check detail view grouped by classname, which rspec_junit_formatter populates with the full describe/context chain — giving a nested view of the suite. --- .github/workflows/test-nonparallel.yml | 1 + .github/workflows/test-parallel.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/test-nonparallel.yml b/.github/workflows/test-nonparallel.yml index 0721167..77df104 100644 --- a/.github/workflows/test-nonparallel.yml +++ b/.github/workflows/test-nonparallel.yml @@ -65,6 +65,7 @@ jobs: name: RSpec Tests path: '${{ inputs.base_path }}/tmp/rspec-results*.xml' reporter: java-junit + list-tests: all fail-on-error: false - name: Build and upload application documentation diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index e4008de..f9a002e 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -147,4 +147,5 @@ jobs: name: RSpec Tests path: rspec-junit/**/*.xml reporter: java-junit + list-tests: all fail-on-error: false From fa99b5bf24ab43dbf515943108439aa97579fe4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 19 Feb 2026 23:59:24 +0100 Subject: [PATCH 5/8] Switch test reporter from JUnit XML to rspec-json --- .github/workflows/test-nonparallel.yml | 5 ++--- .github/workflows/test-parallel.yml | 13 ++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test-nonparallel.yml b/.github/workflows/test-nonparallel.yml index 77df104..1a54dcc 100644 --- a/.github/workflows/test-nonparallel.yml +++ b/.github/workflows/test-nonparallel.yml @@ -63,9 +63,8 @@ jobs: uses: dorny/test-reporter@v1 with: name: RSpec Tests - path: '${{ inputs.base_path }}/tmp/rspec-results*.xml' - reporter: java-junit - list-tests: all + path: '${{ inputs.base_path }}/tmp/rspec-results*.json' + reporter: rspec-json fail-on-error: false - name: Build and upload application documentation diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index f9a002e..6be986d 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -76,8 +76,8 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: rspec-junit-${{ strategy.job-index }} - path: '${{ inputs.base_path }}/tmp/rspec-results*.xml' + name: rspec-json-${{ strategy.job-index }} + path: '${{ inputs.base_path }}/tmp/rspec-results*.json' if-no-files-found: ignore targets: @@ -136,8 +136,8 @@ jobs: continue-on-error: true uses: actions/download-artifact@v4 with: - pattern: rspec-junit-* - path: rspec-junit/ + pattern: rspec-json-* + path: rspec-json/ merge-multiple: true - name: Publish RSpec test report @@ -145,7 +145,6 @@ jobs: uses: dorny/test-reporter@v1 with: name: RSpec Tests - path: rspec-junit/**/*.xml - reporter: java-junit - list-tests: all + path: rspec-json/**/*.json + reporter: rspec-json fail-on-error: false From f0e7d44743deeaf1ef910a6ef5a7f4d9d4f42877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Fri, 20 Feb 2026 00:06:23 +0100 Subject: [PATCH 6/8] Drop merge-multiple, each artifact subdirects its own json --- .github/workflows/test-parallel.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index 6be986d..b474705 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -138,7 +138,6 @@ jobs: with: pattern: rspec-json-* path: rspec-json/ - merge-multiple: true - name: Publish RSpec test report if: always() From 6178f4803497d7511d4ceb322d9127906ee7e068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Fri, 20 Feb 2026 00:08:52 +0100 Subject: [PATCH 7/8] Only list failed tests in report --- .github/workflows/test-nonparallel.yml | 1 + .github/workflows/test-parallel.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/test-nonparallel.yml b/.github/workflows/test-nonparallel.yml index 1a54dcc..58ac3e5 100644 --- a/.github/workflows/test-nonparallel.yml +++ b/.github/workflows/test-nonparallel.yml @@ -65,6 +65,7 @@ jobs: name: RSpec Tests path: '${{ inputs.base_path }}/tmp/rspec-results*.json' reporter: rspec-json + list-tests: failed fail-on-error: false - name: Build and upload application documentation diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index b474705..e88f2a3 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -146,4 +146,5 @@ jobs: name: RSpec Tests path: rspec-json/**/*.json reporter: rspec-json + list-tests: failed fail-on-error: false From 83d000148ede2d6328b7cd37bb9e96971d365b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Fri, 20 Feb 2026 00:25:17 +0100 Subject: [PATCH 8/8] Add debug step to list rspec output files after parallel tests --- .github/workflows/test-parallel.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index e88f2a3..12338b2 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -72,6 +72,10 @@ jobs: run: coverage part working-directory: '${{ inputs.base_path }}' + - name: List RSpec output files (debug) + if: always() + run: find '${{ inputs.base_path }}/tmp' -name 'rspec-results*' 2>/dev/null || echo 'No rspec-results files found' + - name: Upload RSpec test results if: always() uses: actions/upload-artifact@v4