Add Swarm to CI
Bring the same attributable quality gate to committed branch changes, before they become shared history.
Before Swarm can scan a branch, your CI job must have the Zedbee package installed and enough Git history to identify that branch’s changes. A normal checkout and dependency install may not provide both. The first two steps show what to check and what to change.
Make Zedbee available to the CI job
The CI job needs the Zedbee package installed before it can run Swarm. Zedbee is normally a development dependency, so a production-only dependency install leaves it out. Checking out your repository does not install it.
Add zedbee as a development dependency locally and commit the package manifest and lockfile. Then make sure the CI job uses Node.js 22.13.0 or newer and installs development dependencies from that lockfile. The scan commands in this guide use --no-install: they use the installed package rather than downloading a missing one.
For npm, npm ci --include=dev explicitly includes Zedbee. If your job already installs development dependencies from the lockfile, keep that install step; you do not need a second one. For pnpm, Yarn, or Bun, use the equivalent frozen-lockfile install with development dependencies included.
Set up and review your repository policy
npm ci --include=devWhen settings updates take effect
Where does the file go? By default, .zedbeerc.jsonc belongs at the root of the Git repository you are scanning, alongside that project’s code. It is not a file inside the installed Zedbee package or a setting stored in your CI service. It controls things such as which checks run and which findings block the change.
For a local scan, stage your settings edits. After saving the file, run git add .zedbeerc.jsonc. Your next ordinary zedbee scan uses that staged version. You do not have to commit it first. If you edit the file again, stage it again for the next scan to use those newer edits. Saving alone does not replace the settings already staged in Git.
For CI, commit and push the settings with your code. Commit .zedbeerc.jsonc on the branch you want CI to check, then push that branch. A CI scan uses the settings saved inside the commit the job checks out. The update takes effect when a CI run checks out a commit containing it. Rerunning a job against an older commit still uses that older commit’s settings.
Commit them on your feature branch along with the code they should apply to.
--base origin/main tells Swarm which branch to compare the code against; it
does not tell Swarm to load the settings from main.
Do not rewrite the file during the CI job to change the scan. The scan reads the committed copy, so an edit made after checkout is ignored. Update the file in your branch, commit it, and run CI against the updated code instead.
Local and CI scans normally share this one settings file. Selecting CI output with --format json or --format sarif does not require changing it. If the selected staged or committed version of the repository has no .zedbeerc.jsonc, Swarm uses its recommended defaults.
| Your change | When it takes effect |
|---|---|
| Save the file | Not yet. Scans still use the previously staged or committed settings. |
| Stage the file | The next local scan uses the staged settings. CI is unchanged. |
| Commit and push | CI uses the update when its job checks out a commit containing it. |
git add .zedbeerc.jsonc
npx --no-install zedbee scanGive Zedbee the Git history it needs
Zedbee needs more than the files in the current checkout. To identify what your branch changed, Swarm needs the branch’s current commit, the base branch you are comparing against, and their shared Git history.
A CI checkout may download only the latest commit. That can be enough to build your project, but not enough for Swarm to work out which changes belong to your branch. This is a shallow checkout: the earlier commits Swarm needs may be missing.
Configure your checkout step to fetch full history, then make the base branch available locally with the command shown here. Fetching the base branch alone does not necessarily fill in missing history on your checked-out branch. If your existing checkout already includes both full history and the intended base ref, no extra fetch is needed.
The examples use origin/main; replace it with your actual base branch. Swarm finds the shared commit where the branches diverged, called the merge base, and scans the changes from there to your checked-out commit (HEAD). This keeps changes made only on the base branch out of your branch’s results.
Swarm does not download missing branches or history. If the base ref or shared
history is unavailable, it cannot complete the comparison and exits with code
2. That is an incomplete scan, not a clean result. Fix the checkout’s
history settings before running the scan in Step 3.
git fetch --no-tags origin \
+refs/heads/main:refs/remotes/origin/main
# Confirm a shared ancestor is available
git merge-base origin/main HEADScan committed changes, not an empty index
An ordinary zedbee scan compares the Git index with HEAD. On a clean checkout, those states match: there are no staged changes to inspect.
Pass --base origin/main explicitly to scan committed changes from the merge base through HEAD.
Both source snapshots come from commits. Staged, unstaged, and untracked working-tree files do not replace the selected target.
Your CI provider may check out a branch tip or a generated merge commit. Swarm scans whichever commit is checked out as HEAD, so choose the checkout target and base branch to match the changes you want to check.
npx --no-install zedbee scan \
--base origin/main \
--format textKeep a complete report
Choose an explicit output format for your pipeline. JSON is Swarm’s versioned machine-readable contract. SARIF 2.1.0 is intended for systems that ingest code-analysis results. Text gives you a complete human-readable export.
These exports include every finding and incomplete-check notification. They are ANSI-free and are not shortened by the terminal preview limit.
Configure your CI provider’s artifact step to retain the selected report even when the scan fails. Creating a SARIF file does not upload it to a code-scanning service; configure that integration separately if needed.
Secret findings are redacted. Ordinary source excerpts follow your reporting policy and explicit source flags. Apply appropriate access controls and retention to exported reports.
npx --no-install zedbee scan --base origin/main --format sarif > zedbee.sarifPreserve the scan’s decision
A report and a successful job are different things. Swarm’s exit status remains the gate, regardless of the output format.
- 0
- Scan completed without blocking findings
- 1
- Scan completed and repository policy blocked the change
- 2
- Required analysis could not complete
The shell example captures the scan status before printing a summary, then returns that same status to CI. Configure artifact retention in a separate provider step that runs on failure as well as success.
Make the scan job a required check in your repository’s merge policy if it should gate merges.
Do not discard the exit status with || true or let a later successful
command replace it. Resolve incomplete analysis before treating the change as
clean.
set -eu
scan_status=0
npx --no-install zedbee scan \
--base origin/main \
--format sarif > zedbee.sarif || scan_status=$?
case "$scan_status" in
0) echo "Scan completed without blockers" ;;
1) echo "Blocked by repository policy" ;;
2) echo "Required analysis was incomplete" ;;
*) echo "Command failed: $scan_status" ;;
esac
exit "$scan_status"Check the inputs before changing policy
No changes reported? Confirm you used --base, that HEAD is the intended commit, and that the base ref points to the intended comparison branch.
Missing history? Inspect whether the checkout is shallow and whether a shared ancestor is available. More than one best merge base is also ambiguous; Swarm requires a unique one.
Settings changes not taking effect? For a local scan, stage the updated .zedbeerc.jsonc. For CI, commit and push it, then ensure the job checks out a commit containing the update. Editing the file during the CI job will not change the scan. See when settings updates take effect.
Vulnerability analysis unavailable? Review the reported diagnostic and CI network access. OSV lookups send package names, exact versions, and the npm ecosystem identifier, not source code or file hashes. There is no offline advisory database; the selected policy controls whether a supported OSV outage blocks or warns.
Need to fix a finding? CI scans are read-only: they do not modify HEAD, refs, the index, or working files, and zedbee fix --base is not supported. Make and review fixes locally, then commit them and rerun CI.
Review the scanner’s security boundaries
git rev-parse HEAD
git rev-parse --is-shallow-repository
git show-ref --verify refs/remotes/origin/main
git merge-base --all origin/main HEAD