name: Changelog on: push: tags: - 'v*' jobs: changelog: runs-on: ubuntu-latest env: REPO: releases/ClaudeDo steps: - name: Checkout main (full history) env: TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -euo pipefail git clone "https://oauth2:${TOKEN}@git.kuns.dev/${REPO}.git" src cd src git fetch --tags --force git checkout main - name: Regenerate CHANGELOG.md run: | set -euo pipefail cd src emit_group() { # $1 range, $2 conventional-type, $3 heading local range="$1" type="$2" title="$3" lines lines="$(git log "$range" --no-merges --pretty=format:'%s|%h' \ | grep -E "^${type}(\([^)]*\))?(!)?: " || true)" [ -z "$lines" ] && return 0 printf '### %s\n\n' "$title" while IFS='|' read -r subject hash; do printf -- '- %s (%s)\n' "${subject#*: }" "$hash" done <<< "$lines" printf '\n' } emit_section() { # $1 range, $2 tag, $3 date printf '## %s — %s\n\n' "$2" "$3" emit_group "$1" feat "Features" emit_group "$1" fix "Fixes" emit_group "$1" perf "Performance" emit_group "$1" refactor "Refactoring" emit_group "$1" docs "Documentation" } # Tags ascending by semver so we can pair each with its predecessor. mapfile -t TAGS < <(git tag --sort=v:refname | grep -E '^v' || true) { printf '# Changelog\n\n' for ((i=${#TAGS[@]}-1; i>=0; i--)); do TAG="${TAGS[$i]}" DATE="$(git log -1 --format=%ad --date=short "$TAG")" if (( i > 0 )); then RANGE="${TAGS[$((i-1))]}..${TAG}" else RANGE="$TAG" fi emit_section "$RANGE" "$TAG" "$DATE" done } > CHANGELOG.md cat CHANGELOG.md - name: Commit and push if changed env: TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -euo pipefail cd src if git diff --quiet -- CHANGELOG.md; then echo "CHANGELOG.md unchanged; nothing to commit." exit 0 fi git config user.name "ClaudeDo CI" git config user.email "ci@kuns.dev" git add CHANGELOG.md git commit -m "docs(changelog): update for ${GITHUB_REF_NAME}" git push origin main