deps: upgrade server, webapp and e2e dependencies #2

Merged
fmartingr merged 8 commits from chore/upgrade-deps into master 2026-09-22 20:10:10 +02:00
Owner

Upgrades every dependency in the server, the webapp and the e2e module, and fixes the CI breakage found along the way.

Server

All direct and indirect dependencies to latest: goquery 1.9.2 → 1.13.0, go-sqlbuilder 1.38.2 → 1.43.0, cobra 1.9.1 → 1.10.2, testify 1.11.1 → 1.12.1, x/crypto 0.46.0 → 0.57.0, modernc.org/sqlite 1.34.1 → 1.59.0.

The go directive moves to 1.26.0 because the golang.org/x modules now require it. The Actions workflows read go-version-file, so they follow automatically.

Webapp

Major bumps: pinia 2 → 4, vue-router 4 → 5, vite 6 → 8, eslint 9 → 10, vue-tsc 2 → 3, @vitejs/plugin-vue 5 → 6, pdfjs-dist 5 → 6, marked 17 → 18.

TypeScript stays on 5.9.3. typescript-eslint declares typescript >=4.8.4 <6.1.0 and hard-errors under TS 7 (typescript-eslint does not support TS 7.0); TS 6 exists only as 6.0.0-beta. 5.9.3 is the highest version that keeps make lint-webapp working. Tracking: typescript-eslint#10940.

Dropped two dead dependencies: @codemirror/basic-setup (no importers) and @types/dompurify (npm-deprecated stub; dompurify ships its own types).

Vite 8 builds with rolldown, which rejects a type imported as a value, so Extension becomes an import type in JsonEditor.vue.

Fixes found on the way

tsconfig.app.json inherited nothing. It extended ./tsconfig.json, a solution file holding only files: [] and references, so it picked up no target, lib, jsx or noEmit. Type checks failed on every built-in type (Cannot find name 'Map') and vue-tsc -b emitted JavaScript next to the TypeScript sources, which then shadowed them and broke vite build. Now extends @vue/tsconfig/tsconfig.dom.json — already a devDependency, until now unused — and sets noEmit.

With type checking working again, eight pre-existing app-code type errors are now visible (PDF render params, an unused @ts-expect-error, HeadersInit indexing, a missing role, total_size, a route q param). Left untouched — they pre-date this branch, verified by running vue-tsc against the old dependency set and diffing: byte-identical output.

make ci-lint could not work. It pinned golangci-lint v1.64.5 and installed from the pre-v2 module path, against a version: "2" config. Now v2.13.2 on .../golangci-lint/v2/cmd/....

e2e on testcontainers 0.44 rather than 0.40: MappedPort now takes a string instead of a nat.Port.

Verification

go build · go vet (root + e2e) · go test -race 11/11 packages · go mod tidy no-op on both modules · golangci-lint v2.13.2 0 issues · goreleaser check · vite build · eslint 0 problems · vue-tsc identical to the pre-upgrade baseline.

The e2e suite went 41 pass / 6 fail → 47 pass / 0 fail.

The e2e suite was re-run on the merged tree and is green there too: 47 pass / 0 fail (ok github.com/fmartingr/hako/e2e/playwright 996.259s). That confirms the one combination neither branch had exercised — master's shared-network e2e code running against testcontainers 0.44 rather than the 0.40 it was written for.

Merge note

Master's Forgejo Actions migration independently fixed the same three e2e bugs this branch did (the .link-item selector, the CreateLink navigation guard, IsVisible strict mode). Master's wording was kept for all three, along with its shared-Docker-network approach, which is better than the host-gateway route used here — it does not depend on Docker Desktop and works under the Docker-in-Docker service the new e2e job uses.

Consequently eca5c88 is largely inert: its branch-gating and Go-version changes edited .woodpecker/ files the merge deleted. Only its golangci-lint fix survives into the tree.

Upgrades every dependency in the server, the webapp and the e2e module, and fixes the CI breakage found along the way. ## Server All direct and indirect dependencies to latest: goquery 1.9.2 → 1.13.0, go-sqlbuilder 1.38.2 → 1.43.0, cobra 1.9.1 → 1.10.2, testify 1.11.1 → 1.12.1, x/crypto 0.46.0 → 0.57.0, modernc.org/sqlite 1.34.1 → 1.59.0. The `go` directive moves to **1.26.0** because the `golang.org/x` modules now require it. The Actions workflows read `go-version-file`, so they follow automatically. ## Webapp Major bumps: pinia 2 → 4, vue-router 4 → 5, vite 6 → 8, eslint 9 → 10, vue-tsc 2 → 3, `@vitejs/plugin-vue` 5 → 6, pdfjs-dist 5 → 6, marked 17 → 18. **TypeScript stays on 5.9.3.** `typescript-eslint` declares `typescript >=4.8.4 <6.1.0` and hard-errors under TS 7 (`typescript-eslint does not support TS 7.0`); TS 6 exists only as `6.0.0-beta`. 5.9.3 is the highest version that keeps `make lint-webapp` working. Tracking: typescript-eslint#10940. Dropped two dead dependencies: `@codemirror/basic-setup` (no importers) and `@types/dompurify` (npm-deprecated stub; dompurify ships its own types). Vite 8 builds with rolldown, which rejects a type imported as a value, so `Extension` becomes an `import type` in `JsonEditor.vue`. ## Fixes found on the way **`tsconfig.app.json` inherited nothing.** It extended `./tsconfig.json`, a solution file holding only `files: []` and `references`, so it picked up no `target`, `lib`, `jsx` or `noEmit`. Type checks failed on every built-in type (`Cannot find name 'Map'`) and `vue-tsc -b` emitted JavaScript next to the TypeScript sources, which then shadowed them and broke `vite build`. Now extends `@vue/tsconfig/tsconfig.dom.json` — already a devDependency, until now unused — and sets `noEmit`. With type checking working again, eight pre-existing app-code type errors are now visible (PDF render params, an unused `@ts-expect-error`, `HeadersInit` indexing, a missing `role`, `total_size`, a route `q` param). **Left untouched** — they pre-date this branch, verified by running `vue-tsc` against the old dependency set and diffing: byte-identical output. **`make ci-lint` could not work.** It pinned golangci-lint `v1.64.5` and installed from the pre-v2 module path, against a `version: "2"` config. Now `v2.13.2` on `.../golangci-lint/v2/cmd/...`. **e2e on testcontainers 0.44** rather than 0.40: `MappedPort` now takes a `string` instead of a `nat.Port`. ## Verification `go build` · `go vet` (root + e2e) · `go test -race` 11/11 packages · `go mod tidy` no-op on both modules · `golangci-lint` v2.13.2 0 issues · `goreleaser check` · `vite build` · `eslint` 0 problems · `vue-tsc` identical to the pre-upgrade baseline. The e2e suite went 41 pass / 6 fail → **47 pass / 0 fail**. The e2e suite was re-run on the merged tree and is green there too: **47 pass / 0 fail** (`ok github.com/fmartingr/hako/e2e/playwright 996.259s`). That confirms the one combination neither branch had exercised — master's shared-network e2e code running against testcontainers 0.44 rather than the 0.40 it was written for. ## Merge note Master's Forgejo Actions migration independently fixed the same three e2e bugs this branch did (the `.link-item` selector, the `CreateLink` navigation guard, `IsVisible` strict mode). Master's wording was kept for all three, along with its shared-Docker-network approach, which is better than the host-gateway route used here — it does not depend on Docker Desktop and works under the Docker-in-Docker service the new e2e job uses. Consequently `eca5c88` is largely inert: its branch-gating and Go-version changes edited `.woodpecker/` files the merge deleted. Only its golangci-lint fix survives into the tree.
Bumps every direct and indirect dependency to latest. Notable: goquery
1.9.2 -> 1.13.0, go-sqlbuilder 1.38.2 -> 1.43.0, cobra 1.9.1 -> 1.10.2,
testify 1.11.1 -> 1.12.1, x/crypto 0.46.0 -> 0.57.0, modernc.org/sqlite
1.34.1 -> 1.59.0.

The go directive moves to 1.26.0 because the golang.org/x modules now
require it.
Major bumps: pinia 2 -> 4, vue-router 4 -> 5, vite 6 -> 8, eslint 9 -> 10,
vue-tsc 2 -> 3, @vitejs/plugin-vue 5 -> 6, pdfjs-dist 5 -> 6, marked 17 -> 18.

TypeScript stays on 5.9.3: typescript-eslint declares `typescript
>=4.8.4 <6.1.0` and refuses to load under TS 7, and TS 6 exists only as a
beta. 5.9.3 is the highest version that keeps `make lint-webapp` working.

Drops @codemirror/basic-setup (no importers) and @types/dompurify (an
npm-deprecated stub; dompurify ships its own types).

Vite 8 builds with rolldown, which rejects a type imported as a value, so
Extension moves to an `import type` in JsonEditor.
tsconfig.app.json extended ./tsconfig.json, which is a solution file
holding only `files: []` and `references`. It therefore inherited no
target, lib, jsx or noEmit, so type checks failed on every built-in type
("Cannot find name 'Map'") and vue-tsc -b emitted JavaScript next to the
TypeScript sources, which then shadowed them and broke `vite build`.

Extends @vue/tsconfig/tsconfig.dom.json (already a devDependency, until
now unused) and sets noEmit explicitly.

Note vue-tsc must run under node; under `bun --bun` it fails to resolve
.vue modules at all.
Both pipelines gated on `branch: main` while origin/HEAD is master, so
neither had been running.

ci-lint pinned golangci-lint v1.64.5 against a `version: "2"` config, and
used the pre-v2 module path. Moves to v2.13.2 and the /v2 path.

Go images trailed go.mod (golang:1.24 in CI, go1.23.5 in release), which
left GOTOOLCHAIN re-downloading a toolchain on every run. Both move to
1.27.

Alpine goes 3.20 -> 3.24 in both the release image and the e2e image.

Playwright's Go module was renamed upstream to github.com/mxschmitt, so
the driver install commands follow it; the old path resolves to a version
whose go.mod declares the new name and fails.
Upgrades testcontainers 0.40 -> 0.44, otel 1.39 -> 1.46 and playwright-go
0.5200.1 -> 0.6201.1, which also moves to its renamed module path.
MappedPort now takes a string rather than a nat.Port.

Fixes three pre-existing failures, all confirmed against a pristine
worktree at master with the old dependency set:

Hako archives a link by issuing a synchronous HEAD request from inside
its own container, so the test web server's host-published port was
unreachable over localhost and every creation returned 500. The container
now gets a host-gateway entry and the target URL is addressed through it.

CreateLink returns to /home before filling the form. A successful submit
redirects to /links, so tests that create several links could no longer
find the input; the redirect branch in the helper had never been reached
while creation was failing. The navigation is conditional to avoid racing
a page load the caller just started.

Tests clicked `a[href*='/links/']`, which matches nothing because a link
card is a div with a click handler, and IsVisible tripped Playwright's
strict mode on grouped selectors that legitimately match several
elements.
Merge origin/master into chore/upgrade-deps
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 9s
CI / format (pull_request) Successful in 1m11s
CI / build (pull_request) Successful in 6m40s
CI / test (pull_request) Successful in 7m41s
CI / e2e (pull_request) Has been cancelled
CI / lint (pull_request) Has been cancelled
7f9cd3e477
Master migrated CI to Forgejo Actions and, independently, fixed the same
three e2e failures this branch did. Resolution takes master's side for CI
and e2e infrastructure and keeps this branch's dependency upgrades.

Superseded by master, dropped from this branch:
- .woodpecker pipelines, deleted in favour of .github/workflows. The
  branch gating and Go version bumps made here are moot: the workflows
  already target master and read go-version-file from go.mod.
- The host-gateway route added to reach the test web server. Master's
  shared Docker network with a container alias is the better fix; it does
  not depend on Docker Desktop and works under the Docker-in-Docker
  service the new e2e job uses. e2eutil/hostgateway.go is removed.
- Local formatting of e2e/e2eutil/helper.go, to keep master's file intact.

Kept from this branch:
- All dependency upgrades, including e2e on testcontainers 0.44 rather
  than master's 0.40. Master's container.go still called MappedPort with
  a nat.Port; 0.44 takes a string, so its call is adapted and the
  go-connections import dropped.
- golangci-lint v2.13.2 on the /v2 module path. Master left the v1.64.5
  pin and the pre-v2 path against a `version: "2"` config, so `make
  ci-lint` would still fail.

Both sides reached the same conclusions on the selector, CreateLink
navigation and IsVisible strict-mode fixes; master's wording of each is
kept. Containerfile stays on master's Alpine 3.23.
ci: run golangci-lint at the pinned version
Some checks failed
CI / goreleaser-lint (pull_request) Successful in 1m2s
CI / format (pull_request) Successful in 2m44s
CI / test (pull_request) Successful in 4m27s
CI / build (pull_request) Successful in 3m36s
CI / lint (pull_request) Successful in 6m24s
CI / e2e (pull_request) Failing after 3m32s
7c5d341d3d
The ci-lint target guarded its install with `which golangci-lint`, so on a
runner that already ships golangci-lint the pinned version was never
installed and whatever the image carried ran instead. That binary is v1,
which cannot read a `version: "2"` config and exits with "can't load
config: unsupported version of the configuration".

This is why lint fails on master as well, and why it started failing at
ccda656c ("ci: run workflows on the GitHub-compatible runner") while the
target itself has not changed since.

Always installs the pinned version and invokes it by absolute path, so
the result no longer depends on what the runner image happens to carry.

Verified in a golang:1.26 container both clean and with a decoy
golangci-lint ahead of it on PATH; the old target picks up the decoy and
fails, the new one does not.
ci: start containerd before dockerd in the e2e service
All checks were successful
CI / goreleaser-lint (pull_request) Successful in 10s
CI / format (pull_request) Successful in 1m30s
CI / lint (pull_request) Successful in 4m43s
CI / test (pull_request) Successful in 6m59s
CI / build (pull_request) Successful in 6m25s
CI / e2e (pull_request) Successful in 25m10s
4d1af76510
Retrying dockerd was a coin flip. containerd needs a little over ten
seconds to boot in the runner's container and dockerd waits exactly
ten, so every attempt loses that race when the host is busy: run 19
burned all five and the job waited three minutes for a daemon that
never arrived.

Starting containerd first and handing dockerd the socket removes the
timeout from the picture. Measured on the runner: ready in 30 seconds,
no retries.
fmartingr merged commit 54760805c2 into master 2026-09-22 20:10:10 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
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
fmartingr/hako!2
No description provided.