Cleanup Preview #1893
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Cleanup Preview | |
| on: | |
| pull_request: | |
| types: [closed] | |
| workflow_run: | |
| workflows: ["Build & Deploy"] | |
| types: [completed] | |
| workflow_dispatch: | |
| inputs: | |
| pr: | |
| description: "PR number whose preview should be removed" | |
| required: true | |
| permissions: | |
| actions: read | |
| pull-requests: write | |
| jobs: | |
| cleanup: | |
| name: Clean up PR preview | |
| runs-on: ubuntu-latest | |
| # Run if: PR closed directly, cleanup dispatched explicitly, OR build | |
| # completed for a closed PR | |
| if: | | |
| github.event_name == 'pull_request' || | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'workflow_run' && github.event.workflow_run.event == 'pull_request') | |
| steps: | |
| - name: Get PR info | |
| id: pr | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| DISPATCH_PR: ${{ inputs.pr }} | |
| run: | | |
| if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| echo "number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT" | |
| echo "state=closed" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| if ! [[ "$DISPATCH_PR" =~ ^[0-9]+$ ]]; then | |
| echo "Invalid PR number: $DISPATCH_PR" | |
| exit 1 | |
| fi | |
| PR_NUMBER="$DISPATCH_PR" | |
| else | |
| # Extract PR number from workflow_run | |
| PR_NUMBER=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number // empty') | |
| if [[ -z "$PR_NUMBER" ]]; then | |
| echo "No PR associated with this workflow run" | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| fi | |
| # Check if PR is closed | |
| PR_STATE=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUMBER" --jq '.state') | |
| echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" | |
| echo "state=$PR_STATE" >> "$GITHUB_OUTPUT" | |
| - name: Check if cleanup needed | |
| id: check | |
| if: steps.pr.outputs.skip != 'true' | |
| run: | | |
| if [[ "${{ steps.pr.outputs.state }}" != "closed" ]]; then | |
| echo "PR #${{ steps.pr.outputs.number }} is still open, skipping cleanup" | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "PR #${{ steps.pr.outputs.number }} is closed, proceeding with cleanup" | |
| fi | |
| - name: Generate app token | |
| if: steps.pr.outputs.skip != 'true' && steps.check.outputs.skip != 'true' | |
| id: app-token | |
| uses: actions/create-github-app-token@v1 | |
| with: | |
| app-id: ${{ vars.TENZIR_GITHUB_APP_ID }} | |
| private-key: ${{ secrets.TENZIR_GITHUB_APP_PRIVATE_KEY }} | |
| repositories: docs-previews | |
| - name: Remove preview from docs-previews repo | |
| if: steps.pr.outputs.skip != 'true' && steps.check.outputs.skip != 'true' | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| set -e | |
| if ! git clone --depth 1 --branch gh-pages \ | |
| "https://x-access-token:${GH_TOKEN}@github.com/tenzir/docs-previews.git" preview-repo; then | |
| echo "Could not clone docs-previews repo, nothing to clean up" | |
| exit 0 | |
| fi | |
| cd preview-repo | |
| PREVIEW_DIR="${{ steps.pr.outputs.number }}" | |
| if [ ! -d "$PREVIEW_DIR" ]; then | |
| echo "Preview not found: $PREVIEW_DIR" | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| for attempt in 1 2 3 4 5; do | |
| git fetch origin gh-pages | |
| git reset --hard origin/gh-pages | |
| if [ ! -d "$PREVIEW_DIR" ]; then | |
| echo "Preview already removed: $PREVIEW_DIR" | |
| exit 0 | |
| fi | |
| rm -rf "$PREVIEW_DIR" | |
| git add -A | |
| git commit -m "Remove preview for PR #${{ steps.pr.outputs.number }}" | |
| if git push origin HEAD:gh-pages; then | |
| echo "Removed preview: $PREVIEW_DIR" | |
| exit 0 | |
| fi | |
| if [ "$attempt" -eq 5 ]; then | |
| echo "Could not push preview cleanup after $attempt attempts" | |
| exit 1 | |
| fi | |
| echo "Remote changed while cleaning up preview; retrying" | |
| sleep $((attempt * 2)) | |
| done | |
| - name: Comment on PR | |
| if: steps.pr.outputs.skip != 'true' && steps.check.outputs.skip != 'true' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const prNumber = ${{ steps.pr.outputs.number }}; | |
| const url = 'https://preview.docs.tenzir.com/' + prNumber; | |
| const comment = [ | |
| '<!-- docs-preview -->', | |
| `📦 **Preview** · ~~[View →](${url})~~ · ⚪ Removed`, | |
| ].join('\n'); | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| }); | |
| const botComment = comments.find(c => | |
| c.user.type === 'Bot' && c.body.includes('<!-- docs-preview -->') | |
| ); | |
| if (botComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: comment | |
| }); | |
| } |