GitLab CI Pipeline

This page documents the root-level .gitlab-ci.yml. The repository is also hosted on GitHub (.github/workflows/) and a self-hosted Gitea instance. Shared CI tasks use scripts from scripts/ci/.

Stages

test → validate → package → pages → release

Included templates

TemplateProvides
Jobs/Secret-Detection.gitlab-ci.ymlScans commits for leaked secrets.
Jobs/SAST.gitlab-ci.ymlStatic application security testing.
Jobs/SAST-IaC.gitlab-ci.ymlScans infrastructure configuration, including Ansible.

All jobs inherit the chataigne runner tag from default:tags.

Jobs

JobStageRuns whenPurpose
Security scannerstestScanner template rules matchScan source, infrastructure configuration, and commits for security issues.
unit_teststestEvery pipelineRun the Python suite under coverage (floor in .coveragerc) and shell tests.
ansible_lintvalidateBranch and tag pipelinesInstall make and the pinned Ansible tools, then run make lint-ansible.
package_vimpackageEvery default-branch pipeline; elsewhere, changes to .vim/, .vimrc, the role defaults or fetch_vim_plugins.pyPackage Vim configuration and pinned plugins as vim.tar.gz.
package_nvimpackageEvery default-branch pipeline; elsewhere, changes to .config/nvim/ in pushes and merge requestsPackage Neovim configuration as nvim.tar.gz.
pagespagesDefault branch when a Markdown file or the page generator changes, or a vX.Y.Z release tagBuild and deploy the documentation site to public/.
build_pages_reviewpagesNon-default branch or merge request with matching changesBuild the documentation site for review without deploying it.
create_releasereleaseA tag is pushed ($CI_COMMIT_TAG)Publish a release with notes from CHANGELOG.md.

unit_tests

scripts/ci/run_unit_tests.py runs the Python tests in parallel. A few tests drive ansible-playbook for up to two minutes while most take milliseconds, so each slow test gets its own process and starts first. The durations of the previous run are kept in the runner cache under .cache/unit-tests/, with one key for every branch. Without them, the first run starts one process per test class and is slower. The job also caches pip downloads and the Ansible collections, keyed on their requirement files. The log ends with the slowest tests.

pages

This job runs on alpine:latest, installs python3 and py3-markdown, and calls scripts/ci/build_pages.sh. The GitHub deploy-pages.yml workflow and local post-commit hook use the same script. Every Markdown file of the repository becomes a page, and relative links to other files point to the GitLab file browser at CI_COMMIT_SHA. The page layout and link rules are described with deploy-pages.yml.

The pages job deploys documentation from the default branch when a Markdown file or the page generator changes, and from vX.Y.Z release tags. The build_pages_review job builds documentation on non-default branches and merge requests without deploying it. GitLab treats rules:changes as true on pipelines without a push diff, so the review job explicitly skips tag pipelines (GitLab rules).

  1. pages runs on the default branch after documentation changes and on release tags. It publishes the site from that commit.
  2. build_pages_review runs on other branches and merge requests, then uploads a short-lived public/ artifact for validation only.

Note

build_pages.sh uses POSIX sh and does not require Git, so it runs on the minimal alpine image without extra packages. Without Git, gen_pages.py finds the Markdown files by walking the checkout and skips the submodules listed in .gitmodules.

create_release

When a v* tag is pushed, this job runs scripts/ci/extract_release_notes.sh to extract that version's section from CHANGELOG.md, then passes the notes to release-cli create.

Important

Release notes come from CHANGELOG.md at the tagged commit. Add the ## [vX.Y.Z] section before pushing the tag. Without it, the release uses the placeholder "No specific notes found".

Shared scripts (scripts/ci/)

ScriptUsed by
build_pages.shGitLab pages, GitHub deploy-pages.yml, local post-commit hook
extract_release_notes.shGitLab create_release, GitHub release.yml
gen_pages.pybuild_pages.sh

Both shell scripts use POSIX sh, so they run on minimal CI images such as the alpine job.

Variables & secrets

The pipeline uses GitLab's predefined variables; no custom CI/CD variables are needed.

NameUsed bySourceManual setup
CI_JOB_TOKENcreate_release (release-cli)Predefined for every jobNone
CI_COMMIT_TAGcreate_release rule + release namePredefined on tag pipelinesNone
CI_COMMIT_BRANCH, CI_DEFAULT_BRANCHpages rulesPredefinedNone

Note

release-cli uses the predefined CI_JOB_TOKEN to authenticate with the Releases API. No personal access token or Settings → CI/CD → Variables entry is needed.

The included SAST, IaC Scanning, and Secret Detection templates run with their defaults and need no custom variables.