From 49cc4c7336cf95c78f3e42f3935d2febd6a6143d Mon Sep 17 00:00:00 2001 From: Artem Kladov Date: Sun, 5 Jul 2026 20:04:55 +0300 Subject: [PATCH 1/2] [delivery-kit] Add PDF/DOCX export pipeline - Introduce multi-stage werf build for print artefact generation using WeasyPrint and Pandoc inside a dedicated Ubuntu-based image; the print-artifacts stage consumes the built site via an embedded HTTP server, runs the export script per locale, and feeds results into the final web image automatically on deploy - Enable the print output format in Hugo site configuration and documentation landing pages for both locales; add per-language PDF title parameters and the downloads shortcode to surface download links on the documentation index - Restructure the Makefile with a new pdf target that orchestrates werf build and container-based artefact extraction, add ARM cross-compilation platform detection, and migrate help output to self-documenting awk-parsed annotations - Bump hugo-web-product-module dependency from v0.1.17 to v0.1.20 to pull in required print layout and export script support Signed-off-by: Artem Kladov --- Makefile | 99 ++++++++++++++++++------------ README.md | 16 +++++ config/_default/hugo.yaml | 5 ++ content/documentation/_index.md | 3 + content/documentation/_index.ru.md | 3 + go.mod | 2 +- go.sum | 4 +- werf.yaml | 67 +++++++++++++++++++- 8 files changed, 155 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 3a6928e..ecded69 100644 --- a/Makefile +++ b/Makefile @@ -1,72 +1,91 @@ # Makefile for the Hugo website +PLATFORM_NAME := $(shell uname -p) +ifneq ($(filter arm%,$(PLATFORM_NAME)),) + export WERF_PLATFORM=linux/amd64 +endif + +.DEFAULT_GOAL := help + # Tools / variables (can be overridden on the command line) HUGO ?= hugo BIND ?= 0.0.0.0 SERVE_FLAGS ?= --cleanDestinationDir --bind=$(BIND) HUGOFLAGS ?= --minify MARKDOWNLINT_VERSION ?= v0.45.0 +WERF ?= werf WERF_PLATFORM ?= linux/amd64 CURRENT_UID ?= $(shell id -u) CURRENT_GID ?= $(shell id -g) PORTS_TO_FREE ?= 80 1313 1314 -.PHONY: help serve build down lint-markdown lint-markdown-fix mod -.PHONY: help serve build down lint-markdown lint-markdown-fix mod free-ports - -help: - @echo "Usage: make [target]" - @echo - @echo "Common targets:" - @echo " up Start documentation (available at http://localhost and http://ru.localhost)" - @echo " serve Start Hugo dev server (hugo serve --cleanDestinationDir)" - @echo " build Build the site to ./public" - @echo " down Stop and remove documentation containers" - @echo " lint-markdown Lint markdown files" - @echo " lint-markdown-fix Fix markdown files automatically" - @echo " mod Clean up Hugo modules (hugo mod tidy)" - @echo " help Show this help" - @echo - @echo "Variables (can be overridden):" - @echo " HUGO=$(HUGO)" - @echo " PORT=$(PORT)" - @echo " BIND=$(BIND)" - @echo " BASEURL=$(BASEURL)" - @echo " MARKDOWNLINT_VERSION=$(MARKDOWNLINT_VERSION)" - -up: +PRODUCT_CODE ?= $(shell awk '/^ productCode:/ {print tolower($$2); exit}' config/_default/hugo.yaml) + +##@ Main + +up: ## Start documentation (available at http://localhost and http://ru.localhost) @$(MAKE) down @$(MAKE) free-ports @UID=$(CURRENT_UID) GID=$(CURRENT_GID) docker compose up -free-ports: - @containers="$$(for port in $(PORTS_TO_FREE); do docker ps -q --filter "publish=$$port"; done | sort -u)"; \ - if [ -n "$$containers" ]; then \ - echo "Stopping containers using ports $(PORTS_TO_FREE): $$containers"; \ - docker stop $$containers; \ - fi - -down: - docker compose rm -f - docker compose down --remove-orphans - -serve: +serve: ## Start Hugo dev server (hugo serve --cleanDestinationDir) $(HUGO) serve $(SERVE_FLAGS) -build: +build: ## Build the site to ./public @echo "Building site to ./public..." $(HUGO) $(HUGOFLAGS) -lint-markdown: +pdf: ## Build the site and generate PDF+DOCX exports via werf + ##~ Output: public/{en,ru}/documentation/downloads/print/.{pdf,docx} + ##~ Need external registry (e.g. export WERF_REPO=localhost:4999/docs) to run. + @echo "Building print-artifacts via werf..." + @$(WERF) build print-artifacts + @echo "Extracting PDF/DOCX ($(PRODUCT_CODE)) to ./public/{en,ru}/documentation/downloads/print/..." + @IMG=$$($(WERF) stage image print-artifacts) && \ + CID=$$(docker create $$IMG) && \ + trap "docker rm $$CID >/dev/null" EXIT && \ + mkdir -p ./public/en/documentation/downloads/print ./public/ru/documentation/downloads/print && \ + docker cp $$CID:/out/en/documentation/downloads/print/. ./public/en/documentation/downloads/print/ && \ + docker cp $$CID:/out/ru/documentation/downloads/print/. ./public/ru/documentation/downloads/print/ + @echo "Done. Files: public/{en,ru}/documentation/downloads/print/$(PRODUCT_CODE).{pdf,docx}" + +down: ## Stop and remove documentation containers + docker compose rm -f + docker compose down --remove-orphans + +##@ Linters + +lint-markdown: ## Lint markdown files @echo "Linting markdown files..." @docker run --rm -v "$(PWD):/workdir" -w /workdir ghcr.io/igorshubovych/markdownlint-cli:$(MARKDOWNLINT_VERSION) "**/*.md" -c markdownlint.yaml -lint-markdown-fix: +lint-markdown-fix: ## Lint and auto-fix markdown files @echo "Fixing markdown files..." @docker run --rm -v "$(PWD):/workdir" -w /workdir ghcr.io/igorshubovych/markdownlint-cli:$(MARKDOWNLINT_VERSION) "**/*.md" -c markdownlint.yaml --fix -mod: +##@ Helpers + +mod: ## Clean up Hugo modules (hugo mod tidy) @echo "Cleaning up Hugo modules..." $(HUGO) mod tidy +free-ports: ## Stop containers using known dev ports ($(PORTS_TO_FREE)) + @containers="$$(for port in $(PORTS_TO_FREE); do docker ps -q --filter "publish=$$port"; done | sort -u)"; \ + if [ -n "$$containers" ]; then \ + echo "Stopping containers using ports $(PORTS_TO_FREE): $$containers"; \ + docker stop $$containers; \ + fi + +help: ## Show this help message + @echo 'Usage: make [target]' + @echo '' + @echo 'Available targets:' + @awk 'BEGIN {\ + FS = ":.*?## "; \ + } \ + /^##@/ { printf "\n%s\n", substr($$0, 5) } \ + /^[a-zA-Z0-9_-]+:.*?## / { printf " %-20s %s\n", $$1, $$2 } \ + /^.?.?##~/ { printf " %-20s %s\n", "", substr($$1, 6) }' $(MAKEFILE_LIST) + +.PHONY: help up serve build pdf down lint-markdown lint-markdown-fix mod free-ports diff --git a/README.md b/README.md index 6960fce..447f052 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,19 @@ To run locally: ``` 1. Open `http://localhost/products/delivery-kit/documentation/` in your browser (for the english version) or `http://ru.localhost/products/delivery-kit/documentation/` (for the russian version). + +## Generating PDF/DOCX exports + +Run `make pdf` — the werf `print-artifacts` image is built and the resulting files are +extracted into `public/{en,ru}/documentation/downloads/print/delivery-kit.{pdf,docx}`. +On deploy the same image is imported into `web`, so the site serves them under the same URL. + +This project enables PDF/DOCX through: + +- `params.pdf: true` in `config/_default/hugo.yaml`; +- `outputs: [HTML, search, print]` in the front matter of `content/documentation/_index.{md,ru.md}`; +- `{{< downloads >}}` shortcode on the documentation landing page (in-content buttons); the + module theme also renders sidebar download links automatically. + +For the full description of the pipeline (werf stages, requirements, how to enable/disable +for a new product website) see the [PDF/DOCX exports section in the module README](https://github.com/deckhouse/hugo-web-product-module/blob/main/README.md#pdfdocx-exports). diff --git a/config/_default/hugo.yaml b/config/_default/hugo.yaml index a987303..91ae9fd 100644 --- a/config/_default/hugo.yaml +++ b/config/_default/hugo.yaml @@ -67,6 +67,9 @@ params: # Enable Lunr.js offline search offlineSearch: true + # Enable PDF/DOCX documentation exports (generated in CI, downloadable from sidebar). + pdf: true + # Global relevant links. links: @@ -103,6 +106,7 @@ languages: baseURL: https://deckhouse.io/products/delivery-kit/ params: description: "" + pdfTitle: "Deckhouse Delivery Kit Documentation" ru: disabled: false weight: 1 @@ -110,3 +114,4 @@ languages: baseURL: https://deckhouse.ru/products/delivery-kit/ params: description: "" + pdfTitle: "Документация Deckhouse Delivery Kit" diff --git a/content/documentation/_index.md b/content/documentation/_index.md index 0eda738..bc7e343 100644 --- a/content/documentation/_index.md +++ b/content/documentation/_index.md @@ -8,11 +8,14 @@ params: outputs: - HTML - search + - print cascade: params: simple_list: true --- +{{< downloads >}} + {{< alert level="warning" >}} The functionality of the Deckhouse Delivery Kit module is only available if you have a license for any commercial version of the Deckhouse Kubernetes Platform. {{< /alert >}} diff --git a/content/documentation/_index.ru.md b/content/documentation/_index.ru.md index b1eb8df..3018d1a 100644 --- a/content/documentation/_index.ru.md +++ b/content/documentation/_index.ru.md @@ -8,11 +8,14 @@ params: outputs: - HTML - search + - print cascade: params: simple_list: true --- +{{< downloads >}} + {{< alert level="warning" >}} Функциональность Deckhouse Delivery Kit доступна только если у вас есть лицензия на любую коммерческую версию Deckhouse Kubernetes Platform. {{< /alert >}} diff --git a/go.mod b/go.mod index 4b74666..7b8d0e5 100644 --- a/go.mod +++ b/go.mod @@ -4,4 +4,4 @@ module github.com/deckhouse/website-delivery-kit go 1.24.2 -require github.com/deckhouse/hugo-web-product-module v0.1.17 // indirect +require github.com/deckhouse/hugo-web-product-module v0.1.20 // indirect diff --git a/go.sum b/go.sum index 163cfde..d2955dc 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/deckhouse/hugo-web-product-module v0.1.17 h1:HZ9xxXlUYo7geiTyaZTXk0JFvT0xOkXfYaOeXdUmzVE= -github.com/deckhouse/hugo-web-product-module v0.1.17/go.mod h1:iLVlLSCkbOoi7RjYm5RjwAQi+Whs6DjSumhaH1GBjqw= +github.com/deckhouse/hugo-web-product-module v0.1.20 h1:F2PO+Et43hykb0+OBW1f9+Qds4uhKsAhJrRlPpfFPKg= +github.com/deckhouse/hugo-web-product-module v0.1.20/go.mod h1:iLVlLSCkbOoi7RjYm5RjwAQi+Whs6DjSumhaH1GBjqw= diff --git a/werf.yaml b/werf.yaml index 9a6f3cc..99894c4 100644 --- a/werf.yaml +++ b/werf.yaml @@ -18,10 +18,75 @@ git: stageDependencies: setup: ['**/*'] --- +image: print-base +from: ubuntu:24.04 +final: true +shell: + beforeInstall: + - export DEBIAN_FRONTEND=noninteractive DEBCONF_NOWARNINGS=yes + - apt-get update -qq + - apt-get install -y -qq --no-install-recommends apt-utils + - apt-get install -y -qq --no-install-recommends weasyprint pandoc poppler-utils fonts-dejavu-core fonts-liberation ca-certificates curl gnupg git + - curl -fsSL https://deb.nodesource.com/setup_24.x 2>/dev/null | bash - >/dev/null 2>&1 + - apt-get install -y -qq --no-install-recommends nodejs + - mkdir -p /deps && cd /deps && npm init -y >/dev/null + - cd /deps && npm install --silent --no-audit --no-fund cheerio http-server jszip + - apt-get autoclean && apt-get clean +--- +image: print-artifacts +fromImage: print-base +final: false +import: +- image: web-artifacts + add: /out + to: /site + before: setup + stage: setup +git: +- add: / + to: /src + includePaths: + - go.mod + - config/ + stageDependencies: + setup: ['**/*'] +shell: + setup: + - | + set -e + PDF_ENABLED=$(awk '/^ pdf:/ {print tolower($2); exit}' /src/config/_default/hugo.yaml) + mkdir -p /out + if [ "$PDF_ENABLED" != "true" ]; then + echo "params.pdf is not true — skipping PDF/DOCX generation." + cp -a /site/. /out/ + exit 0 + fi + git config --global advice.detachedHead false + export NODE_PATH=/deps/node_modules + export PUBLIC_DIR=/site + HUGO_TEMPLATE_VER=$(awk -v m='github.com/deckhouse/hugo-web-product-module' \ + '{for(i=1;i<=NF;i++) if($i==m && $(i+1) ~ /^v/) {print $(i+1); exit}}' /src/go.mod) + export PRODUCT_CODE=$(awk '/^ productCode:/ {print tolower($2); exit}' /src/config/_default/hugo.yaml) + test -n "$HUGO_TEMPLATE_VER" || { echo "ERROR: cannot parse hugo-web-product-module version from go.mod"; exit 1; } + test -n "$PRODUCT_CODE" || { echo "ERROR: cannot parse params.productCode from config/_default/hugo.yaml"; exit 1; } + git clone --depth=1 --filter=blob:none --sparse \ + --branch "$HUGO_TEMPLATE_VER" \ + https://github.com/deckhouse/hugo-web-product-module.git /tmp/tpl + git -C /tmp/tpl sparse-checkout set .github/scripts + mv /tmp/tpl/.github/scripts /scripts + rm -rf /tmp/tpl + (cd /site && /deps/node_modules/.bin/http-server -p 8088 -s >/tmp/http.log 2>&1 &) + for i in $(seq 1 30); do curl -sf http://localhost:8088/ >/dev/null && break; sleep 1; done + node /scripts/print-export.js en http://localhost:8088 + node /scripts/print-export.js ru http://localhost:8088 + cp -a /site/. /out/ +--- image: web fromImage: nginx:1.29.3-alpine +final: true import: -- image: web-artifacts +- image: print-artifacts add: /out to: /app before: setup + stage: setup From f5037d40b2663a279499f79ccd82ee969e12f496 Mon Sep 17 00:00:00 2001 From: Artem Kladov Date: Sun, 5 Jul 2026 21:03:54 +0300 Subject: [PATCH 2/2] [delivery-kit] Add PDF/DOCX export pipeline - Introduce multi-stage werf build for print artefact generation using WeasyPrint and Pandoc inside a dedicated Ubuntu-based image; the print-artifacts stage consumes the built site via an embedded HTTP server, runs the export script per locale, and feeds results into the final web image automatically on deploy - Enable the print output format in Hugo site configuration and documentation landing pages for both locales; add per-language PDF title parameters and the downloads shortcode to surface download links on the documentation index - Restructure the Makefile with a new pdf target that orchestrates werf build and container-based artefact extraction, add ARM cross-compilation platform detection, and migrate help output to self-documenting awk-parsed annotations - Bump hugo-web-product-module dependency from v0.1.17 to v0.1.21 to pull in required print layout and export script support Signed-off-by: Artem Kladov --- README.md | 3 +-- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 447f052..e26f056 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,7 @@ This project enables PDF/DOCX through: - `params.pdf: true` in `config/_default/hugo.yaml`; - `outputs: [HTML, search, print]` in the front matter of `content/documentation/_index.{md,ru.md}`; -- `{{< downloads >}}` shortcode on the documentation landing page (in-content buttons); the - module theme also renders sidebar download links automatically. +- sidebar download links (rendered automatically by the module theme). For the full description of the pipeline (werf stages, requirements, how to enable/disable for a new product website) see the [PDF/DOCX exports section in the module README](https://github.com/deckhouse/hugo-web-product-module/blob/main/README.md#pdfdocx-exports). diff --git a/go.mod b/go.mod index 7b8d0e5..7933d7b 100644 --- a/go.mod +++ b/go.mod @@ -4,4 +4,4 @@ module github.com/deckhouse/website-delivery-kit go 1.24.2 -require github.com/deckhouse/hugo-web-product-module v0.1.20 // indirect +require github.com/deckhouse/hugo-web-product-module v0.1.21 // indirect diff --git a/go.sum b/go.sum index d2955dc..067b4e1 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/deckhouse/hugo-web-product-module v0.1.20 h1:F2PO+Et43hykb0+OBW1f9+Qds4uhKsAhJrRlPpfFPKg= -github.com/deckhouse/hugo-web-product-module v0.1.20/go.mod h1:iLVlLSCkbOoi7RjYm5RjwAQi+Whs6DjSumhaH1GBjqw= +github.com/deckhouse/hugo-web-product-module v0.1.21 h1:Dxjcd45jRa1EKaCMUnhWjauZnkGlRVa3l/8S9YeSUew= +github.com/deckhouse/hugo-web-product-module v0.1.21/go.mod h1:iLVlLSCkbOoi7RjYm5RjwAQi+Whs6DjSumhaH1GBjqw=