Files
Maestro/.gitea/workflows/license.yml
T
Admin 3220944b12 ci: make the advisory license check work on the egress-free runner
The hardened runner's job network has no internet access, so `apk add` and
downloading addlicense from GitHub cannot work. git, curl, jq and addlicense
are baked into the runner's job image (infra/gitea-runner/ci-tools.Dockerfile).
2026-10-07 23:46:08 +01:00

104 lines
3.8 KiB
YAML

name: license-headers
# Advisory license check.
#
# The Dcntrlized license bot (the webhook service in this repository) is the
# authority: it adds the missing AGPL headers in a separate commit on top of the
# pull request head and reports the `license-bot / addlicense` commit status.
# This workflow
# duplicates the check read-only so a pull request still shows an honest signal
# when the bot is unavailable. It holds no secrets, never writes, and must not
# be made a required check: Gitea evaluates a pull request's workflows from the
# head branch, so any context this job reports can be reproduced by a
# contributor who edits the workflow.
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
pull-requests: read
concurrency:
group: license-headers-${{ gitea.event.pull_request.number }}
cancel-in-progress: true
defaults:
run:
shell: sh
jobs:
addlicense:
name: addlicense
runs-on: alpine-latest
steps:
# git, curl, jq and addlicense are baked into the runner's job image
# (infra/gitea-runner/ci-tools.Dockerfile in the root repo). The job
# network has no egress, so `apk add` and downloading addlicense from
# the internet cannot work here.
- name: Check added files for an AGPL header
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
SERVER: ${{ gitea.server_url }}
REPO: ${{ gitea.repository }}
NUM: ${{ gitea.event.pull_request.number }}
HEAD_REPO: ${{ gitea.event.pull_request.head.repo.full_name }}
HEAD_REF: ${{ gitea.event.pull_request.head.ref }}
run: |
set -e
SCHEME="${SERVER%%://*}"
HOST="${SERVER#*://}"
api() { curl -fsS -H "Authorization: token $TOKEN" "$@"; }
# Every file this pull request added (paginated).
page=1
: > /tmp/added.txt
while :; do
batch="$(api "$SERVER/api/v1/repos/$REPO/pulls/$NUM/files?limit=50&page=$page")"
printf '%s' "$batch" | jq -r '.[] | select(.status=="added") | .filename' >> /tmp/added.txt
[ "$(printf '%s' "$batch" | jq 'length')" -lt 50 ] && break
page=$((page + 1))
done
if [ ! -s /tmp/added.txt ]; then
echo "This pull request adds no files; nothing to check."
exit 0
fi
# The head may be a fork: the per-run token is read-only and can
# still clone it. The scheme comes from gitea.server_url because the
# instance may be plain HTTP.
git clone --quiet --depth 1 --branch "$HEAD_REF" \
"$SCHEME://oauth2:$TOKEN@$HOST/$HEAD_REPO.git" /tmp/pr
cd /tmp/pr
# .licenseignore holds doublestar globs, not prefixes.
set --
while IFS= read -r pattern; do
case "$pattern" in ''|\#*) continue ;; esac
set -- "$@" -ignore "$pattern"
done < .licenseignore
year="$(date +%Y)"
: > /tmp/missing.txt
while IFS= read -r file; do
[ -z "$file" ] && continue
[ -e "$file" ] || continue
if ! addlicense -check -f .license-header.tpl -c Dcntrlized -y "$year" "$@" "$file" >/dev/null 2>&1; then
printf ' - %s\n' "$file" >> /tmp/missing.txt
fi
done < /tmp/added.txt
if [ -s /tmp/missing.txt ]; then
echo "::error::This pull request adds files without an AGPL-3.0 header:"
cat /tmp/missing.txt
echo ""
echo "The license bot normally adds these in a separate commit automatically."
echo "If it did not, copy the header from .license-header.tpl and push again."
exit 1
fi
echo "All added files carry an AGPL-3.0 header."