CI pipeline setup
koryph ci setup renders and installs forge-native CI pipeline assets into
your project. It is the canonical way to give koryph a green gate — the
build/test workflow that must pass before any branch is merged.
What gets installed
koryph ci setup installs pipeline asset files (CI workflow or config
fragments) by rendering them from koryph's embedded templates and writing
them to the forge-native path. Assets are idempotent: re-running over an
already-current file is a no-op.
Gate pipeline
The gate kind is installed by default (--kind gate). It runs the
project's green gate command on every push and
pull/merge request, keeping the default branch and all open PRs/MRs green.
| Forge | Installed path |
|---|---|
| GitHub | .github/workflows/koryph-gate.yml |
| GitLab | .koryph/ci/koryph-gate.yml ¹ |
¹ GitLab CI uses an include fragment (see GitLab: adding the include entry).
Scanner pipeline (optional)
The scanner kind (--kind scanner) installs a dependency/vulnerability
scanner pipeline. It is optional — run --kind all to install both gate
and scanner, or --kind scanner to install only the scanner.
| Forge | Installed path |
|---|---|
| GitHub | .github/workflows/koryph-scanner.yml |
| GitLab | .koryph/ci/koryph-scanner.yml ¹ |
Docs publishing pipeline (optional)
The docs kind (--kind docs) builds a Zensical book with --strict and
publishes it to your forge's Pages service. --kind all installs it alongside
the gate and scanner assets. Your repository must provide mkdocs.yml and a
docs/requirements.txt that declares Zensical.
| Forge | Installed path |
|---|---|
| GitHub | .github/workflows/koryph-docs.yml |
| GitLab | .koryph/ci/koryph-docs.yml ¹ |
GitHub uses the artifact-based Pages flow (configure-pages,
upload-pages-artifact, and deploy-pages); it never creates a gh-pages
branch. It publishes only from the repository default branch; a manual run
against any other ref can build but cannot deploy. Configure the repository's
Pages source as GitHub Actions before the first deployment.
Quickstart
# Install the gate pipeline only (default)
koryph ci setup --project myproject
# Install gate, scanner, and docs publishing
koryph ci setup --project myproject --kind all
# Override the gate command (e.g. for a non-Makefile build)
koryph ci setup --project myproject --gate-cmd "go test ./..."
# Install only the scanner
koryph ci setup --project myproject --kind scanner
# Install only docs publishing
koryph ci setup --project myproject --kind docs
After running ci setup, koryph prints commit guidance:
installed .github/workflows/koryph-gate.yml
Remaining HUMAN steps:
1. Review the installed file(s) above.
2. git add <paths above> && git commit -s -m 'ci: install koryph CI assets'
3. Push and open a PR — GitHub will run the gate workflow on every push and PR.
koryph never commits CI assets automatically; committing is always the
operator's (or agent's) act — the same principle as koryph release setup.
Flags
| Flag | Default | Description |
|---|---|---|
--project ID |
— | Project to install into (required, or pass the ID as a positional argument) |
--kind gate\|scanner\|docs\|all |
gate |
CI asset kind(s) to install |
--gate-cmd CMD |
make gate |
Override the gate command; see The gate command contract |
The gate command contract
The gate command is the single shell command that embodies "the branch is green." koryph renders it verbatim into the CI pipeline; the pipeline checks out the repository, then runs:
<gate-cmd>
No language runtime, package manager, or build tool is installed by the generated pipeline itself — it is toolchain-neutral by design. Your project's Makefile (or whatever owns the gate command) is responsible for its own prerequisites.
Default: make gate
Unless overridden with --gate-cmd, koryph uses make gate. The koryph
project itself defines make gate in its top-level Makefile; your project
should do the same. A typical gate target runs formatting checks, linting,
builds, and the full test suite.
Overriding for non-Makefile projects
Pass --gate-cmd to use a different command:
# Go project without a Makefile
koryph ci setup --project myproject --gate-cmd "go build ./... && go vet ./... && go test ./..."
# Python project
koryph ci setup --project myproject --gate-cmd "pytest"
The override is written into the rendered pipeline header (as a comment) so
you can always see which command the installed file uses. To change it later,
re-run koryph ci setup --gate-cmd <new-cmd> and commit the updated file.
Copyright and license headers
The CI/release assets koryph generates carry an SPDX header. By default that
header attributes the file to koryph (The Koryph Developers, Apache-2.0) —
correct for koryph's own repo, wrong for yours. Declare a copyright block in
koryph.project.json so generated files carry your project's attribution:
{
"copyright": {
"holder": "Acme, Inc.",
"year": "2024-2026",
"license": "MIT"
}
}
Every field is optional and falls back to the built-in default
(year → 2026, holder → The Koryph Developers, license → Apache-2.0),
so an unconfigured project attributes generated files to koryph
((c) 2026 The Koryph Developers, matching koryph's own source-header style).
Re-run koryph ci setup (and koryph release setup) after adding or changing it
to restamp the installed assets. The rendered header becomes:
# SPDX-FileCopyrightText: (c) 2024-2026 Acme, Inc.
# SPDX-License-Identifier: MIT
This applies to both the GitHub Actions and GitLab CI generators.
Checking for drift
koryph ci check compares installed CI assets against the current render
output and exits 1 if any asset is missing or has drifted:
# Check the gate pipeline
koryph ci check --project myproject
# Check all installed kinds
koryph ci check --project myproject --kind all
Example output (all current):
ok .github/workflows/koryph-gate.yml
ci check: all CI assets are current.
Example output (drift detected):
DRIFT .github/workflows/koryph-gate.yml
koryph: ci check: drift detected — run `koryph ci setup --project myproject` to update
Run koryph ci setup to resolve drift; ci check is suitable for a
pre-dispatch gate or a periodic CI step.
Release pipeline routing
koryph release setup also installs CI assets — the caller workflow that
drives the release train. It routes through the same forge seam internally:
forge.CI().Render("caller"). The caller workflow is therefore a first-class
CI kind, available (for reference or manual install) as --kind caller on
koryph ci setup.
Practically: run koryph release setup to wire the release pipeline, and
koryph ci setup to wire the gate pipeline. They are independent and compose
freely.
Forge-agnostic posture
koryph CI assets are designed to be forge-agnostic. The same verb and flags work on GitHub and GitLab; only the rendered output differs.
| GitHub | GitLab | |
|---|---|---|
| Gate kind | .github/workflows/koryph-gate.yml |
.koryph/ci/koryph-gate.yml |
| Scanner kind | .github/workflows/koryph-scanner.yml |
.koryph/ci/koryph-scanner.yml |
| Docs kind | .github/workflows/koryph-docs.yml |
.koryph/ci/koryph-docs.yml |
| Trigger (push) | on: push |
rules: CI_PIPELINE_SOURCE == "push" |
| Trigger (PR/MR) | on: pull_request |
rules: CI_PIPELINE_SOURCE == "merge_request_event" |
| Include mechanism | Standalone workflow file | Fragment; needs include: in .gitlab-ci.yml |
| Commit guidance | PR instructions | MR instructions + include guidance |
The forge is resolved automatically from koryph.project.json; you never
need to specify it explicitly.
GitLab: adding the include entry
On GitLab, koryph writes CI fragments to .koryph/ci/. After installing,
add each fragment to your root .gitlab-ci.yml with an include: entry:
include:
- local: '.koryph/ci/koryph-gate.yml'
# (if you installed the scanner)
- local: '.koryph/ci/koryph-scanner.yml'
# (if you installed docs publishing)
- local: '.koryph/ci/koryph-docs.yml'
koryph ci setup prints the exact include: snippet after installation
so you can copy-paste it directly.
See also
koryph ci setupflags referencekoryph ci checkflags reference- Release pipeline setup — routing through the same forge seam
- Choosing a forge — GitHub vs GitLab capabilities