feat: link each changelog entry to its PR and commit
CI / Checks (pull_request) Successful in 23s
PR title / Conventional title (pull_request) Successful in 2s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-11 11:08:25 +02:00
1 parent 1c8d69d957
commit 718e2f881e
3 files changed
+16 -1

No files matched your search

+3
View File
@@ -25,6 +25,7 @@ Hello world 👋
### {{ group | striptags | trim }} ### {{ group | striptags | trim }}
{% for commit in commits %} {% for commit in commits %}
- {% if commit.breaking %}**Breaking:** {% endif %}{{ commit.message | split(pat="\n") | first | upper_first | trim }} \ - {% if commit.breaking %}**Breaking:** {% endif %}{{ commit.message | split(pat="\n") | first | upper_first | trim }} \
([{{ commit.id | truncate(length=7, end="") }}](https://git.kebcloud.no/keb/lazysecrets/commit/{{ commit.id }}))\
{% endfor %} {% endfor %}
{% endfor %}\n {% endfor %}\n
""" """
@@ -33,6 +34,8 @@ trim = true
# Runs on each part (header, every release) separately. # Runs on each part (header, every release) separately.
postprocessors = [ postprocessors = [
{ pattern = "\n{3,}", replace = "\n\n" }, { pattern = "\n{3,}", replace = "\n\n" },
# Squash commits end in the PR's number: link it.
{ pattern = "\\(#([0-9]+)\\)", replace = "([#${1}](https://git.kebcloud.no/keb/lazysecrets/pulls/${1}))" },
] ]
[git] [git]
+6 -1
View File
@@ -22,6 +22,7 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@@ -49,9 +50,13 @@ type Release struct {
// every release ends with. // every release ends with.
func (r Release) Notes() string { func (r Release) Notes() string {
notes, _, _ := strings.Cut(r.Body, "## Install") notes, _, _ := strings.Cut(r.Body, "## Install")
return strings.TrimSpace(notes) return mdLink.ReplaceAllString(strings.TrimSpace(notes), "$1")
} }
// mdLink is a Markdown link, [text](url): the notes link PRs and commits,
// and a terminal shows them as their text.
var mdLink = regexp.MustCompile(`\[([^\]]+)\]\((https?://[^)\s]+)\)`)
// Client talks to the release server. // Client talks to the release server.
type Client struct { type Client struct {
API string // the repository's API, DefaultAPI when empty API string // the repository's API, DefaultAPI when empty
+7
View File
@@ -123,3 +123,10 @@ func TestInstallRefusesATamperedArchive(t *testing.T) {
t.Error("replaced anyway") t.Error("replaced anyway")
} }
} }
func TestNotesShowLinksAsText(t *testing.T) {
r := Release{Body: "### Added\n\n- Search ([#11](https://git.example.com/pulls/11)) ([65dc2d7](https://git.example.com/commit/65dc2d7abc))\n\n## Install\n\ncurl …"}
if got, want := r.Notes(), "### Added\n\n- Search (#11) (65dc2d7)"; got != want {
t.Errorf("notes %q, want %q", got, want)
}
}