Skip to content

refactor: convert the repository family to Hono sub-apps - #1727

Merged
ColeMurray merged 2 commits into
mainfrom
refactor/hono-pr4-modules
Sep 3, 2026
Merged

refactor: convert the repository family to Hono sub-apps#1727
ColeMurray merged 2 commits into
mainfrom
refactor/hono-pr4-modules

Conversation

@ColeMurray

@ColeMurray ColeMurray commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Rebased onto main after #1724 merged; the diff is this PR alone.

PR 4 of the Hono follow-up series (plan: docs/internal/2026-09-02-control-plane-hono-follow-ups.md in prod). Converts the repository family to Hono sub-apps; 81 of 171 routes are now native.

What changed

Module Routes
repos 4
secrets 6
environments 5
environment-secrets 4
image-builds 8
  • Each module is a Hono sub-app mounted at the catalog position its spread held, so precedence is unchanged.
  • Handlers take the parameters Hono decoded, typed from the path literal, through the dispatch(c, handler) adapter from refactor: convert the sessions cluster to Hono sub-apps #1724. Parameterless handlers keep their three-argument form.
  • Policies are byte-for-byte what defineRoute(s) declared; repeated ones are hoisted into admit() constants.

Decode once (D-B)

The owner/name handlers stop decoding. repositoryParams() (new, routes/repository-params.ts) validates the pair Hono already decoded and answers the same Owner and name must be valid repository path segments 400 as before. No handler in this family calls decodeURIComponent; a segment that does not decode is refused by admission (#1724). The matrix's repo cases (group%2Fsubgroup, web%2Fapp, web%252Fapp) hold without edits.

extractRepoParams stays in routes/shared.ts for the modules PR 6 converts; PR 8 deletes it.

Tests

repos.test.ts, environment-secrets.test.ts, and image-builds.trigger.test.ts now dispatch requests through the production sub-apps (createTestRequestHandler([module]), mocked authenticate, owner authorization database) instead of calling handlers with hand-built match arrays, so a route bound to the wrong handler fails a test. One fixture change: the environment-secrets batch mock returns [] (D1's shape) because the request path goes through the instrumented database, which reads the batch result.

Verification

Check Result
Unit 234 files, 3,495 passed
Integration (workerd, real D1) 96 files, 1,129 passed
Matrix and conformance snapshots byte-identical
Typecheck (tsconfig.json + tsconfig.test.json), ESLint, Prettier clean

https://claude.ai/code/session_01KdDpTgGEjXpBA9SaGQVUH1

Summary by CodeRabbit

  • Refactor

    • Improved consistency and reliability across repository, secret, environment, and image-build request handling.
    • Preserved existing authentication, authorization, validation, and create, read, update, and delete behavior.
    • Improved route validation for repository-related requests, providing clearer handling of invalid repository paths.
  • Tests

    • Updated automated coverage and test infrastructure to better reflect current request-handling behavior.

@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 6 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 28fcd869-7cca-48a9-b060-a5ade7726580

📥 Commits

Reviewing files that changed from the base of the PR and between 99ae138 and 3d3f7a0.

📒 Files selected for processing (4)
  • packages/control-plane/src/routes/repository-params.ts
  • packages/shared/src/types/index.ts
  • packages/shared/src/types/repositories.ts
  • packages/shared/src/types/repository-contracts.test.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 3317c3ae-ae6f-449d-b2af-87b66c0458cf

📥 Commits

Reviewing files that changed from the base of the PR and between 7b561a5 and 99ae138.

📒 Files selected for processing (10)
  • packages/control-plane/src/routes/catalog.ts
  • packages/control-plane/src/routes/environment-secrets.test.ts
  • packages/control-plane/src/routes/environment-secrets.ts
  • packages/control-plane/src/routes/environments.ts
  • packages/control-plane/src/routes/image-builds.trigger.test.ts
  • packages/control-plane/src/routes/image-builds.ts
  • packages/control-plane/src/routes/repos.test.ts
  • packages/control-plane/src/routes/repos.ts
  • packages/control-plane/src/routes/repository-params.ts
  • packages/control-plane/src/routes/secrets.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

The control-plane routes migrated from custom route arrays to typed Hono routers. Handlers now use typed path parameters and shared admission and dispatch helpers. Repository validation moved to repositoryParams. Route tests now send requests through shared test handlers.

Changes

Repository routing

Layer / File(s) Summary
Repository parameter and route migration
packages/control-plane/src/routes/repository-params.ts, packages/control-plane/src/routes/repos.ts, packages/control-plane/src/routes/repos.test.ts
Repository routes use typed owner and name parameters, shared validation, Hono registration, and request-based tests.

Environment and secret routing

Layer / File(s) Summary
Environment and secret route migration
packages/control-plane/src/routes/environments.ts, packages/control-plane/src/routes/environment-secrets.ts, packages/control-plane/src/routes/secrets.ts, packages/control-plane/src/routes/environment-secrets.test.ts
Environment and secret routes use typed Hono parameters, admission policies, and dispatch. Environment-secret tests use the shared request handler and test environment setup.

Image-build routing

Layer / File(s) Summary
Image-build route and test migration
packages/control-plane/src/routes/image-builds.ts, packages/control-plane/src/routes/image-builds.trigger.test.ts
Image-build callbacks and endpoints use typed Hono routing, shared admission policies, repository validation, and background-task test helpers.

Route catalog mounting

Layer / File(s) Summary
Catalog route mounting
packages/control-plane/src/routes/catalog.ts
The catalog registers each migrated route group as an individual entry.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 99ae1

The route migration preserves the existing route catalog and authorization behavior, with no concrete merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.72% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 39 functions across 10 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: converting the repository-family route modules into Hono sub-apps.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/hono-pr4-modules

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Base automatically changed from refactor/hono-pr3-sessions to main September 3, 2026 01:49

@open-inspect open-inspect Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

PR #1727, refactor: convert the repository family to Hono sub-apps, by @ColeMurray converts the repository, secrets, environment, environment-secrets, and image-build route families to admitted Hono sub-apps while preserving route order and policy contracts. Reviewed 10 changed files (+426/-490); the implementation is ready to merge.

Critical Issues

None.

Suggestions

None.

Nitpicks

None.

Positive Feedback

  • dispatch keeps decoded parameter types tied to each path literal, reducing wrong-handler wiring risk at compile time.
  • repositoryParams preserves the decode-once contract, including nested owners and rejection of decoded slashes in repository names.
  • The updated tests exercise production sub-app dispatch and admission rather than invoking handlers through hand-built matches.

Questions

None.

Verification

  • Control-plane unit suite: 234 files, 3,495 tests passed.
  • Relevant workerd integration suites: 2 files, 18 tests passed.
  • Control-plane typecheck and lint passed.
  • git diff --check passed.

Verdict

Approve: No blocking or non-blocking findings.

Repos, secrets, environments, environment secrets, and image builds
register their 27 routes as Hono sub-apps mounted at the catalog
positions the spreads held, so precedence is unchanged. Handlers take
the parameters Hono decoded, typed from the path, through the
`dispatch(c, handler)` adapter; parameterless handlers keep their
three-argument form.

The owner/name handlers stop decoding. `repositoryParams()` validates
the pair Hono already decoded and answers the same 400 as before, and
no handler in this family calls `decodeURIComponent` any more;
admission refuses a segment that does not decode.

The repos, environment-secrets, and image-build trigger suites now
dispatch requests through the production sub-apps instead of calling
handlers with hand-built match arrays, so a route bound to the wrong
handler fails a test. Both integration snapshots are unchanged.

Claude-Session: https://claude.ai/code/session_01KdDpTgGEjXpBA9SaGQVUH1
@ColeMurray
ColeMurray force-pushed the refactor/hono-pr4-modules branch from c14e995 to 99ae138 Compare September 3, 2026 01:53
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Terraform Validation Results

Step Status
Format
Init
Validate
Tests

Note: Terraform plan was skipped because secrets are not configured. This is expected for external contributors. See docs/GETTING_STARTED.md for setup instructions.

Pushed by: @ColeMurray, Action: pull_request

@open-inspect open-inspect Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep code-quality audit completed against the current rebased head (99ae138).

No blocking or non-blocking findings. This conversion removes more code than it adds, keeps every affected file below 1,000 lines, preserves catalog precedence and admission policies, and strengthens the changed tests by exercising the production Hono routing boundary instead of hand-built matcher arrays. The repository parameter helper is narrow and preserves the decode-once invariant without leaking Hono concerns into shared repository identity utilities.

Verification: reviewed all 10 changed files and surrounding admission, route-contract, repository identity, and test-support code; git diff --check is clean; GitHub unit, integration, typecheck, lint, web, and bot checks pass.

… module

Review follow-up. `repositoryParams()` re-implemented the pair
round-trip check that `decodeRepositoryPathSegments` embeds, leaving two
owners of a subtle rule (a nested owner is valid, a slash in a name is
not). `validateRepositoryPathSegments(owner, name)` now holds it once in
the shared package; the decoder decodes and delegates, and the route
adapter only maps null to the 400. The decoded and nested-owner cases
join the shared contract tests.

Claude-Session: https://claude.ai/code/session_01KdDpTgGEjXpBA9SaGQVUH1
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Terraform Validation Results

Step Status
Format
Init
Validate
Tests

Note: Terraform plan was skipped because secrets are not configured. This is expected for external contributors. See docs/GETTING_STARTED.md for setup instructions.

Pushed by: @ColeMurray, Action: pull_request

@ColeMurray

Copy link
Copy Markdown
Owner Author

Carried the shared-validator commit from #1729 here as 3d3f7a0: repositoryParams() now delegates to validateRepositoryPathSegments() in the shared identity module instead of restating the pair rule. Verified on this branch: typecheck, unit, and the admission matrix, snapshots unchanged.

@ColeMurray
ColeMurray merged commit 389eddc into main Sep 3, 2026
13 checks passed
@ColeMurray
ColeMurray deleted the refactor/hono-pr4-modules branch September 3, 2026 02:59
ColeMurray added a commit that referenced this pull request Sep 3, 2026
Last PR of the Hono series (#1720, #1721, #1723, #1724, #1726, #1727,
#1728, #1729). Every route module is a Hono sub-app, so the adapter that
carried catalog routes through admission has nothing left to serve.

## Removed

- `legacy()` and `legacyMatch()` in `routing/hono-app.ts`;
`createControlPlaneApp(modules, host)` mounts modules only.
- `RouteDefinition`, `Route`, `defineRoute()`, `defineRoutes()`, and
`extractRepoParams()` in `routes/shared.ts`. `RouteAdmissionPolicy` is
now an interface over `RoutePolicy` plus `authorization` and
`serviceActorClaims`; `cacheControl` lives on `AdmissionPolicy` in
`routing/admit.ts`.
- `RouteCatalogEntry`; the catalog is `readonly RouteModule[]`.
- `legacyRoutes()` in test support; `matchRoute()` no longer fabricates
a `RegExpMatchArray`.
- `routes/shared.test.ts`, replaced by
`routes/repository-params.test.ts` over the decoded pair.

## Kept on purpose

- `RouteParams`: admission's decoded-parameter dictionary. Hono exports
no such type.
- `rawRouteParams()`: the malformed-encoding guard's raw read-back
(added in #1724).

## Tests

Fixtures that need synthetic routes build a `Hono` module and pass it to
`createTestRequestHandler([module])`: the lifecycle suite, the contract
lister's suite, and the authorization-audit suite's eleven routes. The
two Worker-boundary suites build their shadow catalogs the same way:
conformance echoes the raw read-back through `rawRouteParams()`, and the
matrix's "raw path segments" probe from #1720 is now the decode-once
assertion on what handlers receive (`abc%2Fdef` arrives as `abc/def`,
`web%252Fapp` as `web%2Fapp`).

## Verification

| Check | Result |
|---|---|
| Typecheck (src, test, integration) | clean |
| ESLint, Prettier | clean |
| Unit | 234 files, 3,512 passed |
| Integration (workerd, real D1) | 96 files, 1,129 passed |
| Matrix and conformance snapshots | byte-identical |

https://claude.ai/code/session_01KdDpTgGEjXpBA9SaGQVUH1


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Bug Fixes**
- Repository paths now support nested owner namespaces, such as
`group/subgroup`.
- Repository names containing slash characters are rejected with a clear
validation message.
- URL path parameters are decoded consistently, improving handling of
encoded repository and member identifiers.

- **Refactor**
- Control-plane routing now uses the current route-module system,
providing consistent admission, route matching, and request handling
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant