chore(cd): drop leftover pointer-cd scripts and cutover docs

GitHub Actions already owns SPA bytes, so the unused pointer scripts
and the stale greenlight checklist should not stay in tree.
This commit is contained in:
Adam Moussa 2026-09-18 17:13:32 -04:00
parent 2600234b89
commit 0c867e2cb4
No known key found for this signature in database
7 changed files with 18 additions and 132 deletions

View file

@ -51,7 +51,7 @@ isolation). A task is not done until this is green.
are migration evidence reviewed by a human before an approved apply are migration evidence reviewed by a human before an approved apply
(`terraform/README.md`). G13 fails a diff that contains both `terraform/` (`terraform/README.md`). G13 fails a diff that contains both `terraform/`
and deployable application files (`src/`, `public/`, `pages/`, `config/`, and deployable application files (`src/`, `public/`, `pages/`, `config/`,
`index.html`, Vite/tsconfig, `.env*`, or `scripts/deploy-web.sh`). Workflow, `index.html`, Vite/tsconfig, or `.env*`). Workflow,
docs, and gate-script changes may travel with either side. Runtime isolation docs, and gate-script changes may travel with either side. Runtime isolation
stays: `deploy-web.yaml` ignores `terraform/**`, and app-only tags skip HCP stays: `deploy-web.yaml` ignores `terraform/**`, and app-only tags skip HCP
when workspace trigger patterns miss. when workspace trigger patterns miss.

View file

@ -87,6 +87,6 @@ surface; keep comments inline and high-signal.
Infra and application **PRs** stay separate. GitHub Actions owns SPA content Infra and application **PRs** stay separate. GitHub Actions owns SPA content
(`deploy-web.yaml`). HCP Terraform owns the bucket and CloudFront. A change set (`deploy-web.yaml`). HCP Terraform owns the bucket and CloudFront. A change set
that includes both `terraform/` and deployable application files (`src/`, that includes both `terraform/` and deployable application files (`src/`,
`public/`, `pages/`, `config/`, `index.html`, Vite/tsconfig, `.env*`, or `public/`, `pages/`, `config/`, `index.html`, Vite/tsconfig, or `.env*`)
`scripts/deploy-web.sh`) fails G13. Workflow, docs, and gate-script changes may fails G13. Workflow, docs, and gate-script changes may travel with either
travel with either side. side.

View file

@ -9,10 +9,6 @@ from __future__ import annotations
import argparse import argparse
import sys import sys
APP_SCRIPT_NAMES = {
"scripts/deploy-web.sh",
}
APP_ROOTS = ( APP_ROOTS = (
"src/", "src/",
"public/", "public/",
@ -33,7 +29,7 @@ def is_terraform_path(path: str) -> bool:
def is_app_path(path: str) -> bool: def is_app_path(path: str) -> bool:
normalized = path.replace("\\", "/") normalized = path.replace("\\", "/")
if normalized in APP_SCRIPT_NAMES or normalized in APP_FILES: if normalized in APP_FILES:
return True return True
if normalized in {"src", "public", "pages", "config"}: if normalized in {"src", "public", "pages", "config"}:
return True return True

View file

@ -1,79 +0,0 @@
#!/usr/bin/env bash
#
# Content publish step for the environment deploy workflows
# (`.github/workflows/deploy.yml`, `.github/workflows/deploy-staging.yml`).
#
# Runs as the GitHub OIDC deploy role. Builds the SPA, uploads it to the
# environment's S3 bucket with the right cache headers, and invalidates
# CloudFront. It never touches infrastructure.
#
# Runs from the repo root. The target is resolved from, in order:
# 1. SITE_BUCKET + CLOUDFRONT_DISTRIBUTION_ID (pinned by the workflow; used by
# dev, whose CloudFormation outputs disappear during Terraform adoption)
# 2. the BucketName/DistributionId outputs of STACK_NAME (staging)
set -euo pipefail
STACK_NAME="${STACK_NAME:-shoc-frontend-dev}"
REGION="${AWS_REGION:-us-east-1}"
WAIT_FOR_INVALIDATION="${WAIT_FOR_INVALIDATION:-false}"
echo "Building SPA (VITE_API_URL comes from the process environment or .env.production)..."
export VITE_APP_COMMIT_SHA="${VITE_APP_COMMIT_SHA:-${GITHUB_SHA:-}}"
npm ci
npm run build
BUCKET="${SITE_BUCKET:-}"
DIST_ID="${CLOUDFRONT_DISTRIBUTION_ID:-}"
if [[ -n "${BUCKET}" && -n "${DIST_ID}" ]]; then
echo "Using pinned target: bucket ${BUCKET}, distribution ${DIST_ID}."
elif [[ -n "${BUCKET}" || -n "${DIST_ID}" ]]; then
echo "::error::Set both SITE_BUCKET and CLOUDFRONT_DISTRIBUTION_ID, or neither." >&2
exit 1
else
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
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" \
--exclude "*.map" \
--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}..."
INVALIDATION_ID="$(aws cloudfront create-invalidation \
--distribution-id "${DIST_ID}" \
--paths "/*" \
--query 'Invalidation.Id' \
--output text)"
if [[ "${WAIT_FOR_INVALIDATION}" == "true" ]]; then
echo "Waiting for CloudFront invalidation ${INVALIDATION_ID}..."
aws cloudfront wait invalidation-completed \
--distribution-id "${DIST_ID}" \
--id "${INVALIDATION_ID}"
fi
echo "Web deploy complete."

View file

@ -1,29 +0,0 @@
#!/usr/bin/env python3
"""Read .release/current JSON from stdin and write GitHub Actions outputs."""
from __future__ import annotations
import json
import os
import sys
def main() -> int:
raw = sys.stdin.read().strip()
data = json.loads(raw) if raw else {}
current = data.get("current") or ""
previous = data.get("previous") or ""
output_path = os.environ["GITHUB_OUTPUT"]
with open(output_path, "a", encoding="utf-8") as handle:
handle.write(f"live_current={current}\n")
handle.write(f"live_previous={previous}\n")
print(
"Pointer live current="
+ (current or "<empty>")
+ " previous="
+ (previous or "<empty>")
)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -26,7 +26,6 @@ class IsolationTests(unittest.TestCase):
"src/app/routes.tsx", "src/app/routes.tsx",
"public/favicon.ico", "public/favicon.ico",
"index.html", "index.html",
"scripts/deploy-web.sh",
] ]
) )
) )

View file

@ -7,10 +7,10 @@ to the bucket root and invalidates `/*`.
Creating, formatting, initializing with `-backend=false`, and validating these Creating, formatting, initializing with `-backend=false`, and validating these
files does not authorize an AWS, HCP Terraform, GitHub, or deployment files does not authorize an AWS, HCP Terraform, GitHub, or deployment
mutation. Live cutover waits for an explicit greenlight. mutation.
Do not collapse these roots into one `terraform/` tree in this PR. Flattening Do not collapse these roots into one `terraform/` tree. Flattening retargets
retargets two live HCP working directories and is its own change. two live HCP working directories and is its own change.
## Fixed targets ## Fixed targets
@ -61,15 +61,14 @@ and gate-script changes may travel with either side. G13 is
`npm run test:terraform` and `npm run verify` wrap the same gates. They never `npm run test:terraform` and `npm run verify` wrap the same gates. They never
create an HCP run or touch AWS. create an HCP run or touch AWS.
## Cutover (greenlight only) ## Workspaces
1. Keep HCP working directories `terraform/live/dev` and Dev (`shoc-frontend-new-dev`) watches `main` with working directory
`terraform/live/staging`. Dev VCS branch `main`. Staging tag regex `terraform/live/dev` and auto-apply on. Staging (`shoc-frontend-new-staging`)
`^v[0-9]+\.[0-9]+\.[0-9]+-staging$`. watches tag regex `^v[0-9]+\.[0-9]+\.[0-9]+-staging$` with working directory
2. Auto-apply off. Apply the origin-path move for **dev** before any `terraform/live/staging` and auto-apply on. Merges to `main` do not apply
`--delete` root sync. staging.
3. Create GitHub Environment `dev` (staging already exists). Set
`DEPLOY_ROLE_ARN` on each. GitHub Environments `dev` and `staging` set `DEPLOY_ROLE_ARN` and allow `main`
4. Enable `deploy-web.yaml`. Then delete leftover `deploy.yml` / plus tag `v*`. Promote staging with `gh release create vX.Y.Z-staging --target
`deploy-staging.yml` and repo `TF_API_TOKEN`, `TERRAFORM_CONTENT_CD_ENABLED`, main`.
and `AWS_DEPLOY_ROLE_ARN`.