Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/update-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Update CHANGELOG.md

# Prepend the GitHub Release body to CHANGELOG.md when a release is
# published. Released-bearing repos (npm/PyPI/marketplace/GHCR) all use
# softprops/action-gh-release with `generate_release_notes: true` in their
# CD workflow, which means GitHub's auto-generated notes (PR titles since
# the previous tag) are the authoritative changelog. This workflow simply
# mirrors that into a checked-in CHANGELOG.md so people who don't browse
# Releases still see the history.

on:
release:
types: [published]

permissions:
contents: write

jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: main
token: ${{ secrets.GITHUB_TOKEN }}

- name: Prepend release entry to CHANGELOG.md
env:
TAG: ${{ github.event.release.tag_name }}
NAME: ${{ github.event.release.name }}
BODY: ${{ github.event.release.body }}
DATE: ${{ github.event.release.published_at }}
run: |
set -euo pipefail
[ -f CHANGELOG.md ] || { echo "::warning::CHANGELOG.md missing — skipping"; exit 0; }
DAY="${DATE:0:10}"
HEADER="## [${NAME:-$TAG}] - $DAY"

# Write the body to a tmp file so we don't have to inline-escape it.
printf '%s\n' "$BODY" > /tmp/release-body

if grep -q '^## \[Unreleased\]' CHANGELOG.md; then
# Insert after the "## [Unreleased]" line + its blank line, so the
# Unreleased section stays at the top and manual in-flight notes
# are preserved.
awk -v hdr="$HEADER" -v body_file="/tmp/release-body" '
BEGIN { inserted = 0 }
{
print
if (!inserted && /^## \[Unreleased\]/) {
getline blank
print blank
print hdr
print ""
while ((getline line < body_file) > 0) print line
close(body_file)
print ""
inserted = 1
}
}
' CHANGELOG.md > CHANGELOG.md.new
else
{ echo "$HEADER"; echo; cat /tmp/release-body; echo; cat CHANGELOG.md; } > CHANGELOG.md.new
fi
mv CHANGELOG.md.new CHANGELOG.md

- name: Commit and push
run: |
if git diff --quiet -- CHANGELOG.md; then
echo "No changes to CHANGELOG.md — release body was empty?"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add CHANGELOG.md
git commit -m "docs(changelog): record ${{ github.event.release.tag_name }} [skip ci]"
git push
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

This file is **append-only**. Each release on
[GitHub Releases](https://github.com/starter-series/react-native-starter/releases) is the
authoritative source — `.github/workflows/update-changelog.yml` prepends a
new entry here when a release is published, so the file mirrors the
release feed without duplicating maintenance.

## [Unreleased]

<!-- Future entries land here. Manual edits are welcome — the workflow
prepends BELOW this header so it never overwrites in-flight notes. -->