Badges #21930
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
| name: Badges | |
| on: | |
| schedule: | |
| - cron: '0 */6 * * *' | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - '**.py' | |
| - '.github/**' | |
| - 'requirements.txt' | |
| pull_request: | |
| paths: | |
| - '**.py' | |
| - '.github/**' | |
| - 'requirements.txt' | |
| pull_request_target: | |
| types: [opened, synchronize, reopened] | |
| # For bot PRs, we use pull_request_target without path filtering | |
| # to ensure badge update PRs (which only contain docs/**/*.json files) are handled | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| env: | |
| DEFAULT_PYTHON: "3.13" | |
| jobs: | |
| # Job that runs on automated PRs to provide status check for auto-merge | |
| validate: | |
| name: Validate automated PR | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'pull_request' && github.head_ref == 'update-badges') || | |
| (github.event_name == 'pull_request_target' && | |
| contains(fromJson('["github-actions[bot]", "dependabot[bot]", "copilot-swe-agent[bot]", "asusrouter-bot"]'), github.actor) && | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| steps: | |
| # No checkout needed for validation - we only echo information and don't access repository files | |
| - name: Validate PR | |
| env: | |
| HEAD_REF: ${{ github.head_ref }} | |
| run: | | |
| echo "β Automated badge update PR validated successfully" | |
| echo "This PR contains badge data updates and can be auto-merged." | |
| echo "Event: ${{ github.event_name }}" | |
| echo "Actor: ${{ github.actor }}" | |
| echo "Head ref: $HEAD_REF" | |
| generate: | |
| name: Generate badge files | |
| runs-on: ubuntu-latest | |
| if: | | |
| !( | |
| (github.event_name == 'pull_request' && github.head_ref == 'update-badges') || | |
| (github.event_name == 'pull_request_target' && | |
| contains(fromJson('["github-actions[bot]", "dependabot[bot]", "copilot-swe-agent[bot]", "asusrouter-bot"]'), github.actor) && | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| ) | |
| steps: | |
| - name: Checkout the repository | |
| uses: actions/[email protected] | |
| with: | |
| persist-credentials: false | |
| - name: Setup uv | |
| uses: astral-sh/[email protected] | |
| - name: Setup Python ${{ env.DEFAULT_PYTHON }} | |
| uses: actions/[email protected] | |
| with: | |
| python-version: ${{ env.DEFAULT_PYTHON }} | |
| - name: Install Python dependencies | |
| run: | | |
| uv pip install --system -r requirements.txt | |
| - name: Get and save data | |
| shell: bash | |
| run: | | |
| uv run python script/custom_integration_badges.py | |
| - name: Read changes summary | |
| id: changes | |
| run: | | |
| if [ -f "badge_changes_summary.json" ]; then | |
| echo "summary=$(cat badge_changes_summary.json | jq -c .)" >> $GITHUB_OUTPUT | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| # Calculate array lengths using jq | |
| echo "added_count=$(cat badge_changes_summary.json | jq '.added | length')" >> $GITHUB_OUTPUT | |
| echo "modified_count=$(cat badge_changes_summary.json | jq '.modified | length')" >> $GITHUB_OUTPUT | |
| echo "removed_count=$(cat badge_changes_summary.json | jq '.removed | length')" >> $GITHUB_OUTPUT | |
| # Get first few files from each category for display (limit to 5 each) | |
| echo "added_preview=$(cat badge_changes_summary.json | jq -c '.added[:5]')" >> $GITHUB_OUTPUT | |
| echo "modified_preview=$(cat badge_changes_summary.json | jq -c '.modified[:5]')" >> $GITHUB_OUTPUT | |
| echo "removed_preview=$(cat badge_changes_summary.json | jq -c '.removed[:5]')" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Generate history data | |
| shell: bash | |
| run: | | |
| python script/generate_history.py | |
| - name: Create Pull Request | |
| id: cpr | |
| if: steps.changes.outputs.has_changes == 'true' && github.event_name != 'pull_request' | |
| uses: peter-evans/create-pull-request@v8 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| author: "asusrouter-bot <[email protected]>" | |
| committer: "asusrouter-bot <[email protected]>" | |
| title: "π€ Update badges" | |
| branch: "update-badges" | |
| base: main | |
| body: | | |
| ## π€ Automated badge update | |
| This PR is automatically generated to update integration badges with the latest data. | |
| ### Summary | |
| - **Total files changed**: ${{ fromJson(steps.changes.outputs.summary).total_changes }} | |
| - **Added**: ${{ steps.changes.outputs.added_count }} files | |
| - **Modified**: ${{ steps.changes.outputs.modified_count }} files | |
| - **Removed**: ${{ steps.changes.outputs.removed_count }} files | |
| <details> | |
| <summary>π File changes preview (showing first 5 of each type)</summary> | |
| **Added files:** | |
| ${{ join(fromJson(steps.changes.outputs.added_preview), ' | |
| ') }} | |
| **Modified files:** | |
| ${{ join(fromJson(steps.changes.outputs.modified_preview), ' | |
| ') }} | |
| **Removed files:** | |
| ${{ join(fromJson(steps.changes.outputs.removed_preview), ' | |
| ') }} | |
| _Note: Only showing first 5 files per category to avoid overly long descriptions._ | |
| </details> | |
| This PR will be automatically merged if all checks pass. | |
| commit-message: "π€ Autoupdate badges" | |
| delete-branch: true | |
| labels: | | |
| data-update | |
| automated | |
| - name: Comment on source PR | |
| if: github.event_name == 'pull_request' && steps.changes.outputs.has_changes == 'true' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const commentBody = `## π€ Badge Update Test Results | |
| This PR would trigger badge updates if merged to main. | |
| **Files that would be affected:** | |
| - **Added**: ${{ steps.changes.outputs.added_count }} files | |
| - **Modified**: ${{ steps.changes.outputs.modified_count }} files | |
| - **Removed**: ${{ steps.changes.outputs.removed_count }} files | |
| <details> | |
| <summary>π File changes preview (showing first 5 of each type)</summary> | |
| **Added files:** | |
| ${{ join(fromJson(steps.changes.outputs.added_preview), ' | |
| ') }} | |
| **Modified files:** | |
| ${{ join(fromJson(steps.changes.outputs.modified_preview), ' | |
| ') }} | |
| **Removed files:** | |
| ${{ join(fromJson(steps.changes.outputs.removed_preview), ' | |
| ') }} | |
| _Note: Only showing first 5 files per category to avoid overly long descriptions._ | |
| </details> | |
| βΉοΈ **Note**: Badge files are only updated when changes are merged to the main branch.`; | |
| // Check for existing comment from asusrouter-bot | |
| const comments = await github.rest.issues.listComments({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| }); | |
| const botComment = comments.data.find(comment => | |
| comment.user.login === 'github-actions[bot]' && | |
| comment.body.includes('π€ Badge Update Test Results') | |
| ); | |
| if (botComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| comment_id: botComment.id, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentBody | |
| }); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentBody | |
| }); | |
| } | |
| - run: sleep 5 | |
| if: steps.cpr.outputs.pull-request-operation == 'created' && github.event_name != 'pull_request' | |
| - name: Enable Pull Request Automerge | |
| if: steps.cpr.outputs.pull-request-operation == 'created' && github.event_name != 'pull_request' | |
| uses: peter-evans/enable-pull-request-automerge@v3 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} | |
| merge-method: squash | |
| - name: Add PR status comment | |
| if: steps.cpr.outputs.pull-request-operation == 'created' && github.event_name != 'pull_request' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| github.rest.issues.createComment({ | |
| issue_number: ${{ steps.cpr.outputs.pull-request-number }}, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: `β **Automerge enabled** - This PR will be automatically merged when all status checks pass. | |
| π **Transparency note**: This automation ensures badge data stays current with minimal manual intervention while maintaining full visibility of all changes.` | |
| }); | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| rm -f badge_changes_summary.json |