Skip to content

Commit

Permalink
Switch to environment files for SetOutput and SaveState (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
sethvargo committed Oct 12, 2022
1 parent a0bd34b commit b3883e8
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 27 deletions.
47 changes: 25 additions & 22 deletions actions.go
Expand Up @@ -39,15 +39,16 @@ var (
)

const (
addMaskCmd = "add-mask"
setOutputCmd = "set-output"
saveStateCmd = "save-state"
addMaskCmd = "add-mask"

pathCmd = "path" // used when issuing the file command
envCmd = "env"
outputCmd = "output"
pathCmd = "path"
stateCmd = "state"

envCmd = "env" // used when issuing the file command
envCmdMsgFmt = "%s<<%s" + EOF + "%s" + EOF + "%s" // ${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}
envCmdDelimiter = "_GitHubActionsFileCommandDelimeter_"
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
multiLineFileDelim = "_GitHubActionsFileCommandDelimeter_"
multilineFileCmd = "%s<<" + multiLineFileDelim + EOF + "%s" + EOF + multiLineFileDelim // ${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}

addMatcherCmd = "add-matcher"
removeMatcherCmd = "remove-matcher"
Expand Down Expand Up @@ -196,14 +197,15 @@ func (c *Action) AddPath(p string) {

// SaveState saves state to be used in the "finally" post job entry point. It
// panics if it cannot write to the output stream.
//
// On 2022-10-11, GitHub deprecated "::save-state name=<k>::<v>" in favor of
// [environment files].
//
// [environment files]: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
func (c *Action) SaveState(k, v string) {
// ::save-state name=<k>::<v>
c.IssueCommand(&Command{
Name: saveStateCmd,
Message: v,
Properties: CommandProperties{
"name": k,
},
c.IssueFileCommand(&Command{
Name: stateCmd,
Message: fmt.Sprintf(multilineFileCmd, k, v),
})
}

Expand Down Expand Up @@ -275,20 +277,21 @@ func (c *Action) AddStepSummaryTemplate(tmpl string, data any) error {
func (c *Action) SetEnv(k, v string) {
c.IssueFileCommand(&Command{
Name: envCmd,
Message: fmt.Sprintf(envCmdMsgFmt, k, envCmdDelimiter, v, envCmdDelimiter),
Message: fmt.Sprintf(multilineFileCmd, k, v),
})
}

// SetOutput sets an output parameter. It panics if it cannot write to the
// output stream.
//
// On 2022-10-11, GitHub deprecated "::set-output name=<k>::<v>" in favor of
// [environment files].
//
// [environment files]: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
func (c *Action) SetOutput(k, v string) {
// ::set-output name=<k>::<v>
c.IssueCommand(&Command{
Name: setOutputCmd,
Message: v,
Properties: CommandProperties{
"name": k,
},
c.IssueFileCommand(&Command{
Name: outputCmd,
Message: fmt.Sprintf(multilineFileCmd, k, v),
})
}

Expand Down
54 changes: 49 additions & 5 deletions actions_test.go
Expand Up @@ -183,10 +183,32 @@ func TestAction_SaveState(t *testing.T) {
t.Parallel()

var b bytes.Buffer
a := New(WithWriter(&b))
file, err := os.CreateTemp("", "")
if err != nil {
t.Fatalf("unable to create a temp env file: %s", err)
}
defer os.Remove(file.Name())

fakeGetenvFunc := newFakeGetenvFunc(t, "GITHUB_STATE", file.Name())

a := New(WithWriter(&b), WithGetenv(fakeGetenvFunc))
a.SaveState("key", "value")
a.SaveState("key2", "value2")

// expect an empty stdout buffer
if got, want := b.String(), ""; got != want {
t.Errorf("expected %q to be %q", got, want)
}

// expect the command to be written to the file.
data, err := io.ReadAll(file)
if err != nil {
t.Errorf("unable to read temp env file: %s", err)
}

if got, want := b.String(), "::save-state name=key::value"+EOF; got != want {
want := "key<<_GitHubActionsFileCommandDelimeter_" + EOF + "value" + EOF + "_GitHubActionsFileCommandDelimeter_" + EOF
want += "key2<<_GitHubActionsFileCommandDelimeter_" + EOF + "value2" + EOF + "_GitHubActionsFileCommandDelimeter_" + EOF
if got := string(data); got != want {
t.Errorf("expected %q to be %q", got, want)
}
}
Expand Down Expand Up @@ -314,8 +336,8 @@ func TestAction_SetEnv(t *testing.T) {
if err != nil {
t.Fatalf("unable to create a temp env file: %s", err)
}

defer os.Remove(file.Name())

fakeGetenvFunc := newFakeGetenvFunc(t, "GITHUB_ENV", file.Name())
a := New(WithWriter(&b), WithGetenv(fakeGetenvFunc))
a.SetEnv("key", "value")
Expand Down Expand Up @@ -343,10 +365,32 @@ func TestAction_SetOutput(t *testing.T) {
t.Parallel()

var b bytes.Buffer
a := New(WithWriter(&b))
file, err := os.CreateTemp("", "")
if err != nil {
t.Fatalf("unable to create a temp env file: %s", err)
}
defer os.Remove(file.Name())

fakeGetenvFunc := newFakeGetenvFunc(t, "GITHUB_OUTPUT", file.Name())

a := New(WithWriter(&b), WithGetenv(fakeGetenvFunc))
a.SetOutput("key", "value")
a.SetOutput("key2", "value2")

// expect an empty stdout buffer
if got, want := b.String(), ""; got != want {
t.Errorf("expected %q to be %q", got, want)
}

// expect the command to be written to the file.
data, err := io.ReadAll(file)
if err != nil {
t.Errorf("unable to read temp env file: %s", err)
}

if got, want := b.String(), "::set-output name=key::value"+EOF; got != want {
want := "key<<_GitHubActionsFileCommandDelimeter_" + EOF + "value" + EOF + "_GitHubActionsFileCommandDelimeter_" + EOF
want += "key2<<_GitHubActionsFileCommandDelimeter_" + EOF + "value2" + EOF + "_GitHubActionsFileCommandDelimeter_" + EOF
if got := string(data); got != want {
t.Errorf("expected %q to be %q", got, want)
}
}
Expand Down

0 comments on commit b3883e8

Please sign in to comment.