Organization-level GitHub configuration — Claude Code review and compliance workflows
Find a file
Adam Moussa e43a9cb447 ci-static: add build mode for templated static sites
Add check-dir + build-command inputs. When build-command is set, run
npm ci + the build, then validate the built output in check-dir (e.g.
_site) instead of repo source. Without this, a site that templates its
HTML (Eleventy etc.) has no source HTML and the checks pass vacuously.

Backward-compatible: defaults (check-dir='.', build-command='') preserve
source-mode behavior for existing callers. build-command is passed via
env to avoid expression injection into the run script.
2026-06-12 16:29:19 -04:00
.github ci-static: add build mode for templated static sites 2026-06-12 16:29:19 -04:00
scripts Add id-token: write permission for claude-code-action 2026-05-06 19:44:35 -04:00
workflow-templates Add org-wide reusable PR labeler (INFRA-56) (#50) 2026-06-11 13:34:39 -04:00
.gitignore Add Claude Code review and compliance audit workflows 2026-05-06 15:10:48 -04:00
oidc-deploy-roles.yaml Scope github-cfn-execution-role down from *FullAccess (#46) 2026-06-10 14:31:50 -04:00
README.md docs: fix README review drift + add community-health files (#48) 2026-06-10 15:35:31 -04:00
SECURITY.md docs: fix README review drift + add community-health files (#48) 2026-06-10 15:35:31 -04:00
SUPPORT.md docs: fix README review drift + add community-health files (#48) 2026-06-10 15:35:31 -04:00

.github

Organization-level GitHub configuration for Sea Haven Industries.

What's in here

Reusable Workflows

.github/workflows/ci-python-sam.yaml — Reusable CI workflow for Python / SAM repos. Runs ruff check + ruff format --check, optional pytest, and optional sam validate --lint. Also usable for Python CDK repos by disabling SAM validate.

.github/workflows/ci-typescript-cdk.yaml — Reusable CI workflow for TypeScript / CDK repos. Runs npm ci + optional tsc --noEmit, optional ESLint, optional Jest, and optional cdk synth. Also supports Node.js SAM repos via an optional sam validate step.

.github/workflows/cd-sam.yaml — Reusable CD workflow for SAM repos. Runs sam build + sam deploy with OIDC credentials and a CloudFormation execution role. Triggers via workflow_call from per-repo deploy.yaml on push to main.

.github/workflows/cd-cdk.yaml — Reusable CD workflow for CDK repos (TypeScript and Python). Runs cdk deploy --all with OIDC credentials. Supports optional Python setup for Python CDK repos and QEMU emulation for cross-platform Docker builds.

.github/workflows/compliance-audit.yaml — Scheduled weekly audit (Mondays 10am ET) that checks all org repos for compliance with Sea Haven conventions. Creates GitHub issues on repos with violations. Can also be triggered manually via workflow_dispatch. Uses the claude-code-ci GitHub App + ANTHROPIC_API_KEY (see Setup).

PR Reviews

PR reviews are handled by the official Claude Code GitHub App (installed org-wide, enabled as a required check in the org ruleset) — there is no review workflow in this repo. The earlier custom claude-code-review.yaml reusable workflow and its per-repo wrapper were retired on 2026-05-13 when the App took over.

Scripts

scripts/rollout-review-workflow.sh — Legacy / superseded. One-time script that pushed the old PR-review wrapper workflow to all org repos. Obsolete since reviews moved to the official Claude Code App (2026-05-13); retained only for historical reference.

AWS deploy roles & IAM (oidc-deploy-roles.yaml)

oidc-deploy-roles.yaml is a bootstrap CloudFormation stack (github-oidc-deploy-roles, us-east-1, account 328440206208) that owns the IAM the CI/CD workflows assume. It contains:

  • The GitHub Actions OIDC provider (conditional — already exists in the account).
  • One OIDC deploy role per repo (githubdeploy-<repo>), assumed by that repo's deploy.yaml via OIDC and passed in as AWS_DEPLOY_ROLE_ARN. CDK repos use these to assume the cdk-hnb659fds-* bootstrap roles; SAM repos use these to run sam deploy.
  • The shared SAM CloudFormation execution role github-cfn-execution-role (SamCfnExecutionRole) — passed as cfn-role-arn by every SAM deploy.yaml (see §5). CloudFormation assumes it to provision the SAM stacks' resources.
  • The seahaven-lambda-execution-boundary managed policy.

⚠️ This stack has no CD pipeline — it is deployed manually. (It defines the very roles the pipelines use, so it can't deploy itself.)

# Review IAM changes FIRST (IAM changes also require the cross-family review per the handbook):
aws cloudformation deploy \
  --region us-east-1 \
  --stack-name github-oidc-deploy-roles \
  --template-file oidc-deploy-roles.yaml \
  --capabilities CAPABILITY_NAMED_IAM \
  --s3-bucket cdk-hnb659fds-assets-328440206208-us-east-1 \
  --no-execute-changeset
# inspect the printed change-set, then drop --no-execute-changeset to apply.

--s3-bucket is required — the template is larger than the 51,200-byte inline limit.

github-cfn-execution-role is scoped (no *FullAccess)

The execution role carries no blanket *FullAccess/IAMFullAccess — only per-service inline policies. Its iam:CreateRole / iam:AttachRolePolicy / iam:PutRolePolicy are conditioned on iam:PermissionsBoundary == seahaven-lambda-execution-boundary, so it can only create roles that carry the boundary (it cannot mint an unconstrained admin role). Adding a new AWS service to a SAM stack means adding that service's provisioning actions to this role, or the deploy fails.

seahaven-lambda-execution-boundary is the Lambda runtime ceiling

Every SAM-created Lambda execution role gets this boundary attached — SAM stacks set it on Globals.Function:

Globals:
  Function:
    PermissionsBoundary: arn:aws:iam::328440206208:policy/seahaven-lambda-execution-boundary

A function's effective permissions are the intersection of its own role policy and this boundary. A new runtime permission must also be added to the boundary, or it is silently denied at runtime (the deploy still succeeds — the failure only shows when the function runs). SAM does not support a custom Path on auto-generated function roles, so the boundary condition (not a role path) is the escalation guard.

Order of operations when changing the exec role or boundary

  1. Deploy the boundary change first.
  2. Redeploy the SAM stacks so their roles pick it up (while the exec role still permits it).
  3. Then tighten the exec role.

Wrong order breaks every SAM deploy. (History: INFRA-103 established the boundary, INFRA-97 scoped the role.) CDK repos are unaffected — they deploy via cdk-hnb659fds-* roles, not this execution role.

Setup

1. Create a GitHub App

  1. Go to Organization Settings > Developer settings > GitHub Apps > New GitHub App
  2. Name it claude-code-ci (or similar)
  3. Set Homepage URL to your org URL
  4. Disable Webhook (uncheck "Active")
  5. Set these Repository permissions:
    • Contents: Read and write
    • Issues: Read and write
    • Metadata: Read-only
    • Pull requests: Read and write
  6. Set Where can this app be installed? to "Only on this account"
  7. Click Create GitHub App
  8. Note the App ID from the app's settings page
  9. Under Private keys, click Generate a private key — save the .pem file

2. Install the App

  1. From the app's settings page, click Install App
  2. Select Sea-Haven-Industries
  3. Choose All repositories

3. Add org-level secrets

Go to Organization Settings > Secrets and variables > Actions and add:

Secret Value
ANTHROPIC_API_KEY Your Claude API key
CLAUDE_CI_APP_ID The App ID from step 1
CLAUDE_CI_APP_PRIVATE_KEY The full contents of the .pem file from step 1

4. Add CI to a repo

Create .github/workflows/ci.yaml in the target repo. Examples:

Python SAM repo (e.g., afterhours-shift-manager, expense-approval-bot):

name: CI
on:
  pull_request:
    branches: [main]

jobs:
  ci:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@main

TypeScript CDK repo (e.g., seahaven-door-unlock-api, seahaven-slack-bot):

name: CI
on:
  pull_request:
    branches: [main]

jobs:
  ci:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main

Node.js SAM repo (e.g., payments-dashboard):

name: CI
on:
  pull_request:
    branches: [main]

jobs:
  ci:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main
    with:
      run-typecheck: false
      run-cdk-synth: false
      run-sam-validate: true

Mixed stack (e.g., exec-aide — TypeScript CDK + Python Lambdas):

name: CI
on:
  pull_request:
    branches: [main]

jobs:
  python:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@main
    with:
      source-dirs: "src"
      run-sam-validate: false
  typescript:
    uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main

5. Add CD to a repo

Create .github/workflows/deploy.yaml in the target repo. Requires AWS_DEPLOY_ROLE_ARN repo secret.

SAM repo (e.g., afterhours-shift-manager):

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    uses: Sea-Haven-Industries/.github/.github/workflows/cd-sam.yaml@main
    with:
      stack-name: afterhours-shift-manager
      cfn-role-arn: arn:aws:iam::328440206208:role/github-cfn-execution-role
    secrets:
      deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

The cfn-role-arn (github-cfn-execution-role) is scoped and boundary-gated — adding a new AWS service or a new Lambda runtime permission to a SAM stack may require updating that role and/or seahaven-lambda-execution-boundary first. See AWS deploy roles & IAM.

TypeScript CDK repo (e.g., seahaven-door-unlock-api):

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@main
    secrets:
      deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

Python CDK repo (e.g., po-ingest):

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@main
    with:
      python-version: "3.12"
      cdk-dir: cdk
    secrets:
      deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

CDK repo with arm64 Docker builds (e.g., exec-aide):

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@main
    with:
      enable-qemu: true
    secrets:
      deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

Enable optional steps as repos adopt them:

Input Default Turn on when...
run-tests false Repo has pytest tests or Jest tests
run-lint false Repo has an ESLint config
run-typecheck true Repo has tsconfig.json
run-cdk-synth true Repo is CDK-based
run-sam-validate true (Python) / false (TS) Repo has a SAM template

6. PR reviews

PR reviews run via the official Claude Code GitHub App — install it on the org and enable it as a required check in the ruleset. No per-repo workflow or rollout is needed; the legacy rollout-review-workflow.sh is retained only for historical reference.