From ed4ff72166cbf2e198b0a044e90b09535f86e0be Mon Sep 17 00:00:00 2001 From: scriptautomate-bc <204508229+scriptautomate-bc@users.noreply.github.com> Date: Mon, 13 Jul 2026 16:05:03 -0500 Subject: [PATCH 1/3] Pull from npm, don't save to source repo --- .devcontainer/Dockerfile | 10 ++++ .devcontainer/devcontainer.json | 15 +++--- .github/workflows/gh-pages.yml | 9 ++++ .github/workflows/pr-checks.yml | 9 ++++ .gitignore | 2 + .node-version | 1 + README.md | 13 +++++ themes/pydata/.gitignore | 1 + themes/pydata/hugo.toml | 35 ++++++++++++ themes/pydata/layouts/_partials/head.html | 2 +- .../layouts/_partials/head/bootstrap-js.html | 15 ++++++ .../layouts/_partials/head/fontawesome.html | 15 ++++++ themes/pydata/layouts/baseof.html | 2 +- themes/pydata/package-lock.json | 50 ++++++++++++++++++ themes/pydata/package.json | 9 ++++ themes/pydata/static/scripts/bootstrap.js | 3 -- themes/pydata/static/scripts/fontawesome.js | 3 -- .../static/styles/pydata-sphinx-theme.css | 8 +-- .../fontawesome/webfonts/fa-brands-400.woff2 | Bin 110088 -> 0 bytes .../fontawesome/webfonts/fa-regular-400.woff2 | Bin 18924 -> 0 bytes .../fontawesome/webfonts/fa-solid-900.woff2 | Bin 114740 -> 0 bytes 21 files changed, 183 insertions(+), 19 deletions(-) create mode 100644 .node-version create mode 100644 themes/pydata/.gitignore create mode 100644 themes/pydata/layouts/_partials/head/bootstrap-js.html create mode 100644 themes/pydata/layouts/_partials/head/fontawesome.html create mode 100644 themes/pydata/package-lock.json create mode 100644 themes/pydata/package.json delete mode 100644 themes/pydata/static/scripts/bootstrap.js delete mode 100644 themes/pydata/static/scripts/fontawesome.js delete mode 100644 themes/pydata/static/vendor/fontawesome/webfonts/fa-brands-400.woff2 delete mode 100644 themes/pydata/static/vendor/fontawesome/webfonts/fa-regular-400.woff2 delete mode 100644 themes/pydata/static/vendor/fontawesome/webfonts/fa-solid-900.woff2 diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 464ae9c..0a64b34 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -16,5 +16,15 @@ RUN HUGO_VERSION="$(cat /tmp/.hugo-version)" \ && apt-get install /tmp/hugo.deb -y \ && rm /tmp/hugo.deb /tmp/.hugo-version +# Install Node.js (needed to `npm ci` the FontAwesome/Bootstrap build-time +# deps in themes/pydata). Version is pinned in .node-version at the repo +# root — the same file CI's actions/setup-node reads — so the devcontainer +# and GitHub Actions never drift apart. +COPY .node-version /tmp/.node-version +RUN NODE_VERSION="$(cat /tmp/.node-version)" \ + && curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o /tmp/node.tar.xz \ + && tar -xJf /tmp/node.tar.xz --strip-components=1 -C /usr/local \ + && rm /tmp/node.tar.xz /tmp/.node-version + # Help avoid "unsupported locale setting" in Sphinx RUN echo "export LC_ALL=C.UTF-8" > ~/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index abe7bc6..c59e473 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -17,17 +17,18 @@ }, // Features to add to the dev container. More info: https://containers.dev/features. - // "features": { - // node / npm is required for markdownlint-cli2 - // By default, installs lts version - // "ghcr.io/devcontainers/features/node:1": {} - // }, + // Node.js itself is installed directly in the Dockerfile (pinned via the + // root .node-version file), not via this feature — avoids two divergent + // install paths. + // "features": {}, // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "" + // Install the theme's build-time npm deps (FontAwesome/Bootstrap) after + // the workspace is mounted — a Dockerfile RUN step would get shadowed by + // the workspace bind mount, since node_modules isn't part of the repo. + "postCreateCommand": "cd themes/pydata && npm ci", // There is also a postStartCommand that executes every time the container starts. // The parameters behave exactly like postCreateCommand, but the commands execute on start rather than create. diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 27fcccc..8974130 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -49,6 +49,15 @@ jobs: uses: actions/checkout@v4 - name: Install Hugo CLI uses: ./.github/actions/setup-hugo + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'npm' + cache-dependency-path: themes/pydata/package-lock.json + - name: Install npm dependencies + working-directory: themes/pydata + run: npm ci - name: Setup Pages id: pages uses: actions/configure-pages@v5 diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 3a4aa3f..497db6d 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -27,6 +27,15 @@ jobs: uses: actions/checkout@v4 - name: Install Hugo CLI uses: ./.github/actions/setup-hugo + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'npm' + cache-dependency-path: themes/pydata/package-lock.json + - name: Install npm dependencies + working-directory: themes/pydata + run: npm ci - name: Build with Hugo env: HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache diff --git a/.gitignore b/.gitignore index dfb1e1c..b2cf406 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ static/images/.DS_Store .env.* *.pem *.key +sandbox/ +node_modules/ diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..ba33190 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20.19.2 diff --git a/README.md b/README.md index 15e6049..cd6eb0c 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,17 @@ This repository is for the main static site of https://saltproject.io, built wit - The exact version pinned for this project is tracked in the root `.hugo-version` file. The devcontainer and CI both install that exact version automatically (see `.devcontainer/Dockerfile` and `.github/actions/setup-hugo`), so it only needs to be updated in one place. - Must be the `extended` version, and at least the minimum declared in the vendored `themes/pydata` theme's `hugo.toml` (`module.hugoVersion.min`). - This was built with the `extended` version of Hugo, which is required. +- Node.js — version pinned in the root `.node-version` file, same single-source-of-truth pattern as `.hugo-version`. Needed to install the theme's FontAwesome/Bootstrap build-time dependencies (see [FontAwesome and Bootstrap](#fontawesome-and-bootstrap-npm-at-build-time)). - Git - Python 3.14+ (only needed to run `scripts/validate-tags.py` locally) ### Build a local preview ```bash +# Install the theme's build-time npm dependencies (FontAwesome/Bootstrap) — +# only needs to be re-run when themes/pydata/package.json changes. +cd themes/pydata && npm ci && cd - + # Serves for viewing changes locally # Dynamically loads updates when changes happen in repo hugo serve @@ -195,6 +200,14 @@ The `scripts` folder holds standalone helper scripts used in local development a - `.github/workflows/gh-pages.yml` — builds the site on every push, and deploys it to GitHub Pages when the push is a tag matching `v**` (see [Push the current `main` branch to the live site](#push-the-current-main-branch-to-the-live-site)). Deploy-time (`pages`/`id-token` write) permissions are scoped to just the `deploy` job; it never triggers on `pull_request`. - `.github/actions/setup-hugo` — local composite action shared by both workflows above to install the Hugo CLI. Defaults to the version pinned in the root `.hugo-version` file — the same file the devcontainer's `Dockerfile` reads — so the required Hugo version only needs to be maintained in that one place. +### FontAwesome and Bootstrap (npm, at build time) + +`themes/pydata` doesn't vendor FontAwesome or Bootstrap as committed files. `themes/pydata/package.json` pins the exact versions (FontAwesome's JS+SVG icon kit, Bootstrap's JS bundle); Hugo's `[[module.mounts]]` (in `themes/pydata/hugo.toml`) mounts the relevant prebuilt files straight out of `node_modules` into the asset pipeline, and `themes/pydata/layouts/_partials/head/{fontawesome,bootstrap-js}.html` load them through Hugo Pipes (fingerprinted in production builds). This means: + +- You need to run `npm ci` inside `themes/pydata` before `hugo build`/`hugo server` will work — the devcontainer does this automatically via `postCreateCommand`; CI does it via an `actions/setup-node` + `npm ci` step in both workflows. +- Their license text isn't duplicated anywhere in this repo — it ships inside the respective (gitignored) npm packages under `themes/pydata/node_modules/.../LICENSE*`. +- The Node.js version used for this is pinned in the root `.node-version` file, following the same single-source-of-truth pattern as `.hugo-version`. + ## Credits The `themes/pydata` theme vendored in this repository is a Hugo port of the [PyData Sphinx Theme](https://github.com/pydata/pydata-sphinx-theme) ([docs](https://pydata-sphinx-theme.readthedocs.io/en/stable/)), originally built for Sphinx documentation sites. Credit to the PyData Sphinx Theme authors and contributors for the design and functionality this port is based on. diff --git a/themes/pydata/.gitignore b/themes/pydata/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/themes/pydata/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/themes/pydata/hugo.toml b/themes/pydata/hugo.toml index 45e66e7..49fe3f1 100644 --- a/themes/pydata/hugo.toml +++ b/themes/pydata/hugo.toml @@ -7,6 +7,41 @@ title = 'My New Hugo Project' extended = true min = '0.162.1' + # Declaring any [[module.mounts]] disables Hugo's implicit default mounts + # for this module, so the standard component dirs must be re-declared + # explicitly alongside the new npm-sourced vendor mounts below. + [[module.mounts]] + source = "content" + target = "content" + [[module.mounts]] + source = "static" + target = "static" + [[module.mounts]] + source = "layouts" + target = "layouts" + [[module.mounts]] + source = "data" + target = "data" + [[module.mounts]] + source = "assets" + target = "assets" + [[module.mounts]] + source = "i18n" + target = "i18n" + [[module.mounts]] + source = "archetypes" + target = "archetypes" + + # Build-time-only npm deps (FontAwesome JS+SVG icon kit, Bootstrap JS + # bundle). Requires `npm install` in themes/pydata before + # `hugo build`/`hugo server`. See themes/pydata/package.json. + [[module.mounts]] + source = "node_modules/@fortawesome/fontawesome-free/js/all.min.js" + target = "assets/vendor/fontawesome/all.min.js" + [[module.mounts]] + source = "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" + target = "assets/vendor/bootstrap/bootstrap.bundle.min.js" + # --------------------------------------------------------------------------- # Default menus (overridable by site hugo.toml) # --------------------------------------------------------------------------- diff --git a/themes/pydata/layouts/_partials/head.html b/themes/pydata/layouts/_partials/head.html index 9794d80..fec9885 100644 --- a/themes/pydata/layouts/_partials/head.html +++ b/themes/pydata/layouts/_partials/head.html @@ -28,7 +28,7 @@ {{- end }} - +{{ partial "head/fontawesome.html" . }} {{- if not site.Params.disable_search }} + {{- else }} + {{- with . | fingerprint }} + + {{- end }} + {{- end }} +{{- end }} diff --git a/themes/pydata/layouts/_partials/head/fontawesome.html b/themes/pydata/layouts/_partials/head/fontawesome.html new file mode 100644 index 0000000..78a56bf --- /dev/null +++ b/themes/pydata/layouts/_partials/head/fontawesome.html @@ -0,0 +1,15 @@ +{{- /* + FontAwesome's JS+SVG icon kit, mounted from node_modules via + [[module.mounts]] in hugo.toml (see themes/pydata/package.json). It's + already a prebuilt minified bundle, so no js.Build step is needed — just + fingerprint it in production. +*/ -}} +{{- with resources.Get "vendor/fontawesome/all.min.js" }} + {{- if hugo.IsDevelopment }} + + {{- else }} + {{- with . | fingerprint }} + + {{- end }} + {{- end }} +{{- end }} diff --git a/themes/pydata/layouts/baseof.html b/themes/pydata/layouts/baseof.html index d343a80..30bc42e 100644 --- a/themes/pydata/layouts/baseof.html +++ b/themes/pydata/layouts/baseof.html @@ -63,7 +63,7 @@ {{- /* Scripts at end of body */ -}} - +{{ partial "head/bootstrap-js.html" . }}