engineering-handbook/cicd.md
Adam Moussa 4b5d39fb91
Add CDK version policy, update Node 24 and GitHub Actions CI/CD (#6)
* Update CDK version policy, Node 24 runtime, and GitHub Actions CI/CD

- Pin blessed aws-cdk-lib version (2.253.1) with upgrade procedure
- Update Lambda runtime default from Node 22 to Node 24
- Rewrite CI/CD page to reflect GitHub Actions reusable workflows
  (was still referencing CodePipeline/CodeBuild)

* Add pre-push hook for npm ci validation

Catches lock file drift locally before it breaks CI. Includes
install instructions in git-workflow.md.

* Add repo provisioning script

Automates the new-repo checklist: GitHub repo creation, OIDC deploy
role, repo secret, security features, CI/CD workflow stubs, and
pre-push hook installation. Supports both SAM and CDK stack types.

* Add shared VpnEc2Instance CDK construct

Reference construct for the VPN-accessible EC2 pattern used by
file-share and forgejo. Includes VPC/subnet lookup, SG, IAM role,
encrypted EBS, and DLM snapshots. Copy into lib/constructs/.

* Add post-deploy health check template

Template script for project-specific health checks. Copy to
scripts/health-check.sh — CD workflows run it automatically.
2026-05-14 18:39:13 -04:00

2.6 KiB

CI/CD Pipelines

Requirement

Every deployable repo must have a CI/CD pipeline. No manual deploys to production. If it deploys to AWS, it needs a pipeline.

Platform

GitHub Actions is the standard CI/CD platform. All pipelines use reusable workflows from the Sea-Haven-Industries/.github org repo (.github/workflows/).

Workflow Structure

Every repo gets two thin workflow files in .github/workflows/:

File Trigger Purpose
ci.yaml pull_request on main Lint, typecheck, test, synth/validate
deploy.yaml push on main Deploy to AWS

CDK Stacks (TypeScript)

# .github/workflows/ci.yaml
name: CI
on:
  pull_request:
    branches: [main]
jobs:
  ci:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main
    with:
      node-version: "24"

# .github/workflows/deploy.yaml
name: Deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@main
    with:
      node-version: "24"
    secrets:
      deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

SAM Stacks (Python)

# .github/workflows/ci.yaml
name: CI
on:
  pull_request:
    branches: [main]
jobs:
  ci:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@main

# .github/workflows/deploy.yaml
name: Deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    uses: Sea-Haven-Industries/.github/.github/workflows/cd-sam.yaml@main
    with:
      stack-name: "your-stack-name"
    secrets:
      cfn-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

Authentication

Deploy workflows authenticate to AWS via OIDC (no long-lived credentials). Each repo needs:

  1. An IAM role named githubdeploy-<repo-name> with:
    • OIDC trust policy for token.actions.githubusercontent.com
    • Subject condition: repo:Sea-Haven-Industries/<repo>:ref:refs/heads/main
    • Inline policy allowing sts:AssumeRole on CDK/SAM bootstrap roles
  2. A repo secret AWS_DEPLOY_ROLE_ARN containing the role ARN

Node.js Version

Always pass node-version: "24" to reusable workflows. Local dev uses Node 24 / npm 11 which generates lockfileVersion 3. The workflow defaults match this, but be explicit to avoid drift.

Naming

  • All workflow files: kebab-case
  • Reusable workflow references: @main branch

When to Add a Pipeline

  • When creating a new deployable project — the pipeline is part of the initial setup, not a follow-up
  • When working on an existing project that lacks one — flag it and add it as part of the current work

A project is not production-ready without CI/CD.