fix: avoid serializing full File instance for determining uploading state #605
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validation | |
| on: | |
| schedule: | |
| - cron: '30 23 * * *' | |
| pull_request: | |
| branches: ['main', '25.*'] | |
| merge_group: | |
| workflow_dispatch: | |
| inputs: | |
| components: | |
| description: 'Space-separated component names (e.g. "grid combo-box"), empty for all' | |
| required: false | |
| default: '' | |
| shards: | |
| description: 'Number of parallel IT shards' | |
| required: false | |
| default: '5' | |
| local-wc-validation: | |
| description: 'Run validation against local web-components checkout' | |
| required: false | |
| default: false | |
| type: boolean | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.merge_group.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| FORK_COUNT: 4 | |
| jobs: | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| outputs: | |
| skip: ${{ steps.skip-ci.outputs.skip }} | |
| components: ${{ steps.components.outputs.elements }} | |
| build-cache-key: ${{ steps.build-key.outputs.key }} | |
| steps: | |
| - name: Set Maven args | |
| run: | | |
| args="-ntp -B" | |
| [ "${{ runner.debug }}" != "1" ] && args="$args -q" | |
| echo "MAVEN_ARGS=$args" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} | |
| fetch-depth: ${{ github.event_name == 'merge_group' && 50 || 1 }} | |
| - name: Check for skip-ci | |
| id: skip-ci | |
| if: github.event_name == 'pull_request' || github.event_name == 'merge_group' | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| if [ "${{ github.event_name }}" = "merge_group" ]; then | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if echo "$PR_TITLE" | grep -q '\[skip ci\]'; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Compute build cache key | |
| id: build-key | |
| if: steps.skip-ci.outputs.skip != 'true' | |
| run: echo "key=${{ runner.os }}-build-${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| - name: Restore build cache | |
| id: build-cache | |
| if: steps.skip-ci.outputs.skip != 'true' | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.m2/repository/com/vaadin | |
| vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/src/main/resources/META-INF/frontend/generated/ | |
| key: ${{ steps.build-key.outputs.key }} | |
| - name: Setup JDK 21 | |
| if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Setup Node | |
| if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| - name: Show environment info | |
| if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' | |
| run: | | |
| java -version | |
| mvn -version | |
| node --version | |
| npm --version | |
| google-chrome --version | |
| chromedriver --version | |
| - name: Install artifacts | |
| if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' | |
| run: | | |
| mvn install -Dmaven.test.skip=true -Drelease -T $FORK_COUNT $MAVEN_ARGS || { | |
| echo "::warning::First attempt failed (Maven multi-thread race). Retrying..." | |
| sleep 15 | |
| mvn install -Dmaven.test.skip=true -Drelease -T $FORK_COUNT $MAVEN_ARGS | |
| } | |
| - name: Detect modified components | |
| id: components | |
| if: steps.skip-ci.outputs.skip != 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| elements="${{ github.event.inputs.components || '' }}" | |
| changed_files="" | |
| if [ -n "$elements" ]; then | |
| echo "elements=$elements" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| pr_number="${{ github.event.pull_request.number }}" | |
| changed_files=$(gh api "repos/${{ github.repository }}/pulls/$pr_number/files" --jq '.[].filename') | |
| elif [ "${{ github.event_name }}" = "merge_group" ]; then | |
| changed_files=$(git diff --name-only "${{ github.event.merge_group.base_sha }}" "${{ github.event.merge_group.head_sha }}") | |
| fi | |
| if [ -n "$changed_files" ]; then | |
| modified=$(echo "$changed_files" \ | |
| | grep 'vaadin.*flow-parent' \ | |
| | sed 's,^vaadin-\(.*\)-flow-parent.*,\1,' \ | |
| | sort -u) | |
| nmods=$(echo "$modified" | wc -w | tr -d ' ') | |
| all_files=$(echo "$changed_files" | sort -u | tr -d '[:space:]') | |
| component_files=$(echo "$changed_files" | grep 'vaadin.*flow-parent' | sort -u | tr -d '[:space:]') | |
| if [ "$nmods" -lt 5 ] && [ ${#all_files} -eq ${#component_files} ]; then | |
| elements=$(echo $modified | tr '\n' ' ') | |
| echo "Running partial build for: $elements" | |
| fi | |
| fi | |
| echo "elements=$elements" >> "$GITHUB_OUTPUT" | |
| fast-tests: | |
| name: ${{ matrix.name }} | |
| needs: build | |
| if: needs.build.outputs.skip != 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| outputs: | |
| matrix: ${{ steps.shards.outputs.matrix }} | |
| has-tests: ${{ steps.shards.outputs.has-tests }} | |
| war-cache-key: ${{ steps.war-key.outputs.key }} | |
| unit-failed: ${{ steps.type-failed.outputs.unit }} | |
| wtr-failed: ${{ steps.type-failed.outputs.wtr }} | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| include: | |
| - name: Unit tests | |
| type: unit | |
| - name: WTR tests | |
| type: wtr | |
| - name: Package WAR | |
| type: war | |
| steps: | |
| - name: Set Maven args | |
| run: | | |
| args="-ntp -B" | |
| [ "${{ runner.debug }}" != "1" ] && args="$args -q" | |
| echo "MAVEN_ARGS=$args" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} | |
| fetch-depth: 1 | |
| - name: Setup Node | |
| if: matrix.type != 'unit' | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| - name: Checkout web-components | |
| if: matrix.type != 'unit' && github.event_name == 'schedule' || inputs.local-wc-validation | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: vaadin/web-components | |
| ref: main | |
| path: web-components | |
| - name: Install web-components | |
| if: matrix.type != 'unit' && github.event_name == 'schedule' || inputs.local-wc-validation | |
| run: yarn install --ignore-engines --ignore-scripts | |
| working-directory: web-components | |
| - name: Configure local web-components | |
| if: matrix.type != 'unit' && github.event_name == 'schedule' || inputs.local-wc-validation | |
| run: echo "LOCAL_WEB_COMPONENTS_PATH=web-components" > .env | |
| - name: npm install | |
| if: matrix.type != 'unit' | |
| run: npm ci --ignore-scripts | |
| - name: Detect @NpmPackage version changes | |
| id: npm-changes | |
| if: matrix.type != 'unit' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| changed=false | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| # Use the PR files API so we diff against the merge base, not against | |
| # main's current tip — otherwise unrelated @NpmPackage commits already | |
| # merged into main since the PR branched would trigger a false positive. | |
| if gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/files" \ | |
| --jq '.[] | select(.filename | endswith(".java")) | .patch // ""' \ | |
| | grep -qE '^\+.*@NpmPackage'; then | |
| changed=true | |
| fi | |
| else | |
| base="${{ github.base_ref || 'main' }}" | |
| if git fetch --depth=1 origin "$base" 2>/dev/null && \ | |
| git diff FETCH_HEAD -- '*.java' | grep -q '@NpmPackage'; then | |
| changed=true | |
| fi | |
| fi | |
| if [ "$changed" = "true" ]; then | |
| echo "MAVEN_OPTS=${MAVEN_OPTS} -Dvaadin.npm.minimumFrontendPackageAgeDays=0" >> "$GITHUB_ENV" | |
| echo "changed=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Request changes on PR for @NpmPackage version bump | |
| if: >- | |
| matrix.type == 'war' | |
| && steps.npm-changes.outputs.changed == 'true' | |
| && github.event_name == 'pull_request' | |
| env: | |
| GH_TOKEN: ${{ secrets.VAADIN_REVIEW_BOT }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| MARKER="<!-- vaadin-flow-components:npm-package-bump-review -->" | |
| existing=$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews" \ | |
| --jq "[.[] | select(.state == \"CHANGES_REQUESTED\") | select(.body | contains(\"$MARKER\"))] | length") | |
| if [ "$existing" -gt 0 ]; then | |
| echo "Existing CHANGES_REQUESTED review found, skipping." | |
| exit 0 | |
| fi | |
| BODY=$(sed 's/^ //' <<'EOF' | |
| <!-- vaadin-flow-components:npm-package-bump-review --> | |
| This PR is updating the @NpmPackage version. Due to the default value of `vaadin.npm.minimumFrontendPackageAgeDays` is 1, I'm blocking this PR for now. | |
| In order to not producing a failed snapshot for other projects, please come back one day after to unblock and merge it. | |
| EOF | |
| ) | |
| gh api -X POST "repos/$REPO/pulls/$PR_NUMBER/reviews" \ | |
| -f event=REQUEST_CHANGES \ | |
| -f body="$BODY" | |
| - name: Merge ITs | |
| if: matrix.type == 'war' | |
| run: node scripts/mergeITs.js ${{ needs.build.outputs.components }} | |
| - name: Compute WAR cache key | |
| if: matrix.type == 'war' | |
| id: war-key | |
| env: | |
| KEY: ${{ runner.os }}-war-${{ hashFiles('**/pom.xml', '**/src/main/java/**', '**/src/main/resources/**', 'integration-tests/src/test/java/**') }} | |
| run: echo "key=$KEY" >> "$GITHUB_OUTPUT" | |
| - name: Restore WAR cache | |
| if: matrix.type == 'war' | |
| id: war-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| integration-tests/pom.xml | |
| integration-tests/target | |
| key: ${{ steps.war-key.outputs.key }} | |
| - name: Setup JDK 21 | |
| if: steps.war-cache.outputs.cache-hit != 'true' | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Install TestBench license | |
| if: env.TB_LICENSE != '' && steps.war-cache.outputs.cache-hit != 'true' | |
| env: | |
| TB_LICENSE: ${{ secrets.TB_LICENSE }} | |
| run: | | |
| mkdir -p ~/.vaadin | |
| user="${TB_LICENSE%%/*}" | |
| key="${TB_LICENSE#*/}" | |
| echo "{\"username\":\"${user}\",\"proKey\":\"${key}\"}" > ~/.vaadin/proKey | |
| - name: Restore build cache | |
| if: steps.war-cache.outputs.cache-hit != 'true' | |
| id: build-cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.m2/repository/com/vaadin | |
| vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/src/main/resources/META-INF/frontend/generated/ | |
| key: ${{ needs.build.outputs.build-cache-key }} | |
| fail-on-cache-miss: true | |
| - name: Run unit tests | |
| if: matrix.type == 'unit' | |
| run: mvn test -Drelease -T $FORK_COUNT -Dsurefire.parallel=classes -Dsurefire.threadCount=2 -DskipSvgChartsBuild $MAVEN_ARGS | |
| - name: Upload unit test reports | |
| if: always() && matrix.type == 'unit' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: surefire-reports | |
| path: '**/target/surefire-reports/TEST-*.xml' | |
| retention-days: 1 | |
| if-no-files-found: ignore | |
| - name: Run WTR tests | |
| if: matrix.type == 'wtr' | |
| run: node scripts/wtr.js ${{ needs.build.outputs.components }} | |
| - name: Upload WTR reports | |
| if: always() && matrix.type == 'wtr' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: wtr-reports | |
| path: '**/wtr-results.xml' | |
| retention-days: 1 | |
| if-no-files-found: ignore | |
| - name: Package integration-tests WAR | |
| if: matrix.type == 'war' && steps.war-cache.outputs.cache-hit != 'true' | |
| run: | | |
| mvn package -pl integration-tests \ | |
| -Dvaadin.pnpm.enable -Drun-it -Drelease \ | |
| -Dvaadin.productionMode -Dvaadin.force.production.build=true \ | |
| -Dmaven.test.skip=true -DskipJetty $MAVEN_ARGS | |
| - name: Compile IT test sources | |
| if: matrix.type == 'war' && steps.war-cache.outputs.cache-hit != 'true' | |
| run: mvn test-compile -pl integration-tests -Drun-it -DskipFrontend -DskipJetty -DskipUnitTests $MAVEN_ARGS | |
| - name: Compute IT shards | |
| if: matrix.type == 'war' | |
| id: shards | |
| env: | |
| SHARDS: ${{ github.event.inputs.shards || '0' }} | |
| TARGET_PER_SHARD: 35 | |
| MAX_SHARDS: 10 | |
| run: | | |
| mapfile -t its < <(find integration-tests/src/test/java -name '*IT.java' -printf '%P\n' | sed -e 's|/|.|g' -e 's|\.java$||' | sort) | |
| count=${#its[@]} | |
| echo "Found $count IT classes" | |
| if [ "$count" -eq 0 ]; then | |
| echo "has-tests=false" >> "$GITHUB_OUTPUT" | |
| echo 'matrix={"include":[]}' >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| n=$SHARDS | |
| if [ "$n" -eq 0 ]; then | |
| n=$(( (count + TARGET_PER_SHARD - 1) / TARGET_PER_SHARD )) | |
| [ "$n" -lt 1 ] && n=1 | |
| [ "$n" -gt "$MAX_SHARDS" ] && n=$MAX_SHARDS | |
| fi | |
| if [ "$n" -gt "$count" ]; then n=$count; fi | |
| echo "$n shards for $count classes (~$(( count / n )) per shard)" | |
| declare -a buckets | |
| for i in $(seq 1 $n); do buckets[$i]=""; done | |
| i=1 | |
| for t in "${its[@]}"; do | |
| if [ -n "${buckets[$i]}" ]; then buckets[$i]+=","; fi | |
| buckets[$i]+="$t" | |
| i=$((i+1)) | |
| [ $i -gt $n ] && i=1 | |
| done | |
| json='{"include":[' | |
| for k in $(seq 1 $n); do | |
| [ $k -gt 1 ] && json+=',' | |
| json+='{"shard":"'"$k"'","tests":"'"${buckets[$k]}"'"}' | |
| done | |
| json+=']}' | |
| echo "$json" | |
| echo "matrix=$json" >> "$GITHUB_OUTPUT" | |
| echo "has-tests=true" >> "$GITHUB_OUTPUT" | |
| - name: Record job type on failure | |
| id: type-failed | |
| if: always() && failure() | |
| run: echo "${{ matrix.type }}=true" >> "$GITHUB_OUTPUT" | |
| its: | |
| name: ITs (${{ matrix.shard }}) | |
| needs: [build, fast-tests] | |
| if: needs.fast-tests.outputs.has-tests == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.fast-tests.outputs.matrix) }} | |
| steps: | |
| - name: Set Maven args | |
| run: | | |
| args="-ntp -B" | |
| [ "${{ runner.debug }}" != "1" ] && args="$args -q" | |
| echo "MAVEN_ARGS=$args" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} | |
| fetch-depth: 1 | |
| - name: Setup JDK 21 | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Install TestBench license | |
| if: env.TB_LICENSE != '' | |
| env: | |
| TB_LICENSE: ${{ secrets.TB_LICENSE }} | |
| run: | | |
| mkdir -p ~/.vaadin | |
| user="${TB_LICENSE%%/*}" | |
| key="${TB_LICENSE#*/}" | |
| echo "{\"username\":\"${user}\",\"proKey\":\"${key}\"}" > ~/.vaadin/proKey | |
| - name: Restore build cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.m2/repository/com/vaadin | |
| vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/src/main/resources/META-INF/frontend/generated/ | |
| key: ${{ needs.build.outputs.build-cache-key }} | |
| fail-on-cache-miss: true | |
| - name: Restore WAR cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| integration-tests/pom.xml | |
| integration-tests/target | |
| key: ${{ needs.fast-tests.outputs.war-cache-key }} | |
| fail-on-cache-miss: true | |
| - name: Run integration tests (shard ${{ matrix.shard }}) | |
| env: | |
| SHARD_TESTS: ${{ matrix.tests }} | |
| run: | | |
| mvn -pl integration-tests -Drun-it \ | |
| jetty:start-war failsafe:integration-test jetty:stop failsafe:verify \ | |
| -Dvaadin.productionMode \ | |
| -DskipFrontend \ | |
| -Dfailsafe.forkCount=$FORK_COUNT \ | |
| -Dcom.vaadin.testbench.Parameters.testsInParallel=2 \ | |
| -Dfailsafe.rerunFailingTestsCount=2 \ | |
| -Dmaven.test.redirectTestOutputToFile=true \ | |
| -Dtest.reuseDriver=true \ | |
| -Dit.test="$SHARD_TESTS" \ | |
| -B | |
| - name: Upload error screenshots | |
| if: failure() | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: error-screenshots-${{ matrix.shard }} | |
| path: integration-tests/error-screenshots/ | |
| retention-days: 5 | |
| if-no-files-found: ignore | |
| - name: Upload failsafe reports | |
| if: always() | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: failsafe-reports-${{ matrix.shard }} | |
| path: integration-tests/target/failsafe-reports/ | |
| retention-days: 1 | |
| if-no-files-found: ignore | |
| results: | |
| name: Collect tests | |
| needs: [build, fast-tests, its] | |
| if: always() && needs.build.result == 'success' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| checks: write | |
| actions: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} | |
| fetch-depth: 1 | |
| - uses: actions/download-artifact@v8 | |
| continue-on-error: true | |
| with: | |
| name: surefire-reports | |
| path: surefire-reports | |
| - uses: actions/download-artifact@v8 | |
| continue-on-error: true | |
| with: | |
| pattern: failsafe-reports-* | |
| merge-multiple: true | |
| path: failsafe-reports | |
| - uses: actions/download-artifact@v8 | |
| continue-on-error: true | |
| with: | |
| name: wtr-reports | |
| path: wtr-reports | |
| - name: Remove passing test reports | |
| run: | | |
| # Detect real failures via testsuite attributes (flaky retries leave | |
| # <flakyError> tags but keep failures="0" errors="0" on the suite). | |
| has_failures=false | |
| for dir in surefire-reports failsafe-reports wtr-reports; do | |
| [ -d "$dir" ] || continue | |
| if find "$dir" -name '*.xml' | xargs grep -lE 'failures="[1-9]|errors="[1-9]' 2>/dev/null | grep -q .; then | |
| has_failures=true | |
| break | |
| fi | |
| done | |
| echo "has_failures=$has_failures" >> $GITHUB_ENV | |
| # Red build: keep only failing reports so dorny focuses on failures. | |
| # Green build: keep all reports so every suite shows as passed. | |
| if [ "$has_failures" = "true" ]; then | |
| for dir in surefire-reports failsafe-reports wtr-reports; do | |
| [ -d "$dir" ] || continue | |
| find "$dir" -name '*.xml' | while read -r f; do | |
| grep -qE 'failures="[1-9]|errors="[1-9]' "$f" || rm -f "$f" | |
| done | |
| done | |
| fi | |
| - name: Check for unit test reports | |
| id: unit-check | |
| run: | | |
| count=$(find surefire-reports -name 'TEST-*.xml' 2>/dev/null | wc -l | tr -d ' ') | |
| echo "count=$count" >> $GITHUB_OUTPUT | |
| - name: Unit Tests header | |
| if: steps.unit-check.outputs.count != '0' && (needs.fast-tests.outputs.unit-failed != 'true' || env.has_failures == 'true') | |
| run: echo "## Unit Tests" >> $GITHUB_STEP_SUMMARY | |
| - name: Publish unit test results | |
| id: unit-dorny | |
| if: steps.unit-check.outputs.count != '0' && (needs.fast-tests.outputs.unit-failed != 'true' || env.has_failures == 'true') | |
| uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 | |
| with: | |
| name: Unit Tests | |
| path: surefire-reports/**/TEST-*.xml | |
| reporter: java-junit | |
| list-tests: ${{ env.has_failures == 'true' && 'failed' || 'all' }} | |
| list-suites: ${{ env.has_failures == 'true' && 'failed' || 'all' }} | |
| fail-on-error: 'false' | |
| - name: Unit test compilation error | |
| if: needs.fast-tests.outputs.unit-failed == 'true' && env.has_failures != 'true' | |
| run: | | |
| echo ":x: Unit tests compilation failed. Check the **Unit tests** job for details." >> $GITHUB_STEP_SUMMARY | |
| - name: Check for IT reports | |
| id: it-check | |
| run: | | |
| count=$(find failsafe-reports -name 'TEST-*.xml' 2>/dev/null | wc -l | tr -d ' ') | |
| echo "count=$count" >> $GITHUB_OUTPUT | |
| - name: Integration Tests header | |
| if: steps.it-check.outputs.count != '0' && (needs.fast-tests.result == 'success' || env.has_failures == 'true') | |
| run: echo "## Integration Tests" >> $GITHUB_STEP_SUMMARY | |
| - name: Publish integration test results | |
| id: it-dorny | |
| if: steps.it-check.outputs.count != '0' && (needs.fast-tests.result == 'success' || env.has_failures == 'true') | |
| uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 | |
| with: | |
| name: Integration Tests | |
| path: failsafe-reports/TEST-*.xml | |
| reporter: java-junit | |
| list-tests: ${{ env.has_failures == 'true' && 'failed' || 'all' }} | |
| list-suites: ${{ env.has_failures == 'true' && 'failed' || 'all' }} | |
| fail-on-error: 'false' | |
| - name: Check for WTR reports | |
| id: wtr-check | |
| run: | | |
| count=$(find wtr-reports -name 'wtr-results.xml' 2>/dev/null | wc -l | tr -d ' ') | |
| echo "count=$count" >> $GITHUB_OUTPUT | |
| - name: WTR Tests header | |
| if: steps.wtr-check.outputs.count != '0' && (needs.fast-tests.result == 'success' || needs.fast-tests.outputs.wtr-failed == 'true') | |
| run: echo "## WTR Tests" >> $GITHUB_STEP_SUMMARY | |
| - name: Publish WTR results | |
| id: wtr-dorny | |
| if: steps.wtr-check.outputs.count != '0' && (needs.fast-tests.result == 'success' || needs.fast-tests.outputs.wtr-failed == 'true') | |
| uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 | |
| with: | |
| name: WTR Tests | |
| path: wtr-reports/**/wtr-results.xml | |
| reporter: java-junit | |
| list-tests: ${{ env.has_failures == 'true' && 'failed' || 'all' }} | |
| list-suites: ${{ env.has_failures == 'true' && 'failed' || 'all' }} | |
| fail-on-error: 'false' | |
| - name: WTR setup error | |
| if: steps.wtr-check.outputs.count == '0' && needs.fast-tests.outputs.wtr-failed == 'true' | |
| run: | | |
| echo ":x: WTR tests did not produce results. Check the **WTR tests** job for details." >> $GITHUB_STEP_SUMMARY | |
| - uses: actions/download-artifact@v8 | |
| if: needs.its.result != 'success' | |
| continue-on-error: true | |
| with: | |
| pattern: error-screenshots-* | |
| merge-multiple: true | |
| path: error-screenshots | |
| - name: Upload merged error screenshots | |
| if: needs.its.result != 'success' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: error-screenshots | |
| path: error-screenshots/ | |
| retention-days: 5 | |
| if-no-files-found: ignore | |
| - name: Delete intermediate artifacts | |
| if: always() | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| RUN_ID: ${{ github.run_id }} | |
| run: | | |
| gh api --paginate "repos/$GH_REPO/actions/runs/$RUN_ID/artifacts" \ | |
| --jq '.artifacts[] | select( | |
| (.name | startswith("error-screenshots-")) or | |
| (.name | startswith("failsafe-reports-")) or | |
| .name == "wtr-reports" or | |
| .name == "surefire-reports" | |
| ) | "\(.id) \(.name)"' \ | |
| | while read -r id name; do | |
| echo "Deleting artifact $name (id=$id)" | |
| gh api -X DELETE "repos/$GH_REPO/actions/artifacts/$id" || true | |
| done | |
| - name: Fail if any test failed | |
| if: always() | |
| run: | | |
| failed=false | |
| [[ "${{ steps.unit-dorny.outputs.conclusion }}" == "failure" ]] && failed=true | |
| [[ "${{ steps.wtr-dorny.outputs.conclusion }}" == "failure" ]] && failed=true | |
| [[ "${{ steps.it-dorny.outputs.conclusion }}" == "failure" ]] && failed=true | |
| [[ "$failed" == "true" ]] && exit 1 || exit 0 |