Skip to main content

GitHub Actions

The recommended CI setup runs vyb check on every pull request. Violations block the merge. On passing runs, the Evidence Pack is uploaded as a workflow artifact.

Basic workflow

.github/workflows/vyb-check.yml
name: vybdocs constraint check

on:
pull_request:
branches: [main, develop]
push:
branches: [main]

permissions:
contents: read
pull-requests: write # for PR comment on violation

jobs:
vyb-check:
name: vyb check
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # needed for merge-base diffing

- name: Set up Node 24
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run vybdocs check
run: npx @vybdocs/vyb check --base origin/${{ github.base_ref }} --ci
env:
VYB_EVIDENCE_DIR: .vyb/evidence

- name: Upload Evidence Pack
if: success()
uses: actions/upload-artifact@v4
with:
name: evidence-pack-${{ github.sha }}
path: .vyb/evidence/
retention-days: 90

PR comment on violation

Add a step that posts a formatted comment to the PR when vyb check fails:

- name: Run vybdocs check (with JSON output)
id: vyb
run: |
npx @vybdocs/vyb check \
--base origin/${{ github.base_ref }} \
--ci \
--output-format json \
--output vyb-results.json || echo "VYB_FAILED=true" >> $GITHUB_ENV

- name: Comment violations on PR
if: env.VYB_FAILED == 'true' && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('vyb-results.json', 'utf8'));
const violations = results.violations;

const lines = violations.map(v =>
`**[${v.severity.toUpperCase()}]** \`${v.ruleId}\` — ${v.file}:${v.line}\n> ${v.message}`
).join('\n\n');

const body = `## vybdocs constraint violations\n\n${lines}\n\n_Fix these violations to unblock the merge._`;

github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body
});

SARIF output for Code Scanning

For GitHub Code Scanning integration (inline annotations on the diff):

- name: Run vybdocs check (SARIF)
run: |
npx @vybdocs/vyb check \
--base origin/${{ github.base_ref }} \
--output-format sarif \
--output vyb-results.sarif || true

- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: vyb-results.sarif
category: vybdocs

Evidence Pack archiving to S3

For long-term compliance storage, archive Evidence Packs to S3 on every main branch merge:

archive-evidence:
name: Archive Evidence Pack
runs-on: ubuntu-latest
needs: vyb-check
if: github.ref == 'refs/heads/main' && success()

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'

- run: npm ci

- name: Run check and generate evidence
run: npx @vybdocs/vyb check --base HEAD~1 --ci
env:
VYB_EVIDENCE_DIR: .vyb/evidence

- name: Upload to S3
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

- run: |
aws s3 cp .vyb/evidence/ \
s3://${{ vars.EVIDENCE_BUCKET }}/evidence/${{ github.repository }}/${{ github.sha }}/ \
--recursive

Branch protection rules

After adding the workflow, configure branch protection in your repository settings:

  1. Go to Settings → Branches → Add rule
  2. Branch name pattern: main
  3. Enable Require status checks to pass before merging
  4. Add vyb check to required checks
  5. Enable Require branches to be up to date before merging

This makes vyb check a hard requirement for all PRs — no exceptions, regardless of reviewer approvals.

Caching for faster runs

Cache the vyb binary to avoid repeated npm installs:

- name: Cache vyb
uses: actions/cache@v4
with:
path: ~/.npm/_npx
key: vyb-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

- name: Run check
run: npx @vybdocs/vyb check --ci

Complete production workflow

.github/workflows/vyb-check.yml
name: vybdocs constraint check

on:
pull_request:
branches: [main, develop, 'release/**']
push:
branches: [main]

permissions:
contents: read
pull-requests: write
security-events: write # for SARIF upload

concurrency:
group: vyb-${{ github.ref }}
cancel-in-progress: true

jobs:
vyb-check:
name: vyb check
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'

- run: npm ci

- name: Run vybdocs check
id: vyb
run: |
npx @vybdocs/vyb check \
--base origin/${{ github.base_ref || 'main' }} \
--ci \
--output-format sarif \
--output vyb-results.sarif
continue-on-error: true

- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: vyb-results.sarif
category: vybdocs

- name: Upload Evidence Pack
if: steps.vyb.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: evidence-pack-${{ github.sha }}
path: .vyb/evidence/
retention-days: 365

- name: Fail on violations
if: steps.vyb.outcome == 'failure'
run: exit 1

Next: Pre-commit Hooks