Skip to content

Update Contributors

Update Contributors #9

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 }}