GitHub Action
Run the FlagShark scanner inside GitHub Actions, post a PR comment, and optionally fail the build below a health threshold.
FlagShark/flagshark is the official FlagShark GitHub Action. It runs the same detection engine as the CLI, posts a sticky comment on every pull request, and writes a job summary to the Actions UI. You can optionally fail the workflow when your flag health score drops below a threshold you set.
No FlagShark account required. The Action is open-source (MIT) and lives at FlagShark/flagshark.
Quickstart
Drop this into .github/workflows/flagshark.yml:
name: FlagShark
on: [pull_request]
permissions:
contents: read
pull-requests: write
jobs:
flagshark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required: git blame (flag age) and the changed-file diff need full history
- uses: FlagShark/flagshark@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
On the next PR, FlagShark scans the changed files, posts a comment, and writes a job summary.
pull-requests: write is needed so the Action can post (and update) its PR comment; contents: read lets it read the diff. If you set output-format: none, you can drop pull-requests: write.
@v2 tracks the latest v2.x (staleness threshold in days, the current behavior shown here). You can pin more strictly to a full version tag or a commit SHA for supply-chain control.
@v1 is the legacy line where threshold is measured in months (default 6). If you're still on @v1, the threshold value means months, not days; upgrade to @v2 for the day-based behavior documented here.
fetch-depth: 0 is required. The default actions/checkout@v4 performs a shallow clone, which breaks git blame (used to determine flag age) and prevents the changed-file diff from resolving against the base branch.
Inputs
All inputs are optional.
| Input | Default | Description |
|---|---|---|
scan | changed | changed — only files modified in the PR (fast). full — entire repository (full health score). |
threshold | 30 | Staleness threshold in days. Flags older than this are marked stale. |
fail-threshold | 0 | Fail the workflow if the health score drops below this value. 0 = never fail. |
output-format | markdown | PR comment format: markdown (default) or none to disable the comment entirely. |
sarif | — | Write SARIF v2.1.0 output to this path. Omit to skip SARIF output. |
no-cache | false | Skip the platform-flag cache and force a re-fetch from the connected flag platform. |
fail-on-error | true | Fail the build when any missing-in-platform flag is detected. |
missing-in-platform, archived-in-platform), and therefore fail-on-error and the error-count output, only apply when you've connected a flag platform via the platforms: block in .flagshark.yml. Without one, no platform signals are produced and fail-on-error has no effect.
Pass inputs via with::
- uses: FlagShark/flagshark@v2
with:
scan: full # scan the whole repo, not just PR files
threshold: 7 # stricter staleness window
fail-threshold: 80 # block the PR below 80/100 health
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Outputs
The Action sets the following outputs you can chain into later steps.
| Output | Description |
|---|---|
health-score | Flag health score (0–100) |
stale-count | Number of unique stale flag names found |
total-count | Total number of flags detected |
sarif-path | Absolute path to the SARIF file written (only set when sarif: input is provided) |
error-count | Number of unique flag names with error-severity signals (e.g. missing-in-platform) |
Reference outputs in a later step by giving the Action an id: and using steps.<id>.outputs.<name>:
jobs:
flagshark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: FlagShark/flagshark@v2
id: flagshark
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Enforce health gate
run: |
echo "Health score: ${{ steps.flagshark.outputs.health-score }}"
echo "Stale flags: ${{ steps.flagshark.outputs.stale-count }}"
echo "Flags with errors: ${{ steps.flagshark.outputs.error-count }}"
What the Action produces
Each run produces up to four artifacts:
- Sticky PR comment: Posted on
pull_requestevents when at least one flag is found andoutput-formatismarkdown. If a comment from a previous push already exists (identified by a hidden HTML marker), the Action updates it in place rather than stacking new ones. - Actions job summary: Written on every run. Headed "🦈 FlagShark Scan Results", it includes the health score, a metrics table, detected providers, and the top 15 stale flags. Visible under the Summary tab on the workflow run page, useful for scheduled scans and pushes to
mainwhere there is no PR comment. - Status check:
core.setFailed()is called whenfail-thresholdis exceeded orfail-on-errortriggers amissing-in-platformerror, failing the workflow step and any required branch-protection check wired to it. - SARIF file: Written to the path specified by the
sarif:input (optional). Thesarif-pathoutput contains the resolved absolute path.
Gating the merge
Set fail-threshold to block PRs whose health score falls below a target. Once the workflow has run on the default branch at least once, GitHub recognizes the check name and you can mark it required under Settings → Branches → Branch protection rules.
- uses: FlagShark/flagshark@v2
with:
fail-threshold: 80 # Block merges when health score drops below 80
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
With the default fail-threshold: 0, the Action only reports; it never fails the workflow even if your code is full of stale flags.
SARIF → GitHub Code Scanning
Set the sarif: input to emit a SARIF file, then upload it with github/codeql-action/upload-sarif@v3. Stale flags then appear in the repo's Security → Code Scanning tab alongside other static-analysis findings.
jobs:
flagshark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: FlagShark/flagshark@v2
id: flagshark
with:
sarif: flagshark.sarif
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.flagshark.outputs.sarif-path }}
For the full GitHub integration setup, see GitHub Integration.
Runtime details
The Action runs on Node 20.
Related Documentation
- FlagShark CLI: The same scanner, run locally or in any CI
- Configuration:
.flagshark.ymlfor custom providers and exclusions - Library (@flagshark/core): use the detection engine directly in your own tooling