This tutorial walks you through setting up CI/CD with Kizuna Actions. The workflow syntax is GitHub Actions-compatible, so existing workflows can migrate with minimal changes.
Prerequisites
- A Kizuna repository with code to build/test
- Basic familiarity with YAML
- A project with a test suite (we'll use Node.js as an example)
Step 1: Create Your First Workflow
Create the Workflow File
Kizuna Actions reads workflow files from .kizuna/workflows/:
mkdir -p .kizuna/workflowsCreate .kizuna/workflows/ci.yml:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Check coverage
run: npm run test:coverageCommit and Push
# With Jujutsu
jj describe -m "Add CI workflow"
jj git push
# With Git
git add .kizuna/workflows/ci.yml
git commit -m "Add CI workflow"
git pushThe pipeline triggers automatically on push.
Step 2: View Pipeline Results
In the Web UI
- Go to your repository > Pipelines tab
- You'll see the running (or completed) pipeline
- Click on it to see:
- Job list — each job and its status
- Step logs — click a step to see its output
- Timing — how long each step took
On Pull Requests
When a PR triggers CI:
- Status checks appear at the bottom of the PR
- Green checkmark = passed, Red X = failed
- Click "Details" to see the full log
Via CLI
# Coming soon
kz pipeline list --repo my-team/my-project
kz pipeline logs --repo my-team/my-project --run 42Step 3: Add a Build Matrix
Test across multiple versions or platforms:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm testThis creates three parallel jobs, one for each Node.js version.
Step 4: Add Secrets
Store sensitive values like API keys securely.
Add a Secret
- Go to Repository Settings > Secrets
- Click New Secret
- Enter:
- Name:
DEPLOY_TOKEN - Value: Your secret value
- Name:
- Click Save
Use Secrets in Workflows
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
curl -X POST https://api.example.com/deploy \
-H "Authorization: Bearer $DEPLOY_TOKEN"Security: Secrets are masked in logs and never exposed in PR builds from forks.
Step 5: Multi-Stage Pipeline
Create a pipeline with build, test, and deploy stages:
name: Build, Test & Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
build:
needs: [lint, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
deploy-staging:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: staging
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- name: Deploy to staging
env:
DEPLOY_TOKEN: ${{ secrets.STAGING_DEPLOY_TOKEN }}
run: |
echo "Deploying to staging..."
# Your deployment script here
deploy-production:
needs: deploy-staging
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- name: Deploy to production
env:
DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}
run: |
echo "Deploying to production..."
# Your deployment script herePipeline Flow
lint ──┐
├──> build ──> deploy-staging ──> deploy-production
test ──┘lintandtestrun in parallelbuildwaits for both to passdeploy-stagingruns only onmainbranchdeploy-productionruns after staging succeeds
Step 6: Add Policy Gates (Optional)
Use Kizuna's policy engine to gate deployments:
deploy-production:
needs: deploy-staging
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Check deployment policy
run: |
kz policy check \
--action "deploy.production" \
--resource "${{ github.repository }}" \
--context '{"branch": "${{ github.ref_name }}", "actor": "${{ github.actor }}"}'
- name: Deploy
run: echo "Deploying..."If the policy check fails (exit code 1), the deployment is blocked.
Step 7: Set Up Self-Hosted Runners (Optional)
For faster builds or specialized hardware:
Register a Runner
- Go to Organization Settings > Runners
- Click New Runner
- Follow the setup instructions for your platform:
# Download runner
curl -O https://kizuna.yourcompany.com/runner/download/linux-amd64
chmod +x kizuna-runner
# Configure
./kizuna-runner configure \
--url https://kizuna.yourcompany.com \
--token RUNNER_REGISTRATION_TOKEN \
--name my-runner \
--labels gpu,linux
# Start
./kizuna-runner startUse in Workflows
jobs:
ml-training:
runs-on: [self-hosted, gpu]
steps:
- uses: actions/checkout@v4
- run: python train.pyStep 8: Require CI in Branch Protection
Make CI mandatory for merges:
- Go to Repository Settings > Branch Protection
- Edit the
mainbranch rule - Under Required Status Checks, add:
CI / lintCI / testCI / build
- Save
Now PRs cannot merge unless all CI checks pass.
Common Workflow Patterns
Docker Build and Push
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and push
run: |
docker build -t kizuna.yourcompany.com/my-team/my-app:${{ github.sha }} .
docker push kizuna.yourcompany.com/my-team/my-app:${{ github.sha }}Scheduled Builds
on:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM UTC
jobs:
nightly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:e2eConditional Steps
steps:
- name: Deploy docs
if: contains(github.event.head_commit.message, '[docs]')
run: npm run deploy:docsTroubleshooting
Pipeline Not Triggering
- Verify the workflow file is in
.kizuna/workflows/(not.github/workflows/) - Check the
on:trigger matches your event (push, pull_request, etc.) - Ensure the YAML syntax is valid
Job Fails with "Runner Not Found"
- For
ubuntu-latest: ensure the Kizuna instance has cloud runners configured - For self-hosted: verify the runner is online in Settings > Runners
Secrets Not Available in PR Builds
For security, secrets are not available in PRs from forks. Use environment-level secrets with protection rules for sensitive deployments.
Next Steps
- Actions Reference — Complete workflow syntax
- Runners Reference — Runner setup and management
- Tutorial: Team Setup — Configure your team workflow
- CI/CD Migration Guide — Migrate from GitHub Actions/GitLab CI