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: - name: Prerequisites run: apk add --no-cache git curl ca-certificates jq - name: Install addlicense run: | set -e curl -fsSL -o /tmp/addlicense.tgz \ https://github.com/google/addlicense/releases/download/v1.2.0/addlicense_v1.2.0_Linux_x86_64.tar.gz tar -xzf /tmp/addlicense.tgz -C /tmp install -m 0755 /tmp/addlicense /usr/local/bin/addlicense - 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."