Ctrl K
ComunidadGuías…

scripts/release_version_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package scripts

import (
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/usememos/memos/internal/version"
)

func TestDevelopmentVersion(t *testing.T) {
	original := version.Version
	t.Cleanup(func() { version.Version = original })
	for _, tc := range []struct{ date, version string }{
		{"2026-09-27T14:58:52Z", "26.09.27"},
		{"2026-10-01T00:30:00+08:00", "26.09.30"},
		{"2026-12-31T23:30:00-08:00", "27.01.1"},
	} {
		t.Run(tc.date, func(t *testing.T) {
			repo := t.TempDir()
			runGit := func(args ...string) {
				t.Helper()
				cmd := exec.Command("git", append([]string{"-C", repo, "-c", "user.name=Version Test", "-c", "user.email=test@example.com", "-c", "commit.gpgsign=false"}, args...)...)
				cmd.Env = append(os.Environ(), "GIT_AUTHOR_DATE=2020-01-01T00:00:00Z", "GIT_COMMITTER_DATE="+tc.date)
				out, err := cmd.CombinedOutput()
				require.NoError(t, err, string(out))
			}
			check := func(repo string) {
				t.Helper()
				sha, err := exec.Command("git", "-C", repo, "rev-parse", "HEAD").Output()
				require.NoError(t, err)
				cmd := exec.Command("bash", "release_version.sh", "development-version", repo)
				cmd.Env = append(os.Environ(), "TZ=Pacific/Honolulu")
				out, err := cmd.CombinedOutput()
				require.NoError(t, err, string(out))
				want := tc.version + "-dev." + strings.TrimSpace(string(sha))[:7] + "\n"
				require.Equal(t, want, string(out))
				// The script and the binary must name the same development build.
				version.Version = strings.TrimSpace(string(out))
				require.NoError(t, version.Validate())
			}
			runGit("init", "-b", "main")
			runGit("commit", "--allow-empty", "-m", "source")
			runGit("tag", "26.10.1")
			check(repo)
			require.NoError(t, os.WriteFile(filepath.Join(repo, "uncommitted"), []byte("local change"), 0o600))
			check(repo)

			shallow := filepath.Join(t.TempDir(), "shallow")
			out, err := exec.Command("git", "clone", "--depth=1", "file://"+repo, shallow).CombinedOutput()
			require.NoError(t, err, string(out))
			check(shallow)
		})
	}
	t.Run("no Git metadata", func(t *testing.T) {
		out, err := exec.Command("bash", "release_version.sh", "development-version", t.TempDir()).CombinedOutput()
		require.Error(t, err, string(out))
	})
}

func TestReleaseVersions(t *testing.T) {
	for _, tc := range []struct {
		tag, series, prerelease, images string
	}{
		{"26.09.0", "26.09", "false", "26.09.0\n26.09\nstable\n"},
		{"26.09.1", "26.09", "false", "26.09.1\n26.09\nstable\n"},
		{"26.09.10", "26.09", "false", "26.09.10\n26.09\nstable\n"},
		{"26.10.1", "26.10", "false", "26.10.1\n26.10\nstable\n"},
		{"27.01.0", "27.01", "false", "27.01.0\n27.01\nstable\n"},
		{"26.09.0-rc.1", "26.09", "true", "26.09.0-rc.1\n"},
		{"26.09.1-rc.2", "26.09", "true", "26.09.1-rc.2\n"},
	} {
		t.Run(tc.tag, func(t *testing.T) {
			out, err := exec.Command("bash", "release_version.sh", "version", tc.tag).CombinedOutput()
			require.NoError(t, err, string(out))
			require.Equal(t, "tag="+tc.tag+"\nversion="+tc.tag+"\nseries="+tc.series+"\nis_prerelease="+tc.prerelease+"\n", string(out))
			out, err = exec.Command("bash", "release_version.sh", "image-tags", tc.tag).CombinedOutput()
			require.NoError(t, err, string(out))
			require.Equal(t, tc.images, string(out))
		})
	}
	for _, tag := range []string{
		"v0.31.0", "v26.09.0", "v26.09.1", "v26.09.0-rc.1", "26.09", "26.09-rc.1", "26.9.0", "26.00.0", "26.13.0", "2026.09.0",
		"26.09.01", "26.09.0-rc.0", "26.09.0-rc.01", "26.09.0beta", "26.09.1+build", "26.09.1-dev.abc1234",
	} {
		out, err := exec.Command("bash", "release_version.sh", "version", tag).CombinedOutput()
		require.Error(t, err, tag)
		require.Contains(t, string(out), "Unsupported release tag")
	}
}

// The script and the binary must accept the same release tags, or a tag could
// build a binary that refuses to start. Development versions are binary-only.
func TestReleaseTagsMatchBinaryVersions(t *testing.T) {
	original := version.Version
	t.Cleanup(func() { version.Version = original })
	for _, tag := range []string{
		"26.09.0", "26.09.1", "26.09.10", "27.01.0", "26.09.0-rc.1", "26.09.1-rc.2",
		"v26.09.0", "0.31.0", "26.09", "26.9.0", "26.00.0", "26.13.0", "2026.09.0", "26.09.01", "26.09-rc.1", "26.09.0-rc.0", "26.09.0-rc.01",
		"26.09.1-dev.1", "26.09.1-dirty", "26.09.0beta", "26.09.1+build", "dev",
	} {
		scriptErr := exec.Command("bash", "release_version.sh", "version", tag).Run()
		version.Version = tag
		require.Equal(t, scriptErr == nil, version.Validate() == nil, tag)
	}
	version.Version = "26.09.1-dev.abc1234"
	require.NoError(t, version.Validate())
	require.Error(t, exec.Command("bash", "release_version.sh", "version", version.Version).Run())
}

func TestPreviousReleaseImage(t *testing.T) {
	repo := t.TempDir()
	runGit := func(args ...string) {
		t.Helper()
		cmd := exec.Command("git", append([]string{"-C", repo, "-c", "user.name=Release Test", "-c", "user.email=test@example.com", "-c", "commit.gpgsign=false"}, args...)...)
		out, err := cmd.CombinedOutput()
		require.NoError(t, err, string(out))
	}
	check := func(want string) {
		t.Helper()
		out, err := exec.Command("bash", "release_version.sh", "previous-tag", repo).CombinedOutput()
		require.NoError(t, err, string(out))
		require.Equal(t, want+"\n", string(out))
		out, err = exec.Command("bash", "release_version.sh", "previous-image", repo).CombinedOutput()
		require.NoError(t, err, string(out))
		require.Equal(t, "neosmemo/memos:"+strings.TrimPrefix(want, "v")+"\n", string(out))
	}
	runGit("init", "-b", "main")
	runGit("commit", "--allow-empty", "-m", "old")
	runGit("tag", "v0.30.0")
	runGit("commit", "--allow-empty", "-m", "baseline")
	runGit("tag", "v0.31.0")
	runGit("commit", "--allow-empty", "-m", "first calendar release")
	runGit("tag", "26.09.0")
	check("v0.31.0")
	runGit("commit", "--allow-empty", "-m", "point release")
	runGit("tag", "26.09.2")
	check("26.09.0")
	runGit("commit", "--allow-empty", "-m", "tenth point release")
	runGit("tag", "26.09.10")
	// Two-part tags are image aliases, never releases.
	runGit("tag", "99.99")
	runGit("commit", "--allow-empty", "-m", "release candidate")
	runGit("tag", "26.10.0-rc.1")
	check("26.09.10")
	runGit("commit", "--allow-empty", "-m", "after release candidate")
	check("26.09.10")
	runGit("checkout", "--orphan", "unrelated")
	runGit("commit", "--allow-empty", "-m", "unrelated release")
	runGit("tag", "29.01.0")
	runGit("checkout", "main")
	check("26.09.10")
	runGit("tag", "26.10.0")
	runGit("commit", "--allow-empty", "-m", "next year")
	runGit("tag", "27.01.0")
	check("26.10.0")
	// The floor excludes pre-baseline tags even if no supported release exists.
	repo = t.TempDir()
	runGit("init", "-b", "main")
	runGit("commit", "--allow-empty", "-m", "old")
	runGit("tag", "v0.30.0")
	runGit("commit", "--allow-empty", "-m", "candidate")
	for _, command := range []string{"previous-tag", "previous-image"} {
		out, err := exec.Command("bash", "release_version.sh", command, repo).CombinedOutput()
		require.Error(t, err, command)
		require.Contains(t, string(out), "No supported previous release found")
	}
}