6.4 KiB
pipeline-actions
Reusable composite actions for Gitea Actions CI/CD pipelines in the homelab.
Actions
build-and-push
Builds and pushes a multi-architecture Docker image using a remote Buildx builder over SSH.
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: git.ivanch.me/ivanch/my-app
registry_password: ${{ secrets.REGISTRY_PASSWORD }}
ssh_key: ${{ secrets.SSH_KEY_DOCKERBUILD }}
# optional — these have sensible defaults:
# image_tag: latest
# registry_host: git.ivanch.me
# registry_username: ivanch
# platforms: linux/amd64,linux/arm64
# build_context: .
# build_dockerfile: Dockerfile
# docker_host: docker-build.haven
# docker_user: root
| Input | Required | Default | Description |
|---|---|---|---|
image |
✅ | — | Full image reference without tag |
registry_password |
✅ | — | Registry password/token (use secrets) |
ssh_key |
✅ | — | SSH private key for the remote builder (use secrets) |
docker_host |
❌ | docker-build.haven |
Remote builder hostname |
docker_user |
❌ | root |
SSH user for remote builder |
deploy-restart
Validates a kubeconfig, installs kubectl, and performs a rollout restart of a Kubernetes Deployment.
| Input | Required | Default | Description |
|---|---|---|---|
kube_config |
✅ | — | Full kubeconfig YAML (use secrets) |
deployment_name |
✅ | — | Deployment name to restart |
namespace |
❌ | default |
Kubernetes namespace |
kube_version |
❌ | stable |
kubectl version (stable or e.g. v1.31.0) |
kubectl-apply
Validates a kubeconfig, installs kubectl, and applies Kubernetes manifest(s) that live inside the repository (the non-Docker, in-repo analog of ssh-deploy's compose_files). Pair it with deploy-restart when you also want a rollout restart after the apply — or use it alone for resources that don't need a restart (CronJob, Service, Ingress, Secrets, etc.).
jobs:
deploy:
name: Apply Manifests (internal)
runs-on: ubuntu-amd64
needs: build
steps:
- uses: https://git.ivanch.me/ivanch/pipeline-actions/kubectl-apply@main
with:
kube_config: ${{ secrets.KUBE_CONFIG }}
manifest: Mindforge.API/deploy/mindforge-api.yaml
# or apply several at once:
# manifests: deploy/svc.yaml,deploy/deployment.yaml
# optional:
# namespace: mindforge # adds -n when set (manifests may also self-declare)
| Input | Required | Default | Description |
|---|---|---|---|
kube_config |
✅ | — | Full kubeconfig YAML (use secrets) |
manifest |
❌ | (empty) | Single manifest path (relative to repo root) to apply |
manifests |
❌ | (empty) | Space-/comma-separated list of manifest paths to apply (each gets its own kubectl apply -f) |
namespace |
❌ | (empty) | Adds -n <ns> when non-empty; manifests may also declare their own namespace |
kube_version |
❌ | stable |
kubectl version (stable or e.g. v1.31.0) |
At least one of
manifestormanifestsmust be set; a missing file fails the step (the manifest must live in the repo).
jobs:
restart:
name: Rollout Restart (internal)
runs-on: ubuntu-amd64
needs: apply
steps:
- uses: https://git.ivanch.me/ivanch/pipeline-actions/deploy-restart@main
with:
kube_config: ${{ secrets.KUBE_CONFIG }}
deployment_name: my-app
# optional:
# namespace: default
# kube_version: stable
ssh-deploy
SSH into a remote host and run docker compose pull + docker compose up -d --force-recreate to deploy the latest images. No third-party SSH action — uses native ssh and ssh-keyscan.
jobs:
deploy:
name: SSH Deploy (internal)
runs-on: ubuntu-amd64
needs: build
steps:
- uses: https://git.ivanch.me/ivanch/pipeline-actions/ssh-deploy@main
with:
ssh_host: ${{ secrets.DEPLOY_HOST }}
ssh_username: ${{ secrets.DEPLOY_USERNAME }}
ssh_key: ${{ secrets.DEPLOY_KEY }}
remote_dir: ${{ secrets.DEPLOY_DIR }}
# optional:
# ssh_port: "22"
# compose_files: docker-compose.yml compose.override.yml
# image: git.ivanch.me/ivanch/my-app # pins matching services
# image_tag: latest # Docker-only custom tag
| Input | Required | Default | Description |
|---|---|---|---|
ssh_host |
✅ | — | Remote server hostname or IP |
ssh_username |
✅ | — | SSH username |
ssh_key |
✅ | — | SSH private key (use secrets) |
remote_dir |
✅ | — | Directory on the remote server with docker-compose.yml |
ssh_port |
❌ | 22 |
SSH port |
compose_files |
❌ | (empty) | Space-separated compose file paths (applied via -f flags; when empty docker compose uses default detection) |
image |
❌ | (empty) | Image base (host/path/name, without tag). When set, every compose service whose image matches this base is pinned to image_tag at deploy time. Docker-only — k8s deploys use deploy-restart, not this. |
image_tag |
❌ | latest |
Tag applied to image when image is set. (Single tag — comma-lists are not supported for deploys.) |
Rules
- Every job must have a
name:field (e.g.name: Build Image,name: Deploy (internal)). Named jobs make the Gitea Actions UI and run logs readable — unnamed jobs show up as the raw job ID (build,deploy, …). The templates above all includename:. - Pin composite action refs to
@mainuntil version tags are created.
Consumer repositories need these secrets configured in Gitea:
| Secret | Used by | Purpose |
|---|---|---|
REGISTRY_PASSWORD |
build-and-push |
Container registry password/token |
SSH_KEY_DOCKERBUILD |
build-and-push |
SSH private key for docker-build.haven |
KUBE_CONFIG |
deploy-restart |
Full kubeconfig YAML for cluster access |
DEPLOY_HOST |
ssh-deploy |
Remote server hostname or IP |
DEPLOY_USERNAME |
ssh-deploy |
SSH username for the remote server |
DEPLOY_KEY |
ssh-deploy |
SSH private key for the remote server |
DEPLOY_DIR |
ssh-deploy |
Directory on the remote server with docker-compose.yml |