diff --git a/.changeset/drop-type-fest-dep.md b/.changeset/drop-type-fest-dep.md new file mode 100644 index 0000000..c5c7961 --- /dev/null +++ b/.changeset/drop-type-fest-dep.md @@ -0,0 +1,5 @@ +--- +"@vlandoss/env": patch +--- + +Drop the `type-fest` dependency. `PartialDeep` is now defined locally in `src/lib/types.ts` with an equivalent shape, so the public surface of `Config` and `Defaults` is unchanged. One fewer transitive dep for consumers. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48d9918..5648889 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,8 @@ jobs: - name: πŸ“¦ Install root workspace run: pnpm install --frozen-lockfile - - name: πŸ’… Test static (biome + tsc) - run: mise run test:static + - name: πŸ’… Check (biome + tsc) + run: mise run check - name: 🎭 Install Playwright browser (lib browser tests) run: mise run playwright:install @@ -92,3 +92,26 @@ jobs: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} LEFTHOOK: 0 + + preview: + runs-on: ubuntu-latest + if: ${{ startsWith(github.head_ref, 'feat') || startsWith(github.head_ref, 'fix') || contains(github.event.pull_request.labels.*.name, 'preview') }} + permissions: + id-token: write + contents: read + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: 🟒 Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: .node-version + + - name: βŒ› Setup CI + uses: variableland/gh-actions/actions/setup-pnpm@main + + - name: πŸš€ Preview release + uses: variableland/gh-actions/actions/monorepo-preview-release@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml deleted file mode 100644 index c319526..0000000 --- a/.github/workflows/preview.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Preview - -on: - pull_request: - types: [opened, synchronize, reopened, labeled] - branches: - - main - paths: - - "package/**" - - ".github/workflows/preview.yml" - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - preview: - runs-on: ubuntu-latest - if: ${{ startsWith(github.head_ref, 'feat') || startsWith(github.head_ref, 'fix') || contains(github.event.pull_request.labels.*.name, 'preview') }} - permissions: - id-token: write - contents: read - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 🟒 Setup Node.js - uses: actions/setup-node@v6 - with: - node-version-file: .node-version - - - name: βŒ› Setup CI - uses: variableland/gh-actions/actions/setup-pnpm@main - - - name: πŸš€ Preview release - uses: variableland/gh-actions/actions/monorepo-preview-release@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - npm_token: ${{ secrets.NPM_TOKEN }} diff --git a/README.md b/README.md index 9e7cb31..ec2ee31 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,11 @@ pnpm add @vlandoss/env This is the monorepo. Three things live here: -| Path | What it is | -| -------------------------- | ----------------------------------------------------------------------------------------------------- | -| [`package/`](./package) | The [`@vlandoss/env`](./package) library β€” published to npm | -| [`docsite/`](./docsite) | The Fumadocs site behind [env.oss.variable.land](https://env.oss.variable.land), on Cloudflare Workers | -| [`examples/`](./examples) | 9 runtime-isolated demos (Node, Bun, Deno, Workers, Edge, Vite SPA, SSR) β€” each one is a real consumer of the published tarball | +| Path | What it is | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| [`package/`](./package) | The [`@vlandoss/env`](./package) library β€” published to npm | +| [`docsite/`](./docsite) | The Fumadocs site behind [env.oss.variable.land](https://env.oss.variable.land), on Cloudflare Workers | +| [`examples/`](./examples) | 9 runtime-isolated demos (Node, Bun, Deno, Workers, Edge, Vite SPA, SSR) β€” each one is a real consumer of the published tarball | ## Working on it @@ -40,7 +40,7 @@ Day-to-day: mise run docsite # docs site dev server mise run lib:test # unit tests for @vlandoss/env mise run lib:build # build @vlandoss/env -mise run test:static # JS & TS check across package + docsite +mise run check # JS & TS check across package + docsite ``` Run `mise tasks` for the full list. @@ -53,4 +53,4 @@ Issues, ideas, and PRs welcome. Read [CONTRIBUTING.md](./docs/CONTRIBUTING.md) b ## License -[MIT](./LICENSE) Β© [Variableland](https://variable.land) +[MIT](./LICENSE) Β© [Variable Land](https://variable.land) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 79d489a..1924256 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -74,7 +74,7 @@ Don't bump versions or edit `CHANGELOG.md` by hand β€” Changesets does both duri - [ ] Branch named `feat/*`, `fix/*`, `docs/*`, `chore/*`, or `test/*` - [ ] PR title follows Conventional Commits - [ ] Tests cover the change (unit in `package/src/__tests__/`, e2e in `examples//test/e2e/` if relevant) -- [ ] `mise run lib:test` and `mise run test:static` pass locally (JS & TS check) +- [ ] `mise run lib:test` and `mise run check` pass locally (JS & TS check) - [ ] `mise run test:e2e` passes locally for affected examples - [ ] Changeset added (if the published `@vlandoss/env` changed) - [ ] Docs updated (if public API or behavior changed) @@ -97,7 +97,7 @@ Examples are runtime-isolated demos. Each one is a real consumer of the publishe ```jsonc "@vlandoss/env": "file:../../package/.local/vlandoss-env.tgz" ``` -3. Add a `mise.toml` with the runtime tools (`node` / `bun` / `deno` / `pnpm`) and the standard tasks (`install`, `start`, `test:e2e`, `test:types`, `test:static`). Use any of the existing examples as a template β€” pick the one with the closest runtime. +3. Add a `mise.toml` with the runtime tools (`node` / `bun` / `deno` / `pnpm`) and the standard tasks (`setup`, `start`, `test:e2e`, `check`). Use any of the existing examples as a template β€” pick the one with the closest runtime. 4. Add a `biome.json` extending `@vlandoss/config/biome` (skip this for Deno-only examples). 5. Add the path to `[monorepo].config_roots` in the root [`mise.toml`](../mise.toml). 6. Add a row to the matrix in [`.github/workflows/e2e.yml`](../.github/workflows/e2e.yml). diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index f11ef95..72b4e50 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -48,11 +48,10 @@ mise run setup # ↓ runs the bootstrap chain `mise run setup` runs the following steps in order: 1. `mise install` β€” installs the root tools. -2. `for d in examples/*/; do mise install -C "$d"; done` β€” installs each example's runtime (bun, deno, etc.). +2. `for d in examples/*/; do mise install -C "$d"; done` β€” installs each example's runtime (bun, deno, etc.). `mise install` doesn't accept monorepo globs, so the loop stays. 3. `pnpm install` β€” workspace deps for `package` + `docsite`. -4. `mise run env:pack` β€” builds `@vlandoss/env` and packs it into `package/.local/vlandoss-env.tgz`. -5. `for d in examples/*/; do mise -C "$d" run install; done` β€” installs each example. -6. `mise run playwright:install` β€” fetches Chromium for the SPA / SSR e2e suites. +4. `mise run "//examples/...:setup"` β€” runs each example's `setup` task in parallel (resolved via `[monorepo].config_roots`). Each `setup` declares `depends = ["//:env:pack"]`, so mise dedupes `env:pack` to a single execution before the example installs. +5. `mise run playwright:install` β€” fetches Chromium for the SPA / SSR e2e suites. End state: every example has its own `node_modules/`, its own lockfile, and a freshly installed copy of `@vlandoss/env` extracted from the tarball. @@ -63,10 +62,10 @@ The library uses [tsdown](https://tsdown.dev) for the build and [vitest](https:/ ```sh mise run lib:test # unit tests mise run lib:build # emits dist/ -mise run test:static # JS & TS check across package + docsite +mise run check # JS & TS check across package + docsite ``` -If you're hacking inside `package/`, the library's own `package.json` exposes the underlying scripts β€” those are what `mise run lib:*` and `mise run test:static` ultimately call. +If you're hacking inside `package/`, the library's own `package.json` exposes the underlying scripts β€” those are what `mise run lib:*` and `mise run check` ultimately call. ### Iterating with the examples @@ -77,7 +76,7 @@ mise run env:pack # rebuild + repack the tarball mise run examples:bump # reinstall the tarball in every example ``` -Each example's `install` task prepends `mise run //:env:pack` (with `sources` / `outputs` declared on `env:pack` itself), so any of these will pull in the latest tarball automatically: +Each example's `setup` task declares `depends = ["//:env:pack"]` (with `sources` / `outputs` declared on `env:pack` itself), so any of these will pull in the latest tarball automatically: ```sh mise run //examples/backend-node:test:e2e @@ -111,11 +110,11 @@ Content lives in `docsite/content/docs/` as MDX. Read [`docsite/README.md`](../d Every example has the same task vocabulary, so you can `cd` into any of them and run: ```sh -mise run install # install deps (uses the example's native PM) +mise run setup # pack env + install deps (uses the example's native PM) mise run reinstall # force-reinstall the env tarball mise run start # run the server / dev server mise run test:e2e # Playwright -mise run test:static # JS & TS check +mise run check # JS & TS check ``` Or invoke from the repo root with the `//path:task` syntax: @@ -162,7 +161,7 @@ The full step-by-step is in [CONTRIBUTING.md](./CONTRIBUTING.md#adding-a-new-exa 5. Add the path to `[monorepo].config_roots` in the root [`mise.toml`](../mise.toml). 6. Add a row to the matrix in [`.github/workflows/e2e.yml`](../.github/workflows/e2e.yml). 7. Update the table in [`examples/README.md`](../examples/README.md). -8. `mise run install` from the new dir β€” commit the generated lockfile. +8. `mise run setup` from the new dir β€” commit the generated lockfile. ## mise tasks reference @@ -178,20 +177,20 @@ Run `mise tasks` from anywhere in the repo to see what's available. The core one | `playwright:install` | Install Chromium for Playwright (one-time, idempotent). | | `lib:test` | Unit tests for `@vlandoss/env`. | | `lib:build` | Build `@vlandoss/env`. | -| `test:static` | JS & TS check across the workspace (`package` + `docsite`). | +| `check` | JS & TS check across the workspace (`package` + `docsite`). | | `test:e2e` | Run e2e for every example. | -| `examples:test:static` | JS & TS check across every example. | +| `examples:check` | JS & TS check across every example. | | `examples:bump` | `reinstall` the tarball in every example. | ### Per-example tasks (uniform across every `examples/*/mise.toml`) | Task | What it does | | ------------- | ------------------------------------------------------------------------- | -| `install` | Install deps with the example's native PM. Prepends `mise run //:env:pack`. | +| `setup` | Pack env + install deps with the example's native PM (depends on `//:env:pack`). | | `reinstall` | Force-reinstall the env tarball. | | `start` | Run the server (or `dev` / `build` / `preview` for the Vite-based ones). | | `test:e2e` | Playwright. | -| `test:static` | JS & TS check. | +| `check` | JS & TS check. | ## Why mise is the only API @@ -244,21 +243,19 @@ depends = ["//:env:pack"] If you're writing a new task and hit this error, use the `//:` prefix. -### `task not found: env:pack` (when running across examples) +### Fanning out a task across every example -If you write a root task that loops over examples, use `mise -C path run task` rather than `cd path && mise run task`. The latter inherits a stale shell context that can confuse the resolver: +Use mise's monorepo glob β€” it resolves against `[monorepo].config_roots` and runs in parallel (controlled by `MISE_JOBS`): ```toml -# good -run = "for d in examples/*/; do mise -C \"$d\" run test:e2e || exit 1; done" - -# bad β€” fails inside the orchestrator task context -run = "for d in examples/*/; do (cd \"$d\" && mise run test:e2e) || exit 1; done" +run = "mise run \"//examples/...:test:e2e\"" ``` +Avoid `for d in examples/*/; do ...; done` β€” it's sequential and predates this feature. The one place a bash loop still makes sense is `mise install -C "$d"` for per-example tool installs (bun, deno, etc.), since `mise install` doesn't accept the monorepo glob. + ### pnpm tries to install across the whole monorepo from inside an example -Because the example dirs sit *inside* the same directory tree as `pnpm-workspace.yaml`, pnpm thinks they're workspace members. They're not β€” but pnpm needs an explicit `--ignore-workspace` to honor that. The 6 pnpm-based examples already pass it in their `install` tasks; if you're adding a new pnpm-based example, do the same. +Because the example dirs sit *inside* the same directory tree as `pnpm-workspace.yaml`, pnpm thinks they're workspace members. They're not β€” but pnpm needs an explicit `--ignore-workspace` to honor that. The 6 pnpm-based examples already pass it in their `setup` tasks; if you're adding a new pnpm-based example, do the same. ### Deno can't import `@vlandoss/env` from the tarball diff --git a/docsite/src/components/landing/close.tsx b/docsite/src/components/landing/close.tsx index 9c7dc8c..596e9bb 100644 --- a/docsite/src/components/landing/close.tsx +++ b/docsite/src/components/landing/close.tsx @@ -71,7 +71,7 @@ export function Close() { Β· made at Β· - {LANDING_META.version} + + {LANDING_META.version} + Β· {LANDING_META.publishDate} diff --git a/docsite/src/components/landing/data.ts b/docsite/src/components/landing/data.ts index c3cdf94..bc31ee4 100644 --- a/docsite/src/components/landing/data.ts +++ b/docsite/src/components/landing/data.ts @@ -117,7 +117,9 @@ export const WHY_POINTS = [ export const LANDING_META = { version: "v0.2.0", + vlandUrl: "https://variable.land", githubUrl: "https://github.com/variableland/env", + npmUrl: "https://npmx.dev/package/@vlandoss/env", docsHref: "/docs", publishDate: "2026", } as const; diff --git a/docsite/src/components/landing/nav.tsx b/docsite/src/components/landing/nav.tsx index df8dd40..ef38918 100644 --- a/docsite/src/components/landing/nav.tsx +++ b/docsite/src/components/landing/nav.tsx @@ -21,9 +21,9 @@ export function LandingNav() { className=" relative z-10 flex items-center justify-between gap-3 border-b border-landing-border - px-16 py-[26px] - @max-[1100px]/dirA:px-10 @max-[1100px]/dirA:py-[22px] - @max-[760px]/dirA:px-7 @max-[760px]/dirA:py-[18px] + px-16 py-6.5 + @max-[1100px]/dirA:px-10 @max-[1100px]/dirA:py-5.5 + @max-[760px]/dirA:px-7 @max-[760px]/dirA:py-4.5 @max-[480px]/dirA:px-5 @max-[480px]/dirA:py-4 " > @@ -32,21 +32,21 @@ export function LandingNav() { @vlandoss/env - - {LANDING_META.version} - + + + {LANDING_META.version} + +