diff --git a/CHANGELOG.md b/CHANGELOG.md index 456edd3..a4f4238 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## [2.1.0] - +* [#28] Allow setting a custom timezone for 'Build Triggered' time * [#29] Added ability to add custom image to `MessageCard`. ## [2.0.0] - 28th Feb 2021 diff --git a/action.go b/action.go index 5f6dfac..73ec668 100644 --- a/action.go +++ b/action.go @@ -3,6 +3,8 @@ package main import ( "encoding/json" "fmt" + + "github.com/bitrise-io/go-utils/colorstring" ) // Action object within the `actions` JSON object array. @@ -21,8 +23,8 @@ func parseActions(jsonString string) []Action { var actionList []Action err := json.Unmarshal([]byte(jsonString), &actionList) if err != nil { - fmt.Println(fmt.Sprintf("Couldn't Unmarshal JSON: %v, \n %s", jsonString, err)) + fmt.Println(colorstring.Redf("Couldn't Unmarshal JSON: %v, \n %s", jsonString, err)) } - fmt.Println(fmt.Sprintf("JSON value: %v", actionList)) + fmt.Printf("JSON value: %v", actionList) return actionList } diff --git a/config.go b/config.go index f1fca60..8664b00 100644 --- a/config.go +++ b/config.go @@ -32,4 +32,5 @@ type config struct { EnableDebug string `env:"enable_debug"` RepoURL string `env:"repository_url"` Actions string `env:"actions"` + Timezone string `env:"timezone"` } diff --git a/go.mod b/go.mod index 8626699..fe54f94 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.16 require ( github.com/bitrise-io/go-steputils v0.0.0-20201016102104-03ae3a6ded35 - github.com/bitrise-io/go-utils v0.0.0-20201211082830-859032e9adf0 // indirect + github.com/bitrise-io/go-utils v0.0.0-20201211082830-859032e9adf0 ) diff --git a/main.go b/main.go index 109a59f..8dccc9f 100644 --- a/main.go +++ b/main.go @@ -5,12 +5,14 @@ import ( "encoding/json" "fmt" "io/ioutil" + "log" "net/http" "os" "strconv" "time" "github.com/bitrise-io/go-steputils/stepconf" + "github.com/bitrise-io/go-utils/colorstring" ) var buildSucceeded = os.Getenv("BITRISE_BUILD_STATUS") == "0" @@ -33,6 +35,25 @@ func valueOptionToBool(userValue string) bool { return userValue == "yes" } +func parseTimeString(cfg config) string { + var timeAtLoc time.Time + i, err := strconv.ParseInt(cfg.BuildTime, 10, 64) + if err != nil { + return string("Couldn't parse build time") + } + loc, err := time.LoadLocation(cfg.Timezone) + if err != nil { + fmt.Println(colorstring.Redf("\n%s", err)) + fmt.Println(colorstring.Cyan("\nExporting time in UTC...\n")) + + timeAtLoc = time.Unix(i, 0).In(time.UTC) + return timeAtLoc.Format(time.RFC1123) + } + timeAtLoc = time.Unix(i, 0).In(loc) + + return timeAtLoc.Format(time.RFC1123) +} + func newMessage(cfg config, buildSuccessful bool) Message { message := Message{} message.Type = "MessageCard" @@ -130,15 +151,9 @@ func buildFactsSection(cfg config, buildSuccessful bool) Section { Value: cfg.GitBranch, } - i, err := strconv.ParseInt(cfg.BuildTime, 10, 64) - if err != nil { - _ = fmt.Errorf("failed to parse the given build time: %s", err) - } - // Force UTC, as it otherwise defaults to locale of executing system - parsedTime := time.Unix(i, 0).In(time.UTC) buildTimeFact := Fact{ Name: "Build Triggered", - Value: parsedTime.Format(time.RFC1123), + Value: parseTimeString(cfg), } workflowFact := Fact{ @@ -174,9 +189,8 @@ func postMessage(webhookURL string, msg Message, debugEnabled bool) error { if err != nil { return err } - fmt.Println(fmt.Sprintf("Request to Microsoft Teams: %s", webhookURL)) if debugEnabled { - fmt.Println(fmt.Sprintf("JSON body: %s\n", b)) + log.Print(colorstring.Yellowf("\nRequest to Microsoft Teams:\n%s", b)) } resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(b)) @@ -203,16 +217,14 @@ func postMessage(webhookURL string, msg Message, debugEnabled bool) error { func main() { var cfg config if err := stepconf.Parse(&cfg); err != nil { - fmt.Fprintf(os.Stderr, "Error: %s\n", err) - os.Exit(1) + log.Fatalf("Error: %s\n", err) } stepconf.Print(cfg) message := newMessage(cfg, buildSucceeded) if err := postMessage(cfg.WebhookURL, message, valueOptionToBool(cfg.EnableDebug)); err != nil { - fmt.Println(fmt.Sprintf("Error: %s", err)) - os.Exit(1) + log.Fatalf("Error: %s", err) } - fmt.Println("Message successfully sent!") + fmt.Println(colorstring.Cyan("\nMessage successfully sent!")) } diff --git a/main_test.go b/main_test.go index 4631f5e..b2ddbd0 100644 --- a/main_test.go +++ b/main_test.go @@ -83,6 +83,49 @@ func TestOptionalUserValue(t *testing.T) { } } +func TestParseTimeString(t *testing.T) { + + var tests = []struct { + input config + expected string + }{ + // successful UTC + { + mockConfig, + parsedUnixTime, + }, + // successful local + { + config{ + BuildTime: unixTimeString, + Timezone: "Australia/Sydney", + }, + "Sat, 16 Jan 2021 14:44:52 AEDT", + }, + // invalid timezone, returns UTC + { + config{ + BuildTime: unixTimeString, + Timezone: "Bermuda Triangle", + }, + parsedUnixTime, + }, + // invalid `buildTime`` + { + config{ + BuildTime: "unixTimeString", + }, + string("Couldn't parse build time"), + }, + } + + for _, test := range tests { + if output := parseTimeString(test.input); output != test.expected { + t.Errorf("Test failed: output was %v, expected %v", output, test.expected) + } + } +} + func TestBuildPrimarySection(t *testing.T) { var defaultValuesConfig = config{ SectionTitle: "Some author", diff --git a/step.yml b/step.yml index 0a74121..4759568 100644 --- a/step.yml +++ b/step.yml @@ -226,3 +226,15 @@ inputs: * Select **Incoming Webhook* and in the text input type **Bitrise** * Save and copy the link to the input for this step is_required: true + + - timezone: UTC + opts: + category: "MessageCard Content" + title: "Timezone" + summary: "Sets the timezone to use for the 'Build triggered' time" + description: | + Sets the timezone to use for the 'Build triggered' time in the MessageCard. + + Defaults to UTC if no value is given. + + Valid timezone name inputs can be [found here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).