# Gha Pipelines

> Create and modify GitHub Actions CI/CD workflows for the homelab repository. Covers validation pipelines, OCI artifact promotion, and infrastructure testing. Use when: (1) Creating new GitHub Actions workflows, (2) Modifying existing CI/CD pipelines, (3) Adding validation or testing stages, (4) Debugging workflow failures. Triggers: "github actions", "workflow", "ci/cd", "pipeline", "gha", "build artifact", "validation workflow", "ci pipeline"

- Skill: `ionfury/gha-pipelines` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add ionfury/gha-pipelines`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ionfury/gha-pipelines/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: ionfury (https://skillmd.com/u/ionfury)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ionfury/gha-pipelines

---


# GitHub Actions Pipelines

This repository uses `mise` for tool version management so CI and local dev use identical versions. Delegate to Taskfile commands, not raw CLI. Follow homelab-specific conventions below; for generic GHA patterns (matrix builds, github-script, action catalog), see the global [gha-pipelines skill](~/.claude/skills/gha-pipelines/SKILL.md).

## Core Patterns

**Tool setup** — always `jdx/mise-action@v3`, never `apt-get`/`brew`:
```yaml
steps:
  - uses: actions/checkout@v7
  - uses: jdx/mise-action@v4
  - run: task k8s:validate
```

**Actions reference:**

| Need | Action |
|------|--------|
| Checkout | `actions/checkout@v7` |
| Tool setup | `jdx/mise-action@v4` (reads `.mise.toml`) |
| GHCR login | `docker/login-action@v4` |
| GitHub API | `actions/github-script@v9` |
| Flux CLI | `fluxcd/flux2/action@v2` |

**Path-based triggers** — always include the workflow file itself and `.mise.toml`:
```yaml
on:
  pull_request:
    paths:
      - "kubernetes/**"
      - ".github/workflows/kubernetes-validate.yaml"
      - ".mise.toml"
      - ".taskfiles/kubernetes/**"
  workflow_dispatch:
```

**YAML schema comment** on every workflow file:
```yaml
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
```

**Permissions** — always minimal:
```yaml
permissions:
  contents: read
  packages: write   # Only when pushing to GHCR
  statuses: read    # Only when reading commit status events
```

## Workflow Inventory

| Workflow | Trigger | Purpose |
|----------|---------|---------|
| `kubernetes-validate.yaml` | PR (kubernetes/) | Lint, expand ResourceSets, build, template, kubeconform, pluto |
| `infrastructure-validate.yaml` | PR (infrastructure/) | Format checks, module tests (matrix per module) |
| `renovate-validate.yaml` | PR (renovate config) | Validate Renovate configuration |
| `build-platform-artifact.yaml` | Push to main (kubernetes/) | Build OCI artifact, tag as stable, create GitHub Release |
| `check-version-holds.yaml` | Weekly / push (version-holds.yaml) / manual | Monitor upstream issues for held-back versions |
| `renovate.yaml` | Scheduled (hourly) | Dependency update automation |
| `label-sync.yaml` | Scheduled / manual | Sync GitHub labels |

## OCI Promotion Pipeline

For full pipeline tracing and debugging, see the [promotion-pipeline skill](../promotion-pipeline/SKILL.md).

Key design decisions when modifying these workflows:
- The pipeline is direct build-to-live: the build workflow tags artifacts as stable (`X.Y.Z` + `sha-<short>` + `validated-<short>`) at build time — there is no separate promotion workflow
- Build workflow queries GHCR for the latest stable tag, bumps patch, and creates a GitHub Release
- Integration polls with `semver >= 0.0.0-0`; live polls `>= 0.0.0` — both receive the same stable artifacts (integration is not a gate)

## New Validation Workflow Template

```yaml
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: <Domain> Validate

on:
  pull_request:
    paths:
      - "<domain>/**"
      - ".github/workflows/<domain>-validate.yaml"
      - ".mise.toml"
  workflow_dispatch:

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: jdx/mise-action@v4
      - run: task <domain>:validate
```

## Anti-Patterns

- **NEVER** install tools with `apt-get` or `brew` — use `mise`
- **NEVER** use raw `curl`/`jq` for GitHub API — use `actions/github-script`
- **NEVER** hardcode versions in workflow files — versions come from `.mise.toml` or `versions.env`
- **NEVER** use `permissions: write-all` — specify exact permissions needed
- **NEVER** skip `workflow_dispatch` — all workflows support manual runs

## Cross-References

- [.github/CLAUDE.md](../../.github/CLAUDE.md) — Declarative workflow architecture
- [promotion-pipeline skill](../promotion-pipeline/SKILL.md) — Debugging promotion failures
- [.taskfiles/CLAUDE.md](../../.taskfiles/CLAUDE.md) — Task commands used in workflows

