Merge pull request 'Add consumer-facing CHANGELOG.md maintained by release CI' (#53) from cursor/consumer-changelog into main
Release on merge to main / release (push) Successful in 7s
Code Quality Pipeline / code-quality (push) Successful in 19s
Test Python Package / unit-tests (push) Successful in 13s
Build CI Image / build-and-push (push) Successful in 36s
Test Python Package / integration-tests (push) Successful in 20s
Test Python Package / coverage-report (push) Successful in 11s

Reviewed-on: https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/pulls/53
This commit was merged in pull request #53.
This commit is contained in:
2026-07-10 20:40:34 +02:00
8 changed files with 524 additions and 5 deletions
+10 -1
View File
@@ -40,6 +40,15 @@ jobs:
NEW_TAG="v${{ steps.bump.outputs.version }}" NEW_TAG="v${{ steps.bump.outputs.version }}"
scripts/ci/generate-release-notes.sh "$NEW_TAG" "$PR_TITLE" "$PREV_TAG" scripts/ci/generate-release-notes.sh "$NEW_TAG" "$PR_TITLE" "$PREV_TAG"
- name: Update CHANGELOG
if: steps.meta.outputs.bump != 'skip'
env:
PR_TITLE: ${{ steps.meta.outputs.pr_title }}
run: |
PREV_TAG=$(git describe --tags --abbrev=0)
VERSION="${{ steps.bump.outputs.version }}"
scripts/ci/update-changelog.sh "$VERSION" "$PR_TITLE" "$PREV_TAG"
- name: Commit, tag, and push - name: Commit, tag, and push
if: steps.meta.outputs.bump != 'skip' if: steps.meta.outputs.bump != 'skip'
env: env:
@@ -48,7 +57,7 @@ jobs:
run: | run: |
git config user.name "CI Bot" git config user.name "CI Bot"
git config user.email "[email protected]" git config user.email "[email protected]"
git add pyproject.toml uv.lock git add pyproject.toml uv.lock CHANGELOG.md
git commit -m "chore: release v${VERSION} [skip ci]" git commit -m "chore: release v${VERSION} [skip ci]"
git tag "v${VERSION}" git tag "v${VERSION}"
git remote set-url origin "https://x-access-token:${CI_RUNNER_TOKEN}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" git remote set-url origin "https://x-access-token:${CI_RUNNER_TOKEN}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git"
+325
View File
@@ -0,0 +1,325 @@
# 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).
## [Unreleased]
## [2.0.4] - 2026-07-10
### Summary
Include optional dependencies in security audit
### Changed
- 4f7b672 chore: release v2.0.4 [skip ci]
- a27e9e5 Merge pull request '[fix] Include optional dependencies in security audit' (#50) from cursor/security-audit-all-extras into main
- fd0045d Include optional dependencies in security audit.
- 515f4bb Merge pull request 'revert 707f11f578f007c7152582ea524b66dacea50111' (#49) from brian-patch-1 into main
- ef31fb4 revert 707f11f578f007c7152582ea524b66dacea50111
- 707f11f chore: release v2.0.4 [skip ci]
- b1d34f8 Merge pull request '[patch] Unify dev tooling via uv so pre-commit, CI, and the update bot stay aligned' (#48) from chore/align-dev-tooling-via-uv into main
- 565879d Unify dev tooling via uv so pre-commit, CI, and the update bot stay aligned.
- 0d0f430 Merge pull request 'Fix automated package publishing in release workflow' (#47) from fix/release-workflow-publish into main
- 5ac40b1 Publish packages from the release workflow so automated releases reach the registry.
## [2.0.3] - 2026-07-10
### Summary
Use structured fields for adapter debug and info logs
### Changed
- fa4ff1f chore: release v2.0.3 [skip ci]
- 0a39151 Merge pull request '[patch] Use structured fields for adapter debug and info logs' (#46) from cursor/structured-adapter-logging into main
- 82a702d Fix mypy error in Minio adapter log assertion.
- b886a7c Use structured fields for adapter debug and info logs.
- 4518a93 Merge pull request 'Migrate Python workflows to python-repositories-ci runner' (#41) from cursor/migrate-python-repositories-ci into main
- a8b7b59 Migrate Python workflows to python-repositories-ci runner label.
- 0e6941d Merge pull request 'Use lowercase CI image registry owner for Docker compatibility' (#45) from cursor/fix-ci-registry-owner-lowercase into main
- a6428cc Use lowercase CI image registry owner for Docker compatibility.
- 655fdc4 Merge pull request 'Fix CI image registry owner to match Gitea org slug' (#44) from cursor/fix-ci-registry-owner-case into main
- e031c54 Fix CI image registry owner to match Gitea org slug.
- 49b6238 Merge pull request 'Rename CI registry owner from brian to lille-vemmelund' (#43) from cursor/rename-ci-owner-to-lille-vemmelund into main
- 0549358 Keep python-utils package index under brian owner.
- 33efbd1 Update CI registry owner from brian to lille-vemmelund.
- 24126e4 Merge pull request 'Fix CI image build failures on runners with isolated DinD DNS' (#42) from fix/ci-image-build-dns into main
- f3b6cdb Fix CI image build failures on runners with isolated DinD DNS.
- fa2554e Merge pull request 'Add nightly CI base image and migrate workflows to python-repositories-ci' (#40) from cursor/ci-base-image into main
- b21fd24 Revert workflows to ubuntu-latest until CI image is seeded.
- 441a212 Add local CI image build script and document bootstrap flow.
- f2a8581 Read Python version from .python-version in CI image build.
- 3b05260 Add nightly CI base image and migrate workflows to python-repositories-ci.
## [2.0.2] - 2026-07-09
### Summary
Use dict[str, Any] for JSON repository document types
### Changed
- 369295b chore: release v2.0.2 [skip ci]
- 95c7859 Merge pull request '[patch] Use dict[str, Any] for JSON repository document types' (#38) from cursor/json-dict-str-any-typing into main
- 42e885e Use dict[str, Any] for JSON repository document types.
## [2.0.1] - 2026-07-09
### Summary
Align Redis and MinIO connect() idempotency
### Changed
- bd4794d chore: release v2.0.1 [skip ci]
- 3dc412c Merge pull request '[patch] Align Redis and MinIO connect() idempotency' (#37) from cursor/connect-idempotency-alignment into main
- b8d88e6 Cover injected-client connect when client was cleared by disconnect.
- 67bb88f Align Redis and MinIO connect() idempotency in ConnectionAwareAdapter.
## [2.0.0] - 2026-07-09
### Summary
Make MinIO bucket creation opt-in with production-safe defaults
### Changed
- c2e6a96 chore: release v2.0.0 [skip ci]
- 547a1b3 Merge pull request '[breaking] Make MinIO bucket creation opt-in with production-safe defaults' (#36) from cursor/minio-bucket-creation-opt-in into main
- 39baf9b Fix examples integration test by provisioning MinIO bucket in fixture.
- 4a5b3b6 Make MinIO bucket creation opt-in with production-safe defaults.
- 1431f45 Merge pull request 'Move Redis test container helpers into integration conftest' (#35) from cursor/move-redis-container-to-conftest into main
- eafc717 Move Redis test container helpers into integration conftest.
## [1.1.0] - 2026-07-08
### Summary
Add Redis scan_keys iterator API
### Changed
- 9a9b7b2 chore: release v1.1.0 [skip ci]
- 5b9573d Merge pull request '[minor] Add Redis scan_keys iterator API' (#34) from cursor/redis-scan-keys into main
- 50444af Add Redis scan_keys iterator API.
## [1.0.0] - 2026-07-08
### Summary
Clarify MinIO get() error semantics to match Redis behavior
### Changed
- 2f19fcc chore: release v1.0.0 [skip ci]
- 3bd6589 Merge pull request '[breaking] Clarify MinIO get() error semantics to match Redis behavior' (#33) from cursor/minio-error-semantics into main
- 5311d49 Clarify MinIO get() error semantics to match Redis behavior.
## [0.5.1] - 2026-07-07
### Summary
Fix MinIO get_object response leak in MinioAdapter.get()
### Changed
- 703bb95 chore: release v0.5.1 [skip ci]
- 8e47ebf Merge pull request '[patch] Fix MinIO get_object response leak in MinioAdapter.get()' (#32) from fix/minio-get-object-response-cleanup into main
- 9a800bf Fetch live PR title in pr-title-check CI workflow.
- 8c34534 Fix MinIO get_object response leak in MinioAdapter.get().
- b1210bd Merge pull request 'Reach 100% combined coverage with targeted unit tests' (#31) from cursor/balanced-100-coverage into main
- 39b1043 Fix mypy unreachable-code warning in minio reconnect test.
- beb2b51 Reach 100% combined coverage with targeted unit tests.
- ce062be Merge pull request 'Enforce 90% combined coverage floor in CI' (#29) from cursor/enforce-coverage-floor into main
- a381d45 Lower combined coverage floor from 95% to 90%.
- 5c8cd84 Document where combined coverage floor is enforced in CI.
- 3463298 Skip coverage floor check in partial CI test jobs.
- 5393efc Enforce a 95% combined coverage floor in CI and local runs.
- e39fc96 Merge pull request 'Split CI into parallel unit, integration, and coverage report jobs' (#28) from cursor/split-ci-test-jobs into main
- c1f4826 Use christopherhx v4 artifact actions for parallel coverage merge.
- 0315a33 Avoid cross-job artifacts; combine coverage with --cov-append.
- 5d33ec6 Use artifact action v3 for Gitea Actions compatibility.
- 9538e4d Split CI into parallel unit, integration, and coverage report jobs.
- 14b8d27 Merge pull request 'Replace hardcoded version examples in release docs' (#27) from cursor/fix-version-doc-drift into main
- d3cbb65 Use version-agnostic examples in release docs.
## [0.5.0] - 2026-07-06
### Summary
Add config and client injection with test reorganization
### Changed
- 7dbb1fc chore: release v0.5.0 [skip ci]
- 918e5e6 Merge pull request '[minor] Add config and client injection with test reorganization' (#25) from cursor/config-client-injection into main
- 3aa9128 Load MINIO_SECURE from env and replace adapter asserts with explicit errors.
- 7991dab Add config and client injection with test reorganization.
- 366831a Merge pull request 'chore(deps): update dependencies' (#26) from renovate/auto-deps-update into main
- a98905d chore(deps): update dependencies [automated]
- 7ed1b34 Merge pull request 'Sync uv.lock on release to prevent CI failures' (#24) from cursor/sync-uv-lock-on-release into main
- 3236f27 manually updated package version
- ac487d9 Sync uv.lock on release to keep CI clean.
## [0.4.1] - 2026-07-05
### Summary
Extract shared connection lifecycle into ConnectionAwareAdapter
### Changed
- a049ce3 chore: release v0.4.1 [skip ci]
- 7b4cf84 Merge pull request '[patch] Extract shared connection lifecycle into ConnectionAwareAdapter' (#23) from cursor/extract-connection-aware-adapter into main
- b5a92e6 Sync uv.lock with pyproject.toml version 0.4.0.
- 7b950e0 Extract shared connection lifecycle into ConnectionAwareAdapter.
## [0.4.0] - 2026-07-05
### Summary
Strengthen is_connected with cached health probes
### Changed
- fe0c477 chore: release v0.4.0 [skip ci]
- e7e0fc8 Merge pull request '[minor] Strengthen is_connected with cached health probes' (#22) from cursor/strengthen-is-connected-health-checks into main
- 34fc046 Sync uv.lock with pyproject.toml version 0.3.2.
- 5149299 Strengthen is_connected with cached health probes.
## [0.3.2] - 2026-06-30
### Summary
Fix optional dependency handling for Redis and MinIO adapters
### Changed
- fef9552 chore: release v0.3.2 [skip ci]
- e9b2189 Merge pull request '[patch] Fix optional dependency handling for Redis and MinIO adapters' (#19) from cursor/fix-optional-dependencies into main
- f595390 Fix optional-deps import test for full-suite execution.
- 1f02195 Delegate top-level adapter imports to adapters package.
- f092ca2 Fix trailing whitespace in LICENSE and .gitignore.
- c6eed43 Fix optional dependency handling for Redis and MinIO adapters.
- 9e4b1e2 Merge pull request 'Avoid testcontainers Redis deprecation warning in integration tests.' (#18) from fix/redis-testcontainer-deprecation into main
- 0096df7 Avoid testcontainers Redis deprecation warning in integration tests.
- 3073bfb Merge pull request 'Fix PR coverage comment posting in CI.' (#17) from fix/coverage-pr-comment into main
- 30a1de3 Fix PR coverage comment posting in CI.
- 8465957 Merge pull request '[patch] update dependencies' (#16) from renovate/auto-deps-update into main
- 3ecb9c3 chore: retrigger CI
- 0f31170 Fix mypy errors from minio 7.2.20 type stubs.
- e3cab5e chore(deps): update dependencies [automated]
- f428a97 Merge pull request 'Fix dependency bot PR creation for Gitea.' (#15) from cursor/fix-dependency-bot-gitea-pr into main
- a3b9912 Fix dependency bot PR creation for Gitea.
- abaa078 Merge pull request 'Fix dependency update bot to use uv lock --upgrade.' (#14) from cursor/fix-dependency-update-bot-uv-lock into main
- 9864f0c Fix dependency update bot to use uv lock --upgrade.
- e39b467 Merge pull request 'Automate releases from PR titles and clean up CI workflows.' (#13) from cursor/pr-title-release-automation into main
- 85c1a64 Sync uv.lock with pyproject.toml version 0.3.1.
- a8491c0 Automate releases from PR titles and clean up CI workflows.
## [0.3.1] - 2026-06-28
### Summary
Add public repository interfaces and subclassable adapter CRUD API.
### Changed
- 2bb361e Merge pull request 'Add public repository interfaces and subclassable adapter CRUD API.' (#11) from cursor/public-repository-api into main
- c5169df Use pre-commit for Prettier in CI and document local hook setup.
- 497533f Fix mypy context manager typing for adapter subclasses.
- e98fd3b Add public repository interfaces and subclassable adapter CRUD API.
- f4280f1 Merge pull request 'Remove non-existent Mongo adapter from README.' (#10) from cleanup/remove-mongo-adapter-mentions into main
- d9b9fa4 updated package settings
- 9d25f7c updated package settings
- 1635815 updated package settings
- 933c4ee updated package settings
- 2b0d98f updated package settings
- 729fa48 Remove non-existent Mongo adapter from README.
## [0.2.3] - 2025-09-18
### Summary
added support for content type when putting object in minio
### Changed
- fa011be Merge pull request 'added support for content type when putting object in minio' (#9) from add-support-for-content-type-in-minio into main
- 2e93309 ruff format fix
- 3ab8da9 added support for content type when putting object in minio
## [0.2.2] - 2025-09-17
### Summary
moved import of optional packages into classes
### Changed
- 1dd604d Merge pull request 'moved import of optional packages into classes' (#6) from make-optional-parts-independent into main
- e5c4025 added graceful handling of missing optional packages
- 396cf83 code quality fixes
- 538b26b mypy fixed
- ee6acc6 moved import of optional packages into classes
## [0.2.1] - 2025-09-15
### Summary
exposed minio adapter
### Changed
- 0ca07c0 Merge pull request 'exposed minio adapter' (#5) from expose-minio-adapter into main
- 7446e88 added py.typed mypy config file
- d5f437f ruff format fix
- 7beca7c exposed minio adapter
## [0.2.0] - 2025-09-15
### Summary
add-minio-adapter
### Changed
- 65d8051 Merge pull request 'add-minio-adapter' (#4) from add-minio-adapter into main
- f5af303 auto install all extra packages
- 3260a3f added new optional package to ci
- c7bced4 ruff lint fixes
- 800d702 pyupgrade
- 5a72507 ruff format
- c45ba3c mypy fixes
- a3b5443 added minio adapter and tests
- cc99fe5 minor corrections
- 93fffe1 added optional group minio
## [0.1.0] - 2025-09-14
### Summary
Release v0.1.0
### Changed
- 2eafd73 Merge pull request 'added redis adapter' (#1) from collect-code-from-other-repos into main
- 1cc047d removed unused bound ports for test
- c7cc2a3 added optional package redis
- b5d0297 pyupgrade fixed imports
- 2fa633a ruff fixed formatting
- 0e47db2 fuxed mypy issues
- 0948799 added integration tests
- 524bd0f fixed connection error handling
- 969c2c8 installed more pytest-cov
- 7caee87 added installing optional redis group
- 918535e added test coverage and upload step
- 5d7afe7 ruff format corrections
- 59a943e added redis types stub and fixed return type
- 1abcae4 added redis adapter
- c789e33 initial commit
- 56cad42 Initial commit
+5 -2
View File
@@ -194,11 +194,14 @@ uv run pre-commit run --all-files
Releases are automated when a pull request is merged to `main`. CI reads the **merged PR title** to decide whether and how to bump the version. Releases are automated when a pull request is merged to `main`. CI reads the **merged PR title** to decide whether and how to bump the version.
- **Version history:** [`CHANGELOG.md`](CHANGELOG.md)
- **Gitea releases:** [releases page](https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/releases)
### How it works ### How it works
1. Open a PR targeting `main` (see [`.gitea/PULL_REQUEST_TEMPLATE.md`](.gitea/PULL_REQUEST_TEMPLATE.md)). 1. Open a PR targeting `main` (see [`.gitea/PULL_REQUEST_TEMPLATE.md`](.gitea/PULL_REQUEST_TEMPLATE.md)).
2. If the PR changes files under `python_repositories/`, the title **must** start with a version bump prefix (enforced by CI). 2. If the PR changes files under `python_repositories/`, the title **must** start with a version bump prefix (enforced by CI).
3. On merge, [`release.yml`](.gitea/workflows/release.yml) bumps [`pyproject.toml`](pyproject.toml) and syncs [`uv.lock`](uv.lock), commits, tags `vX.Y.Z`, creates a Gitea release with auto-generated notes, pushes the tag, and publishes the package to the Gitea Package Registry. 3. On merge, [`release.yml`](.gitea/workflows/release.yml) bumps [`pyproject.toml`](pyproject.toml) and syncs [`uv.lock`](uv.lock), updates [`CHANGELOG.md`](CHANGELOG.md), commits, tags `vX.Y.Z`, creates a Gitea release with auto-generated notes, pushes the tag, and publishes the package to the Gitea Package Registry.
4. [`publish.yml`](.gitea/workflows/publish.yml) handles manual `v*.*.*` tag pushes only (automated releases publish from `release.yml` because release commits use `[skip ci]`, which suppresses tag-push workflows). 4. [`publish.yml`](.gitea/workflows/publish.yml) handles manual `v*.*.*` tag pushes only (automated releases publish from `release.yml` because release commits use `[skip ci]`, which suppresses tag-push workflows).
Docs-, CI-, and test-only PRs do not need a prefix and will not trigger a release. Docs-, CI-, and test-only PRs do not need a prefix and will not trigger a release.
@@ -219,7 +222,7 @@ Example titles:
### Release notes ### Release notes
Release notes are generated from commits since the previous tag (see [`scripts/ci/generate-release-notes.sh`](scripts/ci/generate-release-notes.sh)). Release notes are generated from commits since the previous tag (see [`scripts/ci/generate-release-notes.sh`](scripts/ci/generate-release-notes.sh)). The same content is appended to [`CHANGELOG.md`](CHANGELOG.md) on each release (see [`scripts/ci/update-changelog.sh`](scripts/ci/update-changelog.sh)).
### Manual release ### Manual release
+2
View File
@@ -22,6 +22,8 @@ dependencies = [
[project.urls] [project.urls]
Repository = "https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories" Repository = "https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories"
Changelog = "https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/src/branch/main/CHANGELOG.md"
Releases = "https://gitea.lille-vemmelund.dk/LilleVemmelund/python-repositories/releases"
[project.optional-dependencies] [project.optional-dependencies]
redis = [ redis = [
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=common.sh
source "${SCRIPT_DIR}/common.sh"
CHANGELOG="CHANGELOG.md"
# Best-effort summary for historical releases without stored PR titles.
summary_for_range() {
local from_ref="$1"
local to_ref="$2"
local subject
while IFS= read -r subject; do
[[ -z "$subject" ]] && continue
if echo "$subject" | grep -qE '^chore: release v'; then
continue
fi
if echo "$subject" | grep -qE "^Merge pull request '"; then
local title
title=$(extract_pr_title_from_merge_commit "$subject")
if [[ -n "$title" ]]; then
strip_bump_prefix "$title"
return 0
fi
fi
echo "$subject"
return 0
done < <(git log "${from_ref}..${to_ref}" --pretty=format:'%s' 2>/dev/null || true)
echo "Release ${to_ref}"
}
TAGS=()
while IFS= read -r tag; do
TAGS+=("$tag")
done < <(git tag -l 'v*' --sort=version:refname)
if [[ ${#TAGS[@]} -eq 0 ]]; then
echo "No version tags found." >&2
exit 1
fi
changelog_header > "$CHANGELOG"
for ((i = ${#TAGS[@]} - 1; i >= 0; i--)); do
TAG="${TAGS[$i]}"
VERSION="${TAG#v}"
DATE=$(git log -1 --format=%cs "$TAG" 2>/dev/null || date -u +%Y-%m-%d)
if [[ $i -eq 0 ]]; then
PREV_TAG=""
else
PREV_TAG="${TAGS[$((i - 1))]}"
fi
SUMMARY=$(summary_for_range "$PREV_TAG" "$TAG")
COMMITS=$(commits_between "$PREV_TAG" "$TAG")
SECTION=$(changelog_section "$VERSION" "$DATE" "$SUMMARY" "$COMMITS")
printf '\n%s\n' "$SECTION" >> "$CHANGELOG"
done
echo "Generated ${CHANGELOG} from ${#TAGS[@]} tags." >&2
+53
View File
@@ -61,6 +61,59 @@ set_pyproject_version() {
rm -f pyproject.toml.bak rm -f pyproject.toml.bak
} }
# Returns markdown bullet list of commits between two refs (exclusive..inclusive).
# Optional third argument limits entries when from_ref is empty (release notes only).
commits_between() {
local from_ref="$1"
local to_ref="${2:-HEAD}"
local limit="${3:-}"
if [[ -z "$from_ref" ]]; then
if [[ -n "$limit" ]]; then
git log "${to_ref}" --pretty=format:'- %h %s' -"${limit}" 2>/dev/null || true
else
git log "${to_ref}" --pretty=format:'- %h %s' 2>/dev/null || true
fi
else
git log "${from_ref}..${to_ref}" --pretty=format:'- %h %s' 2>/dev/null || true
fi
}
commits_since() {
commits_between "$1" HEAD
}
changelog_header() {
cat <<'EOF'
# 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).
## [Unreleased]
EOF
}
changelog_section() {
local version="$1"
local date="$2"
local summary="$3"
local commits="$4"
cat <<EOF
## [${version}] - ${date}
### Summary
${summary}
### Changed
${commits:-- (no commits recorded)}
EOF
}
bump_semver() { bump_semver() {
local current="$1" local current="$1"
local bump_type="$2" local bump_type="$2"
+2 -2
View File
@@ -34,13 +34,13 @@ if [[ -n "$PREV_TAG" ]]; then
## Changes since ${PREV_TAG} ## Changes since ${PREV_TAG}
$(git log "${PREV_TAG}..HEAD" --pretty=format:'- %h %s' || true)" $(commits_since "$PREV_TAG")"
else else
NOTES="${NOTES} NOTES="${NOTES}
## Changes ## Changes
$(git log --pretty=format:'- %h %s' -20 || true)" $(commits_between "" HEAD 20)"
fi fi
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=common.sh
source "${SCRIPT_DIR}/common.sh"
VERSION="${1:-}"
SUMMARY="${2:-}"
PREV_TAG="${3:-}"
DATE="${4:-$(date -u +%Y-%m-%d)}"
CHANGELOG="CHANGELOG.md"
if [[ -z "$VERSION" ]]; then
echo "Usage: update-changelog.sh <version> <summary> <prev-tag> [date]" >&2
exit 1
fi
if [[ -f "$CHANGELOG" ]] && grep -qF "## [${VERSION}]" "$CHANGELOG"; then
echo "CHANGELOG already contains version ${VERSION}; skipping." >&2
exit 0
fi
if [[ -n "$SUMMARY" ]]; then
SUMMARY_TEXT=$(strip_bump_prefix "$SUMMARY")
else
SUMMARY_TEXT="Automated release v${VERSION}."
fi
COMMITS=$(commits_since "$PREV_TAG")
SECTION=$(changelog_section "$VERSION" "$DATE" "$SUMMARY_TEXT" "$COMMITS")
if [[ ! -f "$CHANGELOG" ]]; then
changelog_header > "$CHANGELOG"
printf '\n%s\n' "$SECTION" >> "$CHANGELOG"
else
UNRELEASED_MARKER='## [Unreleased]'
if ! grep -qF "$UNRELEASED_MARKER" "$CHANGELOG"; then
echo "CHANGELOG.md exists but is missing ${UNRELEASED_MARKER}" >&2
exit 1
fi
TMP=$(mktemp)
SECTION_FILE=$(mktemp)
printf '%s\n' "$SECTION" > "$SECTION_FILE"
awk -v section_file="$SECTION_FILE" '
/^## \[Unreleased\]/ {
print
print ""
while ((getline line < section_file) > 0) {
print line
}
close(section_file)
next
}
{ print }
' "$CHANGELOG" > "$TMP"
rm -f "$SECTION_FILE"
mv "$TMP" "$CHANGELOG"
fi
echo "Updated ${CHANGELOG} with version ${VERSION}." >&2