diff --git a/.changeset/no-docker.md b/.changeset/no-docker.md new file mode 100644 index 000000000..3bb68cf6e --- /dev/null +++ b/.changeset/no-docker.md @@ -0,0 +1,20 @@ +--- +'@pmndrs/docs': major +--- + +Drop Docker. `npx @pmndrs/docs build` does the same build, so the image, the `Dockerfile` and +the publish steps that maintained them are gone. `ghcr.io/pmndrs/docs` stops being pushed — +its existing tags stay in the registry, frozen. + +Major because of the git tag, not the inputs: releases force-move `vX`, so anything short of a +major would slide every caller pinning `build.yml@v3` onto the Docker-free workflow. `@v3` +keeps building through the image until its repository moves to `@v4`. + +`build.yml` itself keeps every input, every environment variable and the same Pages artifact. +Only the build step changes, and `docker_tag` gives way to `version` — an npm version or range. + +The job keeps `id-token: write` — no longer to attest a Docker image, now to sign the npm +publish with trusted publishing. + +`preview.sh` builds through the CLI too, and reads its options straight from the environment +rather than forwarding each one into a container. diff --git a/.changeset/npm-cli.md b/.changeset/npm-cli.md index a18ee8e82..c2d690645 100644 --- a/.changeset/npm-cli.md +++ b/.changeset/npm-cli.md @@ -4,9 +4,9 @@ Publish the generator to npm, as `npx @pmndrs/docs build`. -`--format website` statically exports the documentation site, as the Docker image does. +`--format website` statically exports the documentation site. `--format fragment` — the default — compiles MDX to plain HTML with no layout, stylesheet or script, either from a folder or from stdin, and needs nothing but node. -`bin/build.mjs` is gone: it predated the Docker image, was never published, and built a server -bundle rather than a static export. +`bin/build.mjs` is gone: it was never published, and built a server bundle rather than a +static export. diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index e5915db4c..000000000 --- a/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -out -.next \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 99cbf4159..35e3d408b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,10 +58,10 @@ on: theme_caution: type: string default: '#da3633' - docker_tag: + version: type: string - default: '3' - description: 'Docker image tag for ghcr.io/pmndrs/docs' + default: '4' + description: 'npm version or range of @pmndrs/docs to build with' jobs: build-job: @@ -76,47 +76,16 @@ jobs: # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#example-of-setting-an-output-parameter - id: set-base-path run: echo "BASE_PATH=${{ inputs.base_path || steps.configurepages.outputs.base_path }}" >> "$GITHUB_OUTPUT" - - run: | - set -ex - - docker run --rm --init \ - -v "./$MDX":/app/docs \ - -e MDX \ - -e NEXT_PUBLIC_LIBNAME \ - -e NEXT_PUBLIC_LIBNAME_SHORT \ - -e NEXT_PUBLIC_LIBNAME_DOTSUFFIX_LABEL \ - -e NEXT_PUBLIC_LIBNAME_DOTSUFFIX_HREF \ - -e BASE_PATH \ - -e DIST_DIR \ - -e OUTPUT \ - -e HOME_REDIRECT \ - -e MDX_BASEURL \ - -e SOURCECODE_BASEURL \ - -e EDIT_BASEURL \ - -e NEXT_PUBLIC_URL \ - -e ICON \ - -e LOGO \ - -e GITHUB \ - -e DISCORD \ - -e THEME_PRIMARY \ - -e THEME_SCHEME \ - -e THEME_CONTRAST \ - -e THEME_NOTE \ - -e THEME_TIP \ - -e THEME_IMPORTANT \ - -e THEME_WARNING \ - -e THEME_CAUTION \ - -e CONTRIBUTORS_PAT \ - ghcr.io/pmndrs/docs:${{ inputs.docker_tag }} pnpm run build + - uses: actions/setup-node@v6 + with: + node-version: 24 + - run: npx -y @pmndrs/docs@${{ inputs.version }} build "${{ inputs.mdx }}" out --format website env: - MDX: ${{ inputs.mdx }} NEXT_PUBLIC_LIBNAME: ${{ inputs.libname }} NEXT_PUBLIC_LIBNAME_SHORT: ${{ inputs.libname_short }} NEXT_PUBLIC_LIBNAME_DOTSUFFIX_LABEL: ${{ inputs.libname_dotsuffix_label }} NEXT_PUBLIC_LIBNAME_DOTSUFFIX_HREF: ${{ inputs.libname_dotsuffix_href }} BASE_PATH: ${{ steps.set-base-path.outputs.BASE_PATH }} - DIST_DIR: '${{ inputs.mdx }}/out${{ steps.set-base-path.outputs.BASE_PATH }}' - OUTPUT: 'export' HOME_REDIRECT: ${{ inputs.home_redirect }} MDX_BASEURL: 'https://github.com/${{ github.repository }}/raw/${{ github.head_ref || github.ref_name }}/${{ inputs.mdx }}' SOURCECODE_BASEURL: 'https://github.com/${{ github.repository }}/tree/${{ github.head_ref || github.ref_name }}' @@ -138,4 +107,4 @@ jobs: - uses: actions/upload-pages-artifact@v5 with: - path: ${{ inputs.mdx }}/out${{ steps.set-base-path.outputs.BASE_PATH }} + path: out diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54abb85ff..e11496a91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - jobs: main-job: runs-on: ubuntu-latest @@ -21,8 +17,7 @@ jobs: permissions: contents: write pull-requests: write - packages: write - attestations: write + # npm trusted publishing signs the release with an OIDC token id-token: write # Update the Production/Preview environment with the Vercel deployed URL @@ -135,48 +130,6 @@ jobs: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} - # - # ██████ ██████ ██████ ██ ██ ███████ ██████ - # ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ - # ██ ██ ██ ██ ██ █████ █████ ██████ - # ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ - # ██████ ██████ ██████ ██ ██ ███████ ██ ██ - # - - - uses: docker/login-action@v3 - if: steps.check.outputs.changed == 'true' - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - uses: docker/metadata-action@v5 - if: steps.check.outputs.changed == 'true' - id: meta - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=raw,value=latest - type=raw,value=${{ steps.get-version.outputs.major_version }} - type=raw,value=${{ steps.get-version.outputs.version }} - - - uses: docker/build-push-action@v6 - id: push - with: - context: . - # Push only if a new version was published - push: ${{ steps.check.outputs.changed == 'true' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - - uses: actions/attest-build-provenance@v3 - if: steps.check.outputs.changed == 'true' - with: - subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - subject-digest: ${{ steps.push.outputs.digest }} - push-to-registry: true - - name: git tags if: steps.check.outputs.changed == 'true' run: | diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 51da550e3..3d2008091 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -17,6 +17,10 @@ jobs: id-token: write uses: pmndrs/docs/.github/workflows/build.yml@main with: + # Whatever is published, rather than a version number this repository would have to keep + # in step with itself. Our own site is then built by exactly what consumers install — + # a broken release shows up here before anyone downstream moves to it. + version: 'latest' mdx: 'docs' libname: 'Poimandres' libname_short: 'pmndrs' diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c9fb451f7..000000000 --- a/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM node:24-alpine - -RUN apk add --no-cache libc6-compat git && apk update - -WORKDIR /app - -# Copy package.json first so corepack can read the packageManager field -COPY package.json pnpm-lock.yaml ./ - -# Enable corepack and prepare pnpm (reads version from package.json) -RUN corepack enable && corepack prepare --activate - -RUN pnpm install --frozen-lockfile - -COPY . . \ No newline at end of file diff --git a/README.md b/README.md index 77d7591de..016990924 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ $ npx @pmndrs/docs build docs out # one .html per .mdx, asset $ npx @pmndrs/docs build docs out --format website # the whole website, statically exported ``` -`--format fragment` (the default) needs nothing but node — no Docker, no `next build`. A +`--format fragment` (the default) needs nothing but node — no `next build`, no bundler. A fragment is the compiled MDX and nothing else: no layout, no stylesheet, no script. Mermaid diagrams stay fenced blocks, and Sandpack shows its code without the editor. @@ -22,18 +22,19 @@ one falls back to the environment variable it maps to, the same ones [configuration](docs/getting-started/introduction.mdx#Configuration) documents.
-Docker +Preview a folder of MDX, served ```sh $ curl -sL https://raw.githubusercontent.com/pmndrs/docs/refs/heads/main/preview.sh | \ MDX="docs" \ ICON="🥑" \ - DOCKER_IMAGE="ghcr.io/pmndrs/docs:latest" \ sh ``` -- you can pass any option from [configuration](docs/getting-started/introduction.mdx#Configuration) -- in `DOCKER_IMAGE`, you can specify any `:tag` value from [docs packages](https://github.com/pmndrs/docs/pkgs/container/docs) container registry +Builds the website, then serves it — alongside the MDX folder itself, so relative assets +resolve while you edit. Any option from +[configuration](docs/getting-started/introduction.mdx#Configuration) goes in the same way, and +`VERSION` picks a published version of the CLI.
@@ -41,7 +42,7 @@ $ curl -sL https://raw.githubusercontent.com/pmndrs/docs/refs/heads/main/preview Every push to `main` redeploys [docs.pmnd.rs](https://docs.pmnd.rs) via [ci.yml](.github/workflows/ci.yml) — no [changeset](.changeset/) needed for that. -Add one (`pnpm changeset`) only when downstream consumers pinning `pmndrs/docs/.github/workflows/build.yml@v3` or `ghcr.io/pmndrs/docs:v3` should pull the change. It bumps [`package.json`](package.json), tags `vX.Y.Z` + `vX`, and publishes a matching Docker image — so `@v3` resolves to the latest. +Add one (`pnpm changeset`) only when downstream consumers pinning `pmndrs/docs/.github/workflows/build.yml@v4` or `@pmndrs/docs@4` should pull the change. It bumps [`package.json`](package.json), publishes to npm, and tags `vX.Y.Z` + `vX` — so `@v4` resolves to the latest. TL;DR — site-only tweak: skip. Anything consumers see (workflow, build behavior, templates): add one. diff --git a/docs/getting-started/introduction.mdx b/docs/getting-started/introduction.mdx index 8a797ee31..a4725f7e9 100644 --- a/docs/getting-started/introduction.mdx +++ b/docs/getting-started/introduction.mdx @@ -204,11 +204,9 @@ $ ( http://localhost:3000 -### Docker +### CLI -```sh -$ docker build -t pmndrs-docs . -``` +No clone, no install — the published CLI does the same build: ```sh $ cd ~/code/pmndrs/react-three-fiber @@ -217,69 +215,20 @@ $ ( export _PORT=60141 - export MDX=docs export NEXT_PUBLIC_LIBNAME="React Three Fiber" export NEXT_PUBLIC_LIBNAME_SHORT="r3f" - export NEXT_PUBLIC_LIBNAME_DOTSUFFIX_LABEL="docs" - export NEXT_PUBLIC_LIBNAME_DOTSUFFIX_HREF="https://docs.pmnd.rs" export BASE_PATH=/toto - export DIST_DIR="$MDX/out$BASE_PATH" - export OUTPUT=export export HOME_REDIRECT=/getting-started/introduction export MDX_BASEURL=http://localhost:$_PORT - export SOURCECODE_BASEURL= - export EDIT_BASEURL= - export NEXT_PUBLIC_URL= export ICON=🇨🇭 - export LOGO=/logo.png export GITHUB=https://github.com/pmndrs/react-three-fiber - export DISCORD=https://discord.com/channels/740090768164651008/740093168770613279 - export THEME_PRIMARY="#323e48" - export THEME_SCHEME="tonalSpot" - export THEME_CONTRAST="0" - export THEME_NOTE="#1f6feb" - export THEME_TIP="#238636" - export THEME_IMPORTANT="#8957e5" - export THEME_WARNING="#d29922" - export THEME_CAUTION="#da3633" - export CONTRIBUTORS_PAT= - rm -rf "$MDX/out" - - docker run --rm --init -it \ - -v "./$MDX":/app/docs \ - -e MDX \ - -e NEXT_PUBLIC_LIBNAME \ - -e NEXT_PUBLIC_LIBNAME_SHORT \ - -e NEXT_PUBLIC_LIBNAME_DOTSUFFIX_LABEL \ - -e NEXT_PUBLIC_LIBNAME_DOTSUFFIX_HREF \ - -e BASE_PATH \ - -e DIST_DIR \ - -e OUTPUT \ - -e HOME_REDIRECT \ - -e MDX_BASEURL \ - -e SOURCECODE_BASEURL \ - -e EDIT_BASEURL \ - -e NEXT_PUBLIC_URL \ - -e ICON \ - -e LOGO \ - -e GITHUB \ - -e DISCORD \ - -e THEME_PRIMARY \ - -e THEME_SCHEME \ - -e THEME_CONTRAST \ - -e THEME_NOTE \ - -e THEME_TIP \ - -e THEME_IMPORTANT \ - -e THEME_WARNING \ - -e THEME_CAUTION \ - -e CONTRIBUTORS_PAT \ - pmndrs-docs pnpm run build + npx -y @pmndrs/docs build docs docs/out --format website kill $(lsof -ti:"$_PORT") - npx serve $MDX -p $_PORT --no-port-switching --no-clipboard & + npx serve docs -p $_PORT --no-port-switching --no-clipboard & - npx -y serve "$MDX/out" & + npx -y serve docs/out & wait ) @@ -287,6 +236,8 @@ $ ( Then go to: http://localhost:3000 +Every option above has a flag too — `npx @pmndrs/docs build --help` lists them. + ## Agents `llms.txt` dumps and the pmndrs MCP server moved to their own page: [Agents](/agents/introduction). diff --git a/preview.sh b/preview.sh index fa46a4ec7..2c3796531 100755 --- a/preview.sh +++ b/preview.sh @@ -4,44 +4,17 @@ main() { trap 'kill -9 0' SIGINT export _PORT="${_PORT:-60141}" - export DOCKER_IMAGE="${DOCKER_IMAGE:-ghcr.io/pmndrs/docs:latest}" + export VERSION="${VERSION:-latest}" export MDX="${MDX:-docs}" export NEXT_PUBLIC_LIBNAME="${NEXT_PUBLIC_LIBNAME:-Poimandres}" + # Relative assets resolve against the MDX folder, served below on the same port + export MDX_BASEURL="${MDX_BASEURL:-http://localhost:$_PORT}" rm -rf "$MDX/out" - # docker build -t $DOCKER_IMAGE . - - docker run --rm --init -t \ - -v "./$MDX":/app/docs \ - -e MDX \ - -e NEXT_PUBLIC_LIBNAME \ - -e NEXT_PUBLIC_LIBNAME_SHORT \ - -e NEXT_PUBLIC_LIBNAME_DOTSUFFIX_LABEL \ - -e NEXT_PUBLIC_LIBNAME_DOTSUFFIX_HREF \ - -e BASE_PATH \ - -e DIST_DIR="$MDX/out$BASE_PATH" \ - -e OUTPUT=export \ - -e HOME_REDIRECT \ - -e MDX_BASEURL=http://localhost:$_PORT \ - -e SOURCECODE_BASEURL \ - -e EDIT_BASEURL \ - -e NEXT_PUBLIC_URL \ - -e ICON \ - -e LOGO \ - -e GITHUB \ - -e DISCORD \ - -e THEME_PRIMARY \ - -e THEME_SCHEME \ - -e THEME_CONTRAST \ - -e THEME_NOTE \ - -e THEME_TIP \ - -e THEME_IMPORTANT \ - -e THEME_WARNING \ - -e THEME_CAUTION \ - -e CONTRIBUTORS_PAT \ - $DOCKER_IMAGE pnpm run build || exit 1 + # Every other option is read straight from the environment — same process, nothing to forward + npx -y "@pmndrs/docs@$VERSION" build "$MDX" "$MDX/out" --format website || exit 1 kill $(lsof -ti:"$_PORT") npx serve $MDX -p $_PORT --no-port-switching --no-clipboard & @@ -51,4 +24,4 @@ main() { wait } -main \ No newline at end of file +main diff --git a/src/cli/main.ts b/src/cli/main.ts index 852460ea1..955e222ef 100644 --- a/src/cli/main.ts +++ b/src/cli/main.ts @@ -11,8 +11,7 @@ import { buildWebsite } from './website' * * Each carries the environment variable the app reads it as, so that a flag and its variable * are declared in one place, and `--help` says which is which. `Option.env()` then does the - * fallback itself, which is what keeps the Docker image and the reusable workflow working - * with no flags at all. + * fallback itself, which is what keeps the reusable workflow working with no flags at all. */ const websiteOptions = [ new Option('--libname ', 'Library name, e.g. "React Three Fiber"').env(