#!/usr/bin/env bash # # Post-deploy step for the org reusable workflow `cd-cdk.yaml` # (wired in via `.github/workflows/deploy.yml` -> `post-deploy-script`). # # Runs AFTER `cdk deploy` has provisioned/updated the infra, as the GitHub # OIDC deploy role. Builds the SPA, uploads it to the stack's S3 bucket with # the right cache headers, and invalidates CloudFront. # # Runs from the repo root. Reads the bucket + distribution from stack outputs, # so it has no hardcoded resource IDs. set -euo pipefail STACK_NAME="${STACK_NAME:-shoc-frontend-dev}" REGION="${AWS_REGION:-us-east-1}" echo "Building SPA (VITE_API_URL comes from .env.production)..." npm ci npm run build echo "Reading stack outputs from ${STACK_NAME}..." stack_output() { aws cloudformation describe-stacks \ --stack-name "${STACK_NAME}" \ --region "${REGION}" \ --query "Stacks[0].Outputs[?OutputKey=='$1'].OutputValue" \ --output text } BUCKET="$(stack_output BucketName)" DIST_ID="$(stack_output DistributionId)" if [[ -z "${BUCKET}" || "${BUCKET}" == "None" || -z "${DIST_ID}" || "${DIST_ID}" == "None" ]]; then echo "::error::Could not resolve BucketName/DistributionId from stack ${STACK_NAME}." >&2 exit 1 fi echo "Uploading hashed assets (immutable) to s3://${BUCKET}..." # Everything except index.html: long-lived + immutable, prune stale objects. aws s3 sync dist/ "s3://${BUCKET}/" \ --delete \ --exclude "index.html" \ --cache-control "public,max-age=31536000,immutable" echo "Uploading index.html (never cached)..." aws s3 cp dist/index.html "s3://${BUCKET}/index.html" \ --cache-control "no-cache,no-store,must-revalidate" \ --content-type "text/html" echo "Invalidating CloudFront ${DIST_ID}..." aws cloudfront create-invalidation \ --distribution-id "${DIST_ID}" \ --paths "/*" echo "Web deploy complete."