GitHub Actions Reference
kindling ships two reusable composite actions that replace 15+ lines
of signal-file boilerplate with a single uses: step. These actions
live in the kindling repo under .github/actions/ and are referenced as:
kindling-sh/kindling/.github/actions/kindling-build@main
kindling-sh/kindling/.github/actions/kindling-deploy@main
kindling-build
Build and push a container image via the Kaniko build-agent sidecar.
This action runs the Dockerfile found in the build context directory as-is using Kaniko. It does not generate or modify Dockerfiles. Each service must have a working Dockerfile that builds successfully on its own (e.g. docker build .). If it doesn't build locally, it won't build in kindling.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
name | ✅ | — | Unique build name (used for signal files: /builds/<name>.*) |
context | ✅ | — | Path to the build context directory |
image | ✅ | — | Full image reference (registry/name:tag) |
exclude | ❌ | "" | tar --exclude patterns (space-separated, e.g. "./ui ./.git") |
dockerfile | ❌ | "" | Path to Dockerfile relative to build context (e.g. api/Dockerfile). If omitted, Kaniko uses the default Dockerfile in the context root. |
timeout | ❌ | 300 | Max seconds to wait for the build to complete |
What it does
- Creates a tarball of the build context at
/builds/<name>.tar.gz(with optional--excludepatterns) - Writes the target image to
/builds/<name>.dest - If
dockerfileis specified, writes the path to/builds/<name>.dockerfile - Touches
/builds/<name>.requestto trigger the Kaniko sidecar - Polls for
/builds/<name>.done(up totimeoutseconds) - Checks
/builds/<name>.exitcode— exits non-zero on failure
Usage
- name: Build my-app
uses: kindling-sh/kindling/.github/actions/kindling-build@main
with:
name: my-app
context: ${{ github.workspace }}
image: "registry:5000/my-app:${{ github.sha }}"
With exclusions
- name: Build API (exclude UI directory)
uses: kindling-sh/kindling/.github/actions/kindling-build@main
with:
name: my-api
context: ${{ github.workspace }}
image: "registry:5000/my-api:${{ github.sha }}"
exclude: "./ui ./.git ./node_modules"
With custom Dockerfile path
When the Dockerfile is not at the context root (common in monorepos or
projects using docker-compose with context: . and dockerfile: api/Dockerfile):
- name: Build API (Dockerfile in subdirectory)
uses: kindling-sh/kindling/.github/actions/kindling-build@main
with:
name: my-api
context: ${{ github.workspace }}
image: "registry:5000/my-api:${{ github.sha }}"
dockerfile: "api/Dockerfile"
kindling-deploy
Deploy a DevStagingEnvironment CR via the build-agent sidecar.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
name | ✅ | — | DSE metadata.name (typically <actor>-<service>) |
image | ✅ | — | Container image reference |
port | ✅ | — | Container port (string) |
labels | ❌ | "" | Extra labels as YAML block |
env | ❌ | "" | Extra env vars as YAML block |
dependencies | ❌ | "" | Dependencies as YAML block |
ingress-host | ❌ | "" | Ingress hostname (omit to skip ingress) |
ingress-class | ❌ | nginx | Ingress class name |
health-check-path | ❌ | /healthz | HTTP health check path |
replicas | ❌ | 1 | Number of replicas |
service-type | ❌ | ClusterIP | Service type |
wait | ❌ | true | Wait for deployment rollout |
wait-timeout | ❌ | 180s | Rollout wait timeout |
What it does
- Generates a complete
DevStagingEnvironmentYAML manifest from the inputs - Writes it to
/builds/<name>-dse.yaml - Touches
/builds/<name>-dse.applyto trigger sidecarkubectl apply - Waits for the sidecar to confirm the apply succeeded
- Optionally waits for the Deployment rollout to complete
Basic usage
- name: Deploy my-app
uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
with:
name: "${{ github.actor }}-my-app"
image: "registry:5000/my-app:${{ github.sha }}"
port: "8080"
ingress-host: "${{ github.actor }}-my-app.localhost"
With dependencies
- name: Deploy with Postgres + Redis
uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
with:
name: "${{ github.actor }}-my-app"
image: "registry:5000/my-app:${{ github.sha }}"
port: "8080"
ingress-host: "${{ github.actor }}-my-app.localhost"
dependencies: |
- type: postgres
version: "16"
- type: redis
With env vars
- name: Deploy with environment variables
uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
with:
name: "${{ github.actor }}-my-ui"
image: "registry:5000/my-ui:${{ github.sha }}"
port: "80"
health-check-path: "/"
ingress-host: "${{ github.actor }}-my-ui.localhost"
env: |
- name: API_URL
value: "http://${{ github.actor }}-my-api:8080"
- name: NODE_ENV
value: "development"
Complete workflow example
A full workflow using both actions:
name: Dev Deploy
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: [self-hosted, "${{ github.actor }}"]
env:
TAG: ${{ github.sha }}
steps:
- uses: actions/checkout@v4
- name: Clean builds directory
run: rm -f /builds/*
# ── Build ──────────────────────────────────────────────
- name: Build API image
uses: kindling-sh/kindling/.github/actions/kindling-build@main
with:
name: my-api
context: ${{ github.workspace }}
image: "registry:5000/my-api:${{ env.TAG }}"
exclude: "./ui"
- name: Build UI image
uses: kindling-sh/kindling/.github/actions/kindling-build@main
with:
name: my-ui
context: "${{ github.workspace }}/ui"
image: "registry:5000/my-ui:${{ env.TAG }}"
# ── Deploy ─────────────────────────────────────────────
- name: Deploy API
uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
with:
name: "${{ github.actor }}-my-api"
image: "registry:5000/my-api:${{ env.TAG }}"
port: "8080"
ingress-host: "${{ github.actor }}-my-api.localhost"
dependencies: |
- type: postgres
version: "16"
- type: redis
- name: Deploy UI
uses: kindling-sh/kindling/.github/actions/kindling-deploy@main
with:
name: "${{ github.actor }}-my-ui"
image: "registry:5000/my-ui:${{ env.TAG }}"
port: "80"
health-check-path: "/"
ingress-host: "${{ github.actor }}-my-ui.localhost"
env: |
- name: API_URL
value: "http://${{ github.actor }}-my-api:8080"
Troubleshooting
Build times out
Increase the timeout:
with:
timeout: "600" # 10 minutes
Deploy apply fails
Check the output for:
- Invalid YAML indentation
- Missing required fields
- Image not found in registry
Rollout doesn't complete
Check pod events:
kubectl describe pod -l app.kubernetes.io/name=<name>
kubectl logs -l app.kubernetes.io/name=<name>
Common causes:
- Image pull errors (image not pushed to registry:5000)
- Health check failing (wrong path or port)
- Dependency not ready (database still starting)