From fddb50c6254a21332614bcf0595a90b4b9baa5ce Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 15 Mar 2026 16:31:41 +0000 Subject: [PATCH 1/8] Add Cloudflare Pages preview deployment workflow Adds a GitHub Actions workflow that deploys PR previews to Cloudflare Pages, matching the same mechanism used in the presentations repo. On PR open/update it builds the Docusaurus site and deploys it, commenting a preview URL on the PR. On PR close it cleans up the preview deployments. Requires CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID repository secrets. https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/preview.yml | 144 ++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 0000000..0304080 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,144 @@ +name: Preview Deployment + +on: + pull_request: + types: [opened, synchronize, reopened, closed] + +permissions: + contents: read + pull-requests: write + issues: write + +concurrency: + group: preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + deploy-preview: + if: github.event.action != 'closed' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build site + run: npm run build + + - name: Create Cloudflare Pages project if needed + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages project create ${{ github.event.repository.name }} --production-branch=main + continue-on-error: true + + - name: Deploy to Cloudflare Pages + id: deploy + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy build --project-name=${{ github.event.repository.name }} --branch=pr-${{ github.event.pull_request.number }} + + - name: Comment preview URL on PR + uses: actions/github-script@v7 + env: + DEPLOYMENT_URL: ${{ steps.deploy.outputs.deployment-url }} + with: + script: | + const body = `### Preview Deployment\n\nThis PR has been deployed for preview:\n\n` + + `| Site | URL |\n|---|---|\n` + + `| DevOps Training | ${process.env.DEPLOYMENT_URL} |\n`; + + // Find existing bot comment + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const botComment = comments.find(c => + c.user.type === 'Bot' && c.body.includes('### Preview Deployment') + ); + + if (botComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } + + cleanup-preview: + if: github.event.action == 'closed' + runs-on: ubuntu-latest + steps: + - name: Delete preview deployments + uses: actions/github-script@v7 + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + PROJECT_NAME: ${{ github.event.repository.name }} + BRANCH_ALIAS: pr-${{ github.event.pull_request.number }} + with: + script: | + const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/pages/projects/${process.env.PROJECT_NAME}/deployments`; + const headers = { + 'Authorization': `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`, + 'Content-Type': 'application/json', + }; + + // List deployments (with pagination) and delete those matching this PR's branch alias + const deployments = []; + let page = 1; + + while (true) { + const url = `${baseUrl}?page=${page}`; + const res = await fetch(url, { headers }); + if (!res.ok) { + core.warning(`Failed to list deployments on page ${page}: ${res.status}`); + break; + } + + const data = await res.json(); + const pageDeployments = Array.isArray(data.result) ? data.result : []; + deployments.push(...pageDeployments); + + const info = data.result_info; + if (!info || typeof info.total_pages !== 'number' || page >= info.total_pages) { + break; + } + + page += 1; + } + const prDeployments = deployments.filter( + d => d.deployment_trigger?.metadata?.branch === process.env.BRANCH_ALIAS + ); + + core.info(`Found ${prDeployments.length} deployment(s) for ${process.env.BRANCH_ALIAS}`); + + for (const d of prDeployments) { + const delRes = await fetch(`${baseUrl}/${d.id}?force=true`, { + method: 'DELETE', + headers, + }); + if (delRes.ok) { + core.info(`Deleted deployment ${d.id}`); + } else { + core.warning(`Failed to delete deployment ${d.id}: ${delRes.status}`); + } + } From aca1eb1bb68592bfc7e53696efc5e5a3b08c036e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 09:45:29 +0000 Subject: [PATCH 2/8] Fix yamllint errors in preview workflow Wrap long lines to stay within 80 character limit and add YAML document start marker to pass super-linter checks. https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/preview.yml | 115 ++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 41 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 0304080..be20fbf 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,3 +1,4 @@ +--- name: Preview Deployment on: @@ -17,6 +18,9 @@ jobs: deploy-preview: if: github.event.action != 'closed' runs-on: ubuntu-latest + env: + PROJECT: ${{ github.event.repository.name }} + PR_BRANCH: pr-${{ github.event.pull_request.number }} steps: - uses: actions/checkout@v4 @@ -36,7 +40,9 @@ jobs: with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages project create ${{ github.event.repository.name }} --production-branch=main + command: >- + pages project create ${{ env.PROJECT }} + --production-branch=main continue-on-error: true - name: Deploy to Cloudflare Pages @@ -45,39 +51,53 @@ jobs: with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy build --project-name=${{ github.event.repository.name }} --branch=pr-${{ github.event.pull_request.number }} + command: >- + pages deploy build + --project-name=${{ env.PROJECT }} + --branch=${{ env.PR_BRANCH }} - name: Comment preview URL on PR uses: actions/github-script@v7 env: - DEPLOYMENT_URL: ${{ steps.deploy.outputs.deployment-url }} + DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }} with: script: | - const body = `### Preview Deployment\n\nThis PR has been deployed for preview:\n\n` + - `| Site | URL |\n|---|---|\n` + - `| DevOps Training | ${process.env.DEPLOYMENT_URL} |\n`; + const url = process.env.DEPLOY_URL; + const body = [ + '### Preview Deployment', + '', + 'This PR has been deployed for preview:', + '', + '| Site | URL |', + '|---|---|', + `| DevOps Training | ${url} |`, + '', + ].join('\n'); + + const { data: comments } = await github.rest.issues + .listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const existing = comments.find(c => + c.user.type === 'Bot' && + c.body.includes('### Preview Deployment') + ); - // Find existing bot comment - const { data: comments } = await github.rest.issues.listComments({ + const params = { owner: context.repo.owner, repo: context.repo.repo, - issue_number: context.issue.number, - }); - const botComment = comments.find(c => - c.user.type === 'Bot' && c.body.includes('### Preview Deployment') - ); - - if (botComment) { + }; + if (existing) { await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: botComment.id, + ...params, + comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, + ...params, issue_number: context.issue.number, body, }); @@ -90,55 +110,68 @@ jobs: - name: Delete preview deployments uses: actions/github-script@v7 env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - PROJECT_NAME: ${{ github.event.repository.name }} - BRANCH_ALIAS: pr-${{ github.event.pull_request.number }} + CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + PROJECT: ${{ github.event.repository.name }} + BRANCH: pr-${{ github.event.pull_request.number }} with: script: | - const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/pages/projects/${process.env.PROJECT_NAME}/deployments`; + const acct = process.env.CF_ACCOUNT; + const proj = process.env.PROJECT; + const base = 'https://api.cloudflare.com/client/v4'; + const url = `${base}/accounts/${acct}` + + `/pages/projects/${proj}/deployments`; const headers = { - 'Authorization': `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`, + 'Authorization': `Bearer ${process.env.CF_TOKEN}`, 'Content-Type': 'application/json', }; - // List deployments (with pagination) and delete those matching this PR's branch alias const deployments = []; let page = 1; while (true) { - const url = `${baseUrl}?page=${page}`; - const res = await fetch(url, { headers }); + const res = await fetch( + `${url}?page=${page}`, { headers } + ); if (!res.ok) { - core.warning(`Failed to list deployments on page ${page}: ${res.status}`); + core.warning( + `Failed to list deployments: ${res.status}` + ); break; } const data = await res.json(); - const pageDeployments = Array.isArray(data.result) ? data.result : []; - deployments.push(...pageDeployments); + const items = data.result || []; + deployments.push(...items); const info = data.result_info; - if (!info || typeof info.total_pages !== 'number' || page >= info.total_pages) { + if (!info || page >= (info.total_pages || 0)) { break; } - page += 1; } - const prDeployments = deployments.filter( - d => d.deployment_trigger?.metadata?.branch === process.env.BRANCH_ALIAS + + const matched = deployments.filter(d => + d.deployment_trigger?.metadata?.branch === + process.env.BRANCH ); - core.info(`Found ${prDeployments.length} deployment(s) for ${process.env.BRANCH_ALIAS}`); + core.info( + `Found ${matched.length} deployment(s) ` + + `for ${process.env.BRANCH}` + ); - for (const d of prDeployments) { - const delRes = await fetch(`${baseUrl}/${d.id}?force=true`, { + for (const d of matched) { + const delUrl = `${url}/${d.id}?force=true`; + const res = await fetch(delUrl, { method: 'DELETE', headers, }); - if (delRes.ok) { + if (res.ok) { core.info(`Deleted deployment ${d.id}`); } else { - core.warning(`Failed to delete deployment ${d.id}: ${delRes.status}`); + core.warning( + `Failed to delete ${d.id}: ${res.status}` + ); } } From 26c73ab18632c1c317e0cb6bd8710378e7964fa8 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 10:10:17 +0000 Subject: [PATCH 3/8] Add explicit permissions to all workflows to fix Checkov CKV2_GHA_1 Checkov (run by super-linter) requires workflows to declare explicit top-level permissions rather than relying on defaults. Add minimal permissions blocks to linter, test deploy, and deploy workflows. https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/gh-pages-deploy.yml | 4 ++++ .github/workflows/gh-pages-test-deploy.yml | 3 +++ .github/workflows/linter.yml | 3 +++ 3 files changed, 10 insertions(+) diff --git a/.github/workflows/gh-pages-deploy.yml b/.github/workflows/gh-pages-deploy.yml index 804fabb..65c89ca 100644 --- a/.github/workflows/gh-pages-deploy.yml +++ b/.github/workflows/gh-pages-deploy.yml @@ -5,6 +5,10 @@ on: push: branches: [main] +permissions: + contents: read + pages: write + jobs: deploy: name: Deploy to GitHub Pages diff --git a/.github/workflows/gh-pages-test-deploy.yml b/.github/workflows/gh-pages-test-deploy.yml index 145e681..7105c30 100644 --- a/.github/workflows/gh-pages-test-deploy.yml +++ b/.github/workflows/gh-pages-test-deploy.yml @@ -5,6 +5,9 @@ on: pull_request: branches: [main] +permissions: + contents: read + jobs: test-deploy: name: GitHub Pages test deployment diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 23d3e5b..d20604e 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -19,6 +19,9 @@ on: pull_request: branches: [main] +permissions: + contents: read + ############### # Set the Job # ############### From 0be39bbb149e8d7deca8983faabd56547a531211 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 13:47:49 +0000 Subject: [PATCH 4/8] Fix yamllint truthy rule violations in all workflow files Add yamllint disable-line directives for the truthy rule on `on:` keys in all GitHub Actions workflow files. The `on` key triggers a yamllint truthy warning which super-linter treats as an error. https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/gh-pages-deploy.yml | 2 +- .github/workflows/gh-pages-test-deploy.yml | 2 +- .github/workflows/linter.yml | 2 +- .github/workflows/preview.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gh-pages-deploy.yml b/.github/workflows/gh-pages-deploy.yml index 65c89ca..4a1cb10 100644 --- a/.github/workflows/gh-pages-deploy.yml +++ b/.github/workflows/gh-pages-deploy.yml @@ -1,7 +1,7 @@ --- name: Deploy to GitHub Pages -on: +on: # yamllint disable-line rule:truthy push: branches: [main] diff --git a/.github/workflows/gh-pages-test-deploy.yml b/.github/workflows/gh-pages-test-deploy.yml index 7105c30..0f497b2 100644 --- a/.github/workflows/gh-pages-test-deploy.yml +++ b/.github/workflows/gh-pages-test-deploy.yml @@ -1,7 +1,7 @@ --- name: GitHub Pages test deployment -on: +on: # yamllint disable-line rule:truthy pull_request: branches: [main] diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index d20604e..ac15cb0 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -14,7 +14,7 @@ name: Lint Code Base ############################# # Start the job on all push # ############################# -on: +on: # yamllint disable-line rule:truthy push: pull_request: branches: [main] diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index be20fbf..9f41aae 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,7 +1,7 @@ --- name: Preview Deployment -on: +on: # yamllint disable-line rule:truthy pull_request: types: [opened, synchronize, reopened, closed] From ae5180491e8a63ffba96cc8c6fb92c9097257ba3 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 13:54:05 +0000 Subject: [PATCH 5/8] Fix Prettier formatting and Checkov Dockerfile violations - Apply Prettier formatting to all workflow YAML files - Add USER instruction to Dockerfile (CKV_DOCKER_3) - Add HEALTHCHECK instruction to Dockerfile (CKV_DOCKER_2) https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/gh-pages-deploy.yml | 2 +- .github/workflows/gh-pages-test-deploy.yml | 2 +- .github/workflows/linter.yml | 2 +- .github/workflows/preview.yml | 2 +- Dockerfile | 5 +++++ 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gh-pages-deploy.yml b/.github/workflows/gh-pages-deploy.yml index 4a1cb10..44ecbc3 100644 --- a/.github/workflows/gh-pages-deploy.yml +++ b/.github/workflows/gh-pages-deploy.yml @@ -1,7 +1,7 @@ --- name: Deploy to GitHub Pages -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy push: branches: [main] diff --git a/.github/workflows/gh-pages-test-deploy.yml b/.github/workflows/gh-pages-test-deploy.yml index 0f497b2..ac4b0d1 100644 --- a/.github/workflows/gh-pages-test-deploy.yml +++ b/.github/workflows/gh-pages-test-deploy.yml @@ -1,7 +1,7 @@ --- name: GitHub Pages test deployment -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy pull_request: branches: [main] diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index ac15cb0..8bf9827 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -14,7 +14,7 @@ name: Lint Code Base ############################# # Start the job on all push # ############################# -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy push: pull_request: branches: [main] diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 9f41aae..67183d5 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,7 +1,7 @@ --- name: Preview Deployment -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy pull_request: types: [opened, synchronize, reopened, closed] diff --git a/Dockerfile b/Dockerfile index be78611..39cab85 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,9 @@ COPY ./ /app RUN yarn install \ && yarn cache clean +USER node + +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:3000/ || exit 1 + CMD ["yarn", "start"] From 46f105d266e4ca8a285c0caa03dd6374da2dd70c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 14:06:22 +0000 Subject: [PATCH 6/8] Improve preview workflow: remove duplicate build, harden cleanup - Remove gh-pages-test-deploy.yml since preview.yml already validates the build on every PR - Add commit SHA to preview deployment comment for traceability - Add page-limit safety valve (max 50) in cleanup pagination - Move permissions to job-level for least privilege - Drop unnecessary issues: write permission https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/gh-pages-test-deploy.yml | 25 ---------------------- .github/workflows/preview.yml | 21 ++++++++++-------- 2 files changed, 12 insertions(+), 34 deletions(-) delete mode 100644 .github/workflows/gh-pages-test-deploy.yml diff --git a/.github/workflows/gh-pages-test-deploy.yml b/.github/workflows/gh-pages-test-deploy.yml deleted file mode 100644 index ac4b0d1..0000000 --- a/.github/workflows/gh-pages-test-deploy.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: GitHub Pages test deployment - -on: # yamllint disable-line rule:truthy - pull_request: - branches: [main] - -permissions: - contents: read - -jobs: - test-deploy: - name: GitHub Pages test deployment - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Test build - run: | - npm ci - npm run build diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 67183d5..b59967f 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -5,11 +5,6 @@ on: # yamllint disable-line rule:truthy pull_request: types: [opened, synchronize, reopened, closed] -permissions: - contents: read - pull-requests: write - issues: write - concurrency: group: preview-${{ github.event.pull_request.number }} cancel-in-progress: true @@ -18,6 +13,9 @@ jobs: deploy-preview: if: github.event.action != 'closed' runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write env: PROJECT: ${{ github.event.repository.name }} PR_BRANCH: pr-${{ github.event.pull_request.number }} @@ -63,14 +61,15 @@ jobs: with: script: | const url = process.env.DEPLOY_URL; + const sha = context.sha.substring(0, 7); const body = [ '### Preview Deployment', '', 'This PR has been deployed for preview:', '', - '| Site | URL |', - '|---|---|', - `| DevOps Training | ${url} |`, + '| Site | URL | Commit |', + '|---|---|---|', + `| DevOps Training | ${url} | \`${sha}\` |`, '', ].join('\n'); @@ -106,6 +105,8 @@ jobs: cleanup-preview: if: github.event.action == 'closed' runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Delete preview deployments uses: actions/github-script@v7 @@ -129,7 +130,9 @@ jobs: const deployments = []; let page = 1; - while (true) { + const maxPages = 50; + + while (page <= maxPages) { const res = await fetch( `${url}?page=${page}`, { headers } ); From dd87b8a6ff9ae73f27e1d68b8c6485fa1b2dc2a8 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 20:10:28 +0000 Subject: [PATCH 7/8] Add last-updated timestamp to preview deployment comment https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/preview.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index b59967f..a381897 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -62,6 +62,7 @@ jobs: script: | const url = process.env.DEPLOY_URL; const sha = context.sha.substring(0, 7); + const now = new Date().toUTCString(); const body = [ '### Preview Deployment', '', @@ -71,6 +72,8 @@ jobs: '|---|---|---|', `| DevOps Training | ${url} | \`${sha}\` |`, '', + `> Last updated: ${now}`, + '', ].join('\n'); const { data: comments } = await github.rest.issues From 031d6cc7171f279c8785cb237378f3e36ee3b8ae Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 20:24:08 +0000 Subject: [PATCH 8/8] Address Copilot review comments - Dockerfile: add --chown=node:node to COPY so /app is writable as node - preview.yml: add issues: write permission for PR comment API calls - preview.yml: use github.paginate() for listComments to handle >30 comments - preview.yml: use PR head SHA instead of merge commit SHA - gh-pages-deploy.yml: grant contents: write for gh-pages branch push https://claude.ai/code/session_01P7QZZ9gtBDbS6BeoLdrPMt --- .github/workflows/gh-pages-deploy.yml | 2 +- .github/workflows/preview.yml | 12 ++++++++---- Dockerfile | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gh-pages-deploy.yml b/.github/workflows/gh-pages-deploy.yml index 44ecbc3..57bd594 100644 --- a/.github/workflows/gh-pages-deploy.yml +++ b/.github/workflows/gh-pages-deploy.yml @@ -6,7 +6,7 @@ on: # yamllint disable-line rule:truthy branches: [main] permissions: - contents: read + contents: write pages: write jobs: diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a381897..8512e34 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -16,6 +16,7 @@ jobs: permissions: contents: read pull-requests: write + issues: write env: PROJECT: ${{ github.event.repository.name }} PR_BRANCH: pr-${{ github.event.pull_request.number }} @@ -61,7 +62,8 @@ jobs: with: script: | const url = process.env.DEPLOY_URL; - const sha = context.sha.substring(0, 7); + const sha = (context.payload.pull_request?.head?.sha + || context.sha).substring(0, 7); const now = new Date().toUTCString(); const body = [ '### Preview Deployment', @@ -76,12 +78,14 @@ jobs: '', ].join('\n'); - const { data: comments } = await github.rest.issues - .listComments({ + const comments = await github.paginate( + github.rest.issues.listComments, + { owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, - }); + } + ); const existing = comments.find(c => c.user.type === 'Bot' && c.body.includes('### Preview Deployment') diff --git a/Dockerfile b/Dockerfile index 39cab85..45c4a28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM node:lts WORKDIR /app EXPOSE 3000 35729 -COPY ./ /app +COPY --chown=node:node ./ /app RUN yarn install \ && yarn cache clean