feat: auto-close PRs that only needed license updates #4924
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Automatically fix license files on PRs that need updates | ||
| # Instead of just failing, this workflow pushes the fix and comments on the PR | ||
| name: License Check | ||
| on: | ||
| pull_request: | ||
| paths: | ||
| - "**.go" | ||
| - go.mod | ||
| - go.sum | ||
| - ".github/licenses.tmpl" | ||
| - "script/licenses*" | ||
| - "third-party-licenses.*.md" | ||
| - "third-party/**" | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| jobs: | ||
| license-check: | ||
| runs-on: ubuntu-latest | ||
| # Don't run on forks (they can't push back) or dependabot | ||
| if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' | ||
| steps: | ||
| - name: Check out code | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| ref: ${{ github.head_ref }} | ||
| - name: Set up Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version-file: "go.mod" | ||
| # actions/setup-go does not setup the installed toolchain to be preferred over the system install, | ||
| # which causes go-licenses to raise "Package ... does not have module info" errors. | ||
| # For more information, https://github.com/google/go-licenses/issues/244#issuecomment-1885098633 | ||
| - name: Regenerate licenses | ||
| env: | ||
| CI: "true" | ||
| run: | | ||
| export GOROOT=$(go env GOROOT) | ||
| export PATH=${GOROOT}/bin:$PATH | ||
| ./script/licenses | ||
| - name: Check for changes | ||
| id: changes | ||
| run: | | ||
| if git diff --exit-code; then | ||
| echo "changed=false" >> $GITHUB_OUTPUT | ||
| echo "✅ License files are up to date" | ||
| else | ||
| echo "changed=true" >> $GITHUB_OUTPUT | ||
| echo "📝 License files need updating" | ||
| git diff --stat | ||
| fi | ||
| - name: Commit and push fixes | ||
| if: steps.changes.outputs.changed == 'true' | ||
| run: | | ||
| git config --local user.name "github-actions[bot]" | ||
| git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add third-party third-party-licenses.*.md | ||
| git commit -m "chore: regenerate third-party licenses" | ||
| git push | ||
| - name: Comment on PR | ||
| if: steps.changes.outputs.changed == 'true' | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: `## 📜 License files updated | ||
| I noticed the third-party license files were out of date and pushed a fix to this PR. | ||
| **What changed:** Dependencies were added, removed, or updated, which requires regenerating the license documentation. | ||
| **What I did:** Ran \`./script/licenses\` and committed the result. | ||
| Please pull the latest changes before pushing again.` | ||
| }) | ||
| # After pushing the fix, check if PR now has no functional changes (just license updates) | ||
| # This handles the case where the PR only needed license updates and nothing else | ||
| - name: Check if PR is now empty | ||
| if: steps.changes.outputs.changed == 'true' | ||
| id: empty_check | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const { data: pr } = await github.rest.pulls.get({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| pull_number: context.issue.number | ||
| }); | ||
| const { data: files } = await github.rest.pulls.listFiles({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| pull_number: context.issue.number | ||
| }); | ||
| // Check if ALL changes are just license files | ||
| const nonLicenseFiles = files.filter(f => | ||
| !f.filename.startsWith('third-party-licenses.') && | ||
| !f.filename.startsWith('third-party/') | ||
| ); | ||
| const isEmpty = nonLicenseFiles.length === 0; | ||
| core.setOutput('is_empty', isEmpty); | ||
| if (isEmpty) { | ||
| core.info('PR only contains license file changes - will close as stale'); | ||
| } else { | ||
| core.info(`PR has ${nonLicenseFiles.length} non-license file changes - keeping open`); | ||
| } | ||
| - name: Close stale license-only PR | ||
| if: steps.changes.outputs.changed == 'true' && steps.empty_check.outputs.is_empty == 'true' | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: `## 🤖 Auto-closing stale PR | ||
| This PR now only contains license file updates with no other functional changes. The license updates have been applied, so closing this PR as complete. | ||
| If this PR should have had other changes, please reopen it and add the intended changes.` | ||
| }); | ||
| await github.rest.pulls.update({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| pull_number: context.issue.number, | ||
| state: 'closed' | ||
| }); | ||