From e67ab1bdaae6dc69a10922bca19b0bf4bfc0defa Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Thu, 12 Mar 2026 13:44:56 -0700 Subject: [PATCH 1/7] Add healthchecks. Document github flow. Streamline CI. --- healthcheck.sh | 2 ++ 1 file changed, 2 insertions(+) create mode 100755 healthcheck.sh diff --git a/healthcheck.sh b/healthcheck.sh new file mode 100755 index 0000000..b47e6a6 --- /dev/null +++ b/healthcheck.sh @@ -0,0 +1,2 @@ +#!/bin/sh +curl -sf "http://localhost:${APP_PORT:-8000}/api/ping" > /dev/null From 3e3d8920a93832efc355aeeab7e7d82867d540f9 Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Thu, 12 Mar 2026 15:07:21 -0700 Subject: [PATCH 2/7] Rewrite healthcheck to remove dependency on curl. --- healthcheck.sh | 2 -- 1 file changed, 2 deletions(-) delete mode 100755 healthcheck.sh diff --git a/healthcheck.sh b/healthcheck.sh deleted file mode 100755 index b47e6a6..0000000 --- a/healthcheck.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -curl -sf "http://localhost:${APP_PORT:-8000}/api/ping" > /dev/null From 3d99cfd49c550b6cd0dbc23328853a2d25374503 Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Fri, 13 Mar 2026 10:26:55 -0700 Subject: [PATCH 3/7] Migrate from Github Actions to AWS Build. --- .github/workflows/code-analysis.yml | 47 -------------- README.md | 39 +++++++++++- buildspec.yml | 25 ++++++++ deployment/config/dev/codebuild.yaml | 5 ++ deployment/templates/codebuild.yaml.j2 | 86 ++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 48 deletions(-) delete mode 100644 .github/workflows/code-analysis.yml create mode 100644 buildspec.yml create mode 100644 deployment/config/dev/codebuild.yaml create mode 100644 deployment/templates/codebuild.yaml.j2 diff --git a/.github/workflows/code-analysis.yml b/.github/workflows/code-analysis.yml deleted file mode 100644 index 42ac01b..0000000 --- a/.github/workflows/code-analysis.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Code Analysis - -permissions: - contents: read - -on: - pull_request: - -jobs: - CodeAnalysis: - runs-on: ubuntu-24.04 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v5 - - - name: Display Python version - run: | - uv run python --version - - - name: Install dependencies - run: | - uv sync --frozen - - - name: Check for outdated dependencies - run: | - uv tree --outdated - - - name: Run tests with coverage in latest stable 3.x - run: | - uv run pytest --cov=app --cov-report=term-missing - - - name: Run Bandit for security analysis - run: | - uv run bandit -r app - - - name: Run Ruff for linting - run: | - uv run ruff check . - - - name: Run Vulture for dead code analysis - run: | - uv run vulture . --min-confidence 70 --exclude .venv - diff --git a/README.md b/README.md index c3eb62c..dc60e23 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,44 @@ The app resolves the database connection from environment variables in priority | `DATABASE_CREDENTIALS_SECRET_NAME` + AWS vars | Pull credentials from AWS Secrets Manager | | `DB_USERNAME` + `DB_PASSWORD` + `DB_HOST` + `DB_DATABASE` | Individual credential env vars | ---- +## CI (Continuous Integration) + +CI runs on AWS CodeBuild in the `cdl-d2d-dev` account. Every pull request triggers a build that runs tests, linting, and security checks, and reports a check status with a link to the build log back to GitHub. + +The job configuration lives in [`buildspec.yml`](buildspec.yml). + +### First-time setup + +The CodeBuild infrastructure is managed by Sceptre. Deploying it requires a one-time manual step to authorize the AWS–GitHub connection. + + +1. **Deploy the CodeBuild stack** + + ```sh + export AWS_PROFILE=cdl-d2d-dev + aws sso login --profile cdl-d2d-dev + uv run sceptre launch dev/codebuild.yaml + ``` + +2. **Activate the GitHub connection** (one-time, manual) + + The `AWS::CodeStarConnections::Connection` resource is created in a `PENDING_HANDSHAKE` state and must be authorized before CodeBuild can access GitHub. + + - Open the [AWS Console → Developer Tools → Connections](https://us-west-2.console.aws.amazon.com/codesuite/settings/connections) in the `cdl-d2d-dev` account (`us-west-2`) + - Find the connection named `d2d-zephir-api-api-dev-github` + - Click **Update pending connection** and complete the GitHub OAuth flow + + Once authorized the connection status changes to **Available** and the CodeBuild webhook is live. + +3. **Validate** + + Open a pull request. The CodeBuild project `d2d-zephir-api-api-dev-ci` should trigger automatically and post a check status on the PR. + +### Test results + +Build status is automatically reported to GitHub. + +Test results are published to the CodeBuild **Test reports** panel (JUnit XML). ## Deploying to AWS diff --git a/buildspec.yml b/buildspec.yml new file mode 100644 index 0000000..45e91dc --- /dev/null +++ b/buildspec.yml @@ -0,0 +1,25 @@ +version: 0.2 + +phases: + install: + commands: + - pip install uv + + pre_build: + commands: + - uv sync --frozen + + build: + commands: + - uv run python --version + - uv tree --outdated + - uv run pytest --cov=app --cov-report=term-missing --junitxml=pytest-report.xml + - uv run bandit -r app + - uv run ruff check . + - uv run vulture . --min-confidence 70 --exclude .venv + +reports: + pytest-reports: + files: + - pytest-report.xml + file-format: JUNITXML diff --git a/deployment/config/dev/codebuild.yaml b/deployment/config/dev/codebuild.yaml new file mode 100644 index 0000000..1eecba0 --- /dev/null +++ b/deployment/config/dev/codebuild.yaml @@ -0,0 +1,5 @@ +template: + path: codebuild.yaml.j2 + type: file + +# No dependencies on other stacks; CodeBuild is independent of ECS/network/etc. diff --git a/deployment/templates/codebuild.yaml.j2 b/deployment/templates/codebuild.yaml.j2 new file mode 100644 index 0000000..5317cac --- /dev/null +++ b/deployment/templates/codebuild.yaml.j2 @@ -0,0 +1,86 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: CodeBuild CI project for Zephir API + +Resources: + GitHubConnection: + Type: AWS::CodeStarConnections::Connection + Properties: + ConnectionName: "{{ sceptre_user_data.resource_name_prefix }}-github" + ProviderType: GitHub + + CodeBuildServiceRole: + Type: AWS::IAM::Role + Properties: + RoleName: "{{ sceptre_user_data.resource_name_prefix }}-codebuild-service-role" + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: codebuild.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: CloudWatch-Logs + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/{{ sceptre_user_data.resource_name_prefix }}-ci" + - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/{{ sceptre_user_data.resource_name_prefix }}-ci:*" + - PolicyName: CodeBuild-Reports + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - codebuild:CreateReportGroup + - codebuild:CreateReport + - codebuild:UpdateReport + - codebuild:BatchPutTestCases + Resource: !Sub "arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/{{ sceptre_user_data.resource_name_prefix }}-ci-*" + - PolicyName: GitHub-Connection + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: codestar-connections:UseConnection + Resource: !Ref GitHubConnection + + CodeBuildProject: + Type: AWS::CodeBuild::Project + Properties: + Name: "{{ sceptre_user_data.resource_name_prefix }}-ci" + Description: "CI for Zephir API" + ServiceRole: !GetAtt CodeBuildServiceRole.Arn + Source: + Type: GITHUB + Location: "{{ sceptre_user_data.repository }}" + BuildSpec: buildspec.yml + GitCloneDepth: 1 + ReportBuildStatus: true + Auth: + Type: OAUTH + Resource: !Ref GitHubConnection + Environment: + Type: LINUX_CONTAINER + Image: aws/codebuild/standard:7.0 + ComputeType: BUILD_GENERAL1_SMALL + Triggers: + Webhook: true + FilterGroups: + - - Type: EVENT + Pattern: PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED,PULL_REQUEST_REOPENED + Artifacts: + Type: NO_ARTIFACTS + +Outputs: + ConnectionArn: + Value: !Ref GitHubConnection + ProjectName: + Value: !Ref CodeBuildProject + ProjectArn: + Value: !GetAtt CodeBuildProject.Arn From 1f51ed74d5d4f7630000b7be6bb18e7776e8d5c5 Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Fri, 13 Mar 2026 10:43:27 -0700 Subject: [PATCH 4/7] Create GitHub Connection manually. --- README.md | 29 ++------------------------ deployment/config/dev/codebuild.yaml | 5 +++++ deployment/templates/codebuild.yaml.j2 | 17 +++++++-------- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index dc60e23..2710092 100644 --- a/README.md +++ b/README.md @@ -115,36 +115,11 @@ The job configuration lives in [`buildspec.yml`](buildspec.yml). ### First-time setup -The CodeBuild infrastructure is managed by Sceptre. Deploying it requires a one-time manual step to authorize the AWS–GitHub connection. - - -1. **Deploy the CodeBuild stack** - - ```sh - export AWS_PROFILE=cdl-d2d-dev - aws sso login --profile cdl-d2d-dev - uv run sceptre launch dev/codebuild.yaml - ``` - -2. **Activate the GitHub connection** (one-time, manual) - - The `AWS::CodeStarConnections::Connection` resource is created in a `PENDING_HANDSHAKE` state and must be authorized before CodeBuild can access GitHub. - - - Open the [AWS Console → Developer Tools → Connections](https://us-west-2.console.aws.amazon.com/codesuite/settings/connections) in the `cdl-d2d-dev` account (`us-west-2`) - - Find the connection named `d2d-zephir-api-api-dev-github` - - Click **Update pending connection** and complete the GitHub OAuth flow - - Once authorized the connection status changes to **Available** and the CodeBuild webhook is live. - -3. **Validate** - - Open a pull request. The CodeBuild project `d2d-zephir-api-api-dev-ci` should trigger automatically and post a check status on the PR. +The CodeBuild project is managed by Sceptre. Note that the GitHub connection is created and activated manually before deploying. ### Test results -Build status is automatically reported to GitHub. - -Test results are published to the CodeBuild **Test reports** panel (JUnit XML). +Build status is automatically reported to GitHub on every PR. Test results are published to the CodeBuild **Test reports** panel (JUnit XML). ## Deploying to AWS diff --git a/deployment/config/dev/codebuild.yaml b/deployment/config/dev/codebuild.yaml index 1eecba0..61c967e 100644 --- a/deployment/config/dev/codebuild.yaml +++ b/deployment/config/dev/codebuild.yaml @@ -3,3 +3,8 @@ template: type: file # No dependencies on other stacks; CodeBuild is independent of ECS/network/etc. +# +# GitHubConnectionArn must be created and activated manually before deploying. +# See the "CI" section in README.md for instructions. +parameters: + GitHubConnectionArn: arn:aws:codeconnections:us-west-2:445017934155:connection/6af1f14e-4157-4e78-a1bd-73f160a9c4c5 diff --git a/deployment/templates/codebuild.yaml.j2 b/deployment/templates/codebuild.yaml.j2 index 5317cac..db5a639 100644 --- a/deployment/templates/codebuild.yaml.j2 +++ b/deployment/templates/codebuild.yaml.j2 @@ -1,13 +1,12 @@ AWSTemplateFormatVersion: 2010-09-09 Description: CodeBuild CI project for Zephir API -Resources: - GitHubConnection: - Type: AWS::CodeStarConnections::Connection - Properties: - ConnectionName: "{{ sceptre_user_data.resource_name_prefix }}-github" - ProviderType: GitHub +Parameters: + GitHubConnectionArn: + Type: String + Description: ARN of the manually-created and activated CodeStar connection to GitHub +Resources: CodeBuildServiceRole: Type: AWS::IAM::Role Properties: @@ -48,7 +47,7 @@ Resources: Statement: - Effect: Allow Action: codestar-connections:UseConnection - Resource: !Ref GitHubConnection + Resource: !Ref GitHubConnectionArn CodeBuildProject: Type: AWS::CodeBuild::Project @@ -64,7 +63,7 @@ Resources: ReportBuildStatus: true Auth: Type: OAUTH - Resource: !Ref GitHubConnection + Resource: !Ref GitHubConnectionArn Environment: Type: LINUX_CONTAINER Image: aws/codebuild/standard:7.0 @@ -78,8 +77,6 @@ Resources: Type: NO_ARTIFACTS Outputs: - ConnectionArn: - Value: !Ref GitHubConnection ProjectName: Value: !Ref CodeBuildProject ProjectArn: From bb280cedfa7fd0d2ece6c399c13324617c490a83 Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Fri, 13 Mar 2026 10:50:32 -0700 Subject: [PATCH 5/7] Fix permissions for Github connection in CodeBuild. --- deployment/templates/codebuild.yaml.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deployment/templates/codebuild.yaml.j2 b/deployment/templates/codebuild.yaml.j2 index db5a639..1b977c7 100644 --- a/deployment/templates/codebuild.yaml.j2 +++ b/deployment/templates/codebuild.yaml.j2 @@ -46,7 +46,9 @@ Resources: Version: 2012-10-17 Statement: - Effect: Allow - Action: codestar-connections:UseConnection + Action: + - codeconnections:GetConnectionToken + - codeconnections:GetConnection Resource: !Ref GitHubConnectionArn CodeBuildProject: From e90bb203ff317935b85813cfc593664d189e728c Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Fri, 13 Mar 2026 15:47:15 -0700 Subject: [PATCH 6/7] Disable CodeQL. --- .github/workflows/codeql.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..e69de29 From 9f48d5cdaa3a1b309378d25da85b70666b362ce9 Mon Sep 17 00:00:00 2001 From: Christopher Groskopf Date: Mon, 16 Mar 2026 13:17:13 -0700 Subject: [PATCH 7/7] Test --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2710092..c159ae6 100644 --- a/README.md +++ b/README.md @@ -148,3 +148,4 @@ Build status is automatically reported to GitHub on every PR. Test results are p **CAUTION! CAUTION! This command will destroy all related AWS resources** `uv run sh deployment/scripts/destroy.sh `. +