- Shell 98.7%
- Just 1.3%
| .github | ||
| scripts | ||
| tests | ||
| .editorconfig | ||
| .gitignore | ||
| cliff.toml | ||
| justfile | ||
| LICENSE | ||
| mise.toml | ||
| README.md | ||
| renovate.json | ||
| repo-toolkit.json | ||
cjournois/reusable-pipeline
This project is licensed under the GNU AGPL-3.0. See the LICENSE file for details.
Modular CI/CD workflow templates for Forgejo Actions.
Summary
Developer: Usage
Why no packages/services structure
This repo is a GitHub/Forgejo Actions repo — its structure is dictated by the .github/ convention (workflows/ for reusable workflows, actions/ for composite actions). It produces neither packages nor deployable services.
Workflows
| Workflow | Purpose |
|---|---|
ci-pipeline |
Two-job pipeline: CI (lint, test, build) + Publish & Release |
image-build |
Standalone container image build and push |
release-changelog |
Auto-discover units, bump versions, update CHANGELOG, tag, push |
Actions
| Action | Purpose |
|---|---|
configure-registry-auth |
Write private npm/PyPI auth (node, bun, or python). Toolchains come from the caller's mise.toml. |
configure-npm-auth |
Write .npmrc auth for private Forgejo registries (called by configure-registry-auth) |
generate-registry-secret |
Temp .npmrc/pip.conf for BuildKit --secret mounts |
docker-build-push |
Docker login, build, and push with optional secrets and latest tag |
compute-version |
Semver from tags + conventional commits |
check-coverage |
Enforce minimum test coverage |
discover-units |
Parse ci-*.yml callers to find buildable units |
create-forgejo-release |
Create Forgejo release with assets |
publish-npm-package |
Publish to Forgejo npm registry |
publish-poetry-package |
Publish to Forgejo PyPI |
publish-helm-chart |
Publish Helm chart to OCI registry |
Caller examples
ci-pipeline
Each caller declares its toolchain (node/bun/python) in a mise.toml at the repo root or working_directory. The pipeline runs mise install early; tools land on PATH via shims.
jobs:
ci:
uses: cjournois/reusable-pipeline/.github/workflows/ci-pipeline.yml@main
with:
mode: image # image, package, helm, or check
language: bun # node, bun, or python (not required for helm/check)
registry: ${{ vars.REGISTRY }} # container registry host (image/helm)
registry_username: ${{ vars.BOT_REGISTRY_USERNAME }} # not required for mode=check
image_name: my-service # image mode
# private_scopes: "@scope" # npm scopes / PyPI name:group
# build_artifact_path: "lib/" # default dist/
# skip_linter: true # default false
# skip_coverage: true # default false
# min_coverage: 80 # default 60
# tag_prefix: farewell-api # monorepo tag prefix
# working_directory: services/farewell-api # monorepo subdirectory
secrets:
registry_token: ${{ secrets.BOT_REGISTRY_TOKEN }} # not required for mode=check
release_token: ${{ secrets.BOT_RELEASE_TOKEN }} # not required for mode=check
Mode: check (lint + test only)
Use mode: check for repos that aren't publishable (no package/image/chart) but still want lint and test on every push. No language / registry_username / secrets required. If the project has a just ci recipe, it runs before lint (useful for installing dev deps like Python tooling).
jobs:
ci:
uses: cjournois/reusable-pipeline/.github/workflows/ci-pipeline.yml@main
with:
mode: check
Required mise.toml
Caller repos pin their toolchain in mise.toml. Example for a bun service:
[tools]
bun = "1.3.13"
The pipeline calls mise install (no-op when mise.toml is absent and mode is check).
image-build
jobs:
image:
uses: cjournois/reusable-pipeline/.github/workflows/image-build.yml@main
with:
registry: ${{ vars.REGISTRY }}
registry_username: ${{ vars.BOT_REGISTRY_USERNAME }}
image_name: my-org/my-app
# build_dir: . # default .
# tag_prefix: sandbox # optional prefix
# tag_latest: true # default true
# rolling_prefix: rolling-weekly # date-based rolling tag
# language: bun # needed with private_scopes
# private_scopes: "@scope" # private npm/PyPI deps
secrets:
registry_token: ${{ secrets.BOT_REGISTRY_TOKEN }}
release-changelog
jobs:
release:
uses: cjournois/reusable-pipeline/.github/workflows/release-changelog.yml@main
with:
release_username: ${{ vars.BOT_USERNAME }}
secrets:
release_token: ${{ secrets.BOT_RELEASE_TOKEN }}
Developer: Getting Started
Requirements
- Forgejo Actions (or compatible reusable workflow host)
- Registry + Git credentials exposed as shown in the caller snippets
just— command runner
Commands
| Command | Purpose |
|---|---|
just lint |
Shellcheck scripts + actionlint workflows |
just test |
Run bats test suite |
Maintainer: Troubleshooting
- Secrets missing:
registry_tokenandrelease_tokenare both required for publish paths. - Wrong artifact path: override
build_artifact_pathwhen libraries emit something other thanlib/. - Private registry 401: ensure
private_scopesis set and the token hasread:packagescope. For k8s runners with internal URLs, the pipeline writes auth for both internal and external hosts automatically.