|
| 1 | +# GitHub Merge Queue Setup |
| 2 | + |
| 3 | +This document describes the GitHub-based approval and merge system that replaces Prow Tide. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The repository now uses GitHub workflows and merge queue instead of Prow Tide for managing PR approvals and merges. This provides: |
| 8 | + |
| 9 | +- Label-based approval system via comment commands |
| 10 | +- Required status checks for merge readiness |
| 11 | +- Automatic merging via GitHub merge queue |
| 12 | + |
| 13 | +## Workflow Diagram |
| 14 | + |
| 15 | +```mermaid |
| 16 | +flowchart TD |
| 17 | + Start([PR Created/Updated]) --> AutoChecks{Automatic Checks} |
| 18 | + |
| 19 | + AutoChecks --> WIP[Check WIP Status] |
| 20 | + AutoChecks --> ReleaseNote[Check Release Note Label] |
| 21 | + AutoChecks --> Rebase[Check Merge Conflicts] |
| 22 | + |
| 23 | + WIP -->|WIP detected| WIPLabel[Add: do-not-merge/work-in-progress] |
| 24 | + WIP -->|Ready| WIPRemove[Remove: do-not-merge/work-in-progress] |
| 25 | + |
| 26 | + ReleaseNote -->|Missing label| RNLabel[Add: do-not-merge/release-note-label-needed] |
| 27 | + ReleaseNote -->|Has label| RNRemove[Remove: do-not-merge/release-note-label-needed] |
| 28 | + |
| 29 | + Rebase -->|Conflicts| RebaseLabel[Add: needs-rebase] |
| 30 | + Rebase -->|Clean| RebaseRemove[Remove: needs-rebase] |
| 31 | + |
| 32 | + WIPLabel --> ManualReview |
| 33 | + WIPRemove --> ManualReview |
| 34 | + RNLabel --> ManualReview |
| 35 | + RNRemove --> ManualReview |
| 36 | + RebaseLabel --> ManualReview |
| 37 | + RebaseRemove --> ManualReview |
| 38 | + |
| 39 | + ManualReview{Manual Review} -->|Reviewer comments /lgtm| LGTMLabel[Add: lgtm] |
| 40 | + ManualReview -->|Maintainer comments /approve| ApprovedLabel[Add: approved] |
| 41 | + ManualReview -->|Anyone comments /hold| HoldLabel[Add: do-not-merge/hold] |
| 42 | + |
| 43 | + LGTMLabel --> MergeCheck |
| 44 | + ApprovedLabel --> MergeCheck |
| 45 | + HoldLabel --> MergeCheck |
| 46 | + |
| 47 | + MergeCheck{Merge Readiness Check} |
| 48 | + |
| 49 | + MergeCheck -->|Has lgtm + approved<br/>No blocking labels| Ready[✅ Status: PASS] |
| 50 | + MergeCheck -->|Missing lgtm or approved| NotReady[❌ Status: FAIL<br/>Missing required labels] |
| 51 | + MergeCheck -->|Has blocking labels| Blocked[❌ Status: FAIL<br/>Has blocking labels] |
| 52 | + |
| 53 | + Ready --> MergeQueue[Add to Merge Queue] |
| 54 | + NotReady --> Wait[Wait for approvals] |
| 55 | + Blocked --> Wait |
| 56 | + |
| 57 | + Wait --> ManualReview |
| 58 | + |
| 59 | + MergeQueue --> FinalChecks{All CI Checks Pass?} |
| 60 | + FinalChecks -->|Yes| Merge([🎉 PR Merged]) |
| 61 | + FinalChecks -->|No| Failed([❌ Merge Failed]) |
| 62 | + |
| 63 | + style Start fill:#e1f5ff |
| 64 | + style Merge fill:#d4edda |
| 65 | + style Failed fill:#f8d7da |
| 66 | + style Ready fill:#d4edda |
| 67 | + style NotReady fill:#fff3cd |
| 68 | + style Blocked fill:#f8d7da |
| 69 | + style MergeQueue fill:#cfe2ff |
| 70 | +``` |
| 71 | + |
| 72 | +### Key Points |
| 73 | +- **Green boxes** = Success states |
| 74 | +- **Yellow boxes** = Waiting/pending states |
| 75 | +- **Red boxes** = Blocked/failed states |
| 76 | +- **Blue boxes** = Active processing |
| 77 | + |
| 78 | +## Approval System |
| 79 | + |
| 80 | +### Commands |
| 81 | + |
| 82 | +Maintainers with **write** access can use the following commands in PR comments: |
| 83 | + |
| 84 | +#### `/lgtm` - Looks Good To Me |
| 85 | +Adds the `lgtm` label to indicate code review approval. |
| 86 | + |
| 87 | +``` |
| 88 | +/lgtm |
| 89 | +``` |
| 90 | + |
| 91 | +To remove the label: |
| 92 | +``` |
| 93 | +/lgtm cancel |
| 94 | +``` |
| 95 | + |
| 96 | +**Restrictions**: |
| 97 | +- Requires write access to the repository |
| 98 | +- ⚠️ PR authors and co-authors cannot `/lgtm` or `/approve` their own PRs |
| 99 | + |
| 100 | +#### `/approve` - Final Approval |
| 101 | +Adds the `approved` label to indicate final approval for merge. |
| 102 | + |
| 103 | +``` |
| 104 | +/approve |
| 105 | +``` |
| 106 | + |
| 107 | +To remove the label: |
| 108 | +``` |
| 109 | +/approve cancel |
| 110 | +``` |
| 111 | + |
| 112 | +**Restrictions**: |
| 113 | +- Requires write access to the repository |
| 114 | +- ⚠️ PR authors and co-authors cannot `/lgtm` or `/approve` their own PRs |
| 115 | + |
| 116 | +#### `/hold` - Hold PR from Merging |
| 117 | +Adds the `do-not-merge/hold` label to block a PR from merging. Both maintainers and PR authors can use this command. |
| 118 | + |
| 119 | +``` |
| 120 | +/hold |
| 121 | +``` |
| 122 | + |
| 123 | +To remove the hold: |
| 124 | +``` |
| 125 | +/unhold |
| 126 | +``` |
| 127 | +or |
| 128 | +``` |
| 129 | +/hold cancel |
| 130 | +``` |
| 131 | + |
| 132 | +### Permissions |
| 133 | + |
| 134 | +- Only users with **write** access to the repository can use approval commands |
| 135 | +- Commands must be placed at the start of a comment |
| 136 | +- The bot will react with emoji to indicate status: |
| 137 | + - 👀 (eyes) - Processing command |
| 138 | + - 👍 (+1) - Label added successfully |
| 139 | + - 👎 (-1) - Label removed successfully |
| 140 | + - 😕 (confused) - Insufficient permissions |
| 141 | + |
| 142 | +## Automatic Label Management |
| 143 | + |
| 144 | +Several workflows automatically manage labels based on PR state: |
| 145 | + |
| 146 | +### Work in Progress (WIP) |
| 147 | +- **Trigger**: PR title contains `[WIP]`, `WIP:`, `[Draft]`, `Draft:`, or 🚧 emoji, or PR is marked as draft |
| 148 | +- **Action**: Adds `do-not-merge/work-in-progress` label |
| 149 | +- **Resolution**: Remove WIP indicators from title or convert from draft to ready |
| 150 | + |
| 151 | +### Release Notes |
| 152 | +- **Trigger**: PR is missing a release note label |
| 153 | +- **Action**: Adds `do-not-merge/release-note-label-needed` label |
| 154 | +- **Resolution**: Add one of these labels manually, or use commands: |
| 155 | + - `release-note` - For user-facing changes |
| 156 | + - `release-note-action-required` - For breaking changes requiring user action |
| 157 | + - `release-note-none` - For internal changes with no user impact |
| 158 | + - **Commands**: `/release-note`, `/release-note-action-required`, `/release-note-none` |
| 159 | + - **Permissions**: ⚠️ **PR author ONLY** (following Prow's behavior - this ensures the author takes responsibility for documenting their changes) |
| 160 | + |
| 161 | +### Merge Conflicts |
| 162 | +- **Trigger**: PR has merge conflicts with base branch |
| 163 | +- **Action**: Adds `needs-rebase` label |
| 164 | +- **Resolution**: Rebase or merge the base branch to resolve conflicts |
| 165 | + |
| 166 | +### Hold |
| 167 | +- **Trigger**: Someone comments `/hold` |
| 168 | +- **Action**: Adds `do-not-merge/hold` label |
| 169 | +- **Resolution**: Comment `/unhold` or `/hold cancel` |
| 170 | +- **Permissions**: PR author OR maintainers with write access |
| 171 | + |
| 172 | +## Blocking Labels |
| 173 | + |
| 174 | +The following labels will block a PR from merging (checked by the Merge Readiness workflow): |
| 175 | + |
| 176 | +- `do-not-merge/hold` - Manual hold requested |
| 177 | +- `do-not-merge/invalid-owners-file` - OWNERS file is invalid |
| 178 | +- `do-not-merge/release-note-label-needed` - Missing release note label |
| 179 | +- `do-not-merge/requires-unreleased-pipelines` - Depends on unreleased Tekton pipelines |
| 180 | +- `do-not-merge/work-in-progress` - PR is still in progress |
| 181 | +- `needs-ok-to-test` - PR needs approval to run tests |
| 182 | +- `needs-rebase` - PR has merge conflicts |
| 183 | + |
| 184 | + |
| 185 | + |
| 186 | +## Enabling Auto-Merge with Merge Queue |
| 187 | + |
| 188 | +Once both required labels are present: |
| 189 | + |
| 190 | +1. The "Merge Readiness Check" status will turn green |
| 191 | +2. The PR can be added to the merge queue |
| 192 | +3. Enable auto-merge on the PR to have it automatically merge when ready |
| 193 | + |
| 194 | +### Repository Settings |
| 195 | + |
| 196 | +To enable merge queue for the repository: |
| 197 | + |
| 198 | +1. Go to **Settings** → **General** → **Pull Requests** |
| 199 | +2. Enable **Allow auto-merge** |
| 200 | +3. Go to **Settings** → **Branches** → **Branch protection rules** for your main branch |
| 201 | +4. Enable **Require merge queue** |
| 202 | +5. Add **Merge Readiness Check** as a required status check |
| 203 | +6. Configure merge queue settings: |
| 204 | + - Minimum PRs to merge: 1 (or as desired) |
| 205 | + - Maximum PRs to merge: 5 (or as desired) |
| 206 | + - Merge method: Squash, merge commit, or rebase (as per project preference) |
| 207 | + |
| 208 | +## Workflow Files |
| 209 | + |
| 210 | +All merge automation workflows are located in `.github/workflows/` with the `pr_` prefix. |
| 211 | + |
| 212 | +### [`pr_approval-labels.yaml`](workflows/pr_approval-labels.yaml) |
| 213 | +Handles `/lgtm` and `/approve` commands in PR comments. Manages label addition and removal based on user permissions. |
| 214 | +- **Permissions**: Requires write access to the repository |
| 215 | +- **Commands**: `/lgtm`, `/lgtm cancel`, `/approve`, `/approve cancel` |
| 216 | +- **Restrictions**: PR authors and co-authors cannot approve their own PRs (prevents self-approval) |
| 217 | + |
| 218 | +### [`pr_hold-label.yaml`](workflows/pr_hold-label.yaml) |
| 219 | +Handles `/hold` and `/unhold` commands. Allows maintainers and PR authors to block/unblock PRs from merging by adding/removing the `do-not-merge/hold` label. |
| 220 | +- **Permissions**: PR author or users with write access |
| 221 | +- **Commands**: `/hold`, `/unhold`, `/hold cancel` |
| 222 | + |
| 223 | +### [`pr_wip-label.yaml`](workflows/pr_wip-label.yaml) |
| 224 | +Automatically detects work-in-progress PRs by checking for: |
| 225 | +- PR titles starting with `[WIP]`, `WIP:`, `[Draft]`, or `Draft:` |
| 226 | +- Draft PR status |
| 227 | +- 🚧 emoji in title |
| 228 | + |
| 229 | +Adds/removes `do-not-merge/work-in-progress` label accordingly. |
| 230 | + |
| 231 | +### [`pr_release-notes-label.yaml`](workflows/pr_release-notes-label.yaml) |
| 232 | +Checks for release note labels on PRs. Adds `do-not-merge/release-note-label-needed` if missing one of: |
| 233 | +- `release-note` - User-facing changes |
| 234 | +- `release-note-action-required` - Requires action from users |
| 235 | +- `release-note-none` - No user-facing changes |
| 236 | + |
| 237 | +**NEW**: Also supports comment commands for easier label management: |
| 238 | +- **Commands**: `/release-note`, `/release-note-action-required`, `/release-note-none` |
| 239 | +- **Permissions**: ⚠️ **PR author ONLY** (matches Prow's release-note plugin behavior) |
| 240 | +- **Rationale**: Only the PR author can set release note labels to ensure they take responsibility for documenting their changes |
| 241 | +- **Features**: Automatically removes other release-note labels when applying a new one |
| 242 | + |
| 243 | +### [`pr_needs-rebase-label.yaml`](workflows/pr_needs-rebase-label.yaml) |
| 244 | +Automatically detects merge conflicts and adds/removes the `needs-rebase` label when conflicts are present. |
| 245 | + |
| 246 | +### [`pr_merge-readiness.yaml`](workflows/pr_merge-readiness.yaml) |
| 247 | +Provides a required status check that verifies both `lgtm` and `approved` labels are present and no blocking labels exist. |
| 248 | + |
| 249 | +## Migration from Prow |
| 250 | + |
| 251 | +This system replaces the Prow Tide configuration with native GitHub functionality: |
| 252 | + |
| 253 | +| Prow Tide | GitHub Workflows | |
| 254 | +|-----------|------------------| |
| 255 | +| `/lgtm` command | `/lgtm` command (via `pr_approval-labels.yaml`) | |
| 256 | +| `/approve` command | `/approve` command (via `pr_approval-labels.yaml`) | |
| 257 | +| `/hold` command | `/hold` command (via `pr_hold-label.yaml`) | |
| 258 | +| Release note plugin | Release note workflow (via `pr_release-notes-label.yaml`) with `/release-note-*` commands | |
| 259 | +| Tide merge pool | GitHub Merge Queue | |
| 260 | +| Tide status contexts | Merge Readiness Check | |
| 261 | +| Automatic merging | Auto-merge + Merge Queue | |
| 262 | + |
| 263 | +### Key Differences from Prow Tide |
| 264 | + |
| 265 | +#### Architecture |
| 266 | +- **Prow Tide**: Centralized service running on Kubernetes cluster, polls GitHub API for PRs matching criteria |
| 267 | +- **GitHub Workflows**: Distributed event-driven workflows, triggered by GitHub webhooks on PR events |
| 268 | +- **Result**: Lower latency (immediate response vs polling), no infrastructure to maintain |
| 269 | + |
| 270 | +#### Label Management |
| 271 | +- **Prow Tide**: Plugins (lgtm, approve, hold, wip) managed by central Prow plugins |
| 272 | +- **GitHub Workflows**: Individual workflows handle each command independently |
| 273 | +- **Result**: More modular, easier to customize individual behaviors |
| 274 | + |
| 275 | +#### Merge Process |
| 276 | +- **Prow Tide**: |
| 277 | + - Batches multiple PRs together for testing |
| 278 | + - Maintains merge pool with sync loop (default: 2m) |
| 279 | + - Tests PRs together, merges if batch passes |
| 280 | + - Bisects on failure to find culprit |
| 281 | +- **GitHub Merge Queue**: |
| 282 | + - Tests each PR individually or in configurable groups |
| 283 | + - Queue-based approach with configurable merge strategies |
| 284 | + - Native GitHub UI for queue visibility |
| 285 | + - No separate infrastructure needed |
| 286 | +- **Result**: Similar reliability, simpler setup, better UI |
| 287 | + |
| 288 | +#### Permission Model |
| 289 | +- **Prow Tide**: Uses GitHub team membership and OWNERS files |
| 290 | +- **GitHub Workflows**: Uses GitHub's native repository permissions (read/write/admin) |
| 291 | +- **Result**: More straightforward, one permission system to manage |
| 292 | + |
| 293 | +#### Status Checks |
| 294 | +- **Prow Tide**: Multiple required contexts, complex configuration |
| 295 | +- **GitHub Workflows**: Single "Merge Readiness Check" workflow |
| 296 | +- **Result**: Simpler to understand, single source of truth |
| 297 | + |
| 298 | +#### Commands |
| 299 | +- **Prow Tide**: Fixed set of commands defined in plugins config |
| 300 | +- **GitHub Workflows**: Flexible, can add new commands easily by creating new workflows |
| 301 | +- **Result**: More extensible and customizable |
| 302 | + |
| 303 | +#### What's the Same |
| 304 | +✅ `/lgtm` and `/approve` commands work identically |
| 305 | +✅ `/hold` blocks merging |
| 306 | +✅ `do-not-merge/*` labels prevent merging |
| 307 | +✅ Automatic WIP detection |
| 308 | +✅ Release note label enforcement |
| 309 | +✅ Merge conflict detection |
| 310 | +✅ Permission-based access control |
| 311 | + |
| 312 | +#### What's Different |
| 313 | +⚠️ **No batch merging** - GitHub merge queue tests PRs individually or in smaller groups |
| 314 | +⚠️ **No OWNERS file** - Uses GitHub repository permissions instead |
| 315 | +⚠️ **Different UI** - GitHub PR UI instead of Prow dashboard |
| 316 | +⚠️ **Faster response** - Event-driven instead of polling (2m sync period) |
| 317 | +⚠️ **Simpler setup** - No Prow infrastructure needed |
| 318 | + |
| 319 | +#### Migration Considerations |
| 320 | +- **OWNERS files**: If you rely on OWNERS files for approval, you'll need to migrate to GitHub CODEOWNERS |
| 321 | +- **Batch testing**: If you need to test multiple PRs together, configure merge queue groups |
| 322 | +- **Custom plugins**: Any custom Prow plugins need to be reimplemented as GitHub workflows |
| 323 | +- **Tide configuration**: Context requirements → Branch protection rules |
| 324 | +- **Bot accounts**: Replace Prow bot token with GitHub Actions bot or app |
| 325 | + |
| 326 | +## Troubleshooting |
| 327 | + |
| 328 | +### Commands not working |
| 329 | +- Verify you have write access to the repository |
| 330 | +- Ensure the command is at the start of the comment |
| 331 | +- Check workflow run logs in the Actions tab |
| 332 | + |
| 333 | +### Merge Readiness Check failing |
| 334 | +- Verify both `lgtm` and `approved` labels are present |
| 335 | +- Check the workflow logs for detailed status |
| 336 | + |
| 337 | +### Auto-merge not triggering |
| 338 | +- Ensure merge queue is enabled in repository settings |
| 339 | +- Verify all required status checks are passing |
| 340 | +- Check that auto-merge is enabled on the PR |
0 commit comments