Using git-nest In CI Pipelines
This guide is written from the perspective of a DevOps engineer who wants to build a pipeline that consumes a git-nest workspace: install git-nest, restore the subprojects, and build. It covers every common CI system.
Every CI run of a git-nest workspace does the same three things:
- Check out the outer repository.
- Install git-nest (pinned to a version for reproducible builds).
- Run
git-nest restore(materialize the subprojects) andgit-nest verify(confirm the workspace matches the manifest), then build and test.
git-nest is pure shell with no build step, so “installation” in CI is just fetching the release tarball and putting bin/ on PATH.
Install One-Liners
For interactive installs the installers append bin/ to the user’s PATH by default. In CI the pipeline manages PATH itself (e.g. $GITHUB_PATH), so the recipes below install with --no-add-path (POSIX) or GIT_NEST_ADD_PATH=0 (Windows) and add the prefix’s bin/ to the pipeline PATH explicitly.
POSIX runners (Linux, macOS, BSD, Git Bash)
Pinned version (recommended for reproducible builds):
VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
Latest release (default when VERSION is unset):
curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
The installer downloads the release tarball, verifies it against the release’s SHA256SUMS, and installs into $HOME/.local/bin. Add that to PATH in the pipeline, or install to a known prefix with --prefix:
VERSION=0.8.17 sh <(curl -fsSL .../git-nest-install.sh) --prefix "$RUNNER_TOOL_CACHE/git-nest" --no-add-path
Windows runners (PowerShell 5.1+ or pwsh)
Git for Windows must be present on the runner (git-nest runs on Git Bash; without it every git-nest command exits with “Git is not installed or not on PATH.”). GitHub-hosted Windows runners ship it; for self-hosted runners install it as part of the agent provisioning.
Pinned version:
powershell -NoProfile -ExecutionPolicy Bypass -Command "$env:VERSION='0.8.17'; $env:GIT_NEST_ADD_PATH='0'; iwr -useb https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.ps1 | iex"
Latest release:
powershell -NoProfile -ExecutionPolicy Bypass -Command "$env:GIT_NEST_ADD_PATH='0'; & { iwr -useb https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.ps1 | iex }"
Or directly from PowerShell (no cmd.exe wrapper):
$env:GIT_NEST_ADD_PATH='0'
iex (iwr -useb https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.ps1)
The -ExecutionPolicy Bypass flag makes the one-liner work regardless of the machine’s execution policy. The installer installs into %USERPROFILE%\.local\bin; set GIT_NEST_PREFIX to change the prefix.
Always pin a version in CI – reproducibility of the build starts with reproducibility of the tool.
Two Installation Models
There are two ways a CI system can make git-nest available, dictated by whether runners are ephemeral or long-lived:
- Install-once at the infrastructure level (Jenkins-style): install git-nest once on the agent, or bake it into the agent Docker image (
RUN curl -fsSL .../git-nest-install.sh | sh -s -- --no-add-pathin the image build, with anENV PATHfor the install prefix). Every job on that agent then has git-nest on PATH. This works on long-lived agents: Jenkins agents, self-hosted Gitea/GitLab/GitHub runners, Azure self-hosted agents. It behaves exactly like a provisioned JDK – one version managed centrally by the infrastructure owner. - Per-project install (ephemeral-runner style): GitHub-hosted runners, Azure-hosted agents, and GitLab SaaS runners give every job a fresh VM, so each project must install git-nest per run. The one-liners above reduce this to a single line, and caching makes it cheap.
A project can keep the per-project model even on self-hosted infrastructure, but install-once is strictly better there: zero install step per project, one version managed centrally.
Per-CI-System Recipes
GitHub Actions
steps:
- uses: actions/checkout@v5
- name: Install git-nest
run: |
VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Restore subprojects
run: git-nest restore
- name: Verify workspace
run: git-nest verify
Windows runners: shell: bash works (Git for Windows ships bash), or use the PowerShell one-liner from a pwsh step. Cache subproject clones between runs with actions/cache keyed on the .gitnest file to speed up repeated builds.
Azure Pipelines
steps:
- checkout: self
- bash: |
VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
echo "##vso[task.prependpath]$HOME/.local/bin"
displayName: Install git-nest
- bash: git-nest restore
displayName: Restore subprojects
- bash: git-nest verify
displayName: Verify workspace
Notes: task.prependpath persists the PATH change for later steps. Windows agents: use the Bash task (Git Bash) or a PowerShell task with the Windows one-liner. macOS/Linux hosted agents work with the same snippet.
GitLab CI
image: alpine:3.21
before_script:
- apk add --no-cache git curl
- VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
- export PATH="$HOME/.local/bin:$PATH"
script:
- git-nest restore
- git-nest verify
Notes: pick an image with sh + git; Alpine needs the apk add line, Debian needs apt-get install -y git curl. The before_script lines share shell state, so the export PATH applies to script.
Gitea Actions
Gitea Actions is GitHub-Actions-compatible (act runner), so use the same recipe as GitHub Actions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- run: |
VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: git-nest restore && git-nest verify
Private Gitea instances can host the release tarball on their own (Gitea has Releases too) and point GIT_NEST_REPO at their instance and repository; the install scripts honor that override.
Jenkins
Jenkins has two project types: Pipelines (Jenkinsfile, code-as-config) and freestyle projects (point-and-click). Both work with git-nest.
Pipeline (Jenkinsfile, Declarative)
pipeline {
agent any
stages {
stage('Build') {
steps {
sh '''
VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
export PATH="$HOME/.local/bin:$PATH"
git-nest restore
git-nest verify
'''
}
}
}
}
Notes: keep the install + restore + verify in one sh block so the export PATH stays in scope (Jenkins does not persist environment between steps unless you use env or an environment binding). Windows agents: use bat/powershell steps with the Windows one-liner.
Freestyle project (classic)
Add one or two “Execute shell” build steps (Unix) or “Execute Windows batch command” steps (Windows):
# Build step 1: install git-nest and restore
VERSION=0.8.17 curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
export PATH="$HOME/.local/bin:$PATH"
git-nest restore
git-nest verify
Freestyle specifics: there is no export persistence between build steps, so either keep install + restore + verify in a single step, or add $HOME/.local/bin to the job’s Global properties -> Environment variables. Environment variables from the job config (including secrets) are available as plain variables in the shell step. The Git plugin is not needed for subprojects; git-nest calls git directly.
Credentials For Private Subproject Remotes
Subproject remotes may be private. git-nest delegates to git, so credential handling is standard git behavior; CI just needs to make credentials available to git. The generic approach that works almost everywhere is a .netrc written from a secret before restore (git reads ~/.netrc for HTTPS remotes):
printf 'machine github.com\nlogin x-access-token\npassword %s\n' "$TOKEN" > ~/.netrc
chmod 600 ~/.netrc
One machine block covers all private subprojects on the same host; add more machine blocks for additional hosts (e.g. github.com + gitlab.com).
Per-system shortcuts:
| CI | Mechanism |
|---|---|
| GitHub Actions | GITHUB_TOKEN works for github.com remotes (scope: contents: read on the subproject repos) |
| Azure Pipelines | System.AccessToken or a PAT as a secret; configure a git credential helper |
| GitLab | CI_JOB_TOKEN (own instance) or deploy tokens |
| Jenkins | Credentials Binding plugin: withCredentials([usernamePassword(credentialsId:'x', usernameVariable:'U', passwordVariable:'P')]) + git credential helper |
| Gitea | Token in GITEA_TOKEN + credential helper, or a .netrc |
Docker Agent Images
For self-hosted agents that run jobs in containers, bake git-nest into the agent image at build time:
RUN curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
ENV PATH="/root/.local/bin:${PATH}"
Pin the version with an ARG for reproducible images:
ARG GIT_NEST_VERSION=0.8.17
RUN VERSION=$GIT_NEST_VERSION curl -fsSL https://raw.githubusercontent.com/f-steff/git-nest/main/bin/git-nest-install.sh | sh -s -- --no-add-path
ENV PATH="/root/.local/bin:${PATH}"
The image digest (sha256) then serves as the trust anchor for every job that runs on it, and the pinned version makes the image reproducible.
Security Notes
- CI agents need zero code signing for git-nest: the payload is plain shell text, and no platform requires a signature on
.sh/.ps1files before they run. The trust model is HTTPS + the releaseSHA256SUMS(which the install scripts verify automatically), plus the pinned version. - For high-trust environments, pin both the version and the tarball hash (verify against the release
SHA256SUMSyourself) instead of relying on the installer’s download path.