wails-release/internal/config/config.go

151 lines
4.8 KiB
Go
Raw Normal View History

package config
import (
"fmt"
"strings"
)
// Config is the complete set of inputs to the action, parsed from env.
type Config struct {
WorkingDirectory string
AppName string
Version string
WailsVersion string
ExtraBuildFlags string
DeveloperIDCertBase64 string
DeveloperIDCertPassword string
NotarizationMethod string // "api-key" | "apple-id" | "auto"
NotarizationAPIKeyBase64 string
NotarizationAPIKeyID string
NotarizationAPIIssuerID string
NotarizationAppleID string
NotarizationApplePassword string
NotarizationTeamID string
S3Bucket string
S3Key string
S3EndpointURL string
S3Region string
}
// Load reads the action's INPUT_* environment variables.
func Load(get func(string) string) *Config {
c := &Config{
WorkingDirectory: getOr(get, "INPUT_WORKING_DIRECTORY", "."),
AppName: get("INPUT_APP_NAME"),
Version: get("INPUT_VERSION"),
WailsVersion: get("INPUT_WAILS_VERSION"),
ExtraBuildFlags: get("INPUT_EXTRA_BUILD_FLAGS"),
DeveloperIDCertBase64: get("INPUT_DEVELOPER_ID_CERT_BASE64"),
DeveloperIDCertPassword: get("INPUT_DEVELOPER_ID_CERT_PASSWORD"),
NotarizationMethod: getOr(get, "INPUT_NOTARIZATION_METHOD", "auto"),
NotarizationAPIKeyBase64: get("INPUT_NOTARIZATION_API_KEY_BASE64"),
NotarizationAPIKeyID: get("INPUT_NOTARIZATION_API_KEY_ID"),
NotarizationAPIIssuerID: get("INPUT_NOTARIZATION_API_ISSUER_ID"),
NotarizationAppleID: get("INPUT_NOTARIZATION_APPLE_ID"),
NotarizationApplePassword: get("INPUT_NOTARIZATION_APPLE_PASSWORD"),
NotarizationTeamID: get("INPUT_NOTARIZATION_TEAM_ID"),
S3Bucket: get("INPUT_S3_BUCKET"),
S3Key: get("INPUT_S3_KEY"),
S3EndpointURL: get("INPUT_S3_ENDPOINT_URL"),
S3Region: getOr(get, "INPUT_S3_REGION", "us-east-1"),
}
return c
}
func getOr(get func(string) string, key, def string) string {
if v := get(key); v != "" {
return v
}
return def
}
// Validate checks structural rules. It does NOT touch the filesystem.
func (c *Config) Validate() error {
var missing []string
if c.DeveloperIDCertBase64 == "" {
missing = append(missing, "developer-id-cert-base64")
}
if c.DeveloperIDCertPassword == "" {
missing = append(missing, "developer-id-cert-password")
}
if len(missing) > 0 {
return fmt.Errorf("missing required input(s): %s", strings.Join(missing, ", "))
}
apiFields := []struct{ name, value string }{
{"notarization-api-key-base64", c.NotarizationAPIKeyBase64},
{"notarization-api-key-id", c.NotarizationAPIKeyID},
{"notarization-api-issuer-id", c.NotarizationAPIIssuerID},
}
appleFields := []struct{ name, value string }{
{"notarization-apple-id", c.NotarizationAppleID},
{"notarization-apple-password", c.NotarizationApplePassword},
{"notarization-team-id", c.NotarizationTeamID},
}
apiFilled, apiMissing := groupStatus(apiFields)
appleFilled, appleMissing := groupStatus(appleFields)
switch c.NotarizationMethod {
case "api-key":
if !apiFilled {
return fmt.Errorf("notarization-method=api-key requires: %s (missing: %s)",
joinNames(apiFields), strings.Join(apiMissing, ", "))
}
case "apple-id":
if !appleFilled {
return fmt.Errorf("notarization-method=apple-id requires: %s (missing: %s)",
joinNames(appleFields), strings.Join(appleMissing, ", "))
}
case "auto", "":
switch {
case apiFilled && appleFilled:
return fmt.Errorf("notarization credentials are ambiguous: both api-key and apple-id groups are populated; set notarization-method explicitly")
case !apiFilled && !appleFilled:
return fmt.Errorf("no notarization credentials supplied: populate either the api-key group (%s) or the apple-id group (%s)",
joinNames(apiFields), joinNames(appleFields))
}
default:
return fmt.Errorf("notarization-method must be one of api-key, apple-id, auto (got %q)", c.NotarizationMethod)
}
if c.S3Bucket != "" && c.S3Key == "" {
return fmt.Errorf("s3-bucket is set but s3-key is empty")
}
return nil
}
// ResolvedNotarizationMethod returns "api-key" or "apple-id" once Validate has succeeded.
func (c *Config) ResolvedNotarizationMethod() string {
if c.NotarizationMethod == "api-key" || c.NotarizationMethod == "apple-id" {
return c.NotarizationMethod
}
if c.NotarizationAPIKeyID != "" {
return "api-key"
}
return "apple-id"
}
func groupStatus(fields []struct{ name, value string }) (filled bool, missing []string) {
any := false
for _, f := range fields {
if f.value != "" {
any = true
} else {
missing = append(missing, f.name)
}
}
return any && len(missing) == 0, missing
}
func joinNames(fields []struct{ name, value string }) string {
names := make([]string, len(fields))
for i, f := range fields {
names[i] = f.name
}
return strings.Join(names, ", ")
}