mode |
no |
compare |
Operation mode. The Action exposes four analysis modes, mirroring abicheck's core per-library CLI commands (compare/dump/deps tree/deps compare; the CLI additionally has project-orchestration commands like aggregate and project plan that this Action does not expose as separate modes): "compare" (default) compares two ABI surfaces — old-library/new-library may be single binaries/snapshots OR directories/packages, in which case abicheck fans out to a per-library comparison automatically (no separate mode); omitting old-library (and abi-baseline) runs an audit-only compare --no-baseline against new-library alone, reporting no old/new compatibility verdict — see the migration section of docs/use/github-action.md for converting a mode: scan job (retired) to this shape, including the severity-preset requirement to keep it gating a CI job the way mode: scan's own audit mode did; "dump" generates a JSON baseline snapshot from a single library (now also embeds optional L3/L4/L5 build-source evidence via source/build inputs); "deps-tree" resolves transitive dependencies and symbol bindings for one binary (Linux ELF); "deps-compare" compares a binary's full dependency stack across two sysroots (Linux ELF). mode: scan itself is retired outright (hard removal, no deprecation window) — setting it fails the step with an error naming the replacement for your shape. |
old-library |
no |
— |
Path to the old library or JSON snapshot. Required for a two-sided compare; omit it (and abi-baseline) to run an audit-only compare --no-baseline against new-library alone instead (the replacement for a baseline-less mode: scan/audit: true request — see the mode input's own description). May also be a directory or package (RPM, Deb, tar, conda, wheel) — abicheck then fans out to a per-library comparison automatically. May also be a stored BundleFacts document written by an earlier run's --bundle-facts-out (plain .json, a compressed .json.gz/.json.zst, or the content-addressed archive form): no separate input or flag selects that shape, since compare classifies the operand from the file's own content, so pointing this input at such a document is all a stored-OLD-side bundle comparison needs. A real large-toolkit document may exceed the conservative pre-json.loads() decode-node ceiling; raise it with resource_limits.max_bundle_facts_decode_nodes in a .abicheck.yml passed as build-config (an explicit, operator-reviewed config — an auto-discovered one may only lower that budget, never raise it, since it can come from the same untrusted checkout being decoded). Producing such a document is --bundle-facts-out, which stays an extra-args option rather than a first-class input: it names one pipeline stage's output artifact path, and a dedicated input would add a second spelling for something extra-args already forwards and validates. |
new-library |
no |
— |
Path to the new (current) library, binary, or JSON snapshot. Required for compare (both the two-sided and audit-only shapes), dump (unless a source-only sources/build-info/compile-db input is given), and deps-tree/deps-compare modes. May be a directory or package (RPM, Deb, tar, conda, wheel) ONLY in a two-sided compare, matching old-library — compare then fans out to a per-library comparison automatically. dump, and compare's own audit-only shape, each analyse exactly one artifact and reject a directory/package with an error (neither has a per-library fan-out); for a multi-library release, dump each library individually or use a two-sided compare instead. |
new-library-set |
no |
— |
RETIRED (hard removal, no deprecation window). It mapped to the now fully-removed scan --artifact-set/mode: scan. Still declared so a workflow that sets it gets an explicit ::error:: instead of a silently-ignored input; remove it and compare each library individually. For a multi-library release comparison against an old side, use mode: compare with a directory/package operand instead. |
debug-info1 |
no |
— |
Debug info package for old side (RPM/Deb/tar). compare mode, directory/package operands only. |
debug-info2 |
no |
— |
Debug info package for new side (RPM/Deb/tar). compare mode, directory/package operands only. |
devel-pkg1 |
no |
— |
Development package with headers for old side. compare mode, directory/package operands only. |
devel-pkg2 |
no |
— |
Development package with headers for new side. compare mode, directory/package operands only. |
dso-only |
no |
— |
Only compare shared objects, skip executables. compare mode, directory/package operands only. Deliberately no declared default (Codex review, fresh evidence): the synthesized release:/gate: config overlay needs to tell "omitted" apart from an explicit "false" (which must override a discovered/explicit .abicheck.yml's own release.dso_only: true) -- a declared default would make every omitted invocation indistinguishable from an explicit false, silently losing that override. |
include-private-dso |
no |
— |
Include private (non-public) shared objects from non-standard paths. compare mode, directory/package operands only. Deliberately no declared default -- see dso-only's own description for why. |
fail-on-removed-library |
no |
— |
Exit 8 when a library present in old is proven removed in new -- NEW must have a proven-complete declared inventory: either a stored ProjectSnapshot package whose capture asserted inventory_complete, or a package archive (e.g. .rpm/.deb) whose own readable member table this run extracted and could enumerate in full; a live directory, or an archive whose member table could not be read in full, is an unproven inventory and an unmatched library there is an incomplete scope instead, governed by the scope.on_incomplete key in .abicheck.yml. compare mode, directory/package operands only. Deliberately no declared default -- see dso-only's own description for why. |
header |
no |
— |
Public header file(s) applied to both sides (space-separated). Required when input is an ELF binary; ignored for JSON snapshots. If old and new actually declare different header sets (e.g. a new release added a header), set old-header/new-header instead -- a bare header parses BOTH snapshots against the same files, which silently hides the removed/added declarations you're trying to check. |
old-header |
no |
— |
Public header(s) for the old side only (overrides header for old). Space-separated. |
new-header |
no |
— |
Public header(s) for the new side only (overrides header for new). Space-separated. |
public-header-dir |
no |
— |
Directory whose headers are treated as public for provenance classification (repeatable, space-separated) — establishes the public/internal boundary so leakage/RTTI/exported-vs-public cross-checks run instead of skipping. dump mode forwards it as one more -H/--header root, which is where dump reads declaration provenance from AND extracts headers from (a directory entry tags everything under it public and expands to every header inside). compare's audit-only shape (old-library/abi-baseline both omitted) forwards it the same way, as a bare -H root applying to the one audited artifact — a two-sided compare has no equivalent flag. |
build-target |
no |
— |
RETIRED (hard removal, no deprecation window). scan --build-target was retired first; dump --build-target, which this input mapped to, was retired next, once that removal resolved the routing hazard that had deferred it — neither command has this flag any more. Still declared so a workflow that sets it gets an explicit ::error:: naming the replacement instead of a silently-ignored input: put the root target(s) in .abicheck.yml's build.targets (Bazel only so far, e.g. targets: ["//:math"]) and pass the config with mode: dump's build-config: input, or let it auto-discover from sources:. compare has no equivalent. |
include |
no |
— |
Extra include directories for header AST parsing (castxml or clang). Space-separated. Set this (or old-include/new-include for a side-specific root) whenever a header passed via header itself #includes a dependency's header from a separate include root (e.g. PVXS's own version.h pulling in EPICS Base's epicsVersion.h, found in a real PVXS Action acceptance run) -- header/public-header-dir alone never cover a dependency's own headers. On ELF the parse then aborts on the first such include with a "file not found" error; on Mach-O/PE it can instead warn and fall back to export-table scoping (--header/--include are silently ignored for that dump), which is quieter but leaves header-based coverage incomplete rather than failing loud. In a two-sided compare, old-include/new-include replace this list for their side rather than adding to it (repeat any shared directory there too); in dump and compare's audit-only shape, a side-specific include is added alongside this list instead. (sources/build-info can sometimes auto-derive a build's own include dirs for this instead of a manual -I, when neither side has any explicit include input of its own.) |
old-include |
no |
— |
Include directories for old side only. Space-separated. Used by a two-sided compare; not applicable to compare's audit-only shape, which has no old side. Replaces include for this side rather than adding to it (repeat any directory include also lists that's still needed). |
new-include |
no |
— |
Include directories for new side only. Space-separated. In a two-sided compare, replaces include for this side rather than adding to it (repeat any directory include also lists that the new side still needs); in dump and compare's audit-only shape, it is added alongside include instead. |
old-version |
no |
old |
Version label for the old library (embedded in reports). |
new-version |
no |
new |
Version label for the new library (embedded in reports). |
lang |
no |
c++ |
Language mode for header AST parsing: "c++" or "c". |
ast-frontend |
no |
— |
L2 header-AST frontend for native-binary inputs: "auto" (resolves to castxml and never changes producer unless the CLI's --allow-ast-frontend-fallback flag is also passed via extra-args (or ABICHECK_ALLOW_AST_FALLBACK=1 is set) — with that opt-in, a recognized castxml toolchain-version mismatch, an unsupported castxml release, or a direct-include-guard failure falls back to clang, G16; without it, and on any host with no castxml at all, auto does not silently switch to clang — the command fails asking you to install castxml or pass ast-frontend: clang explicitly. One exception: a non-host --frontend-context (SYCL/DPC++, passed via extra-args) routes an auto that resolves to plain castxml (no pin) straight to clang with no opt-in needed, since castxml can't satisfy it at all — but any way of pinning the resolved backend away from plain castxml-or-clang still rejects it: an explicit ast-frontend: castxml, auto pinned to castxml via ABICHECK_AST_FRONTEND=castxml, and hybrid (explicit or auto pinned via ABICHECK_AST_FRONTEND=hybrid — hybrid has no device concept either) all reject a non-host context. Explicit ast-frontend: clang satisfies it directly, and so does auto pinned to clang via ABICHECK_AST_FRONTEND=clang), "castxml" (default), "clang" (clang -ast-dump=json; explicit opt-in for clang-only hosts), or "hybrid" (runs both and merges them; needs both tools installed on the runner, never auto-selected). Applies to dump and compare mode, on single-pair and directory/package (release) operands alike — the per-library release fan-out threads this both-sides L2 context to every pair's header dump (cli_resolve.resolve_directory_compile_context), so it is forwarded, not rejected, for a directory/package operand. (Only a sided old=/new= frontend override has no per-library-pair meaning across a release; this input has no sided spelling.) Same as the ABICHECK_AST_FRONTEND env var. |
gcc-path |
no |
— |
Path to GCC/G++ (or clang) cross-compiler binary. Like dump and single-pair compare (including the audit-only shape), it folds into a synthesized .abicheck.yml compile: block forwarded via --config (together with gcc-prefix, gcc-options, sysroot, and nostdinc, when any of those are also set). Applies to dump and compare mode, on single-pair and directory/package (release) operands alike (same scope as ast-frontend above). Combining any of this group with build-config is supported: the synthesized compile: block is merged into a copy of the named build-config, and this Action's input wins on a key conflict. |
gcc-prefix |
no |
— |
Cross-toolchain prefix, e.g. aarch64-linux-gnu-. Folds into the same synthesized compile: block gcc-path describes above, on every mode that accepts it (a full gcc-path wins if both are set, since the merged compile.compiler config key can only hold one). Applies to dump and compare mode, on single-pair and directory/package (release) operands alike (same scope as ast-frontend above). |
gcc-options |
no |
— |
Extra compiler flags passed through to the header frontend. Folds into a synthesized compile.options list in the same synthesized compile: block gcc-path describes above, on every mode that accepts it. A single-line value is shell-quoting-aware split on whitespace into separate flags (a quoted segment such as -DMSG="hello world" stays one flag, but that one flag still contains a space internally); a multi-line (YAML block scalar) value treats each line as one already-complete flag, not split further. Either way, each resulting compile.options entry must be a single whitespace-free flag -- a flag containing a space (whether from a quoted single-line segment or a spaced multi-line entry) is rejected with a clear error rather than silently accepted or silently split further; put each word needing its own flag on its own line instead. This is a real, accepted narrowing from an earlier Action version, where the CLI's own now-removed --compiler-option flag once forwarded such a flag verbatim (a raw CLI arg is not subject to compile.options' own whitespace-free-atom contract). Applies to dump and compare mode, on single-pair and directory/package (release) operands alike (same scope as ast-frontend above). |
sysroot |
no |
— |
Alternative system root directory for cross-compilation. On dump and single-pair compare (including the audit-only shape) this folds into the same synthesized compile: block gcc-path describes above (deps-tree keeps its own direct --sysroot CLI forwarding, unaffected -- it is not part of this compile-context group at all). Applies to dump, deps-tree, and compare mode, the latter on single-pair and directory/package (release) operands alike (same scope as ast-frontend above). |
nostdinc |
no |
false |
Do not search standard system include paths. On dump and single-pair compare this folds into the same synthesized compile: block gcc-path describes above. Applies to dump and compare mode, on single-pair and directory/package (release) operands alike (same scope as ast-frontend above). |
follow-deps |
no |
false |
Include transitive dependency graph and symbol binding info in dump or compare output. ELF only. Applies to dump and compare modes. For compare, requires a baseline (old-library or abi-baseline) -- rejected outright for the audit-only shape (compare --no-baseline's own DT_NEEDED dependency walk is not wired to that path yet). |
old-root |
no |
— |
Sysroot for the old (baseline) environment. Required for mode=deps-compare. |
new-root |
no |
— |
Sysroot for the new (candidate) environment. Required for mode=deps-compare. |
search-path |
no |
— |
Additional directories to search for shared libraries (space-separated). Used by deps-tree, deps-compare, and follow-deps. |
ld-library-path |
no |
— |
Simulated LD_LIBRARY_PATH (colon-separated). Used by deps-tree, deps-compare, and follow-deps. |
used-by |
no |
— |
Application binary/binaries whose actual imports/required symbol versions scope the comparison (space-separated; maps to repeated compare --used-by). The full library comparison always determines this run's own verdict/exit code; the supplied application's own confirmed/potential/unresolved impact is reported alongside it (informational), never in place of it. Mutually exclusive with required-symbol/required-symbols (the CLI rejects both being set). Requires a baseline (old-library or abi-baseline) -- rejected outright for the audit-only shape (consumer scoping needs two versions to compare, and an audit has none). compare mode only. |
used-by-manifest |
no |
— |
Path(s) to a JSON document naming one or more consumer binaries (space-separated; maps to repeated compare --used-by-manifest), each with optional digest/platform/profile/provider_baseline provenance and a requirement ("required", the default -- an unreadable consumer aborts the run, same as used-by -- or "advisory" -- an unreadable consumer is skipped and reported instead). Merged into the same scoping pipeline as used-by; every listed consumer counts toward the reported "N of M consumers affected" summary (consumer_impact_summary in a json export). Mutually exclusive with required-symbol/required-symbols. compare mode only. Requires a baseline (old-library or abi-baseline) -- rejected outright for the audit-only shape, same reason as used-by above. |
required-symbol |
no |
— |
An exported linker symbol a plugin host resolves via dlopen/dlsym and requires (space-separated; maps to repeated compare --required-symbol). The full library comparison always determines this run's own verdict/exit code; this contract's own confirmed/ potential/unresolved impact is reported alongside it (informational), never in place of it. Mutually exclusive with used-by. compare mode only. Requires a baseline (old-library or abi-baseline) -- rejected outright for the audit-only shape, same reason as used-by above. |
required-symbols |
no |
— |
Path to a file of required symbols, one per line (blank lines and '#' comments ignored) -- combined with any required-symbol values. compare mode only. Requires a baseline (old-library or abi-baseline) -- rejected outright for the audit-only shape, same reason as used-by above. |
against |
no |
— |
RETIRED (hard removal). This applied only to the now-removed mode: scan, as the baseline artifact to compare the scanned new-library against. Set old-library (or abi-baseline) to the same value under mode: compare instead. Still declared so a workflow that sets it gets an explicit ::error:: naming that replacement instead of a silently-ignored input. |
sources |
no |
— |
Source checkout / tree for source-intelligence analysis. The compile database is auto-discovered within it. Drives L4 source-ABI replay and L5 source-graph collection. Used by dump mode, and by compare mode for the new (candidate) side only — mapped to compare's --sources new=... (the old side's evidence, if any, is expected to already be embedded in whatever old-library snapshot was resolved; not applicable to compare's audit-only shape, which has no old side). |
build-info |
no |
— |
Out-of-tree L3 build context: a build directory, a compile_commands.json, or a previously-collected evidence pack. Use when the build tree lives outside --sources. Used by dump mode, and by compare mode for the new (candidate) side only — mapped to compare's --build-info new=... (same old-side caveat as sources above). |
compile-db |
no |
— |
Explicit path to a compile_commands.json, when it is not under sources. Folded into --build-info for every mode that accepts it (dump, and compare mode's new side) — --build-info already accepts a build dir, a compile_commands.json, or a pre-captured pack, so it is the one flag that takes this operand. |
build-config |
no |
— |
Path to a trusted .abicheck.yml. For dump mode, supplying this alone is enough — an explicit --config is itself the operator's consent to run its build.query. Used by dump mode, and by compare mode (--config). Also the only way to configure the cross-library bundle-analysis layer's system-provider allow-list extension and co-versioned cohort declarations: .abicheck.yml's bundle: block (system_providers:/cohorts:, CLI cleanup phase two, PR J — there is no longer a per-invocation Action input for either, matching the native CLI's own removal of --bundle-system-providers/ --bundle-cohort). system_providers: applies to compare mode (directory/package operands); cohorts: (the SONAME-skew check) applies to compare only. |
jobs |
no |
— |
Removed and ignored. This input used to forward -j/--jobs to compare, capping the directory/package release fan-out's worker count. Both the flag and the input are gone: the release engine auto-detects the CPU count and clamps it to available memory, and there is no manual override any more. Kept registered as a tombstone — deleting the input outright made GitHub drop it before the Action ever ran, so a pinned workflow that still sets it got no error and no annotation, and its worker cap silently stopped applying. Setting it now emits an explicit warning telling you it has no effect. Remove it from your workflow. |
bundle-system-providers |
no |
— |
RETIRED (CLI cleanup phase two, PR J — hard removal). The cross-library bundle-analysis layer's system-provider allow-list extension was removed here and moved to .abicheck.yml's bundle.system_providers: block, reachable through the build-config input. Kept registered as a tombstone for the same reason as jobs above — an undeclared input is dropped silently, which here would drop a real analysis setting. Setting it is a hard error: move the list into .abicheck.yml and point build-config at it. (Marked RETIRED, like every other hard-error tombstone here, so tests/test_action_retired_inputs_contract.py holds it to the same executable fail-closed guarantee; jobs above is the softer warn-only class and deliberately keeps its own wording.) |
allow-build-query |
no |
false |
Deprecated and ignored. The --allow-build-query dump flag it used to forward was already a no-op and has since been removed outright (CLI cleanup H1); this input is kept registered only so an existing workflow that still sets it doesn't get an unknown-input warning. abicheck always runs its own inferred, abicheck-authored cmake/bazel/make compile-DB query whenever a sources input needs build context: pointing abicheck at a source tree is itself the request to analyse it. A trusted, operator-supplied build.query (build-config) needs no opt-in either — see build-config above. |
depth |
no |
— |
Evidence-depth selector: binary, headers, build, or source. Used by dump mode, and by compare mode (--depth) -- both the two-sided and audit-only shapes. Omitting it means 'headers' -- set it to build or source explicitly to collect those (there is no risk-driven auto escalation). --depth source analyses the whole current library target unless since/changed-path seeds a narrower changed scope. Maps to --depth. For a compare directory/package (release) operand, every rung is forwarded per member exactly as for a single pair. build and source are reachable there without any inline evidence input when the members are pre-dumped snapshots that already carry it (dump --sources/--build-info); what a release operand does not support is the inline sources/build-info/compile-db inputs themselves, which are rejected with an error before the run since the per-library fan-out never collects them. Note what pinning a rung does and does not guarantee: a shortfall is reported (the exit-7 evidence-contract axis) only for a pinned build/source rung on a side this run extracts live. A member that is already a serialized snapshot was never extracted by this run, so no shortfall is reported for it -- a successful run is therefore not by itself proof that every member carried the requested evidence. |
since |
no |
— |
compare mode (single-pair operands, two-sided only). Focus the run's source-evidence scope on files changed vs a ref (e.g. origin/main). Maps to compare --since. Not forwarded for a compare directory/package operand (the per-library release fan-out collects no build/source evidence for either side to scope). Rejected outright (step fails before any dependency install) for compare's audit-only shape (old-library and abi-baseline both omitted): compare --no-baseline does not implement revision-range evidence scoping -- set old-library (or abi-baseline) to use since. |
changed-path |
no |
— |
compare mode (single-pair operands, two-sided only). Changed path(s) to focus the run's source-evidence scope on (space-separated; alternative to since). Maps to repeated compare --changed-path. Not forwarded for a compare directory/package operand, same as since above. Rejected outright for compare's audit-only shape, same as since above and for the same reason. |
budget |
no |
— |
compare mode, two-sided shape only. Time guard (e.g. 15m, 900s, 1h). The step FAILS on overflow (exit 5) — a budget never silently shrinks scope. Maps to compare --budget. Rejected outright (step fails before any dependency install) for compare's audit-only shape (old-library and abi-baseline both omitted): compare --no-baseline does not wire the wall-clock guard to that path yet -- set old-library (or abi-baseline) to use budget. |
dry-run |
no |
false |
Resolve inputs/config and print what the run would do, without performing any analysis or writing output. Exits 0 for a resolvable preview; an invocation the real run would itself reject (an invalid flag combination) still exits with that same usage error, and a requested-but-unsatisfiable depth/evidence contract still exits nonzero — a dry run validates what it can see, it does not turn every outcome into success. The one deliberate exception is this composite Action's own baseline resolution: an unresolved abi-baseline is tolerated under dry-run rather than hard-failing, since the point of a preview is to report what would be compared, not to require the comparison already be resolvable. Maps to --dry-run; supported by every mode (compare -- both the two-sided and audit-only shapes -- dump, deps-tree, deps-compare). To preview an audit-only single-build hygiene lint instead of a two-sided compare, simply omit old-library and abi-baseline for that step. |
estimate |
no |
false |
RETIRED. This applied only to the now-removed mode: scan, as a dry-run alias. Use dry-run: 'true' instead, which applies to every mode. Still declared so a workflow that sets it gets an explicit ::error:: naming that replacement instead of a silently-ignored input. |
audit |
no |
false |
RETIRED. This applied only to the now-removed mode: scan, forcing a one-build audit-only run. Under mode: compare, simply omit old-library and abi-baseline to run an audit-only compare --no-baseline instead; set severity-preset (e.g. 'default') if this job should still gate on a BREAKING/API_BREAK-classified finding the way mode: scan's own audit mode always did. Still declared so a workflow that sets it gets an explicit ::error:: naming that replacement instead of a silently-ignored input. |
crosscheck |
no |
— |
RETIRED (superseded, not a hard removal with nothing to replace it). scan --crosscheck's KEY=LEVEL promotion syntax, which this input mapped to, no longer exists (along with mode: scan itself): every cross-source check it used to gate already reaches compare as an ordinary ChangeKind, so policy / .abicheck.yml's policy.overrides.<CHANGE_KIND>: error already lets you control any one check's severity — only the KEY=LEVEL syntax itself doesn't survive. Still declared so a workflow that sets it gets an explicit ::error:: naming that replacement instead of a silently-ignored input. |
risk-rules |
no |
— |
RETIRED (hard removal). scan --risk-rules is gone, together with mode: scan itself and the risk-driven auto depth escalation it fed: an omitted depth now resolves to the fixed headers rung — the same default compare has always used — instead of being scored from the changed paths. Set depth: source (or build) explicitly to pin the level a risk profile used to escalate to. Still declared so a workflow that sets it gets an explicit ::error:: saying so. |
abi-baseline |
no |
— |
Automatically fetch an ABI baseline snapshot for compare mode, used as old-library. Values: "latest-release" fetches *.abicheck.json from the latest GitHub Release; a tag name (e.g. "v2.0.0") fetches from that release; a file path uses the file directly. Requires GITHUB_TOKEN with contents:read permission. Overrides old-library when set. When the resolved release has no single *.abicheck.json[.gz\|.zst] asset, set baseline-profile and baseline-target to instead fetch a release-contract baseline-set archive (abicheck-baseline-<profile>.tar.zst, published by publish-baseline.yml -- see docs/reference/publish-baseline.md); the single-snapshot search always takes priority when both exist. |
baseline-profile |
no |
— |
Selects which contract profile's baseline-set to fetch when abi-baseline resolves to a release-contract baseline-set archive (docs/reference/publish-baseline.md) rather than a single *.abicheck.json asset. Requires baseline-target to also be set. Omit when the release publishes a single-snapshot asset (abi-baseline's original, unchanged contract) -- this input is only consulted as a fallback when that search finds nothing. |
baseline-target |
no |
— |
The target/library id (the baseline-set manifest.json's "library" field, matching the name passed to actions/baseline's libraries input when the baseline-set was published) to resolve from the baseline-set archive selected by baseline-profile. Required when baseline-profile is set. |
baseline-asset-name-template |
no |
abicheck-baseline-{profile}.tar.zst |
Release asset filename template for the baseline-set archive fetched via baseline-profile; "{profile}" is replaced with baseline-profile's value, and "{generation}" (optional) with baseline-generation's value. Must match the asset-name-template the publishing workflow (publish-baseline.yml, or a custom equivalent) used. |
baseline-generation |
no |
— |
Substituted for "{generation}" in baseline-asset-name-template -- set this when the publishing workflow's asset-name-template includes "{generation}" (e.g. it published a baseline scoped to a scanner-compatibility generation -- see baseline-management.md's "Scanner upgrades and baseline generations" section). Omit when baseline-asset-name-template doesn't reference "{generation}" at all -- the default template never does, so this input is a no-op unless you opt in by including the placeholder. |
format |
no |
— |
Output format: json, markdown, sarif, html, junit, review, or oneline (each mode's default when this input is left unset). compare, two-sided shape, single-pair (non-directory, non-package) operand: all seven. compare, two-sided shape, directory/package operand: json, markdown, junit, oneline, or html (a release page rendered from the release JSON) — sarif/review are rejected with an error (the per-library release fan-out has no single report those formats describe). compare against a stored BundleFacts baseline (old-library naming such a document, new-library a directory/package): json or markdown only — that driver renders no junit either. This one narrowing is NOT pre-checked before the dependency install, unlike every other row here: deciding it needs the document's own content (see the old-library input), and neither re-implementing that classifier in shell nor reading an untrusted document at preflight is acceptable, so -o junit=... on this shape fails in the CLI instead. Tracked in docs/contribute/known-gaps.md. compare, audit-only shape (old-library/abi-baseline both omitted): json, markdown, sarif, junit, or oneline — html and review are two-sided-report renderers with no audit-only equivalent and are rejected with an error. html is also supported by deps-tree/deps-compare (a dependency-stack report); sarif/junit/review/oneline are not. dump ignores this input; it always writes a JSON snapshot. Requesting an unsupported format for the mode/shape is a hard error raised before any dependency install (it used to silently fall back to a supported format with only a warning, which is unsafe for CI — see upload-sarif). Deliberately has no Action-level default (unlike most inputs): GitHub Actions has no way to tell "left unset" from "explicitly set to the default" apart once a default is declared — each mode branch in action/run.sh supplies its own correct default instead. |
output-file |
no |
— |
Path to write the report file. If not set, output goes to stdout and job summary. |
snapshot-compression |
no |
— |
dump mode only. Storage envelope for the written snapshot: 'auto' (default) infers gzip/zstd/plain from output-file's canonical suffix (.abicheck.json.gz/.abicheck.json.zst/plain .abicheck.json); an explicit 'none', 'gzip', or 'zstd' is used as-is and is a hard error if it contradicts output-file's suffix, mirroring the CLI's own --compression flag it maps to directly. Ignored by every other mode -- compare/deps-tree/deps-compare produce a report, not a stored snapshot, and transparently read a compressed snapshot operand either way via magic-byte detection regardless of this input. |
policy |
no |
strict_abi |
Built-in policy profile: strict_abi (default), sdk_vendor, plugin_abi. |
policy-file |
no |
— |
Path to a YAML policy document with per-kind (overrides:) or selector-scoped (reclassify:) verdict re-classification, or the name of a packaged built-in one (e.g. security). Forwarded as --policy, which takes a profile name or a document; setting this outranks policy for the run, exactly as the removed --policy-file flag did. |
suppress |
no |
— |
Path to a YAML suppression file to filter known/intentional changes. |
verbose |
no |
false |
Enable verbose/debug output from abicheck. |
python-version |
no |
3.13 |
Python version for setup-python. |
install-deps |
no |
true |
Deprecated — use dependency-source instead (kept for one release cycle). Ignored if dependency-source is set. true (the default) maps to dependency-source=conda-forge; false maps to dependency-source=none. |
dependency-source |
no |
— |
How to install system dependencies (castxml, gcc/g++, clang, bear): 'conda-forge' (default — this repo's pixi-managed scanner conda-forge environment, castxml 0.7.x + whichever gcc/g++ conda-forge currently resolves as default; Linux/macOS only, no clang, no bear), 'conda-forge-gcc14' (same, but pinned to gcc/g++ 14.x instead of whatever's currently default; Linux-only, no clang, no bear), 'conda-forge-clang20' (castxml + clang/clang++ 20.x instead of gcc — the one conda-forge source that provides clang, needed for L4 source-ABI replay and the clang-backed call/type/include-graph edges of L5 (the structural L5 source graph itself still builds from L3 build evidence alone, without clang); Linux/macOS, no bear), 'system' (apt/Homebrew + the pinned CastXML Superbuild — the previous default, still available; installs bear on Linux only — the macOS path installs only castxml via Homebrew and relies on Xcode's preinstalled clang, no bear), or 'none' (skip; dependencies must already be on PATH). Leave unset to fall back to install-deps for backward compatibility. On a Windows runner the unset default is 'system', not 'conda-forge' — every conda-forge source is unsupported there, so the usual default would hard-fail before analysis; an explicitly requested conda-forge* still errors rather than being silently rewritten. |
upload-sarif |
no |
false |
Upload SARIF results to GitHub Code Scanning (requires security-events: write permission). Requires format=sarif and mode=compare — setting this with any other mode or format is a hard error raised before any dependency install (mode=dump/deps-tree/deps-compare never produce a SARIF report). |
fail-on-breaking |
no |
true |
Fail the step when a binary ABI break is detected (exit code 4). |
fail-on-api-break |
no |
false |
Fail the step when a source-level API break is detected (exit code 2). |
severity-preset |
no |
— |
Severity preset: 'default', 'strict', or 'info-only'. Controls exit codes and report labels. Applies to compare mode -- both the two-sided shape and the audit-only shape, where it is also the required opt-in for the AUDIT_GATE audit-gate axis: that axis is inactive by default (see the AUDIT_GATE verdict entry below), so set this to a value other than 'info-only' to gate an audit-only run on a BREAKING/API_BREAK-classified finding. Does not apply to dump, deps-tree, or deps-compare. |
require-complete-analysis |
no |
false |
RETIRED (rulings.py deferred-option followup -- hard removal, no deprecation window): removed and no longer forwarded. The CLI's own compare --require-complete-analysis flag it mirrored is gone entirely: P0.4's orthogonal ANALYSIS_INCOMPLETE axis is config-only now, .abicheck.yml's assurance.require_complete: true, with no CLI override. Applied identically to single-pair compare's two-sided and audit-only (--no-baseline) shapes before its removal, and rejected outright for a directory/package compare's per-library release fan-out until that operand was given real semantics: the fan-out folds every compared member's own analysis_assurance with max into the same exit axis, so assurance.require_complete: true is no longer single-pair-only. Still declared here so a workflow that sets it gets an explicit ::error:: naming that replacement instead of a silently-ignored input; set assurance.require_complete: true in your .abicheck.yml and pass that file as build-config instead, then remove this input. |
annotate |
no |
false |
Emit GitHub Actions workflow command annotations (inline PR-diff comments) for ABI/API findings, in compare mode's two-sided shape (single-pair and directory/package release operands alike). Not supported for compare's audit-only shape (old-library/abi-baseline both omitted) -- its report has no additions/removals to annotate, only candidate-side findings; requesting it there emits a ::notice:: explaining why and renders nothing, rather than silently producing zero annotations. Rendered by this Action itself from the run's own persisted JSON report (schema 2.43+), not by passing --annotate to the abicheck CLI -- no second comparison is ever run to collect them, for either operand shape. Has no effect on dump/deps-tree/deps-compare. A dedicated input rather than routing through extra-args: this Action's own detection of whether annotations were requested must never be ambiguous with some other extra-args value, which a free-text passthrough can't guarantee. |
annotate-additions |
no |
false |
Include additions and other compatible-but-notable changes as ::notice annotations. Off by default (only errors/warnings, plus the one notice kind that is always shown regardless of this input -- a --contract finding compatibility policy did not evaluate). Has no effect unless annotate is also true. |
extra-args |
no |
— |
Additional CLI arguments passed directly to the abicheck command. |
add-job-summary |
no |
true |
Write a markdown summary to the GitHub Actions Job Summary. Ignored for dump mode. |
pr-comment |
no |
true |
Post a sticky ABI report comment on the pull request. Supports compare mode (both the two-sided shape, including directory/package operands, and the single-artifact audit-only shape), rendering the same verdict/breaking/needs-review sections plus a green "Public API additions" table, and (audit-only) a risk/coverage summary line. The comment is a content channel and never changes the check's red/green state — breaks still gate via fail-on-breaking / fail-on-api-break. Defaults to 'true', but is a no-op unless the workflow is triggered by a pull_request event and a token with 'pull-requests: write' is available. |
pr-comment-mode |
no |
update |
'update' (default) keeps a single sticky comment and edits it in place on every run; 'new' posts a fresh comment each run. Either way the scanned head SHA is shown in the comment. |
pr-comment-on |
no |
changes |
When to comment: 'changes' (default) comments when the run produced anything a reviewer must act on -- at least one ABI/API change, a removed/added library, an incompletely checked comparison scope, a finding disposed of by a suppression rule, or a material analysis limitation the comparison itself recorded (its 'coverage_warnings', e.g. "No header/AST data; type-level changes may be missed"). A clean run whose only evidence note is a permanently-inapplicable detector (the PE and Mach-O detectors on an ELF comparison) is not such an outcome and still posts nothing. 'always' comments every run (including a clean "no changes" result), 'never' disables the comment unconditionally. Changing this input never changes the compatibility verdict, the gate, or the step's exit code -- it only decides whether a comment is written. |
pr-comment-report-artifact-url |
no |
— |
Optional direct URL of an uploaded full-report artifact (JSON/HTML), linked in the comment footer as 'Download full report' -- distinct from the always-present 'View workflow run' link. Leave unset unless an upload step actually succeeded: set it from that step's own 'artifact-url' output, so a link in the comment always corresponds to an artifact that exists. This Action does not upload artifacts itself, so it cannot derive this value. |
pr-comment-detail |
no |
standard |
Detail level of the comment body: 'summary' (verdict + counts only), 'standard' (default; per-symbol tables for breaking/review, grouped safe list) or 'full' (every change with locations, all sections expanded). |
github-token |
no |
${{ github.token }} |
Token used to post the PR comment and to auto-fetch release baselines. Defaults to the workflow token; requires 'pull-requests: write' for the comment. |