mirror of
https://gitea.com/gitea/docs.git
synced 2026-09-17 19:55:34 +00:00
143 lines
4.8 KiB
Bash
Executable File
143 lines
4.8 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Fails when a pull request depends on a gitea change that is not merged yet.
|
|
#
|
|
# Usage: ./scripts/check-upstream-deps.sh <pull request json>
|
|
#
|
|
# The json is what the gitea api returns for a pull request; the script reads
|
|
# the description and the labels from it. A dependency is declared on a line of
|
|
# its own in the description:
|
|
#
|
|
# Depends on: gitea#35851
|
|
# Depends on: https://github.com/go-gitea/gitea/pull/35851
|
|
#
|
|
# and may be declared several times. Only such lines count, so a pull request
|
|
# that merely mentions gitea#35851 in prose is not held back.
|
|
#
|
|
# The `depends-on-upstream` label is what blocks the merge: it fails the check
|
|
# unless every declared dependency is verified as merged. Without the label, a
|
|
# dependency that is known to be unmerged still fails, so a forgotten label does
|
|
# not let an unreleased feature through.
|
|
#
|
|
# Exit codes: 0 nothing blocks, 1 blocked, 2 usage.
|
|
#
|
|
# Environment:
|
|
# GITHUB_COM_TOKEN optional, lifts the rate limit of the github api
|
|
# UPSTREAM_LABEL label to look for, `depends-on-upstream` by default
|
|
# REQUIRE_VERIFIED set to 1 to also fail when the state cannot be determined
|
|
|
|
set -euo pipefail
|
|
|
|
LABEL="${UPSTREAM_LABEL:-depends-on-upstream}"
|
|
PULL_JSON="${1:-}"
|
|
|
|
if [ -z "$PULL_JSON" ] || [ ! -f "$PULL_JSON" ]; then
|
|
echo "usage: $0 <pull request json>" >&2
|
|
exit 2
|
|
fi
|
|
|
|
body="$(jq -r '.body // ""' "$PULL_JSON")"
|
|
# `label` is a keyword in jq 1.6, which is what the runner image has, so the
|
|
# argument cannot be named after it; `(.labels // [])` keeps it parsable there
|
|
labelled="$(jq -r --arg want "$LABEL" '[(.labels // [])[].name] | index($want) != null' "$PULL_JSON")"
|
|
|
|
require_verified="${REQUIRE_VERIFIED:-0}"
|
|
if [ "$labelled" = 'true' ]; then
|
|
# the label says the pull request is not ready, so an unverifiable dependency
|
|
# keeps it blocked instead of letting it through
|
|
require_verified=1
|
|
fi
|
|
|
|
# the ids of the `Depends on:` lines, deduplicated
|
|
refs="$(printf '%s\n' "$body" \
|
|
| grep -iE '^[[:space:]]*depends[ _-]?on[[:space:]]*:' \
|
|
| grep -oiE 'gitea#[0-9]+|github\.com/go-gitea/gitea/pull/[0-9]+' \
|
|
| grep -oE '[0-9]+' \
|
|
| sort -un || true)"
|
|
|
|
if [ -z "$refs" ]; then
|
|
if [ "$labelled" = 'true' ]; then
|
|
echo "This pull request carries the \"$LABEL\" label but does not say what it"
|
|
echo "depends on. Add a line to the description, for example:"
|
|
echo
|
|
echo " Depends on: gitea#35851"
|
|
exit 1
|
|
fi
|
|
echo "no upstream dependency declared"
|
|
exit 0
|
|
fi
|
|
|
|
github_api() {
|
|
local url="$1"
|
|
if [ -n "${GITHUB_COM_TOKEN:-}" ]; then
|
|
curl --silent --show-error --write-out '\n%{http_code}' \
|
|
-H "Authorization: Bearer $GITHUB_COM_TOKEN" "$url"
|
|
else
|
|
curl --silent --show-error --write-out '\n%{http_code}' "$url"
|
|
fi
|
|
}
|
|
|
|
unmerged=0
|
|
unknown=0
|
|
for ref in $refs; do
|
|
response="$(github_api "https://api.github.com/repos/go-gitea/gitea/pulls/$ref")"
|
|
code="$(printf '%s' "$response" | tail -n 1)"
|
|
payload="$(printf '%s' "$response" | sed '$d')"
|
|
|
|
case "$code" in
|
|
200)
|
|
if [ "$(printf '%s' "$payload" | jq -r '.merged')" = 'true' ]; then
|
|
echo "gitea#$ref is merged"
|
|
else
|
|
echo "gitea#$ref is not merged yet ($(printf '%s' "$payload" | jq -r '.state'))"
|
|
unmerged=1
|
|
fi
|
|
;;
|
|
404)
|
|
echo "gitea#$ref is not a pull request of go-gitea/gitea, reference the pull request that adds the feature"
|
|
unmerged=1
|
|
;;
|
|
403 | 429)
|
|
echo "gitea#$ref: the github api rejected the request (rate limit), cannot tell whether it is merged"
|
|
unknown=1
|
|
;;
|
|
*)
|
|
echo "gitea#$ref: unexpected response $code from the github api, cannot tell whether it is merged"
|
|
unknown=1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "$unknown" -eq 1 ] && [ -z "${GITHUB_COM_TOKEN:-}" ]; then
|
|
echo
|
|
echo "The github api allows 60 unauthenticated requests per hour and address,"
|
|
echo "which the runners share. Set the GITHUB_COM_TOKEN secret to a token with"
|
|
echo "no scopes to raise that limit."
|
|
fi
|
|
|
|
if [ "$unmerged" -eq 1 ] || { [ "$unknown" -eq 1 ] && [ "$require_verified" = '1' ]; }; then
|
|
echo
|
|
if [ "$labelled" = 'true' ]; then
|
|
echo "This pull request is labelled \"$LABEL\", so it stays blocked until every"
|
|
echo "dependency above is merged into gitea main. The scheduled job removes the"
|
|
echo "label and reruns this check as soon as that is the case."
|
|
else
|
|
echo "The documentation of an unreleased feature can only be merged once the"
|
|
echo "feature itself is in gitea main. Add the \"$LABEL\" label so the pull"
|
|
echo "request is picked up by the job that watches for it."
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$unknown" -eq 1 ]; then
|
|
echo
|
|
echo "Could not verify every dependency, letting the check pass: the pull request"
|
|
echo "does not carry the \"$LABEL\" label."
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$labelled" = 'true' ]; then
|
|
echo
|
|
echo "every declared dependency is merged, the \"$LABEL\" label can be removed"
|
|
fi
|