Generate Profile Badges #908
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: Generate Profile Badges | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'challenge-*/SCOREBOARD.md' | |
| - 'packages/*/challenge-*/SCOREBOARD.md' | |
| - 'README.md' # When main scoreboard updates | |
| workflow_run: | |
| workflows: ["Update Main Scoreboard", "Update Main Package Scoreboard"] | |
| types: | |
| - completed | |
| branches: | |
| - main | |
| workflow_dispatch: # Allow manual triggering | |
| schedule: | |
| - cron: '0 6 * * *' # Daily at 6 AM UTC | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: generate-profile-badges | |
| cancel-in-progress: false | |
| jobs: | |
| generate-badges: | |
| if: (github.event_name != 'pull_request' || github.event.pull_request.merged == true) && github.repository == 'RezaSi/go-interview-practice' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 2 # Need to compare with previous commits | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.x' | |
| - name: Generate contributor badges | |
| run: | | |
| echo "🏆 Starting badge generation process..." | |
| echo "📊 Using existing scoreboard data..." | |
| # Run with timeout protection | |
| timeout 300 python3 scripts/generate_contributor_badges.py || { | |
| echo "⚠️ Badge generation timed out or failed, but continuing..." | |
| # Don't fail the entire workflow - badges are supplementary | |
| exit 0 | |
| } | |
| - name: Check for changes | |
| id: git-check | |
| run: | | |
| echo "Checking for changes..." | |
| if git diff --quiet && git diff --cached --quiet; then | |
| echo "changes=false" >> $GITHUB_OUTPUT | |
| echo "No changes detected" | |
| else | |
| echo "changes=true" >> $GITHUB_OUTPUT | |
| echo "Changes detected" | |
| echo "Changed files:" | |
| git diff --name-only | |
| git diff --cached --name-only | |
| fi | |
| - name: Commit and push changes | |
| if: steps.git-check.outputs.changes == 'true' | |
| run: | | |
| git config user.name "GitHub Actions" | |
| git config user.email "actions@github.com" | |
| echo "Adding badge files..." | |
| git add -A badges/ || true | |
| # Check if there are actually changes to commit | |
| if git diff --staged --quiet; then | |
| echo "No staged changes to commit" | |
| exit 0 | |
| fi | |
| echo "Committing changes..." | |
| git commit -m "🏆 Auto-update: Profile badges regenerated | |
| - Regenerated contributor profile badges from current scoreboards | |
| - Updated badge files: *.svg, *.json, *_badges.md | |
| - Auto-generated by GitHub Actions" || { | |
| echo "⚠️ Commit failed, but continuing..." | |
| exit 0 | |
| } | |
| # Robust push with retry logic for concurrent workflows | |
| MAX_RETRIES=5 | |
| RETRY_COUNT=0 | |
| while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do | |
| echo "Push attempt $((RETRY_COUNT + 1))/$MAX_RETRIES" | |
| # Pull latest changes before pushing | |
| git fetch origin main || { | |
| echo "⚠️ Fetch failed, retrying..." | |
| sleep $((RETRY_COUNT + 1)) | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| continue | |
| } | |
| # Check if we need to rebase | |
| if ! git diff --quiet HEAD origin/main; then | |
| echo "Remote has new changes, rebasing..." | |
| git rebase origin/main || { | |
| echo "Rebase failed, trying merge strategy..." | |
| git rebase --abort 2>/dev/null || true | |
| git merge origin/main -m "Merge remote changes before badge update" || { | |
| echo "⚠️ Merge failed, retrying..." | |
| sleep $((RETRY_COUNT + 1)) | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| continue | |
| } | |
| } | |
| fi | |
| # Try to push | |
| if git push origin main; then | |
| echo "✅ Successfully pushed changes" | |
| break | |
| else | |
| echo "❌ Push failed, retrying in $((RETRY_COUNT + 1)) seconds..." | |
| sleep $((RETRY_COUNT + 1)) | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| fi | |
| done | |
| if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then | |
| echo "⚠️ Failed to push after $MAX_RETRIES attempts, but not failing workflow" | |
| echo "Badge updates will be retried on next scoreboard change" | |
| exit 0 | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create summary | |
| if: always() | |
| run: | | |
| echo "## 🏆 Profile Badge Update Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Check workflow status | |
| if [ "${{ job.status }}" == "success" ]; then | |
| if [ "${{ steps.git-check.outputs.changes }}" == "true" ]; then | |
| echo "✅ **Status**: Updates applied successfully" >> $GITHUB_STEP_SUMMARY | |
| echo "🏆 **Changes**: Profile badges regenerated from current scoreboards" >> $GITHUB_STEP_SUMMARY | |
| echo "🔄 **Auto-commit**: Changes committed and pushed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "ℹ️ **Status**: No changes detected" >> $GITHUB_STEP_SUMMARY | |
| echo "📊 **Scoreboards**: Already up to date" >> $GITHUB_STEP_SUMMARY | |
| echo "🏆 **Badges**: Already current" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| else | |
| echo "⚠️ **Status**: Workflow completed with warnings" >> $GITHUB_STEP_SUMMARY | |
| echo "📊 **Note**: Some operations may have been skipped due to errors" >> $GITHUB_STEP_SUMMARY | |
| echo "🔄 **Recovery**: Badge updates will retry on next scoreboard change" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 📁 Generated Badge Files" >> $GITHUB_STEP_SUMMARY | |
| echo "- Dynamic badges: \`badges/*.json\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- Custom SVG badges: \`badges/*.svg\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- Badge collections: \`badges/*_badges.md\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- Instructions: \`badges/README.md\`" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "🔗 **View badges**: [Browse badges directory](https://github.com/${{ github.repository }}/tree/main/badges)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🔧 Workflow Robustness" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Timeout protection (5 min max)" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Retry logic with exponential backoff" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Graceful failure handling" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Concurrency control" >> $GITHUB_STEP_SUMMARY |