PR Stats #451
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: PR Stats | |
| on: | |
| schedule: | |
| - cron: '0 0 2 * *' # Run monthly collection on 2nd of each month | |
| - cron: '0 0 * * *' # Run daily updates at midnight | |
| workflow_dispatch: # Manual trigger | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| pr-stats: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.24.x' | |
| - name: Install jq | |
| run: sudo apt-get install -y jq | |
| - name: Install GitHub CLI | |
| run: | | |
| type -p curl >/dev/null || (sudo apt-get update && sudo apt-get install curl -y) | |
| curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ | |
| && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ | |
| && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ | |
| && sudo apt-get update \ | |
| && sudo apt-get install gh -y | |
| - name: Debug Environment | |
| run: env | |
| - name: Configure GitHub CLI | |
| env: | |
| TOKEN: ${{ github.token }} | |
| run: | | |
| unset GITHUB_TOKEN && unset GH_TOKEN | |
| echo "$TOKEN" | gh auth login --with-token | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.x' | |
| - name: Install Python dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Set up Google credentials | |
| id: google-credentials | |
| env: | |
| GOOGLE_CREDS: ${{ secrets.GOOGLE_CREDENTIALS }} | |
| run: | | |
| # Write the service account json file | |
| CREDENTIALS_FILE="$RUNNER_TEMP/google-credentials.json" | |
| printf '%s' "$GOOGLE_CREDS" > "$CREDENTIALS_FILE" | |
| chmod 600 "$CREDENTIALS_FILE" | |
| echo "credentials_file=$CREDENTIALS_FILE" >> "$GITHUB_OUTPUT" | |
| shell: bash | |
| - name: Monthly Collection | |
| if: github.event_name == 'schedule' && contains(github.workflow_ref, '/pr-stats.yml') && github.event.schedule == '0 0 2 * *' | |
| run: | | |
| chmod +x collect-monthly.sh | |
| ./collect-monthly.sh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Daily Update | |
| if: github.event_name == 'schedule' && github.event.schedule == '0 0 * * *' | |
| run: | | |
| chmod +x update-daily.sh | |
| ./update-daily.sh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Manual Run | |
| if: github.event_name == 'workflow_dispatch' | |
| run: | | |
| chmod +x update-daily.sh | |
| ./update-daily.sh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload PR data artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pr-data | |
| path: | | |
| data/consolidated/*.json | |
| data/monthly/*.json | |
| data/junit5/*.json | |
| retention-days: 30 | |
| - name: Generate timestamp | |
| id: timestamp | |
| run: echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_OUTPUT" | |
| - name: Validate PAT_TOKEN | |
| id: validate-token | |
| env: | |
| PAT_TOKEN: ${{ secrets.PAT_TOKEN }} | |
| run: | | |
| if [ -z "$PAT_TOKEN" ]; then | |
| echo "::error::PAT_TOKEN secret is not set or empty" | |
| echo "Please configure PAT_TOKEN in repository Settings → Secrets and variables → Actions" | |
| echo "The token needs 'repo' scope for creating pull requests" | |
| exit 1 | |
| fi | |
| # Test token validity by making a simple API call | |
| echo "Testing PAT_TOKEN validity..." | |
| HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ | |
| -H "Authorization: Bearer $PAT_TOKEN" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "https://api.github.com/user") | |
| if [ "$HTTP_CODE" = "200" ]; then | |
| echo "✓ PAT_TOKEN is valid" | |
| echo "valid=true" >> "$GITHUB_OUTPUT" | |
| elif [ "$HTTP_CODE" = "401" ]; then | |
| echo "::error::PAT_TOKEN is invalid or expired (HTTP 401)" | |
| echo "Please regenerate the token at https://github.com/settings/tokens" | |
| echo "Required scopes: repo" | |
| exit 1 | |
| elif [ "$HTTP_CODE" = "403" ]; then | |
| echo "::error::PAT_TOKEN lacks required permissions (HTTP 403)" | |
| echo "Ensure the token has 'repo' scope" | |
| exit 1 | |
| else | |
| echo "::warning::Unexpected HTTP response: $HTTP_CODE" | |
| echo "Proceeding anyway, but the Create Pull Request step may fail" | |
| echo "valid=unknown" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create Pull Request | |
| if: success() | |
| uses: peter-evans/create-pull-request@v6 | |
| with: | |
| token: ${{ secrets.PAT_TOKEN }} | |
| add-paths: | | |
| data/ | |
| commit-message: "Update PR data ${{ github.event.schedule == '0 0 2 * *' && 'Monthly' || 'Daily' }} collection (${{ steps.timestamp.outputs.timestamp }})" | |
| title: "Update PR data ${{ github.event.schedule == '0 0 2 * *' && 'Monthly' || 'Daily' }} collection (${{ steps.timestamp.outputs.timestamp }})" | |
| body: "This PR contains automatically updated PR statistics data. Generated by GitHub Actions." | |
| branch: auto-update-pr-data | |
| delete-branch: true | |
| base: main | |
| labels: automation | |