-
Notifications
You must be signed in to change notification settings - Fork 0
Add preview deployment workflow for pull requests #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+202
−25
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
fddb50c
Add Cloudflare Pages preview deployment workflow
claude aca1eb1
Fix yamllint errors in preview workflow
claude 26c73ab
Add explicit permissions to all workflows to fix Checkov CKV2_GHA_1
claude 0be39bb
Fix yamllint truthy rule violations in all workflow files
claude ae51804
Fix Prettier formatting and Checkov Dockerfile violations
claude 46f105d
Improve preview workflow: remove duplicate build, harden cleanup
claude dd87b8a
Add last-updated timestamp to preview deployment comment
claude 031d6cc
Address Copilot review comments
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| --- | ||
| name: Preview Deployment | ||
|
|
||
| on: # yamllint disable-line rule:truthy | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, closed] | ||
|
|
||
| concurrency: | ||
| group: preview-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| deploy-preview: | ||
| if: github.event.action != 'closed' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| issues: write | ||
| env: | ||
| PROJECT: ${{ github.event.repository.name }} | ||
| PR_BRANCH: pr-${{ github.event.pull_request.number }} | ||
| 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 ${{ env.PROJECT }} | ||
| --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=${{ env.PROJECT }} | ||
| --branch=${{ env.PR_BRANCH }} | ||
|
|
||
| - name: Comment preview URL on PR | ||
| uses: actions/github-script@v7 | ||
| env: | ||
| DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }} | ||
| with: | ||
| script: | | ||
| const url = process.env.DEPLOY_URL; | ||
| const sha = (context.payload.pull_request?.head?.sha | ||
| || context.sha).substring(0, 7); | ||
| const now = new Date().toUTCString(); | ||
| const body = [ | ||
| '### Preview Deployment', | ||
| '', | ||
| 'This PR has been deployed for preview:', | ||
| '', | ||
| '| Site | URL | Commit |', | ||
| '|---|---|---|', | ||
| `| DevOps Training | ${url} | \`${sha}\` |`, | ||
| '', | ||
| `> Last updated: ${now}`, | ||
| '', | ||
| ].join('\n'); | ||
|
|
||
| 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') | ||
| ); | ||
|
|
||
| const params = { | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| }; | ||
| if (existing) { | ||
| await github.rest.issues.updateComment({ | ||
| ...params, | ||
| comment_id: existing.id, | ||
| body, | ||
| }); | ||
| } else { | ||
| await github.rest.issues.createComment({ | ||
| ...params, | ||
| issue_number: context.issue.number, | ||
| body, | ||
| }); | ||
| } | ||
|
|
||
| cleanup-preview: | ||
| if: github.event.action == 'closed' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Delete preview deployments | ||
| uses: actions/github-script@v7 | ||
| env: | ||
| 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 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.CF_TOKEN}`, | ||
| 'Content-Type': 'application/json', | ||
| }; | ||
|
|
||
| const deployments = []; | ||
| let page = 1; | ||
|
|
||
| const maxPages = 50; | ||
|
|
||
| while (page <= maxPages) { | ||
| const res = await fetch( | ||
| `${url}?page=${page}`, { headers } | ||
| ); | ||
| if (!res.ok) { | ||
| core.warning( | ||
| `Failed to list deployments: ${res.status}` | ||
| ); | ||
| break; | ||
| } | ||
|
|
||
| const data = await res.json(); | ||
| const items = data.result || []; | ||
| deployments.push(...items); | ||
|
|
||
| const info = data.result_info; | ||
| if (!info || page >= (info.total_pages || 0)) { | ||
| break; | ||
| } | ||
| page += 1; | ||
| } | ||
|
|
||
| const matched = deployments.filter(d => | ||
| d.deployment_trigger?.metadata?.branch === | ||
| process.env.BRANCH | ||
| ); | ||
|
|
||
| core.info( | ||
| `Found ${matched.length} deployment(s) ` + | ||
| `for ${process.env.BRANCH}` | ||
| ); | ||
|
|
||
| for (const d of matched) { | ||
| const delUrl = `${url}/${d.id}?force=true`; | ||
| const res = await fetch(delUrl, { | ||
| method: 'DELETE', | ||
| headers, | ||
| }); | ||
| if (res.ok) { | ||
| core.info(`Deleted deployment ${d.id}`); | ||
| } else { | ||
| core.warning( | ||
| `Failed to delete ${d.id}: ${res.status}` | ||
| ); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.