diff --git a/.github/workflows/checkAuditRequired.yml b/.github/workflows/checkAuditRequired.yml new file mode 100644 index 000000000..fd0fce09e --- /dev/null +++ b/.github/workflows/checkAuditRequired.yml @@ -0,0 +1,117 @@ +# Audit Requirement Checker +# - checks if an audit is required for a given PR +# - an audit is required if any .sol file in path 'src/' has been modified or added +# - if audit is required, the action will assign the label "AuditRequired", otherwise it will assign label "AuditNotRequired" +# - it will also make sure that at the end, exactly one of these two labels is indeed assigned + +name: Audit Requirement Check + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check-audit-required: + if: ${{ github.event.pull_request.draft == false }} # will only run once the PR is in "Ready for Review" state + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 ##### Fetch all history for all branches + + - name: Remove existing 'AuditRequired' and 'AuditNotRequired' labels + uses: actions-ecosystem/action-remove-labels@v1 + with: + github_token: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }} + labels: | + AuditRequired + AuditNotRequired + number: ${{ github.event.pull_request.number }} + + - name: Check Git Diff for protected contracts + id: check_eligibility + run: | + + ##### get all files modified by this PR + FILES=$(git diff --name-only origin/main HEAD) + + ##### make sure that there are modified files + if [[ -z $FILES ]]; then + echo -e "\033[31mNo files found. This should not happen. Please check the code of the Github action. Aborting now.\033[0m" + echo "CONTINUE=false" >> $GITHUB_ENV + fi + + ##### Initialize empty variables + PROTECTED_CONTRACTS="" + + ##### go through all modified file names/paths and identify contracts with path 'src/*' + while IFS= read -r FILE; do + if echo "$FILE" | grep -E '^src/.*\.sol$'; then + ##### contract found + PROTECTED_CONTRACTS="${PROTECTED_CONTRACTS}${FILE}"$'\n' + fi + done <<< "$FILES" + + ##### if none found, exit here as there is nothing to do + if [[ -z "$PROTECTED_CONTRACTS" ]]; then + echo -e "\033[32mNo protected contracts found in Git Diff.\033[0m" + echo -e "\033[32mAssigning label 'AuditNotRequired' to this PR.\033[0m" + echo "AUDIT_REQUIRED=false" >> $GITHUB_ENV + exit 0 + else + echo -e "\033[31mProtected contracts found in Git Diff.\033[0m" + echo -e "\033[31mAssigning label 'AuditRequired' to this PR.\033[0m" + echo "AUDIT_REQUIRED=true" >> $GITHUB_ENV + fi + + echo "PROTECTED_CONTRACTS: $PROTECTED_CONTRACTS" + + ##### Write filenames to temporary files (using variables here was causing issues due to the file names) + echo -e "$PROTECTED_CONTRACTS" > protected_contracts.txt + + - name: Assign correct label based on check outcome + uses: actions-ecosystem/action-add-labels@v1 + id: assign_label + with: + github_token: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }} # we use the token of the git action user so the label protection check will pass + labels: ${{ env.AUDIT_REQUIRED == 'true' && 'AuditRequired' || 'AuditNotRequired' }} # if the action made it until here and CONTINUE was true then all checks passed. It CONTINUE was false then no audit is required + number: ${{ github.event.pull_request.number }} + + - name: Verify label assignments (make sure exactly one of the two labels is assigned) + env: + GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }} + run: | + + echo "Fetching currently assigned labels..." + assigned_labels=$(gh pr view ${{ github.event.pull_request.number }} --json labels --jq '.labels | map(.name) | .[]') + + echo "Assigned labels: $assigned_labels" + + audit_required_assigned=0 + audit_not_required_assigned=0 + + ##### go through all assigned labels and count how many protected labels are found + for label in $assigned_labels; do + if [ "$label" = "AuditRequired" ]; then + audit_required_assigned=$((audit_required_assigned + 1)) + elif [ "$label" = "AuditNotRequired" ]; then + audit_not_required_assigned=$((audit_not_required_assigned + 1)) + fi + done + + total_labels_assigned=$((audit_required_assigned + audit_not_required_assigned)) + echo "Total labels assigned: $total_labels_assigned" + + ##### make sure that exactly (only) one protected label is assigned + if [ "$total_labels_assigned" -ne 1 ]; then + echo -e "\033[31mError: Exactly one of the two labels should be assigned but found $total_labels_assigned assigned labels.\033[0m" + exit 1 + else + echo -e "\033[32mVerified that exactly one label is assigned.\033[0m" + echo -e "\033[32mAll good :)\033[0m" + fi + + echo -e "\033[31mGit Action completed successfully\033[0m"