|
50 | 50 | permissions: |
51 | 51 | contents: read |
52 | 52 |
|
| 53 | +# A dedicated label, separate from the existing `api change` label. |
| 54 | +# `api change` may be applied manually for behavioral changes that aren't |
| 55 | +# strictly API changes, so we can't safely auto-remove it when this check |
| 56 | +# passes. This auto-managed label is fully owned by the workflow. |
| 57 | +env: |
| 58 | + BREAKING_CHANGE_LABEL: "auto detected api change" |
| 59 | + |
53 | 60 | jobs: |
54 | 61 | comment-on-pr: |
55 | 62 | name: Comment on pull request |
@@ -97,36 +104,84 @@ jobs: |
97 | 104 | echo "${DELIM}" |
98 | 105 | } >> "$GITHUB_OUTPUT" |
99 | 106 |
|
100 | | - # The marker `<!-- semver-check-comment -->` is what makes the comment |
101 | | - # "sticky": maintain-one-comment uses it to find and replace (or |
102 | | - # delete) the existing comment instead of stacking new ones. |
| 107 | +
|
| 108 | + # Find any existing sticky comment by its hidden marker so we can update |
| 109 | + # or delete it instead of stacking new ones. |
| 110 | + - name: Find existing sticky comment |
| 111 | + id: find |
| 112 | + env: |
| 113 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 114 | + REPO: ${{ github.repository }} |
| 115 | + PR_NUMBER: ${{ steps.read.outputs.pr_number }} |
| 116 | + run: | |
| 117 | + COMMENT_ID=$(gh api --paginate "repos/${REPO}/issues/${PR_NUMBER}/comments" \ |
| 118 | + --jq '.[] | select(.body | contains("<!-- semver-check-comment -->")) | .id' \ |
| 119 | + | head -n1) |
| 120 | + echo "comment_id=${COMMENT_ID}" >> "$GITHUB_OUTPUT" |
| 121 | +
|
| 122 | + # update the existing comment found above, or create a new one. The hidden |
| 123 | + # marker `<!-- semver-check-comment -->` stays in the body so the next run |
| 124 | + # finds it again. LOGS is interpolated via a shell parameter expansion, |
| 125 | + # whose result bash does not re-scan, so untrusted log content cannot |
| 126 | + # inject further commands. |
103 | 127 | - name: Upsert sticky comment |
104 | 128 | if: steps.read.outputs.result != 'success' |
105 | | - uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0 |
106 | | - with: |
107 | | - token: ${{ secrets.GITHUB_TOKEN }} |
108 | | - number: ${{ steps.read.outputs.pr_number }} |
109 | | - body-include: '<!-- semver-check-comment -->' |
110 | | - body: | |
111 | | - <!-- semver-check-comment --> |
112 | | - Thank you for opening this pull request! |
| 129 | + env: |
| 130 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 131 | + REPO: ${{ github.repository }} |
| 132 | + PR_NUMBER: ${{ steps.read.outputs.pr_number }} |
| 133 | + COMMENT_ID: ${{ steps.find.outputs.comment_id }} |
| 134 | + LOGS: ${{ steps.read.outputs.logs }} |
| 135 | + run: | |
| 136 | + set -euo pipefail |
| 137 | + BODY="<!-- semver-check-comment --> |
| 138 | + Thank you for opening this pull request! |
113 | 139 |
|
114 | | - Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch). |
| 140 | + Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch). |
115 | 141 |
|
116 | | - <details> |
117 | | - <summary>Details</summary> |
| 142 | + <details> |
| 143 | + <summary>Details</summary> |
118 | 144 |
|
119 | | - ``` |
120 | | - ${{ steps.read.outputs.logs }} |
121 | | - ``` |
| 145 | + \`\`\` |
| 146 | + ${LOGS} |
| 147 | + \`\`\` |
122 | 148 |
|
123 | | - </details> |
| 149 | + </details>" |
| 150 | + |
| 151 | + # Use --raw-field (not --field): always sends the value as a literal string. while --field would treat a leading `@` as a file to read |
| 152 | + # (even though the body does not start with user input we are being cautious) |
| 153 | + if [ -n "$COMMENT_ID" ]; then |
| 154 | + gh api "repos/${REPO}/issues/comments/${COMMENT_ID}" --method PATCH --raw-field body="$BODY" |
| 155 | + else |
| 156 | + gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" --method POST --raw-field body="$BODY" |
| 157 | + fi |
124 | 158 |
|
| 159 | + # Clear a stale comment once the breaking change is resolved. |
125 | 160 | - name: Delete sticky comment |
| 161 | + if: steps.read.outputs.result == 'success' && steps.find.outputs.comment_id != '' |
| 162 | + env: |
| 163 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 164 | + REPO: ${{ github.repository }} |
| 165 | + COMMENT_ID: ${{ steps.find.outputs.comment_id }} |
| 166 | + run: gh api -X DELETE "repos/${REPO}/issues/comments/${COMMENT_ID}" |
| 167 | + |
| 168 | + - name: Add "auto detected api change" label |
| 169 | + if: steps.read.outputs.result != 'success' |
| 170 | + env: |
| 171 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 172 | + REPO: ${{ github.repository }} |
| 173 | + PR_NUMBER: ${{ steps.read.outputs.pr_number }} |
| 174 | + run: | |
| 175 | + gh pr edit "$PR_NUMBER" --repo "$REPO" \ |
| 176 | + --add-label "$BREAKING_CHANGE_LABEL" |
| 177 | +
|
| 178 | + - name: Remove "auto detected api change" label |
126 | 179 | if: steps.read.outputs.result == 'success' |
127 | | - uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0 |
128 | | - with: |
129 | | - token: ${{ secrets.GITHUB_TOKEN }} |
130 | | - number: ${{ steps.read.outputs.pr_number }} |
131 | | - body-include: '<!-- semver-check-comment -->' |
132 | | - delete: true |
| 180 | + env: |
| 181 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 182 | + REPO: ${{ github.repository }} |
| 183 | + PR_NUMBER: ${{ steps.read.outputs.pr_number }} |
| 184 | + run: | |
| 185 | + # No-op when the label isn't currently applied. |
| 186 | + gh pr edit "$PR_NUMBER" --repo "$REPO" \ |
| 187 | + --remove-label "$BREAKING_CHANGE_LABEL" || true |
0 commit comments