Skip to content

Coding‑hours report #8

Coding‑hours report

Coding‑hours report #8

Workflow file for this run

name: Coding‑hours report
on:
schedule:
- cron: '0 0 * * 1' # every Monday at 00:00 UTC
workflow_dispatch: # manual trigger
inputs:
window_start:
description: 'Report since YYYY‑MM‑DD'
required: false
permissions:
contents: write # needed for committing to the metrics branch
jobs:
report:
runs-on: ubuntu-latest
steps:
# 1️⃣ Check out full history
- uses: actions/checkout@v4
with:
fetch-depth: 0
# 2️⃣ Set up Go (>=1.24 to support git-hours v0.1.2 go.mod)
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.24'
# 3️⃣ Install git-hours (Go) v0.1.2 with go.mod patch
- name: Install git-hours (Go) v0.1.2
run: |
git clone --depth 1 --branch v0.1.2 https://github.com/trinhminhtriet/git-hours.git git-hours-src
cd git-hours-src
sed -i 's/go 1.24.1/go 1.24/' go.mod
go install .
# 4️⃣ Generate the report as JSON
- name: Generate report
run: |
ARGS=""
if [ -n "${{ github.event.inputs.window_start }}" ]; then
ARGS+=" -since ${{ github.event.inputs.window_start }}"
fi
git-hours --json $ARGS > git-hours.json
# 4️⃣½ Build a Shields.io badge from the JSON report
- name: Build badge.json
run: |
HOURS=$(jq '.total.hours' git-hours.json)
cat > badge.json <<EOF
{
"schemaVersion": 1,
"label": "Coding hours",
"message": "${HOURS}h",
"color": "informational"
}
EOF
# 5️⃣ Publish the raw report to the run summary
- name: Add workflow summary
run: |
echo "### ⏱ Coding‑hours report" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
jq -r '
["Contributor","Hours","Commits"],
(.[] | select(.name!="") | [ .name, .hours, .commits ])
| @tsv' git-hours.json \
| column -t -s $'\''\t'\'' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
# 6️⃣ Upload the JSON output as an artifact
- uses: actions/upload-artifact@v4
with:
name: git-hours-output-${{ github.run_id }}
path: git-hours.json
retention-days: 30
# 7️⃣ (Optional) Commit to metrics branch
- name: Commit to metrics branch
if: github.ref == 'refs/heads/develop'
env:
GH_TOKEN: ${{ secrets.GH_PAT }} # PAT needed for write access
run: |
git config --global user.name "git-hours bot"
git config --global user.email "[email protected]"
git switch -C metrics || git checkout metrics
mkdir -p reports
mv git-hours.json reports/git-hours-$(date +%F).json
# Keep badge.json at repo root (in metrics branch) for a stable URL
git add reports badge.json
git commit -m "chore(metrics): add report $(date +%F)" || echo "No change"
git push https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }} metrics
###############################################################################
# build a static site and push it to the gh-pages branch
###############################################################################
build-pages:
needs: report # wait for the main 'report' job
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ① Pull the raw JSON we just produced
- name: Download git-hours artifact
uses: actions/download-artifact@v4
with:
name: git-hours-output-${{ github.run_id }}
path: tmp # contains git-hours.json
# ② Prepare a static site under ./site
- name: Build site
run: |
mkdir -p site/data
# Keep a dated copy for time‑series work
cp tmp/git-hours.json "site/data/git-hours-$(date +%F).json"
# Produce index.html
python - <<'PY'
import json, datetime, pathlib
data = json.load(open('tmp/git-hours.json'))
total = data['total']
rows = "\n".join(
f"<tr><td>{k}</td><td>{v['hours']}</td><td>{v['commits']}</td></tr>"
for k,v in data.items() if k != 'total'
)
html = f"""<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Collaborator KPIs</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/simpledotcss/simple.min.css">
<script src="https://cdn.jsdelivr.net/npm/sortable-tablesort/sortable.min.js" defer></script>
</head>
<body>
<h1>Collaborator KPIs</h1>
<p><em>Last updated {datetime.datetime.utcnow().strftime('%F %H:%M UTC')}</em></p>
<h2>Totals</h2>
<ul>
<li><strong>Hours</strong>: {total['hours']}</li>
<li><strong>Commits</strong>: {total['commits']}</li>
<li><strong>Contributors</strong>: {len(data)-1}</li>
</ul>
<h2>Per‑contributor breakdown</h2>
<table class="sortable">
<thead><tr><th>Contributor</th><th>Hours</th><th>Commits</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p>Raw data files live in <code>/data</code> for further analysis.</p>
</body></html>"""
pathlib.Path('site/index.html').write_text(html)
PY
# ③ Deploy ./site to the gh-pages branch
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4 # battle‑tested Pages deployer
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: site
publish_branch: gh-pages