|
| 1 | +name: Dependencies |
| 2 | + |
| 3 | +# -------------------------------------------------------------------------- |
| 4 | +# Orchestrates dependency review for all PRs and dependabot-specific |
| 5 | +# processing: structured PR comments with review data and auto-approval |
| 6 | +# for safe dependency updates (non-major, 24h+ release age, no vulnerabilities). |
| 7 | +# -------------------------------------------------------------------------- |
| 8 | + |
| 9 | +on: |
| 10 | + push: |
| 11 | + branches: |
| 12 | + - main |
| 13 | + pull_request: |
| 14 | + branches: |
| 15 | + - main |
| 16 | + |
| 17 | +permissions: |
| 18 | + contents: read |
| 19 | + issues: none |
| 20 | + pull-requests: none |
| 21 | + |
| 22 | +env: |
| 23 | + MIN_RELEASE_AGE_HOURS: 24 |
| 24 | + |
| 25 | +jobs: |
| 26 | + call_deps_reviewer: |
| 27 | + name: General |
| 28 | + uses: complytime/org-infra/.github/workflows/reusable_deps_reviewer.yml@baf5b2e21e61581b4a3a129795286e8592e6afbb # v0.1.0 |
| 29 | + |
| 30 | + call_dependabot_reviewer: |
| 31 | + name: Dependabot |
| 32 | + uses: complytime/org-infra/.github/workflows/reusable_dependabot_reviewer.yml@baf5b2e21e61581b4a3a129795286e8592e6afbb # v0.1.0 |
| 33 | + |
| 34 | + comment_on_dependabot_prs: |
| 35 | + name: Dependabot Comment |
| 36 | + if: github.actor == 'dependabot[bot]' |
| 37 | + runs-on: ubuntu-latest |
| 38 | + needs: [call_deps_reviewer, call_dependabot_reviewer] |
| 39 | + permissions: |
| 40 | + issues: read |
| 41 | + pull-requests: write # Necessary to write a comment |
| 42 | + steps: |
| 43 | + - name: Comment from Dependabot Reviewer |
| 44 | + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 |
| 45 | + env: |
| 46 | + REVIEW_CONCLUSION: ${{ needs.call_deps_reviewer.outputs.review_conclusion }} |
| 47 | + RISK_LEVEL: ${{ needs.call_dependabot_reviewer.outputs.risk_level }} |
| 48 | + UPDATES_COUNT: ${{ needs.call_dependabot_reviewer.outputs.updates_count }} |
| 49 | + DEP_NAME: ${{ needs.call_dependabot_reviewer.outputs.dep_name }} |
| 50 | + DEP_VERSION: ${{ needs.call_dependabot_reviewer.outputs.dep_version }} |
| 51 | + RELEASE_AGE_HOURS: ${{ needs.call_dependabot_reviewer.outputs.release_age_hours }} |
| 52 | + with: |
| 53 | + issue-number: ${{ github.event.pull_request.number }} |
| 54 | + edit-mode: replace |
| 55 | + body: | |
| 56 | + 🤖 **Standardized Dependabot Review Summary** 🤖 |
| 57 | +
|
| 58 | + This PR was processed by the organization's reusable CI pipeline. |
| 59 | +
|
| 60 | + | Criterion | Status | Detail | |
| 61 | + |-----------|--------|--------| |
| 62 | + | **Dependencies Review** | **${{ env.REVIEW_CONCLUSION }}** | [View logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) | |
| 63 | + | **Calculated Risk** | **${{ env.RISK_LEVEL }}** | `${{ env.DEP_NAME }}` v${{ env.DEP_VERSION }} | |
| 64 | + | **Release Age** | **${{ (env.RELEASE_AGE_HOURS == '-1' || env.RELEASE_AGE_HOURS == '') && 'unknown' || format('{0}h', env.RELEASE_AGE_HOURS) }}** | ${{ (env.RELEASE_AGE_HOURS == '-1' || env.RELEASE_AGE_HOURS == '') && 'Release date unavailable — manual review required' || format('Released {0} hours ago', env.RELEASE_AGE_HOURS) }} | |
| 65 | + | **Dependency Usage** | ${{ env.UPDATES_COUNT == '0' && 'unavailable' || format('{0} repos', env.UPDATES_COUNT) }} | Informational only — does not affect approval | |
| 66 | +
|
| 67 | + **Auto-approval:** ${{ env.RISK_LEVEL != 'high' && env.REVIEW_CONCLUSION == 'success' && env.RELEASE_AGE_HOURS != '-1' && fromJSON(env.RELEASE_AGE_HOURS) >= fromJSON(env.MIN_RELEASE_AGE_HOURS) && '✅ Approved' || '⏳ Manual review required' }} |
| 68 | +
|
| 69 | + --- |
| 70 | +
|
| 71 | + Maintainer check list: |
| 72 | + 1. Ensure the PR passed all CI tests (required status checks). |
| 73 | + 2. Investigate failures for Major updates or any manual review requirement. |
| 74 | + 3. Don't overlook breaking changes and changelog information. |
| 75 | + 4. If the scorecard value is low, consider to contribute to make it higher. Everybody wins! |
| 76 | + 5. Be diligent. When in doubt, ask another maintainer for additional review. |
| 77 | +
|
| 78 | + approve_dependabot_prs: |
| 79 | + name: Dependabot Auto-approve |
| 80 | + if: github.actor == 'dependabot[bot]' |
| 81 | + runs-on: ubuntu-latest |
| 82 | + needs: [call_deps_reviewer, call_dependabot_reviewer] |
| 83 | + permissions: |
| 84 | + pull-requests: write # Necessary to approve a PR |
| 85 | + steps: |
| 86 | + - name: Auto-approve if Confident |
| 87 | + if: >- |
| 88 | + needs.call_dependabot_reviewer.outputs.risk_level != 'high' && |
| 89 | + needs.call_deps_reviewer.outputs.review_conclusion == 'success' && |
| 90 | + needs.call_dependabot_reviewer.outputs.release_age_hours != '-1' && |
| 91 | + fromJSON(needs.call_dependabot_reviewer.outputs.release_age_hours) >= fromJSON(env.MIN_RELEASE_AGE_HOURS) |
| 92 | + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 |
| 93 | + with: |
| 94 | + script: | |
| 95 | + const risk = '${{ needs.call_dependabot_reviewer.outputs.risk_level }}'; |
| 96 | + const review = '${{ needs.call_deps_reviewer.outputs.review_conclusion }}'; |
| 97 | + const releaseAge = '${{ needs.call_dependabot_reviewer.outputs.release_age_hours }}'; |
| 98 | +
|
| 99 | + github.rest.pulls.createReview({ |
| 100 | + owner: context.repo.owner, |
| 101 | + repo: context.repo.repo, |
| 102 | + pull_number: context.issue.number, |
| 103 | + event: 'APPROVE', |
| 104 | + body: `Automatically approved: risk=${risk}, review=${review}, release_age=${releaseAge}h.` |
| 105 | + }); |
| 106 | + console.log(`Dependabot PR approved: risk=${risk}, review=${review}, release_age=${releaseAge}h`); |
0 commit comments