Skip to content

[CI/CD] Auto-Update PRs based on 1412/merge #626

[CI/CD] Auto-Update PRs based on 1412/merge

[CI/CD] Auto-Update PRs based on 1412/merge #626

---
# SPDX-FileCopyrightText: (C) 2025 - 2026 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
name: "[CI/CD] Auto-Update Pull Requests"
run-name: "[CI/CD] Auto-Update PRs based on ${{ github.ref_name }}"
on: # yamllint disable-line rule:truthy
push:
pull_request:
types:
- auto_merge_enabled
workflow_dispatch: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
update-pull-requests:
name: "Update pull requests targeting this branch"
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
env:
# Only PRs carrying this label are updated (drafts included).
UPDATE_LABEL: "auto-update"
steps:
- name: "Find and update pull requests"
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
BASE_BRANCH: ${{ github.ref_name }}
run: |
echo "Searching for open PRs targeting '${BASE_BRANCH}'"
if ! pr_list_output=$(gh pr list \
--repo "$GITHUB_REPOSITORY" \
--base "$BASE_BRANCH" \
--label "$UPDATE_LABEL" \
--state open \
--json number,isDraft,headRefName,title \
--jq '.[] | @json'); then
echo "ERROR: gh pr list failed — check API access and token permissions."
exit 1
fi
mapfile -t prs <<< "$pr_list_output"
# When output is empty, mapfile produces one empty element — normalize it.
if [[ ${#prs[@]} -eq 1 && -z "${prs[0]}" ]]; then
prs=()
fi
if [[ ${#prs[@]} -eq 0 ]]; then
echo "No open PRs with label '${UPDATE_LABEL}' targeting '${BASE_BRANCH}' — nothing to do."
exit 0
fi
echo "Found ${#prs[@]} candidate PR(s)."
failed=0
for pr_json in "${prs[@]}"; do
pr_number=$(echo "$pr_json" | jq -r '.number')
is_draft=$(echo "$pr_json" | jq -r '.isDraft')
head_ref=$(echo "$pr_json" | jq -r '.headRefName')
title=$(echo "$pr_json" | jq -r '.title')
echo "→ PR #${pr_number}: '${title}' (head: ${head_ref}, draft: ${is_draft})"
if gh pr update-branch "$pr_number" --repo "$GITHUB_REPOSITORY"; then
echo " ✓ PR #${pr_number} updated successfully."
else
echo " ✗ PR #${pr_number} could not be updated (may already be up to date or have a merge conflict)."
failed=$((failed + 1))
fi
done
echo "Done. Failed: ${failed}."
if [[ $failed -gt 0 ]]; then
echo "Warning: ${failed} PR(s) could not be updated — review the logs above."
fi
remove-label-on-automerge:
name: "Remove auto-update label when auto-merge is enabled"
if: github.event_name == 'pull_request' && github.event.action == 'auto_merge_enabled'
runs-on: ubuntu-latest
permissions:
pull-requests: write
env:
UPDATE_LABEL: "auto-update"
steps:
- name: "Remove '${{ env.UPDATE_LABEL }}' label from PR"
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
# Query labels first and fail explicitly if the GitHub CLI request fails.
if ! pr_labels=$(gh pr view "$PR_NUMBER" \
--repo "$GITHUB_REPOSITORY" \
--json labels \
--jq '.labels[].name'); then
echo "Failed to read labels for PR #${PR_NUMBER}."
exit 1
fi
# Treat a missing label as a normal no-op, but do not mask query failures.
if ! printf '%s\n' "$pr_labels" | grep -Fxq -- "$UPDATE_LABEL"; then
echo "PR #${PR_NUMBER} does not have the '${UPDATE_LABEL}' label — nothing to do."
exit 0
fi
echo "Removing '${UPDATE_LABEL}' label from PR #${PR_NUMBER} (auto-merge enabled)."
gh pr edit "$PR_NUMBER" \
--repo "$GITHUB_REPOSITORY" \
--remove-label "$UPDATE_LABEL"
echo "Label removed."