Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
node-version: 26
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml

Expand Down Expand Up @@ -510,7 +510,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
node-version: 26
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml

Expand Down Expand Up @@ -565,7 +565,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
node-version: 26
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml

Expand Down Expand Up @@ -639,7 +639,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
node-version: 26
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
node-version: 26
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Images in Dockerfiles, compose files, kind manifests, Go pod specs and testconta
| `gcr.io/distroless/base-nossl-debian12:nonroot` | `deploy/versions.env` (DISTROLESS_BASE_IMAGE) — app and simulator images (`make check-docker` guards `deploy/Dockerfile.*`; the init image's runtime base is GO_IMAGE); `e2e/mockmsft/Dockerfile:6` hardcodes `static-debian12:nonroot` — not in `check-docker`, but Renovate refreshes its digest |
| `grafana/alloy:v1.20.1` | `deploy/versions.env` (ALLOY_IMAGE); compose files restate it as a `${ALLOY_IMAGE:-…}` fallback, `dev/kind/alloy.yaml` takes it via `__ALLOY_IMAGE__` |
| `golang:1.27-alpine` | `deploy/versions.env` (GO_IMAGE); also the init image's runtime base; `e2e/mockmsft/Dockerfile:1` hardcodes it — not in `check-docker`, Renovate-refreshed |
| `node:24-slim` | `deploy/versions.env` (NODE_IMAGE) |
| `node:26-slim` | `deploy/versions.env` (NODE_IMAGE) |
| `postgres:18-alpine` / `postgres:16-alpine` | 18: the dev and e2e compose files (#154; Renovate-managed). 16: `Makefile` (smoke), `internal/testutil/postgres.go`, `e2e/k8s/fixtures_test.go` — the supported floor. NOT versions.env |
| `busybox:1.36`, `curlimages/curl:8.11.1` | `e2e/k8s/*_test.go` pod specs — NOT versions.env, NOT Renovate-managed |
| `ghcr.io/navikt/mock-oauth2-server:6.0.1` | compose files and `dev/kind/oidc.yaml` — NOT versions.env |
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Categories used here:

- **Built with Go 1.27.** `go.mod` moves to `go 1.27.1` and every image builds on
`golang:1.27-alpine` (`GO_IMAGE` in `deploy/versions.env`). Building from source needs Go 1.27.
- **The SPA builds on Node 26 with pnpm 12.** `NODE_IMAGE` is `node:26-slim`, `PNPM_VERSION` and
`packageManager` are `12.8.1`, `@types/node` is 26, and `web/package.json` declares
`engines.node >=26` (with `engineStrict`, an install on an older Node is refused). Node 26 no longer
bundles corepack, so the image builds install pnpm with `npm install -g pnpm@<pin>`.

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ rebuilds the image and recreates the container after a Go change. If you would
rather run the SPA with hot reload against that backend, `make dev-frontend`
(Vite proxies `/api`, `/auth` and the Connect procedures to `:8080`).

Building by hand needs Go (version per `go.mod`), Node 24 with pnpm, Docker, and
Building by hand needs Go (version per `go.mod`), Node 26 with pnpm, Docker, and
Helm. `make tools` installs the Go-side generators at their pinned versions.

## Before you open a pull request
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ traces; it configures the collectors that ship them.
|---|---|
| Run Shepherd | A Kubernetes cluster (1.29+), Helm 3 or 4, and **PostgreSQL 16 or newer** it can reach — the test suites run 16, the dev and e2e stacks 18; older majors are untested. The chart needs no CRDs by default. |
| Run collectors | [Grafana Alloy](https://grafana.com/docs/alloy/) **v1.20.1** — the version whose component schema this build validates against, pinned in `deploy/versions.env`. |
| Build from source | Go (see `go.mod`), Node 24 with pnpm, Docker (tests start real PostgreSQL via testcontainers), and Helm. |
| Build from source | Go (see `go.mod`), Node 26 with pnpm, Docker (tests start real PostgreSQL via testcontainers), and Helm. |

Two optional integrations need their operators installed first:
[CloudNativePG](https://procoduck.github.io/shepherd/docs/database.html) to have
Expand Down
12 changes: 8 additions & 4 deletions deploy/Dockerfile.init
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
ARG GO_IMAGE=golang:1.27-alpine@sha256:8a5910f31396cd4d89662f56c68b3ae31d374308270a1c3bd96672ee5ed43414
ARG NODE_IMAGE=node:24-slim@sha256:2fe369e969550cde8e867afc3fe370b260140cab4a23d467074295b42163d553
ARG PNPM_VERSION=11.28.3
ARG NODE_IMAGE=node:26-slim@sha256:ec7758ee051e457b468b32bde57b0879010b325bb9862718e9615225ce4aaae1
ARG PNPM_VERSION=12.8.1

# Stage 1: Build the web SPA (required for go:embed to compile)
FROM ${NODE_IMAGE} AS web
ARG PNPM_VERSION
ENV COREPACK_NPM_REGISTRY=https://registry.npmjs.org
WORKDIR /app
COPY web/package.json web/pnpm-lock.yaml web/.npmrc web/pnpm-workspace.yaml web/
RUN corepack enable && corepack prepare pnpm@${PNPM_VERSION} --activate
# Node 25+ no longer bundles corepack, so pnpm comes from npm at the exact
# PNPM_VERSION pin (npm verifies the tarball against the registry integrity).
# --ignore-scripts: pnpm's preinstall only relinks its bin onto the native binary;
# without it the placeholder bin starts that same binary through Node.
# Point npm at your organisation's registry mirror here if applicable.
RUN npm install --global --no-fund --no-audit --ignore-scripts pnpm@${PNPM_VERSION}
COPY web/ web/
COPY scripts/ scripts/
RUN chmod +x scripts/build-web.sh && ./scripts/build-web.sh
Expand Down
12 changes: 8 additions & 4 deletions deploy/Dockerfile.local
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
ARG GO_IMAGE=golang:1.27-alpine@sha256:8a5910f31396cd4d89662f56c68b3ae31d374308270a1c3bd96672ee5ed43414
ARG NODE_IMAGE=node:24-slim@sha256:2fe369e969550cde8e867afc3fe370b260140cab4a23d467074295b42163d553
ARG NODE_IMAGE=node:26-slim@sha256:ec7758ee051e457b468b32bde57b0879010b325bb9862718e9615225ce4aaae1
ARG ALLOY_IMAGE=grafana/alloy:v1.20.1@sha256:2aa2099af76c0098d4af7a4d6e48f86cb66dc1a000222ad927a1c67c6542d13f
ARG DISTROLESS_BASE_IMAGE=gcr.io/distroless/base-nossl-debian12:nonroot@sha256:be40c00dfabd86576d92666e87e406714d5618342de1a0c213ad232de255172e
ARG PNPM_VERSION=11.28.3
ARG PNPM_VERSION=12.8.1

# Stage 1: Build the web SPA via the canonical build script
FROM ${NODE_IMAGE} AS web
ARG PNPM_VERSION
ENV COREPACK_NPM_REGISTRY=https://registry.npmjs.org
WORKDIR /app
COPY web/package.json web/pnpm-lock.yaml web/.npmrc web/pnpm-workspace.yaml web/
RUN corepack enable && corepack prepare pnpm@${PNPM_VERSION} --activate
# Node 25+ no longer bundles corepack, so pnpm comes from npm at the exact
# PNPM_VERSION pin (npm verifies the tarball against the registry integrity).
# --ignore-scripts: pnpm's preinstall only relinks its bin onto the native binary;
# without it the placeholder bin starts that same binary through Node.
# Point npm at your organisation's registry mirror here if applicable.
RUN npm install --global --no-fund --no-audit --ignore-scripts pnpm@${PNPM_VERSION}
COPY web/ web/
COPY scripts/ scripts/
RUN chmod +x scripts/build-web.sh && ./scripts/build-web.sh
Expand Down
4 changes: 2 additions & 2 deletions deploy/versions.env
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Update here only; the CI check-docker guard enforces consistency.
# Replace with your organisation's registry mirror prefix if applicable.
GO_IMAGE=golang:1.27-alpine@sha256:8a5910f31396cd4d89662f56c68b3ae31d374308270a1c3bd96672ee5ed43414
NODE_IMAGE=node:24-slim@sha256:2fe369e969550cde8e867afc3fe370b260140cab4a23d467074295b42163d553
NODE_IMAGE=node:26-slim@sha256:ec7758ee051e457b468b32bde57b0879010b325bb9862718e9615225ce4aaae1
ALLOY_IMAGE=grafana/alloy:v1.20.1@sha256:2aa2099af76c0098d4af7a4d6e48f86cb66dc1a000222ad927a1c67c6542d13f
ALLOY_VERSION=v1.20.1
# The simulator image must RUN the Alloy binary, not just ship it. Alloy v1.18.1
Expand All @@ -19,7 +19,7 @@ ALLOY_VERSION=v1.20.1
# dynamic loader — the binary lands in the image unrunnable and Stage 2 of the
# validation gate silently dies. `make check-alloy-runnable` guards that.
DISTROLESS_BASE_IMAGE=gcr.io/distroless/base-nossl-debian12:nonroot@sha256:be40c00dfabd86576d92666e87e406714d5618342de1a0c213ad232de255172e
PNPM_VERSION=11.28.3
PNPM_VERSION=12.8.1
# Every image is pinned by DIGEST as well as tag: the tag says what it is, the
# digest says exactly which build, so a base image republished under the same
# tag cannot change what the release ships without a reviewed PR. Renovate
Expand Down
2 changes: 1 addition & 1 deletion scripts/docs-content/requirements.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ <h1>Requirements</h1>
</tr>
<tr>
<td>Build from source</td>
<td>Go (version per <code>go.mod</code>), Node 24 + pnpm, Docker (the Go suite starts real
<td>Go (version per <code>go.mod</code>), Node 26 + pnpm, Docker (the Go suite starts real
Postgres via testcontainers), and Helm for the chart tests.</td>
</tr>
</tbody>
Expand Down
2 changes: 1 addition & 1 deletion site/docs/requirements.html
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ <h1>Requirements</h1>
</tr>
<tr>
<td>Build from source</td>
<td>Go (version per <code>go.mod</code>), Node 24 + pnpm, Docker (the Go suite starts real
<td>Go (version per <code>go.mod</code>), Node 26 + pnpm, Docker (the Go suite starts real
Postgres via testcontainers), and Helm for the chart tests.</td>
</tr>
</tbody>
Expand Down
6 changes: 4 additions & 2 deletions web/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ React 19 + TypeScript + Vite SPA, embedded into the Go binary via `go:embed`.
- Single spec: `pnpm exec playwright test tests/specs/<name>.spec.ts`

## Tooling
- **Package manager**: pnpm v11 via corepack; the pin is `package.json` `packageManager` (CI reads it) and `deploy/versions.env` PNPM_VERSION must match
- Activate on a new machine: `corepack prepare pnpm@11.28.3 --activate` (or `brew install pnpm` if your registry lacks v11)
- **Runtime**: Node 26 (`deploy/versions.env` NODE_IMAGE, ci.yml/release.yml `node-version`, `engines.node`; `engineStrict` refuses an install on an older Node). `@types/node` tracks the same major
- **Package manager**: pnpm v12; the pin is `package.json` `packageManager` (CI reads it) and `deploy/versions.env` PNPM_VERSION must match
- Install on a new machine: `npm install -g pnpm@12.8.1` (or `brew install pnpm`) — Node 25+ no longer bundles corepack. A pnpm 12 that differs from the pin switches to the pinned version itself
- pnpm 12 fails on any `pnpm-workspace.yaml` key it does not recognise (`ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS`) — check a new setting's spelling against the pnpm docs
- **Linter/formatter**: Biome (`biome.json`) — replaces ESLint + Prettier entirely
- **Build**: Vite 8 (rolldown bundler) with `@tailwindcss/vite` plugin. Heavy code is behind lazy boundaries — the visual builder and graph view as routes (`src/routes/router.tsx`), CodeMirror behind `src/editor/LazyAlloyEditor.tsx` — all through `src/lib/lazyNamed.ts`, which rejects readably when a chunk lacks its export. `chunkSizeWarningLimit` in `vite.config.ts` sits just above the measured entry so a new static import trips it
- **Registry**: public npm by default; configure a mirror in `web/.npmrc` if your organisation uses one
Expand Down
7 changes: 5 additions & 2 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"version": "0.1.0",
"private": true,
"type": "module",
"packageManager": "pnpm@11.28.3",
"packageManager": "pnpm@12.8.1",
"engines": {
"node": ">=26"
},
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
Expand Down Expand Up @@ -56,7 +59,7 @@
"@playwright/test": "^1.63.0",
"@tailwindcss/vite": "^4.1.8",
"@testing-library/react": "^16.3.3",
"@types/node": "^24.19.0",
"@types/node": "^26.6.3",
"@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0",
"@vitejs/plugin-react": "^6.1.1",
Expand Down
Loading
Loading