CI Shared Workflows (rune-ci)¶
The rune-ci repository centralizes
reusable GitHub Actions workflows and composite actions for the entire RUNE
platform. Consumer repos call these shared workflows with thin callers
(typically 15-20 lines each), eliminating duplication across 8 repositories.
Repository Structure¶
rune-ci/
.github/workflows/ # Reusable workflows (workflow_call)
python-quality.yml # Coverage + lint + SAST + license
go-quality.yml # Go test + fmt + vet + gosec + license
security-scan.yml # Gitleaks + optional SBOM scan
container-build.yml # Multi-arch Docker build (amd64 + arm64)
release.yml # Tag verify + build + manifest + GH Release
helm-release.yml # Helm chart packaging + GH Release
helm-quality.yml # helm lint + trivy config scan
docs-quality.yml # mkdocs build --strict + pymarkdown
shell-quality.yml # ShellCheck + YAMLLint
pr-compliance.yml # PR body validation + merge gate + ML4
project-sync.yml # Project board automation
quality-gates.yml # CI for CI (actionlint + yamllint)
actions/ # Composite actions
gitleaks-scan/ # Secret scanning
sbom-scan/ # SBOM generation + CVE scanning
license-check/ # License compliance (Python + Go)
docker-setup/ # Docker login + buildx + cache metadata
scripts/
merge_gate.py # Merge gate evaluator
Reusable Workflows¶
python-quality.yml¶
Python test coverage, linting (ruff), SAST (bandit), and license compliance.
| Input | Type | Default | Description |
|---|---|---|---|
python-version |
string | "3.12" |
Python version |
coverage-threshold |
number | 97 |
Minimum coverage percentage |
requirements-file |
string | "requirements.txt" |
Pip requirements file |
source-dir |
string | "." |
Source directory for coverage |
go-quality.yml¶
Go test coverage, formatting, vetting, static analysis (gosec), and license compliance.
| Input | Type | Default | Description |
|---|---|---|---|
go-version |
string | "1.24" |
Go version |
coverage-threshold |
number | 80 |
Minimum coverage percentage |
security-scan.yml¶
Gitleaks secret scanning with optional SBOM + CVE scanning.
| Input | Type | Default | Description |
|---|---|---|---|
gitleaks-version |
string | "8.24.3" |
Gitleaks version |
run-sbom |
boolean | false |
Enable SBOM + CVE scan |
image |
string | "" |
Container image for SBOM scan |
container-build.yml¶
Multi-arch Docker image build (amd64 + arm64) with registry caching.
| Input | Type | Default | Description |
|---|---|---|---|
image-name |
string | required | Image name |
registry-owner |
string | "lpasquali" |
Registry owner |
dockerfile |
string | "./Dockerfile" |
Dockerfile path |
release.yml¶
Tag verification, multi-arch Docker build, manifest creation, GitHub Release, optional SBOM generation, SLSA L3 attestation, and rune-charts notification.
| Input | Type | Default | Description |
|---|---|---|---|
image-name |
string | "" |
Image name (required if build-container is true) |
registry-owner |
string | "lpasquali" |
Registry owner |
dockerfile |
string | "./Dockerfile" |
Dockerfile path |
build-container |
boolean | true |
Build and publish container image |
notify-charts |
boolean | false |
Send dispatch to rune-charts |
generate-sbom |
boolean | false |
Generate CycloneDX SBOM |
slsa-attestation |
boolean | false |
Generate SLSA L3 attestation |
| Secret | Required | Description |
|---|---|---|
RUNE_CHARTS_BOT_TOKEN |
No | PAT for cross-repo dispatch |
helm-release.yml¶
Helm chart packaging and GitHub Release creation.
| Input | Type | Default | Description |
|---|---|---|---|
charts-dir |
string | "charts" |
Directory containing chart subdirectories |
helm-quality.yml¶
Helm lint and Trivy configuration scanning.
| Input | Type | Default | Description |
|---|---|---|---|
charts-dir |
string | "charts" |
Directory containing chart subdirectories |
docs-quality.yml¶
MkDocs strict build and pymarkdown linting.
| Input | Type | Default | Description |
|---|---|---|---|
python-version |
string | "3.12" |
Python version |
requirements-file |
string | "requirements.txt" |
Pip requirements file |
shell-quality.yml¶
ShellCheck and YAMLLint for shell scripts and YAML files.
| Input | Type | Default | Description |
|---|---|---|---|
script-dirs |
string | "scripts" |
Space-separated script directories |
script-glob |
string | "*.sh" |
Glob pattern for shell scripts |
pr-compliance.yml¶
PR body structure validation, merge gate aggregation, and ML4 automated approval.
No configurable inputs. The workflow validates PR body sections (issue reference, DoD level, Acceptance Criteria Evidence, Audit Checks, Breaking Changes) and auto-approves after all gates pass.
project-sync.yml¶
Automated project board synchronization. Sets Status (Todo/In progress/Done) and Agent Lane (Claude/Gemini/Copilot/Cursor/Human) based on issue/PR events and labels.
| Secret | Required | Description |
|---|---|---|
PROJECT_TOKEN |
Yes | PAT with project scope |
Composite Actions¶
gitleaks-scan¶
Secret scanning using Gitleaks. Supports both PR (range-based) and push event scanning.
sbom-scan¶
SBOM generation with Syft, CVE scanning with Grype and Trivy, and policy enforcement against a configurable CVSS threshold. Supports VEX suppression.
license-check¶
License compliance checking for Python (pip-licenses) and Go (go-licenses) ecosystems. Configurable blocklist and package-level exceptions.
docker-setup¶
Docker login to GHCR, buildx setup, and cache metadata computation. Outputs
full-image, cache-from, and cache-to for use with docker/build-push-action.
Versioning and Pinning¶
Consumer repos pin to a tagged version:
uses: lpasquali/rune-ci/.github/workflows/release.yml@v0.1.0
The current version is v0.1.0. Tags are updated in-place during pre-1.0 development. After 1.0, tags will follow strict semver with immutable releases.
All third-party actions within rune-ci are SHA-pinned for supply chain security (SLSA L3 compliance).
Onboarding a New Repository¶
-
Quality gates -- copy
project-sync-caller-template.ymlto.github/workflows/project-sync.ymlin the new repo. -
Create a quality-gates.yml caller that invokes the appropriate shared workflows (python-quality, go-quality, security-scan, etc.) based on the repo's tech stack.
-
Create a release.yml caller that invokes
release.yml(for container repos) orhelm-release.yml(for Helm repos), or usesbuild-container: false(for non-container repos like rune-audit). -
Set secrets at the org or repo level:
PROJECT_TOKEN-- PAT withprojectscope (required for project-sync)-
RUNE_CHARTS_BOT_TOKEN-- PAT for cross-repo dispatch (only ifnotify-charts: true) -
Add the repo to the project board and verify sync works by opening a test issue.
Consumer Repo Examples¶
Container repo with charts notification (rune, rune-ui)¶
# .github/workflows/release.yml
name: Release
on:
push:
tags: ["v*"]
jobs:
release:
uses: lpasquali/rune-ci/.github/workflows/release.yml@v0.1.0
with:
image-name: "rune"
notify-charts: true
secrets:
RUNE_CHARTS_BOT_TOKEN: ${{ secrets.RUNE_CHARTS_BOT_TOKEN }}
Container repo with SBOM and SLSA (rune-docs)¶
# .github/workflows/release.yml
name: Release
on:
push:
tags: ["v*"]
jobs:
release:
uses: lpasquali/rune-ci/.github/workflows/release.yml@v0.1.0
with:
image-name: "rune-docs"
generate-sbom: true
slsa-attestation: true
Non-container repo (rune-audit)¶
# .github/workflows/release.yml
name: Release
on:
push:
tags: ["v*"]
jobs:
release:
uses: lpasquali/rune-ci/.github/workflows/release.yml@v0.1.0
with:
build-container: false
Helm repo (rune-charts)¶
# .github/workflows/release.yml
name: Release Charts
on:
push:
tags: ["v*"]
jobs:
release:
uses: lpasquali/rune-ci/.github/workflows/helm-release.yml@v0.1.0
with:
charts-dir: "charts"
Rollback Procedure¶
This section defines the rollback playbook for failed CI workflow migrations. The target rollback time is under 15 minutes per repository.
Pre-Migration Safety¶
Before migrating any consumer repository to rune-ci shared workflows, tag
the current known-good state so you can return to it:
# In the consumer repo (e.g., rune, rune-operator, rune-ui, etc.)
git tag pre-rune-ci -m "Last known-good CI state before rune-ci migration"
git push origin pre-rune-ci
This tag is your safety net. Every consumer repo must have a pre-rune-ci tag
before migration begins.
Scenario 1: Migrated Workflow Fails in a Consumer Repo¶
If a consumer repo's CI breaks after migrating to rune-ci shared workflows,
revert the migration commit in that repo:
# 1. Identify the migration commit
git log --oneline --all -- '.github/workflows/'
# 2. Revert the migration commit (creates a new commit, preserving history)
git revert <migration-commit-sha> --no-edit
# 3. Push the revert
git push origin <branch>
# 4. Verify CI passes on the reverted state
# (wait for GitHub Actions to complete)
If multiple commits were involved in the migration, revert them in reverse chronological order:
# Revert a range (newest first)
git revert --no-edit <newest-sha>...<oldest-sha>
git push origin <branch>
Scenario 2: rune-ci Itself Is Broken¶
If a bug in rune-ci breaks CI across multiple consumer repos, each consumer
repo can roll back independently without waiting for a rune-ci fix:
# Option A: Revert the migration commit (preferred)
git revert <migration-commit-sha> --no-edit
git push origin <branch>
# Option B: Restore workflows from the pre-migration tag
git checkout pre-rune-ci -- .github/workflows/
git commit -m "ci: restore pre-migration workflows (rune-ci broken)"
git push origin <branch>
Option A is preferred because it creates a clean revert commit. Option B is useful when you need to restore the exact workflow files without identifying individual migration commits.
Scenario 3: Partial Migration Failure¶
If only some workflows fail after migration (e.g., release.yml works but
quality-gates.yml does not):
# Restore only the broken workflow from the pre-migration tag
git checkout pre-rune-ci -- .github/workflows/quality-gates.yml
git commit -m "ci: restore quality-gates.yml from pre-migration state"
git push origin <branch>
Step-by-Step Rollback Commands¶
Complete rollback procedure for a single consumer repository:
# 1. Switch to the repo's default branch
cd ~/Devel/<repo-name>
git checkout main && git pull origin main
# 2. Create a rollback branch
git checkout -b ci/rollback-rune-ci
# 3. Revert the migration commit
git log --oneline -- '.github/workflows/' # find the commit
git revert <migration-commit-sha> --no-edit
# 4. Push and open a PR
git push -u origin ci/rollback-rune-ci
# 5. Wait for CI to pass on the reverted state
# Verify all checks are green before merging
# 6. After merge, confirm the pre-rune-ci tag still exists
git tag -l 'pre-rune-ci'
Post-Rollback Verification¶
After rolling back, verify the following:
- CI passes: All GitHub Actions checks on the default branch are green.
- Workflows are correct: The
.github/workflows/directory matches the expected pre-migration state. - Tags are preserved: The
pre-rune-citag still exists and points to the correct commit. - No orphaned secrets: If the migration added new secrets (e.g.,
PROJECT_TOKEN), they can remain -- unused secrets cause no harm.
# Quick verification script
echo "=== CI Status ==="
gh run list --limit 3 --json status,conclusion,name \
--template '{{range .}}{{.name}}: {{.conclusion}}{{"\n"}}{{end}}'
echo "=== Workflow files ==="
ls -la .github/workflows/
echo "=== Pre-migration tag ==="
git log --oneline -1 pre-rune-ci 2>/dev/null \
|| echo "WARNING: pre-rune-ci tag missing"
Estimated Rollback Time¶
| Step | Time |
|---|---|
| Identify migration commit | 2 min |
| Create rollback branch and revert | 3 min |
| Push and open PR | 2 min |
| Wait for CI to pass | 5-8 min |
| Total | ~15 min |
For emergency situations where CI must be restored immediately, the revert can
be pushed directly to main (bypassing PR review) if branch protection rules
permit it. This should be documented as an incident per ML4 compliance.