Update Contributors #9
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: Update Contributors | |
| on: | |
| schedule: | |
| - cron: '0 0 * * 0' # Runs weekly on Sunday at midnight UTC | |
| workflow_dispatch: # Allows manual trigger | |
| jobs: | |
| update-contributors: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Fetch all history to access commit details | |
| - name: Log checkout completion | |
| run: echo "Checked out repository at $(date -u +'%Y-%m-%d %H:%M:%S UTC')" | |
| - name: Get Contributors, Lines Added, and Commits | |
| id: contributors | |
| run: | | |
| set -euo pipefail | |
| echo "Starting contributor data collection at $(date -u +'%Y-%m-%d %H:%M:%S UTC')" | |
| # Initialize output file for contributor stats | |
| echo "{}" > contributors.json || { echo "Error: Failed to create contributors.json"; exit 1; } | |
| commit_count=0 | |
| # Switch to dev branch | |
| git checkout dev || { echo "Error: Failed to checkout dev branch"; exit 2; } | |
| # Get all commits in dev branch | |
| commits=$(git log --pretty=format:%H 2>/dev/null || { echo "Error: Failed to run git log"; exit 3; }) | |
| total_commits=$(echo "$commits" | wc -w | tr -d ' ') | |
| echo "Total commits to process: $total_commits" | |
| for commit in $commits; do | |
| ((commit_count++)) | |
| echo "Processing commit $commit ($commit_count/$total_commits)" | |
| # Get author name | |
| author_name=$(git show -s --format=%an "$commit" 2>/dev/null || { echo "Error: git show failed to get author for commit $commit"; continue; }) | |
| if [ -z "$author_name" ]; then | |
| echo "Skipping commit $commit with no author name" | |
| continue | |
| fi | |
| # Sanitize author name as GitHub username | |
| login=$(echo "$author_name" | tr -s ' ' '-' | tr -dc '[:alnum:]-') | |
| if echo "$author_name" | grep -q '[[:space:]]'; then | |
| echo "Warning: Author '$author_name' may not be a valid GitHub username (contains spaces, sanitized to '$login')" | |
| fi | |
| echo "Processing commit $commit by $login" | |
| # Get commit stats | |
| stats=$(git show --shortstat --format= "$commit" 2>/dev/null | grep -E '[0-9]+ file(s)? changed' | awk '{add=$4; del=$6} END {print (add ? add : 0) - (del ? del : 0)}' 2>/dev/null || echo "0") | |
| net_lines=${stats:-0} | |
| echo "Commit $commit by $login: $net_lines net lines" | |
| # Update JSON with contributor stats | |
| if ! jq --arg login "$login" --arg net_lines "$net_lines" \ | |
| '.[$login] |= (. // {netLines: 0, commits: 0, login: $login} | .netLines += ($net_lines | tonumber) | .commits += 1)' \ | |
| contributors.json > tmp.json 2>/dev/null; then | |
| echo "Error: jq failed to update stats for $login in commit $commit" | |
| exit 4 | |
| fi | |
| if ! mv tmp.json contributors.json 2>/dev/null; then | |
| echo "Error: Failed to move tmp.json for commit $commit" | |
| exit 5 | |
| fi | |
| done | |
| echo "Total commits processed: $commit_count" | |
| # Format table | |
| if ! table=$(jq -r 'to_entries | sort_by(.value.netLines) | reverse | .[] | select(.value.netLines > 0 or .value.commits > 0) | "| [\(.key)](https://github.com/\(.key)) | \(.value.netLines) | \(.value.commits) |"' contributors.json 2>/dev/null); then | |
| echo "Error: jq failed to format table" | |
| exit 6 | |
| fi | |
| if [ -z "$table" ]; then | |
| table="No contributors with commits or net lines added." | |
| echo "Warning: No valid contributors found" | |
| else | |
| table="| Contributor | Net Lines Added | Commits |\n|-------------|-----------------|---------|\n$table" | |
| fi | |
| total_contributors=$(jq 'length' contributors.json 2>/dev/null || { echo "Error: jq failed to count contributors"; exit 7; }) | |
| echo "Total contributors: $total_contributors" | |
| echo "Generated table:" | |
| echo "$table" | |
| if ! echo "$table" > contributors.txt; then | |
| echo "Error: Failed to write contributors.txt" | |
| exit 8 | |
| fi | |
| shell: bash | |
| - name: Update README | |
| run: | | |
| set -euo pipefail | |
| echo "Starting README update at $(date -u +'%Y-%m-%d %H:%M:%S UTC')" | |
| if [ ! -s contributors.txt ] || [ "$(cat contributors.txt)" = "No contributors with commits or net lines added." ]; then | |
| echo "No contributors with commits or net lines added. Skipping README update." | |
| exit 0 | |
| fi | |
| if grep -q "## Contributors" README.md; then | |
| echo "Found existing ## Contributors section. Replacing content." | |
| sed -i '/## Contributors/,/##/c\## Contributors\n\n'"$(cat contributors.txt)"'\n\n##' README.md || { echo "Error: failed to update README with sed"; exit 1; } | |
| else | |
| echo "No ## Contributors section found. Appending to README." | |
| echo -e "\n## Contributors\n\n$(cat contributors.txt)\n" >> README.md || { echo "Error: failed to append to README"; exit 2; } | |
| fi | |
| echo "Updated README content. Checking for changes." | |
| git config user.name "GitHub Action" | |
| git config user.email "[email protected]" | |
| git add README.md || { echo "Error: git add failed"; exit 3; } | |
| if git diff-index --quiet HEAD; then | |
| echo "No changes to commit. Exiting." | |
| exit 0 | |
| fi | |
| echo "Committing changes to README at $(date -u +'%Y-%m-%d %H:%M:%S UTC')" | |
| git commit -m "Update contributors table with net lines and commits" || { echo "Error: git commit failed"; exit 4; } | |
| git push || { echo "Error: git push failed"; exit 5; } | |
| echo "Pushed updated README to dev branch." | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.CUSTOM_GITHUB_TOKEN }} |