Changelog Automation

This commit is contained in:
2026-05-06 13:51:00 +02:00
parent a7b4c4a908
commit 90ba281f1b
4 changed files with 698 additions and 0 deletions
+86
View File
@@ -11,6 +11,7 @@ import (
"sync"
"time"
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/changelog"
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/pipeline"
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project"
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/topdata"
@@ -158,6 +159,11 @@ var commands = []command{
description: "Deploy generated wiki pages to NodeBB.",
run: runDeployWiki,
},
{
name: "build-changelog",
description: "Build a release changelog from tagged pull requests and write it to stdout or a file.",
run: runBuildChangelog,
},
}
func Run(args []string) (int, error) {
@@ -830,6 +836,86 @@ func parseDeployWikiArgs(commandName string, args []string) (topdata.DeployWikiO
return opts, nil
}
type buildChangelogOptions struct {
configPath string
outputPath string
currentTag string
previousTag string
apiBaseURL string
token string
}
func runBuildChangelog(ctx context) error {
opts, err := parseBuildChangelogArgs("build-changelog", ctx.args[1:])
if err != nil {
return err
}
return changelog.Generate(changelog.Options{
RepoRoot: ctx.cwd,
ConfigPath: opts.configPath,
OutputPath: opts.outputPath,
CurrentTag: opts.currentTag,
PreviousTag: opts.previousTag,
APIBaseURL: opts.apiBaseURL,
Token: opts.token,
Stdout: ctx.stdout,
})
}
func parseBuildChangelogArgs(commandName string, args []string) (buildChangelogOptions, error) {
opts := buildChangelogOptions{}
usage := fmt.Errorf("usage: %s [--config <path>] [--output <path>] [--current-tag <tag>] [--previous-tag <tag>] [--api-base-url <url>] [--token <token>]", commandName)
for i := 0; i < len(args); i++ {
arg := args[i]
switch arg {
case "--config":
i++
if i >= len(args) || strings.TrimSpace(args[i]) == "" {
return opts, usage
}
opts.configPath = args[i]
case "--output":
i++
if i >= len(args) || strings.TrimSpace(args[i]) == "" {
return opts, usage
}
opts.outputPath = args[i]
case "--current-tag":
i++
if i >= len(args) || strings.TrimSpace(args[i]) == "" {
return opts, usage
}
opts.currentTag = args[i]
case "--previous-tag":
i++
if i >= len(args) || strings.TrimSpace(args[i]) == "" {
return opts, usage
}
opts.previousTag = args[i]
case "--api-base-url":
i++
if i >= len(args) || strings.TrimSpace(args[i]) == "" {
return opts, usage
}
opts.apiBaseURL = args[i]
case "--token":
i++
if i >= len(args) || strings.TrimSpace(args[i]) == "" {
return opts, usage
}
opts.token = args[i]
case "-h", "--help":
return opts, usage
default:
return opts, fmt.Errorf("unknown %s argument %q", commandName, arg)
}
}
return opts, nil
}
func parseWikiCategoryList(raw string, target map[string]int) error {
for _, part := range strings.Split(raw, ",") {
part = strings.TrimSpace(part)