--- /dev/null
+#
+# 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