From a315acf15fd808e6a0eab7da03338a6e17236462 Mon Sep 17 00:00:00 2001 From: SiorMeir Date: Sun, 26 Jul 2026 10:35:56 +0300 Subject: [PATCH] ci: add changelog fragment tooling (changie + fold script) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ports the changelog infrastructure from kai-scheduler/KAI-Scheduler (#1839): - hack/changelog-fold.sh: fold unreleased fragments into CHANGELOG.md - Makefile: changie, changelog, changelog-release, changelog-preview targets - .changie.yaml: fix issue URL to point to kai-scheduler/api Unblocks the Release — Prepare Changelog workflow (make changelog-release). Signed-off-by: SiorMeir --- .changie.yaml | 2 +- Makefile | 31 +++++++++++++++++++++++++ hack/changelog-fold.sh | 52 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100755 hack/changelog-fold.sh diff --git a/.changie.yaml b/.changie.yaml index 803d68c..656019e 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -7,7 +7,7 @@ versionExt: md fragmentFileFormat: '{{.Kind}}-{{.Time.Format "20060102-150405"}}' versionFormat: '## [{{.Version}}] - {{.Time.Format "2006-01-02"}}' kindFormat: '### {{.Kind}}' -changeFormat: '- {{.Body}}{{if .Custom.Issue}} [#{{.Custom.Issue}}](https://github.com/kai-scheduler/KAI-Scheduler/issues/{{.Custom.Issue}}){{end}}{{if .Custom.Author}} [{{.Custom.Author}}](https://github.com/{{.Custom.Author}}){{end}}' +changeFormat: '- {{.Body}}{{if .Custom.Issue}} [#{{.Custom.Issue}}](https://github.com/kai-scheduler/api/issues/{{.Custom.Issue}}){{end}}{{if .Custom.Author}} [{{.Custom.Author}}](https://github.com/{{.Custom.Author}}){{end}}' kinds: - label: Added - label: Changed diff --git a/Makefile b/Makefile index 45ab6c9..a5a01ff 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,14 @@ # SPDX-License-Identifier: Apache-2.0 CONTROLLER_TOOLS_VERSION ?= v0.20.1 +CHANGIE_VERSION ?= v1.25.0 LOCALBIN ?= $(shell pwd)/bin $(LOCALBIN): mkdir -p $(LOCALBIN) CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +CHANGIE ?= $(LOCALBIN)/changie # CRDs derived from Kubernetes projects that require the Kubernetes copyright header. K8S_COPYRIGHTED_MANIFEST_FILES := config/crd/kai.scheduler_topologies.yaml @@ -51,6 +53,35 @@ manifests: controller-gen ## Generate CustomResourceDefinition objects. clients: ## Generate clientset, listers, and informers. hack/update-client.sh +.PHONY: changie +changie: $(CHANGIE) ## Download changie locally if necessary. +$(CHANGIE): $(LOCALBIN) + test -s $(LOCALBIN)/changie || GOBIN=$(LOCALBIN) go install github.com/miniscruff/changie@$(CHANGIE_VERSION) + +.PHONY: changelog +changelog: changie ## Add a changelog entry. Agents: make changelog KIND=Fixed BODY="...". Humans: make changelog (interactive). + @if [ -n "$(KIND)" ] && [ -n "$(BODY)" ]; then \ + kind_lower=$$(echo "$(KIND)" | tr '[:upper:]' '[:lower:]'); \ + ts=$$(date '+%Y%m%d-%H%M%S'); \ + out=".changes/unreleased/$${kind_lower}-$${ts}.yaml"; \ + printf 'kind: %s\nbody: |-\n %s\n' "$(KIND)" "$(BODY)" > "$${out}"; \ + echo "Created $${out}"; \ + elif [ -n "$(KIND)" ] || [ -n "$(BODY)" ]; then \ + echo "Both KIND and BODY must be set for non-interactive mode"; exit 1; \ + else \ + $(CHANGIE) new; \ + fi + +.PHONY: changelog-release +changelog-release: changie ## Fold unreleased fragments into CHANGELOG.md as VERSION and clear them. Usage: make changelog-release VERSION=v0.1.1 + @test -n "$(VERSION)" || { echo "VERSION is required, e.g. make changelog-release VERSION=v0.1.1"; exit 1; } + CHANGIE=$(CHANGIE) bash hack/changelog-fold.sh $(VERSION) + +.PHONY: changelog-preview +changelog-preview: changie ## Preview the next release section without writing anything. Usage: make changelog-preview VERSION=v0.1.1 + @test -n "$(VERSION)" || { echo "VERSION is required, e.g. make changelog-preview VERSION=v0.1.1"; exit 1; } + $(CHANGIE) batch $(VERSION) --dry-run + .PHONY: controller-gen controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. $(CONTROLLER_GEN): $(LOCALBIN) diff --git a/hack/changelog-fold.sh b/hack/changelog-fold.sh new file mode 100755 index 0000000..567bab2 --- /dev/null +++ b/hack/changelog-fold.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Copyright 2026 NVIDIA CORPORATION +# SPDX-License-Identifier: Apache-2.0 + +# Fold pending changie fragments into CHANGELOG.md as a new released version section, +# then clear the fragments. CHANGELOG.md is the source of truth — this edits it in place +# and does NOT keep a per-version archive. +# +# Usage: hack/changelog-fold.sh vX.Y.Z +# CHANGIE=/path/to/changie hack/changelog-fold.sh v0.17.0 # override the binary +# +# The new section is rendered by `changie batch --dry-run` (no disk writes, fragments left +# intact) and inserted immediately before the newest existing version heading, keeping one +# blank line between versions per Keep a Changelog. Fragments are removed only after the +# CHANGELOG.md write succeeds. +set -euo pipefail + +VERSION="${1:-}" +if [ -z "$VERSION" ]; then + echo "usage: $0 vX.Y.Z" >&2 + exit 1 +fi + +CHANGIE="${CHANGIE:-bin/changie}" +if [ ! -x "$CHANGIE" ]; then + echo "changie not found at '$CHANGIE' — run: make changie" >&2 + exit 1 +fi + +CHANGELOG="CHANGELOG.md" + +# Render the version section only (no header, no disk mutation, fragments untouched). +section="$("$CHANGIE" batch "$VERSION" --dry-run)" +if [ -z "$section" ]; then + echo "no unreleased fragments to release for $VERSION" >&2 + exit 1 +fi + +# Insert the section before the first existing "## [" heading (one blank line between). +# Falls back to appending after the header block if the changelog has no versions yet. +SECTION="$section" awk ' + BEGIN { sec = ENVIRON["SECTION"] } + /^## \[/ && !ins { print sec "\n"; ins = 1 } + { print } + END { if (!ins) print "\n" sec } +' "$CHANGELOG" > "$CHANGELOG.tmp" +mv "$CHANGELOG.tmp" "$CHANGELOG" + +# Clear the folded fragments (keep the directory + .gitkeep). +find .changes/unreleased -maxdepth 1 -type f -name '*.yaml' -delete + +echo "Folded $(basename "$VERSION") into $CHANGELOG and cleared fragments."