Spec: phpboyscout/cicd v0.12.0 — hugo-pages component¶
- Repository:
gitlab.com/phpboyscout/cicd - Released as:
v0.12.0(minor — a new component /feat). - Driver: the portfolio CI audit (2026-06-22).
blog,dusthole, andshutterandstoveeach hand-roll a near-identicalpagesjob (pinnedhugomods/hugoimage,GIT_DEPTH: 0, nightly-schedule rebuild) with no MR build gate — a broken Hugo build only surfaces after it lands on the default branch. No reusable component covers Hugo;zensical-pagesonly covers the Zensical docs framework.
Decisions¶
D1 — Two-job build + deploy split (mirror zensical-pages)¶
hugo-build— builds the site topublic/. Carries an explicitrules:($CI_COMMIT_TAG → never, elsewhen: on_success) so it runs in merge-request pipelines too. This is the new value: an MR build gate.interruptible: true(a superseding push cancels it — consistent with v0.11.5 D1). Produces thepublic/artifact.pages— deploys thepublic/artifact (pages: true). Runs ondeploy_branchand onschedule, never on merge requests. UsesGIT_STRATEGY: none(it only republishes the artifact, no clone needed). Not interruptible (it is a deploy).
D2 — schedule deploys, deliberately (exception to v0.10.8)¶
Every other component carries a leading schedule → never guard so it
does not fire on the Renovate schedule
(specs/2026-06-21-schedule-pipeline-scoping-v0.10.8.md). hugo-pages
is the deliberate exception: a nightly pipeline schedule is the
mechanism by which future-dated, non-draft posts go live once their date
arrives — Hugo excludes future-dated content from production builds
until then, so a scheduled rebuild+deploy is what publishes them. The
schedule is the feature. These Hugo sites carry no Renovate schedule,
so there is no Renovate run to suppress.
D3 — Inputs¶
image(defaulthugomods/hugo:debian-git-0.163.1) — the-gitvariant bundles git for.GitInfo/.Lastmod; the extended debian build covers SCSS/Sass themes.stage(defaultdeploy— a GitLab default stage, so consumers need not declare astages:list).working_directory(default.) — site root containinghugo.toml. Passed tohugo --source; output is forced to$CI_PROJECT_DIR/publicvia--destinationso Pages finds it regardless of source dir.base_url(default$CI_PAGES_URL/) —hugo --baseURL. Resolves to a custom domain automatically once configured in Pages settings.flags(default--gc --minify) — extrahugoflags; add--buildFutureto surface future-dated content (e.g. a pre-launch showcase). String, word-split in the shell (per authoring rule 4).hugo_env(defaultproduction) —HUGO_ENV;productionexcludes drafts + future-dated content.tz(defaultEurope/London) —TZ; affects how "future-dated" is compared against now.submodule_strategy(defaultnone) —GIT_SUBMODULE_STRATEGYfor the build clone. Setrecursivefor a theme that is a git submodule (e.g.blog).deploy_branch(defaultmain).
D4 — GIT_DEPTH: 0 on the build¶
Hugo's enableGitInfo / .Lastmod need full history, so the build job
sets GIT_DEPTH: 0. (The deploy job sets GIT_STRATEGY: none — no clone
at all.)
D5 — Consumer migration (follow-on, separate MRs)¶
blog, dusthole, shutterandstove migrate to the component in their
own repos:
- blog: submodule_strategy: recursive (theme submodule), schedule
enabled (nightly).
- dusthole: defaults; no schedule (it has no time-bound content).
- shutterandstove: flags: "--gc --minify --buildFuture" (pre-launch
showcase), schedule enabled.
D6 — Versioning¶
New component → feat(hugo-pages): → v0.12.0 (minor). Should land
after the pending v0.11.5 patch is tagged, so the perf/cache work
keeps its own release rather than being absorbed into the minor.