No description
Find a file
2026-07-15 14:44:19 +00:00
_lib feat: add milestone-sync, issue-sync, issue-intake actions 2026-07-15 15:16:53 +02:00
create-pr Added create-pr action to test. 2026-05-11 15:37:11 +02:00
docker-cleanup Added a bunch of actions. 2026-05-11 15:51:28 +02:00
docker-login Added a bunch of actions. 2026-05-11 15:51:28 +02:00
issue-intake feat: add milestone-sync, issue-sync, issue-intake actions 2026-07-15 15:16:53 +02:00
issue-sync feat: add milestone-sync, issue-sync, issue-intake actions 2026-07-15 15:16:53 +02:00
keys-cleanup Added a bunch of actions. 2026-05-11 15:51:28 +02:00
milestone-sync fix(milestone-sync): suppress leaked API response bodies 2026-07-15 16:43:35 +02:00
prepare-cosign Added a bunch of actions. 2026-05-11 15:51:28 +02:00
prepare-melange Added a bunch of actions. 2026-05-11 15:51:28 +02:00
prepare-repo Added a bunch of actions. 2026-05-11 15:51:28 +02:00
prepare-ssh Added a bunch of actions. 2026-05-11 15:51:28 +02:00
prepare-ssh-signing Added a bunch of actions. 2026-05-11 15:51:28 +02:00
README.md feat: add milestone-sync, issue-sync, issue-intake actions 2026-07-15 15:16:53 +02:00

CI Actions

Custom composite actions for Forgejo Actions. Each is a folder with its own action.yml; reference them as uses: https://forgejo.wulf.science/WulfScience-FOSS/ci-actions/<name>@vN. The whole repo is tagged together (v1, v2, v3, …) rather than each action having its own version — bump the tag whenever an action is added or changed.

Repo checkout

prepare-repo

Runs ./update.sh in the consuming repo. Every repo using this action must have its own update.sh at the root that fetches whatever it needs (submodules, typically: git submodule update --init --recursive + git submodule update --remote --merge --recursive).

No inputs/outputs.

SSH / signing

prepare-ssh

Restores an SSH deploy/push key from inputs.ssh_key, writes it to ~/.ssh/id_ed25519, and exports GIT_SSH_COMMAND (via $GITHUB_ENV) pointed at it with host-key checking disabled. Use this when a workflow needs to git push as itself.

Inputs: ssh_key (required)

prepare-ssh-signing

Restores an SSH commit-signing key from inputs.signing_key, derives its public key, and writes a matching ~/.ssh/allowed_signers line for ci@wulf.science. Pairs with git config gpg.format ssh + gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers + user.signingkey ~/.ssh/signing_key.pub +commit.gpgsign true in the calling workflow (see issue-intake's "Commit issue file" step for the pattern).

Inputs: signing_key (required)

keys-cleanup

Removes the keys/ directory (used by prepare-cosign/prepare-melange below). Run with if: always() so it fires even if earlier steps failed. Does not clean up ~/.ssh/* from prepare-ssh/prepare-ssh-signing — those live outside keys/ and aren't touched by this action.

No inputs/outputs.

Docker / registry

docker-login

Logs into a registry using an ephemeral DOCKER_CONFIG directory (avoids touching the runner's real Docker config) and exports DOCKER_CONFIG via $GITHUB_ENV for subsequent steps.

Inputs: registry, username, token (all required)

docker-cleanup

Removes the ephemeral DOCKER_CONFIG directory created by docker-login, if set. Pair the two, with cleanup on if: always().

No inputs/outputs.

Artifact signing key prep

prepare-cosign

Restores a cosign private key from inputs.cosign_key to keys/prod/cosign.key.

Inputs: cosign_key (required)

prepare-melange

Restores a base64-encoded melange signing key from inputs.melange_key to keys/prod/melange.rsa.

Inputs: melange_key (required)

Both of these are cleaned up by keys-cleanup (they write under keys/).

Pull requests

create-pr

Creates a PR and immediately attempts to merge it, without waiting for checks — see its own TODO comment. That's the right behavior for automated deploy pipelines where the PR is a formality/audit trail rather than a real review gate, and the wrong behavior anywhere a human needs to review before it becomes canonical.

Do not use create-pr for anything that needs review-before-merge. issue-intake (below) needed exactly that and creates its PR with a direct API call instead of reusing this action — see its action.yml for the pattern to copy if you hit the same need elsewhere.

Inputs: description, head, repository, title, token (all required) Outputs: pr_number

Issue-tracker-as-code

Three actions implementing the repo-as-source-of-truth issue/milestone system (originally built in the services repo, consolidated here so it isn't duplicated per-repo). All three share _lib/issue-lib.sh (not an action itself — internal helpers only, sourced via ${{ github.action_path }}/../_lib/issue-lib.sh). They operate on the consuming repo's checkout, not on ci-actions itself.

Consuming-repo conventions these assume:

  • docs/roadmap/phase-*.md files with a ## Phase Gate Checklist section, items formatted - [ ] P<N>-<M> <description>.
  • issues/NNNN.yaml files, one per issue, linked to their Forgejo counterpart only by a [#NNNN] tag in the Forgejo issue title.

milestone-sync

Syncs Forgejo milestones + issues from docs/roadmap/phase-*.md checklists. Idempotent. Typically run on PR-merge-to-main.

Inputs: token, owner, repo (required); pr_number, dry_run (optional)

issue-sync

Forward sync: projects issues/NNNN.yaml files into Forgejo issues. The repo is the source of truth — this overwrites any divergent UI state. Only ever touches [#NNNN]-tagged issues. Typically run on push to main.

Inputs: token, owner, repo (required); dry_run (optional)

issue-intake

Reverse sync: records a Forgejo UI issue event (opened/edited/closed) as an issues/NNNN.yaml file, commits it to a per-issue branch (chore/issues-intake--NNNN, signed as ci@wulf.science), and opens a PR — never pushed to main, so a UI-originated issue is always reviewed before becoming canonical. Internally chains prepare-ssh + prepare-ssh-signing

  • its own direct PR-creation call (not create-pr — see above) + keys-cleanup.

Inputs: token, owner, repo, ssh_key, signing_ssh_key, pr_token (all required) Outputs: changed, id