Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions generator/site/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func main() {
previous := flag.String("previous", "", "path to previous commands.json for new-command detection")
flag.Parse()

versionOut, err := exec.Command(*binary, "version").Output()
versionOut, err := exec.Command(*binary, "version", "-o", "json").Output()
if err != nil {
fmt.Fprintf(os.Stderr, "error running %s version: %v\n", *binary, err)
os.Exit(1)
Expand Down Expand Up @@ -369,13 +369,16 @@ func splitCSV(s string) []string {
}

func parseVersion(output string) string {
line, _, _ := strings.Cut(output, "\n")
fields := strings.Fields(line)
if len(fields) < 2 {
v := extractRawVersion(output)
if v == "" {
return "unknown"
}
v := fields[1]
// Strip git-describe suffix (e.g. "v1.2.0-52-gffc0b5a-dirty" → "v1.2.0")
// Drop the git-describe "-dirty" marker so the site shows the clean
// release tag. The deploy workflow builds from the latest release tag but
// overlays site files from main, which dirties the tree — without this a
// clean tag surfaces as "v1.17.0-dirty" instead of "v1.17.0".
v = strings.TrimSuffix(v, "-dirty")
// Strip git-describe suffix (e.g. "v1.2.0-52-gffc0b5a" → "v1.2.0")
if parts := strings.SplitN(v, "-", 2); len(parts) == 2 && strings.ContainsAny(parts[1], "0123456789") {
if _, err := strconv.Atoi(strings.Split(parts[1], "-")[0]); err == nil {
v = parts[0]
Expand All @@ -385,3 +388,24 @@ func parseVersion(output string) string {
v = strings.TrimPrefix(v, "v")
return v
}

// extractRawVersion pulls the raw version string out of `jamf-cli version`
// output. The command emits JSON by default (the global -o default is json),
// so we parse that first; older binaries that predate -o support print a
// "jamf-cli <version>" banner, so we fall back to that. Returns "" when
// neither yields a version, letting the caller map it to "unknown".
func extractRawVersion(output string) string {
if strings.HasPrefix(strings.TrimSpace(output), "{") {
var report struct {
Version string `json:"version"`
}
if json.Unmarshal([]byte(output), &report) == nil {
return report.Version
}
}
line, _, _ := strings.Cut(output, "\n")
if fields := strings.Fields(line); len(fields) >= 2 {
return fields[1]
}
return ""
}
25 changes: 25 additions & 0 deletions generator/site/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,31 @@ func TestParseVersion(t *testing.T) {
input: "",
want: "unknown",
},
{
name: "json default output strips git-describe suffix",
input: "{\n \"version\": \"v1.17.0-25-g74846ff\",\n \"commit\": \"74846ff\",\n \"built\": \"2026-05-31T04:31:46Z\"\n}\n",
want: "1.17.0",
},
{
name: "json exact tag",
input: `{"version":"v1.2.0","commit":"abc1234"}`,
want: "1.2.0",
},
{
name: "json empty version falls back to unknown",
input: `{"version":"","commit":"abc1234"}`,
want: "unknown",
},
{
name: "json exact tag dirty build strips dirty marker",
input: `{"version":"v1.17.0-dirty","commit":"abc1234"}`,
want: "1.17.0",
},
{
name: "json describe with count and dirty marker",
input: `{"version":"v1.17.0-25-g74846ff-dirty","commit":"74846ff"}`,
want: "1.17.0",
},
}

for _, tt := range tests {
Expand Down