diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..90d2854 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,71 @@ +name: CI + +# Static validation — no AWS credentials required. Gives a meaningful green check +# on every push/PR before any environment is configured. Deployment lives in deploy.yml. + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + terraform: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: hashicorp/setup-terraform@v3 + - name: fmt + run: terraform fmt -check -recursive iac/ + - name: validate static stack + working-directory: iac/spip/static + run: | + terraform init -backend=false -input=false + terraform validate + - name: validate app stack + working-directory: iac/spip/app + run: | + terraform init -backend=false -input=false + terraform validate + + php-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: '8.5' + - name: php -l on our PHP + run: | + find spip/overlay spip/scripts spip/plugins -name '*.php' -print0 \ + | xargs -0 -n1 -P4 php -l >/dev/null + echo "no syntax errors" + + shell-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: bash -n on scripts + run: for s in spip/scripts/*.sh; do bash -n "$s"; done + + docker-build: + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - name: Read pinned SPIP version + run: echo "SPIP_VERSION=$(cat spip/SPIP_VERSION)" >> "$GITHUB_ENV" + # Build without pushing. Fetches SPIP core, builds PHP extensions + the image. + # ADOT collector is downloaded at deploy time; stub it so the COPY resolves. + - name: Stub ADOT collector (real one is fetched at deploy time) + run: touch spip/overlay/adot-collector + - name: Build image (no push) + uses: docker/build-push-action@v6 + with: + context: . + file: spip/Dockerfile + platforms: linux/arm64 + push: false + build-args: | + SPIP_VERSION=${{ env.SPIP_VERSION }} + provenance: false diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 287aaa4..ca76aa9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,6 +32,9 @@ concurrency: jobs: deploy: runs-on: ubuntu-24.04-arm + # Skips (stays green) until the target GitHub Environment defines AWS_ACCOUNT_ID. + # See docs/environments.md for the required environment variables. + if: ${{ vars.AWS_ACCOUNT_ID != '' }} environment: ${{ github.event.inputs.environment || 'test' }} permissions: contents: read diff --git a/iac/spip/app/.terraform.lock.hcl b/iac/spip/app/.terraform.lock.hcl new file mode 100644 index 0000000..7d94455 --- /dev/null +++ b/iac/spip/app/.terraform.lock.hcl @@ -0,0 +1,26 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "6.63.0" + constraints = ">= 4.40.0, >= 6.47.0" + hashes = [ + "h1:dRlYHkc+r6fgzF57WC7Zjcmb6sF/6TTGDEgwGK+LAZY=", + "zh:005d56736afd17d963998c405cee6f434dbc23a415109f9435ff1542879ae611", + "zh:026ef126321a86ad7080b5d858e2527f96f5289678cbcd8856296e229c43339d", + "zh:06e0b58b2d1eddb5137fc86bee7ad2d07953c0bc3f57cccfc5ae0d2456068a3a", + "zh:07221735d61ababed84734e5ffcfc5bd59d01f29f029166ba5f2175895dceed1", + "zh:1a72db00583112bdb8c19b213a78a3f5de754fffc08f07e061f4e326289fab7d", + "zh:32968e74a53b03e97a084dc7050c22ef661fb5b3ea8a44f5a63e47bc45ad0e7c", + "zh:4b357dfe4b820e3e4acd2881cff8288b2186491e63416751f0d12692ba478ceb", + "zh:81e30884d7de686265e7d87bb92527e802878c65a378470ede2a1e9f4e40ccc9", + "zh:82e137297f6a5a08b9ce2138f7aabea245ad99495d9d9eff502f752d6ca90dbd", + "zh:8eb83b67099f0ea9df238a979dff933ff50ce06a2e3ff05a48556a10f10dd204", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:d0ba30886cbe41850fee689f51ef9088578f323cfd21817bb409951d43c465eb", + "zh:dd48e7089784454bc03d713e9057f5ca0ea1613bd402125054a51894957b7925", + "zh:f250fa81e54cf60fcb0e9c0fc4ac043f1ecc2ac24967f628b3609364fcab3d04", + "zh:f38fc09fc25a8d2cf89a4d4cd6a5ef7cb1aad72798dbdcad58b8876b6a551a54", + "zh:f7c7380fdf126e1901f2084588dbfd724c76cb131ccfa795a541219111103c06", + ] +} diff --git a/iac/spip/app/api-gateway.tf b/iac/spip/app/api-gateway.tf index 3aaa823..9b37178 100644 --- a/iac/spip/app/api-gateway.tf +++ b/iac/spip/app/api-gateway.tf @@ -74,7 +74,7 @@ resource "aws_cloudwatch_log_group" "apigw_access" { resource "aws_api_gateway_stage" "spip" { rest_api_id = aws_api_gateway_rest_api.spip.id deployment_id = aws_api_gateway_deployment.spip.id - stage_name = "live" + stage_name = local.stage_name xray_tracing_enabled = true diff --git a/iac/spip/app/cloudfront.tf b/iac/spip/app/cloudfront.tf index 701dd54..21d1e48 100644 --- a/iac/spip/app/cloudfront.tf +++ b/iac/spip/app/cloudfront.tf @@ -34,7 +34,7 @@ resource "aws_cloudfront_distribution" "spip" { origin { domain_name = "${aws_api_gateway_rest_api.spip.id}.execute-api.${var.aws_region}.amazonaws.com" origin_id = "apigw" - origin_path = "/${aws_api_gateway_stage.spip.stage_name}" + origin_path = "/${local.stage_name}" custom_origin_config { http_port = 80 https_port = 443 diff --git a/iac/spip/app/locals.tf b/iac/spip/app/locals.tf index 2a5d71a..fac8d63 100644 --- a/iac/spip/app/locals.tf +++ b/iac/spip/app/locals.tf @@ -19,6 +19,11 @@ locals { account_id = data.aws_caller_identity.current.account_id region = var.aws_region + # Constant (not derived from the stage resource) so CloudFront's origin_path can use + # it without depending on the stage → deployment → integration → lambda chain, which + # would form a cycle with the Lambda env var CF_DISTRIBUTION_ID. + stage_name = "live" + dsql_endpoint = data.terraform_remote_state.static.outputs.dsql_endpoint dsql_arn = data.terraform_remote_state.static.outputs.dsql_arn s3_bucket = data.terraform_remote_state.static.outputs.s3_assets_bucket