diff --git a/.github/workflows/fork-pr-comment-recipe.yml b/.github/workflows/fork-pr-comment-recipe.yml new file mode 100644 index 0000000..b5d3d37 --- /dev/null +++ b/.github/workflows/fork-pr-comment-recipe.yml @@ -0,0 +1,102 @@ +name: fork-PR comment recipe test +on: + pull_request: + paths: ['**.c', '**.cpp', '**.h', '**.hpp', '**.cxx', '**.hxx', '**.cc', '**.hh', '**CMakeLists.txt', 'meson.build', '**.cmake'] + +permissions: {} + +jobs: + cpp-linter: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + + # ... optionally setup build env to create a compilation database + + - uses: cpp-linter/cpp-linter-action@v2 + id: linter + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + style: 'file' # Use .clang-format config file. + tidy-checks: '' # Use .clang-tidy config file. + # No thread-comments here: this job's token is read-only. + summary-output-file: ${{ runner.temp }}/cpp-linter-comment/comment.md + + - name: Save the pull request number + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + mkdir -p "$RUNNER_TEMP/cpp-linter-comment" + echo "$PR_NUMBER" > "$RUNNER_TEMP/cpp-linter-comment/pr-number.txt" + + - uses: actions/upload-artifact@v7 + with: + name: cpp-linter-comment + path: ${{ runner.temp }}/cpp-linter-comment/ + retention-days: 1 + + - name: Fail fast?! + if: steps.linter.outputs.checks-failed > 0 + run: exit 1 + + # Stand-in for the workflow_run workflow, which GitHub only runs from the default branch. + comment: + needs: cpp-linter + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + permissions: + actions: read + pull-requests: write + steps: + - uses: actions/download-artifact@v8 + id: download + continue-on-error: true + with: + name: cpp-linter-comment + path: ${{ runner.temp }}/cpp-linter-comment + run-id: ${{ github.run_id }} + github-token: ${{ github.token }} + + - name: Post or update the comment + if: steps.download.outcome == 'success' + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + dir="$RUNNER_TEMP/cpp-linter-comment" + # The artifact was made while linting the pull request: use it only as data. + pr="$(tr -cd '0-9' < "$dir/pr-number.txt" | head -c 10)" + if [ -z "$pr" ] || [ ! -f "$dir/comment.md" ]; then + echo "::warning::The artifact has no pull request number or no comment" + exit 0 + fi + # Only comment on the pull request whose head the lint run checked. (4) + if [ "$(gh api "repos/$GH_REPO/pulls/$pr" --jq .head.sha)" != "$HEAD_SHA" ]; then + echo "::notice::Pull request #$pr has new commits since this run; not commenting" + exit 0 + fi + marker='' + body="$RUNNER_TEMP/body.md" + if [ "$(wc -c < "$dir/comment.md")" -gt 60000 ]; then + # A comment holds at most 65536 characters. + printf '%s\nToo many findings to show here. See the [workflow run](%s).\n' "$marker" "$RUN_URL" > "$body" + else + { echo "$marker"; cat "$dir/comment.md"; } > "$body" + fi + # Update the comment from an earlier run instead of adding another one. + id="$(gh api --paginate "repos/$GH_REPO/issues/$pr/comments" \ + --jq ".[] | select(.user.login == \"github-actions[bot]\" and (.body | startswith(\"$marker\"))) | .id" \ + | head -n 1)" + if [ -n "$id" ]; then + gh api -X PATCH "repos/$GH_REPO/issues/comments/$id" -F "body=@$body" > /dev/null + else + gh api "repos/$GH_REPO/issues/$pr/comments" -F "body=@$body" > /dev/null + fi diff --git a/src/demo.cpp b/src/demo.cpp index 0c1db60..53bb519 100644 --- a/src/demo.cpp +++ b/src/demo.cpp @@ -15,3 +15,6 @@ int main() return 0; } +// fork-PR comment recipe test +// second run: the comment should be updated, not duplicated +int thirdRun(int x) { return x; }