Skip to content

Update Bazel Files #2784

Update Bazel Files

Update Bazel Files #2784

name: Update Bazel Files
on:
workflow_run:
workflows:
- Generate Bazel Files
types:
- completed
permissions:
actions: read
contents: write
concurrency:
group: update-bazel-files-${{ github.event.workflow_run.id }}
cancel-in-progress: true
jobs:
update:
name: Update Bazel Files
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Resolve PR metadata
id: pr
shell: bash
env:
GH_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
RUN_ID: ${{ github.event.workflow_run.id }}
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
HEAD_OWNER: ${{ github.event.workflow_run.head_repository.owner.login }}
HEAD_REF: ${{ github.event.workflow_run.head_branch }}
RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
set -euo pipefail
pr_number="$(
gh api "repos/${REPOSITORY}/pulls" \
--method GET \
-f state=open \
-f head="${HEAD_OWNER}:${HEAD_REF}" \
--jq '.[0].number'
)"
if [[ -z "${pr_number}" || "${pr_number}" == "null" ]]; then
echo "Unable to resolve pull request for ${HEAD_OWNER}:${HEAD_REF}." >&2
exit 1
fi
head_repo="$(gh api "repos/${REPOSITORY}/pulls/${pr_number}" --jq '.head.repo.full_name')"
head_ref="$(gh api "repos/${REPOSITORY}/pulls/${pr_number}" --jq '.head.ref')"
pr_head_sha="$(gh api "repos/${REPOSITORY}/pulls/${pr_number}" --jq '.head.sha')"
printf 'pr_number=%s\n' "${pr_number}" >> "${GITHUB_OUTPUT}"
printf 'head_repo=%s\n' "${head_repo}" >> "${GITHUB_OUTPUT}"
printf 'head_ref=%s\n' "${head_ref}" >> "${GITHUB_OUTPUT}"
if [[ "${head_repo}" != "${REPOSITORY}" ]]; then
echo "same_repo=false" >> "${GITHUB_OUTPUT}"
else
echo "same_repo=true" >> "${GITHUB_OUTPUT}"
fi
if [[ "${pr_head_sha}" != "${RUN_HEAD_SHA}" ]]; then
echo "stale=true" >> "${GITHUB_OUTPUT}"
exit 0
fi
echo "stale=false" >> "${GITHUB_OUTPUT}"
- name: Skip stale workflow run
if: steps.pr.outputs.same_repo == 'true' && steps.pr.outputs.stale == 'true'
shell: bash
run: |
echo "Skip stale bazel update for PR #${{ steps.pr.outputs.pr_number }}."
- name: Download Fork Bazel Files Artifact
if: steps.pr.outputs.same_repo != 'true' && steps.pr.outputs.stale != 'true'
uses: actions/download-artifact@v4
with:
name: bazel-files
path: bazel-artifact
repository: ${{ github.repository }}
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Report fork PR Bazel changes
if: steps.pr.outputs.same_repo != 'true' && steps.pr.outputs.stale != 'true'
shell: bash
env:
PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
REPOSITORY: ${{ github.repository }}
RUN_ID: ${{ github.event.workflow_run.id }}
run: |
set -euo pipefail
patch_path="${PWD}/bazel-artifact/bazel.patch"
if [[ ! -f "${patch_path}" ]]; then
echo "Missing bazel.patch artifact for fork PR #${PR_NUMBER}." >&2
exit 1
fi
if [[ ! -s "${patch_path}" ]]; then
echo "No generated Bazel changes for fork PR #${PR_NUMBER}."
exit 0
fi
{
echo "Generated Bazel changes cannot be committed automatically for fork PR #${PR_NUMBER}."
echo "Run: gh run download ${RUN_ID} --repo ${REPOSITORY} --name bazel-files --dir bazel-artifact && git apply bazel-artifact/bazel.patch"
} | tee -a "${GITHUB_STEP_SUMMARY}"
exit 1
- name: Checkout PR branch
if: steps.pr.outputs.same_repo == 'true' && steps.pr.outputs.stale != 'true'
uses: actions/checkout@v6
with:
repository: ${{ steps.pr.outputs.head_repo }}
ref: ${{ steps.pr.outputs.head_ref }}
path: pr
fetch-depth: 0
token: ${{ github.token }}
persist-credentials: false
- name: Download Bazel Files Artifact
if: steps.pr.outputs.same_repo == 'true' && steps.pr.outputs.stale != 'true'
uses: actions/download-artifact@v4
with:
name: bazel-files
path: bazel-artifact
repository: ${{ github.repository }}
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Apply Bazel Files Artifact
if: steps.pr.outputs.same_repo == 'true' && steps.pr.outputs.stale != 'true'
shell: bash
run: |
set -euo pipefail
patch_path="${PWD}/bazel-artifact/bazel.patch"
summary="$(git -C pr apply --summary "${patch_path}")"
while IFS= read -r line; do
case "${line}" in
" rename "*|" copy "*)
echo "Unsupported patch summary: ${line}" >&2
exit 1
;;
esac
done <<< "${summary}"
declare -A seen_paths=()
while IFS= read -r -d '' record; do
if [[ -z "${record}" ]]; then
continue
fi
IFS=$'\t' read -r _ _ path <<< "${record}"
case "${path}" in
""|/*|..|../*|*/..|*/../*)
echo "Unexpected patch path: ${path}" >&2
exit 1
;;
build/BUILD.bazel|build/*/BUILD.bazel)
;;
WORKSPACE|WORKSPACE.bazel|build|build/*)
echo "Unsafe patch path: ${path}" >&2
exit 1
;;
DEPS.bzl|*.bazel|*.bzl)
;;
*)
echo "Unexpected patch path: ${path}" >&2
exit 1
;;
esac
if [[ -n "${seen_paths[${path}]:-}" ]]; then
echo "Duplicate patch path: ${path}" >&2
exit 1
fi
seen_paths["${path}"]=1
done < <(git -C pr apply --numstat -z "${patch_path}")
git -C pr apply --check --index "${patch_path}"
git -C pr apply --index "${patch_path}"
- name: Commit Bazel Files
if: steps.pr.outputs.same_repo == 'true' && steps.pr.outputs.stale != 'true'
shell: bash
env:
HEAD_REF: ${{ steps.pr.outputs.head_ref }}
PUSH_TOKEN: ${{ github.token }}
TARGET_REPOSITORY: ${{ steps.pr.outputs.head_repo }}
run: |
set -euo pipefail
if git -C pr diff --cached --quiet -- DEPS.bzl ':(glob)**/*.bazel' ':(glob)**/*.bzl'; then
echo "No generated Bazel changes to commit."
exit 0
fi
git -C pr config user.name "Ti Chi Robot"
git -C pr config user.email "ti-community-prow-bot@tidb.io"
git -C pr commit -m "chore: update bazel file"
git -C pr push "https://x-access-token:${PUSH_TOKEN}@github.com/${TARGET_REPOSITORY}.git" "HEAD:${HEAD_REF}"