Article : GitHub Issues Driven Development #7
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
| name: Preview PR on Surge | |
| on: | |
| issue_comment: | |
| types: [created] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: preview-${{ github.event.issue.number || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| preview: | |
| runs-on: ubuntu-latest | |
| # Run only if it's a /preview comment on a pull request (not an issue) | |
| if: > | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '/preview') | |
| steps: | |
| - name: Resolve PR number | |
| shell: bash | |
| run: | | |
| echo "PR_NUMBER=${{ github.event.issue.number }}" >> $GITHUB_ENV | |
| echo "Resolved PR_NUMBER=${{ github.event.issue.number }}" | |
| - name: Comment PR with preview starting | |
| id: start_comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const prNumber = Number(process.env.PR_NUMBER); | |
| const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; | |
| const body = `⏳ **Preview build in progress...**\n\n🔗 [View workflow run](${runUrl})`; | |
| const { data: comment } = await github.rest.issues.createComment({ | |
| issue_number: prNumber, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body | |
| }); | |
| core.setOutput('comment_id', comment.id); | |
| # Checkout PR merge ref | |
| - name: Checkout PR (merge ref) | |
| uses: actions/checkout@v4.1.7 | |
| with: | |
| ref: refs/pull/${{ env.PR_NUMBER }}/merge | |
| - name: Setup Graphviz | |
| uses: ts-graphviz/setup-graphviz@v2 | |
| - name: Setup Ruby | |
| uses: ruby/setup-ruby@v1.180.1 | |
| with: | |
| ruby-version: '3.1' # Not needed with a .ruby-version file | |
| bundler-cache: true # runs 'bundle install' and caches installed gems automatically | |
| cache-version: 1 # Increment this number if you need to re-download cached gems | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install Surge | |
| run: npm install -g surge | |
| - name: Build with Jekyll | |
| run: | | |
| bundle exec jekyll build | |
| env: | |
| JEKYLL_ENV: production | |
| - name: Check SURGE_TOKEN | |
| env: | |
| SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} | |
| run: | | |
| if [ -z "$SURGE_TOKEN" ]; then | |
| echo "❌ ERROR: SURGE_TOKEN is not set!" | |
| echo "" | |
| echo "SURGE_TOKEN is mandatory to deploy to surge.sh with an account." | |
| echo "" | |
| echo "To generate a token:" | |
| echo " 1. Install surge: npm install -g surge" | |
| echo " 2. Login: surge login" | |
| echo " 3. Generate token: surge token" | |
| echo "" | |
| echo "Then add the token as a secret in GitHub Actions settings:" | |
| echo " Repository Settings > Secrets and variables > Actions > New repository secret" | |
| echo " Name: SURGE_TOKEN" | |
| echo " Value: <your token from 'surge token' command>" | |
| echo "" | |
| exit 1 | |
| fi | |
| echo "✓ SURGE_TOKEN is set" | |
| - name: Deploy to Surge | |
| env: | |
| SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| export DEPLOY_DOMAIN="pr-${{ env.PR_NUMBER }}-sciam-preview.surge.sh" | |
| surge ./_site --domain "$DEPLOY_DOMAIN" --token "$SURGE_TOKEN" | |
| echo "DEPLOY_URL=https://$DEPLOY_DOMAIN" >> $GITHUB_ENV | |
| - name: Update PR comment with preview link | |
| if: success() | |
| uses: actions/github-script@v7 | |
| env: | |
| COMMENT_ID: ${{ steps.start_comment.outputs.comment_id }} | |
| PREVIEW_URL: ${{ env.DEPLOY_URL }} | |
| with: | |
| script: | | |
| const commentId = Number(process.env.COMMENT_ID); | |
| const previewUrl = process.env.PREVIEW_URL || 'unavailable'; | |
| const body = `🚀 **Preview deployed successfully!**\n\n🌐 Preview: [${previewUrl}](${previewUrl})`; | |
| await github.rest.issues.updateComment({ | |
| comment_id: commentId, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body | |
| }); | |
| - name: Update PR comment on failure | |
| if: failure() && steps.start_comment.outputs.comment_id | |
| uses: actions/github-script@v7 | |
| env: | |
| COMMENT_ID: ${{ steps.start_comment.outputs.comment_id }} | |
| with: | |
| script: | | |
| const commentId = Number(process.env.COMMENT_ID); | |
| const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; | |
| const body = `❌ **Preview build failed.**\n\n🔗 [View workflow run](${runUrl})`; | |
| await github.rest.issues.updateComment({ | |
| comment_id: commentId, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body | |
| }); |