Repository navigation
fix(cli): make init scaffolds build, add repo to team before push, fix register/secret/status - #9
Merged
Merged
Conversation
…x register/secret/status - init: each runtime writes a minimal app (pom.xml/Gradle/package.json/ requirements.txt/go.mod + source) that serves /health on the chosen port; Dockerfiles need no mvnw/gradlew/lockfile and run as uid 1000 writing only /tmp. Adds the repo to the app.yaml team before pushing; on 403/404 stops with the maintainer command and git push. No routing.priority. - register-team: serialise teams/<name>.yaml with yaml.v3, first member is role: maintainer, print the PUT form of the team-repo command. - secret: point at javabin-team-<team>, default a missing name to the repo name and explain invalid (dotted) names with a suggestion. - status: use LoadConfigForTeam and show costs as USD with ~NOK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Alexanderamiri
added a commit
to javaBin/platform
that referenced
this pull request
Oct 31, 2026
…me, validate compute (#181) ## Problem - **ALB priority collisions (finding 1).** app-template ships `routing.priority: 100`, which cupcake (frosting) already holds. jz-watch run 40079243698 failed at apply with `CreateRule PriorityInUse: Priority '100' is currently in use`. `routing.login` rules take the numbers directly below `routing.priority`, so nearby picks collide too. The docs said to "coordinate via the registry", but the registry has nothing for priorities, and nothing checked them before apply. - **`name` default was inconsistent (part of finding 13).** Only the generator fell back to the repo name. detect.yml emitted `app_name=""`, the CLI rejects a missing name, and a repo name like `2027.javazone.no` fails `NAME_RE` anyway. - **Compute values were not validated (part of finding 14).** An invalid Fargate cpu/memory pair, port or desired_count only failed at apply. ## Change - `scripts/generate-modules.py` - `routing.priority` is optional. When it is left out, `derived_priority(team, name)` takes sha256 of `team/name` and maps it to one of 4454 slots of 11 in 1000-50000. The host rule sits at the top of its slot and up to 10 login rules sit below it, inside the same slot. The value is printed as a `::notice`. `domain:` no longer needs a priority. - An explicit `routing.priority` must be 1-999, so it can never land in the derived range. Explicit values are passed through unchanged. - `name` is required, with a clear message. The message for a dotted name gives an example fix (`2027.javazone.no` becomes e.g. `javazone-2027`). The `APP_SERVICE` repo-name fallback is removed. - `compute.cpu` and `compute.memory` must be whole numbers and a valid Fargate task size; the error lists the memory values allowed for that cpu. `port` must be 1-65535 and `desired_count` 0 or more. - New `scripts/check-alb-priorities.py`, run in tf-plan after the plan when it has changes, using the team's read-only plan credentials (`ReadOnlyAccess` covers `elbv2:DescribeRules`). It takes every `aws_lb_listener_rule` the plan creates or moves and compares its priority with the live rules on that listener. - Priorities the plan frees in the same run (delete-then-create, or the app's own rule moving) count as free. - On a conflict it fails with `::error`, naming the host that holds the priority and suggesting the lowest free number that leaves 10 free below it. - If the plan or the live rules cannot be read, it only warns, because apply still catches a conflict. - `detect.yml` fails when `app.yaml` has no `name`. `expand-terraform.yml` no longer passes `APP_SERVICE`. - Docs: `docs/app-yaml-reference.md` (name, compute table, routing.priority, login priorities, domain), `docs/reusable-workflows.md` and `CLAUDE.md`. ## No rule churn These are the live rules on `javabin-platform-alb`:443: | Priority | Host | |---|---| | 10 | password | | 100 | cupcake | | 101 | cupcake-backend | | 150 | watch | | 200 | 2027 | | 900 | test | Every app.yaml in the org (cupcake, frosting, jz-watch, 2027.javazone.no, platform-test-app, app-template) sets `name` and an explicit priority below 1000. Their generated priorities are unchanged; I checked by generating each app.yaml from GitHub with this branch. ## Verification - `python3 -m unittest discover -s scripts/tests`: 153 tests OK, including new tests for name, priority range, derived priority (stability, range, room for 10 login rules, `domain:`), compute validation, and `test_check_alb_priorities.py`. - `python3 -m unittest discover -s terraform/lambda-src/tests`: 219 tests OK. - Ran the check against the live listener rules (read-only `describe-rules`): - priority 100 is reported as held by `cupcake.javazone.no`, with suggestion 21; - the derived priority for cupcake/cupcake-backend (2297) passes. - `actionlint` on the changed workflows: the only finding is the existing SC2129 style note in detect.yml. ## Follow-ups (other repos) - javaBin/app-template#4 drops `priority: 100` from the template `app.yaml` (merge after this PR). - javaBin/javabin-cli#9 removes the priority prompt from `javabin init` (no `priority` written, so new apps take the derived one). - `docs/getting-started.md` in javaBin/docs still shows `priority: 120`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Findings 2, 5, 13 and 14 from the developer-experience audit:
./mvnw/./gradlew/pnpm install --frozen-lockfile/pip install -r requirements.txt, but init never wrote those files, so no scaffold could build. init also pushed tomainbefore telling the user to add the repo to the team, so the broker rejected the first pipeline run. It also prompted for a fixedrouting.priority.role:, so no member became a GitHub team maintainer able to add repos. It printed a team-repo endpoint that doesn't exist (gh api orgs/javaBin/teams/TEAM/repos -f owner=... -f repo=...). And it wrotedescription:unquoted, so a:or#broke the YAML.javabin-developer. That role can't reach team parameters: its policy keys onaws:PrincipalTag/team, and no Identity Center user hasenterprise.teamset (checked in live AWS). Also, a missingname:was a flat error. Dotted repo names are common (2023–2027.javazone.no,java.no), and the pipeline defaultsnameto the repo name and then rejects it.LoadConfig, notLoadConfigForTeam, so it failed afterjavabin aws setupunlessAWS_PROFILEwas set. It also printed costs as$while team budgets are NOK.Change
cmd/scaffold.go(new): each runtime writes a minimal app that needs no wrapper scripts or lockfiles:pom.xml+ JDK HttpServerbuild.gradle.ktsnpm install+tschttp.server+requirements.txtnet/http+go.modEach app serves
GET /healthon the chosen port (ENV PORT/EXPOSEset to it) and runs asUSER 1000. Nothing writes outside/tmp(python setsPYTHONDONTWRITEBYTECODE). Each also gets a.dockerignore.cmd/init.go: commits locally, then adds the repo to the team withPUT orgs/javaBin/teams/<team>/repos/javaBin/<repo>(gh.AddRepoToTeam), and only then pushes. On 403/404 it stops before pushing and explains why: the user isn't a team maintainer or org owner, or the team doesn't exist yet. It prints thegh api -X PUT ...command for a maintainer andcd <repo> && git push. The priority prompt is gone andapp.yamlno longer setsrouting.priority.cmd/register.go:teams/<name>.yamlis now written with yaml.v3. The first member getsrole: maintainer, and the budget is checked to be a whole number before confirming. The post-PR hint uses the PUT form.cmd/secret.go: the help text points atjavabin-team-<team>. Whenname:is missing, the CLI uses the repo name (from the origin remote, or the directory name), the same as the pipeline. If the name isn't a valid app name (the platform'sNAME_RE), it fails with a suggestion, for examplename: javazone-no-2027for2027.javazone.no.cmd/status.go: usesLoadConfigForTeam(team). Costs print as$12.34 (~130 NOK), using the same 10.5 rate as the platform'sshared/constants.pyUSD_TO_NOK(which the cost reports use too).README and CLAUDE.md are updated to match.
Verification
go build ./...,go vet ./...andgo test ./...all pass.COPYsource is written by the scaffold, there's no mvnw/gradlew,USER 1000/PORT/EXPOSEare set, and no placeholders are left:and#in the description, plus the maintainer roleAddRepoToTeamagainst httptest (PUT path and body; 403/404 returnErrNoTeamAccess)sanitizeAppName, the defaulted and dotted repo-name cases, andformatCostJAVABIN_SCAFFOLD_DOCKER=1 go test ./cmd -run TestScaffoldImagesServeHealth -count=1built all 5 images locally and ran each one the way ECS does (--user 1000 --read-only --tmpfs /tmp).GET /healthreturned 200 for all five. This test is opt-in because it needs Docker and network.javabin-team-cupcakeallowsce:GetCostAndUsageandecs:ListServices, sostatusworks with the team profile. Thejavabin-developerpolicy is ABAC onPrincipalTag/team, and no identity-store user hasenterprise.team.Notes for reviewers
routing.priority.generate-modules.pyon platformmainstill rejectsroutingwithoutpriority, so until that change merges, apps scaffolded by this CLI failexpand.javaBin/registryREADME line 24 still has the old team-repo command. It's out of scope for this PR.🤖 Generated with Claude Code