diff --git a/.github/workflows/cloudflare-preview.yml b/.github/workflows/cloudflare-preview.yml new file mode 100644 index 0000000000..461cacdfc6 --- /dev/null +++ b/.github/workflows/cloudflare-preview.yml @@ -0,0 +1,117 @@ +name: Cloudflare Pages Preview Deployment + +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: + inputs: + pull_request_number: + description: 'Pull Request Number (for fork PRs)' + required: true + type: string + +jobs: + deploy-preview: + 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' }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - name: Checkout for manually triggered fork PR + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - 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" + + # 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 url = "${{ steps.deploy.outputs.deployment-url }}"; + const commentMarker = "🚀 Preview deployment available at:"; + + // 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 current commit + commitSha = '${{ github.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, + repo: context.repo.repo, + body: commentBody + }); + console.log("Updated existing preview comment"); + } else { + // Create new comment + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Created new preview comment"); + } diff --git a/.github/workflows/pr-preview-comment.yml b/.github/workflows/pr-preview-comment.yml new file mode 100644 index 0000000000..87ae033d53 --- /dev/null +++ b/.github/workflows/pr-preview-comment.yml @@ -0,0 +1,68 @@ +name: Comment on Fork PRs + +on: + pull_request: + types: [opened, reopened, synchronize] + +jobs: + comment-on-fork-pr: + runs-on: ubuntu-latest + # Only run for fork PRs + if: github.event.pull_request.head.repo.fork == true + steps: + - name: Comment on PR with manual deployment instructions + uses: actions/github-script@v7 + with: + script: |- + const prNumber = context.payload.pull_request.number; + const workflowUrl = `https://github.com/ruby/rdoc/actions/workflows/cloudflare-preview.yml`; + const branch = context.payload.pull_request.head.ref; + const commentMarker = "## Cloudflare Preview Deployment"; + + // Create a direct link that pre-fills the PR number input + const dispatchUrl = `${workflowUrl}/dispatch?ref=main&inputs%5Bpull_request_number%5D=${prNumber}`; + + // 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 messageLines = [ + `${commentMarker}`, + `⚠️ This PR is from a fork, so the preview deployment workflow doesn't run automatically for security reasons.`, + `If you're a maintainer and want to preview this PR:`, + ``, + `[➡️ Click here to run the workflow with PR #${prNumber} pre-filled](${dispatchUrl})`, + ``, + `This will trigger a Cloudflare Pages preview deployment for this PR.` + ]; + + const commentBody = messageLines.join('\n'); + + if (existingComment) { + // Update existing comment + await github.rest.issues.updateComment({ + comment_id: existingComment.id, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Updated existing fork PR comment"); + } else { + // Create new comment + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log("Created new fork PR comment"); + }