diff --git a/.github/workflows/publish-hub.yml b/.github/workflows/publish-hub.yml index cae48f46..40516b05 100644 --- a/.github/workflows/publish-hub.yml +++ b/.github/workflows/publish-hub.yml @@ -17,8 +17,9 @@ permissions: concurrency: group: publish-hub # A newer master push supersedes queued runs: intermediate snapshots are - # pointless because reviewers only ever diff pin against pin, and a cancelled - # run never leaves partial state on the remote (push is the last step). + # pointless because reviewers only ever diff pin against pin. A cancelled + # run can leave only the scratch hub/validate ref behind, which the next + # run overwrites; hub/publish itself is only pushed after validation. cancel-in-progress: true jobs: @@ -68,7 +69,17 @@ jobs: COMMIT: ${{ steps.snapshot.outputs.commit }} run: git checkout --detach "${COMMIT}" + # The official packager clones the plugin repository from GitHub and + # checks out the pinned SHA, so the snapshot must be reachable from a + # ref there before it can be validated. hub/validate is a scratch ref + # for exactly that; it is deleted once validation finishes and is never + # pinned. hub/publish itself is only pushed after validation passes. + - name: Expose the snapshot commit to the packager + if: ${{ steps.snapshot.outputs.changed == 'true' }} + run: git push origin refs/heads/hub/publish:refs/heads/hub/validate + - name: Validate with the official Plugin Hub packager + id: validate if: ${{ steps.snapshot.outputs.changed == 'true' }} env: PLUGIN_REPOSITORY: ${{ github.repository }} @@ -76,6 +87,10 @@ jobs: shell: bash run: bash "${RUNNER_TEMP}/hub-check/check-plugin-hub.sh" + - name: Drop the validation ref + if: ${{ always() && steps.snapshot.outputs.changed == 'true' }} + run: git push origin --delete refs/heads/hub/validate || true + - name: Upload Plugin Hub feedback and package if: ${{ always() && steps.snapshot.outputs.changed == 'true' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -95,6 +110,7 @@ jobs: COMMIT: ${{ steps.snapshot.outputs.commit }} PREVIOUS: ${{ steps.snapshot.outputs.previous }} CHANGED: ${{ steps.snapshot.outputs.changed }} + VALIDATED: ${{ steps.validate.outcome }} BASE: ${{ inputs.base || github.sha }} REPOSITORY: ${{ github.repository }} shell: bash @@ -106,6 +122,12 @@ jobs: echo "Nothing to publish: \`hub/publish\` already matches \`${BASE:-master}\` at \`${COMMIT}\`." exit 0 fi + if [[ "${VALIDATED}" != success ]]; then + echo "Validation failed for \`${COMMIT}\`; \`hub/publish\` was not updated." + echo "Do not pin \`${COMMIT}\` — it was not pushed. Check the job log and the" + echo "plugin-hub-check artifact, fix the cause, and push to \`master\` again." + exit 0 + fi echo "- Commit to pin: \`${COMMIT}\`" if [[ -n "${PREVIOUS}" ]]; then echo "- Review diff: [${PREVIOUS:0:10}...${COMMIT:0:10}](https://github.com/${REPOSITORY}/compare/${PREVIOUS}...${COMMIT})" diff --git a/README.md b/README.md index 45c29cc2..b2f1f833 100644 --- a/README.md +++ b/README.md @@ -194,13 +194,17 @@ To cut a new pin: 1. Merge your changes to `master` and set `version=` in `runelite-plugin.properties`. 2. The **Publish Plugin Hub branch** workflow runs automatically on every push - to `master`. It appends one snapshot commit to `hub/publish`, validates that - commit with RuneLite's official packager, pushes it, and reports the commit - SHA to pin in its summary. Pushes that do not change plugin files (tests, - docs, CI) are detected and skipped. You can also run the workflow manually - for another ref, or locally: `bash .github/scripts/publish-hub.sh --push`. - On first use the branch is seeded from the currently pinned commit, so the - transition review only shows the removal of non-plugin files. + to `master`. It appends one snapshot commit, exposes it on the temporary + `hub/validate` ref so RuneLite's official packager can clone and check out + that exact commit from GitHub, validates it, and only then pushes + `hub/publish` (deleting the temporary ref) and reports the commit SHA to + pin in its summary. If validation fails, `hub/publish` is left untouched + and the summary says so — never pin an unreported commit. Pushes that do + not change plugin files (tests, docs, CI) are detected and skipped. You can + also run the workflow manually for another ref, or locally: + `bash .github/scripts/publish-hub.sh --push`. On first use the branch is + seeded from the currently pinned commit, so the transition review only + shows the removal of non-plugin files. 3. Open a pull request against [runelite/plugin-hub](https://github.com/runelite/plugin-hub) updating [`plugin-hub/plugins/flipping-utilities`](https://github.com/runelite/plugin-hub/blob/master/plugins/flipping-utilities) with that commit.