fix(codegen/hetzner): list filters, unique image names, id-targeted image methods (swamp-club #2725, #2731) #373

Merged
stack72 merged 1 commit from 2725 into main 2026-09-29 21:21:38 +00:00
Owner

Fixes swamp-club #2725 and #2731.

Problem

@swamp/hetzner-cloud/images list was unusable against a real project:

  1. It sent no type filter, so GET /images returned Hetzner's whole public catalog with no way to scope to snapshots/backups.
  2. It named each state instance after image.name alone. Public images repeat a name across CPU architectures (x86 and arm ubuntu-24.04), so the run failed output validation with Duplicate data instance name.

Adjacent (#2731): images has no name global argument, so update and change_protection looked for state under current while get/adopt wrote it under the image name — adopt then update failed with "No data found".

Changes (all in the Hetzner codegen; model/hetzner-cloud is regenerated)

  • pipeline: extractListFilters reads each collection GET's query parameters from the spec, dropping page/per_page/sort/label_selector. A NON_UNIQUE_NAME_RESOURCES allowlist (only images) marks resources whose names repeat.
  • lib: listAll/request send array query params as repeated keys (type=snapshot&type=backup).
  • generator: every list gains one typed optional argument per spec filter (e.g. images type, architecture, status; servers name, status). Images name state <name>-<id> (or <id> when unnamed) in get/adopt/list.
  • generator (#2731): resources whose naming field is not a global argument (images) take an id in update/change_protection/delete and name state from the API response; delete reads first so its record lands on the same instance.
  • Design doc (codegen/designs/hetzner.md) and generated README updated. @swamp/hetzner-cloud → 2026.09.29.2.

⚠️ Behaviour change for images

Images get and adopt now store state under <name>-<id> (e.g. ubuntu-24.04-101) instead of the bare name. Image state written earlier under the bare name is left in place, not migrated, and anything referencing it by that name must be updated. Images update/change_protection now require an id argument (they never worked on adopted images before). No other model's naming changes.

Testing

  • New pipeline_test.ts (filter extraction), generator tests (images vs servers output), listAll repeated-param test, and an images integration test on the mock Hetzner API (duplicate x86/arm names across pages + unnamed snapshot → three instances; repeated type params; adopt/update/change_protection/delete converge on one instance).
  • Regeneration is idempotent (second run: zero diff); upgrade path from the published version verified.
  • Not exercised against the live Hetzner API.

Verification: verify-build 11/11, verify-reviews 2 passed + ci-security-review skipped (no trust-root changes); attestation posted for a63840684.

🤖 Generated with Claude Code

Fixes swamp-club #2725 and #2731. ## Problem `@swamp/hetzner-cloud/images` `list` was unusable against a real project: 1. It sent no `type` filter, so `GET /images` returned Hetzner's whole public catalog with no way to scope to snapshots/backups. 2. It named each state instance after `image.name` alone. Public images repeat a name across CPU architectures (x86 and arm `ubuntu-24.04`), so the run failed output validation with `Duplicate data instance name`. Adjacent (#2731): images has no `name` global argument, so `update` and `change_protection` looked for state under `current` while `get`/`adopt` wrote it under the image name — `adopt` then `update` failed with "No data found". ## Changes (all in the Hetzner codegen; `model/hetzner-cloud` is regenerated) - **pipeline**: `extractListFilters` reads each collection GET's query parameters from the spec, dropping `page`/`per_page`/`sort`/`label_selector`. A `NON_UNIQUE_NAME_RESOURCES` allowlist (only `images`) marks resources whose names repeat. - **lib**: `listAll`/`request` send array query params as repeated keys (`type=snapshot&type=backup`). - **generator**: every `list` gains one typed optional argument per spec filter (e.g. images `type`, `architecture`, `status`; servers `name`, `status`). Images name state `<name>-<id>` (or `<id>` when unnamed) in `get`/`adopt`/`list`. - **generator (#2731)**: resources whose naming field is not a global argument (images) take an `id` in `update`/`change_protection`/`delete` and name state from the API response; `delete` reads first so its record lands on the same instance. - Design doc (`codegen/designs/hetzner.md`) and generated README updated. `@swamp/hetzner-cloud` → `2026.09.29.2`. ## ⚠️ Behaviour change for images Images `get` and `adopt` now store state under `<name>-<id>` (e.g. `ubuntu-24.04-101`) instead of the bare name. Image state written earlier under the bare name is left in place, not migrated, and anything referencing it by that name must be updated. Images `update`/`change_protection` now require an `id` argument (they never worked on adopted images before). No other model's naming changes. ## Testing - New `pipeline_test.ts` (filter extraction), generator tests (images vs servers output), `listAll` repeated-param test, and an images integration test on the mock Hetzner API (duplicate x86/arm names across pages + unnamed snapshot → three instances; repeated `type` params; adopt/update/change_protection/delete converge on one instance). - Regeneration is idempotent (second run: zero diff); upgrade path from the published version verified. - Not exercised against the live Hetzner API. Verification: verify-build 11/11, verify-reviews 2 passed + ci-security-review skipped (no trust-root changes); attestation posted for `a63840684`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(codegen/hetzner): list filters, unique image names, id-targeted image methods (swamp-club #2725, #2731)
All checks were successful
CI / Review Integrity (pull_request) Successful in 57s
CI / Validate Attestation (pull_request) Successful in 58s
a63840684b
Hetzner list methods only offered label_selector, so images list returned
the whole public catalog, and named each state instance after the image
name alone, which repeats across CPU architectures and failed output
validation with duplicate instance names.

- pipeline: extractListFilters reads each collection GET's spec query
  params (dropping page/per_page/sort/label_selector); a
  NON_UNIQUE_NAME_RESOURCES allowlist (images) marks nameUnique false
- lib: listAll/request send array query params as repeated keys
- generator: list emits one typed optional argument per filter; images
  name state <name>-<id> (or <id> when unnamed) in get/adopt/list
- generator (#2731): resources whose naming field is not a global
  argument (images) take an id in update/change_protection/delete and
  name state from the API response; delete reads first so its record
  lands on the same instance
- tests: extractListFilters, repeated array params, generator output for
  images vs servers, and an images integration test on the mock API
- docs: hetzner design doc and generated README; regenerated
  model/hetzner-cloud (2026.09.29.2)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
stack72 deleted branch 2725 2026-09-29 21:21:38 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
swamp-club/swamp-extensions!373
No description provided.