Skip to content
Draft
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
36 changes: 30 additions & 6 deletions make_release/notes/generate.nu
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,9 @@ export def extract-notes []: string -> string {
# this should already have been checked
| if ($in | is-empty) { assert false } else {}
| skip 1 # remove header
# extract until next heading
| take until {
$in starts-with "# " or $in starts-with "## " or $in starts-with "---"
}
# extract until end of summary
| reduce -f {code: false, done: false, out: []} (extract_until_end)
| get out
| str join (char nl)
# remove HTML comments
| str replace -amr '<!--\O*?-->' ''
Expand Down Expand Up @@ -151,12 +150,12 @@ export def generate-section []: record<section: string, prs: table> -> string {
$body ++= $multiline.notes

# Add single-line summaries
if ($multiline | is-not-empty) {
if ($multiline | is-not-empty) and ($bullet | is-not-empty) {
$body ++= [$"### ($section.h3)"]
}
$body ++= $bullet | each {|pr| "* " ++ $pr.notes ++ $" \(($pr | pr-link)\)" }

$body | str join (char nl)
$body | str join $"(char nl)(char nl)"
}

# Generate the "Hall of Fame" section of the release notes.
Expand All @@ -178,6 +177,31 @@ export def generate-full-changelog [version: string]: nothing -> string {
| pr-table
}

# Create closure for `reduce` to extract the whole release notes summary.
def extract_until_end []: nothing -> closure {
let terminators = ["# " "## " "---"]
{|line: string, state: record|
mut state = $state

if $state.done { return $state }

# check if we're entering/exiting a code block
# this might be kind of brittle
if $line has "```" {
$state.code = not $state.code
}

let found_terminator = $terminators | any { $line starts-with $in }
if $found_terminator and not $state.code {
$state.done = true
return $state
}

$state.out ++= [$line]
$state
}
}

# Get section labels which don't have a corresponding heading (i.e., don't appear in Changes section)
def labels-without-heading [] {
$SECTIONS | where h2 == null | get label
Expand Down
39 changes: 29 additions & 10 deletions make_release/notes/tools.nu
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,16 @@ def query-prs [

let query = $query_parts | str join ' '

(gh --repo $repo pr list --state merged
--limit (inf | into int)
--json author,title,number,mergedAt,url,body,labels
--search $query)
| from json
let results = (
gh --repo $repo pr list --state merged
--limit (inf | into int)
--json author,title,number,mergedAt,url,body,labels
--search $query
| from json
)

assert ($results | is-not-empty) "Query returned no results"
$results
}

# Generate the release notes for the specified version.
Expand Down Expand Up @@ -148,11 +153,9 @@ export def write-toc [file: path] {
| each {|header|
let indent = '- ' | fill -w ($header.level * 2) -a right

let text = $header.line | str trim -l -c '#' | str trim -l
let text = if $text ends-with $toc {
$text | str substring ..<(-1 * ($toc | str length)) | str trim -r
} else {
$text
mut text = $header.line | str trim -l -c '#' | str trim -l
if $text ends-with $toc {
$text = $text | str substring ..<(-1 * ($toc | str length)) | str trim -r
}

let link = (
Expand All @@ -161,6 +164,22 @@ export def write-toc [file: path] {
| str kebab-case
)

# remove PR link from header, if applicable
let regex = r#'(?x) # verbose mode
(?<text>.+?) # the actual header text
\s+
\( # start PR link
\[\#\d+\] # PR number component
(?: # optional non-capturing group
\(.+?\) # link to PR
)? # end group
\)
'#
let prlink = $text | parse -r $regex
if ($prlink | is-not-empty) {
$text = $prlink.0.text
}

$"($indent)[_($text)_]\(#($link)-toc\)"
}
)
Expand Down