summaryrefslogtreecommitdiff
path: root/.github/workflows/pr_comment.yml
blob: 1393e13953a3452a4aa684ac773986946c877534 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
name: PR Comment

on:
  workflow_run:
    workflows: ["Build"]
    types:
      - completed

jobs:
  # Resolve the PR number from trusted workflow_run metadata, NOT from build artifacts: a forked PR
  # controls its own Build run and could plant any number, which the privileged jobs below would
  # then post to. Same-repo PRs populate workflow_run.pull_requests; for forks it is empty, so look
  # the PR up by the trusted head SHA.
  pr_number:
    if: github.event.workflow_run.event == 'pull_request'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
    outputs:
      number: ${{ steps.resolve.outputs.number }}
    steps:
      - name: Resolve PR number
        id: resolve
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPO: ${{ github.repository }}
          HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
          HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
          HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
          PRS_JSON: ${{ toJSON(github.event.workflow_run.pull_requests) }}
        run: |
          # Every lookup is best-effort: on any miss the number stays empty and the comment jobs
          # below simply skip (never a failed check).
          # Same-repo PRs: workflow_run.pull_requests is populated.
          num=$(printf '%s' "$PRS_JSON" | jq -r '.[0].number // empty')
          # Fork PRs: pull_requests is empty. Find the open PR by its trusted head ref and confirm
          # its head SHA matches the built commit.
          if [ -z "$num" ] && [ -n "$HEAD_BRANCH" ] && [ -n "$HEAD_REPO" ]; then
            num=$(gh api --method GET "repos/$REPO/pulls" \
              -f state=open -f head="${HEAD_REPO%%/*}:$HEAD_BRANCH" \
              --jq '[.[] | select(.head.sha == env.HEAD_SHA)][0].number // empty' 2>/dev/null || true)
          fi
          echo "number=$num" >> "$GITHUB_OUTPUT"

  # ---------------------------------------
  # Combine the rigs' HIL reports into one sticky PR comment (one table per rig).
  # Runs here (workflow_run / base-repo context) rather than in build.yml so it also works on
  # forked PRs, whose build-side GITHUB_TOKEN is read-only and cannot post comments. Posts even
  # on build/HIL failure (when the report matters most); skips only on cancellation.
  # ---------------------------------------
  hil-comment:
    needs: pr_number
    if: >
      github.event.workflow_run.conclusion != 'cancelled' &&
      needs.pr_number.outputs.number != ''
    runs-on: ubuntu-latest
    permissions:
      actions: read
      pull-requests: write
    steps:
      - name: Download HIL reports
        uses: actions/download-artifact@v5
        with:
          run-id: ${{ github.event.workflow_run.id }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          pattern: hil-report-*
          path: hil-reports
        continue-on-error: true

      - name: Combine rig reports (one table per rig)
        id: combine
        run: |
          shopt -s nullglob
          dirs=(hil-reports/hil-report-*)
          if [ ${#dirs[@]} -eq 0 ]; then
            # No rig produced a report: PR selection matched no board anywhere, or the
            # HIL jobs did not run at all. Post it rather than exiting, so a table from
            # an earlier push is replaced instead of being left to look current.
            echo "No HIL reports found"
            {
              echo "## Hardware-in-the-loop (HIL) Test Report"
              echo
              echo "_No HIL run for this push (no affected boards, or hardware testing did not run)._"
            } > hil_combined.md
            echo "found=true" >> "$GITHUB_OUTPUT"
            exit 0
          fi
          {
            echo "## Hardware-in-the-loop (HIL) Test Report"
            echo
            for d in "${dirs[@]}"; do
              [ -d "$d" ] || continue
              echo "### ${d#hil-reports/hil-report-}"
              echo
              cat "$d/hil_report.md" 2>/dev/null || echo "_no report produced_"
              echo
            done
          } > hil_combined.md
          # Fork PRs can influence report content and this job posts in base-repo context, so
          # neutralize @-mentions (insert a zero-width space) to prevent notification abuse.
          zwsp=$(printf '\342\200\213')
          sed -i -E "s/@([A-Za-z0-9_-])/@${zwsp}\1/g" hil_combined.md
          cat hil_combined.md
          echo "found=true" >> "$GITHUB_OUTPUT"

      - name: Post HIL report as sticky PR comment
        if: steps.combine.outputs.found == 'true'
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: hil-report
          path: hil_combined.md
          number: ${{ needs.pr_number.outputs.number }}