6.9 KiB
pipeline-actions — Agent Guide
Overview
This repo provides reusable Gitea composite actions for homelab CI/CD pipelines. Actions are consumed by other projects via the full-URL form uses: https://git.ivanch.me/ivanch/pipeline-actions/<action>@main.
Actions
build-and-push (build-and-push/action.yaml)
Logs into the container registry, sets up SSH key for docker-build.haven, creates a remote Buildx context over SSH, and builds + pushes a multi-arch Docker image.
Inputs:
image(required) — full image ref without tagregistry_password(required) — registry password/token (use secrets)ssh_key(required) — SSH private key for remote builder (use secrets)image_tag(defaultlatest) — comma-separated tag(s) to apply to the built image (e.g.latest,abc1234)registry_host(defaultgit.ivanch.me) — container registry hostnameregistry_username(defaultivanch) — registry usernameplatforms(defaultlinux/amd64,linux/arm64) — target build platformsbuild_context(default.) — Docker build context pathbuild_dockerfile(defaultDockerfile) — Dockerfile path relative to contextbuild_args(default empty) — build arguments, oneKEY=VALUEper line; each becomes a--build-argdocker_host(defaultdocker-build.haven) — remote builder hostnamedocker_user(defaultroot) — SSH user for remote builder
deploy-restart (deploy-restart/action.yaml)
Validates KUBE_CONFIG, installs kubectl, and performs rollout restart of a Kubernetes Deployment.
Inputs:
kube_config(required) — full kubeconfig YAML (use secrets)deployment_name(required) — Deployment name to restartnamespace(defaultdefault) — Kubernetes namespacekube_version(defaultstable) — kubectl version to download
kubectl-apply (kubectl-apply/action.yaml)
Validates KUBE_CONFIG, installs kubectl, and applies Kubernetes manifest(s) that live inside the repository. This is the in-repo, k8s analog of ssh-deploy's compose_files, and the recommended way to deploy manifest specs committed to the consuming repo. Pair it with deploy-restart when a restart is also required (Deployments); use it alone for CronJobs, Services, Ingresses, Secrets, etc.
Inputs:
kube_config(required) — full kubeconfig YAML (use secrets)manifest(default empty) — single manifest path (relative to repo root) to applymanifests(default empty) — space-/comma-separated list of manifest paths; each applied with its ownkubectl apply -fnamespace(default empty) — adds-n <ns>when non-empty (manifests may also self-declare their namespace)kube_version(defaultstable) — kubectl version to download
At least one of
manifest/manifestsmust be set. A path that does not exist in the repo fails the step — the manifest must be committed to the repo.
ssh-deploy (ssh-deploy/action.yaml)
SSH into a remote host, pull the latest images with docker compose pull, and recreate containers with docker compose up -d --force-recreate. Uses native ssh/ssh-keyscan — no third-party SSH action.
Inputs:
ssh_host(required) — remote server hostname or IPssh_username(required) — SSH usernamessh_key(required) — SSH private key (use secrets)remote_dir(required) — directory on the remote server containing docker-compose.ymlssh_port(default22) — SSH portcompose_files(default empty) — space-separated compose file paths (applied via -f flags)image(default empty) — image base (host/path/name, no tag); when set, every compose service matching this base is pinned toimage_tagat deploy timeimage_tag(defaultlatest) — tag applied toimagewhen set (single tag; no comma-lists)
Workflow Template for New Projects
When wiring up CI/CD for a new homelab project, create .gitea/workflows/main.yaml:
name: Build and Deploy (internal)
on:
push:
branches:
- main
workflow_dispatch: {}
env:
IMAGE: git.ivanch.me/ivanch/<PROJECT_NAME>
jobs:
build:
name: Build Image
runs-on: ubuntu-amd64
steps:
- uses: actions/checkout@v4
- uses: https://git.ivanch.me/ivanch/pipeline-actions/build-and-push@main
with:
image: ${{ env.IMAGE }}
registry_password: ${{ secrets.REGISTRY_PASSWORD }}
ssh_key: ${{ secrets.SSH_KEY_DOCKERBUILD }}
deploy:
name: Deploy (internal)
runs-on: ubuntu-amd64
needs: build
steps:
# Deployment specs live in the repo; apply them with kubectl-apply.
- uses: https://git.ivanch.me/ivanch/pipeline-actions/kubectl-apply@main
with:
kube_config: ${{ secrets.KUBE_CONFIG }}
manifest: deploy/<PROJECT_NAME>.yaml
# Restart the Deployment so the new image is rolled out.
- uses: https://git.ivanch.me/ivanch/pipeline-actions/deploy-restart@main
with:
kube_config: ${{ secrets.KUBE_CONFIG }}
deployment_name: <DEPLOYMENT_NAME>
namespace: <NAMESPACE>
Required Secrets
Consumer projects must set these secrets in Gitea repo settings (Settings → Actions → Secrets):
| Secret | Purpose |
|---|---|
REGISTRY_PASSWORD |
Container registry password/token for git.ivanch.me |
SSH_KEY_DOCKERBUILD |
SSH private key for root@docker-build.haven |
KUBE_CONFIG |
Full kubeconfig YAML for k8s cluster access |
DEPLOY_HOST |
Remote server hostname or IP (for ssh-deploy) |
DEPLOY_USERNAME |
SSH username for the remote server (for ssh-deploy) |
DEPLOY_KEY |
SSH private key for the remote server (for ssh-deploy) |
DEPLOY_DIR |
Directory on the remote server with docker-compose.yml (for ssh-deploy) |
Rules
- Pin composite action refs to
@mainuntil version tags are created. - Always use the full URL
https://git.ivanch.me/ivanch/pipeline-actions/<action>@mainforuses:— Gitea cannot resolve the bare GitHub-styleivanch/pipeline-actions/...path. - Always use
runs-on: ubuntu-amd64(homelab Gitea runner label). - Always build
linux/amd64,linux/arm64— the cluster has mixed arch (iris+vega=amd64, nebula+nexus=arm64). - Workflow files go in
.gitea/workflows/main.yamlof the consuming project. - The consuming project must have a working
Dockerfileat the repo root (or passbuild_dockerfileinput). - Kubernetes deploy specs are committed to the consuming repo (e.g. under
*/deploy/*.yaml) and applied withkubectl-apply. Pass their repo-relative path viamanifest/manifests. Do not write deploy specs inline in the workflow — they belong in the repo so they can be reviewed and versioned.
Do Not
- Do not add GitHub Actions workflows — these are Gitea composite actions only.
- Do not hardcode secrets in workflow files — always use
${{ secrets.* }}. - Do not override
platformsto a single arch unless there's a specific reason. - Do not vendor dependencies — consumers reference this repo via the full-URL
uses:form.