mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
Refactor PR label workflow to require an approved review from a non-author with write access for ECR artifact builds, enhancing TOCTOU protection and clarifying approval requirements in error messages.
Some checks failed
Unit Tests: Caching (Redis) / caching-redis (push) Has been cancelled
Unit Tests: Proxy DB Operations / assert-shard-coverage (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
Unit Tests: Proxy DB Operations / auth-checks (push) Has been cancelled
Unit Tests: Proxy DB Operations / budgets (push) Has been cancelled
Unit Tests: Proxy DB Operations / custom-logging (push) Has been cancelled
Unit Tests: Proxy DB Operations / db-and-spend (push) Has been cancelled
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Has been cancelled
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Has been cancelled
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Has been cancelled
Unit Tests: Proxy DB Operations / key-generation (push) Has been cancelled
Unit Tests: Proxy DB Operations / logging-misc (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-runtime (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-server-core (push) Has been cancelled
Unit Tests: Proxy DB Operations / schema-migration (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-utils (push) Has been cancelled
Some checks failed
Unit Tests: Caching (Redis) / caching-redis (push) Has been cancelled
Unit Tests: Proxy DB Operations / assert-shard-coverage (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
Unit Tests: Proxy DB Operations / auth-checks (push) Has been cancelled
Unit Tests: Proxy DB Operations / budgets (push) Has been cancelled
Unit Tests: Proxy DB Operations / custom-logging (push) Has been cancelled
Unit Tests: Proxy DB Operations / db-and-spend (push) Has been cancelled
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Has been cancelled
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Has been cancelled
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Has been cancelled
Unit Tests: Proxy DB Operations / key-generation (push) Has been cancelled
Unit Tests: Proxy DB Operations / logging-misc (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-runtime (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-server-core (push) Has been cancelled
Unit Tests: Proxy DB Operations / schema-migration (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-utils (push) Has been cancelled
This commit is contained in:
parent
a803471270
commit
fa26228394
1 changed files with 42 additions and 24 deletions
66
.github/workflows/pr-label-build-artifact.yml
vendored
66
.github/workflows/pr-label-build-artifact.yml
vendored
|
|
@ -1,9 +1,10 @@
|
|||
# Builds and pushes the LiteLLM database image to ECR when a maintainer applies
|
||||
# `build-ecr-artifact-` + the first 5 hexadecimal characters of the PR head commit
|
||||
# (lowercase), e.g. head e21326b… → label `build-ecr-artifact-e2132`.
|
||||
# the `build-ecr-artifact` label.
|
||||
#
|
||||
# Weaker than full-SHA or PR-approval gates: 5 hex chars can collide across commits;
|
||||
# add an approval check later if you need stronger TOCTOU protection.
|
||||
# TOCTOU mitigation: GitHub stores commit_id on each review. The workflow requires
|
||||
# at least one APPROVED review whose commit_id matches the current PR head, from a
|
||||
# reviewer who is not the PR author and has write+ access. If the branch is
|
||||
# force-pushed, re-approve the new tip before labeling.
|
||||
name: PR Build Artifact
|
||||
|
||||
on:
|
||||
|
|
@ -29,14 +30,16 @@ jobs:
|
|||
|
||||
# Least privilege for this job only (HIGH fix: job-scoped id-token, not workflow).
|
||||
# - contents: read — checkout + collaborator permission API for the actor check
|
||||
# - pull-requests: read — list PR reviews (commit_id for approval gate)
|
||||
# - id-token: write — mint OIDC JWT for AWS role assumption (no long-lived keys)
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
id-token: write
|
||||
|
||||
if: >
|
||||
github.event.action == 'labeled' &&
|
||||
startsWith(github.event.label.name, 'build-ecr-artifact-') &&
|
||||
github.event.label.name == 'build-ecr-artifact' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
env:
|
||||
AWS_REGION: ${{ vars.AWS_REGION }}
|
||||
|
|
@ -44,30 +47,45 @@ jobs:
|
|||
ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }}
|
||||
|
||||
steps:
|
||||
- name: Verify label prefix matches first 5 hex chars of PR head
|
||||
- name: Verify PR head has maintainer approval on this commit
|
||||
env:
|
||||
LABEL_NAME: ${{ github.event.label.name }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
run: |
|
||||
prefix="build-ecr-artifact-"
|
||||
suffix="${LABEL_NAME#"${prefix}"}"
|
||||
if [[ "${LABEL_NAME}" == "${suffix}" ]]; then
|
||||
echo "::error::Label must be ${prefix}<first-5-hex-chars-of-head-sha> (e.g. ${prefix}e2132 for tip starting with e21326…)."
|
||||
exit 1
|
||||
fi
|
||||
lc_head="$(printf '%s' "${HEAD_SHA}" | tr '[:upper:]' '[:lower:]')"
|
||||
head5="${lc_head:0:5}"
|
||||
lc_suffix="$(printf '%s' "${suffix}" | tr '[:upper:]' '[:lower:]')"
|
||||
if [[ "${#lc_suffix}" -ne 5 ]]; then
|
||||
echo "::error::Expected exactly 5 hex characters after '${prefix}', got length ${#lc_suffix}."
|
||||
mapfile -t reviewers < <(gh api "/repos/${REPOSITORY}/pulls/${PR_NUMBER}/reviews" --paginate \
|
||||
--jq --arg sha "${lc_head}" --arg author "${PR_AUTHOR}" -r '
|
||||
[ .[]
|
||||
| select(.state == "APPROVED")
|
||||
| select((.commit_id // "") | ascii_downcase == $sha)
|
||||
| select(.user.login != null)
|
||||
| select(.user.login != $author)
|
||||
| .user.login
|
||||
] | unique | .[]')
|
||||
|
||||
if [[ "${#reviewers[@]}" -eq 0 ]] || [[ -z "${reviewers[0]:-}" ]]; then
|
||||
echo "::error::Need an APPROVED review on the current head (${HEAD_SHA}) from someone other than the PR author. If the branch changed, approve again, then apply the label."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${lc_suffix}" =~ ^[0-9a-f]{5}$ ]]; then
|
||||
echo "::error::Suffix must be 5 hexadecimal characters."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${lc_suffix}" != "${head5}" ]]; then
|
||||
echo "::error::Label suffix '${lc_suffix}' does not match head prefix '${head5}' (full head ${HEAD_SHA}). Update or recreate the label."
|
||||
|
||||
found=0
|
||||
for login in "${reviewers[@]}"; do
|
||||
[[ -z "${login}" ]] && continue
|
||||
perm="$(gh api "/repos/${REPOSITORY}/collaborators/${login}/permission" --jq '.permission')"
|
||||
case "${perm}" in
|
||||
admin|maintain|write)
|
||||
echo "Qualifying approval: ${login} (${perm}) on ${HEAD_SHA}"
|
||||
found=1
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "${found}" -ne 1 ]]; then
|
||||
echo "::error::Approvals on this commit were found, but no approver has write, maintain, or admin."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
@ -158,5 +176,5 @@ jobs:
|
|||
echo "- Head SHA: \`${PR_HEAD_SHA}\`"
|
||||
echo "- **Immutable** image URI (pin by digest in production): \`${TRACE_URI}\`"
|
||||
echo
|
||||
echo "Label format: \`build-ecr-artifact-\` + first 5 hex chars of head (lowercase)."
|
||||
echo "Requires label \`build-ecr-artifact\` and an **Approve** on the current head from a non-author reviewer with write+ access."
|
||||
} >> "${GITHUB_STEP_SUMMARY}"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue