diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e02aaca..809f2ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,22 @@ jobs: echo "::error::Invalid release tag format: $GITHUB_REF_NAME" exit 1 fi + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + cache: true + - name: Build the CLI for macOS and Linux + run: | + version="${GITHUB_REF_NAME#v}" + for platform in darwin-arm64 darwin-amd64 linux-arm64 linux-amd64; do + os="${platform%-*}" + arch="${platform#*-}" + GOOS="$os" GOARCH="$arch" CGO_ENABLED=0 \ + go build -trimpath -ldflags="-s -w -X main.version=$version" -o appmeta ./cmd/appmeta + zip -9 "appmeta-$version-${os/darwin/macos}-$arch.zip" appmeta + rm appmeta + done + ls -l appmeta-*.zip - name: Extract release notes from CHANGELOG.md run: | awk -v version="${GITHUB_REF_NAME#v}" '/^## \[/{f = ($0 ~ "^## \\[" version "\\]")} f' CHANGELOG.md > release-notes.md @@ -96,3 +112,5 @@ jobs: with: name: Version ${{ github.ref_name }} body_path: release-notes.md + files: appmeta-*.zip + fail_on_unmatched_files: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 3373b84..a93c2b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,6 @@ +## [1.0.1](https://github.com/mobile-next/appmeta/releases/tag/v1.0.1) (2026-09-29) +* Feat: releases include the `appmeta` CLI for macOS and Linux, on arm64 and amd64 +* Feat: `appmeta --version` prints the release version + ## [1.0.0](https://github.com/mobile-next/appmeta/releases/tag/v1.0.0) (2026-09-29) * Initial version diff --git a/cmd/appmeta/main.go b/cmd/appmeta/main.go index d328068..00c0e8a 100644 --- a/cmd/appmeta/main.go +++ b/cmd/appmeta/main.go @@ -12,6 +12,9 @@ import ( "github.com/mobile-next/appmeta" ) +// version is the release version; the release workflow sets it with -ldflags. +var version = "dev" + type options struct { iconPath string noIcon bool @@ -31,6 +34,7 @@ func newRootCommand(out io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "appmeta [flags] ", Short: "Print the metadata of an Android or iOS app as JSON", + Version: version, Args: cobra.ExactArgs(1), SilenceErrors: true, SilenceUsage: true, @@ -39,6 +43,8 @@ func newRootCommand(out io.Writer) *cobra.Command { }, } cmd.Flags().StringVar(&opts.iconPath, "icon", "", "also write the icon PNG to this file") + // Declared here so that cobra does not add it with a short form. + cmd.Flags().Bool("version", false, "print the version") cmd.Flags().BoolVar(&opts.noIcon, "no-icon", false, "omit the base64 icon from the JSON") return cmd } diff --git a/cmd/appmeta/main_test.go b/cmd/appmeta/main_test.go index ee1a827..3fd040e 100644 --- a/cmd/appmeta/main_test.go +++ b/cmd/appmeta/main_test.go @@ -73,6 +73,19 @@ func (closedPipe) Write([]byte) (int, error) { return 0, errClosedPipe } +func TestTheVersionFlagPrintsTheVersionWithoutAPath(t *testing.T) { + var out bytes.Buffer + cmd := newRootCommand(&out) + cmd.SetArgs([]string{"--version"}) + cmd.SetOut(&out) + if err := cmd.Execute(); err != nil { + t.Fatal(err) + } + if got, want := out.String(), "appmeta version "+version+"\n"; got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + func runCommand(t *testing.T, args ...string) error { t.Helper() var out bytes.Buffer @@ -101,6 +114,7 @@ func writeZipWithOneFile(t *testing.T, path, name string) { func TestThereAreNoShortFlagsExceptHelp(t *testing.T) { cmd := newRootCommand(&bytes.Buffer{}) cmd.InitDefaultHelpFlag() + cmd.InitDefaultVersionFlag() cmd.Flags().VisitAll(func(f *pflag.Flag) { if f.Shorthand != "" && f.Name != "help" { t.Errorf("--%s has short form -%s", f.Name, f.Shorthand)