mirror of
https://github.com/apache/airflow.git
synced 2026-11-04 07:12:48 +00:00
* Show why external contributors' workflow runs wait for approval Contributors whose runs the auto-approve workflow leaves for a maintainer only saw a label, with no reason, and a comment for each would notify every subscriber. A pending "Workflow approval" commit status shows the reason in the PR's checks without notifying anyone. GitHub has no event for approving runs, but a waiting run never starts, so a run that starts is the signal to clear the status and the label, also for runs a maintainer approves by hand, without listing every waiting run. Generated-by: Claude Opus 5 * Keep the approval status in sync with runs approved during a tick Generated-by: Claude Opus 5 * Re-check approved runs after the failure path writes the approval state Generated-by: Claude Opus 5
86 lines
4.3 KiB
YAML
86 lines
4.3 KiB
YAML
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
---
|
|
# When the "Tests (AMD)" run of an external contributor's PR starts, turns the pending "Workflow
|
|
# approval" status that auto-approve-workflow-runs.yml set on its commit green and removes the
|
|
# "need workflow approval" label. GitHub has no event for approving runs, but a run waiting for
|
|
# approval never starts, so a started run was approved, by a maintainer or automatically.
|
|
#
|
|
# workflow_run runs with this repository's token whatever the PR, so this workflow checks out
|
|
# nothing and only calls the GitHub API. The head branch is chosen by the contributor and reaches
|
|
# the script only through the environment.
|
|
name: Mark workflow runs approved
|
|
on: # yamllint disable-line rule:truthy
|
|
workflow_run: # zizmor: ignore[dangerous-triggers]
|
|
workflows: ["Tests (AMD)"]
|
|
types: [in_progress]
|
|
permissions:
|
|
# Removing the "need workflow approval" label.
|
|
pull-requests: write
|
|
# Turning the "Workflow approval" status green.
|
|
statuses: write
|
|
concurrency:
|
|
group: mark-workflow-runs-approved-${{ github.event.workflow_run.head_sha }}
|
|
cancel-in-progress: false
|
|
jobs:
|
|
mark-workflow-runs-approved:
|
|
name: "Mark workflow runs approved"
|
|
runs-on: ["ubuntu-slim"]
|
|
if: >-
|
|
github.repository == 'apache/airflow' &&
|
|
github.event.workflow_run.event == 'pull_request' &&
|
|
github.event.workflow_run.head_repository.full_name != github.repository
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: "Mark workflow runs approved"
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
REPO: ${{ github.repository }}
|
|
HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }}
|
|
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
|
|
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
STATUS_URL: "https://github.com/apache/airflow/blob/main/contributing-docs/\
|
|
05_pull_requests.rst#ci-workflow-runs-of-external-contributors"
|
|
run: |
|
|
# Keep in sync with APPROVAL_STATUS_CONTEXT and NEED_WORKFLOW_APPROVAL_LABEL in
|
|
# dev/breeze/src/airflow_breeze/utils/workflow_run_approval.py.
|
|
context="Workflow approval"
|
|
label="need workflow approval"
|
|
# The sha is put into jq filters below.
|
|
[[ "${HEAD_SHA}" =~ ^[0-9a-f]{40}$ ]] || { echo "Unexpected head sha: ${HEAD_SHA}"; exit 1; }
|
|
# Paginated: the fork CI reconciler posts a status per job, so a commit can have many contexts.
|
|
state=$(gh api --paginate "repos/${REPO}/commits/${HEAD_SHA}/status?per_page=100" \
|
|
--jq ".statuses[] | select(.context == \"${context}\") | .state")
|
|
if [[ "${state}" == "pending" ]]; then
|
|
gh api -X POST "repos/${REPO}/statuses/${HEAD_SHA}" \
|
|
-f state=success -f context="${context}" -f description="Workflow runs approved" \
|
|
-f target_url="${STATUS_URL}" \
|
|
--silent
|
|
echo "${HEAD_SHA}: status turned green"
|
|
fi
|
|
# -f with GET encodes the branch into the query string. A PR pushed again after the run
|
|
# started has newer runs, which may wait, so it keeps its label.
|
|
prs=$(gh api -X GET --paginate "repos/${REPO}/pulls" \
|
|
-f state=open -f per_page=100 -f head="${HEAD_REPOSITORY%%/*}:${HEAD_BRANCH}" \
|
|
--jq ".[] | select(.head.sha == \"${HEAD_SHA}\")
|
|
| select(any(.labels[]; .name == \"${label}\")) | .number")
|
|
for number in ${prs}; do
|
|
gh api -X DELETE "repos/${REPO}/issues/${number}/labels/${label// /%20}" --silent
|
|
echo "#${number}: label removed"
|
|
done
|