Fix orphaned HTML files not being deleted from S3 on deploy #73
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: Deploy to AWS | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'app/**' | |
| - 'components/**' | |
| - 'public/**' | |
| - 'content/**' | |
| - 'lib/**' | |
| - 'scripts/**' | |
| - 'package.json' | |
| - 'next.config.ts' | |
| - 'tailwind.config.ts' | |
| - '.github/workflows/deploy.yml' | |
| workflow_dispatch: # Allow manual triggering | |
| permissions: | |
| id-token: write # Required for OIDC | |
| contents: read | |
| env: | |
| AWS_REGION: us-east-1 | |
| jobs: | |
| deploy: | |
| name: Build and deploy Next.js website | |
| runs-on: ubuntu-latest | |
| env: | |
| S3_BUCKET: ${{ secrets.S3_BUCKET }} | |
| IMAGES_BUCKET: ${{ secrets.IMAGES_BUCKET }} | |
| CLOUDFRONT_DISTRIBUTION_ID: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build Next.js app | |
| run: npm run build | |
| env: | |
| NEXT_PUBLIC_FATHOM_SITE_ID: ${{ secrets.NEXT_PUBLIC_FATHOM_SITE_ID }} | |
| NEXT_PUBLIC_NEWSLETTER_API_URL: ${{ secrets.NEXT_PUBLIC_NEWSLETTER_API_URL }} | |
| - name: Configure AWS credentials using OIDC | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Sync static files to S3 | |
| run: | | |
| # Sync static assets with long cache (JS, CSS, images) | |
| aws s3 sync out/ s3://${{ env.S3_BUCKET }}/ \ | |
| --delete \ | |
| --cache-control "public, max-age=31536000, immutable" \ | |
| --exclude "*.html" \ | |
| --exclude "*.json" \ | |
| --exclude "*.txt" | |
| # Sync HTML, JSON, and txt files with no cache (for dynamic content) | |
| # --delete removes orphaned files (e.g. posts set to draft) that are no longer in the build | |
| aws s3 sync out/ s3://${{ env.S3_BUCKET }}/ \ | |
| --delete \ | |
| --cache-control "public, max-age=0, must-revalidate" \ | |
| --exclude "*" \ | |
| --include "*.html" \ | |
| --include "*.json" \ | |
| --include "*.txt" | |
| - name: Invalidate CloudFront cache | |
| run: | | |
| aws cloudfront create-invalidation \ | |
| --distribution-id ${{ env.CLOUDFRONT_DISTRIBUTION_ID }} \ | |
| --paths "/*" | |
| - name: Deployment summary | |
| run: | | |
| echo "✅ Next.js app built successfully" | |
| echo "✅ Files synced to S3 bucket: ${{ env.S3_BUCKET }}" | |
| echo "✅ CloudFront cache invalidated" | |
| echo "🌐 CloudFront Distribution: ${{ env.CLOUDFRONT_DISTRIBUTION_ID }}" | |
| echo "ℹ️ Images are managed locally and uploaded to S3 separately" |