From eaa909648fa132fa771ded229a4eba4b0d8985ce Mon Sep 17 00:00:00 2001 From: Lenox Wiltshire Date: Tue, 7 Jul 2026 20:25:16 -0400 Subject: [PATCH 1/4] [chore]: makefile recipes call to npm, remove docsy scripts leftover, update workflows to call hugo cmds from workflow env and make deployment non-indexable Signed-off-by: Lenox Wiltshire --- .github/workflows/build-and-deploy-site.yml | 10 +- .github/workflows/build-and-preview-site.yml | 19 +- Makefile | 130 ++++++++---- go.mod | 2 +- package-lock.json | 198 ++++++------------- package.json | 37 ++-- 6 files changed, 198 insertions(+), 198 deletions(-) diff --git a/.github/workflows/build-and-deploy-site.yml b/.github/workflows/build-and-deploy-site.yml index 6970e59a..2e7636f5 100644 --- a/.github/workflows/build-and-deploy-site.yml +++ b/.github/workflows/build-and-deploy-site.yml @@ -43,8 +43,14 @@ jobs: - name: Setup site dependencies run: make setup + # Production build. The GitHub Pages base URL is per-fork, so it is passed + # here directly rather than baked into config or the standardized scripts. + # Mirrors 'npm run build:production' (hugo --cleanDestinationDir --minify --gc), + # with --baseURL added for the Pages deploy. - name: Build site - run: make build-production BASE_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/" + run: | + BASE_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/" + hugo --cleanDestinationDir --gc --minify --baseURL "${BASE_URL}" - name: Prepare Pages output run: touch public/.nojekyll @@ -55,4 +61,4 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} publish_branch: gh-pages publish_dir: ./public - keep_files: true + keep_files: true \ No newline at end of file diff --git a/.github/workflows/build-and-preview-site.yml b/.github/workflows/build-and-preview-site.yml index 1eedc4a5..7cbf196c 100644 --- a/.github/workflows/build-and-preview-site.yml +++ b/.github/workflows/build-and-preview-site.yml @@ -63,12 +63,27 @@ jobs: if: github.event.action != 'closed' run: make setup + # Preview build. The GitHub Pages preview URL is a per-PR subpath, so it is + # passed here directly rather than via the standardized scripts (whose + # build:preview targets Netlify's DEPLOY_PRIME_URL, not GitHub Pages). + # Mirrors 'npm run build:preview' (hugo --cleanDestinationDir -e dev -DFE + # --minify), with the computed --baseURL for the Pages subpath. - name: Build PR preview if: github.event.action != 'closed' run: | - make build-preview BASE_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr-preview/pr-${{ github.event.pull_request.number }}/" + PR_BASE_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr-preview/pr-${{ github.event.pull_request.number }}/" + hugo --cleanDestinationDir -e dev -DFE --minify --baseURL "${PR_BASE_URL}" touch public/.nojekyll + # Preview URLs are public GitHub Pages. Mark the whole deployment + # non-indexable so search engines don't crawl preview content or let it + # compete with production. Runs on the built public/ output. + - name: Make preview non-indexable + if: github.event.action != 'closed' + run: | + printf 'User-agent: *\nDisallow: /\n' > public/robots.txt + find public -name '*.html' -exec perl -0pi -e 's|||g; s|||g; s|||i unless /]+name="?robots"?[^>]+noindex, nofollow/i' {} + + - name: Deploy PR preview if: github.event.action != 'closed' uses: rossjrw/pr-preview-action@v1.6.3 @@ -94,4 +109,4 @@ jobs: with: preview-branch: gh-pages umbrella-dir: pr-preview - action: remove + action: remove \ No newline at end of file diff --git a/Makefile b/Makefile index 54a163c6..256ceb06 100644 --- a/Makefile +++ b/Makefile @@ -15,55 +15,101 @@ include .github/build/Makefile.core.mk include .github/build/Makefile.show-help.mk -#---------------------------------------------------------------------------- +# Changes to any main recipe in this Makefile, require a corresponding change in all other repositories subscribed to the 'meshery-academy' topic. + +# htmltest is fetched and run on demand via 'go run' (no install step). Pin it for +# reproducible link checks; leave as 'latest' to always use the newest release. +HTMLTEST_VERSION ?= latest +export HTMLTEST_VERSION + +# --------------------------------------------------------------------------- # Academy # --------------------------------------------------------------------------- -.PHONY: setup build build-production build-preview site clean check-go theme-update -BASE_URL ?= +# --------------------------------------------------------------------------- +# MAINTENANCE: Show help for available targets +# --------------------------------------------------------------------------- -## ------------------------------------------------------------ -----LOCAL_BUILDS: Show help for available targets - -## Local: Install site dependencies -setup: - @if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then \ - npm ci; \ - else \ - npm i; \ - fi - -## Local: Build site for local consumption -build: - BASE_URL="$(BASE_URL)" npm run build - -## CI: Build production site output -build-production: - BASE_URL="$(BASE_URL)" npm run build:production - -## CI: Build preview site output and mark it non-indexable -build-preview: - BASE_URL="$(BASE_URL)" npm run build:preview - -## Local: Build and run site locally with draft and future content enabled. -site: check-go - hugo server -D -F - -## Empty build cache and run on your local machine. -clean: - hugo --cleanDestinationDir - make setup - make site - -## ------------------------------------------------------------ -----MAINTENANCE: Show help for available targets +## Verify required commands and local dependencies are present. +check-deps: + @echo "Checking if 'npm' and local 'hugo' binary are present..." + @command -v npm > /dev/null || { echo "Error: 'npm' not found. Please install Node.js and npm."; exit 1; } + @test -x node_modules/.bin/hugo || { echo "Error: Hugo binary not found in node_modules. Please run 'make setup' first."; exit 1; } + @echo "Dependencies check passed." +## Validate Go is installed check-go: @echo "Checking if Go is installed..." - @command -v go > /dev/null || (echo "Go is not installed. Please install it before proceeding."; exit 1) + @command -v go > /dev/null || { echo "Go is not installed. Please install it before proceeding."; exit 1; } @echo "Go is installed." ## Update the academy-theme package to latest version -theme-update: - echo "Updating to latest academy-theme..." && \ - hugo mod get github.com/layer5io/academy-theme +theme-update: check-go check-deps + @echo "Updating to latest academy-theme..." + npm run update:theme + +# --------------------------------------------------------------------------- +# LOCAL BUILDS: Show help for available targets +# --------------------------------------------------------------------------- + +## Install site dependencies +setup: + npm install + +## Build the site locally with draft and future content enabled. +build: check-go check-deps + npm run build + +## Build the site for a deploy preview. +build-preview: check-go check-deps + npm run build:preview + +## Build the site for production. +build-production: check-go check-deps + npm run build:production + +## Build and run the site locally with live reload (draft and future content enabled). +site: check-go check-deps + npm run site + +## Build and serve the site once with the file-watcher off (no live reload). +site-no-watch: check-go check-deps + npm run site:no-watch + +## Empty the build cache, reinstall dependencies, and run the site locally. +clean: + npm run clean + $(MAKE) setup + $(MAKE) site + +## Check internal links in the built site (htmltest is fetched on demand via 'go run'). +check-links: check-go check-deps + npm run check:links + +## Format code using Prettier +format: + npm run format + +## Check formatting without writing changes. +format-check: + npm run format:check + +## Fix Markdown linting issues +lint-fix: + npx --yes markdownlint-cli2 --fix "content/**/*.md" + +.PHONY: \ + setup \ + build \ + build-preview \ + build-production \ + site \ + site-no-watch \ + clean \ + check-links \ + format \ + format-check \ + lint-fix \ + check-deps \ + check-go \ + theme-update \ No newline at end of file diff --git a/go.mod b/go.mod index 5b3607a3..1c6fc77e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/layer5io/academy-example go 1.24.5 // Uncomment line below when testing changes to the academy theme -replace github.com/layer5io/academy-theme v0.4.2 => ../academy-theme +// replace github.com/layer5io/academy-theme v0.4.2 => ../academy-theme replace github.com/FortAwesome/Font-Awesome v4.7.0+incompatible => github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3 diff --git a/package-lock.json b/package-lock.json index 73ccb904..c1aa9a05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,11 @@ "version": "0.12.0", "license": "Apache-2.0", "devDependencies": { - "autoprefixer": "^10.4.21", - "cross-env": "^7.0.3", + "autoprefixer": "^10.4.27", "hugo-extended": "0.158.0", "postcss": "^8.5.12", "postcss-cli": "^11.0.1", + "prettier": "3.8.3", "rtlcss": "^4.3.0" }, "optionalDependencies": { @@ -84,9 +84,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", + "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", "dev": true, "funding": [ { @@ -104,10 +104,9 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", + "browserslist": "^4.28.4", + "caniuse-lite": "^1.0.30001799", + "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, @@ -121,6 +120,19 @@ "postcss": "^8.1.0" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -148,9 +160,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz", + "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==", "dev": true, "funding": [ { @@ -168,10 +180,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001800", + "electron-to-chromium": "^1.5.387", + "node-releases": "^2.0.50", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -181,9 +194,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "version": "1.0.30001803", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz", + "integrity": "sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==", "dev": true, "funding": [ { @@ -271,40 +284,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/dependency-graph": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", @@ -316,9 +295,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.182", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz", - "integrity": "sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==", + "version": "1.5.389", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz", + "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==", "dev": true, "license": "ISC" }, @@ -353,16 +332,16 @@ } }, "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "dev": true, "license": "MIT", "engines": { "node": "*" }, "funding": { - "type": "patreon", + "type": "github", "url": "https://github.com/sponsors/rawify" } }, @@ -501,13 +480,6 @@ "node": ">=0.12.0" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -577,11 +549,14 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -593,16 +568,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/npm-check-updates": { "version": "18.0.1", "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-18.0.1.tgz", @@ -618,16 +583,6 @@ "npm": ">=8.12.1" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -790,6 +745,22 @@ "dev": true, "license": "MIT" }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -852,29 +823,6 @@ "node": ">=12.0.0" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -1032,9 +980,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -1062,22 +1010,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index b1bb173d..1f43f560 100644 --- a/package.json +++ b/package.json @@ -8,43 +8,44 @@ "author": "Docsy Authors", "license": "Apache-2.0", "bugs": "https://github.com/google/docsy-example/issues", + "private": true, "spelling": "cSpell:ignore docsy hugo htmltest precheck postbuild rtlcss -", "scripts": { - "_check:links": "echo IMPLEMENTATION PENDING for check-links; echo", "_hugo": "hugo --cleanDestinationDir", "_hugo-dev": "npm run _hugo -- -e dev -DFE", - "_local": "npx cross-env HUGO_MODULE_WORKSPACE=docsy.work", - "_serve": "npm run _hugo-dev -- --minify serve --renderToMemory", - "build": "sh -c 'hugo build --cleanDestinationDir ${BASE_URL:+--baseURL \"$BASE_URL\"}'", - "build:preview": "cross-env HUGO_ENVIRONMENT=production HUGO_ENV=production HUGO_PREVIEW=true sh -c 'hugo build -D --gc --buildFuture --cleanDestinationDir --minify ${BASE_URL:+--baseURL \"$BASE_URL\"}'", - "build:production": "cross-env HUGO_ENVIRONMENT=production HUGO_ENV=production sh -c 'hugo build -D --gc --buildFuture --cleanDestinationDir --minify ${BASE_URL:+--baseURL \"$BASE_URL\"}'", - "check:links:all": "HTMLTEST_ARGS= npm run _check:links", - "check:links": "npm run _check:links", + "_build": "npm run _hugo-dev", + "_site": "npm run _hugo-dev -- --minify server", + "_check:links": "echo \"Skipped: go run github.com/wjdp/htmltest@${HTMLTEST_VERSION:-latest} -s\"", + "build": "npm run _build", + "build:preview": "npm run _hugo-dev -- --minify --baseURL \"${DEPLOY_PRIME_URL:-/}\"", + "build:production": "npm run _hugo -- --minify --gc", + "site": "npm run _site", + "site:no-watch": "npm run _hugo-dev -- --minify --watch=false server", "clean": "rm -Rf public/* resources", - "local": "npm run _local -- npm run", "make:public": "git init -b main public", - "precheck:links:all": "npm run build", + "check:links": "npm run _check:links", "precheck:links": "npm run build", - "postbuild:preview": "printf 'User-agent: *\\nDisallow: /\\n' > public/robots.txt && find public -name '*.html' -exec perl -0pi -e 's|||g; s|||g; s|||i unless /]+name=\"?robots\"?[^>]+noindex, nofollow/i' {} +", + "postbuild:preview": "npm run _check:links", "postbuild:production": "npm run _check:links", - "serve": "npm run _serve", "test": "npm run check:links", - "update:dep": "npm install --save-dev autoprefixer@latest postcss-cli@latest", - "update:hugo": "npm install --save-dev --save-exact hugo-extended@latest", - "update:pkgs": "npx npm-check-updates -u" + "format": "prettier --write .", + "format:check": "prettier --check .", + "update:pkg:dep": "npm install --save-dev autoprefixer@latest postcss-cli@latest", + "update:pkg:hugo": "npm install --save-dev --save-exact hugo-extended@latest", + "update:pkgs": "npx npm-check-updates -u", + "update:theme": "hugo mod get github.com/layer5io/academy-theme" }, "devDependencies": { - "autoprefixer": "^10.4.21", - "cross-env": "^7.0.3", + "autoprefixer": "^10.4.27", "hugo-extended": "0.158.0", "postcss": "^8.5.12", "postcss-cli": "^11.0.1", + "prettier": "3.8.3", "rtlcss": "^4.3.0" }, "optionalDependencies": { "npm-check-updates": "^18.0.1" }, - "private": true, "prettier": { "proseWrap": "always", "singleQuote": true From 61f533c18e66afc91877b61b2f70b0c7aec439ee Mon Sep 17 00:00:00 2001 From: Lenox Wiltshire Date: Wed, 8 Jul 2026 02:34:10 -0400 Subject: [PATCH 2/4] [chore]: standardize build and publish publish and update wording in workflows Signed-off-by: Lenox Wiltshire --- .github/workflows/build-and-deploy-site.yml | 7 +++--- .github/workflows/build-and-preview-site.yml | 12 ++++------ .github/workflows/build-and-release.yml | 25 +++++++++++++------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build-and-deploy-site.yml b/.github/workflows/build-and-deploy-site.yml index 2e7636f5..eb8aaea0 100644 --- a/.github/workflows/build-and-deploy-site.yml +++ b/.github/workflows/build-and-deploy-site.yml @@ -43,10 +43,9 @@ jobs: - name: Setup site dependencies run: make setup - # Production build. The GitHub Pages base URL is per-fork, so it is passed - # here directly rather than baked into config or the standardized scripts. - # Mirrors 'npm run build:production' (hugo --cleanDestinationDir --minify --gc), - # with --baseURL added for the Pages deploy. + # Production build. The GitHub Pages base URL is per-fork, so it is passed here directly + # rather than baked into config or the standardized scripts. + # Mirrors 'npm run build:production' (hugo --cleanDestinationDir --minify --gc). - name: Build site run: | BASE_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/" diff --git a/.github/workflows/build-and-preview-site.yml b/.github/workflows/build-and-preview-site.yml index 7cbf196c..6743459f 100644 --- a/.github/workflows/build-and-preview-site.yml +++ b/.github/workflows/build-and-preview-site.yml @@ -63,11 +63,10 @@ jobs: if: github.event.action != 'closed' run: make setup - # Preview build. The GitHub Pages preview URL is a per-PR subpath, so it is - # passed here directly rather than via the standardized scripts (whose - # build:preview targets Netlify's DEPLOY_PRIME_URL, not GitHub Pages). - # Mirrors 'npm run build:preview' (hugo --cleanDestinationDir -e dev -DFE - # --minify), with the computed --baseURL for the Pages subpath. + # The GitHub Pages preview URL is a per-PR subpath, so it is passed here + # directly rather than via the standardized scripts (whose build:preview + # targets Netlify's DEPLOY_PRIME_URL, not GitHub Pages). + # Mirrors 'npm run build:preview' (hugo --cleanDestinationDir -e dev -DFE --minify). - name: Build PR preview if: github.event.action != 'closed' run: | @@ -76,8 +75,7 @@ jobs: touch public/.nojekyll # Preview URLs are public GitHub Pages. Mark the whole deployment - # non-indexable so search engines don't crawl preview content or let it - # compete with production. Runs on the built public/ output. + # non-indexable so search engines don't crawl preview content. - name: Make preview non-indexable if: github.event.action != 'closed' run: | diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 75928b03..186c13b3 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -15,7 +15,8 @@ on: academy-name: description: 'Name of the Academy represented by this repo' required: false - default: 'Academy' + default: 'Academy' + type: string version: description: 'Module version' required: false @@ -27,19 +28,27 @@ jobs: steps: - name: Checkout site - uses: actions/checkout@v5 + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true - - name: Setup Hugo Extended - uses: peaceiris/actions-hugo@v3 + - name: Setup Node + uses: actions/setup-node@v4 with: - hugo-version: '0.158.0' - extended: true + node-version: '20' + cache: 'npm' - name: Install dependencies run: make setup - name: Run production build test - run: make build + run: make build-production - name: Publish to layer5 academy id: academy @@ -47,7 +56,7 @@ jobs: with: orgId: ${{ github.event.inputs.orgId || secrets.ACADEMY_ORG_ID }} token: ${{ github.event.inputs.token || secrets.ACADEMY_TOKEN }} - academy-name: 'Academy' + academy-name: ${{ github.event.inputs.academy-name || 'Academy' }} version: ${{ github.event.inputs.version != '' && github.event.inputs.version || github.ref_name }} - name: Show response From ddde6366ca8fec40e9317cbc33cbd2375eb28e4b Mon Sep 17 00:00:00 2001 From: Lenox Wiltshire Date: Wed, 8 Jul 2026 23:21:47 -0400 Subject: [PATCH 3/4] [chore]: replace leftover package.json metadata Signed-off-by: Lenox Wiltshire --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1f43f560..b822f200 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { - "name": "docsy-example-site", + "name": "academy-example", "version": "0.12.0", "version.next": "0.12.1-dev-unreleased", - "description": "Example site that uses Docsy theme for technical documentation.", - "repository": "github:google/docsy-example", - "homepage": "https://example.docsy.dev", - "author": "Docsy Authors", + "description": "Example site for Academy", + "repository": "github:layer5io/academy-example", + "homepage": "https://layer5io.github.io/academy-example", + "author": "Layer5 Authors", "license": "Apache-2.0", - "bugs": "https://github.com/google/docsy-example/issues", + "bugs": "https://github.com/layer5io/academy-example/issues", "private": true, "spelling": "cSpell:ignore docsy hugo htmltest precheck postbuild rtlcss -", "scripts": { From 3ec4427c1e0faf1f967e52d082b0c69d7495a080 Mon Sep 17 00:00:00 2001 From: Lenox Wiltshire Date: Wed, 8 Jul 2026 23:35:25 -0400 Subject: [PATCH 4/4] [chore]: add htmltest config Signed-off-by: Lenox Wiltshire --- .htmltest.yml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .htmltest.yml diff --git a/.htmltest.yml b/.htmltest.yml new file mode 100644 index 00000000..4354005d --- /dev/null +++ b/.htmltest.yml @@ -0,0 +1,45 @@ +# htmltest configuration. +# Checks the built HTML in public/ for broken links, images, and scripts. +# External links are skipped at runtime via the -s flag in the check:links script. + +DirectoryPath: "public" + +CheckInternal: true +CheckExternal: true # skipped at runtime by -s; left true for when you drop -s +EnforceHTTPS: true # still flags real http:// links (e.g. exoscale.com) to fix + +# --- Silence intentional or non-blocking findings --- + +# Hugo serves pages as directories, so a link to "./foo" (no trailing slash) +# only causes a redirect, not a break. Don't treat these as errors. +IgnoreDirectoryMissingTrailingSlash: true + +# Alt-text issues are an accessibility backlog, not broken links. Empty alt is +# valid for decorative images. Re-enable (set these false) when you work the +# accessibility pass. +IgnoreAltEmpty: true +IgnoreAltMissing: true + +# Deliberate example URLs in workshop content (intentionally http, not real +# reachable hosts). These skip HTTPS enforcement; genuine http links elsewhere +# (exoscale.com, etc.) are NOT listed here, so they still surface for fixing. +IgnoreHTTPS: + - '^http://localhost' + - 'votingapp\.(com|cc)' + - 'nip\.io' + - 'thesecretlivesofdata\.com' + +# Directories in public/ to skip entirely (adjust per repo as needed). +# Theme/shortcode demonstration pages full of intentional example links and +# placeholder image paths. Not real content; skip the whole section. +IgnoreDirs: + - 'content-formatting-examples' + +# Cache external-link results for fast repeat runs (stored under tmp/.htmltest; +# add tmp/ to .gitignore). Harmless under -s. +CacheExpires: "336h" + + +# Known-noisy or intentionally-unreachable URLs to ignore (regex). +# IgnoreURLs: +# - "^https://linkedin\\.com/" \ No newline at end of file