Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7b19041
use zensical, WIP, tag system not completed yet.
rpietzsch Dec 29, 2025
360dbbe
update zensical and copyright partial
rpietzsch Jan 21, 2026
b3224dd
fix outdated python setup documentation (CMEM-7287)
seebi Jan 14, 2026
316625b
initial commit on Marketplace Packages (WIP)
rpietzsch Jan 20, 2026
9f7b1be
advance development section
rpietzsch Jan 20, 2026
0ae1b5d
first draft of development.md
rpietzsch Jan 21, 2026
9a3b962
wip
rpietzsch Jan 21, 2026
4485c2a
language review
rpietzsch Jan 21, 2026
83d3725
initial draft for install
rpietzsch Jan 21, 2026
23e951c
add cmemc group
seebi Jan 26, 2026
f22e2fc
update package repository before installation
seebi Jan 26, 2026
dfd1206
add update on other job
seebi Jan 26, 2026
d65bc86
add missing ACL Actions
rpietzsch Jan 27, 2026
3803cf5
Merge branch 'main' into feature/zensical
rpietzsch May 12, 2026
4584a6a
bump to zensical v0.0.41
rpietzsch May 12, 2026
3c946a9
bump pzensical to 0.0.42
rpietzsch May 15, 2026
6bfa15d
regression on reload loop
rpietzsch May 21, 2026
b76ce38
add explicit nav
rpietzsch May 21, 2026
3d6c46c
bump zensical to 0.0.44
rpietzsch Jun 4, 2026
c1a7818
Merge branch 'main' into feature/zensical
rpietzsch Jun 9, 2026
1127e47
Merge branch 'main' into feature/zensical
rpietzsch Aug 22, 2026
e4785b3
finish zensical migration: vendored assets, nav fixes and guard rails
rpietzsch Aug 23, 2026
0b199ee
replace the `extra` markdown extension with the members of `pymdownx.…
rpietzsch Aug 23, 2026
a724bd5
drop issue input
rpietzsch Aug 23, 2026
69c3fd5
spec for tag listing injection
rpietzsch Aug 23, 2026
7d6f89a
add post build step to render tag pages
rpietzsch Aug 23, 2026
4ba4acc
link page tags to tags listing page
rpietzsch Aug 23, 2026
6168fd0
Merge remote-tracking branch 'origin/main' into feature/zensical
rpietzsch Sep 3, 2026
1b969f4
bump to 0.0.58
rpietzsch Sep 3, 2026
f3741e7
Taskfile: rename the nav task to update:navigation
seebi Sep 4, 2026
b0c0bd0
tools: expose every script as a dec-tool subcommand
seebi Sep 4, 2026
aa75a22
docs: drop the tag-listing workarounds from the README
seebi Sep 4, 2026
a6911b9
tests: cover the navigation builder, not just its --check mode
seebi Sep 4, 2026
69cc006
Merge pull request #260 from eccenca/feature/zensical-addons
rpietzsch Sep 4, 2026
0a42fd3
build: bump zensical to 0.0.59
rpietzsch Sep 4, 2026
300d5a5
nav: keep single-page sections attachable instead of flattening them
rpietzsch Sep 4, 2026
5747181
nav: move tags above content, matching mkdocs-material default
rpietzsch Sep 4, 2026
84390da
style: tighten gap above tags now that they render first
rpietzsch Sep 4, 2026
b2b80f0
build: use squidfunk's mike fork for zensical
rpietzsch Sep 4, 2026
98f6db6
publish: build with post-build steps, commit via mike
rpietzsch Sep 4, 2026
e7c39f9
task: add public:preview, drop preview
rpietzsch Sep 4, 2026
69aace3
assets: vendor resize-observer-polyfill, add licence notices
rpietzsch Sep 4, 2026
7b0e371
Merge pull request #262 from eccenca/feature/zensical-mike
seebi Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"permissions": {
"allow": [
"Bash(git log *)",
"WebFetch(domain:zensical.org)",
"WebSearch",
"Bash(gh release *)"
]
}
}
5 changes: 1 addition & 4 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ jobs:
run: sudo apt-get update -y

- name: install packages
run: sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev

- name: reconfigure private repository access
run: ACCESS_TOKEN=${{ secrets.ACCESS_TOKEN }} task use:insider-https-token
run: sudo apt-get install -y libffi-dev libz-dev

- name: check
run: task check
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ jobs:
run: sudo apt-get update -y

- name: install packages
run: sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev

- name: reconfigure private repository access
run: ACCESS_TOKEN=${{ secrets.ACCESS_TOKEN }} task use:insider-https-token
run: sudo apt-get install -y libffi-dev libz-dev

- name: test
run: task test:unit
Expand Down
2 changes: 1 addition & 1 deletion .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ tasks:
before: |
brew install go-task/tap/go-task
init: |
task use:insider-https-token
task install
command: |
task serve
github:
Expand Down
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ repos:
entry: task check:rumdl
language: python
pass_filenames: false

- id: nav-drift
name: check:navigation
entry: task check:navigation
language: python
pass_filenames: false
files: '(^docs/.*\.pages$|^nav\.yml$|^tools/build_navigation\.py$)'
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,83 @@ Shared repository of the eccenca Corporate Memory documentation.

If you consider to contribute to this project, please have a look on [CONTRIBUTING.md](https://github.com/eccenca/documentation.eccenca.com/blob/main/CONTRIBUTING.md)

## Building the site

The site is built with [Zensical](https://zensical.org), the successor to Material for
MkDocs. Run `task build` to build into `site/` and `task check` for the full check suite.

For previewing there are two tasks:

| Task | Live reload | Shows |
| :--- | :---------- | :---- |
| `task serve` | yes | the pages as you write them |
| `task public:preview` | no | the site as it will be published |

Use `serve` while writing prose. It rebuilds into `site/` on every change, which overwrites
what the post-build steps produced, so it loads `glightbox` and the ResizeObserver polyfill
from a CDN instead of from the vendored copies - invisible on screen, and nothing
downstream trusts a `site/` left behind that way.

`task public:preview` is the one to run before publishing: it deploys into a throwaway copy
of the `published` branch, serves that on port 8002 (override with `PORT=…`), and deletes
the branch again when you stop it. Because it is `public:deploy` pointed at a scratch
branch, what it serves is what publishing produces - versioned URLs, the version selector,
the outdated-version banner and the root redirect included.

Two Material for MkDocs features are **not yet implemented by Zensical** and are
therefore missing from the output. They are tracked in `tools/check_zensical_output.py`,
which reports them as `PEND` on every build and prints a banner as soon as one starts
working:

| Feature | Zensical backlog | Effect today |
| :------ | :--------------- | :----------- |
| Social cards | [#37](https://github.com/zensical/backlog/issues/37) | No `og:image`, so link previews are blank |
| Revision dates | [#18](https://github.com/zensical/backlog/issues/18) | No "Last update" on any page |

Everything else Zensical leaves out is reimplemented here and **guarded as a required
check** - the build fails if any of it regresses:

| Feature | Replaced by |
| :------ | :---------- |
| Self-hosted fonts | `docs/assets/fonts.css` plus `theme.font: false` |
| `tablesort`, `glightbox`, `resize-observer-polyfill` | vendored under `docs/assets/`; `tools/localize_bundle_assets.py` rewrites the CDN URLs Zensical bakes into its JS bundle |
| Redirects | static stubs under `docs/` |
| Comment opt-out | `overrides/partials/comments.html` |

### Vendored third-party assets

Serving these from our own origin is what keeps visitor IP addresses away from third
parties - but it also makes us their redistributor, so each copy carries its licence:

| Asset | Version | Licence | Upstream |
| :---- | :------ | :------ | :------- |
| `assets/glightbox/glightbox.min.{js,css}` | 3.3.1 | MIT, © 2018 Biati Digital | [glightbox](https://github.com/biati-digital/glightbox) |
| `assets/resize-observer-polyfill/ResizeObserver.global.js` | 1.5.1 | MIT, © 2016 Denis Rul | [resize-observer-polyfill](https://github.com/que-etc/resize-observer-polyfill) |
| `assets/tablesort.min.js` | 5.2.1 | MIT, © 2021 Tristen Brown | [tablesort](http://tristen.ca/tablesort/demo/) |
| `assets/fonts/*.woff2` | - | Apache-2.0 | Roboto and Roboto Mono via Google Fonts |

The files are byte-identical to their upstream builds except for a prepended `/*! … */`
licence banner, which is the notice MIT asks to travel with a copy; the full licence text
sits next to each one where upstream ships it. Three of the URLs Zensical bakes into its
bundle are deliberately **not** vendored - mermaid, Ace and Pyodide are unreachable for
this corpus, and `localize_bundle_assets.py` fails the build if a page ever starts using
one.

Tag listings and the links from each page's tag chips to them are **native** as of
Zensical 0.0.58. The local stand-ins for both - a post-build renderer and a `tags.html`
partial override - are gone; the Markdown sources still carry Material's own
`<!-- material/tags -->` markers, which Zensical now expands itself.

`check-zensical-output` keeps guarding the result: it asserts that tag chips link
somewhere at all and that every anchor they point at exists on `/tags/`. A slug mismatch
between a chip and its listing would otherwise ship as hundreds of dead links rather than
fail the build.

`task check:navigation` additionally fails if `nav.yml` no longer matches the `docs/**/.pages`
files, which remain the source of truth for navigation (`task update:navigation` regenerates it).

See `tasks/handoff.md` for the full migration notes.

## License

Copyright © 2025 [eccenca GmbH](https://eccenca.com)
Expand Down
157 changes: 119 additions & 38 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ dotenv: ['.env']

vars:
PUBLIC_BRANCH: published
# Throwaway branch used by public:preview. Never pushed, recreated on every
# run and deleted again when the preview server stops.
PREVIEW_BRANCH: publish-preview
CURRENT_VERSION: 26.2
MATERIAL_TAG: 9.6.14
MATERIAL_INSIDER_TAG: 9.6.14-insiders-4.53.16
# the markdown linter command, used by format:fix:path and check:rumdl
RUMDL_CHECK: poetry run rumdl --config .markdownlint.jsonc check
# the default lint targets: the docs tree plus the top-level markdown files
Expand All @@ -25,39 +26,65 @@ tasks:
- task --list

versions:
desc: List relevant versions for a mkdocs material bug report
desc: List relevant versions for a zensical material bug report
silent: true
cmds:
- |
cat << EOF
- Python: {{.PYTHON_VERSION}}
- MkDocs: {{.MKDOCS_VERSION}}
- Material: {{.MATERIAL_VERSION}}
- Zensical: {{.ZENSICAL_VERSION}}
EOF
vars:
PYTHON_VERSION:
sh: poetry run python --version
MKDOCS_VERSION:
sh: poetry run mkdocs --version | cut -d " " -f -3
MATERIAL_VERSION:
sh: poetry run pip show mkdocs-material | grep Version | cut -d " " -f 2
ZENSICAL_VERSION:
sh: poetry run zensical --version | cut -d " " -f -3

clean:
desc: Clean up working directory
run: once
cmds:
- rm -rf site
# Only ever the throwaway branch of public:preview, which normally deletes
# itself; this catches the run that was killed before it could.
- git branch -D {{.PREVIEW_BRANCH}} >/dev/null 2>&1 || true

install:
desc: Install needed dependencies
# `run: once` because five tasks depend on this and `task check` resolves its
# dependencies in parallel - without it, concurrent `poetry install`
# invocations collide and one of them fails with a non-obvious exit 1.
run: once
cmds:
- poetry install

check:
desc: Check documentation links and Markdown style
desc: Check documentation links, Markdown style, nav drift and build output
# Sequential (`cmds`, not `deps`) on purpose. Task resolves `deps` in
# parallel, which ran several `poetry install` invocations at once and, worse,
# ran `zensical build` alongside the link and style checks - under that load
# Zensical intermittently reports false "page does not exist" warnings and
# `--strict` fails the build (zensical/zensical#641). Serialising costs a
# little wall-clock and makes the stage deterministic.
cmds:
- task: check:links
- task: check:rumdl
- task: check:navigation
- task: check:output

check:navigation:
desc: Fail if nav.yml is out of sync with the docs/**/.pages files
deps:
- install
cmds:
- poetry run dec-tool build-navigation --check

check:output:
desc: Fail if a feature we reimplemented for Zensical regressed in the build
deps:
- check:links
- check:rumdl
- build
cmds:
- poetry run dec-tool check-zensical-output

check:links:
desc: Check outgoing links
Expand Down Expand Up @@ -90,35 +117,30 @@ tasks:
deps:
- task: install
cmds:
- poetry run mkdocs build --strict
# `--clean` is not optional: with a warm .cache Zensical intermittently
# reports false "page does not exist" warnings and --strict then fails the
# build (zensical/zensical#641). Measured on this repo: 4 of 6 warm builds
# failed, 6 of 6 passed with --clean. Costs ~5s; buys a deterministic build.
- poetry run zensical build --strict --clean
# Zensical bakes unpkg.com URLs into its JS bundle; rewrite them to the
# vendored copies. Part of building, not of checking - without it the
# published site issues third-party requests.
- poetry run dec-tool localize-bundle-assets

serve:
desc: Serve the page on localhost
desc: Serve the page on localhost with live reload (no post-build steps)
# `zensical serve` rebuilds into site/ on every change, which overwrites what
# the post-build steps in `build` produced - so this preview loads glightbox
# and the ResizeObserver polyfill from unpkg rather than from our vendored
# copies. Nothing downstream consumes a site/ left behind this way: `build`
# and `check:output` rebuild, and `public:deploy` refuses a site/ whose
# canonical URL is unversioned, which such a rebuild always is.
#
# Use `task public:preview` to see the site as it will actually be published.
deps:
- task: install
cmds:
- poetry run mkdocs serve

use:public:
desc: switch to public package (non insider)
cmds:
- poetry remove mkdocs-material || exit 0
- poetry add mkdocs-material=={{.MATERIAL_TAG}}
- poetry update

use:insider-ssh:
desc: switch to insider package from github:eccenca via ssh (default)
cmds:
- poetry remove mkdocs-material || exit 0
- poetry add git+ssh://git@github.com:eccenca/mkdocs-material-insiders.git#{{.MATERIAL_INSIDER_TAG}}
- poetry update

use:insider-https-token:
desc: switch to insider package from github:eccenca via ACCESS_TOKEN variable (build plan)
cmds:
- poetry remove mkdocs-material || exit 0
- poetry add git+https://$ACCESS_TOKEN@github.com/eccenca/mkdocs-material-insiders.git#{{.MATERIAL_INSIDER_TAG}}
- poetry update
- poetry run zensical serve

update:icons:
desc: update the used eccenca icons from carbon
Expand Down Expand Up @@ -226,6 +248,13 @@ tasks:
PATHS: ./docs/build/integrations/index.md
ignore_error: true

update:navigation:
desc: Regenerate nav.yml from the docs/**/.pages files
deps:
- install
cmds:
- poetry run dec-tool build-navigation

public:versions:
desc: List public documentation versions
deps:
Expand All @@ -235,12 +264,28 @@ tasks:

public:deploy:
desc: Publish the working directory as version {{.CURRENT_VERSION}}
summary: |
Builds the site and commits it as version {{.CURRENT_VERSION}} on the
{{.PUBLIC_BRANCH}} branch. Nothing is pushed - that stays a deliberate
`git push` afterwards.

Deliberately not `mike deploy`: that builds the site itself, without
`--strict` and without the post-build steps below, and its rebuild would
overwrite them anyway. So the build happens here and `dec-tool publish`
hands the result to mike, which still owns versions.json, the aliases and
the root redirect.

MIKE_DOCS_VERSION is what makes the pages carry a versioned canonical URL;
`dec-tool publish` refuses to commit a site/ built without it.
deps:
- task: install
cmds:
- MIKE_DOCS_VERSION={{.CURRENT_VERSION}} task build
- >
poetry run mike deploy -b {{.PUBLIC_BRANCH}}
--update-aliases {{.CURRENT_VERSION}} latest
poetry run dec-tool publish
--branch {{.PUBLIC_BRANCH}}
--version {{.CURRENT_VERSION}}
--alias latest

public:serve:
desc: Start a webserver to manually validate the public branch
Expand All @@ -249,6 +294,42 @@ tasks:
cmds:
- poetry run mike serve -b {{.PUBLIC_BRANCH}}

public:preview:
desc: Rehearse a deployment on a throwaway branch and serve it
summary: |
Deploys the working directory into a throwaway copy of the public branch,
serves it on localhost, and deletes that branch again when the server
stops. Nothing is pushed and {{.PUBLIC_BRANCH}} is never touched.

The rehearsal is public:deploy itself, pointed at the throwaway branch, so
what it serves is exactly what publishing would produce.

Ctrl-C removes the branch. Should the process be killed harder than that,
`task clean` removes it, as does the next run.

task public:preview PORT=9000
deps:
- task: install
vars:
PORT: '{{.PORT | default "8002"}}'
cmds:
# Deleted when the server stops: `defer` runs on Ctrl-C too, since that
# reaches mike and Task alike.
- defer: git branch -D {{.PREVIEW_BRANCH}} >/dev/null 2>&1 || true
# Start from the branch as it stands - locally if it exists, otherwise as
# last fetched - so the rehearsal shows the new version among the existing
# ones: version selector, outdated banner and root redirect included.
- |
base={{.PUBLIC_BRANCH}}
git show-ref --verify --quiet refs/heads/{{.PUBLIC_BRANCH}} \
|| base=origin/{{.PUBLIC_BRANCH}}
git branch -f --no-track {{.PREVIEW_BRANCH}} "$base"
- task: public:deploy
vars:
PUBLIC_BRANCH: "{{.PREVIEW_BRANCH}}"
- echo "Serving the deployment rehearsal on http://localhost:{{.PORT}} - Ctrl-C to stop and discard it"
- poetry run mike serve -b {{.PREVIEW_BRANCH}} --dev-addr localhost:{{.PORT}}

format:fix:path:
internal: true
summary: |
Expand Down
2 changes: 0 additions & 2 deletions docs/.meta.yml

This file was deleted.

11 changes: 11 additions & 0 deletions docs/assets/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
text-decoration: underline;
}

/* .md-tags' own margin/padding are tuned for sitting below the page title,
which is where upstream renders it by default. This site renders tags
first (see overrides/partials/content.html), directly under the
breadcrumb path, so that spacing left a gap far bigger than the one
between the path and a title. Zero it out so the gap matches the
baseline space `.md-content__inner` already puts above its first child. */
.md-content__inner > .md-tags:first-child {
margin-top: 0;
padding-top: 0;
}

/* Comment out this section if the header should not be light colored */

[data-md-color-scheme="eccenca-light"] .md-header,
Expand Down
Loading
Loading