mirror of
https://gitea.com/gitea/docs.git
synced 2026-09-17 19:55:34 +00:00
ci: only read the Depends on lines, and let the label be the gate
This commit is contained in:
@@ -52,23 +52,34 @@ group from the `_category_.json` of its directory.
|
||||
|
||||
A page that describes a gitea change which is not merged yet must wait for it,
|
||||
otherwise the site documents something no release has. Say so in the description
|
||||
of the pull request:
|
||||
of the pull request, on a line of its own, and add the `depends-on-upstream`
|
||||
label:
|
||||
|
||||
```
|
||||
Depends on: gitea#35851
|
||||
```
|
||||
|
||||
The `depends-upstream` check reads those references (`gitea#<id>` or the full
|
||||
pull request url, several are allowed) and fails while any of them is unmerged,
|
||||
which blocks the merge since `main` requires the `checks` contexts. Add the
|
||||
`depends-on-upstream` label as well, so the pull request is easy to find; the
|
||||
label alone fails the check, it has to be accompanied by a reference.
|
||||
The label is what blocks the merge: the `depends-upstream` check fails while it
|
||||
is set, unless every dependency is verified as merged, and `main` requires the
|
||||
`checks` contexts. The check reads the `Depends on:` lines (`gitea#<id>` or the
|
||||
full pull request url, several lines are allowed) to find out what to wait for,
|
||||
so the label needs at least one of them. A `gitea#<id>` mentioned anywhere else
|
||||
in the description is ignored.
|
||||
|
||||
Without the label, a dependency that the check finds unmerged still fails it, so
|
||||
forgetting the label does not let an unreleased feature through.
|
||||
|
||||
The `unlabel merged upstream dependencies` job runs every 6 hours, removes the
|
||||
label once every referenced pull request is merged and comments on the pull
|
||||
request, which reruns the check. `scripts/check-upstream-deps.sh` is the check
|
||||
itself and can be run locally against the json of a pull request.
|
||||
|
||||
The check asks the github api whether a pull request is merged, and the runners
|
||||
share the 60 requests per hour it allows without authentication. The optional
|
||||
`GITHUB_COM_TOKEN` secret (a token without scopes is enough) raises that limit;
|
||||
without it an unverifiable dependency only fails the check when the label is
|
||||
set.
|
||||
|
||||
## Cutting a version
|
||||
|
||||
```shell
|
||||
|
||||
@@ -5,15 +5,26 @@
|
||||
# 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 in the
|
||||
# description as
|
||||
# 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 appear several times. `GITHUB_COM_TOKEN` is optional and only lifts
|
||||
# the rate limit of the unauthenticated github api, `UPSTREAM_LABEL` overrides
|
||||
# the label the check looks for.
|
||||
# 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
|
||||
|
||||
@@ -30,8 +41,16 @@ body="$(jq -r '.body // ""' "$PULL_JSON")"
|
||||
# argument cannot be named after it; `(.labels // [])` keeps it parsable there
|
||||
labelled="$(jq -r --arg want "$LABEL" '[(.labels // [])[].name] | index($want) != null' "$PULL_JSON")"
|
||||
|
||||
# every gitea#<id> and every pull request url, deduplicated
|
||||
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)"
|
||||
@@ -58,7 +77,8 @@ github_api() {
|
||||
fi
|
||||
}
|
||||
|
||||
status=0
|
||||
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)"
|
||||
@@ -70,34 +90,53 @@ for ref in $refs; do
|
||||
echo "gitea#$ref is merged"
|
||||
else
|
||||
echo "gitea#$ref is not merged yet ($(printf '%s' "$payload" | jq -r '.state'))"
|
||||
status=1
|
||||
unmerged=1
|
||||
fi
|
||||
;;
|
||||
404)
|
||||
echo "gitea#$ref is not a pull request of go-gitea/gitea, reference the pull request that adds the feature"
|
||||
status=1
|
||||
unmerged=1
|
||||
;;
|
||||
403 | 429)
|
||||
echo "the github api refused the request for gitea#$ref (rate limit?), cannot tell whether it is merged"
|
||||
status=1
|
||||
echo "gitea#$ref: the github api rejected the request (rate limit), cannot tell whether it is merged"
|
||||
unknown=1
|
||||
;;
|
||||
*)
|
||||
echo "unexpected response $code from the github api for gitea#$ref"
|
||||
status=1
|
||||
echo "gitea#$ref: unexpected response $code from the github api, cannot tell whether it is merged"
|
||||
unknown=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$status" -ne 0 ]; then
|
||||
if [ "$unknown" -eq 1 ] && [ -z "${GITHUB_COM_TOKEN:-}" ]; then
|
||||
echo
|
||||
echo "The documentation of an unreleased feature can only be merged once the"
|
||||
echo "feature itself is in gitea main. Keep the \"$LABEL\" label on this pull"
|
||||
echo "request; the scheduled job removes it and reruns this check as soon as"
|
||||
echo "every referenced pull request is merged."
|
||||
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 referenced pull request is merged, the \"$LABEL\" label can be removed"
|
||||
echo "every declared dependency is merged, the \"$LABEL\" label can be removed"
|
||||
fi
|
||||
|
||||
@@ -54,7 +54,9 @@ for index in $indexes; do
|
||||
# the check script exits 0 when every reference is merged; it needs the label
|
||||
# to be absent from its input to stay quiet about it, so drop it here
|
||||
jq 'del(.labels)' "$work/pull.json" > "$work/pull-unlabelled.json"
|
||||
if ! output="$("$here/check-upstream-deps.sh" "$work/pull-unlabelled.json" 2>&1)"; then
|
||||
# REQUIRE_VERIFIED keeps a dependency whose state could not be determined from
|
||||
# counting as merged, which would drop the label too early
|
||||
if ! output="$(REQUIRE_VERIFIED=1 "$here/check-upstream-deps.sh" "$work/pull-unlabelled.json" 2>&1)"; then
|
||||
echo "#$index still waits for upstream:"
|
||||
printf '%s\n' "$output" | sed 's/^/ /'
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user