All checks were successful
check / check (pull_request) Successful in 2m37s
No tag could be cut from this repo at all. Three independent blockers. goreleaser was configured for GitHub while the repo lives on Gitea: .goreleaser.yaml had a release: block but no gitea_urls:, so goreleaser defaulted to the GitHub API and a release would have failed or published somewhere nobody is looking. It now points at https://git.eeqj.de/api/v1. The version was a hardcoded Makefile constant, VERSION := 1.0.0-rc.1, so every local build claimed to be a release candidate that had never been tagged and did not exist, while git tag -l was empty and internal/globals defaulted to dev. The version now comes from git, via the new script/version: the exact tag with a leading v stripped when HEAD is on one (so a make build and a goreleaser build of the same commit report the same string, and it matches the archive names), otherwise dev-<12-char sha>, with -dirty appended in either case when tracked files are modified. Untracked files are not counted, matching git describe --dirty. goreleaser's snapshot template gets the same treatment: it was {{ incpatch .Version }}-next, which manufactures a release number from the last tag and, with no tags at all, from goreleaser's fabricated v0.0.0. That change had one non-obvious consequence. internal/cli/version.go gated its "this is a development build" notice on the version being exactly "dev", so as soon as untagged builds carried a commit sha the notice would have gone silent and an unreleased binary would have read as a release. The gate is now globals.IsDevVersion, a predicate over a string rather than a comparison against a global so that it can be tested, and it is tested at the boundary that matters: dev-<sha> and its -dirty variant are development builds, 1.0.0-dev and 1.0.0-rc.1 are not. The command writes to cmd.OutOrStdout() so its output can be asserted on at all. Releases now come from CI rather than a workstation: a tag-triggered .gitea/workflows/release.yml, with fetch-depth: 0 because a shallow checkout has no tags and would silently mislabel the release, and with the RELEASE_TOKEN repository secret passed as GITEA_TOKEN (documented in README.md; the runner's automatic token is deliberately not used, since it is not guaranteed to carry release write scope). script/release unsets any GITHUB_TOKEN or GITLAB_TOKEN it finds, because goreleaser picks its forge from whichever token variable is set and refuses to run when it sees more than one -- an unrelated runner token must not get to decide where these artifacts are published. make release and make release-snapshot were the last two Makefile targets that were not shims; they now call script/release and script/release-snapshot, which resolve goreleaser the way script/lint resolves the linter -- a PATH binary is accepted only at the pinned version, never as a silent fallback. script/bootstrap installs it from a sha256-verified GitHub release archive per REPO_POLICIES.md, through a separate script/install-goreleaser: separate because script/bootstrap hard-fails without a usable Docker daemon by design, and the release runner needs goreleaser without needing Docker. dist/ and .tool/ are gitignored and excluded from the Docker build context. Verified by running it: make release-snapshot produces the four linux,darwin x amd64,arm64 archives plus checksums.txt, and the binary from dist/ reports dev-<sha> with the development-build notice. Tag handling was exercised in a throwaway repository; no tag was created here, since that is the owner's call. Signing, SBOM, reproducible builds, shell completions and a man page remain out of scope.
51 lines
1.6 KiB
Go
51 lines
1.6 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"runtime"
|
|
|
|
"github.com/spf13/cobra"
|
|
"sneak.berlin/go/vaultik/internal/globals"
|
|
)
|
|
|
|
// NewVersionCommand creates the version command
|
|
func NewVersionCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "version",
|
|
Short: "Print version information",
|
|
Long: `Print version, git commit, and build information for vaultik.`,
|
|
Args: cobra.NoArgs,
|
|
Run: func(cmd *cobra.Command, _ []string) {
|
|
writeVersion(cmd.OutOrStdout())
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
// writeVersion prints the version report. It takes a writer rather than
|
|
// using os.Stdout directly so the output can be asserted on in tests.
|
|
func writeVersion(w io.Writer) {
|
|
_, _ = fmt.Fprintf(w, "vaultik %s\n", globals.Version)
|
|
_, _ = fmt.Fprintf(w, " commit: %s\n", globals.Commit)
|
|
_, _ = fmt.Fprintf(w, " build date: %s\n", globals.CommitDate)
|
|
_, _ = fmt.Fprintf(w, " go: %s\n", runtime.Version())
|
|
_, _ = fmt.Fprintf(w, " os/arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
|
|
_, _ = fmt.Fprintf(w, " author: %s\n", globals.Author)
|
|
_, _ = fmt.Fprintf(w, " homepage: %s\n", globals.Homepage)
|
|
_, _ = fmt.Fprintf(w, " license: %s\n", globals.License)
|
|
|
|
if globals.IsDevVersion(globals.Version) {
|
|
_, _ = fmt.Fprintln(w)
|
|
_, _ = fmt.Fprintln(w,
|
|
"This is a development build: it was not built from a tagged")
|
|
_, _ = fmt.Fprintln(w,
|
|
"commit, so it carries no release version. Released binaries")
|
|
_, _ = fmt.Fprintf(w,
|
|
"are published at %s\n", globals.ReleasesURL)
|
|
_, _ = fmt.Fprintln(w,
|
|
"and report their tag on the first line above.")
|
|
}
|
|
}
|