name: "Docs: Deploy Preview" on: pull_request_target: types: [opened, reopened, synchronize] paths: - 'site/**' - '.github/workflows/docs-*' concurrency: group: preview-cms-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: authorization-check: name: Authorization Check permissions: read-all runs-on: ubuntu-latest outputs: approval-env: ${{ steps.auth.outputs.approval-env }} steps: - name: Check Authorization id: auth uses: strands-agents/devtools/authorization-check@main with: username: ${{ github.event.pull_request.user.login }} allowed-roles: 'write,maintain,admin' build-and-deploy: name: Build and Deploy Preview runs-on: ubuntu-latest needs: authorization-check environment: ${{ needs.authorization-check.outputs.approval-env }} permissions: contents: read issues: write pull-requests: write id-token: write # For OIDC authentication env: # PR metadata PR_NUMBER: ${{ github.event.pull_request.number }} PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} RUN_ID: ${{ github.run_id }} # Secrets AWS_DEPLOY_ROLE: ${{ secrets.STRANDS_DOCS_DEPLOY_ROLE }} S3_BUCKET: ${{ secrets.STRANDS_DOCS_BUCKET }} CLOUDFRONT_DISTRIBUTION_ID: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} CLOUDFRONT_DOMAIN: ${{ secrets.CLOUDFRONT_DOMAIN }} # Derived paths (defined once, used everywhere) BUILD_OUTPUT_DIR: site/dist S3_PATH: pr-cms-${{ github.event.pull_request.number }} PREVIEW_URL: https://${{ secrets.CLOUDFRONT_DOMAIN }}/pr-cms-${{ github.event.pull_request.number }}/docs/user-guide/quickstart/overview/ RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} defaults: run: working-directory: site steps: - name: Checkout head commit uses: actions/checkout@v6 with: ref: ${{ env.PR_HEAD_SHA }} persist-credentials: false - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: '22' - name: Install dependencies run: npm ci - name: Build CMS env: ASTRO_BASE_PATH: /${{ env.S3_PATH }}/ run: npm run cms:build - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: role-to-assume: ${{ env.AWS_DEPLOY_ROLE }} role-session-name: GitHubActions-Docs-${{ env.RUN_ID }} aws-region: us-east-1 mask-aws-account-id: true - name: Deploy to S3 working-directory: . run: | aws s3 sync ${{ env.BUILD_OUTPUT_DIR }}/ s3://${{ env.S3_BUCKET }}/${{ env.S3_PATH }}/ \ --cache-control "public, max-age=3600" - name: Invalidate CloudFront cache for PR preview working-directory: . run: | aws cloudfront create-invalidation \ --distribution-id ${{ env.CLOUDFRONT_DISTRIBUTION_ID }} \ --invalidation-batch '{"Paths":{"Quantity":1,"Items":["/${{ env.S3_PATH }}/*"]},"CallerReference":"'$(date +%s)'"}' - name: Output deployment info run: | echo "Deployment complete!" echo "Deployed to: ${{ env.PREVIEW_URL }}" echo "This is a preview deployment for PR #${{ env.PR_NUMBER }}" - name: Comment on PR (success) if: success() uses: actions/github-script@v8 with: script: | const prNumber = context.payload.pull_request.number; const previewUrl = '${{ env.PREVIEW_URL }}'; // Find existing bot comment const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, }); const botComment = comments.data.find(comment => comment.user.type === 'Bot' && comment.body.includes('Documentation Preview') ); const body = [ '## Documentation Preview Ready', '', 'Your documentation preview has been successfully deployed!', '', `**Preview URL**: ${previewUrl}`, '', `_Updated at: ${new Date().toISOString()}_` ].join('\n'); if (botComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: botComment.id, body: body }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: body }); } - name: Comment on PR (failure) if: failure() uses: actions/github-script@v8 with: script: | const prNumber = context.payload.pull_request.number; const runUrl = '${{ env.RUN_URL }}'; const body = [ '## Documentation Preview Failed', '', `The documentation deployment encountered an error. Please check the [deployment logs](${runUrl}) for more details.` ].join('\n'); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: body });