Deploy on GitLab Pages¶
Render this repository's CI job file for GitLab, include it from your root
.gitlab-ci.yml, then add the pages job GitLab itself requires to publish
the built site — ocx-catalog ci renders the build/verify half only; the
pages job is yours to write.
Render the CI job file¶
Add a ci block to catalog.config.json:
Then run:
This writes .gitlab-ci/catalog.yml — a job file, not a root
.gitlab-ci.yml. Add it to your own root file's include: block, exactly
as the rendered file's own header comment says:
With packageManager defaulted to npm and verifyCi defaulted to true,
a first render (no committed pins to carry forward — GitLab jobs pin by
image:, not uses:) produces:
# generated by ocx-catalog ci v1 — do not edit
#
# Rendered by `ocx-catalog ci` from this repository's own catalog.config.json
# `ci` block. Not a root .gitlab-ci.yml — this repository's own root file
# includes it:
#
# include:
# - local: ".gitlab-ci/catalog.yml"
#
# Do not hand-edit this file — change the config instead and re-render:
#
# npx ocx-catalog ci
#
# `ci.verifyCi: false` in catalog.config.json omits the catalog:verify job
# below (`ocx-catalog ci --check`) and stops CI from catching a hand-edit —
# the repository then owns this file by hand instead.
catalog:build:
image: node:22-alpine
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- npm ci
- npx ocx-catalog build
artifacts:
paths:
- dist
catalog:verify:
image: node:22-alpine
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- npm ci
- npx ocx-catalog ci --check
Both jobs run on a merge request pipeline and on the default branch;
catalog:build keeps dist as an artifact, catalog:verify re-renders the
job file in memory and fails if it has drifted from catalog.config.json
(see CI rendering). Set "verifyCi": false
in the ci block to omit catalog:verify.
Set "packageManager": "bun" and the image and script lines change instead:
Add the pages job¶
GitLab Pages has its own contract, independent of this package: the
publishing job must be literally named pages, and its artifacts
must include the directory it publishes — conventionally public. Neither
requirement comes from ocx-catalog; add the job yourself in your root
.gitlab-ci.yml, alongside the include: block above:
pages:
image: node:22-alpine
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- npm ci
- npx ocx-catalog build --out public
artifacts:
paths:
- public
--out public builds straight into the directory GitLab publishes, so no
separate move step is needed. The rules: entry limits the job to the
default branch — GitLab publishes whatever the most recent successful
pages job on that branch produced.
The default project Pages URL is a subpath
A generated catalog site cannot be served from a URL subpath: the build
never emits a VitePress base:, and the theme's data fetches
(/data/catalog/catalog.json, /p/<ns>/<pkg>.json, and the OCI image
index fetches) are literal root-relative strings. The default GitLab
Pages URL — https://<group>.gitlab.io/<project>/ — is a subpath, so
every asset and every one of those fetches 404s once deployed there.
This is GitLab's own project-Pages URL topology, not a missing option in
this package: enable GitLab Pages' unique domain for the project (a
dedicated root URL GitLab assigns per project) or attach a custom
domain at the domain root instead.
The mirrored /p/* tree also ships an inert _headers file — GitLab Pages
never reads it. See Hosting and headers for
what that means and what to do about it.