BUILD SLACK PAYLOADS FROM GITHUB SECURITY ALERT RUNS
This guide shows you how to merge one run of the Dependabot, code scanning and secret scanning alert behaviors into one Slack Block Kit payload per repository with open alerts. It also shows how the build behaves when a scanner's results leave out a requested repository.
Prerequisites
- A Swamp repository
- Scanner results in the shape of the alert behaviors'
runresources. Collect open security alerts across GitHub repositories produces them.
Pull the extension
swamp extension pull @hivemq/githubThe output looks like:
INF extension·pull: Pulling "@hivemq/github"@"2026.08.27.1787839782"
INF extension·pull: Identity verified: "@hivemq/github"@"2026.08.27.1787839782"
INF extension·pull: Pulled "@hivemq/github"@"2026.08.27.1787839782"
INF extension·pull: Extracted 21 files:Create the security-alerts behavior
Create a behavior named slack-alerts of type @hivemq/github/security-alerts.
Its only global argument is org, the organization that every scanner run must
belong to:
globalArguments:
org: example-orgCreate and Run a Behavior shows the create command.
Know the build inputs
The build method takes four inputs:
repos, an array of the repository names that must be covereddependabot,codeScanningandsecretScanning, one object per scanner
Each scanner object has org, capturedAt and repos. Every entry in repos
has org, repo, capturedAt, unavailable (a string or null), truncated
and alerts. This is the shape of an alert behavior's run resource. Pass the
objects as JSON with the :json= suffix.
Build the payloads
Run build with results from all three scanners covering api. In this
example, Dependabot reports one open alert:
swamp behavior run slack-alerts build \
--input 'repos:json=["api"]' \
--input 'dependabot:json={"org":"example-org","capturedAt":"2026-10-15T09:00:00Z","repos":[{"org":"example-org","repo":"api","capturedAt":"2026-10-15T09:00:00Z","unavailable":null,"truncated":false,"alerts":[{"number":12,"htmlUrl":"https://github.com/example-org/api/security/dependabot/12","title":"Prototype pollution in lodash","severity":"high"}]}]}' \
--input 'codeScanning:json={"org":"example-org","capturedAt":"2026-10-15T09:00:00Z","repos":[{"org":"example-org","repo":"api","capturedAt":"2026-10-15T09:00:00Z","unavailable":null,"truncated":false,"alerts":[]}]}' \
--input 'secretScanning:json={"org":"example-org","capturedAt":"2026-10-15T09:00:00Z","repos":[{"org":"example-org","repo":"api","capturedAt":"2026-10-15T09:00:00Z","unavailable":null,"truncated":false,"alerts":[]}]}'This checks that every scanner covers api in example-org. It then writes a
payloads resource holding the Slack payload for api, with the blocks
JSON-stringified so they can go straight to a Slack behavior's postBlocks
method.
Check the coverage gate
If you request a repository that a scanner's results do not include, the build fails and writes nothing:
swamp behavior run slack-alerts build \
--input 'repos:json=["api","web"]' \
--input 'dependabot:json={"org":"example-org","capturedAt":"2026-10-15T09:00:00Z","repos":[{"org":"example-org","repo":"api","capturedAt":"2026-10-15T09:00:00Z","unavailable":null,"truncated":false,"alerts":[]}]}' \
--input 'codeScanning:json={"org":"example-org","capturedAt":"2026-10-15T09:00:00Z","repos":[{"org":"example-org","repo":"api","capturedAt":"2026-10-15T09:00:00Z","unavailable":null,"truncated":false,"alerts":[]}]}' \
--input 'secretScanning:json={"org":"example-org","capturedAt":"2026-10-15T09:00:00Z","repos":[{"org":"example-org","repo":"api","capturedAt":"2026-10-15T09:00:00Z","unavailable":null,"truncated":false,"alerts":[]}]}'This requests api and web while every scanner covers only api, so the
method stops at the coverage gap and writes no payloads resource.
If a real run fails this way, run the missing scanner again with the full repository list, then build again.
Wire the build into a workflow
In a workflow, do not pass JSON by hand. Run the three alert behaviors' list
methods first, then pass their run resources to the dependabot,
codeScanning and secretScanning inputs of build with CEL expressions.
Refer to CEL Expressions and
Workflows for the syntax. Read the stored
payloads resource with
Query and Manage Data.