@cjournois/e2e-kind (0.1.2)

Published 2026-08-10 12:05:29 +00:00 by cjournois

Installation

@cjournois:registry=
npm install @cjournois/e2e-kind@0.1.2
"@cjournois/e2e-kind": "0.1.2"

About this package

@cjournois/e2e-kind

Stand a Helm chart up on an ephemeral kind cluster from a declarative config, run a suite against it, and tear it down — including the diagnostics dump that makes a CI failure conclusive.

Replaces the ~55 lines of hand-written bash that each deployable project used to carry in its just e2e recipe.

Usage

Install it in the project's e2e harness, then point it at a stack config:

bun add -d @cjournois/e2e-kind
./e2e/node_modules/.bin/e2e-kind e2e/stack.json

In a justfile, as the e2e-full recipe:

# Full stack on an ephemeral kind cluster, driven by e2e/stack.json.
e2e-full:
    ./e2e/node_modules/.bin/e2e-kind e2e/stack.json

Paths inside the config are repo-root relative, so run it from the repo root.

Flags:

Flag Default Role
--tag <tag> e2e-<epoch> Image tag to build and deploy.
--npmrc <path> ~/.npmrc npmrc to mount as the npmrc build secret.

What it does

  1. Delete any leftover cluster, then kind create cluster --wait 120s.
  2. docker build each image with DOCKER_BUILDKIT=1.
  3. docker pull each preload, then one kind load docker-image for images and preloads together.
  4. Create the namespace idempotently (create --dry-run=client -o yaml piped to apply -f -).
  5. helm upgrade --install with the values file and one --set <key>.image.tag= per image.
  6. kubectl rollout status for each rollout.
  7. Background kubectl port-forward per forward, then poll the health URL.
  8. Run the suite. Its exit code is the driver's.
  9. On failure, dump describe pods and the primary deployment's logs, then kill the forwards and delete the cluster. Order matters: a workflow-level if: failure() step runs after teardown and would find nothing left to inspect.

Teardown runs whether the suite passed, failed, or threw.

Config

Point your editor at the shipped schema for completion:

{
  "$schema": "./node_modules/@cjournois/e2e-kind/schema.json",
  "cluster": "recall-e2e",
  "namespace": "recall",
  "release": "recall",
  "chart": "packages/recall-helm/recall",
  "values": "values-local.yaml",
  "npmrcSecret": true,
  "images": [
    { "helmKey": "api", "name": "recall-api", "containerfile": "services/recall-api/Containerfile" },
    { "helmKey": "app", "name": "recall-app", "containerfile": "services/recall-app/Containerfile" }
  ],
  "preload": ["pgvector/pgvector:pg18"],
  "rollouts": [{ "deploy": "recall-api", "timeout": "180s" }, { "deploy": "recall-app" }],
  "forward": [{ "svc": "recall-app", "local": 3400 }],
  "health": { "path": "/healthz", "port": 3400 },
  "diagnostics": { "deploy": "recall-api" }
}
Field Default Role
cluster — kind cluster name. The kubeconfig context is kind-<cluster>.
namespace / release — Target namespace and Helm release name.
chart — Chart directory, repo-root relative.
values none Values file, resolved inside chart. Omit for a chart that needs no overrides.
npmrcSecret false Mount ~/.npmrc as --secret id=npmrc — only when the file exists, so it works with and without private-registry access.
images[] — name, containerfile, optional context (default .), optional helmKey.
images[].helmKey '' Chart value holding the image block: api writes api.image.tag; omitted writes the top-level image.tag.
setRepository false Also set <key>.image.repository and pullPolicy=IfNotPresent, for charts that default to a remote registry.
preload[] [] Images pulled on the host and loaded into the node. Use for anything large enough that an in-cluster pull would outrun a service's migrate-on-boot.
set {} Extra --set key=value pairs, appended last.
rollouts[] — deploy plus optional timeout (default 120s), waited in order.
forward[] [] svc and local; remote defaults to local.
health none path and port (must match a forward.local), plus attempts (30) and intervalSeconds (2).
diagnostics none deploy to tail on failure, plus tail (120). Without it only describe pods is dumped.
spec Playwright in e2e/ cwd, command, env for the suite.

Validation is strict: an unknown key is an error, not a silent no-op. Two images sharing a helmKey, or a health.port that no forward exposes, are rejected up front rather than at minute eight of a cluster run.

Commands

just install    # bun install
just lint       # biome + eslint
just test       # bun test
just build      # tsdown -> lib/, then regenerate schema.json

The tests assert the exact argv the driver emits for all four real project stacks, so a change in command construction shows up as a diff rather than a broken pipeline.

Dependencies

Dependencies

ID Version
commander ^15.0.0
zod ^4.3.6

Development dependencies

ID Version
@biomejs/biome 2.5.1
@cjournois/biome-config-ts ^0.1.0
@cjournois/eslint-config-ts ^0.1.0
@eslint/js ^9.39.4
@stryker-mutator/core ^9.6.1
@types/bun 1.3.14
eslint ^9.39.4
eslint-plugin-import ^2.32.0
globals ^17.4.0
tsdown ^0.22.0
typescript ^6.0.0
typescript-eslint ^8.58.0
Details
npm
2026-08-10 12:05:29 +00:00
163
Corentin JOURNOIS
UNLICENSED
8.4 KiB
Assets (1)
Versions (5) View all
0.1.3 2026-09-07
0.1.2 2026-08-10
0.1.1-ac356865 2026-08-05
0.1.1 2026-08-05
0.1.0 2026-08-04