diff --git a/.github/workflows/spread-results-reporter.yaml b/.github/workflows/spread-results-reporter.yaml new file mode 100644 index 00000000000..50dfc36c2fe --- /dev/null +++ b/.github/workflows/spread-results-reporter.yaml @@ -0,0 +1,116 @@ +name: Spread tests results PR commenter + +on: + workflow_run: + workflows: [Tests] + types: + - completed + +jobs: + report-spread-failures: + if: ${{ github.event.workflow_run.event == 'pull_request' }} + runs-on: ubuntu-latest + permissions: + actions: write + pull-requests: write + env: + GH_TOKEN: ${{ github.token }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get PR number + uses: actions/github-script@v6 + with: + script: | + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { + return artifact.name == "pr_number" + })[0]; + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + let fs = require('fs'); + fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data)); + + - name: Unzip PR number + run: unzip pr_number.zip + + - name: Get generated data + uses: actions/github-script@v6 + with: + script: | + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + let matchingArtifacts = allArtifacts.data.artifacts.filter((artifact) => { + return artifact.name.startsWith(`spread-json-${context.payload.workflow_run.id}-${context.payload.workflow_run.run_attempt}`); + }); + for (let artifact of matchingArtifacts) { + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: artifact.id, + archive_format: 'zip', + }); + let fs = require('fs'); + fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data)); + console.log(`Downloaded artifact: ${artifact.name}.zip`); + } + + - name: Unzip spread json files + run: | + find . -name "spread-json-${{ github.event.workflow_run.id }}*.zip" | while read filename; do + dir="${filename%.zip}" + mkdir $dir + unzip $filename -d $dir + done + + - name: Echo collected output + run: | + report="$(date)\n" + if ! ls spread-json-${{ github.event.workflow_run.id }}-*/*.json &> /dev/null; then + report+="## No spread failures" + else + jq -s 'add' spread-json-${{ github.event.workflow_run.id }}*/*.json > consolidated-report.json + + report+="## Failures:\n" + if [[ $(jq -r '.[] | select( .info_type == "Error" ) | select( .verb == "preparing" )' consolidated-report.json) ]]; then + report+="### Prepare:\n" + report+=$(jq -r '.[] | select( .info_type == "Error" ) | select( .verb == "preparing" ) .task' consolidated-report.json | while read line; do echo "- $line\n"; done) + fi + if [[ $(jq -r '.[] | select( .info_type == "Error" ) | select( .verb == "executing" )' consolidated-report.json) ]]; then + report+="### Executing:\n" + report+=$(jq -r '.[] | select( .info_type == "Error" ) | select( .verb == "executing" ) .task' consolidated-report.json | while read line; do echo "- $line\n"; done) + fi + if [[ $(jq -r '.[] | select( .info_type == "Error" ) | select( .verb == "restoring" )' consolidated-report.json) ]]; then + report+="### Restoring:\n" + report+=$(jq -r '.[] | select( .info_type == "Error" ) | select( .verb == "restoring" ) .task' consolidated-report.json | while read line; do echo "- $line\n"; done) + fi + fi + echo -e "$report" > report + + - name: Comment report to PR + run: | + if ! gh pr comment "$(cat pr_number)" --body "$(cat report)" --edit-last; then + gh pr comment "$(cat pr_number)" --body "$(cat report)" + fi + + - name: Delete artifacts + if: always() + run: | + artifact_ids=$(gh api /repos/${{ github.repository }}/actions/artifacts | jq -r '.artifacts[] | select((.name|startswith("spread-json-${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}-")) or (.name == "pr_number")) | "\(.id)"') + for artifact_id in $artifact_ids; do + echo "Deleting $artifact_id"; + gh api -X delete /repos/${{ github.repository }}/actions/artifacts/$artifact_id + + done diff --git a/.github/workflows/spread-tests.yaml b/.github/workflows/spread-tests.yaml index aec7020547c..2466d629a03 100644 --- a/.github/workflows/spread-tests.yaml +++ b/.github/workflows/spread-tests.yaml @@ -291,3 +291,11 @@ jobs: with: path: "${{ github.workspace }}/.test-results" key: "${{ github.job }}-results-${{ github.run_id }}-${{ inputs.group }}-${{ github.run_attempt }}" + + - name: Save spread.json as an artifact + if: ${{ always() && github.event.number }} + uses: actions/upload-artifact@v4 + with: + name: "spread-json-${{ github.run_id }}-${{ github.run_attempt }}-${{ inputs.group }}" + path: "spread-results.json" + if-no-files-found: ignore diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 298ae4c1be1..4b27507abc2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -345,3 +345,16 @@ jobs: systems: 'ubuntu-24.04-64' tasks: 'tests/nested/...' rules: 'nested' + + upload_pr_number: + if: ${{ github.event.number }} + runs-on: ubuntu-latest + steps: + - name: Create PR number file + run: echo "${{ github.event.number }}" > pr_number + + - name: Upload PR number + uses: actions/upload-artifact@v4 + with: + name: pr_number + path: pr_number