[DO NOT MERGE] - Standalone Services plan#4097
Draft
tobybellwood wants to merge 19 commits into
Draft
Conversation
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.
This PR contains my POC work on splitting the JavaScript-based API services into standalone services. I've included a document (in the last commit) that covers the steps undertaken (and reproduced below). This PR is not to be merged - it doesn't reflect the actual HEAD state of the repository, and any refactoring would be nearly impossible - instead, this PR and branch can serve as reference material for future work.
This should not be undertaken until the webhook-handler-go PR (#3979) is merged. We would need to consider when to perform the Apollo Server upgrade PR (#4084), either in conjunction with this work or before/after.
The main benefit in this work is to streamline the creation (and testing) of the main Lagoon services - with API as a single Dockerfile, the creation and testing of automated updates (e.g., renovate/dependabot) would be much simplified. This work also covers the reintroduction of Jest tests, and should also be considered in tandem with the introduction of Cypress/Playwright visual testing.
Yarn-to-pnpm Standalone Services Migration Plan
Background
The Lagoon monorepo historically used Yarn Workspaces to link Node.js services
(
api,auth-server) and a sharednode-packages/commonslibrary together. A rootpackage.json, rootyarn.lock, roottsconfig.json, and ayarn-workspace-builderDocker stage formed the glue.
Go services (
actions-handler,backup-handler,logs2notifications,webhook-handler,api-sidecar-handler) already operate as standalone modulesusing the root
go.mod.Prerequisites (already complete)
The following work was completed on the
webhook-handler-gobranch prior to thismigration and is assumed as a starting point:
webhook-handler and api-sidecar-handler
This means the only remaining Yarn workspace members are
apiandauth-server, plus the sharednode-packages/commonslibrary.Goal
Make every Node.js service fully standalone — each service owns its own
dependencies, lockfile, and build — eliminating the shared Yarn workspace
infrastructure entirely, and migrating from Yarn to pnpm.
Phase 1: Auth-server standalone + pnpm migration
Commits:
defd98e7b..141f6adde(3 commits)Scope: 12 files changed, +4,046 / −2,400 lines
What was done
auth-serverfrom the Yarn workspace — gave it its ownpackage.jsondependencies (previously relied on hoisted workspace deps).auth-serverfrom Yarn to pnpm — addedpnpm-lock.yaml,removed
yarn.lock.auth-servergot its own ESLint setup insteadof referencing the shared
eslint-config-lagoon-nodepackage fromnode-packages/.auth-server/Dockerfileto use standalone pnpm install instead ofthe
yarn-workspace-buildermulti-stage pattern.Key decisions
auth-serveris the simpler of the two remaining Node services, so it wasmigrated first as a proof of concept.
resolution, better monorepo-to-standalone story).
Phase 2: Remove yarn-workspace-builder — standalone API build
Commit:
fc426616fScope: 4 files changed, +24 / −47 lines
What was done
yarn-workspace-builder/Dockerfile— the Docker multi-stage builderimage that previously installed all Yarn workspace dependencies for every Node
service.
services/api/Dockerfileto install its own dependencies directlyinstead of copying from the
yarn-workspace-builderstage.Makefileanddocker-bake.hcl— removed references to theyarn-workspace-builder target.
Why this is separate
The build change can be landed and tested in isolation. After this commit the API
still uses Yarn and still references
node-packages/commons— but its Docker buildno longer depends on the shared builder image.
Phase 3: Consolidate commons and remove Yarn workspace root
Commits:
d389edd91..831981965(4 commits + fixups)Scope: ~95 files changed
What was done
node-packages/commonsintoservices/api/— all sharedTypeScript utilities, types, JWT helpers, logging, and API client code were
moved into the API service's source tree (under
src/commons/or directlyinto relevant modules).
@lagoon/commons/...to local relative imports.
node-packages/directory entirely — no more shared packages.node-packages/eslint-config-lagoon-node/— each service nowowns its own lint configuration.
package.json— no more Yarn workspace root.yarn.lockintoservices/api/— the API now owns its ownlockfile.
tsconfig.json— each service has its own TypeScript config.Key decisions
because the API was the only remaining consumer after webhook-handler and
webhooks2tasks were rewritten in Go.
Phase 4: API — Yarn to pnpm migration
Commits:
2a95edead..e526a9a8b(7 commits)Scope: 183 files changed, +21,251 / −19,968 lines
What was done
pnpm-lock.yaml, removedyarn.lock.(
graphql-tag, Ramda imports, etc.).setup, added module mocks for
mariadb,node-fetch, andredisso theexisting test suites run without external dependencies.
Key decisions
yarn.lockdeleted,pnpm-lock.yamladded).hoisting had silently resolved.
Phase 5: API test coverage expansion
Commit:
e526a9a8b(initial), ongoingReference:
services/api/TEST_COVERAGE_PLAN.mdCurrent state
8 test suites, 22 tests, 14 snapshots — all passing. Coverage is concentrated in
SQL query builders and one permission helper. Utility code, business-logic helpers,
and the auth layer have no tests.
What was done
jest.config.jswithmoduleNameMapperandmanual mocks (
__mocks__/mariadb.js,__mocks__/node-fetch.js,__mocks__/redis.js) so tests run without live infrastructure.sshKey/helpers.ts— extractedvalidateSshKeyinto a testablepure function.
match the post-migration import paths.
TEST_COVERAGE_PLAN.md— a tiered plan for expanding API testcoverage (see below).
Planned test tiers
func.ts,snakeCase.ts,pickNonNil.ts,convertDate.ts,advancedTaskDefinitionArgument.ts— no DB, no mockssql.tsfiles (task,deployment,routes,backup,organization,problem, etc.) — same pattern as existing testsuserActivityLogger(regression),extractWsToken(auth fallback paths),filterAdminTasks,groupByProblemIdentifier, environment validatorsuser.tsmodel,group.tsmodel,authMiddleware.ts— requires mockedsqlClientPoolandkeycloak-adminCoverage targets
Not unit tested (by design)
Resolver files, server bootstrap, HTTP route handlers, and third-party client
wrappers are better covered by the existing k3d integration/E2E test suite.
Final State
Before (starting point — post
webhook-handler-go)After (on
testing/yarn-to-pnpm)What was removed
package.json(root)yarn.lock(root)tsconfig.json(root)yarn-workspace-builder/node-packages/commons/services/api/node-packages/eslint-config-lagoon-node/Remaining / Future Work
adjustments for the new standalone build model (no more yarn-workspace-builder
stage).
build targets.
the standalone service builds.