mirror of
https://github.com/Sea-Haven-Industries/.github.git
synced 2026-09-30 22:13:12 +00:00
- README: mark compliance-audit.yaml deprecated (2026-06-10), document all 12 reusable workflows (was 6), add workflow-templates and action-pinning policy sections - dependency-review.yml template: convert to thin caller of callable-dependency-review.yaml (was inlining dependency-review-action@v4, drifted from callable @v5) - callable-dependency-review.yaml: preserve comment-summary-in-pr on-failure and grant pull-requests: write - add labeler.yml + labeler.properties.json starter template
289 lines
13 KiB
Markdown
289 lines
13 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/ci-typescript-frontend.yaml`** — Reusable CI workflow for bundled TypeScript front-end apps (Vite / React / Vue SPAs). Runs a Sea Haven standards gate (required npm scripts present, no AI-tool footers / hook bypasses / hardcoded secrets in added lines), then `format:check`, `lint`, `build`, vitest unit tests, and an optional Playwright browser smoke. Emits the single `ci / ci` status context — keep the caller job id `ci`.
|
|
|
|
**`.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/ci-python-app.yaml`** — Reusable CI for non-SAM Python apps (ruff check + format, optional pytest; no SAM validate).
|
|
|
|
**`.github/workflows/ci-dotnet.yaml`** — Reusable CI for .NET solutions (`dotnet build`, optional `dotnet test`; SDK version and solution path as inputs).
|
|
|
|
**`.github/workflows/ci-static.yaml`** — Reusable CI for static sites (e.g. Eleventy builds for seahaven-site).
|
|
|
|
**`.github/workflows/cd-mobile-ios.yaml`** — Reusable CD for iOS apps via Fastlane to TestFlight (Node + Ruby setup inputs).
|
|
|
|
**`.github/workflows/callable-labeler.yaml`** — Org-wide PR auto-labeler. Label rules live inline here (single source of truth) — consumer repos need only a thin caller with `contents: read`, `pull-requests: write`, and `issues: write`; no per-repo labeler.yml.
|
|
|
|
**`.github/workflows/callable-dependency-review.yaml`** — Dependency review on PRs, failing on high severity. Requires Dependency Graph.
|
|
|
|
**`.github/workflows/ci.yaml`** — Self-CI for this repo: actionlint (checksum-verified install) over all workflow files, emitting the required `ci / ci` status context.
|
|
|
|
**`.github/workflows/compliance-audit.yaml`** — **DEPRECATED (2026-06-10).** The weekly scheduled org-wide audit has been retired: the schedule was removed and the workflow is disabled in the Actions tab (manual `workflow_dispatch` only, kept for historical reference). Repo compliance is now handled by the Claude Code App on pull requests and the engineering handbook directly. Safe to delete in a future cleanup.
|
|
|
|
### Workflow templates (`workflow-templates/`)
|
|
|
|
Starter workflows offered on the org's **Actions → New workflow** page: `ci-python`, `ci-node`, `cdk-deploy`, `sam-deploy`, `dependency-review`, `labeler`, `triage`. Each is a thin caller of the corresponding reusable workflow above (`triage` is standalone). Every template has a paired `properties.json` (name, description, icon, `filePatterns` for auto-suggestion). Replace any `REPLACE-ME` placeholders before enabling.
|
|
|
|
### Action pinning policy
|
|
|
|
Third-party action refs across the org follow a tiered policy:
|
|
|
|
- **High-trust / high-blast-radius third-party actions are SHA-pinned** with a trailing version comment (e.g. `actions/labeler` in `callable-labeler.yaml`), and binary installs are checksum-verified (actionlint in `ci.yaml`). Dependabot keeps the SHA current via its trailing-comment mechanism.
|
|
- **Common first-party actions** (`actions/checkout`, `actions/dependency-review-action`, `actions/github-script`) are pinned to a **major tag** (`@v7`, `@v5`, …) and kept current by Dependabot version updates gated by CI.
|
|
- **Org reusable workflows** are referenced at **`@main`** (`uses: Sea-Haven-Industries/.github/.github/workflows/…@main`). This is deliberate: caller and callable share one trust domain, and pinning callers to a SHA would freeze every consumer against central fixes. Templates in `workflow-templates/` follow the same `@main` convention.
|
|
|
|
### 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.
|