UNDERSTANDING GITHUB AUTOMATION IN SWAMP
GitHub automation in Swamp is not one integration. It is a set of extensions, each built for a different kind of work, and all of them follow the same pattern. Each extension provides behavior types, and a behavior is a configured instance of one of those types. You run the behavior's methods, and their results become Swamp data. This page discusses how the GitHub extensions use that pattern, which choices they make about authentication and safety, and how those choices affect what you build with them. The general concepts are covered in Behaviors, Types, and Methods.
How the extensions divide the work
The extensions split along the lines of what a team needs from GitHub:
@hivemq/githubis about security: auditing tokens and collecting open Dependabot, code scanning and secret scanning alerts@hivemq/github/mergeproposes and lands changes: pull requests, branch merges and single-file commits@webframp/githubreads repositories, pull requests, issues, releases and Actions runs, and carries out approved triage actions@goodcraft/githuband its fork@dataverket/githubmake sure repositories, releases and pull requests exist@evrardjp/github-local-mirrorand@evrardjp/github-project-activitybuild views for maintainers from mirrored data
The split matters because the extensions do not share types. The pull request
created by @hivemq/github/merge and the pull request created by
@goodcraft/github are stored as different resources with different shapes. A
team that picks one extension for each concern ends up with data that is easier
to query than a team that mixes several extensions for the same job.
What a behavior is bound to
Each type decides what a single behavior stands for, and that decides how many
behaviors you create. A @hivemq/github/token behavior is bound to exactly one
token. Auditing five tokens therefore means five behaviors, and each audit
history stays attached to the token it describes. An alert behavior is bound to
one organization and one token. The repositories it checks are an input to
list, so one behavior can cover a different set of repositories on each run. A
@hivemq/github/merge behavior holds a default owner, and each method names the
repository.
The pattern is that stable identity, such as which token or which organization,
goes into global arguments, and the parts that change from run to run go into
method inputs. Some types bind more tightly. @keeb/github/gh-pr-list and
@taylor/github/repo fix the repository in the definition, which suits a
behavior that watches one repository and is awkward for one that sweeps many.
Tokens and the gh CLI login
The extensions authenticate in one of two ways, and the difference is larger than it first looks.
Octokit-backed types, such as the alert types, @goodcraft/github and the pull
request methods of @hivemq/github/merge, take a token global argument. That
value should always be a vault.get expression. The definition then holds a
reference, and Swamp redacts the resolved value from output and stored data. The
Storing Secrets tutorial shows this
behaviour, and the Vaults reference describes it.
@hivemq/github/token goes further with tokenFile, which lets the token stay
in a file that the definition never reads until audit time.
Methods backed by the gh CLI, such as commitFile, openPullRequest,
readFile, findPullRequest and all of @webframp/github, take no token at
all. They act as whatever account gh is logged in as on the machine that runs
them. That is convenient on a laptop, but it moves the question of identity out
of Swamp and onto the host. When runs move to a worker, the worker needs its own
gh login, and the identity that acts on GitHub is whoever set up that worker.
Remote Execution discusses where runs
happen. Teams that want the acting identity to be visible in the repository's
own configuration often prefer the token-based methods for that reason.
What lands in the data layer
The GitHub types write data that is meant to be queried, not only logged. The
alert types write one alerts resource per repository per scanner, so the
history of a single repository's alerts can be read without unpacking a combined
blob. They also write a run resource that aggregates one list call, so a
later step can consume exactly what one invocation saw.
The alert types also choose to record conditions as data instead of failing. A
repository without code scanning is marked unavailable, and a list cut short
by the API is marked truncated. This means one disabled scanner does not abort
a sweep across fifty repositories. The cost is that a consumer has to read the
markers, because an empty alert list and an unavailable scanner mean different
things.
tokenAudit records hold identity and type but never the secret, so they can be
shared and kept. pullRequest, fileCommit and pullRequestLookup records
give later steps something to reason from.
The Data Layer and
Query and Manage Data
cover how these records are versioned and read.
Composing scanners in a workflow
The alert types are designed to be combined. In a workflow, the three list
methods run, and their run resources are wired into the dependabot,
codeScanning and secretScanning inputs of @hivemq/github/security-alerts
build through CEL Expressions. The build
then checks that every requested repository in the configured organization
appears in every scanner's results, and fails if one does not.
That gate is stricter than the scanners themselves, and on purpose. A scanner run that misses a repository, because of a typo in the list or a failed call, would otherwise produce a Slack message that looks complete and is not. Refusing to build turns a silent omission into a failed run that someone will see. The step ordering and data passing are covered in The Workflow Execution Model, and running the sweep on a timer in Run Workflows on a Schedule.
Writing to GitHub safely
The extensions that write to GitHub handle the risk in different ways.
@goodcraft/github and @dataverket/github default dryRun to true and look
for existing state first. A run plans unless you tell it otherwise, and running
it twice does not create two repositories. @hivemq/github/merge makes dry runs
available on commitFile and openPullRequest but does not turn them on by
default. It also offers findPullRequest as an explicit check before proposing,
and that check answers instead of failing. @webframp/github asks for an
idempotencyKey on every write and describes its writes as approved actions.
That fits a flow where an agent proposes and a person approves, as described in
Gate a Workflow with Manual Approval.
None of these approaches is right for every case. Dry run by default protects people trying things out, but it adds a flag to every real run. Check-then-act keeps runs quick but depends on the workflow author remembering the check. Idempotency keys make retries safe even when a check and a write race each other. Make Workflows Idempotent discusses the trade-offs in general terms.
GitHub Enterprise Server and choosing an extension
The alert types, the token type, @goodcraft/github and @dataverket/github
take a baseUrl global argument, so the same definitions can point at GitHub
Enterprise Server instead of https://api.github.com. The gh CLI-backed methods
follow whichever host gh is logged in to.
When several extensions overlap, the useful questions are about maintenance and
trust, not feature lists. Ask who publishes the extension, how recently it
changed, what license it carries, and whether a fork such as
@dataverket/github has taken over from its upstream. Labels help find
candidates, and the registry pages show versions and pull counts.
Extension Trust and the Supply Chain
discusses how to weigh these signals before giving an extension a token that can
read your security alerts.