Merge pull request #235 from Sea-Haven-Industries/chore/drop-pointer-cd-leftovers

chore(cd): drop leftover pointer-cd scripts and cutover docs
This commit is contained in:
Adam Moussa 2026-09-18 17:25:35 -04:00 • committed by GitHub
commit 148f5f1823
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
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
(`terraform/README.md`). G13 fails a diff that contains both `terraform/`
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
stays: `deploy-web.yaml` ignores `terraform/**`, and app-only tags skip HCP
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
(`deploy-web.yaml`). HCP Terraform owns the bucket and CloudFront. A change set
that includes both `terraform/` and deployable application files (`src/`,
`public/`, `pages/`, `config/`, `index.html`, Vite/tsconfig, `.env*`, or
`scripts/deploy-web.sh`) fails G13. Workflow, docs, and gate-script changes may
travel with either side.
`public/`, `pages/`, `config/`, `index.html`, Vite/tsconfig, or `.env*`)
fails G13. Workflow, docs, and gate-script changes may travel with either
side.

View file

@ -9,10 +9,6 @@ from __future__ import annotations
import argparse
import sys
APP_SCRIPT_NAMES = {
"scripts/deploy-web.sh",
}
APP_ROOTS = (
"src/",
"public/",
@ -33,7 +29,7 @@ def is_terraform_path(path: str) -> bool:
def is_app_path(path: str) -> bool:
normalized = path.replace("\\", "/")
if normalized in APP_SCRIPT_NAMES or normalized in APP_FILES:
if normalized in APP_FILES:
return True
if normalized in {"src", "public", "pages", "config"}:
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",
"public/favicon.ico",
"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
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
retargets two live HCP working directories and is its own change.
Do not collapse these roots into one `terraform/` tree. Flattening retargets
two live HCP working directories and is its own change.
## 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
create an HCP run or touch AWS.
## Cutover (greenlight only)
## Workspaces
1. Keep HCP working directories `terraform/live/dev` and
`terraform/live/staging`. Dev VCS branch `main`. Staging tag regex
`^v[0-9]+\.[0-9]+\.[0-9]+-staging$`.
2. Auto-apply off. Apply the origin-path move for **dev** before any
`--delete` root sync.
3. Create GitHub Environment `dev` (staging already exists). Set
`DEPLOY_ROLE_ARN` on each.
4. Enable `deploy-web.yaml`. Then delete leftover `deploy.yml` /
`deploy-staging.yml` and repo `TF_API_TOKEN`, `TERRAFORM_CONTENT_CD_ENABLED`,
and `AWS_DEPLOY_ROLE_ARN`.
Dev (`shoc-frontend-new-dev`) watches `main` with working directory
`terraform/live/dev` and auto-apply on. Staging (`shoc-frontend-new-staging`)
watches tag regex `^v[0-9]+\.[0-9]+\.[0-9]+-staging$` with working directory
`terraform/live/staging` and auto-apply on. Merges to `main` do not apply
staging.
GitHub Environments `dev` and `staging` set `DEPLOY_ROLE_ARN` and allow `main`
plus tag `v*`. Promote staging with `gh release create vX.Y.Z-staging --target
main`.