When automating GitHub (or similar) APIs from CI/workflows, treat API access like production client code: make it correct, complete, and safely reconcilable.
Standards 1) Use the approved API client/tooling
gh api (or your org’s standard client) over raw curl to avoid missing auth headers, API version headers, and content negotiation.2) Never assume list endpoints fit in one page
gh api --paginate ... --jq ...).3) Ensure query filters match the user-facing intent
hours), the GraphQL/REST query must apply that window to all relevant connections, or explicitly document the asymmetry.4) Reconcile managed state only where provenance is knowable
desired, or intersect with last workflow-managed set).Example pattern
set -euo pipefail
# 1) Prefer gh api over curl
# gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" > release.json
# 2) Paginate list results
reviewed_users="$(gh api --paginate "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/reviews?per_page=100" \
--jq '[.[].user.login]')"
# 3) Apply filters that match inputs (conceptual)
# Ensure both issues and PRs use since/updatedAt bounds when hours is provided.
# 4) Safe reconciliation (conceptual)
# Only remove reviewers that were previously added by *this* workflow run.
# managed="$(...)" # compute current requested_reviewers
# owned="$(...)" # reviewers your workflow previously managed (tracked/provable)
# desired_owned="$(...)" # desired within owned set
# new_managed = (managed - owned) + desired_owned
Applying these rules prevents silent coverage gaps, incorrect reconciliation churn, and maintenance drift in authentication/versioning across API calls.