]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
CI: Enforce Squid Project review process voting (#2067)
authorAmos Jeffries <yadij@users.noreply.github.com>
Thu, 18 Dec 2025 07:22:37 +0000 (07:22 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Thu, 18 Dec 2025 07:22:47 +0000 (07:22 +0000)
Implement the Squid Project merge procedure voting criteria
documented at https://wiki.squid-cache.org/MergeProcedure#votes
as a github action that can be applied as a merge requirement.

This will make the Squid merge procedure voting apply to prevent
Anubis bot attempting to start merge checks before approval limits,
as well as disabling github UI buttons.

Also, currently we rely on Anubis bot to enforce a 48hr hold. This
hold is added to the voting criteria checked.

.github/workflows/review.yaml [new file with mode: 0644]

diff --git a/.github/workflows/review.yaml b/.github/workflows/review.yaml
new file mode 100644 (file)
index 0000000..e2264bc
--- /dev/null
@@ -0,0 +1,106 @@
+#
+# Check for the Squid Project Merge Process criteria
+# published at https://wiki.squid-cache.org/MergeProcedure#votes
+#
+name: PR Approval
+
+on:
+  schedule:
+    - cron: "10 1 * * *" # once a day
+
+  pull_request:
+    # test PRs targeting this branch code
+    branches: [ "master" ]
+
+  # allows to run this workflow manually from the Actions tab
+  workflow_dispatch:
+
+concurrency:
+  # Cancel ongoing tests in case of push to the same PR or staging branch,
+  # but let previous master commit tests complete.
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+  cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
+
+env:
+  # empty except for pull_request events
+  PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
+
+  # required for use of gh CLI tool
+  GH_TOKEN: ${{ github.token }}
+
+jobs:
+
+  Review:
+    if: ${{ github.repository }} == 'squid-cache/squid'
+    runs-on: ubuntu-24.04
+    permissions:
+      contents: read
+      pull-requests: write
+
+    steps:
+      - name: Checkout Squid sources
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 1
+
+      - name: Reviewer Veto
+        # Any Reviewer needing changes has priority hold.
+        id: core-veto
+        run: |
+          test `gh pr view ${{ github.event.pull_request.number }} --json latestReviews \
+            --template '{{range .latestReviews}}{{.state}}{{end}}' |
+            grep CHANGES_REQUESTED | wc -l` -eq 0
+
+      - name: Hold 48 hours for review
+        # Squid Project grants a delay to allow review a chance to veto new additions.
+        if: ${{ steps.fast-track.outcome }} != 'success'
+        id: early-hold
+        run: |
+          last_commit_date=$(git log -1 --format="%cd" --date=short)
+          last_commit_date_in_seconds=$(date -d "$last_commit_date" +%s)
+          current_date=$(date --utc +%Y-%m-%d)
+          current_date_in_seconds=$(date -d "$current_date" +%s)
+          test $((current_date_in_seconds - last_commit_date_in_seconds)) -gt 172800
+
+      - name: Fast Track Approval
+        # Approval from all (currently active) Squid Core team overrides 48hr hold check.
+        # Authorship is treated as implicit approval.
+        if: ${{ steps.early-hold.outcome }} = 'success'
+        id: fast-track
+        run: |
+          test `gh pr view ${{ github.event.pull_request.number }} --json author,latestReviews \
+            --template ' {{.author.login}} APPROVED {{range .latestReviews}}{{.author.login}} {{.state}} {{end}}' |
+            grep -o -E " (hno|kinkie|rousskov|yadij) APPROVED" | wc -l` -eq 3
+
+      - name: Core Team Approval
+        # Two positive votes from core developers accept the submission.
+        # Authorship is treated as implicit approval.
+        if: ${{ steps.fast-track.outcome }} != 'success'
+        id: core-approval
+        run: |
+          test `gh pr view ${{ github.event.pull_request.number }} --json author,latestReviews \
+            --template ' {{.author.login}} APPROVED {{range .latestReviews}}{{.author.login}} {{.state}} {{end}}' |
+            grep -o -E " (hno|kinkie|rousskov|yadij) APPROVED" | wc -l`
+
+      - name: Any 3 Positive Reviews
+        # Any three positive votes accept the submission.
+        # Authorship is treated as implicit approval.
+        if: ${{ steps.fast-track.outcome }} != 'success'
+        id: three-votes
+        run: |
+          test `gh pr view ${{ github.event.pull_request.number }} --json author,latestReviews \
+            --template ' {{.author.login}} APPROVED {{range .latestReviews}}{{.author.login}} {{.state}} {{end}} ' |
+            grep -o -E " APPROVED" | wc -l` -eq 3
+
+      - name: Aged 10 days without negative reviews
+        # Submissions older than 10 days without negative votes are accepted.
+        if: ${{ steps.fast-track.outcome }} != 'success' &&
+            ${{ steps.core-approval.outcome }} != 'success' &&
+            ${{ steps.three-votes.outcome }} != 'success'
+        id: old-aged
+        run: |
+          last_commit_date=$(git log -1 --format="%cd" --date=short)
+          last_commit_date_in_seconds=$(date -d "$last_commit_date" +%s)
+          current_date=$(date --utc +%Y-%m-%d)
+          current_date_in_seconds=$(date -d "$current_date" +%s)
+          test $((current_date_in_seconds - last_commit_date_in_seconds)) -gt 864000