Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
name: dependabot-automerge
description: Review a Dependabot dependency-update pull request, judge whether it is low-risk within the policy below, and auto-merge it if so — otherwise hold it for a human with an explanation. Use when a PR carries the dependencies label.
---

You decide whether a Dependabot pull request is safe to merge automatically.

The invocation `message` names the PR, e.g. `Act on GitHub PR acme/widgets#42`.
Parse the `owner/repo` and number out of it. If the repo is omitted, default to
`$GITHUB_REPOSITORY`.

## When this skill applies

Only act when **all** of these hold (verify, don't assume):

- The PR was opened by `dependabot[bot]` (check `github_get_dependabot_metadata`
→ `is_dependabot`).
- It carries the `dependencies` label.
- It is not a draft and its state is open.

If any fail, post a brief comment saying the skill did not apply and stop.

## The risk policy (these are hard limits — never override them)

You may judge a PR **low-risk and auto-merge it** only if every limit holds. You
have discretion *within* these limits, not around them:

1. **Version bump:** `patch` or `minor` only. **Never `major`. Never
`unknown`.** Determine the bump from the dependency's from/to versions — do
not eyeball it; the change class is provided to you deterministically. A
`major` or `unknown` bump is always held.
2. **Combined CI must be green.** `github_get_combined_status` →
`combined_state` must be `success`. `pending` or `failure` is held. (You will
still enable auto-merge, which re-gates on required checks, but do not treat a
non-green PR as low-risk.)
3. **Change shape looks like a dependency bump.** The changed files should be
limited to manifests/lockfiles (e.g. `package.json`, `package-lock.json`,
`yarn.lock`, `pnpm-lock.yaml`, `go.mod`, `go.sum`, `requirements*.txt`,
`Gemfile.lock`, `*.csproj`). If the PR also edits source/config/CI files,
that is outside a routine bump — hold it.
4. **Single dependency.** If the PR bumps several unrelated dependencies at once
and any one of them fails a limit above, hold the whole PR.

Within those limits, use your judgement: e.g. a minor bump of a well-known,
widely-used library with green CI and a lockfile-only diff is a clear
auto-merge; a minor bump that also touched a config file is a hold even though
the version class passes. **When in doubt, hold.** A wrongly-held PR costs a
human a click; a wrongly-merged one can break production.

## Steps

1. Read the PR with `github_get_pull_request` and the update details with
`github_get_dependabot_metadata`.
2. Confirm "When this skill applies" — stop early with a comment if it doesn't.
3. Determine the version-bump class from the from/to versions (patch / minor /
major / unknown).
4. Check `github_get_combined_status` for green CI.
5. Check `github_list_pull_request_files` for the change shape (limit 3 above).
6. Decide using the policy:
- **Low-risk →** `github_approve_pull_request` with a one-line rationale,
then `github_enable_auto_merge` (squash). GitHub merges once required
checks pass; a later red check still blocks it.
- **Not low-risk →** `github_add_comment` explaining exactly which limit held
it (e.g. "major bump", "CI failing", "edits source files"), and
`github_set_labels` with `automerge-held` so a human can find it. Do not
approve or merge.
7. Read `references/risk-policy.md` and make sure your decision and your comment
conform to it before you act.

Be explicit in every comment about *why* — name the limit, the versions, and the
CI state. Never merge a PR you would not be able to justify in one sentence.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Dependabot auto-merge — decision checklist

Before approving + enabling auto-merge, confirm every line. Any "no" → hold the
PR and comment why.

## Eligibility
- [ ] Author is `dependabot[bot]`.
- [ ] PR carries the `dependencies` label.
- [ ] PR is open and not a draft.

## Risk limits (hard — never overridden by judgement)
- [ ] Version bump is `patch` or `minor` (NOT `major`, NOT `unknown`).
- [ ] Combined CI status is `success` (not `pending`, not `failure`).
- [ ] Changed files are manifests/lockfiles only — no source, config, or CI edits.
- [ ] If multiple dependencies are bumped, every one passes the limits above.

## Action taken
- [ ] **Auto-merge path:** approved with a one-line rationale, then auto-merge
(squash) enabled. Comment states the dependency, from→to versions, bump
class, and that CI is green.
- [ ] **Hold path:** a comment names the exact limit that held it; the
`automerge-held` label is applied. No approval, no merge.

## Tuning this policy
This file plus the limits in `SKILL.md` are the only place to change behavior —
the agent code does not encode any of it. To make the policy stricter or looser
for your repo, edit here (e.g. restrict to `patch` only, or allow `minor` only
for `devDependencies`). The model judges within whatever limits you set; it
cannot widen them. When unsure, the policy is: **hold, don't merge.**
17 changes: 17 additions & 0 deletions .github/agents/dependabot-automerge/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copy to .env and fill in real values. Never commit real secrets.
# In GitHub Actions these come from repo OIDC + the built-in token, not this file.

# LLM provider — AWS Bedrock (model amazon-bedrock/us.anthropic.claude-sonnet-4-6).
# Locally, AWS_PROFILE resolves credentials. In GitHub Actions there is no IAM
# role on a hosted runner, so CI assumes a Bedrock-only role via OIDC instead
# (see .github/workflows/pr-label-actions.yml).
AWS_PROFILE=your-profile
AWS_REGION=us-west-2

# GitHub. Locally, use a PAT with `repo` scope so the agent can read the PR and
# approve / enable auto-merge. In Actions this is the built-in GITHUB_TOKEN,
# scoped by the workflow's permissions: block.
GITHUB_TOKEN=
# Optional — only for GitHub Enterprise Server. Actions sets this automatically;
# Octokit defaults to https://api.github.com when unset.
# GITHUB_API_URL=https://github.example.com/api/v3
4 changes: 4 additions & 0 deletions .github/agents/dependabot-automerge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
.env
.flue
9 changes: 9 additions & 0 deletions .github/agents/dependabot-automerge/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
You act on GitHub pull requests in response to a label. A maintainer (or a bot
like Dependabot) applies a label to a PR; that triggers a one-shot run, and the
skill matching the label tells you what to do — review it, comment, approve,
enable auto-merge, or hold it for a human.

You work entirely through the GitHub API. You never check out or run a PR's
code. Pick the skill that matches the PR's label and follow it exactly; when a
skill's policy says a change is not safe to act on automatically, hold it and
explain why in a comment rather than guessing.
45 changes: 45 additions & 0 deletions .github/agents/dependabot-automerge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# dependabot-automerge agent (vendored)

This is a vendored copy of the `github-pr-label-actions` Flue agent
([upstream](https://github.com/hjgraca/agentic-sdlc/tree/main/examples/github-pr-label-actions)),
committed in-tree so this repo depends on **no external source repository** at
run time. Tracking issue: #1228.

It is invoked one-shot by
[`.github/workflows/dependabot_automerge.yml`](../../workflows/dependabot_automerge.yml):
on a Dependabot PR labelled `dependencies`, the agent judges whether the change
is low-risk within the policy in
[`.agents/skills/dependabot-automerge/SKILL.md`](.agents/skills/dependabot-automerge/SKILL.md)
(patch/minor only, green CI, manifest/lockfile-only diff). If so it approves and
enables GitHub auto-merge (which still waits for required checks); otherwise it
holds the PR and comments why. It works only through the GitHub API and never
checks out or runs PR code.

## Layout

```
AGENTS.md # agent framing
.agents/skills/dependabot-automerge/ # the policy (edit here to tune risk limits)
src/agents/pr-label-actions.ts # model + sandbox + tools (pure wiring)
src/tools/github/ # outbound GitHub tools (@octokit/rest) + tests
```

## Tuning the risk policy

Edit `.agents/skills/dependabot-automerge/SKILL.md` and its
`references/risk-policy.md` — no rebuild. The model judges within the limits
defined there; it cannot widen them.

## Updating this copy

This is a vendored snapshot. To pull upstream changes, re-copy the example from
agentic-sdlc (excluding `node_modules`, `dist`, `.flue`, `.env`) and review the
diff. Local edits to the policy above can be re-applied on top.

## Local check

```bash
npm ci
npm test # unit tests for the pure helpers
./node_modules/.bin/flue build --target node
```
11 changes: 11 additions & 0 deletions .github/agents/dependabot-automerge/flue.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from '@flue/cli/config';

/**
* Build-time config only (target, root, output). Provider/model
* registration is a runtime concern and lives in code that reads
* process.env — never hardcode API keys here.
*
* `target: "node"` is set so `flue run` / `flue dev` work without the flag.
* Switch to "cloudflare" if you deploy there instead.
*/
export default defineConfig({ target: 'node' });
Loading