- Go 97.5%
- Shell 1.4%
- Just 0.5%
- Dockerfile 0.3%
- Go Template 0.2%
| .engine/bin | ||
| .forge-ci | ||
| .forgejo | ||
| .github | ||
| .gitlab/bin | ||
| cmd | ||
| containers | ||
| development | ||
| docs | ||
| examples | ||
| internal | ||
| LICENSES | ||
| scripts | ||
| templates | ||
| test | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| .gommitlint.yaml | ||
| .goreleaser.yml | ||
| .lycheeignore | ||
| .mise.toml | ||
| .semgrepignore | ||
| .shellcheckrc | ||
| .trivyignore.yaml | ||
| CHANGELOG.md | ||
| go.mod | ||
| go.sum | ||
| justfile | ||
| LICENSE | ||
| nanolinter.toml | ||
| README.md | ||
| renovate.json | ||
| REUSE.toml | ||
| SECURITY.md | ||
Forge CI
Forge CI gives a project pull-request checks, builds, publishing and signed
releases on GitHub, GitLab and Forgejo, driven by one Go CLI, forge-ci.
You call its workflows from your repository instead of building SBOMs,
signing, SLSA provenance and pinned third-party actions yourself.
- One release flow: push a signed
release-request/vX.Y.Ztag, and Forge CI validates it, creates the finalvX.Y.Ztag, builds, publishes and signs. - A single-manifest repository needs no configuration file; add
.forge-ci/artifacts.ymlonly when you need more.
Quick Start
Install the CLI, then add pull/merge-request checks and release configuration for your forge. GitHub, GitLab and Forgejo use their own CI syntax.
Install
# With mise (manages the Go toolchain):
mise use -g go@1.27.3
go install github.com/diggsweden/forge-ci/cmd/forge-ci@v0.90.0
# Or with Go alone:
go install github.com/diggsweden/forge-ci/cmd/forge-ci@v0.90.0
forge-ci init <repo-url> writes a project's first CI files;
forge-ci doctor checks local configuration.
Choose your forge and preview initialization
The URL is the Forge CI template repository, not your application's remote.
It also determines the generated CI layout: init does not infer the forge from
your application's Git remote or a global --provider selection.
| Your forge | Template source | Generated CI location |
|---|---|---|
| GitHub | A Forge CI repository on github.com |
.github/workflows/ |
| GitLab | Your instance's Forge CI mirror, declaring forge: gitlab |
.gitlab-ci.yml |
| Forgejo | Your instance's Forge CI mirror, declaring forge: forgejo |
.forgejo/workflows/ |
Outside github.com, the mirror's operator must put that forge value in
.forge-ci/consumer-defaults.yml at the selected release tag.
Without it, initialization refuses rather than guessing from the hostname.
From your project directory, choose one of the following previews. Replace the example URL with the published template repository your organization uses:
# GitHub
forge-ci init https://github.com/YOUR-ORG/forge-ci --dry-run
# GitLab — mirror defaults must declare forge: gitlab
forge-ci init https://gitlab.example.com/team/forge-ci --dry-run
# Forgejo — mirror defaults must declare forge: forgejo
forge-ci init https://forgejo.example.com/team/forge-ci --dry-run
The preview reports the target directory, resolved release and commit, selected
example, proposed files, existing-file conflicts, and remaining placeholders.
Check that its reported forge and proposed file locations match your project.
It fetches templates into temporary storage but writes no project files.
Conflicts return a nonzero status; existing files are never replaced.
Use --example to choose an example and --ref to select an available release.
After review, repeat without --dry-run, retaining the reported release and example.
Preview and generation fetch the source independently; preview is not a saved execution plan.
Linter configuration files are optional customizations: init does not create
or modify Nanolinter or MegaLinter configs. The lint-engine input selects the
engine (Nanolinter by default in the GitHub PR workflow); without a config file,
the selected engine uses its defaults and the workflow's required lint floor
still applies. The examples include configs you can copy
to customize those defaults.
Nanolinter performs its own lookup: root nanolinter.toml, then
development/nanolinter.toml, then built-in defaults.
GitHub: Pull-request checks
The following manual examples are for GitHub only.
Use the GitLab guide or
Forgejo guide for those CI systems.
Replace diggsweden/forge-ci in the GitHub examples with your selected template
repository and pin an available release consistently.
One caller workflow runs lint and security scans on every PR. Add your own test job alongside it:
# .github/workflows/pr.yml
on:
pull_request:
permissions:
contents: read
jobs:
pr-checks:
uses: diggsweden/forge-ci/.github/workflows/pullrequest-orchestrator.yml@v0.90.0
permissions:
actions: read
contents: read
with:
forge-ci-binary-ref: v0.90.0
project-type: go # maven, npm, gradle, cargo, ...
GitHub: Release
Push a signed tag — the flow builds, signs, publishes and creates the final version tag:
# .github/workflows/release.yml
on:
push:
tags: ["release-request/v*"]
permissions:
contents: read
jobs:
release:
uses: diggsweden/forge-ci/.github/workflows/release-orchestrator.yml@v0.90.0
permissions:
contents: write
packages: write
id-token: write # Sigstore keyless signing
actions: read
secrets:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
RELEASE_SSH_SIGNING_KEY: ${{ secrets.RELEASE_SSH_SIGNING_KEY }}
with:
branch: main
forge-ci-binary-ref: v0.90.0
git tag -s release-request/v1.0.0 -m "Release v1.0.0"
git push origin release-request/v1.0.0
GitLab and Forgejo use the same two flows through their own CI syntax — see the examples for complete per-forge files.
Using Forge CI
Start with the Documentation Index for the full map.
- Examples • Ready-made pipelines for Go, Cargo, Maven, Gradle, npm, Android and a monorepo, on each forge that builds them
- Forge guides • GitHub · GitLab · Forgejo, in the same section order
- How-to • Publishing · Runtime Images · Artifact Verification · SBOM · Failed Release Recovery
- Reference • Artifacts Reference · Components Reference · CLI Reference · Secrets, Permissions, and Validation · Project Reference
- Concepts • Workflow Architecture · Artifact and Image Flows · Ecosystems · Providers and Runners · CLI Black Box · Threat Model
Working on Forge CI
- Development • Source checkout, installing the CLI from it, prerequisites, checks and branch testing
- Testing • Test helpers and conventions
- Black-box suite running guide • Local, strict and focused compatibility runs
- Workflow Design Policy · Scripts · Architecture Decisions · Open Questions
- Security • How to report a vulnerability
- Changelog
License
The forge-ci program, meaning the Go source, is dual-licensed
EUPL-1.2 OR
GPL-3.0-or-later, at your option.
Everything you copy into your own repository is
CC0-1.0: the reusable workflows, the GitLab Catalog
components in templates/, the Forgejo workflows and actions in .forgejo/,
the shell scripts, and all configuration, documentation and examples. Lift them
freely. The shell files under .forgejo/ are the exception: they carry the
program's licence.
See LICENSE for the full statement. Every file carries an SPDX identifier, which is authoritative for that file.