From 10bcf6d9c048e27a6e886712a6bd87fcf49f110f Mon Sep 17 00:00:00 2001 From: Alexanderamiri Date: Fri, 23 Oct 2026 10:50:56 +0200 Subject: [PATCH 1/2] fix: grant deploy.yml the permissions the platform pipeline needs Without a permissions block the platform's expand step cannot push generated Terraform, and OIDC is unavailable where org defaults are read-only. Document onboarding (repo in the app.yaml team), drop the unsupported budget_alert_nok and auth: both, and drop secrets: inherit. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/deploy.yml | 12 ++++++++++-- CLAUDE.md | 11 ++++++----- README.md | 12 ++++++++---- app.yaml | 9 ++++----- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d73ee1b..7175268 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,17 @@ name: Deploy on: push: - branches: [main, master] + branches: [main] pull_request: + workflow_dispatch: + +permissions: + id-token: write # AWS access via OIDC + contents: write # platform commits generated Terraform to the branch + pull-requests: write # plan + review comment on PRs + +# No secrets needed — see +# https://github.com/javaBin/platform/blob/main/docs/reusable-workflows.md jobs: javabin: uses: javaBin/platform/.github/workflows/javabin.yml@main - secrets: inherit diff --git a/CLAUDE.md b/CLAUDE.md index d49b01c..9b0ae17 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,7 +15,7 @@ GitHub template repository for creating new services on the Javabin platform. 1. Click **"Use this template"** on GitHub to create a new repo under `javaBin/` 2. Edit `app.yaml` — set your service name, team, compute settings, routing, and any resources -3. Ensure your team is registered in [javaBin/registry](https://github.com/javaBin/registry) (`teams/{name}.yaml`) and add the repo to your GitHub team +3. Ensure your team is registered in [javaBin/registry](https://github.com/javaBin/registry) (`teams/{name}.yaml`) and add the repo to the GitHub team named in `app.yaml` `team:` 4. Push to `main` — the platform CI builds, plans, reviews, and deploys automatically ## app.yaml Fields @@ -24,10 +24,11 @@ GitHub template repository for creating new services on the Javabin platform. - `team` — owning team, must exist in the registry (required) - `compute` — CPU, memory, port, desired count, health check path - `routing` — hostname under `javazone.no` and ALB priority -- `resources` — S3 buckets, DynamoDB tables, Secrets Manager secrets, SQS queues -- `auth` — Cognito integration: `internal`, `external`, `both`, or `none` +- `resources` — S3 buckets, DynamoDB tables / RDS PostgreSQL, SSM secrets, SQS queues +- `auth` — Cognito integration: `internal`, `external`, or `none` - `environment` — custom environment variables -- `budget_alert_nok` — monthly budget alert threshold in NOK + +Unknown fields fail the pipeline's `expand` step. Budgets are per team, set in the registry. Full reference: [app.yaml reference](https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md) @@ -37,7 +38,7 @@ The default Dockerfile uses `eclipse-temurin:21` for a Java/Maven project. Repla ## CI -This template includes `.github/workflows/deploy.yml` which calls the platform's reusable workflow `javaBin/platform/.github/workflows/javabin.yml@main`. No additional workflow config needed. +This template includes `.github/workflows/deploy.yml` which calls the platform's reusable workflow `javaBin/platform/.github/workflows/javabin.yml@main`. No secrets are needed; keep the `permissions:` block (`id-token: write`, `contents: write`, `pull-requests: write`). ## Related diff --git a/README.md b/README.md index 147728f..54db7e1 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,18 @@ A Javabin platform service. ## Getting Started 1. **Create from template**: Click "Use this template" on GitHub -2. **Register your team**: If not already registered, open a PR to [javaBin/registry](https://github.com/javaBin/registry) adding `teams/your-team.yaml`, then add this repo to your GitHub team -3. **Customize `app.yaml`**: Set your service name, team, compute, and routing -4. **Push to main**: The platform CI pipeline builds, plans, reviews, and deploys automatically +2. **Register your team**: If not already registered, open a PR to [javaBin/registry](https://github.com/javaBin/registry) adding `teams/your-team.yaml` (or run `javabin register-team`). Merging creates the GitHub team and the team's AWS CI roles. +3. **Add this repo to your GitHub team** — the one named in `app.yaml` `team:`: + `gh api -X PUT orgs/javaBin/teams//repos/javaBin/ -f permission=push` +4. **Customize `app.yaml`**: Set your service name, team, compute, and routing +5. **Push to main**: The platform CI pipeline builds, plans, reviews, and deploys automatically + +No repository secrets are needed. `.github/workflows/deploy.yml` must keep its `permissions:` block (`id-token`, `contents: write`, `pull-requests`). ## Platform Features - Automatic Docker build and ECR push -- Terraform infrastructure from `app.yaml` (S3, DynamoDB, SQS, Secrets Manager) +- Terraform infrastructure from `app.yaml` (S3, DynamoDB, RDS PostgreSQL, SQS, SSM secrets, Cognito clients) - LLM-powered plan review with risk gating - ECS Fargate deployment with health checks - CloudWatch alarms and cost monitoring diff --git a/app.yaml b/app.yaml index 11e3339..46d3b62 100644 --- a/app.yaml +++ b/app.yaml @@ -1,10 +1,10 @@ # app.yaml — Javabin Platform Service Configuration # Full reference: https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md -# Service name (required) — lowercase + hyphens, max 20 chars +# Service name — lowercase letters, digits, hyphens; max 20 chars (default: repo name) name: my-service -# Owning team (required) — must match a team in javaBin/registry +# Owning team (required) — a team in javaBin/registry; this repo must be in its GitHub team team: my-team # Container compute settings (optional, defaults shown) @@ -36,12 +36,11 @@ routing: # - name: jobs # env: JOBS_QUEUE_URL -# Cognito auth (optional) — internal, external, both, or none +# Cognito auth (optional) — internal or external. Injects COGNITO_* env vars. # auth: internal # Custom environment variables # environment: # LOG_LEVEL: info -# Monthly budget alert in NOK (default: 1000) -# budget_alert_nok: 500 +# Unknown fields fail the pipeline. Budgets are set per team in javaBin/registry. From ba4e4aac04bc5aa6d217542222381399f958551f Mon Sep 17 00:00:00 2001 From: Alexanderamiri Date: Sat, 24 Oct 2026 12:48:47 +0200 Subject: [PATCH 2/2] fix: skip deploy in the template repo and align app.yaml with the platform The template's own Deploy run failed in expand: team `my-team` is invalid (lowercase letters only). Use `myteam`, and skip the javabin job when the repository is javaBin/app-template so the template never deploys while repos created from it do. Document current app.yaml options (auth client/groups/env/localhost callbacks, compute user/readonly_root_filesystem, strict validation, per-team budgets) and the secrets flow via `javabin aws setup` and `javabin secret set`. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/deploy.yml | 2 ++ CLAUDE.md | 18 +++++++++------ README.md | 30 +++++++++++++++++------- app.yaml | 44 ++++++++++++++++++++++++------------ 4 files changed, 65 insertions(+), 29 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7175268..a5e275c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,4 +14,6 @@ permissions: # https://github.com/javaBin/platform/blob/main/docs/reusable-workflows.md jobs: javabin: + # The template repo itself never deploys; repos created from it do. + if: github.repository != 'javaBin/app-template' uses: javaBin/platform/.github/workflows/javabin.yml@main diff --git a/CLAUDE.md b/CLAUDE.md index 9b0ae17..aecebd4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,17 +15,18 @@ GitHub template repository for creating new services on the Javabin platform. 1. Click **"Use this template"** on GitHub to create a new repo under `javaBin/` 2. Edit `app.yaml` — set your service name, team, compute settings, routing, and any resources -3. Ensure your team is registered in [javaBin/registry](https://github.com/javaBin/registry) (`teams/{name}.yaml`) and add the repo to the GitHub team named in `app.yaml` `team:` +3. Ensure your team is registered in [javaBin/registry](https://github.com/javaBin/registry) (`teams/{name}.yaml`) and add the repo to the GitHub team named in `app.yaml` `team:` (CI verifies repo → team before vending credentials) 4. Push to `main` — the platform CI builds, plans, reviews, and deploys automatically +5. Set any secret values: `brew install javaBin/tap/javabin`, `javabin aws setup` (SSO permission set `javabin-team-`), then `javabin secret set ` ## app.yaml Fields - `name` — service name (required, lowercase + hyphens, max 20 chars) -- `team` — owning team, must exist in the registry (required) -- `compute` — CPU, memory, port, desired count, health check path +- `team` — owning team, lowercase letters only (max 12), must exist in the registry (required) +- `compute` — CPU, memory, port, desired count, health check path, `user` (default `"1000"`), `readonly_root_filesystem` (default `true`; only `/tmp` writable) - `routing` — hostname under `javazone.no` and ALB priority -- `resources` — S3 buckets, DynamoDB tables / RDS PostgreSQL, SSM secrets, SQS queues -- `auth` — Cognito integration: `internal`, `external`, or `none` +- `resources` — S3 buckets, DynamoDB tables / RDS PostgreSQL, SSM secrets (created as `PLACEHOLDER`, set with `javabin secret set`), SQS queues +- `auth` — Cognito: `internal`/`external` shorthand, or full form with `client: confidential|public|none`, `callback_urls` (https or `http://localhost`), `groups` (restricts sign-in), `env` (alias injected names) - `environment` — custom environment variables Unknown fields fail the pipeline's `expand` step. Budgets are per team, set in the registry. @@ -38,10 +39,13 @@ The default Dockerfile uses `eclipse-temurin:21` for a Java/Maven project. Repla ## CI -This template includes `.github/workflows/deploy.yml` which calls the platform's reusable workflow `javaBin/platform/.github/workflows/javabin.yml@main`. No secrets are needed; keep the `permissions:` block (`id-token: write`, `contents: write`, `pull-requests: write`). +This template includes `.github/workflows/deploy.yml` which calls the platform's reusable workflow `javaBin/platform/.github/workflows/javabin.yml@main`. No secrets are needed; keep the `permissions:` block (`id-token: write`, `contents: write`, `pull-requests: write`). The job's `if: github.repository != 'javaBin/app-template'` keeps the template itself from deploying; generated repos have another name, so it runs there. + +Validate `app.yaml` locally against the generator from a platform checkout: +`GITHUB_WORKSPACE=. APP_SERVICE=my-service AWS_ACCOUNT_ID=553637109631 TF_ROOT=/tmp/gen python3 -I ../platform/scripts/generate-modules.py` ## Related - [javaBin/platform](https://github.com/javaBin/platform) — shared infrastructure and reusable modules - [javaBin/registry](https://github.com/javaBin/registry) — team registration -- [javaBin/javabin-cli](https://github.com/javaBin/javabin-cli) — `javabin register` automates team registration +- [javaBin/javabin-cli](https://github.com/javaBin/javabin-cli) — `javabin register-team`, `javabin aws setup`, `javabin secret set` diff --git a/README.md b/README.md index 54db7e1..6987895 100644 --- a/README.md +++ b/README.md @@ -4,25 +4,39 @@ A Javabin platform service. ## Getting Started -1. **Create from template**: Click "Use this template" on GitHub -2. **Register your team**: If not already registered, open a PR to [javaBin/registry](https://github.com/javaBin/registry) adding `teams/your-team.yaml` (or run `javabin register-team`). Merging creates the GitHub team and the team's AWS CI roles. -3. **Add this repo to your GitHub team** — the one named in `app.yaml` `team:`: +1. **Create from template**: Click "Use this template" on GitHub (repo under `javaBin/`) +2. **Register your team**: If not already registered, open a PR to [javaBin/registry](https://github.com/javaBin/registry) adding `teams/.yaml` (or run `javabin register-team`). Merging creates the GitHub team and the team's AWS CI roles; members sign in to AWS with the SSO permission set `javabin-team-`. Team names are lowercase letters only, max 12 chars. +3. **Add this repo to your GitHub team** — the one named in `app.yaml` `team:`; CI refuses to deploy otherwise: `gh api -X PUT orgs/javaBin/teams//repos/javaBin/ -f permission=push` -4. **Customize `app.yaml`**: Set your service name, team, compute, and routing -5. **Push to main**: The platform CI pipeline builds, plans, reviews, and deploys automatically +4. **Customize `app.yaml`**: Set your service name, team, compute, routing, and any resources/auth +5. **Push to main**: The platform CI pipeline builds, plans, reviews, and deploys automatically. Pull requests get a Terraform plan and review comment. -No repository secrets are needed. `.github/workflows/deploy.yml` must keep its `permissions:` block (`id-token`, `contents: write`, `pull-requests`). +No repository secrets are needed. `.github/workflows/deploy.yml` must keep its `permissions:` block (`id-token: write`, `contents: write`, `pull-requests: write`). Its `if:` only stops the template repo itself from deploying; it is true in your repo. + +## Secrets + +`resources.secrets` entries are created with the value `PLACEHOLDER` on the first deploy. Set real values with the [javabin CLI](https://github.com/javaBin/javabin-cli) from this repo: + +```bash +brew install javaBin/tap/javabin +javabin aws setup # SSO sign-in with javabin-team- +javabin secret list # which secrets still hold PLACEHOLDER +javabin secret set api-key # prompts without echo; --stdin to pipe +``` + +The service restarts automatically within a minute to pick up the new value. ## Platform Features - Automatic Docker build and ECR push - Terraform infrastructure from `app.yaml` (S3, DynamoDB, RDS PostgreSQL, SQS, SSM secrets, Cognito clients) - LLM-powered plan review with risk gating -- ECS Fargate deployment with health checks -- CloudWatch alarms and cost monitoring +- ECS Fargate deployment with health checks and circuit-breaker rollback +- CloudWatch alarms; budgets per team (set in the registry) ## References - [app.yaml reference](https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md) +- [Reusable workflows](https://github.com/javaBin/platform/blob/main/docs/reusable-workflows.md) - [Platform documentation](https://github.com/javaBin/platform) - [Registry](https://github.com/javaBin/registry) diff --git a/app.yaml b/app.yaml index 46d3b62..6a7b1f8 100644 --- a/app.yaml +++ b/app.yaml @@ -1,21 +1,27 @@ # app.yaml — Javabin Platform Service Configuration # Full reference: https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md +# +# Validated strictly: unknown or misspelled fields fail the pipeline's `expand` step. +# Budgets are not set here — they are per team (`budget_nok` in javaBin/registry teams/.yaml). -# Service name — lowercase letters, digits, hyphens; max 20 chars (default: repo name) +# Service name — starts with a letter; lowercase letters, digits, hyphens; max 20 chars (default: repo name) name: my-service -# Owning team (required) — a team in javaBin/registry; this repo must be in its GitHub team -team: my-team +# Owning team (required) — lowercase letters only, max 12 chars. Must exist in +# javaBin/registry (teams/.yaml), and this repo must be in that GitHub team. +team: myteam -# Container compute settings (optional, defaults shown) +# Container compute settings (optional; omitted fields use platform defaults) compute: cpu: 512 # vCPU units (256, 512, 1024, 2048, 4096) - memory: 1024 # MB (512-30720, must match cpu) - port: 8080 # container port your app listens on + memory: 1024 # MB, must be a valid Fargate combination with cpu + port: 8080 # container port your app listens on (platform default: 8000) desired_count: 1 # number of running tasks health_check: /health + # user: "1000" # container user (default "1000", non-root) + # readonly_root_filesystem: true # default true — only /tmp is writable; set false if the app writes elsewhere -# ALB routing (required for web services) +# ALB routing — omit for a worker with no load balancer routing: host: my-service.javazone.no # DNS name, must be under javazone.no priority: 100 # unique across all apps (1-50000) @@ -26,21 +32,31 @@ routing: # - name: data # env: DATA_BUCKET # databases: -# - name: cache +# - name: cache # DynamoDB (default) # hash_key: id # env: CACHE_TABLE -# secrets: -# - name: api-key +# - name: main # RDS PostgreSQL +# engine: postgres +# env: DATABASE_URL +# secrets: # created as PLACEHOLDER; set the value after the first deploy: +# - name: api-key # javabin aws setup && javabin secret set api-key # env: API_KEY # queues: # - name: jobs # env: JOBS_QUEUE_URL -# Cognito auth (optional) — internal or external. Injects COGNITO_* env vars. -# auth: internal +# Cognito auth (optional). Shorthand: `auth: internal` (Javabin heroes) or `auth: external` (public users). +# auth: +# pool: internal +# client: confidential # confidential (server-side login, id + secret) | public (browser PKCE, id only) | none (API that only verifies tokens) +# callback_urls: # default: https:/// and /auth/callback +# - https://my-service.javazone.no/auth/callback +# - http://localhost:8080/auth/callback # localhost allowed for local dev +# groups: # only members of these registry groups can sign in +# - team-myteam +# env: # also inject values under your own names +# COGNITO_CLIENT_ID: OIDC_CLIENT_ID # Custom environment variables # environment: # LOG_LEVEL: info - -# Unknown fields fail the pipeline. Budgets are set per team in javaBin/registry.