mirror of
https://github.com/Sea-Haven-Industries/.github.git
synced 2026-09-30 09:23:11 +00:00
INFRA-69: README documented the deleted claude-code-review.yaml workflow and its rollout as the live PR-review setup. PR reviews are handled by the official Claude Code App (since 2026-05-13); corrected the workflow list, added a PR Reviews note, marked the legacy rollout script, and replaced the obsolete rollout step. Preserved the claude-code-ci App + secrets (compliance-audit still uses them). INFRA-68: add SECURITY.md (private vuln reporting via GitHub advisory / email) and SUPPORT.md (Jira INFRA, handbook, security pointer).
261 lines
10 KiB
Markdown
261 lines
10 KiB
Markdown
# .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.)
|
|
|
|
```bash
|
|
# 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`:
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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](#aws-deploy-roles--iam-oidc-deploy-rolesyaml).
|
|
|
|
**TypeScript CDK repo** (e.g., seahaven-door-unlock-api):
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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):
|
|
|
|
```yaml
|
|
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.
|