|
| 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 | +#### `/approve` - Final Approval |
| 97 | +Adds the `approved` label to indicate final approval for merge. |
| 98 | + |
| 99 | +``` |
| 100 | +/approve |
| 101 | +``` |
| 102 | + |
| 103 | +To remove the label: |
| 104 | +``` |
| 105 | +/approve cancel |
| 106 | +``` |
| 107 | + |
| 108 | +#### `/hold` - Hold PR from Merging |
| 109 | +Adds the `do-not-merge/hold` label to block a PR from merging. Both maintainers and PR authors can use this command. |
| 110 | + |
| 111 | +``` |
| 112 | +/hold |
| 113 | +``` |
| 114 | + |
| 115 | +To remove the hold: |
| 116 | +``` |
| 117 | +/unhold |
| 118 | +``` |
| 119 | +or |
| 120 | +``` |
| 121 | +/hold cancel |
| 122 | +``` |
| 123 | + |
| 124 | +### Permissions |
| 125 | + |
| 126 | +- Only users with **write** access to the repository can use approval commands |
| 127 | +- Commands must be placed at the start of a comment |
| 128 | +- The bot will react with emoji to indicate status: |
| 129 | + - 👀 (eyes) - Processing command |
| 130 | + - 👍 (+1) - Label added successfully |
| 131 | + - 👎 (-1) - Label removed successfully |
| 132 | + - 😕 (confused) - Insufficient permissions |
| 133 | + |
| 134 | +## Automatic Label Management |
| 135 | + |
| 136 | +Several workflows automatically manage labels based on PR state: |
| 137 | + |
| 138 | +### Work in Progress (WIP) |
| 139 | +- **Trigger**: PR title contains `[WIP]`, `WIP:`, `[Draft]`, `Draft:`, or 🚧 emoji, or PR is marked as draft |
| 140 | +- **Action**: Adds `do-not-merge/work-in-progress` label |
| 141 | +- **Resolution**: Remove WIP indicators from title or convert from draft to ready |
| 142 | + |
| 143 | +### Release Notes |
| 144 | +- **Trigger**: PR is missing a release note label |
| 145 | +- **Action**: Adds `do-not-merge/release-note-label-needed` label |
| 146 | +- **Resolution**: Add one of these labels: |
| 147 | + - `release-note` - For user-facing changes |
| 148 | + - `release-note-action-required` - For breaking changes requiring user action |
| 149 | + - `release-note-none` - For internal changes with no user impact |
| 150 | + |
| 151 | +### Merge Conflicts |
| 152 | +- **Trigger**: PR has merge conflicts with base branch |
| 153 | +- **Action**: Adds `needs-rebase` label |
| 154 | +- **Resolution**: Rebase or merge the base branch to resolve conflicts |
| 155 | + |
| 156 | +### Hold |
| 157 | +- **Trigger**: Someone comments `/hold` |
| 158 | +- **Action**: Adds `do-not-merge/hold` label |
| 159 | +- **Resolution**: Comment `/unhold` or `/hold cancel` |
| 160 | + |
| 161 | +## Blocking Labels |
| 162 | + |
| 163 | +The following labels will block a PR from merging (checked by the Merge Readiness workflow): |
| 164 | + |
| 165 | +- `do-not-merge/hold` - Manual hold requested |
| 166 | +- `do-not-merge/invalid-owners-file` - OWNERS file is invalid |
| 167 | +- `do-not-merge/release-note-label-needed` - Missing release note label |
| 168 | +- `do-not-merge/requires-unreleased-pipelines` - Depends on unreleased Tekton pipelines |
| 169 | +- `do-not-merge/work-in-progress` - PR is still in progress |
| 170 | +- `needs-ok-to-test` - PR needs approval to run tests |
| 171 | +- `needs-rebase` - PR has merge conflicts |
| 172 | + |
| 173 | + |
| 174 | + |
| 175 | +## Enabling Auto-Merge with Merge Queue |
| 176 | + |
| 177 | +Once both required labels are present: |
| 178 | + |
| 179 | +1. The "Merge Readiness Check" status will turn green |
| 180 | +2. The PR can be added to the merge queue |
| 181 | +3. Enable auto-merge on the PR to have it automatically merge when ready |
| 182 | + |
| 183 | +### Repository Settings |
| 184 | + |
| 185 | +To enable merge queue for the repository: |
| 186 | + |
| 187 | +1. Go to **Settings** → **General** → **Pull Requests** |
| 188 | +2. Enable **Allow auto-merge** |
| 189 | +3. Go to **Settings** → **Branches** → **Branch protection rules** for your main branch |
| 190 | +4. Enable **Require merge queue** |
| 191 | +5. Add **Merge Readiness Check** as a required status check |
| 192 | +6. Configure merge queue settings: |
| 193 | + - Minimum PRs to merge: 1 (or as desired) |
| 194 | + - Maximum PRs to merge: 5 (or as desired) |
| 195 | + - Merge method: Squash, merge commit, or rebase (as per project preference) |
| 196 | + |
| 197 | +## Workflow Files |
| 198 | + |
| 199 | +All merge automation workflows are located in [`.github/workflows/merge-automation/`](.github/workflows/merge-automation/). |
| 200 | + |
| 201 | +### [`approval-labels.yaml`](.github/workflows/merge-automation/approval-labels.yaml) |
| 202 | +Handles `/lgtm` and `/approve` commands in PR comments. Manages label addition and removal based on user permissions. |
| 203 | + |
| 204 | +### [`hold-label.yaml`](.github/workflows/merge-automation/hold-label.yaml) |
| 205 | +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. |
| 206 | + |
| 207 | +### [`wip-label.yaml`](.github/workflows/merge-automation/wip-label.yaml) |
| 208 | +Automatically detects work-in-progress PRs by checking for: |
| 209 | +- PR titles starting with `[WIP]`, `WIP:`, `[Draft]`, or `Draft:` |
| 210 | +- Draft PR status |
| 211 | +- 🚧 emoji in title |
| 212 | + |
| 213 | +Adds/removes `do-not-merge/work-in-progress` label accordingly. |
| 214 | + |
| 215 | +### [`release-notes-label.yaml`](.github/workflows/merge-automation/release-notes-label.yaml) |
| 216 | +Checks for release note labels on PRs. Adds `do-not-merge/release-note-label-needed` if missing one of: |
| 217 | +- `release-note` - User-facing changes |
| 218 | +- `release-note-action-required` - Requires action from users |
| 219 | +- `release-note-none` - No user-facing changes |
| 220 | + |
| 221 | +### [`needs-rebase-label.yaml`](.github/workflows/merge-automation/needs-rebase-label.yaml) |
| 222 | +Automatically detects merge conflicts and adds/removes the `needs-rebase` label when conflicts are present. |
| 223 | + |
| 224 | +### [`merge-readiness.yaml`](.github/workflows/merge-automation/merge-readiness.yaml) |
| 225 | +Provides a required status check that verifies both `lgtm` and `approved` labels are present and no blocking labels exist. |
| 226 | + |
| 227 | +## Migration from Prow |
| 228 | + |
| 229 | +This system replaces the Prow Tide configuration with native GitHub functionality: |
| 230 | + |
| 231 | +| Prow Tide | GitHub Workflows | |
| 232 | +|-----------|------------------| |
| 233 | +| `/lgtm` command | `/lgtm` command (via `approval-labels.yaml`) | |
| 234 | +| `/approve` command | `/approve` command (via `approval-labels.yaml`) | |
| 235 | +| Tide merge pool | GitHub Merge Queue | |
| 236 | +| Tide status contexts | Merge Readiness Check | |
| 237 | +| Automatic merging | Auto-merge + Merge Queue | |
| 238 | + |
| 239 | +### Key Differences from Prow Tide |
| 240 | + |
| 241 | +#### Architecture |
| 242 | +- **Prow Tide**: Centralized service running on Kubernetes cluster, polls GitHub API for PRs matching criteria |
| 243 | +- **GitHub Workflows**: Distributed event-driven workflows, triggered by GitHub webhooks on PR events |
| 244 | +- **Result**: Lower latency (immediate response vs polling), no infrastructure to maintain |
| 245 | + |
| 246 | +#### Label Management |
| 247 | +- **Prow Tide**: Plugins (lgtm, approve, hold, wip) managed by central Prow plugins |
| 248 | +- **GitHub Workflows**: Individual workflows handle each command independently |
| 249 | +- **Result**: More modular, easier to customize individual behaviors |
| 250 | + |
| 251 | +#### Merge Process |
| 252 | +- **Prow Tide**: |
| 253 | + - Batches multiple PRs together for testing |
| 254 | + - Maintains merge pool with sync loop (default: 2m) |
| 255 | + - Tests PRs together, merges if batch passes |
| 256 | + - Bisects on failure to find culprit |
| 257 | +- **GitHub Merge Queue**: |
| 258 | + - Tests each PR individually or in configurable groups |
| 259 | + - Queue-based approach with configurable merge strategies |
| 260 | + - Native GitHub UI for queue visibility |
| 261 | + - No separate infrastructure needed |
| 262 | +- **Result**: Similar reliability, simpler setup, better UI |
| 263 | + |
| 264 | +#### Permission Model |
| 265 | +- **Prow Tide**: Uses GitHub team membership and OWNERS files |
| 266 | +- **GitHub Workflows**: Uses GitHub's native repository permissions (read/write/admin) |
| 267 | +- **Result**: More straightforward, one permission system to manage |
| 268 | + |
| 269 | +#### Status Checks |
| 270 | +- **Prow Tide**: Multiple required contexts, complex configuration |
| 271 | +- **GitHub Workflows**: Single "Merge Readiness Check" workflow |
| 272 | +- **Result**: Simpler to understand, single source of truth |
| 273 | + |
| 274 | +#### Commands |
| 275 | +- **Prow Tide**: Fixed set of commands defined in plugins config |
| 276 | +- **GitHub Workflows**: Flexible, can add new commands easily by creating new workflows |
| 277 | +- **Result**: More extensible and customizable |
| 278 | + |
| 279 | +#### What's the Same |
| 280 | +✅ `/lgtm` and `/approve` commands work identically |
| 281 | +✅ `/hold` blocks merging |
| 282 | +✅ `do-not-merge/*` labels prevent merging |
| 283 | +✅ Automatic WIP detection |
| 284 | +✅ Release note label enforcement |
| 285 | +✅ Merge conflict detection |
| 286 | +✅ Permission-based access control |
| 287 | + |
| 288 | +#### What's Different |
| 289 | +⚠️ **No batch merging** - GitHub merge queue tests PRs individually or in smaller groups |
| 290 | +⚠️ **No OWNERS file** - Uses GitHub repository permissions instead |
| 291 | +⚠️ **Different UI** - GitHub PR UI instead of Prow dashboard |
| 292 | +⚠️ **Faster response** - Event-driven instead of polling (2m sync period) |
| 293 | +⚠️ **Simpler setup** - No Prow infrastructure needed |
| 294 | + |
| 295 | +#### Migration Considerations |
| 296 | +- **OWNERS files**: If you rely on OWNERS files for approval, you'll need to migrate to GitHub CODEOWNERS |
| 297 | +- **Batch testing**: If you need to test multiple PRs together, configure merge queue groups |
| 298 | +- **Custom plugins**: Any custom Prow plugins need to be reimplemented as GitHub workflows |
| 299 | +- **Tide configuration**: Context requirements → Branch protection rules |
| 300 | +- **Bot accounts**: Replace Prow bot token with GitHub Actions bot or app |
| 301 | + |
| 302 | +## Troubleshooting |
| 303 | + |
| 304 | +### Commands not working |
| 305 | +- Verify you have write access to the repository |
| 306 | +- Ensure the command is at the start of the comment |
| 307 | +- Check workflow run logs in the Actions tab |
| 308 | + |
| 309 | +### Merge Readiness Check failing |
| 310 | +- Verify both `lgtm` and `approved` labels are present |
| 311 | +- Check the workflow logs for detailed status |
| 312 | + |
| 313 | +### Auto-merge not triggering |
| 314 | +- Ensure merge queue is enabled in repository settings |
| 315 | +- Verify all required status checks are passing |
| 316 | +- Check that auto-merge is enabled on the PR |
0 commit comments