Andrushika opened a new pull request, #76681: URL: https://github.com/apache/airflow/pull/76681
## Why For each pull request gated to fork CI, the reconciler shows the state in four places: the draft state, the `ready for maintainer review` label, the `needs project ci` label and the state comment. Each branch of `classify()` set the draft state and the labels on its own. The branches did not always agree with each other or with the state comment: - #76493 was opened as a draft. Its fork CI is green, and the state comment says "The pull request is ready for maintainer review". It has no review label and is still a draft. - #74540 got `ready for maintainer review`. Then the author converted it to draft. The label stays on the draft. - Closing for the gate asks for a draft change. The draft-state job runs after the close, and GitHub refuses to draft a closed pull request. For #76510 the job logged "does not have permission to convert the pull request ... to draft" and reported it to Slack. ## What `compute_projection` maps each state to the draft state and the two labels. Its second input is whether the pull request is the author's own draft. Every branch of `classify()` now uses it. `test_projection_table` checks the function, and `08_fork_ci_for_external_contributors.md` shows the same diagram and table. The [AIP-120 vote thread](https://lists.apache.org/thread/hh5p3j9cj66767lj3gpotfz8rgvkt0oh) asked for two more changes: - A failed fork run no longer drafts the pull request. A flaky test after a rebase drafted approved pull requests and cancelled their auto-merge. - `close_after_days` is 30, not 7. Some contributors only work on their pull requests in spare moments. Six rows change, marked "new" below. Only the `failed` text changes. The bot edits the comments of failed pull requests once, and leaves the other comments as they are. ```mermaid %%{init: {'theme': 'neutral'}}%% stateDiagram-v2 [*] --> gated: discovery adds fork ci required state gated { [*] --> setup_required: workflow not enabled in the fork [*] --> awaiting_push: workflow enabled, no run for the head commit [*] --> running: fork run in progress setup_required --> awaiting_push: author enables the workflow awaiting_push --> running: author pushes running --> failed: run fails, is cancelled or times out running --> green: run passes, no CI-defining change running --> green_unverified: run passes, CI-defining change failed --> running: author pushes green --> running: author pushes green_unverified --> running: author pushes running --> setup_required: workflow disabled awaiting_push --> setup_required: workflow disabled state green { [*] --> green_ready: not a draft, or the bot's draft [*] --> green_author_draft: the author's draft green_ready --> green_author_draft: author converts to draft green_author_draft --> green_ready: author marks it ready } state green_unverified { [*] --> unverified_ready: not a draft, or the bot's draft [*] --> unverified_author_draft: the author's draft unverified_ready --> unverified_author_draft: author converts to draft unverified_author_draft --> unverified_ready: author marks it ready } } gated --> closed: setup_required or awaiting_push for close_after_days (30 days) gated --> released: maintainer adds use project ci gated --> ungated: base branch without fork CI, e.g. v3-3-test gated --> gate_modified: pull request changes the gate gated --> gate_bypassed: project CI ran without use project ci (gate tampering) closed --> gated: reopened ``` The "author's draft" is a draft that the bot did not make. A pull request opened as a draft is one too. The table follows one rule: a draft waits for the author, `ready for maintainer review` waits for a maintainer review, and `needs project ci` waits for a maintainer to review the CI change and add `use project ci`. | State | Next | Draft | `ready for maintainer review` | `needs project ci` | State comment | |---|---|---|---|---|---| | setup_required | Author enables the workflow | draft | remove | remove | Fork CI: setup required, with the steps to enable the workflow | | awaiting_push | Author pushes | draft | remove | remove | Fork CI: waiting for a push | | failed | Author fixes and pushes | unchanged (new) | remove | remove | Fork CI: failed. Fix the failures and push again (new: no longer says it stays a draft) | | running | Nobody, fork CI runs | unchanged | remove | remove | Fork CI: running | | green | Maintainer reviews | undraft | add | remove | Fork CI: green. Ready for maintainer review | | green, author's draft | Author marks it ready | unchanged | remove (new) | remove | Fork CI: green. Mark it ready for review when it is (new) | | green_unverified | Maintainer reviews the CI change and adds `use project ci` | undraft | remove | add | Fork CI: green, needs a maintainer. A maintainer reviews the change and runs project CI | | green_unverified, author's draft | Author marks it ready | unchanged | remove | remove (new) | Fork CI: green. Once you mark it ready for review, a maintainer runs project CI (new) | | released | Usual review with project CI | undraft, except the author's draft | unchanged | remove | Project CI in use | | ungated | Usual review with project CI | undraft, except the author's draft | unchanged | remove | Project CI in use, the base branch does not use fork CI | | closed | Author sets up fork CI and reopens | unchanged | remove (new) | remove | Fork CI: closed after inactivity | | gate_modified | Maintainer reopens and adds `use project ci` | unchanged (new) | remove | remove | Fork CI: closed, the pull request changes the gate | | gate_bypassed | Maintainer reopens and adds `use project ci` | unchanged (new) | remove | remove | Fork CI: closed, project CI ran for this pull request | The bot edits the state comment on each run. An edit does not notify anyone, so the bot posts a new comment only when someone must act: | When | New comment | |---|---| | setup_required to awaiting_push | Asks the author to push again | | Any other state, except closed, to setup_required | Says that the fork workflow stopped and why | | closed | Says how to continue after the inactivity close | | gate_modified | Says which change to the gate closed it | | gate_bypassed | Links the project CI run that should not have run | The workflow run approval posts two more comments when a pull request changes CI files. This PR does not change them. Replaces #76516. The fork CI gate closed it, because it changes the reconciler. I force-pushed the branch after that, so GitHub cannot reopen it. related: #74822, #76672 --- ##### Was generative AI tooling used to co-author this PR? - [X] Yes — Claude Code (Opus 5.5) Generated-by: Claude Code (Opus 5.5) following [the guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
