# blog Hugo source for the LibreTECH blog with the [Pickles](https://github.com/mismith0227/hugo_theme_pickles) theme as a pinned submodule. ```sh git clone --recurse-submodules https://git.librete.ch/public/blog.git hugo server # local preview ``` ## Releases The blog is published as an immutable release, never from a checkout. The served tree contains only the built site and its release marker: no source, `.git`, credentials or links outside the release. 1. `delivery/build.sh` builds the checked-out commit with the pinned Hugo release (verified by SHA-256) and packages it deterministically as `delivery/.build/site.tar.gz`. A rebuild of the same commit has the same digest. 2. **Publish blog immutable package** (`publish-blog.yml`) runs on every `main` push. With `BLOG_PACKAGE_PUBLISH_ENABLED=true`, the reviewed `package_publish` gate and the `BLOG_PACKAGE_USER`/`BLOG_PACKAGE_TOKEN` secrets, it publishes `public/blog-site//` to the Gitea package registry and prints the `stacks.yml` coordinate. 3. A reviewed pull request in [`libretech/gitops-sandbox`](https://git.librete.ch/libretech/gitops-sandbox) puts that coordinate in the `blog` record. Merging it dispatches **Deploy blog immutable package** (`deploy-blog.yml`). 4. The deploy workflow re-downloads and inspects the package, then streams it to the site-scoped receiver on Netcup, which activates `/srv/libretech-static/blog/current` atomically and verifies `https://blog.static.librete.ch/.well-known/release.json`. A stale or re-run dispatch older than the live selection ends as *superseded* and changes nothing. Rollback is a reviewed `stacks.yml` change back to an earlier complete coordinate. See the [operations guide](https://git.librete.ch/libretech/gitops-sandbox/src/branch/main/OPERATIONS.md). `delivery/scripts/` is a copy of the receiver modules from `libretech/librete.ch` (`donatella/scripts/`); update them together. `blog.librete.ch` itself is still served from the earlier Uberspace in-place build (`publishDir` in `hugo.toml`) until its DNS cut-over; the release workflows override `publishDir` and never write there.