diff --git a/.github/scripts/build_packages.py b/.github/scripts/build_packages.py
index e8c2ccfb..3a78a28a 100644
--- a/.github/scripts/build_packages.py
+++ b/.github/scripts/build_packages.py
@@ -9,8 +9,9 @@
The templates in packaging/ hold the shape. This fills them from the one place
each value lives: the version from the tag, the checksums from the release's
own checksum file, the addresses from go.mod and web/public/CNAME, the date
-from CHANGELOG.md. Nothing is typed twice, and the two values that are - the
-product's name and its licence - are held to their Go originals by a guard.
+from CHANGELOG.md. Nothing is typed twice, and the three values that are - the
+product's name, its licence and its copyright line - are held to their Go
+originals by a guard.
Usage:
python .github/scripts/build_packages.py --tag v0.4.0 \\
@@ -50,6 +51,11 @@
APP_NAME = "Testing Files Generator"
LICENCE = "GPL-3.0-only"
+# The line tfg license prints, held by a guard to internal/version/version.go.
+# Chocolatey's moderation asked for it in the nuspec after 0.4.0, and it
+# refuses one shorter than four characters (rule CPMR0001).
+COPYRIGHT = "Copyright (C) 2026 DonislawDev"
+
# The name both feeds show as the author, and the first part of the WinGet
# identifiers - the same publisher folder the sibling project already has in
# winget-pkgs.
@@ -258,6 +264,7 @@ def values(package, version, tag, sums):
"EXE": package.program + ".exe",
"MONIKER": package.moniker,
"LICENSE": LICENCE,
+ "COPYRIGHT": COPYRIGHT,
"REPO_URL": repo_url,
"PROJECT_URL": site(),
"DOCS_URL": site() + "docs/",
diff --git a/internal/guard/packaging_test.go b/internal/guard/packaging_test.go
index b4bdb086..f3dc6267 100644
--- a/internal/guard/packaging_test.go
+++ b/internal/guard/packaging_test.go
@@ -457,6 +457,38 @@ func TestThePackagesNameTheProductAndLicenceTheProgramDoes(t *testing.T) {
}
}
+// Every package carries, once, the copyright line tfg license prints.
+// Chocolatey's moderation asked for it after 0.4.0 and refuses one shorter than
+// four characters (rule CPMR0001), and winget show prints it. Read from what
+// the renderer wrote rather than from its copy, so a template that loses the
+// element fails here as surely as a copy that drifts from the program.
+func TestEveryPackageCarriesTheCopyrightTheProgramPrints(t *testing.T) {
+ lines := regexp.MustCompile(`(?m)^Copyright \(C\) .+$`).FindAllString(
+ readRepoFile(t, "internal/version/version.go"), -1)
+ if len(lines) != 1 {
+ t.Fatalf("internal/version/version.go holds %d copyright lines, not one - "+
+ "there is no single line to hold the packages to", len(lines))
+ }
+ nuspec := `([^<]*)`
+ locale := `(?m)^Copyright: (.*)$`
+ files := renderedPackages(t)
+ for _, pkg := range []struct{ file, pattern string }{
+ {windowChoco + "testing-files-generator.nuspec", nuspec},
+ {cliChoco + "testing-files-generator-cli.nuspec", nuspec},
+ {windowWinget + ".locale.en-US.yaml", locale},
+ {cliWinget + ".locale.en-US.yaml", locale},
+ } {
+ found := regexp.MustCompile(pkg.pattern).FindAllStringSubmatch(files[pkg.file], -1)
+ if len(found) != 1 {
+ t.Errorf("%s carries %d copyright lines, not one", pkg.file, len(found))
+ continue
+ }
+ if found[0][1] != lines[0] {
+ t.Errorf("%s gives the copyright as %q and tfg license as %q", pkg.file, found[0][1], lines[0])
+ }
+ }
+}
+
// The package sources are in git. Chocolatey's moderation asks packageSourceUrl
// to point at them, the job in ci.yml renders them on a fresh clone, and the
// point of a package source is that somebody else can see what the package
diff --git a/packaging/README.md b/packaging/README.md
index 7989efe5..24d94bf4 100644
--- a/packaging/README.md
+++ b/packaging/README.md
@@ -4,8 +4,9 @@ These are **templates**, not packages. Every `{{PLACEHOLDER}}` is filled by
`.github/scripts/build_packages.py` from the one place that owns the value: the
version from the release tag, the checksums from that release's
`verify-SHA256SUMS.txt`, the addresses from `go.mod` and `web/public/CNAME`, the
-release date from `CHANGELOG.md`. The two values the renderer keeps a copy of,
-the product name and the licence, are held to their Go originals by a guard.
+release date from `CHANGELOG.md`. The three values the renderer keeps a copy
+of, the product name, the licence and the copyright line, are held to their Go
+originals by a guard.
python .github/scripts/build_packages.py --tag v0.4.0 \
--sums verify-SHA256SUMS.txt --out
diff --git a/packaging/chocolatey/package.nuspec.in b/packaging/chocolatey/package.nuspec.in
index 7a9febb4..75e31f03 100644
--- a/packaging/chocolatey/package.nuspec.in
+++ b/packaging/chocolatey/package.nuspec.in
@@ -11,6 +11,7 @@
{{PROJECT_URL}}
{{ICON_URL}}
{{LICENSE_URL}}
+ {{COPYRIGHT}}
false
{{REPO_URL}}
{{DOCS_URL}}
diff --git a/packaging/winget/locale.en-US.yaml.in b/packaging/winget/locale.en-US.yaml.in
index eee61d6f..48736689 100644
--- a/packaging/winget/locale.en-US.yaml.in
+++ b/packaging/winget/locale.en-US.yaml.in
@@ -11,6 +11,7 @@ PackageName: {{TITLE}}
PackageUrl: {{PROJECT_URL}}
License: {{LICENSE}}
LicenseUrl: {{LICENSE_URL}}
+Copyright: {{COPYRIGHT}}
ShortDescription: {{SHORT_DESCRIPTION}}
Description: |-
{{DESCRIPTION}}