diff --git a/cmd/new.go b/cmd/new.go index 1cf082d..a69440e 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -1,6 +1,7 @@ package cmd import ( + "encoding/json" "fmt" "os" "strings" @@ -20,7 +21,8 @@ var ( --product '2313b7e7-1ea6-4a01-901e-2931de6bb1e2' \ --token 'prod-xxx' \ --channel 'beta' \ - --version '1.0.0' + --version '1.0.0' \ + --metadata '{"key": "value"}' Docs: https://keygen.sh/docs/cli/`, @@ -41,6 +43,7 @@ type DraftCommandOptions struct { Package string Entitlements []string NoAutoUpgrade bool + Metadata string } func init() { @@ -57,9 +60,9 @@ func init() { draftCmd.Flags().StringVar(&draftOpts.Package, "package", "", "package identifier for the release") draftCmd.Flags().BoolVar(&draftOpts.NoAutoUpgrade, "no-auto-upgrade", false, "disable automatic upgrade checks [$KEYGEN_NO_AUTO_UPGRADE=1]") draftCmd.Flags().StringSliceVar(&draftOpts.Entitlements, "entitlements", []string{}, "comma seperated list of entitlement constraints (e.g. --entitlements ,,...)") + draftCmd.Flags().StringVar(&draftOpts.Metadata, "metadata", "", "JSON string of metadata key-value pairs") // TODO(ezekg) Prompt multi-line description input from stdin if "--"? - // TODO(ezekg) Add metadata flag if v, ok := os.LookupEnv("KEYGEN_ACCOUNT_ID"); ok { if keygenext.Account == "" { @@ -158,6 +161,13 @@ func draftRun(cmd *cobra.Command, args []string) error { return fmt.Errorf(`version "%s" is not acceptable (%s)`, draftOpts.Version, italic(strings.ToLower(err.Error()))) } + var metadata map[string]interface{} + if m := draftOpts.Metadata; m != "" { + if err := json.Unmarshal([]byte(m), &metadata); err != nil { + return fmt.Errorf("invalid metadata JSON: %v", err) + } + } + release := &keygenext.Release{ Name: name, Description: desc, @@ -167,6 +177,7 @@ func draftRun(cmd *cobra.Command, args []string) error { ProductID: keygenext.Product, PackageID: pkg, Constraints: constraints, + Metadata: metadata, } if err := release.Create(); err != nil { diff --git a/cmd/upload.go b/cmd/upload.go index 6875181..3ff6ae8 100644 --- a/cmd/upload.go +++ b/cmd/upload.go @@ -6,6 +6,7 @@ import ( "crypto/sha512" "encoding/base64" "encoding/hex" + "encoding/json" "errors" "fmt" "io" @@ -36,7 +37,8 @@ var ( --token 'prod-xxx' \ --release '1.0.0' \ --platform 'darwin' \ - --arch 'amd64' + --arch 'amd64' \ + --metadata '{"key": "value"}' Docs: https://keygen.sh/docs/cli/`, @@ -61,6 +63,7 @@ type UploadCommandOptions struct { SigningKeyPath string SigningKey string NoAutoUpgrade bool + Metadata string } func init() { @@ -80,6 +83,7 @@ func init() { uploadCmd.Flags().StringVar(&uploadOpts.SigningAlgorithm, "signing-algorithm", "ed25519ph", "the signing algorithm to use, one of: ed25519ph, ed25519") uploadCmd.Flags().StringVar(&uploadOpts.SigningKeyPath, "signing-key", "", "path to ed25519 private key for signing the artifact [$KEYGEN_SIGNING_KEY_PATH=, $KEYGEN_SIGNING_KEY=]") uploadCmd.Flags().BoolVar(&uploadOpts.NoAutoUpgrade, "no-auto-upgrade", false, "disable automatic upgrade checks [$KEYGEN_NO_AUTO_UPGRADE=1]") + uploadCmd.Flags().StringVar(&uploadOpts.Metadata, "metadata", "", "JSON string of metadata key-value pairs") if v, ok := os.LookupEnv("KEYGEN_ACCOUNT_ID"); ok { if keygenext.Account == "" { @@ -243,6 +247,13 @@ func uploadRun(cmd *cobra.Command, args []string) error { } } + var metadata map[string]interface{} + if m := uploadOpts.Metadata; m != "" { + if err := json.Unmarshal([]byte(m), &metadata); err != nil { + return fmt.Errorf("invalid metadata JSON: %v", err) + } + } + release := &keygenext.Release{ ID: uploadOpts.Release, PackageID: &uploadOpts.Package, @@ -274,6 +285,7 @@ func uploadRun(cmd *cobra.Command, args []string) error { Signature: signature, Checksum: checksum, ReleaseID: &release.ID, + Metadata: metadata, } if err := artifact.Create(); err != nil { diff --git a/internal/keygenext/artifact.go b/internal/keygenext/artifact.go index b0c5a10..e4fb3fb 100644 --- a/internal/keygenext/artifact.go +++ b/internal/keygenext/artifact.go @@ -13,16 +13,17 @@ import ( // Artifact represents a Keygen artifact object. type Artifact struct { - ID string `json:"-"` - Type string `json:"-"` - Filename string `json:"filename,omitempty"` - Filetype string `json:"filetype,omitempty"` - Filesize int64 `json:"filesize,omitempty"` - Platform string `json:"platform,omitempty"` - Arch string `json:"arch,omitempty"` - Signature string `json:"signature,omitempty"` - Checksum string `json:"checksum,omitempty"` - ReleaseID *string `json:"-"` + ID string `json:"-"` + Type string `json:"-"` + Filename string `json:"filename,omitempty"` + Filetype string `json:"filetype,omitempty"` + Filesize int64 `json:"filesize,omitempty"` + Platform string `json:"platform,omitempty"` + Arch string `json:"arch,omitempty"` + Signature string `json:"signature,omitempty"` + Checksum string `json:"checksum,omitempty"` + ReleaseID *string `json:"-"` + Metadata map[string]interface{} `json:"metadata,omitempty"` url string `json:"-"` }