From fe4bbc95fbcb2c816fe3ffcf9c1baded87c2b35b Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Sat, 26 Sep 2026 16:49:44 -0400 Subject: [PATCH] fix(cd): name the missing deploy prerequisites --- .github/workflows/deploy-api.yaml | 22 +++++++++++++++++++++- .github/workflows/deploy-web.yaml | 27 +++++++++++++++++++++++++-- README.md | 2 ++ scripts/test-terraform-dev-only.py | 3 +++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-api.yaml b/.github/workflows/deploy-api.yaml index 0761dcc..6393492 100644 --- a/.github/workflows/deploy-api.yaml +++ b/.github/workflows/deploy-api.yaml @@ -131,6 +131,14 @@ jobs: echo "sha=${sha}" >> "${GITHUB_OUTPUT}" echo "Building ${sha}" + - name: Require deploy role + run: | + set -euo pipefail + if [ -z "${DEPLOY_ROLE_ARN}" ]; then + echo "DEPLOY_ROLE_ARN is empty. Create GitHub Environment dev and set it after the seahaven-ap-dev apply, then re-run." >&2 + exit 1 + fi + - name: Configure AWS credentials using OIDC uses: aws-actions/configure-aws-credentials@e1253824e5c10ff9df46874f81ed3ec929e19cfd # v6.3.0 with: @@ -143,7 +151,19 @@ jobs: run: | set -euo pipefail get_param() { - aws ssm get-parameter --name "$1" --query Parameter.Value --output text + local name="$1" err value + err="$(mktemp)" + if ! value="$(aws ssm get-parameter --name "${name}" --query Parameter.Value --output text 2>"${err}")"; then + if grep -q ParameterNotFound "${err}"; then + echo "SSM parameter ${name} does not exist yet. Apply the seahaven-ap-dev workspace, then re-run this workflow." >&2 + else + cat "${err}" >&2 + fi + rm -f "${err}" + exit 1 + fi + rm -f "${err}" + printf '%s\n' "${value}" } CLUSTER=$(get_param /seahaven-ap/deploy/cluster) SERVICE=$(get_param /seahaven-ap/deploy/service) diff --git a/.github/workflows/deploy-web.yaml b/.github/workflows/deploy-web.yaml index 3e2ea96..a496646 100644 --- a/.github/workflows/deploy-web.yaml +++ b/.github/workflows/deploy-web.yaml @@ -124,6 +124,14 @@ jobs: echo "Deploying ${sha}" test -f placeholder/index.html + - name: Require deploy role + run: | + set -euo pipefail + if [ -z "${DEPLOY_ROLE_ARN}" ]; then + echo "DEPLOY_ROLE_ARN is empty. Create GitHub Environment dev and set it after the seahaven-ap-dev apply, then re-run." >&2 + exit 1 + fi + - name: Configure AWS credentials using OIDC uses: aws-actions/configure-aws-credentials@e1253824e5c10ff9df46874f81ed3ec929e19cfd # v6.3.0 with: @@ -135,8 +143,23 @@ jobs: id: deploy run: | set -euo pipefail - BUCKET=$(aws ssm get-parameter --name /seahaven-ap/deploy/bucket --query Parameter.Value --output text) - DIST_ID=$(aws ssm get-parameter --name /seahaven-ap/deploy/distribution-id --query Parameter.Value --output text) + get_param() { + local name="$1" err value + err="$(mktemp)" + if ! value="$(aws ssm get-parameter --name "${name}" --query Parameter.Value --output text 2>"${err}")"; then + if grep -q ParameterNotFound "${err}"; then + echo "SSM parameter ${name} does not exist yet. Apply the seahaven-ap-dev workspace, then re-run this workflow." >&2 + else + cat "${err}" >&2 + fi + rm -f "${err}" + exit 1 + fi + rm -f "${err}" + printf '%s\n' "${value}" + } + BUCKET=$(get_param /seahaven-ap/deploy/bucket) + DIST_ID=$(get_param /seahaven-ap/deploy/distribution-id) DOMAIN=$(aws cloudfront get-distribution --id "${DIST_ID}" --query Distribution.DomainName --output text) { echo "bucket=${BUCKET}" diff --git a/README.md b/README.md index 9b8c731..a7b2f3a 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ HCP Terraform workspace `seahaven-ap-dev` (project `seahaven-dev`) uses working The first apply creates secret `seahaven-ap/google-oidc` with `client_id` and `client_secret` set to `replace-me`. Replace both values in Secrets Manager, then re-run the HCP apply. A `terraform/**` change on `main` starts that apply. The Google IdP is not registered while the placeholder is still current. +The merge that adds these workflows can start Deploy Web and Deploy API before that apply has written `/seahaven-ap/deploy/*` and before GitHub Environment `dev` has `DEPLOY_ROLE_ARN`. Those runs fail on purpose until both exist. Re-run them after the apply. + - `.github/workflows/deploy-web.yaml` syncs `placeholder/` to the web bucket. It does not run `vite build`. - `.github/workflows/deploy-api.yaml` builds the API image with `GIT_SHA`, registers the task definition from `/seahaven-ap/deploy/task-environment`, migrates, and checks `GET /api/health`. diff --git a/scripts/test-terraform-dev-only.py b/scripts/test-terraform-dev-only.py index 0e64cc2..92d8957 100755 --- a/scripts/test-terraform-dev-only.py +++ b/scripts/test-terraform-dev-only.py @@ -54,6 +54,7 @@ def test_no_hcp_iam_and_no_prod(): assert 'local.google_oidc_client_secret != "replace-me"' in cognito readme = (ROOT / "README.md").read_text() assert "Replace both values in Secrets Manager, then re-run the HCP apply." in readme + assert "Those runs fail on purpose until both exist." in readme secrets = (tf_dir / "secrets.tf").read_text() assert 'resource "aws_secretsmanager_secret_version" "google_oidc"' in secrets assert "ignore_changes = [secret_string]" in secrets @@ -74,6 +75,8 @@ def test_deploy_workflows_are_dev_only(): assert "environment:prod" not in text assert "cancel-in-progress: false" in text assert "environment: ${{ needs.target.outputs.environment }}" in text + assert "DEPLOY_ROLE_ARN is empty" in text + assert "does not exist yet. Apply the seahaven-ap-dev workspace" in text web = (ROOT / ".github" / "workflows" / "deploy-web.yaml").read_text() assert "vite build" not in web assert "placeholder/" in web