Skip to content

Commit 29026bf

Browse files
authored
UI bundle previews (#33)
* Enable pull request draft previews for UI bundle changes
1 parent 348ee01 commit 29026bf

File tree

5 files changed

+315
-77
lines changed

5 files changed

+315
-77
lines changed

.github/workflows/bundle.yml

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
name: Deploy Bundle Preview
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- '*'
7+
8+
jobs:
9+
build-and-deploy:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Configure Git Credentials
14+
uses: de-vri-es/setup-git-credentials@v2
15+
with:
16+
credentials: ${{ secrets.GIT_CREDENTIALS }}
17+
18+
- name: Checkout Repository
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v3
23+
with:
24+
node-version: 16.20.2
25+
26+
- name: Install Dependencies
27+
run: npm ci
28+
29+
- name: Extract Branch Names
30+
shell: bash
31+
run: |
32+
# transform branch names in form of `refs/heads/main` to `main`
33+
draft_branch=$(basename ${{ github.event.pull_request.head.ref }})
34+
echo "draft_branch=$draft_branch" >> $GITHUB_OUTPUT
35+
id: extract_branch
36+
37+
- name: Build UI Bundle Preview
38+
run: |
39+
set -o pipefail
40+
gulp lint |& tee $GITHUB_WORKSPACE/build.log
41+
UI_ROOT_PATH_PREFIX=${{ github.event.repository.name }}/${{ steps.extract_branch.outputs.draft_branch }} \
42+
gulp preview:build |& tee $GITHUB_WORKSPACE/build.log
43+
44+
- name: Check Build Result
45+
id: logFail
46+
if: failure()
47+
run: |
48+
MULTILINE_LOG=$(cat $GITHUB_WORKSPACE/build.log)
49+
echo "BUILD_FAILURE<<EOF" >> $GITHUB_ENV
50+
echo $MULTILINE_LOG >> $GITHUB_ENV
51+
echo "EOF" >> $GITHUB_ENV
52+
53+
- name: Create Build Success Comment
54+
if: ${{ success() && github.event.pull_request.number }}
55+
uses: peter-evans/create-or-update-comment@v3
56+
with:
57+
token: ${{ secrets.COMMENT_GITHUB_TOKEN }}
58+
issue-number: ${{ github.event.pull_request.number }}
59+
body: |
60+
UI bundle preview build successful! :white_check_mark:
61+
Deploying preview to GitHub Pages.
62+
reactions: rocket
63+
64+
- name: Create Build Failure Comment
65+
if: ${{ failure() && github.event.pull_request.number }}
66+
uses: peter-evans/create-or-update-comment@v3
67+
with:
68+
token: ${{ secrets.COMMENT_GITHUB_TOKEN }}
69+
issue-number: ${{ github.event.pull_request.number }}
70+
body: |
71+
UI bundle preview build failure! :x:
72+
> ${{ env.BUILD_FAILURE }}
73+
reactions: confused
74+
75+
- name: Find Comment
76+
if: ${{ success() && github.event.pull_request.number }}
77+
uses: peter-evans/find-comment@v2
78+
id: fc
79+
with:
80+
token: ${{ secrets.COMMENT_GITHUB_TOKEN }}
81+
issue-number: ${{ github.event.pull_request.number }}
82+
comment-author: 'mlr'
83+
body-includes: UI bundle preview build successful!
84+
direction: last
85+
86+
- name: Deploy to GitHub Pages
87+
if: success()
88+
run: |
89+
git clone https://github.com/$GITHUB_REPOSITORY.git pages
90+
cd pages
91+
git checkout gh-pages
92+
93+
# If there was previously a build for the preview, then remove it
94+
# so we get a clean build. This is needed in case a follow up
95+
# build of the same pull request contains content deletions.
96+
rm -rf ${{ steps.extract_branch.outputs.draft_branch }}
97+
98+
mkdir -p ${{ steps.extract_branch.outputs.draft_branch }}
99+
cp -r ../public/* ${{ steps.extract_branch.outputs.draft_branch }}/.
100+
101+
# Records the repository that originally triggered the build so we can post back
102+
# comments upon clean up of a stale draft if it still has an open pull request.
103+
echo "${{ github.event.repository.full_name }}" > ${{ steps.extract_branch.outputs.draft_branch }}/.github_source_repository
104+
105+
git add .
106+
git config user.name 'github-actions[bot]'
107+
git config user.email 'github-actions[bot]@users.noreply.github.com'
108+
git commit --allow-empty -m "Auto-deployed from GitHub Actions"
109+
git push -u origin gh-pages
110+
111+
- name: Obtain GitHub Pages build URL
112+
if: success()
113+
run: |
114+
sleep 5 # Allow time for build to initiate
115+
build_url=$(curl -s -L \
116+
-H "Accept: application/vnd.github+json" \
117+
-H "Authorization: Bearer ${{ secrets.COMMENT_GITHUB_TOKEN }}" \
118+
-H "X-GitHub-Api-Version: 2022-11-28" 'https://api.github.com/repos/${{ github.event.repository.full_name }}/pages/builds/latest' \
119+
| jq -r .url)
120+
echo "url=$build_url" >> $GITHUB_OUTPUT
121+
id: ghpages_build
122+
123+
- name: Wait for Github Pages deployment
124+
if: success()
125+
run: |
126+
for i in {1..60}; do
127+
build_status=$(curl -s -L \
128+
-H "Accept: application/vnd.github+json" \
129+
-H "Authorization: Bearer ${{ secrets.COMMENT_GITHUB_TOKEN }}" \
130+
-H "X-GitHub-Api-Version: 2022-11-28" '${{ steps.ghpages_build.outputs.url }}' \
131+
| jq -r .status)
132+
133+
if [ "$build_status" == "built" ]; then echo "Deploy is complete."
134+
exit 0
135+
else
136+
echo "Deploy is not complete. Status: $build_status. Retrying in 10 seconds..."
137+
sleep 10
138+
fi
139+
done
140+
echo "Deploy is still not complete after approximately 10 minutes."
141+
exit 1
142+
143+
- name: Get GitHub Pages Preview URL
144+
if: success()
145+
shell: bash
146+
run: |
147+
echo "url=https://riptano.github.io/${{ github.event.repository.name }}/${{ steps.extract_branch.outputs.draft_branch }}/" >> $GITHUB_OUTPUT
148+
id: draft_url
149+
150+
- name: Update comment
151+
if: ${{ steps.fc.outputs.comment-id != '' }}
152+
uses: peter-evans/create-or-update-comment@v3
153+
with:
154+
token: ${{ secrets.COMMENT_GITHUB_TOKEN }}
155+
comment-id: ${{ steps.fc.outputs.comment-id }}
156+
body: |
157+
Deployment successful! [View preview](${{ steps.draft_url.outputs.url }})
158+
reactions: hooray
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Dispatch Antora Build and Deploy
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- '*'
7+
8+
jobs:
9+
dispatch-deploy:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Dispatch Antora Build and Deploy
14+
uses: convictional/[email protected]
15+
with:
16+
owner: riptano
17+
repo: datastax-docs-site
18+
github_token: ${{ secrets.DISPATCH_GITHUB_TOKEN }}
19+
github_user: mlr
20+
workflow_file_name: gh-pages-build.yml
21+
client_payload: '{ "build_repository": "${{ github.event.repository.full_name }}", "build_branch": "main", "draft_branch": "${{ github.event.pull_request.head.ref }}", "pull_request_number": "${{ github.event.pull_request.number }}", "ui_bundle_repository": "${{ github.event.repository.full_name }}", "ui_bundle_branch": "${{ github.event.pull_request.head.ref }}" }'
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: Cleanup GitHub Pages
2+
3+
on:
4+
schedule:
5+
# Runs daily at 1AM UTC which is 6PM pacific
6+
- cron: '0 1 * * *'
7+
8+
workflow_dispatch:
9+
inputs:
10+
stale_threshold:
11+
description: 'Threshold after which the preview build is considered to be stale'
12+
default: '2 weeks'
13+
type: string
14+
15+
jobs:
16+
remove_stale_previews:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
with:
22+
ref: 'gh-pages'
23+
fetch-depth: 0
24+
25+
- name: Determine Previews to Delete
26+
id: find_previews
27+
run: |
28+
# Get the stale threshold from the workflow parameter
29+
# and calculate the timestamp for the threshold
30+
STALE_THRESHOLD="${{ github.event.inputs.stale_threshold || '2 weeks' }}"
31+
THRESHOLD_DATE=$(date --date="$STALE_THRESHOLD ago" +%s)
32+
33+
# Find and collect previews older than the specified threshold, skipping "main" and ".git"
34+
STALE_PREVIEWS=()
35+
for dir in $(find . -type d -mindepth 1 -maxdepth 1); do
36+
# Check if the preview name is "main" or ".git" and skip it
37+
if [ "$(basename "$dir")" == "main" ] || [ "$(basename "$dir")" == ".git" ]; then
38+
continue
39+
fi
40+
41+
DIR_DATE=$(git log -1 --format="%ct" -- "$dir")
42+
if [ -n "$DIR_DATE" ] && [ "$DIR_DATE" -lt "$THRESHOLD_DATE" ]; then
43+
STALE_PREVIEWS+=("$(basename "$dir")")
44+
fi
45+
done
46+
47+
if [ -z "${STALE_PREVIEWS[*]}" ]; then
48+
echo "Did not find any stale previews based on $STALE_THRESHOLD threshold. Done."
49+
else
50+
echo "Previews determined to be stale based on $STALE_THRESHOLD threshold: ${STALE_PREVIEWS[*]}"
51+
fi
52+
53+
# Set the list of previews to be removed as an output
54+
echo "previews_to_delete=${STALE_PREVIEWS[*]}" >> $GITHUB_OUTPUT
55+
56+
- name: Notify Open Pull Requests of Preview Removal
57+
if: ${{ steps.find_previews.outputs.previews_to_delete != '' }}
58+
run: |
59+
# Notify open pull requests of their preview being deleted
60+
# but don't fail on this step for any reason
61+
set +e
62+
63+
STALE_PREVIEWS=(${{ steps.find_previews.outputs.previews_to_delete }})
64+
STALE_THRESHOLD="${{ github.event.inputs.stale_threshold || '2 weeks' }}"
65+
66+
# Iterate through the previews and look for open PRs
67+
for dir in "${STALE_PREVIEWS[@]}"; do
68+
if [ -f "$dir/.github_source_repository" ]; then
69+
# Get the source repository for the preview build
70+
SOURCE_REPO=$(cat "$dir/.github_source_repository")
71+
echo "Source repository for $dir is $SOURCE_REPO"
72+
else
73+
# Without .github_source_repository we don't know where to post the comment so we'll skip
74+
echo "Could not determine source repository for $dir. Skipping."
75+
continue
76+
fi
77+
78+
# Check if there are open pull requests for the source repository
79+
OPEN_PRS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$SOURCE_REPO/pulls?state=open")
80+
81+
# Check if any open pull requests match the preview branch name
82+
PREVIEW_PRS=$(echo $OPEN_PRS | jq -r --arg dir "$dir" '.[] | select(.head.ref == $dir) | .number' 2>/dev/null)
83+
84+
if [[ -n "$PREVIEW_PRS" ]]; then
85+
# Comment on the open PRs
86+
for pr_number in $PREVIEW_PRS; do
87+
COMMENT_BODY="The preview build for this pull request has been cleaned up due to being stale.\n\nPreview builds that were $STALE_THRESHOLD old or older were automatically removed to maintain a tidy GitHub Pages site.\n\nYou can rebuild the preview at any time by pushing a new commit to this pull request:\n\n\`\`\`\ngit checkout $dir\ngit commit --allow-empty -m 'rebuild preview'\ngit push origin $dir\n\`\`\`"
88+
curl -X POST -d "{\"body\":\"$COMMENT_BODY\"}" -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$SOURCE_REPO/issues/$pr_number/comments"
89+
done
90+
else
91+
echo "No open pull requests for $dir. No notification needed."
92+
fi
93+
done
94+
95+
env:
96+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
97+
98+
- name: Remove Previews and Push to GitHub Pages
99+
if: ${{ steps.find_previews.outputs.previews_to_delete != '' }}
100+
run: |
101+
# Get the list of directories to delete from the previous step's output
102+
STALE_PREVIEWS=(${{ steps.find_previews.outputs.previews_to_delete }})
103+
104+
# Get the stale threshold from the workflow parameter
105+
# and calculate the timestamp for the threshold
106+
STALE_THRESHOLD="${{ github.event.inputs.stale_threshold || '2 weeks' }}"
107+
108+
echo "Removing stale previews based on $STALE_THRESHOLD threshold: ${STALE_PREVIEWS[*]}"
109+
110+
# Remove the directories and their contents
111+
for dir in "${STALE_PREVIEWS[@]}"; do
112+
rm -rf "$dir"
113+
done
114+
115+
# Commit and push the changes
116+
git add .
117+
118+
if [[ `git status --porcelain` ]]; then
119+
git config user.name 'github-actions[bot]'
120+
git config user.email 'github-actions[bot]@users.noreply.github.com'
121+
git commit -m "Removed previews older than $STALE_THRESHOLD via ${{ github.event_name }} by ${{ github.actor }}"
122+
git push origin gh-pages
123+
else
124+
echo "No previews were deleted."
125+
fi

0 commit comments

Comments
 (0)