diff --git a/.github/workflows/backend-pr-approver.yml b/.github/workflows/backend-pr-approver.yml index 6f0c5cbf15c..0240787eeb0 100644 --- a/.github/workflows/backend-pr-approver.yml +++ b/.github/workflows/backend-pr-approver.yml @@ -1,13 +1,31 @@ name: Backend PR Approver on: - workflow_run: - workflows: - - "Backend PR Labeler" - types: [completed] + pull_request: + types: [labeled, unlabeled] jobs: - say-hi: + check-approval-labels: + name: Confirm Backend Approval + if: github.event.label.name == 'require-backend-approval' || github.event.label.name == 'ready-for-backend-review' runs-on: ubuntu-latest steps: - - name: Say Hi + - name: Check for exemption + id: check_exemption run: | - echo "Hi" + if [ ! ${{ contains(toJSON(github.event.pull_request.requested_teams.*.name), 'backend-review-group') }} ]; then + echo "exempt=true" >> $GITHUB_OUTPUT + echo "PR is exempt from backend approval." + else + echo "exempt=false" >> $GITHUB_OUTPUT + echo "PR requires backend approval." + fi + + - name: Check for backend approval + id: check_approval + if: ${{ steps.check_exemption.outputs.exempt == 'false' }} + run: | + if [ ${{ contains(toJSON(github.event.pull_request.labels.*.name), 'require-backend-approval') && contains(toJSON(github.event.pull_request.labels.*.name), 'ready-for-backend-review') }} ]; then + echo "Pull Request missing approval." + exit 1 + else + echo "Pull Request approved." + fi diff --git a/.github/workflows/backend-pr-labeler.yml b/.github/workflows/backend-pr-labeler.yml index cfbe257a6af..78e49bee54a 100644 --- a/.github/workflows/backend-pr-labeler.yml +++ b/.github/workflows/backend-pr-labeler.yml @@ -74,7 +74,7 @@ jobs: pr_labels: ${{ needs.get-pr-data.outputs.pr_labels }} pr_requested_teams: ${{ needs.get-pr-data.outputs.pr_requested_teams }} outputs: - test_status: ${{ steps.get_code_checks_conclusion.outputs.test_status }} + test_result: ${{ steps.get_code_checks_conclusion.outputs.test_result }} exempt: ${{ steps.check_exemption.outputs.exempt }} failures_detected: ${{ steps.audit_pr_labels.outputs.failures_detected }} steps: @@ -86,8 +86,8 @@ jobs: - name: Get Code Checks result if: github.event_name == 'workflow_run' run: | - echo "test_status=${{ github.event.workflow_run.conclusion }}" >> $GITHUB_OUTPUT - echo "test_status: ${{ github.event.workflow_run.conclusion }}" + echo "test_result=${{ github.event.workflow_run.conclusion }}" >> $GITHUB_OUTPUT + echo "test_result: ${{ github.event.workflow_run.conclusion }}" - name: Check for exemption id: check_exemption @@ -107,8 +107,7 @@ jobs: ${{ contains(env.pr_labels, 'code-health-failure') }} || \ ${{ contains(env.pr_labels, 'codeowners-addition-failure') }} || \ ${{ contains(env.pr_labels, 'codeowners-delete-failure') }} || \ - ${{ contains(env.pr_labels, 'lint-failure') }} || \ - ${{ contains(env.pr_labels, 'test-failure') }} ; then + ${{ contains(env.pr_labels, 'lint-failure') }} ; then echo "failures_detected=true" >> $GITHUB_OUTPUT echo "Failure labels detected." else @@ -190,7 +189,7 @@ jobs: pr_number: ${{ needs.get-pr-data.outputs.pr_number }} pr_draft: ${{ needs.get-pr-data.outputs.pr_draft }} pr_labels: ${{ needs.get-pr-data.outputs.pr_labels }} - test_status: ${{ needs.check-pr-status.outputs.test_status }} + test_result: ${{ needs.check-pr-status.outputs.test_result }} failures_detected: ${{ needs.check-pr-status.outputs.failures_detected }} approval_status: ${{ needs.check-approvals.outputs.approval_status }} steps: @@ -201,6 +200,66 @@ jobs: echo ${{ env.pr_number }} echo ${{ env.pr_draft }} echo ${{ env.pr_labels }} - echo ${{ env.test_status }} + echo ${{ env.test_result }} echo ${{ env.failures_detected }} echo ${{ env.approval_status }} + + # Remove labels if required + - name: Remove require-backend-approval label + if: ${{ env.exempt == 'true' && contains(env.pr_labels, 'require-backend-approval') }} + uses: actions-ecosystem/action-remove-labels@v1 + with: + number: ${{ env.pr_number }} + labels: require-backend-approval + + - name: Remove ready-for-backend-review label + if: | + (env.pr_draft || env.test_result == 'failure' || env.failures_detected == 'true' || env.approval_status == 'confirmed') && + contains(env.pr_labels, 'ready-for-backend-review') + uses: actions-ecosystem/action-remove-labels@v1 + with: + number: ${{ env.pr_number }} + labels: ready-for-backend-review + + - name: Remove test-passing label + if: ${{ env.test_result == 'failure' && contains(fromJSON(env.pr_labels), 'test-passing') }} + uses: actions-ecosystem/action-remove-labels@v1 + with: + number: ${{ env.pr_number }} + labels: test-passing + + - name: Remove test-failure label + if: ${{ env.test_result == 'success' && contains(fromJSON(env.pr_labels), 'test-failure') }} + uses: actions-ecosystem/action-remove-labels@v1 + with: + number: ${{ env.pr_number }} + labels: test-failure + + # Add labels if required + - name: Add require-backend-approval label + if: ${{ env.exempt == 'false'}} + uses: actions-ecosystem/action-add-labels@v1 + with: + number: ${{ env.pr_number }} + labels: require-backend-approval + + - name: Add ready-for-backend-review label + if: ${{ env.test_result == 'success' && env.failures_detected == 'false' && env.approval_status == 'required' }} + uses: actions-ecosystem/action-add-labels@v1 + with: + number: ${{ env.pr_number }} + labels: ready-for-backend-review + + - name: Add test-failure label + if: ${{ env.test_result == 'failure' }} + uses: actions-ecosystem/action-add-labels@v1 + with: + number: ${{ env.pr_number }} + labels: test-failure + + - name: Add test-passing label + if: ${{ env.test_result == 'success' }} + uses: actions-ecosystem/action-add-labels@v1 + with: + number: ${{ env.pr_number }} + labels: test-passing diff --git a/.github/workflows/be_review_prs.yml b/.github/workflows/be_review_prs.yml deleted file mode 100644 index b0bf256d2f1..00000000000 --- a/.github/workflows/be_review_prs.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: Require backend-review-group approval -on: - pull_request: - types: [opened, reopened, review_requested, synchronize, ready_for_review] - pull_request_review: - types: [submitted] - -jobs: - check-approval-requirements: - permissions: write-all - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4.0.2 - with: - aws-access-key-id: ${{ secrets.aws_access_key_id }} - aws-secret-access-key: ${{ secrets.aws_secret_access_key }} - aws-region: "us-gov-west-1" - - - name: Get bot token from Parameter Store - uses: marvinpinto/action-inject-ssm-secrets@latest - with: - ssm_parameter: /devops/VA_VSP_BOT_GITHUB_TOKEN - env_variable_name: VA_VSP_BOT_GITHUB_TOKEN - - -# Find Backend Labels, Approvals and Comments - - name: Find Approval Comment - uses: peter-evans/find-comment@v3 - id: find_backend_approval_comment - with: - issue-number: ${{ github.event.pull_request.number }} - body-includes: Backend-review-group approval confirmed. - - - name: Get backend-review-group members - if: contains(github.event.pull_request.labels.*.name, 'require-backend-approval') - id: get_team_members - uses: octokit/request-action@v2.x - with: - route: GET /orgs/department-of-veterans-affairs/teams/backend-review-group/members - env: - GITHUB_TOKEN: ${{ env.VA_VSP_BOT_GITHUB_TOKEN }} - - - name: Check backend-review-group approval status - if: contains(github.event.pull_request.labels.*.name, 'require-backend-approval') - id: check_backend_review_group_approval_status - uses: octokit/request-action@v2.x - with: - route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number || github.event.pull_request_review.pull_request.number }}/reviews - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Verify backend-review-group approval - if: contains(github.event.pull_request.labels.*.name, 'require-backend-approval') - id: verify_approval - run: | - BACKEND_REVIEWERS=$(cat <<'EOF' | jq -r '.[].login' | tr '\n' '|' | sed 's/|$//' - ${{ steps.get_team_members.outputs.data }} - EOF - ) - - APPROVALS=$(cat <<'EOF' | jq -r '.[] | select(.state == "APPROVED") | .user.login' | grep -iE "$BACKEND_REVIEWERS" | wc -l - ${{ steps.check_backend_review_group_approval_status.outputs.data }} - EOF - ) - - echo "Number of backend-review-group approvals: $APPROVALS" - if [ "$APPROVALS" -eq 0 ]; then - echo "approval_status=required" >> $GITHUB_OUTPUT - exit 1 - else - echo "approval_status=confirmed" >> $GITHUB_OUTPUT - fi - - - name: Comment PR - Approval Confirmed - if: success() && steps.verify_approval.outputs.approval_status == 'confirmed' && steps.find_backend_approval_comment.outputs.comment-id == '' - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{ github.event.pull_request.number }} - body: "Backend-review-group approval confirmed." - - - name: Remove ready-for-review label - if: success() && steps.verify_approval.outputs.approval_status == 'confirmed' && contains(github.event.pull_request.labels.*.name, 'ready-for-backend-review') - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - ready-for-backend-review diff --git a/.github/workflows/check_codeowners.yml b/.github/workflows/check_codeowners.yml index d5bcd26a9e5..bda03af1510 100644 --- a/.github/workflows/check_codeowners.yml +++ b/.github/workflows/check_codeowners.yml @@ -64,7 +64,7 @@ jobs: - name: Remove Failure label uses: actions-ecosystem/action-remove-labels@v1 - if: ${{ success() }} + if: ${{ success() && contains(github.event.pull_request.labels.*.name, 'codeowners-addition-failure') }} with: number: ${{ github.event.pull_request.number }} labels: | diff --git a/.github/workflows/code_checks.yml b/.github/workflows/code_checks.yml index bce18493148..3dff818526e 100644 --- a/.github/workflows/code_checks.yml +++ b/.github/workflows/code_checks.yml @@ -21,14 +21,6 @@ jobs: with: bundler-cache: true - - name: Remove Review label - if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ready-for-backend-review') - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - ready-for-backend-review - - name: Run bundle-audit (checks gems for CVE issues) run: bundle exec bundle-audit check --update --ignore CVE-2024-27456 @@ -92,22 +84,6 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Remove Review label - if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ready-for-backend-review') - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - ready-for-backend-review - - - name: Remove Test Passing label - if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'test-passing') - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - test-passing - - name: Build Docker Image uses: docker/build-push-action@v6 env: @@ -155,70 +131,6 @@ jobs: path: log/*.xml if-no-files-found: ignore - - name: Add Test Failure label - if: failure() && github.event_name == 'pull_request' - uses: actions-ecosystem/action-add-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - test-failure - - - name: Remove Test Failure label - if: success() && github.event_name == 'pull_request' - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - test-failure - - - name: Add Test Passing label - if: success() && github.event_name == 'pull_request' - uses: actions-ecosystem/action-add-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - test-passing - - - name: Add omit-backend-approval label - if: | - github.event_name == 'pull_request' && github.event.pull_request.draft == false && - ( - contains(toJSON(github.event.pull_request.requested_teams.*.name), 'mobile') || - contains(toJSON(github.event.pull_request.requested_teams.*.name), 'lighthouse') || - contains(toJSON(github.event.pull_request.requested_teams.*.name), 'identity') - ) - uses: actions-ecosystem/action-add-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - omit-backend-approval - - - name: Add require-backend-approval label - uses: actions-ecosystem/action-add-labels@v1 - if: | - github.event_name == 'pull_request' && github.event.pull_request.draft == false && - !contains(toJSON(github.event.pull_request.requested_teams.*.name), 'mobile') && - !contains(toJSON(github.event.pull_request.requested_teams.*.name), 'lighthouse') && - !contains(toJSON(github.event.pull_request.requested_teams.*.name), 'identity') - with: - number: ${{ github.event.pull_request.number }} - labels: | - require-backend-approval - - - name: Add Review label - uses: actions-ecosystem/action-add-labels@v1 - if: | - github.event_name == 'pull_request' && success() && github.event.pull_request.draft == false && - !contains(github.event.pull_request.labels.*.name, 'code-health-failure') && - !contains(github.event.pull_request.labels.*.name, 'codeowners-addition-failure') && - !contains(github.event.pull_request.labels.*.name, 'codeowners-delete-failure') && - !contains(github.event.pull_request.labels.*.name, 'lint-failure') && - !contains(github.event.pull_request.labels.*.name, 'test-failure') - with: - number: ${{ github.event.pull_request.number }} - labels: | - ready-for-backend-review - publish_results: name: Publish Test Results and Coverage if: always() diff --git a/.github/workflows/ready_for_review.yml b/.github/workflows/ready_for_review.yml deleted file mode 100644 index 35a76b6e6fc..00000000000 --- a/.github/workflows/ready_for_review.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: Pull Request Ready for Review -on: - pull_request: - types: [labeled, unlabeled, synchronize, ready_for_review, review_requested] - workflow_run: - workflows: ["Code Checks", "Check CODEOWNERS Entries", "Code Health Report"] - types: [completed] -jobs: - ready_for_review: - permissions: write-all - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4.0.2 - with: - aws-access-key-id: ${{ secrets.aws_access_key_id }} - aws-secret-access-key: ${{ secrets.aws_secret_access_key }} - aws-region: "us-gov-west-1" - - - name: Get bot token from Parameter Store - uses: marvinpinto/action-inject-ssm-secrets@latest - with: - ssm_parameter: /devops/VA_VSP_BOT_GITHUB_TOKEN - env_variable_name: VA_VSP_BOT_GITHUB_TOKEN - - # If no failures, no_failures=true - - name: Audit PR Labels - id: audit_pr_labels - if: | - !contains(github.event.pull_request.labels.*.name, 'code-health-failure') && - !contains(github.event.pull_request.labels.*.name, 'codeowners-addition-failure') && - !contains(github.event.pull_request.labels.*.name, 'codeowners-delete-failure') && - !contains(github.event.pull_request.labels.*.name, 'lint-failure') && - !contains(github.event.pull_request.labels.*.name, 'test-failure') - run: | - echo "no_failures=true" >> $GITHUB_OUTPUT - - # If test-passing label is present, ready_for_review=true - - name: Audit Test Passing Label - id: audit_passing_labels - if: | - contains(github.event.pull_request.labels.*.name, 'test-passing') - run: | - echo "ready_for_review=true" >> $GITHUB_OUTPUT - - # If require-backend-approval label is present, get reviews - - name: Check backend-review-group approval status - if: contains(github.event.pull_request.labels.*.name, 'require-backend-approval') - id: check_backend_review_group_approval_status - uses: octokit/request-action@v2.x - with: - route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # - - name: Get backend-review-group members - if: contains(github.event.pull_request.labels.*.name, 'require-backend-approval') - id: get_team_members - uses: octokit/request-action@v2.x - with: - route: GET /orgs/department-of-veterans-affairs/teams/backend-review-group/members - env: - GITHUB_TOKEN: ${{ env.VA_VSP_BOT_GITHUB_TOKEN }} - - - name: Verify backend-review-group approval - if: contains(github.event.pull_request.labels.*.name, 'require-backend-approval') - id: verify_approval - run: | - BACKEND_REVIEWERS=$(cat <<'EOF' | jq -r '.[].login' | tr '\n' '|' | sed 's/|$//' - ${{ steps.get_team_members.outputs.data }} - EOF - ) - - APPROVALS=$(cat <<'EOF' | jq -r '.[] | select(.state == "APPROVED") | .user.login' | grep -iE "$BACKEND_REVIEWERS" | wc -l - ${{ steps.check_backend_review_group_approval_status.outputs.data }} - EOF - ) - - echo "Number of backend-review-group approvals: $APPROVALS" - if [ "$APPROVALS" -eq 0 ]; then - echo "approval_status=required" >> $GITHUB_OUTPUT - else - echo "approval_status=confirmed" >> $GITHUB_OUTPUT - fi - - # Add ready-for-backend-review when all checks are passing and approval - - name: Add Review label - uses: actions-ecosystem/action-add-labels@v1 - if: | - github.event.pull_request.draft == false && - steps.audit_passing_labels.outputs.ready_for_review == 'true' && - steps.audit_pr_labels.outputs.no_failures == 'true' && - steps.verify_approval.outputs.approval_status == 'required' - with: - number: ${{ github.event.pull_request.number }} - labels: | - ready-for-backend-review - - - name: Remove Review label - uses: actions-ecosystem/action-remove-labels@v1 - if: | - github.event.pull_request.draft == true || - ( - contains(github.event.pull_request.labels.*.name, 'ready-for-backend-review') && - steps.audit_passing_labels.outputs.ready_for_review != 'true' || - steps.audit_pr_labels.outputs.no_failures != 'true' || - steps.verify_approval.outputs.approval_status == 'confirmed' - ) - with: - number: ${{ github.event.pull_request.number }} - labels: | - ready-for-backend-review diff --git a/.github/workflows/require_backend_label.yml b/.github/workflows/require_backend_label.yml deleted file mode 100644 index 08fb0b819ab..00000000000 --- a/.github/workflows/require_backend_label.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Label Pull Request Reviewers -on: - pull_request: - types: [opened, reopened, review_requested, synchronize, ready_for_review, unlabeled] - -jobs: - label-pr-codeowners: - permissions: write-all - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Remove require-backend-approval label - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - require-backend-approval - - - name: Remove omit-backend-approval label - uses: actions-ecosystem/action-remove-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - omit-backend-approval - - # The following will be once bebugging as finished - # - name: Require require-backend-approval label - # if: github.event.action == 'unlabeled' && github.event.label.name == 'require-backend-approval' - # uses: actions-ecosystem/action-add-labels@v1 - # with: - # number: ${{ github.event.pull_request.number }} - # labels: | - # require-backend-approval - - # - name: Require omit-backend-approval label - # if: github.event.action == 'unlabeled' && github.event.label.name == 'omit-backend-approval' - # uses: actions-ecosystem/action-add-labels@v1 - # with: - # number: ${{ github.event.pull_request.number }} - # labels: | - # omit-backend-approval - - - name: Add omit-backend-approval label - if: | - github.event.pull_request.draft == false && - ( - contains(toJSON(github.event.pull_request.requested_teams.*.name), 'mobile') || - contains(toJSON(github.event.pull_request.requested_teams.*.name), 'lighthouse') || - contains(toJSON(github.event.pull_request.requested_teams.*.name), 'identity') - ) - uses: actions-ecosystem/action-add-labels@v1 - with: - number: ${{ github.event.pull_request.number }} - labels: | - omit-backend-approval - - - name: Add require-backend-approval label - uses: actions-ecosystem/action-add-labels@v1 - if: | - github.event.pull_request.draft == false && - !contains(toJSON(github.event.pull_request.requested_teams.*.name), 'mobile') && - !contains(toJSON(github.event.pull_request.requested_teams.*.name), 'lighthouse') && - !contains(toJSON(github.event.pull_request.requested_teams.*.name), 'identity') - with: - number: ${{ github.event.pull_request.number }} - labels: | - require-backend-approval