mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Log GITHUB_SHA on /health; move zip-size gate to its own PR workflow
/health already returned GITHUB_SHA in its response but never logged it, and the fastapi lambda's Terraform environment never actually set GITHUB_SHA — so every health check response contained "unknown" in production. Wire var.github_sha through the fastapi lambda module (default "unknown" for local/other invocations) via a new TF_VAR_github_sha env var set from `github.sha` in _deploy_lambda.yml's Terraform Plan step, and log it on every /health call so a request in CloudWatch can be tied back to the deploy that served it. Also fix the zip-size gate added for PR #1469: putting it in tests/test_lambda_zip_size.py (run via the Docker-based ddd_tests.yml suite) broke CI, because Dockerfile.test's build context excludes deployment/* (.dockerignore), so check_lambda_zip_size.py couldn't find variables.tf to read zip_excludes from inside that container. Move the check to its own lightweight workflow, check_lambda_zip_size.yml, triggered on pull_request into main — a plain checkout (no Docker build) has the full repo, so the check works, runs fast, and still gates merges to main before a regression can roll into the dev deploy. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e816972c45
commit
adb1bf4b56
6 changed files with 40 additions and 49 deletions
1
.github/workflows/_deploy_lambda.yml
vendored
1
.github/workflows/_deploy_lambda.yml
vendored
|
|
@ -148,6 +148,7 @@ jobs:
|
|||
- name: Terraform Plan
|
||||
working-directory: ${{ inputs.lambda_path }}
|
||||
env:
|
||||
TF_VAR_github_sha: ${{ github.sha }}
|
||||
TF_VAR_db_host: ${{ secrets.TF_VAR_db_host }}
|
||||
TF_VAR_db_name: ${{ secrets.TF_VAR_db_name }}
|
||||
TF_VAR_db_port: ${{ secrets.TF_VAR_db_port }}
|
||||
|
|
|
|||
23
.github/workflows/check_lambda_zip_size.yml
vendored
Normal file
23
.github/workflows/check_lambda_zip_size.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: Check FastAPI Lambda package size
|
||||
|
||||
# Runs on PRs targeting main so a Lambda-size regression fails the PR before
|
||||
# it can merge to main and roll into the dev deploy — deploy_terraform.yml
|
||||
# only triggers on push to dev/prod, which is too late (see PR #1469: this
|
||||
# broke dev for weeks before anyone noticed).
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
fast_api_lambda_zip_size_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Check projected unzipped Lambda size
|
||||
run: python3 backend/app/requirements/check_lambda_zip_size.py
|
||||
|
|
@ -53,7 +53,9 @@ async def log_requests(request: Request, call_next):
|
|||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "ok", "sha": os.getenv("GITHUB_SHA", "unknown")}
|
||||
sha = os.getenv("GITHUB_SHA", "unknown")
|
||||
logger.info(f"Health check OK - deployed sha={sha}")
|
||||
return {"status": "ok", "sha": sha}
|
||||
|
||||
|
||||
app.include_router(tasks_router.router, prefix="/v1")
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ module "fastapi" {
|
|||
|
||||
environment = {
|
||||
ENVIRONMENT = var.stage
|
||||
GITHUB_SHA = var.github_sha
|
||||
API_KEY = var.api_key
|
||||
SECRET_KEY = var.secret_key
|
||||
# DOMAIN_NAME = var.domain_name
|
||||
|
|
@ -110,11 +111,11 @@ module "fastapi" {
|
|||
CARBON_BASELINE_PREDICTIONS_BUCKET = data.terraform_remote_state.shared.outputs.retrofit_carbon_baseline_predictions_bucket_name
|
||||
HEAT_BASELINE_PREDICTIONS_BUCKET = data.terraform_remote_state.shared.outputs.retrofit_heat_baseline_predictions_bucket_name
|
||||
|
||||
ENGINE_SQS_URL = data.terraform_remote_state.engine.outputs.ara_engine_queue_url
|
||||
CATEGORISATION_SQS_URL = data.terraform_remote_state.categorisation.outputs.categorisation_queue_url
|
||||
POSTCODE_SPLITTER_SQS_URL = data.terraform_remote_state.postcode_splitter.outputs.postcode_splitter_queue_url
|
||||
COMBINER_SQS_URL = data.terraform_remote_state.bulk_address2uprn_combiner.outputs.bulk_address2uprn_combiner_queue_url
|
||||
FINALISER_SQS_URL = data.terraform_remote_state.bulk_upload_finaliser.outputs.bulk_upload_finaliser_queue_url
|
||||
ENGINE_SQS_URL = data.terraform_remote_state.engine.outputs.ara_engine_queue_url
|
||||
CATEGORISATION_SQS_URL = data.terraform_remote_state.categorisation.outputs.categorisation_queue_url
|
||||
POSTCODE_SPLITTER_SQS_URL = data.terraform_remote_state.postcode_splitter.outputs.postcode_splitter_queue_url
|
||||
COMBINER_SQS_URL = data.terraform_remote_state.bulk_address2uprn_combiner.outputs.bulk_address2uprn_combiner_queue_url
|
||||
FINALISER_SQS_URL = data.terraform_remote_state.bulk_upload_finaliser.outputs.bulk_upload_finaliser_queue_url
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,4 +41,10 @@ variable "epc_auth_token" {
|
|||
variable "google_solar_api_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
}
|
||||
|
||||
variable "github_sha" {
|
||||
type = string
|
||||
description = "Commit SHA being deployed, surfaced via /health so cloud logs can be tied back to a deploy."
|
||||
default = "unknown"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
"""Guard against the fastapi Lambda's unzipped package exceeding AWS's
|
||||
262144000 byte (250 MiB) limit.
|
||||
|
||||
dev deployed with `InvalidParameterValueException: Unzipped size must be
|
||||
smaller than 262144000 bytes` for several weeks (2026-06-15 to 2026-07-03)
|
||||
before anyone noticed, because the failure only ever surfaced deep inside
|
||||
`terraform apply` on a push to dev/prod — well after a PR to main had merged.
|
||||
This runs the same check as part of the PR-gated test suite so a regression
|
||||
(e.g. a large fixture or dependency landing outside the Lambda's zip_excludes)
|
||||
fails the PR instead of the dev deploy.
|
||||
|
||||
Runs the real `check_lambda_zip_size.py` script as a subprocess (not an
|
||||
in-process import) so this exercises exactly what a human or CI would run
|
||||
locally: `python3 backend/app/requirements/check_lambda_zip_size.py`.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
CHECK_SCRIPT = REPO_ROOT / "backend/app/requirements/check_lambda_zip_size.py"
|
||||
|
||||
|
||||
def test_fastapi_lambda_unzipped_size_within_aws_limit() -> None:
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(CHECK_SCRIPT)],
|
||||
cwd=REPO_ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
print(result.stdout)
|
||||
assert result.returncode == 0, (
|
||||
"fastapi Lambda's projected unzipped size exceeds (or is dangerously "
|
||||
"close to) AWS's 250 MiB limit — see output above. If this is a real "
|
||||
"new dependency/fixture, either trim it or extend `zip_excludes` in "
|
||||
"deployment/terraform/modules/lambda_with_api_gateway/variables.tf "
|
||||
"(only if it's not needed by the Lambda at runtime).\n"
|
||||
+ result.stdout
|
||||
+ result.stderr
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue