Harden release validation
This commit is contained in:
@@ -11,6 +11,45 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReleaseVersionValidationIsExact(t *testing.T) {
|
||||
repoRoot := releaseCheckRepoRoot(t)
|
||||
library := filepath.Join(repoRoot, "scripts", "release-lib.sh")
|
||||
workingDirectory := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(workingDirectory, "2"), nil, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range []struct {
|
||||
version string
|
||||
valid bool
|
||||
}{
|
||||
{version: "v0.0.0", valid: true},
|
||||
{version: "v1.2.3", valid: true},
|
||||
{version: "v10.200.3000", valid: true},
|
||||
{version: "1.2.3"},
|
||||
{version: "v01.2.3"},
|
||||
{version: "v1.02.3"},
|
||||
{version: "v1.2.03"},
|
||||
{version: "v1.2.3."},
|
||||
{version: "v1.2.3-rc.1"},
|
||||
{version: "v1.2.3+build"},
|
||||
{version: "v1.*.3"},
|
||||
{version: "v1.2.3\nv4.5.6"},
|
||||
} {
|
||||
t.Run(test.version, func(t *testing.T) {
|
||||
command := exec.Command("sh", "-c", `. "$1"; narratio_release_validate_version "$2"`, "release-version-test", library, test.version)
|
||||
command.Dir = workingDirectory
|
||||
err := command.Run()
|
||||
if test.valid && err != nil {
|
||||
t.Fatalf("valid version %q rejected: %v", test.version, err)
|
||||
}
|
||||
if !test.valid && err == nil {
|
||||
t.Fatalf("invalid version %q accepted", test.version)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssetBuilderRejectsUnsafeDestinations(t *testing.T) {
|
||||
repoRoot := releaseCheckRepoRoot(t)
|
||||
builder := filepath.Join(repoRoot, "scripts", "build-release-assets.sh")
|
||||
@@ -62,10 +101,15 @@ func TestAssetBuilderBuildsNamedAssetsAndChecksEmbeddedVersion(t *testing.T) {
|
||||
binDir := t.TempDir()
|
||||
writeFakeGo(t, filepath.Join(binDir, "go"))
|
||||
outputDir := filepath.Join(t.TempDir(), "assets")
|
||||
goLog := filepath.Join(t.TempDir(), "go.log")
|
||||
|
||||
command := exec.Command("sh", builder, "v1.2.3", outputDir)
|
||||
command.Dir = t.TempDir()
|
||||
command.Env = append(os.Environ(), "PATH="+binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
|
||||
command.Env = append(os.Environ(),
|
||||
"PATH="+binDir+string(os.PathListSeparator)+os.Getenv("PATH"),
|
||||
"GOWORK=/caller/controlled/go.work",
|
||||
"NARRATIO_RELEASE_ASSET_GO_LOG="+goLog,
|
||||
)
|
||||
output, err := command.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("asset builder error = %v\n%s", err, output)
|
||||
@@ -99,6 +143,15 @@ func TestAssetBuilderBuildsNamedAssetsAndChecksEmbeddedVersion(t *testing.T) {
|
||||
if got := versionOutput.String(); got != "narratio v1.2.3\n" {
|
||||
t.Fatalf("embedded version output = %q", got)
|
||||
}
|
||||
goCommands, err := os.ReadFile(goLog)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, line := range strings.Split(strings.TrimSpace(string(goCommands)), "\n") {
|
||||
if !strings.HasPrefix(line, "off ") {
|
||||
t.Fatalf("asset builder Go command did not receive GOWORK=off: %q", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCandidateCheckerRejectsMalformedVersionAndReleaseNotes(t *testing.T) {
|
||||
@@ -233,6 +286,10 @@ func writeFakeGo(t *testing.T, path string) {
|
||||
const fake = `#!/bin/sh
|
||||
set -eu
|
||||
|
||||
if [ -n "${NARRATIO_RELEASE_ASSET_GO_LOG:-}" ]; then
|
||||
printf '%s %s\n' "${GOWORK:-}" "$*" >> "$NARRATIO_RELEASE_ASSET_GO_LOG"
|
||||
fi
|
||||
|
||||
if [ "$1" = env ]; then
|
||||
case $2 in
|
||||
GOOS) printf '%s\n' linux ;;
|
||||
|
||||
Reference in New Issue
Block a user