| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| build-push-sign-images | ||
| docs/images | ||
| forge-checkout | ||
| gitops-bump-pr | ||
| LICENSES | ||
| mirror-repo | ||
| next-version | ||
| repo-hygiene | ||
| setup-nix-flake-auth | ||
| CODE_OF_CONDUCT.md | ||
| CODEOWNERS | ||
| CONTRIBUTING.md | ||
| LICENSE.md | ||
| README.md | ||
| REUSE.toml | ||
| SECURITY.md | ||
HOIST IT - Forgejo actions
First-party composite actions shared across HOIST IT repositories.
Reference an action by its full URL and subpath, pinned to a tag:
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
Actions
forge-checkout
Blessed checkout for HOIST IT sha256 Forgejo repos. Wraps
HOIST-IT-Actions/checkout@v7 with GIT_DEFAULT_HASH=sha256 and an optional
exact-SHA reset (full fetch), replacing the per-repo checkout@v6/v7 +
code.forgejo.org drift and every re-pasted GIT_DEFAULT_HASH.
| input | default | description |
|---|---|---|
ref |
(triggering ref) | Branch/tag/ref to check out. |
fetch-depth |
1 |
Shallow depth (0 = full). Forced to 0 when sha is set. |
sha |
(none) | Exact commit SHA to reset the worktree to after checkout. |
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
with:
sha: ${{ github.sha }}
setup-nix-flake-auth
Authenticate nix's flake fetcher against the private forge so a repo can pull a
private git+forge flake input (for example the toolbox). nix uses libgit2,
which ignores git's url.insteadOf but does consult git's credential helper, so
the token is stored in ~/.git-credentials (never in argv or the locked flake
URL). Pass the token as an input; the caller supplies it from a secret.
| input | default | description |
|---|---|---|
forge-token |
(required) | Forgejo token with read access to the private flake-input repo(s). |
host |
forge.hoist-it.nl |
Forge host the credential is scoped to. |
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
with:
forge-token: ${{ secrets.FORGE_TOKEN }}
next-version
Compute the next semver from the conventional-commit history with commitizen
(read-only, no bump/commit/tag). Outputs version and release; release is
false when there are no releasable commits since the last tag, gating the
build/publish/tag jobs into a no-op. Needs uvx on PATH and a full-depth
checkout with tags.
| input | default | description |
|---|---|---|
commitizen-spec |
commitizen>=4.16 |
pip requirement spec for commitizen. |
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
id: ver
- run: echo "release=${{ steps.ver.outputs.release }} version=${{ steps.ver.outputs.version }}"
repo-hygiene
Server-side hygiene gate: actionlint over the workflow files plus gitleaks over
the full history. Self-provisions both tools from a pinned nixpkgs (no version
drift), so it needs nix on the job (run it on a nix-capable image). gitleaks
needs a full-depth checkout.
| input | default | description |
|---|---|---|
actionlint-config |
.github/actionlint.yaml |
actionlint ignore-list; skipped if absent. |
gitleaks-args |
detect --source . --verbose --redact |
gitleaks arguments. |
nixpkgs |
(pinned rev) | nixpkgs providing actionlint + gitleaks. |
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
gitops-bump-pr
Open a GitOps deploy PR: clone the gitops repo, bump the newTag of an image in
a kustomization, commit on a branch, push, and open a PR. Needs git, curl and jq
on PATH.
| input | default | description |
|---|---|---|
gitops-repo |
(required) | owner/repo of the gitops repository. |
kustomization |
(required) | Path (in the gitops repo) to the kustomization to bump. |
image-tag |
(required) | New tag to set as newTag. |
token |
(required) | Token with write access to the gitops repo. |
host |
forge.hoist-it.nl |
Forge host. |
base |
main |
Base branch to target. |
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
with:
gitops-repo: HOISTIT/gitops
kustomization: apps/staging/website/kustomization.yaml
image-tag: ${{ needs.build.outputs.tag }}
token: ${{ secrets.GITOPS_TOKEN }}
mirror-repo
Mirror the checked-out repo to one or more external remotes, optionally converting a SHA-256 repo to SHA-1 first. Needs a full-depth checkout and a recent git (the nix-ci / node-ci images carry git 2.54).
| input | default | description |
|---|---|---|
dst-urls |
(required) | Destination remote URLs (with creds), space- or newline-separated. |
convert-sha256-to-sha1 |
false |
Convert a SHA-256 source to SHA-1 before mirroring. |
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
with:
dst-urls: ${{ secrets.CLIENT_MIRROR_URL }}
convert-sha256-to-sha1: "true"
build-push-sign-images
Build every nix2container image from a flake, push it daemonlessly (skopeo
copyTo), and cosign-sign plus attest it, under strict runner-disk discipline:
an upfront nix store gc, a gc-rooted signing toolchain, and a per-image
nix store gc when free store space drops below a threshold. Each image builds,
pushes and signs independently (a failure is recorded and the loop continues),
then the run exits non-zero if any image failed (fail-closed). Extracted from
toolbox build-images.yaml so the disk-GC discipline and the fail-closed loop
live in one place. The calling job owns the container, the flake checkout and
the registry/cosign secrets; the action owns the loop and the disk discipline.
Run it on a nix-capable image (nixos-nix / nix-ci) whose NIX_CONFIG enables
nix-command + flakes and sets sandbox = false.
Two modes cover the two flake-app shapes in use across the org:
copyto-sign(default, the toolbox shape): per image name, push via<flake>#<name>.copyTothen sign via<flake>#<sign-app> -- <name>.publish-app(the dp-engine /mkPublishImageshape): per target, run one self-contained build+push+sign app as<flake>#<app> -- <dest-ref>:<tag>.
| input | default | description |
|---|---|---|
mode |
copyto-sign |
copyto-sign or publish-app. |
flake |
. |
Flake ref prefix for nix run/nix eval; sha256 repos pass path:.. |
tag |
latest |
Tag to push. publish-app appends it to each dest-ref; copyto-sign's sign-image pins :latest itself, so keep latest there (see caveats). |
registry |
forge.hoist-it.nl/hoist-it-infra |
Base registry+namespace for copyto-sign pushes. |
images |
(enumerated) | copyto-sign: explicit names; enumerated from images-expr when empty. |
images-expr |
.#ciImageNames |
copyto-sign: nix expr evaluated to a JSON list of names. |
sign |
true |
copyto-sign: sign each pushed image. |
sign-app |
sign-image |
copyto-sign: the signing flake app (<flake>#<sign-app> -- <name>). |
apps |
(none) | publish-app: newline list of <app> <dest-ref> targets. |
gc-root-app |
(none) | Flake app to gc-root before the loop (toolbox passes sign-image). |
gc-threshold-gib |
15 |
Per-image nix store gc below this many GiB free (0 disables; see caveats). |
store-path |
/nix |
Filesystem whose free space bounds the per-image gc. |
working-directory |
. |
Directory the loop runs in (where the flake lives); consumers cloning into a temp dir point this at it. |
log-groups |
true |
Wrap each phase in a collapsible ::group:: and print a coloured summary; false for flat output. |
Per-image output is wrapped in a collapsible log group and coloured (honours
NO_COLOR): a successful run shows one folded group per image plus a coloured
summary, and a failed target re-prints its full log expanded with an
::error::. Set log-groups: false for flat, ungrouped output.
Registry auth: set REGISTRY_USER + REGISTRY_TOKEN in the job env (the action
passes them as --dest-creds for copyto-sign), or provide REGISTRY_AUTH_FILE
for skopeo. Signing reads the COSIGN_* env the flake apps expect. Set all
of these on the calling job.
Two caveats:
- copyto-sign's
sign-appderives its own reference. The bundledsign-imagesigns<default registry>/<img>:latest, so keeptag: latestand the defaultregistryin copyto-sign mode unless you pass asign-appthat signs the pushed<registry>/<img>:<tag>(a non-latest tag would otherwise sign the old:latestdigest; the action warns when it detects this). - publish-app apps that SHARE an unrooted build-time toolchain across iterations
(dp-engine's two apps reuse a just-built, unrooted skopeo) must set
gc-threshold-gib: "0", so the per-image gc does not reclaim that toolchain and force a recompile that exhausts the runner disk (#34).
toolbox (copyto-sign, clone into /tmp/tb, enumerate the flake image list, gc-root the shared signer):
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
with:
working-directory: /tmp/tb
gc-root-app: sign-image
dp-engine (publish-app, two self-contained apps, sha256 repo so path:., shared
skopeo so the mid-loop gc is disabled):
- uses: https://forge.hoist-it.nl/HOIST-IT-Actions/actions/[email protected]
with:
mode: publish-app
flake: "path:."
working-directory: /tmp/src
tag: ${{ needs.bump.outputs.version }}
gc-threshold-gib: "0"
apps: |
release-image ${{ vars.REGISTRY_URL }}/${{ env.IMAGE_NAME }}
runner-release-image ${{ vars.REGISTRY_URL }}/${{ env.RUNNER_IMAGE_NAME }}
