Skip to content

Commit 01caa96

Browse files
Merge branch 'master' into smpt
2 parents 8aafa52 + 08d6036 commit 01caa96

33 files changed

Lines changed: 1342 additions & 482 deletions

File tree

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,43 @@
1-
name: Build and Deploy Site
1+
name: Deploy Gatsby site to Pages
2+
23
on:
34
push:
45
branches: [master]
5-
paths-ignore:
6-
- .github/*
7-
86
workflow_dispatch:
9-
workflow_call:
10-
7+
8+
permissions:
9+
contents: write
10+
11+
concurrency:
12+
group: "pages-deployment"
13+
cancel-in-progress: true
14+
1115
jobs:
12-
build-and-deploy:
13-
runs-on: ubuntu-latest
16+
deploy:
17+
runs-on: ubuntu-24.04
18+
1419
steps:
15-
- name: Checkout 🛎️
16-
uses: actions/checkout@master
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Node
24+
uses: actions/setup-node@v4
1725
with:
18-
fetch-depth: 1
19-
20-
# - name: Cache Gatsby .cache and public folders
21-
# uses: actions/cache@v5
22-
# id: gatsby-cache
23-
# with:
24-
# path: |
25-
# public
26-
# .cache
27-
# key: ${{ runner.os }}-gatsby-${{ hashFiles('**/package-lock.json') }}
28-
# restore-keys: |
29-
# ${{ runner.os }}-gatsby-
30-
31-
- name: Install 🔧
32-
run: make setup
33-
34-
- name: Build 🏗️
35-
# Always run the full production build explicitly.
36-
# Do NOT use `make clean` here — that target is a developer convenience
37-
# command whose recipe has changed multiple times, causing blog posts and
38-
# other collections to be silently excluded from the deployed site when
39-
# it ran a lite/dev build instead of the full production build.
40-
# `npm run build` is the canonical, stable production build command:
41-
# cross-env BUILD_FULL_SITE=true gatsby build
42-
run: npm run build
43-
44-
- name: Deploy 🚀
45-
uses: JamesIves/github-pages-deploy-action@v4
26+
node-version: "20"
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Build Gatsby site
32+
run: |
33+
npm run build
34+
echo "layer5.io" > public/CNAME
35+
touch public/.nojekyll
36+
37+
- name: Deploy to GitHub Pages
38+
uses: peaceiris/actions-gh-pages@v4
4639
with:
47-
branch: site # The branch the action should deploy to.
48-
folder: public # The folder the action should deploy.
49-
clean: true
40+
github_token: ${{ secrets.GITHUB_TOKEN }}
41+
publish_dir: ./public
42+
publish_branch: gh-pages
43+
keep_files: true
Lines changed: 182 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,196 @@
1-
name: Build and Preview Site
1+
name: PR Preview Deployment (Gatsby + GitHub Pages)
2+
23
on:
3-
pull_request:
4+
pull_request_target:
45
branches: [master]
5-
types: [opened, synchronize, reopened]
6+
types: [opened, synchronize, reopened, closed]
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
concurrency:
13+
group: preview-${{ github.event.pull_request.number || github.run_id }}
14+
cancel-in-progress: true
15+
16+
defaults:
17+
run:
18+
shell: bash
619

720
jobs:
8-
site-preview:
21+
preview:
922
runs-on: ubuntu-latest
23+
outputs:
24+
removed_prs_json: ${{ steps.prune-previews.outputs.removed_prs_json }}
25+
env:
26+
PREVIEW_RETENTION_LIMIT: 6
27+
1028
steps:
11-
- name: Checkout 🛎️
12-
uses: actions/checkout@master
29+
30+
- name: Checkout PR
31+
if: github.event.action != 'closed'
32+
uses: actions/checkout@v6
1333
with:
14-
persist-credentials: false
15-
fetch-depth: 1
34+
ref: ${{ github.event.pull_request.head.sha }}
1635

17-
- name: Install 🔧
18-
run: make setup
36+
- name: Checkout gh-pages for cleanup
37+
if: github.event.action == 'closed'
38+
uses: actions/checkout@v6
39+
with:
40+
ref: gh-pages
1941

20-
- name: Build 🏗️
21-
# Always run the full production build explicitly.
22-
# Do NOT use `make clean` here — that target is a developer convenience
23-
# command whose recipe has changed multiple times, causing blog posts and
24-
# other collections to be silently excluded from the deployed site when
25-
# it ran a lite/dev build instead of the full production build.
26-
# `npm run build` is the canonical, stable production build command:
27-
# cross-env BUILD_FULL_SITE=true gatsby build
28-
run: npm run build
42+
- name: Setup Node
43+
if: github.event.action != 'closed'
44+
uses: actions/setup-node@v6
45+
with:
46+
node-version: "20"
2947

30-
- name: Broken Link Check 🔗
31-
uses: technote-space/broken-link-checker-action@v2
48+
- name: Install dependencies
49+
if: github.event.action != 'closed'
50+
run: npm ci
51+
52+
- name: Set PATH_PREFIX for preview
53+
if: github.event.action != 'closed'
54+
run: |
55+
echo "PATH_PREFIX=pr-preview/pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
56+
57+
- name: Build PR preview
58+
if: github.event.action != 'closed'
59+
env:
60+
GATSBY_PREVIEW: "true"
61+
GATSBY_SITE_URL: https://${{ github.repository_owner }}.github.io
62+
run: |
63+
PATH_PREFIX=$PATH_PREFIX npm run build:preview
64+
65+
# Prevent indexing
66+
echo -e "User-agent: *\nDisallow: /" > public/robots.txt
67+
68+
- name: Deploy PR preview
69+
if: github.event.action != 'closed'
70+
uses: rossjrw/pr-preview-action@v1.6.3
3271
with:
33-
target: ./public/**/*.html
72+
source-dir: ./public
73+
preview-branch: gh-pages
74+
umbrella-dir: pr-preview
75+
action: auto
76+
comment: false
77+
78+
- name: Checkout gh-pages for preview retention
79+
if: github.event.action != 'closed'
80+
uses: actions/checkout@v6
81+
with:
82+
ref: gh-pages
83+
fetch-depth: 0
84+
filter: blob:none
85+
sparse-checkout: |
86+
pr-preview
87+
path: gh-pages-maintenance
88+
89+
- name: Prune old PR previews
90+
id: prune-previews
91+
if: github.event.action != 'closed'
92+
run: |
93+
cd gh-pages-maintenance
94+
mkdir -p pr-preview
95+
removed_prs=()
96+
97+
mapfile -t previews < <(
98+
while IFS= read -r preview; do
99+
timestamp="$(git log -1 --format=%ct -- "pr-preview/$preview" 2>/dev/null || echo 0)"
100+
printf '%s %s\n' "$timestamp" "$preview"
101+
done < <(find pr-preview -mindepth 1 -maxdepth 1 -type d -name 'pr-*' -printf '%f\n') \
102+
| sort -nr \
103+
| awk '{print $2}'
104+
)
105+
106+
if (( ${#previews[@]} <= PREVIEW_RETENTION_LIMIT )); then
107+
echo "removed_prs_json=[]" >> "$GITHUB_OUTPUT"
108+
exit 0
109+
fi
110+
111+
for preview in "${previews[@]:PREVIEW_RETENTION_LIMIT}"; do
112+
rm -rf "pr-preview/$preview"
113+
removed_prs+=("${preview#pr-}")
114+
done
115+
116+
if git diff --quiet -- pr-preview; then
117+
echo "removed_prs=" >> "$GITHUB_OUTPUT"
118+
echo "removed_prs_json=[]" >> "$GITHUB_OUTPUT"
119+
exit 0
120+
fi
121+
122+
git config user.name "github-actions[bot]"
123+
git config user.email "github-actions[bot]@users.noreply.github.com"
124+
git add pr-preview
125+
git commit -m "Prune old PR previews"
126+
git push
127+
128+
echo "removed_prs=$(IFS=,; echo "${removed_prs[*]}")" >> "$GITHUB_OUTPUT"
129+
echo "removed_prs_json=$(printf '%s\n' "${removed_prs[@]}" | jq -R . | jq -sc .)" >> "$GITHUB_OUTPUT"
130+
131+
- name: Comment PR with Preview URL
132+
if: github.event.action != 'closed'
133+
uses: marocchino/sticky-pull-request-comment@v2
134+
with:
135+
header: pr-preview
136+
message: |
137+
🚀 Preview deployment: https://layer5.io/pr-preview/pr-${{ github.event.pull_request.number }}/
138+
> *Note: Preview may take a moment (GitHub Pages deployment in progress). Please wait and refresh. Track deployment [here](https://github.com/${{ github.repository }}/actions/workflows/pages/pages-build-deployment)*
139+
140+
- name: Comment on pruned previews
141+
if: github.event.action != 'closed' && steps.prune-previews.outputs.removed_prs_json != '[]'
142+
uses: actions/github-script@v7
143+
env:
144+
REMOVED_PRS_JSON: ${{ steps.prune-previews.outputs.removed_prs_json }}
145+
PREVIEW_RETENTION_LIMIT: ${{ env.PREVIEW_RETENTION_LIMIT }}
146+
with:
147+
script: |
148+
const removedPrs = JSON.parse(process.env.REMOVED_PRS_JSON);
149+
const retentionLimit = process.env.PREVIEW_RETENTION_LIMIT;
150+
const header = "pr-preview";
151+
const marker = `<!-- Sticky Pull Request Comment${header} -->`;
152+
153+
for (const prNumber of removedPrs) {
154+
const body =
155+
`Preview deployment for PR #${prNumber} removed.\n\n` +
156+
`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` +
157+
`If needed, push a new commit to this PR to generate a fresh preview.\n` +
158+
`${marker}`;
159+
160+
const { data: comments } = await github.rest.issues.listComments({
161+
owner: context.repo.owner,
162+
repo: context.repo.repo,
163+
issue_number: Number(prNumber),
164+
per_page: 100,
165+
});
166+
167+
const existingComment = [...comments].reverse().find((comment) =>
168+
comment.user?.login === "github-actions[bot]" &&
169+
comment.body?.includes(marker)
170+
);
171+
172+
if (existingComment) {
173+
await github.rest.issues.updateComment({
174+
owner: context.repo.owner,
175+
repo: context.repo.repo,
176+
comment_id: existingComment.id,
177+
body,
178+
});
179+
continue;
180+
}
34181
35-
- name: Zip Site
36-
run: bash ./script.sh
182+
await github.rest.issues.createComment({
183+
owner: context.repo.owner,
184+
repo: context.repo.repo,
185+
issue_number: Number(prNumber),
186+
body,
187+
});
188+
}
37189
38-
- name: Upload files
39-
uses: actions/upload-artifact@v6
190+
- name: Cleanup PR preview on close
191+
if: github.event.action == 'closed'
192+
uses: rossjrw/pr-preview-action@v1.6.3
40193
with:
41-
name: public-dir
42-
path: ./public-dir.zip
43-
retention-days: 1
44-
- name: Trigger Inner workflow
45-
run: echo "triggering inner workflow"
194+
preview-branch: gh-pages
195+
umbrella-dir: pr-preview
196+
action: remove

.github/workflows/preview-site.yml

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)