GitHub Agentic Workflows

Example: Dependabot Rollout

This example uses the central control plane pattern to roll out Dependabot across 100 repositories. An orchestrator workflow filters and prioritizes target repositories, then dispatches a worker workflow that analyzes each repo and creates a customized pull request.

Both workflows live in one private control repository.

flowchart LR
    subgraph central["Central control repo"]
        WeeklySchedule([Weekly schedule]) --> Orchestrator[Orchestrator\nfilter & prioritize]
    end
    Orchestrator -->|dispatch_workflow| WorkerRepoA[Worker: Repo A\ncreate PR]
    Orchestrator -->|dispatch_workflow| WorkerRepoB[Worker: Repo B\ncreate PR]
    Orchestrator -->|dispatch_workflow| WorkerRepoN[Worker: Repo N\ncreate PR]
  1. The orchestrator runs weekly, scans organization repositories, skips ones that already have Dependabot configured, and dispatches up to 5 workers per run.
  2. Each worker checks out its target repository, analyzes the structure, and either creates a customized dependabot.yml pull request or opens an issue when Renovate or another conflict is detected.

In your central control repository, create .github/workflows/dependabot-rollout-orchestrator.md:

---
on:
schedule: weekly on monday
tools:
github:
github-token: ${{ secrets.GH_AW_READ_ORG_TOKEN }}
toolsets: [repos]
safe-outputs:
dispatch-workflow:
workflows: [dependabot-rollout]
max: 5
---
# Dependabot Rollout Orchestrator
Categorize and orchestrate Dependabot rollout across repositories.
**Target repos**: All repos in the organization
## Task
1. **Filter** - Parse repos (from input or variable), check each for existing `.github/dependabot.yml`, keep only repos without it
2. **Categorize** - Read repo contents to assess complexity:
- Simple: Single package.json, <50 dependencies, standard structure
- Complex: Multiple package.json files, >100 deps, or multiple ecosystems
- Conflicting: Has Renovate config or custom update scripts
- Security: Open security alerts or public with dependencies
3. **Prioritize** - Order repos by rollout preference: simple → security → complex → conflicting
4. **Dispatch** - Dispatch `dependabot-rollout` worker for every prioritized repository
5. **Summarize** - Report total candidates, categorization breakdown, selected repos with rationale

Compile this workflow: gh aw compile. Then create the GH_AW_READ_ORG_TOKEN secret — a fine-grained PAT with Contents: Read-only scoped to all target repositories. See Authentication for PAT and GitHub App setup.

Create the worker workflow .github/workflows/dependabot-rollout.md in the same central repository. It checks out each target repo via checkout: and creates a customized PR (or issue) via cross-repo safe outputs:

---
on:
workflow_dispatch:
inputs:
target_repo:
description: 'Target repository (owner/repo format)'
required: true
type: string
run-name: Dependabot rollout for ${{ github.event.inputs.target_repo }}
concurrency:
group: gh-aw-${{ github.workflow }}-${{ github.event.inputs.target_repo }}
engine:
concurrency:
group: gh-aw-copilot-${{ github.workflow }}-${{ github.event.inputs.target_repo }}
checkout:
repository: ${{ github.event.inputs.target_repo }}
github-token: ${{ secrets.ORG_REPO_CHECKOUT_TOKEN }}
current: true
permissions:
contents: read
issues: read
pull-requests: read
tools:
github:
github-token: ${{ secrets.GH_AW_READ_ORG_TOKEN }}
toolsets: [repos]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: ${{ github.event.inputs.target_repo }}
title-prefix: '[dependabot] '
max: 1
create-issue:
target-repo: ${{ github.event.inputs.target_repo }}
title-prefix: '[dependabot-config] '
max: 1
---
# Intelligent Dependabot Configuration
You are creating a **customized** Dependabot configuration based on analyzing this specific repository.
**Target Repository**: ${{ github.event.inputs.target_repo }}
## Why AI is Required
You must analyze the repository structure and create an intelligent, customized configuration - not a generic template.
## Step 1: Analyze Repository
**Check for conflicts:**
- Does `.github/dependabot.yml` already exist? → Stop, create issue explaining it exists
- Does `.github/renovate.json` or `renovate.json` exist? → Create issue about migrating from Renovate
- Are there custom dependency update scripts? → Create issue suggesting Dependabot alternative
**Analyze package manager complexity:**
For **npm** (if package.json exists):
- Count total dependencies (dependencies + devDependencies)
- Check for monorepo: Are there multiple package.json files in subdirectories?
- Simple: <20 dependencies, single package.json
- Complex: >100 dependencies OR monorepo structure
For **Python** (requirements.txt, setup.py, pyproject.toml):
- Count dependencies
- Check for multiple requirement files
For **Go** (go.mod):
- Note if present
For **GitHub Actions** (.github/workflows/*.yml):
- Count workflow files
**Security context:**
- Use GitHub tools to check for open security alerts
- If critical alerts exist, prioritize security updates
## Step 2: Create Customized Configuration
Based on your analysis, create an appropriate config:
### Simple Repository (<20 npm deps, no monorepo)
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily" # Low complexity = more frequent
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
```
### Complex Repository (>100 deps OR security alerts)
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly" # High complexity = less frequent
groups:
production:
patterns: ["*"]
exclude-patterns: ["@types/*", "@jest/*"]
dev-dependencies:
patterns: ["@types/*", "@jest/*", "eslint*"]
```
### Monorepo (multiple package.json)
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/packages/frontend"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/packages/backend"
schedule:
interval: "weekly"
```
## Step 3: Deliver Configuration
**If config is straightforward (no Renovate conflict):**
- Create `.github/dependabot.yml` with your customized config
- Create pull request with:
- Title: "[dependabot] Add customized Dependabot configuration"
- Body explaining: dependency count, why weekly vs daily, grouping strategy, etc.
**If Renovate detected:**
- Create issue explaining migration benefits and proposed config
- Include generated config in issue body
**If no package managers found:**
- Create issue: "No supported package managers detected"
## Key: Explain Your Reasoning
In the PR/issue body, explain **why** you chose this specific configuration (not a generic template).

Compile: gh aw compile.

Create two fine-grained PATs scoped to target repositories (see Authentication for full setup):

SecretPermissionsPurpose
ORG_REPO_CHECKOUT_TOKENContents: Read & write, Actions: Read & writeCheckout target repos
GH_AW_CROSS_REPO_PATContents: Write, Issues: Write, Pull Requests: WriteCreate PRs and issues
GH_AW_READ_ORG_TOKENContents: Read-onlyRead org repos in orchestrator and worker

After setup, the orchestrator runs every Monday and processes up to 5 repositories per run. You can also trigger it manually:

Terminal window
gh workflow run dependabot-rollout-orchestrator.lock.yml

Monitor progress in Actions and in the PRs or issues created in each target repository.

Keep max: 5 during the initial rollout, add the [dependabot] title prefix so PRs are easy to filter, use concurrency groups to prevent duplicate worker runs for the same repository, and manually review a few worker PRs before expanding the rollout.

See MultiRepoOps for other control-plane topologies, Feature Synchronization for upstream-to-downstream sync, Cross-Repository Issue Tracking for a hub-and-spoke example, Cross-Repository Operations for checkout and target-repo configuration, Authentication for PAT and GitHub App setup, and Safe Outputs for secure write operations.