Skip to content

Send Bonus Milestone self-report and use API season rules #581

Send Bonus Milestone self-report and use API season rules

Send Bonus Milestone self-report and use API season rules #581

Workflow file for this run

name: Deploy PR preview
on:
pull_request:
types: [opened, reopened, synchronize, closed]
paths:
- "app/**"
- "components/**"
- "public/**"
- "package.json"
- "yarn.lock"
- "next.config.mjs"
- ".github/workflows/pr-preview.yml"
- ".github/workflows/nextjs.yml"
jobs:
preview-status:
if: github.event.pull_request.head.repo.full_name == github.repository && github.event.action != 'closed'
runs-on: ubuntu-latest
timeout-minutes: 2
permissions:
pull-requests: write
steps:
- name: Mark PR preview as building
uses: actions/github-script@v7
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
with:
script: |
const marker = '<!-- gcsb-pr-preview -->'
const body = `${marker}\n## ⏳ PR preview building\n\nThe preview is queued or currently building.\n\n- Commit: \`${process.env.HEAD_SHA.slice(0, 7)}\`\n- The live preview link will appear only after deployment succeeds and the URL responds successfully.`
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
})
const existing = comments.find((comment) => comment.body?.includes(marker))
if (existing) {
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body })
} else {
await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body })
}
preview:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
timeout-minutes: 25
permissions:
actions: read
contents: write
pull-requests: write
pages: write
id-token: write
concurrency:
group: gcsb-pages-content-v3
cancel-in-progress: false
environment:
name: pr-preview
url: https://arcade.eplus.dev/pr-preview/pr-${{ github.event.number }}/
steps:
- name: Checkout production source
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
path: production-source
persist-credentials: false
- name: Checkout pull request source
if: github.event.action != 'closed'
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
path: preview-source
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: yarn
cache-dependency-path: production-source/yarn.lock
- name: Build current production version
working-directory: production-source
env:
NEXT_PUBLIC_ENABLE_ANALYTICS: "true"
NEXT_PUBLIC_GA_ID: "G-SJNYKL2864"
NEXT_PUBLIC_GA_IDS: "G-SJNYKL2864"
shell: bash
run: |
set -euo pipefail
yarn install --frozen-lockfile --non-interactive
cat > next.config.mjs <<'CONFIG'
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
trailingSlash: true,
images: { unoptimized: true },
}
export default nextConfig
CONFIG
yarn build
- name: Build pull request preview
if: github.event.action != 'closed'
working-directory: preview-source
env:
NEXT_STATIC_EXPORT: "true"
NEXT_PUBLIC_BASE_PATH: "/pr-preview/pr-${{ github.event.number }}"
NEXT_PUBLIC_ENABLE_ANALYTICS: "false"
NEXT_PUBLIC_GA_ID: ""
NEXT_PUBLIC_COOKIE_CONSENT_PREVIEW: "true"
run: |
yarn install --frozen-lockfile --non-interactive
yarn build
- name: Verify preview output
if: github.event.action != 'closed'
working-directory: preview-source
env:
PREVIEW_PATH: "/pr-preview/pr-${{ github.event.number }}"
REPO_NAME: ${{ github.event.repository.name }}
shell: bash
run: |
set -euo pipefail
test -f out/index.html
grep -q "${PREVIEW_PATH}/_next/" out/index.html
grep -q 'name="cookie-notice-preview" content="true"' out/index.html
if grep -R -F -q "G-SJNYKL2864" out; then exit 1; fi
if grep -R -F -q "www.googletagmanager.com/gtag/js" out; then exit 1; fi
if grep -q "/${REPO_NAME}/pr-preview/" out/index.html; then exit 1; fi
- name: Assemble production and preview content
env:
PR_NUMBER: ${{ github.event.number }}
PR_ACTION: ${{ github.event.action }}
shell: bash
run: |
set -euo pipefail
rm -rf published-site
if git ls-remote --exit-code --heads "https://github.com/${GITHUB_REPOSITORY}.git" gh-pages >/dev/null 2>&1; then
git clone --depth 1 --branch gh-pages "https://github.com/${GITHUB_REPOSITORY}.git" published-site
rm -rf published-site/.git
else
mkdir -p published-site
fi
mkdir -p published-site/pr-preview
find published-site -mindepth 1 -maxdepth 1 ! -name pr-preview -exec rm -rf {} +
cp -a production-source/out/. published-site/
preview_dir="published-site/pr-preview/pr-${PR_NUMBER}"
rm -rf "${preview_dir}"
if [ "${PR_ACTION}" != "closed" ]; then
mkdir -p "${preview_dir}"
cp -a preview-source/out/. "${preview_dir}/"
fi
touch published-site/.nojekyll
- name: Save complete Pages content
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
PR_ACTION: ${{ github.event.action }}
shell: bash
run: |
set -euo pipefail
cd published-site
git init
git checkout -B gh-pages
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "preview: ${PR_ACTION} PR #${PR_NUMBER}"
git push --force "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" gh-pages
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: published-site
include-hidden-files: true
- name: Deploy GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
- name: Verify live preview URL
if: success() && github.event.action != 'closed'
env:
PREVIEW_URL: https://arcade.eplus.dev/pr-preview/pr-${{ github.event.number }}/
shell: bash
run: |
set -euo pipefail
for attempt in $(seq 1 18); do
if curl --fail --silent --show-error --location --max-time 15 "${PREVIEW_URL}" >/dev/null; then
echo "Preview is live: ${PREVIEW_URL}"
exit 0
fi
echo "Preview not live yet (attempt ${attempt}/18); waiting 5s..."
sleep 5
done
echo "Preview URL did not become reachable after deployment: ${PREVIEW_URL}" >&2
exit 1
- name: Add preview link to pull request
if: success()
uses: actions/github-script@v7
env:
PAGE_ROOT: https://arcade.eplus.dev/
PR_ACTION: ${{ github.event.action }}
PR_NUMBER: ${{ github.event.number }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
with:
script: |
const marker = '<!-- gcsb-pr-preview -->'
const root = process.env.PAGE_ROOT.endsWith('/') ? process.env.PAGE_ROOT : `${process.env.PAGE_ROOT}/`
const previewUrl = `${root}pr-preview/pr-${process.env.PR_NUMBER}/`
const removed = process.env.PR_ACTION === 'closed'
const body = removed
? `${marker}\n## 🧹 PR preview removed\n\nThe preview for this pull request was removed after the PR was closed.`
: `${marker}\n## 🚀 PR preview ready\n\n[Open the live preview](${previewUrl})\n\n- Commit: \`${process.env.HEAD_SHA.slice(0, 7)}\`\n- Pages artifact deployed successfully\n- Live URL verified successfully\n- Google Analytics remains disabled in previews\n- Updates automatically when new commits are pushed`
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
})
const existing = comments.find((comment) => comment.body?.includes(marker))
if (existing) {
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body })
} else {
await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body })
}
- name: Mark PR preview as failed
if: failure() && github.event.action != 'closed'
uses: actions/github-script@v7
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
with:
script: |
const marker = '<!-- gcsb-pr-preview -->'
const body = `${marker}\n## ❌ PR preview failed\n\nThe preview could not be deployed or verified for commit \`${process.env.HEAD_SHA.slice(0, 7)}\`.\n\nNo live preview link is published until deployment and live verification both succeed.`
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
})
const existing = comments.find((comment) => comment.body?.includes(marker))
if (existing) {
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body })
} else {
await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body })
}