diff --git a/.github/workflows/check-required-reviews.yml b/.github/workflows/check-required-reviews.yml new file mode 100644 index 000000000..d4be5b085 --- /dev/null +++ b/.github/workflows/check-required-reviews.yml @@ -0,0 +1,56 @@ +name: Check required reviews + +on: + pull_request_review: + types: [submitted] + +jobs: + check-reviews: + if: contains(github.event.pull_request.labels.*.name, 'full_review') + runs-on: ubuntu-latest + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Check reviews + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: python + run: | + """Check there are enough approving reviews.""" + import json + import os + import re + import subprocess + import sys + + REQUIRED_REVIEWS = 2 + + repo = "${{ github.repository }}" + pr_number = "${{ github.event.pull_request.number }}" + + # Get info on PR labels and reviews. + pr_info = json.loads( + subprocess.run( + ("gh", "pr", "--json", "reviews", "--repo", repo, "view", pr_number), + check=True, + capture_output=True, + timeout=60, + text=True, + ).stdout + ) + + # Check for enough reviews. Newer reviews invalidate older ones. + approving_reviewers = set() + for review in sorted(pr_info["reviews"], key=lambda r: r["submittedAt"]): + if review["state"] == "APPROVED": + approving_reviewers.add(review["author"]["login"]) + elif review["state"] == "CHANGES_REQUESTED": + approving_reviewers.discard(review["author"]["login"]) + + if len(approving_reviewers) < REQUIRED_REVIEWS: + print(f"\033[31m❌ Not enough reviews.\033[0m ({len(approving_reviewers)}/{REQUIRED_REVIEWS})") + sys.exit(1) + print(f"\033[32m✔ Sufficient reviews.\033[0m ({len(approving_reviewers)}/{REQUIRED_REVIEWS})") diff --git a/.github/workflows/conda-lock.yml b/.github/workflows/conda-lock.yml index 3deed92f8..2c427efce 100644 --- a/.github/workflows/conda-lock.yml +++ b/.github/workflows/conda-lock.yml @@ -50,7 +50,7 @@ jobs: - name: Create pull requests env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if $(sha256sum --status -c ${{ runner.temp }}/lock_file_hashes); then echo "Lock files unchanged. Skipping pull request..." diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index b3ecc6b23..f9023cce5 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -34,7 +34,7 @@ jobs: - name: Create pull requests env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if $(sha256sum --status -c ${{ runner.temp }}/config_file_hashes); then echo "Config file unchanged. Skipping pull request..." diff --git a/.github/workflows/pull_request_checks.yml b/.github/workflows/pull_request_checks.yml index 66c4ab59e..067f8ee1f 100644 --- a/.github/workflows/pull_request_checks.yml +++ b/.github/workflows/pull_request_checks.yml @@ -66,7 +66,7 @@ jobs: coverage html - name: Add report to PR env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # This links to a hosted version of the HTML report. tar -czf coverage-report.tar.gz htmlcov/