Skip to content

Commit 7ba566d

Browse files
authored
Merge pull request #7639 from CodexRaunak/fix-deployment
Prune old PR previews
2 parents 916f75e + bdf28c3 commit 7ba566d

File tree

1 file changed

+109
-1
lines changed

1 file changed

+109
-1
lines changed

.github/workflows/build-and-preview-site.yml

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,17 @@ concurrency:
1313
group: preview-${{ github.event.pull_request.number || github.run_id }}
1414
cancel-in-progress: true
1515

16+
defaults:
17+
run:
18+
shell: bash
19+
1620
jobs:
1721
preview:
1822
runs-on: ubuntu-latest
23+
outputs:
24+
removed_prs_json: ${{ steps.prune-previews.outputs.removed_prs_json }}
25+
env:
26+
PREVIEW_RETENTION_LIMIT: 6
1927

2028
steps:
2129

@@ -67,6 +75,56 @@ jobs:
6775
action: auto
6876
comment: false
6977

78+
- name: Checkout gh-pages for preview retention
79+
if: github.event.action != 'closed'
80+
uses: actions/checkout@v4
81+
with:
82+
ref: gh-pages
83+
fetch-depth: 0
84+
path: gh-pages-maintenance
85+
86+
- name: Prune old PR previews
87+
id: prune-previews
88+
if: github.event.action != 'closed'
89+
run: |
90+
cd gh-pages-maintenance
91+
mkdir -p pr-preview
92+
removed_prs=()
93+
94+
mapfile -t previews < <(
95+
while IFS= read -r preview; do
96+
timestamp="$(git log -1 --format=%ct -- "pr-preview/$preview" 2>/dev/null || echo 0)"
97+
printf '%s %s\n' "$timestamp" "$preview"
98+
done < <(find pr-preview -mindepth 1 -maxdepth 1 -type d -name 'pr-*' -printf '%f\n') \
99+
| sort -nr \
100+
| awk '{print $2}'
101+
)
102+
103+
if (( ${#previews[@]} <= PREVIEW_RETENTION_LIMIT )); then
104+
echo "removed_prs_json=[]" >> "$GITHUB_OUTPUT"
105+
exit 0
106+
fi
107+
108+
for preview in "${previews[@]:PREVIEW_RETENTION_LIMIT}"; do
109+
rm -rf "pr-preview/$preview"
110+
removed_prs+=("${preview#pr-}")
111+
done
112+
113+
if git diff --quiet -- pr-preview; then
114+
echo "removed_prs=" >> "$GITHUB_OUTPUT"
115+
echo "removed_prs_json=[]" >> "$GITHUB_OUTPUT"
116+
exit 0
117+
fi
118+
119+
git config user.name "github-actions[bot]"
120+
git config user.email "github-actions[bot]@users.noreply.github.com"
121+
git add pr-preview
122+
git commit -m "Prune old PR previews"
123+
git push
124+
125+
echo "removed_prs=$(IFS=,; echo "${removed_prs[*]}")" >> "$GITHUB_OUTPUT"
126+
echo "removed_prs_json=$(printf '%s\n' "${removed_prs[@]}" | jq -R . | jq -sc .)" >> "$GITHUB_OUTPUT"
127+
70128
- name: Comment PR with Preview URL
71129
if: github.event.action != 'closed'
72130
uses: marocchino/sticky-pull-request-comment@v2
@@ -75,7 +133,57 @@ jobs:
75133
message: |
76134
🚀 Preview deployment: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr-preview/pr-${{ github.event.pull_request.number }}/
77135
78-
- name: Cleanup PR preview
136+
- name: Comment on pruned previews
137+
if: github.event.action != 'closed' && steps.prune-previews.outputs.removed_prs_json != '[]'
138+
uses: actions/github-script@v7
139+
env:
140+
REMOVED_PRS_JSON: ${{ steps.prune-previews.outputs.removed_prs_json }}
141+
PREVIEW_RETENTION_LIMIT: ${{ env.PREVIEW_RETENTION_LIMIT }}
142+
with:
143+
script: |
144+
const removedPrs = JSON.parse(process.env.REMOVED_PRS_JSON);
145+
const retentionLimit = process.env.PREVIEW_RETENTION_LIMIT;
146+
const header = "pr-preview";
147+
const marker = `<!-- Sticky Pull Request Comment${header} -->`;
148+
149+
for (const prNumber of removedPrs) {
150+
const body =
151+
`Preview deployment for PR #${prNumber} removed.\n\n` +
152+
`This PR preview was automatically pruned because we keep only the ${retentionLimit} most recently updated previews on GitHub Pages to stay within deployment size limits.\n\n` +
153+
`If needed, push a new commit to this PR to generate a fresh preview.\n` +
154+
`${marker}`;
155+
156+
const { data: comments } = await github.rest.issues.listComments({
157+
owner: context.repo.owner,
158+
repo: context.repo.repo,
159+
issue_number: Number(prNumber),
160+
per_page: 100,
161+
});
162+
163+
const existingComment = [...comments].reverse().find((comment) =>
164+
comment.user?.login === "github-actions[bot]" &&
165+
comment.body?.includes(marker)
166+
);
167+
168+
if (existingComment) {
169+
await github.rest.issues.updateComment({
170+
owner: context.repo.owner,
171+
repo: context.repo.repo,
172+
comment_id: existingComment.id,
173+
body,
174+
});
175+
continue;
176+
}
177+
178+
await github.rest.issues.createComment({
179+
owner: context.repo.owner,
180+
repo: context.repo.repo,
181+
issue_number: Number(prNumber),
182+
body,
183+
});
184+
}
185+
186+
- name: Cleanup PR preview on close
79187
if: github.event.action == 'closed'
80188
uses: rossjrw/pr-preview-action@v1.6.3
81189
with:

0 commit comments

Comments
 (0)