Skip to content

feat(build)!: compile with the TypeScript 7 native compiler - #11793

Open
raymondfeng wants to merge 9 commits into
masterfrom
upgrade-typescript-7
Open

raymondfeng wants to merge 9 commits into
masterfrom
upgrade-typescript-7

Conversation

@raymondfeng

@raymondfeng raymondfeng commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Upgrades the monorepo to TypeScript 7, using the side-by-side install recommended for TypeScript 7:

"@typescript/native": "npm:typescript@~7.0.2",
"typescript": "npm:@typescript/typescript6@~6.0.2"

Stacked PR. Per review, this PR was split. It builds on #11811 (typescript-eslint v8) and #11810 (mock-oauth2-provider CodeQL fix), whose commits appear here until they merge. The .yo-rc.json bug is fixed separately in #11812. Merge order: #11810 → #11811 → this PR. Only the last three commits belong to this PR.

TypeScript 7 no longer ships the JS compiler API: its exports["."] resolves to lib/version.cjs. So anything that introspects the compiler (@typescript-eslint, editor language services, tsserver) needs the API that @typescript/typescript6 still provides. The two packages declare different bin names (tsc vs tsc6), so they don't collide.

packages/build/package.json is the source of truth. bin/sync-dev-deps propagates the spec to every workspace package, and bin/update-template-deps carries it into the lb4 scaffolding templates.

A cold build of the monorepo drops from ~10.7s to ~2.1s.

Commits

  1. feat(build)!: the toolchain, tsconfig.common.json, and the README. This is the only commit with BREAKING CHANGE:, so lerna's conventional-commit bump makes a major release of @loopback/build only.
    • @typescript/native is a hard dependency of @loopback/build, and lb-tsc always compiles with TypeScript 7. It prefers the project's own @typescript/native over the one @loopback/build depends on. The fallback to typescript/lib/tsc was unreachable and has been removed.
    • bin/sync-dev-deps.js had been broken since the Lerna → npm workspaces migration (d5c4994 removed loadLernaRepo). It's repaired using the @npmcli/map-workspaces pattern already used by update-template-deps.js.
  2. feat(cli): generated projects target TypeScript 7 and drop moduleResolution: node. The template's mocha moves to ^12; update-template-deps syncs it with the monorepo, which already uses mocha 12.
  3. fix:: the source changes TypeScript 6/7 requires, and the typescript alias in every package.

TypeScript 6/7 changes that required source updates

  • moduleResolution: node (node10) was removed. tsconfig.common.json now sets "moduleResolution": "bundler" explicitly, which is the TypeScript 6 default. With module: commonjs it resolves exports maps using the require and types conditions. Because the resolver honors exports, @loopback/graphql no longer imports Middleware from a deep type-graphql path (that path isn't exported) and declares the type itself.
  • @types/* packages are no longer auto-included. This accounted for 5630 of the 5668 initial errors (describe, process, NodeJS all unresolved). tsconfig.common.json now lists types: ["node", "mocha"].
  • Reading a parent class field through super is an error (TS2855). cron declares fireOnTick as a field but installs it on the prototype, so @loopback/cron now calls it through BaseCronJob.prototype.
  • Declaration emit no longer adds /// <reference path> for ambient files. TypeScript 5.2 emitted one into testlab/dist/expect.d.ts, which is how consumers resolved the global Internal type. Without it, expect silently becomes any in every consuming package, and api-extractor fails with Unable to follow symbol for "Internal". So should-as-function.d.ts moves to src/should-as-function.ts and exports its types as a module.
  • Non-portable inferred types (TS2883). GRAPHQL_CONTEXT_RESOLVER gets an explicit type. Otherwise declaration emit has to name ContextFunction by its path inside @apollo/server.

With TypeScript 6 type information, typescript-eslint reports more findings:

  • Async Express handlers in @loopback/rest and the rpc-server example now pass rejections to next.
  • transactions.suite.ts awaits disconnect().
  • ?? replaces || on objects and arrays. || is kept wherever the operand may be '' (see feat(eslint-config)!: upgrade typescript-eslint to v8 #11811 for the ignorePrimitives rationale).

Defects found along the way

  • belongs-to-repository-factory.unit.ts never assigned companyRepo. Its stub helper assigned customerRepo twice, clobbering the previous beforeEach.
  • The todo-list repository integration tests used repositories they never created.

Verification

Check Result
Cold build (TS 7.0.2) clean
npm run lint (eslint + prettier) clean
@loopback/build tests 21 passing
npm run mocha 4492 passing; the 220 failures are identical to #11811 (TypeScript 5.2)

The 220 failures don't come from this change:

  • Most are packages/cli generator tests. They refuse to prompt when stdin isn't a TTY, so they fail in a non-interactive shell.
  • Two are the todo geocoder tests, whose fixtures don't match the live geocoder's current coordinates.

Checklist

  • DCO (Developer Certificate of Origin) signed in all commits
  • npm test passes on your machine: see Verification
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

🤖 Generated with Claude Code

Comment thread fixtures/mock-oauth2-provider/src/mock-oauth2-social-app.ts Fixed
Comment thread fixtures/mock-oauth2-provider/src/mock-oauth2-social-app.ts Fixed

@samarpanB samarpanB 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.

Thanks for this, the TS 6/7 investigation and the write-up are really thorough, and the build speedup is great.

My main concern is scope and semver. The PR bundles four independent changes: the TS 7 toolchain, typescript-eslint v8, ~60 ||→?? / ??= rewrites in framework code, and an unrelated CodeQL fix in the mock OAuth2 fixture. Two of them are breaking for downstream users but land under a non-breaking feat(build).

Blocking

  1. @typescript/native is a hard dependency of @loopback/build, so the "fall back to typescript when TS 7 isn't installed" path is never reached for consumers. Any app pinned to TS 5.x gets compiled by TS 7 on a minor bump (see inline). This needs feat(build)! + BREAKING CHANGE:, or the native compiler should be opt-in.
  2. @loopback/eslint-config → typescript-eslint v8 is also breaking for consumers (different peer ranges, new/renamed rules). It needs a major bump too.
  3. packages/cli/.yo-rc.json is regenerated with every generator's arguments emptied (see inline).

Suggest splitting out

  • The ||→?? conversions. Most are equivalent, but several change behavior when a value is '' in core packages (inline examples in context, core, boot; also extension-point.ts, inject-config.ts, controller-route.ts, build-schema.ts, repository.mixin.ts, lb3app.booter.ts restApiRoot). They may all be improvements, but they deserve their own refactor/fix PR. Here, the prefer-nullish-coalescing options (ignorePrimitives, ignoreTernaryTests, ignoreIfStatements) could keep this PR behavior-neutral.
  • The fix(mock-oauth2-provider) commit. The fix looks right, but it's unrelated to the TS upgrade.

Minor

  • try-catch-finally.unit.ts: three eslint-disable-next-line comments were replaced by blank lines. The lines can just be removed.
  • graphql/keys.ts: a short comment on why the explicit BindingKey<...> annotation on GRAPHQL_CONTEXT_RESOLVER is needed would help.
  • lb-ttsc / --use-ttypescript is now effectively TS 6-only. Worth a README note or a deprecation.
  • The PR currently has merge conflicts with master.

Looks good: the duplicate route() overload removal, the should-as-function move (nice catch on expect silently becoming any), the cron fireOnTick fix, the sync-dev-deps.js repair, and the test fixes in belongs-to / todo-list / transactions.suite.

"@loopback/eslint-config": "^16.0.1",
"@types/mocha": "^10.0.10",
"@types/node": "^20.19.43",
"@typescript/native": "npm:typescript@~7.0.2",

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.

Because this is a runtime dependency of @loopback/build, resolveNativeTsc() will always find it, via the __dirname entry in paths in compile-package.js. So the typescript/lib/tsc fallback described in the README/PR is unreachable for anyone who installs @loopback/build.

Before this PR, resolveCLI('typescript/lib/tsc') preferred the project's own typescript. Now an app pinned to TS 5.x, or one with "moduleResolution": "node" or extra global @types/* in its own tsconfig, is silently compiled by TS 7 and breaks on a minor version bump.

Either mark this as breaking (feat(build)! + BREAKING CHANGE: footer) or make @typescript/native opt-in (optional/peer dependency) so the fallback actually applies.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Went with marking it breaking. The commit is now feat(build)! with a BREAKING CHANGE: footer, and it only touches @loopback/build, so lerna major-bumps that package alone. @typescript/native stays a hard dependency, and the unreachable typescript/lib/tsc fallback is removed.

Comment thread packages/build/bin/compile-package.js Outdated
function resolveNativeTsc() {
try {
const manifest = require.resolve('@typescript/native/package.json', {
paths: [utils.getPackageDir(), __dirname],

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.

Related to the package.json comment: __dirname here resolves @loopback/build's own copy of @typescript/native, which is always installed. If the fallback is meant to be reachable, only the project's getPackageDir() should be searched, or the dependency needs to be optional.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The fallback is removed. resolveNativeTsc() still searches getPackageDir() before __dirname, so a project can pin its own @typescript/native; otherwise the copy @loopback/build depends on is used. README updated to match.

"dependencies": {
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@typescript-eslint/eslint-plugin": "^8.70.0",

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.

typescript-eslint v7 → v8 is a breaking change for consumers of @loopback/eslint-config (peer ranges for typescript/eslint, renamed/split rules, and stricter prefer-nullish-coalescing defaults that will start flagging their code). I think this needs a major bump and a BREAKING CHANGE: note, ideally in its own commit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Split into #11811 as feat(eslint-config)! with a BREAKING CHANGE: footer. The lint fixes are in separate commits, so only @loopback/eslint-config gets the major bump.

"types": ["node", "mocha"],

"lib": ["es2020"],
"module": "commonjs",

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.

Nit: with moduleResolution removed, TS 6/7 default to Bundler. I checked that with module: commonjs both resolve in CJS mode with the require/types conditions, so it behaves correctly. Since every downstream app inherits this file, though, I'd set "moduleResolution": "bundler" explicitly (or mention the default in the README section) rather than rely on an implicit default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Set explicitly: "moduleResolution": "bundler", with a comment on the require/types conditions under module: commonjs. The README is updated too. Since @loopback/build now requires TypeScript 6+, the TS 5 incompatibility of bundler + commonjs no longer matters.

Comment thread packages/cli/.yo-rc.json Outdated
"name": "name"
}
],
"arguments": [],

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.

This regeneration empties arguments for every generator. The cause is an existing bug in packages/cli/lib/cli.js: if (!gen) { for (const arg of gen._arguments) ... } never runs.

Tab completion only reads options, so users won't notice. But test/integration/cli/cli.integration.js ("saves command metadata to .yo-rc.json") snapshots this file, and the snapshot still has the full arguments, so that test now fails at the snapshot step instead of the "up to date" step. Since the PR notes this file is stale regardless of the change, I'd revert it here, and separately fix if (!gen) → if (gen) and regenerate the file and snapshot together.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reverted here. The if (!gen) bug is fixed in #11812, which also brings the stale snapshot up to date. The committed .yo-rc.json turned out to be correct; with the fix, lb4 --meta reports it as up to date.

}
const user = users[0];
if (!user.credentials || user.credentials.password !== password) {
if (user.credentials?.password !== password) {

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.

This weakens the check slightly: if user.credentials is missing and password is undefined, undefined !== undefined is false and authentication passes. Passport normally hands over a string, so it's likely not reachable today, but this is example auth code people copy. I'd keep the explicit !user.credentials || guard (and disable the lint rule on this line if needed).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Restored !user.credentials || with a scoped eslint-disable-next-line @typescript-eslint/prefer-optional-chain and a comment explaining why (in #11811).

}
const user = users[0];
if (!user.credentials || user.credentials.password !== password) {
if (user.credentials?.password !== password) {

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.

Same concern as in basic.ts: please keep the explicit !user.credentials guard in auth code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same as basic.ts: guard restored (in #11811).

code: authCode,
});
// redirect to call back url with the access code
const callbackUrl = parseRedirectUri(req.body.redirect_uri);

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.

Small ordering point: the token is stored before redirect_uri is validated, so a rejected (400) request still leaves an issued token in tokens/issuedTokens. Validating redirect_uri first would avoid that. Also, since this commit is unrelated to the TS upgrade, it might be easier to review and land as its own PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved to #11810, where redirect_uri is now validated before the token is created and stored. This PR carries that commit until #11810 merges, because TypeScript 6 lint needs its async handler wrapper.

Comment thread packages/cli/package.json
"debug": "^4.4.3",
"fs-extra": "^11.4.0",
"mocha": "^11.8.0",
"mocha": "^12.0.1",

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.

The template mocha bump from ^11.8.0 to ^12.0.1 looks unrelated to the TS upgrade. Was it picked up by update-template-deps? Worth calling out in the description, or dropping.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It came from update-template-deps: master already uses mocha ^12.0.2 (renovate), and the template was still on ^11.8.0. This is now noted in the feat(cli) commit message and the PR description.

result.host = undefined;
}
// Set it to '' so that the http server will listen on all interfaces
result.host ??= undefined;

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.

Nit: result.host ??= undefined only turns null into undefined, and the comment above still says "Set it to ''". Either note that the null → undefined conversion is intended or drop the line and its comment. The same pattern appears in extensions/socketio/src/socketio.server.ts.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The comment now says: "Normalize a null host to undefined so that the http server listens on all interfaces". Updated in both rest.server.ts and socketio.server.ts.

raymondfeng and others added 7 commits October 1, 2026 21:01
typescript-eslint v7 does not support TypeScript 6 or later, so it blocks the
TypeScript upgrade.

Rules that v8 renamed or split are disabled to keep the rule set this
configuration already had: `no-require-imports` replaces `no-var-requires`, and
`ban-types` is split into `no-empty-object-type`, `no-unsafe-function-type` and
`no-wrapper-object-types`.

`prefer-nullish-coalescing` now ignores primitive operands. The rule runs
without `strictNullChecks`, so it cannot tell whether a `string`, `number` or
`boolean` operand may be nullish, and v8 reports `||` on such operands, where
switching to `??` changes the result for `''`, `0` and `false`.

BREAKING CHANGE: `@loopback/eslint-config` requires `@typescript-eslint/parser`
and `@typescript-eslint/eslint-plugin` v8. Projects using it can get new
findings, such as unused `catch` bindings (`no-unused-vars`),
`prefer-optional-chain`, and `prefer-nullish-coalescing` for
`if (x == null) x = y`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
- Drop unused `catch` bindings (`no-unused-vars`).
- Use optional chains where they are equivalent (`prefer-optional-chain`).
- Use `??=` for `if (x == null) x = y` and for `!x` guards on values that are
  objects or arrays, where it is equivalent (`prefer-nullish-coalescing`).
- Remove the `route()` overload that `RestApplication` declared twice
  (`unified-signatures`).
- Remove `eslint-disable` directives that no longer suppress anything.

`||` is kept wherever the left operand may be `''` or `0`. The passport-login
example keeps its explicit `!user.credentials` guard, since
`user.credentials?.password !== password` accepts a user without credentials
when `password` is `undefined`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
…n redirect

Registered apps and issued tokens were held in plain objects keyed by values
taken from the request, so a `__proto__` key reached `Object.prototype`. They
are `Map`s now, which also drops the `[key: string]: any` index signature from
the `App` interface (CodeQL js/prototype-polluting-assignment).

`redirect_uri` is validated before a token is issued and the callback url is
built from the parsed `URL` rather than by concatenating the request value. A
real authorization server matches `redirect_uri` against the callback urls
registered for the client; this provider only ever serves test applications
running on the same machine, so it accepts loopback hosts
(CodeQL js/server-side-unvalidated-url-redirection).

The async route handlers are wrapped so that rejections reach Express instead
of becoming unhandled promise rejections.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
Install TypeScript side by side, as recommended for TypeScript 7: `typescript`
is aliased to `@typescript/typescript6` so that tools consuming the JS compiler
API keep working, and `@typescript/native` provides the native compiler that
`lb-tsc` runs. A cold build of the monorepo drops from ~10.7s to ~2.1s.

`lb-tsc` prefers the `@typescript/native` installed by the project being built
over the one `@loopback/build` depends on. `lb-ttsc` keeps using the JS
compiler, since `ttypescript` patches the compiler API.

`tsconfig.common.json` changes for TypeScript 6/7:

- `moduleResolution: node` (node10) was removed. The config sets
  `moduleResolution: bundler`, the TypeScript 6 default, which resolves
  `exports` maps with the `require` and `types` conditions for
  `module: commonjs`.
- `@types/*` packages are no longer included automatically, so the config lists
  `types: ["node", "mocha"]`.

BREAKING CHANGE: `@loopback/build` depends on TypeScript 7
(`@typescript/native`) and compiles with it, and its `typescript` dependency
is TypeScript 6.
Projects extending `@loopback/build/config/tsconfig.common.json` have to remove
`moduleResolution: node`, and list ambient type packages other than `node` and
`mocha` in `types`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
Generated projects depend on TypeScript 7 (`@typescript/native`) and on
TypeScript 6 as `typescript`, and no longer set `moduleResolution: node`, which
TypeScript 7 removed.

The template's `mocha` moves to `^12` as well. `update-template-deps` syncs it
with the monorepo, which already uses mocha 12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
Packages depend on TypeScript 6 as `typescript`, matching `@loopback/build`.

Source changes required by TypeScript 6/7:

- The default resolver for `module: commonjs` honors `exports` maps, so
  `@loopback/graphql` no longer imports `Middleware` from a deep `type-graphql`
  path and declares it instead. `GRAPHQL_CONTEXT_RESOLVER` gets an explicit
  type, since its inferred type is not portable (TS2883).
- Reading a parent class field through `super` is an error (TS2855), so
  `@loopback/cron` calls `fireOnTick` through `BaseCronJob.prototype`.
- Declaration emit no longer adds `/// <reference path>` for ambient files, so
  `@loopback/testlab` exports the should.js types from a module rather than a
  global declaration file. Without it, `expect` resolves to `any` in every
  consuming package and api-extractor cannot follow the `Internal` symbol.

With TypeScript 6 type information, typescript-eslint reports more findings:

- Async Express handlers in `@loopback/rest` and the rpc-server example pass
  rejections to `next` (`no-misused-promises`).
- `??` / `??=` replace `||` and `!x` guards on objects and arrays
  (`prefer-nullish-coalescing`). `||` is kept where the operand may be `''`.
- `transactions.suite.ts` awaits `disconnect()` (`no-floating-promises`).

Test defects surfaced by the stricter compiler are fixed as well:
`belongs-to-repository-factory.unit.ts` never assigned `companyRepo` and
clobbered `customerRepo` instead, and the todo-list repository tests used
repositories they never created.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
@raymondfeng
raymondfeng force-pushed the upgrade-typescript-7 branch from 8915bc4 to f25e352 Compare October 2, 2026 05:03
@raymondfeng raymondfeng changed the title feat(build): compile with the TypeScript 7 native compiler feat(build)!: compile with the TypeScript 7 native compiler Oct 2, 2026
@raymondfeng

Copy link
Copy Markdown
Contributor Author

@samarpanB this PR is now split per your review:

PR Scope Release
#11810 fix(mock-oauth2-provider): CodeQL fixes, redirect_uri validated before a token is issued patch
#11811 feat(eslint-config)!: typescript-eslint v8, plus the lint fixes in separate commits major, eslint-config only
#11793 feat(build)!: TypeScript 7 (stacked on the two above) major, build only
#11812 fix(cli): the if (!gen) metadata bug patch

|| → ??: lint runs without strictNullChecks, so prefer-nullish-coalescing couldn't tell a string operand from a nullable one. On master it even flagged boolean || boolean in relation.helpers.ts. #11811 sets ignorePrimitives for strings, numbers and booleans, so only == null-style rewrites remain. Every rewrite where '' or 0 could change the result was reverted. That includes all the sites you listed, plus rpc-server (port: 0), http-caching-proxy (statusCode: 0), buffer.ts (encoding: '' would have thrown ERR_UNKNOWN_ENCODING), and the CLI app template's process.env.HOST, where an empty HOST would have bound to all interfaces.

Minor items:

  • try-catch-finally.unit.ts: the blank lines are removed (feat(eslint-config)!: upgrade typescript-eslint to v8 #11811).
  • graphql/keys.ts: commented. The annotation avoids TS2883, which I confirmed by building without it.
  • lb-ttsc: the README notes that it compiles with the JS compiler from typescript, not TypeScript 7. The old sentence claiming it falls back to tsc when ttypescript is missing was wrong (it exits with an error) and is removed.
  • Merge conflicts: resolved; everything is rebased on current master.

raymondfeng and others added 2 commits October 1, 2026 22:15
The US Census geocoder now returns slightly different coordinates for the test
address, so `GeoLookupService` and `TodoApplication` tests fail on every
platform, on master as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>
The hook that launches puppeteer and loads the page intermittently exceeds
15 seconds on the ubuntu-latest runners. It now gets 30 seconds, the same as
the hook that generates the bundle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Raymond Feng <enjoyjava@gmail.com>

This branch has not been deployed

No deployments
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.

4 participants