CI integration

  1. GitHub Actions
  2. PR-only mode
  3. Baselines for adoption
  4. GitLab CI
  5. Pre-commit
  6. SARIF output fields

GitHub Actions

The simplest possible integration — one step, SARIF upload to GitHub Code Scanning:

# .github/workflows/flaw.yml
name: flaw
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v4
      - uses: kdairatchi/flaw@v0.1.0
        with:
          args: scan . --fail-on high --format sarif > flaw.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: flaw.sarif

Findings show up in the Security → Code scanning tab, annotated on PR diffs, and — with --fail-on high — block the merge when a new high-severity issue lands.

PR-only mode

For monorepos where a full scan takes minutes, use --since to scan only what the PR touched:

      - uses: actions/checkout@v4
        with:
          fetch-depth: 0                      # needed for --since
      - uses: kdairatchi/flaw@v0.1.0
        with:
          args: >-
            scan .
            --since $
            --since-lines
            --fail-on high
            --format sarif > flaw.sarif

--since-lines further narrows to lines that were actually added or changed in the PR diff — if the rule fires on an unchanged line, it’s suppressed.

Baselines for adoption

Adopting flaw on an existing codebase without wading through a sea of pre-existing findings:

# one-time, on a clean branch
flaw baseline
git add .flaw-baseline.json && git commit -m "chore: flaw baseline"

Then in CI:

      - uses: kdairatchi/flaw@v0.1.0
        with:
          args: scan . --baseline .flaw-baseline.json --fail-on high

New findings fail the build; baselined ones are surfaced in output but don’t gate. As existing bugs get fixed, the baseline shrinks — never the other way around.

GitLab CI

flaw:
  image: crystallang/crystal:1.19
  script:
    - git clone https://github.com/kdairatchi/flaw /tmp/flaw
    - (cd /tmp/flaw && shards build --release --no-debug --production)
    - /tmp/flaw/bin/flaw scan . --fail-on high --format json > flaw.json
  artifacts:
    when: always
    paths: [flaw.json]

Pre-commit

Run flaw on staged files only:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: flaw
        name: flaw
        entry: flaw scan --since HEAD --since-lines --fail-on high
        language: system
        types: [crystal]
        pass_filenames: false

SARIF output fields

Each finding in SARIF maps to:

SARIF field Source
ruleId FLAW001, FLAW023, etc.
level error (high+), warning (medium), note (low/info)
message.text Rule title + the offending snippet
locations[0] File, line, column
partialFingerprints.findingHash/v1 Stable hash for baseline matching

This is accepted by GitHub Code Scanning, GitLab, Sonar, and any other tool that ingests SARIF 2.1.0.