Skip to content

Refactor PR preview workflow for improved approval process #1370

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 32 additions & 79 deletions .github/workflows/cloudflare-preview.yml
Original file line number Diff line number Diff line change
@@ -1,128 +1,82 @@
name: Cloudflare Pages Preview Deployment
name: Build and Deploy Cloudflare Preview

on:
# Runs automatically for PRs from ruby/rdoc
# Fork PRs will be filtered out by the if condition
pull_request:

# Allows manual triggering for fork PRs
workflow_dispatch:
workflow_call:
inputs:
pull_request_number:
description: 'Pull Request Number (for fork PRs)'
pr_number:
description: 'The pull request number'
required: true
type: string
pr_head_sha:
description: 'The SHA of the PR head commit'
required: true
type: string
pr_checkout_repository:
description: 'The repository to checkout (owner/repo)'
required: true
type: string
secrets:
cloudflare_api_token:
description: 'Cloudflare API Token'
required: true
cloudflare_account_id:
description: 'Cloudflare Account ID'
required: true

permissions:
pull-requests: write # To allow commenting on the PR

jobs:
deploy-preview:
build-deploy-and-comment:
name: Build, Deploy, and Comment
runs-on: ubuntu-latest
# Skip if PR from fork and NOT manually triggered
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == 'ruby/rdoc' }}

steps:
- name: Checkout for PR from main repo
if: ${{ github.event_name == 'pull_request' }}
- name: Checkout PR Code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}

# For fork PRs that are manually triggered, we need to get the PR details first
- name: Get PR details for fork
if: ${{ github.event_name == 'workflow_dispatch' }}
id: pr_details
uses: actions/github-script@v7
with:
script: |
const prNumber = ${{ inputs.pull_request_number }};

// Get PR details to find the head SHA
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});

console.log(`Fork PR head SHA: ${pr.head.sha}`);
console.log(`Fork PR head ref: ${pr.head.ref}`);
console.log(`Fork PR repo: ${pr.head.repo.full_name}`);

// Set outputs for checkout step
core.setOutput('head_sha', pr.head.sha);
core.setOutput('head_ref', pr.head.ref);
core.setOutput('repo_full_name', pr.head.repo.full_name);

- name: Checkout for manually triggered fork PR
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: actions/checkout@v4
with:
ref: ${{ steps.pr_details.outputs.head_sha }}
repository: ${{ steps.pr_details.outputs.repo_full_name }}
repository: ${{ inputs.pr_checkout_repository }}
ref: ${{ inputs.pr_head_sha }}

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler-cache: true

- name: Install dependencies
run: bundle install

- name: Build site
run: bundle exec rake rdoc

- name: Set PR Number
id: pr_number
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
else
echo "PR_NUMBER=${{ inputs.pull_request_number }}" >> $GITHUB_ENV
fi

# Deploy to Cloudflare Pages using wrangler-action
- 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 ./_site --project-name=rdoc --branch="${{ env.PR_NUMBER }}-preview"
apiToken: ${{ secrets.cloudflare_api_token }}
accountId: ${{ secrets.cloudflare_account_id }}
command: pages deploy ./_site --project-name=rdoc --branch="${{ inputs.pr_number }}-preview"

# Comment on PR with preview URL - works for both regular PRs and fork PRs
- name: Comment on PR with preview URL
uses: actions/github-script@v7
with:
script: |
const prNumber = ${{ env.PR_NUMBER }};
const prNumber = ${{ inputs.pr_number }};
const url = "${{ steps.deploy.outputs.deployment-url }}";
const commentMarker = "🚀 Preview deployment available at:";
const commitSha = '${{ inputs.pr_head_sha }}';

// Get commit SHA based on event type
let commitSha;
if ('${{ github.event_name }}' === 'pull_request') {
commitSha = '${{ github.event.pull_request.head.sha }}';
} else {
// For workflow_dispatch, get the SHA from the PR details
commitSha = '${{ steps.pr_details.outputs.head_sha }}';
}

// Get all comments on the PR
const comments = await github.rest.issues.listComments({
issue_number: prNumber,
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
});

// Look for our previous bot comment
const existingComment = comments.data.find(comment =>
comment.body.includes(commentMarker)
);

const commentBody = `${commentMarker} [${url}](${url}) (commit: ${commitSha})`;

if (existingComment) {
// Update existing comment
await github.rest.issues.updateComment({
comment_id: existingComment.id,
owner: context.repo.owner,
Expand All @@ -131,7 +85,6 @@ jobs:
});
console.log("Updated existing preview comment");
} else {
// Create new comment
await github.rest.issues.createComment({
issue_number: prNumber,
owner: context.repo.owner,
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/pr-preview-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: PR Preview Check and Trigger

on:
pull_request:

jobs:
# For PRs from the main repo - direct call to the shared workflow
trigger-main-repo-preview:
name: Trigger Preview (Main Repo)
uses: ./.github/workflows/cloudflare-preview.yml
if: github.event.pull_request.head.repo.fork == false
with:
pr_number: ${{ github.event.pull_request.number }}
pr_head_sha: ${{ github.event.pull_request.head.sha }}
pr_checkout_repository: ${{ github.repository }}
secrets:
cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

# For fork PRs - this job requires approval
wait-for-approval:
name: Wait for Approval (Fork PR)
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.fork == true
environment: fork-preview-protection
# This job only serves as an approval gate - it doesn't do anything else
steps:
- run: echo "Approval granted. Proceeding with preview deployment for commit ${{ github.event.pull_request.head.sha }}."

# Once approval is granted, call the shared workflow
trigger-fork-preview:
name: Trigger Preview (Fork - After Approval)
needs: wait-for-approval
uses: ./.github/workflows/cloudflare-preview.yml
if: github.event.pull_request.head.repo.fork == true
with:
pr_number: ${{ github.event.pull_request.number }}
pr_head_sha: ${{ github.event.pull_request.head.sha }}
pr_checkout_repository: ${{ github.event.pull_request.head.repo.full_name }}
secrets:
cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN_FOR_FORKS }}
cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID_FOR_FORKS }}
72 changes: 0 additions & 72 deletions .github/workflows/pr-preview-comment.yml

This file was deleted.

Loading