Skip to content

Commit

Permalink
gitlab: prefix outputs with action's name (#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
giautm authored Dec 25, 2024
1 parent 02e5011 commit 67c0c25
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 52 deletions.
29 changes: 19 additions & 10 deletions atlasaction/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -1240,26 +1240,35 @@ func RenderTemplate(name string, data any) (string, error) {
return buf.String(), nil
}

// toEnvVar converts the given string to an environment variable name.
func toEnvVar(s string) string {
// toEnvName converts the given string to an environment variable name.
func toEnvName(s string) string {
return strings.ToUpper(strings.NewReplacer(
" ", "_", "-", "_", "/", "_",
).Replace(s))
}

// writeBashEnv writes the given name and value to the bash environment file.
func writeBashEnv(path, name, value string) error {
// toInputVarName converts the given string to an input variable name.
func toInputVarName(input string) string {
return fmt.Sprintf("ATLAS_INPUT_%s", toEnvName(input))
}

// toOutputVar converts the given values to an output variable.
// The action and output are used to create the output variable name with the format:
// ATLAS_OUTPUT_<ACTION>_<OUTPUT>="<value>"
func toOutputVar(action, output, value string) string {
return fmt.Sprintf("ATLAS_OUTPUT_%s=%q", toEnvName(action+"_"+output), value)
}

// fprintln writes the given values to the file using fmt.Fprintln.
func fprintln(name string, val ...any) error {
// Write the output to a file.
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
f, err := os.OpenFile(name, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer f.Close()
_, err = fmt.Fprintf(f, "export %s=%q\n", name, value)
if err != nil {
return err
}
return nil
_, err = fmt.Fprintln(f, val...)
return err
}

// commentMarker creates a hidden marker to identify the comment as one created by this action.
Expand Down
10 changes: 5 additions & 5 deletions atlasaction/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (a *bbPipe) GetTriggerContext(context.Context) (*TriggerContext, error) {

// GetInput implements the Action interface.
func (a *bbPipe) GetInput(name string) string {
return strings.TrimSpace(a.getenv("ATLAS_INPUT_" + toEnvVar(name)))
return strings.TrimSpace(a.getenv(toInputVarName(name)))
}

// SetOutput implements Action.
Expand All @@ -104,11 +104,11 @@ func (a *bbPipe) SetOutput(name, value string) {
a.Errorf("failed to create output directory %s: %v", dir, err)
return
}
cmd := a.getenv("ATLAS_ACTION_COMMAND")
err := writeBashEnv(filepath.Join(dir, "outputs.sh"), toEnvVar(
fmt.Sprintf("ATLAS_OUTPUT_%s_%s", cmd, name)), value)
outputs := filepath.Join(dir, "outputs.sh")
err := fprintln(outputs,
"export", toOutputVar(a.getenv("ATLAS_ACTION_COMMAND"), name, value))
if err != nil {
a.Errorf("failed to write output to file %s: %v", dir, err)
a.Errorf("failed to write output to file %s: %v", outputs, err)
}
}

Expand Down
15 changes: 9 additions & 6 deletions atlasaction/circleci_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,22 @@ func (a *circleCIOrb) Getenv(key string) string {

// GetInput implements the Action interface.
func (a *circleCIOrb) GetInput(name string) string {
return strings.TrimSpace(a.getenv(toEnvVar("INPUT_" + name)))
v := a.getenv(toInputVarName(name))
if v == "" {
// TODO: Remove this fallback once all the actions are updated.
v = a.getenv(toEnvName("INPUT_" + name))
}
return strings.TrimSpace(v)
}

// SetOutput implements the Action interface.
func (a *circleCIOrb) SetOutput(name, value string) {
if bashEnv := a.getenv("BASH_ENV"); bashEnv != "" {
cmd := a.getenv("ATLAS_ACTION_COMMAND")
err := writeBashEnv(bashEnv, toEnvVar(
fmt.Sprintf("ATLAS_OUTPUT_%s_%s", cmd, name)), value)
err := fprintln(bashEnv,
"export", toOutputVar(a.getenv("ATLAS_ACTION_COMMAND"), name, value))
if err != nil {
a.Fatalf("failed to write env to file %s: %v", bashEnv, err)
a.Fatalf("failed to write output to file %s: %v", bashEnv, err)
}
return
}
}

Expand Down
4 changes: 2 additions & 2 deletions atlasaction/circleci_action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func Test_circleCIOrb_GetTriggerContext(t *testing.T) {
func TestCircleCI(t *testing.T) {
var (
actions = "actions"
output = filepath.Join(actions, "output.txt")
output = filepath.Join(actions, "output.sh")
)
wd, err := os.Getwd()
require.NoError(t, err)
Expand All @@ -75,7 +75,7 @@ func TestCircleCI(t *testing.T) {
e.Setenv("CIRCLECI", "true")
e.Setenv("CIRCLE_PROJECT_REPONAME", "atlas-orb")
e.Setenv("CIRCLE_SHA1", "1234567890")
e.Setenv("BASH_ENV", filepath.Join(dir, "output.txt"))
e.Setenv("BASH_ENV", filepath.Join(dir, "output.sh"))
return nil
},
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
Expand Down
9 changes: 3 additions & 6 deletions atlasaction/gitlab_ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"context"
"fmt"
"io"
"os"
"slices"
"strconv"
"strings"
Expand Down Expand Up @@ -40,17 +39,15 @@ func (a *gitlabCI) Getenv(key string) string {

// GetInput implements the Action interface.
func (a *gitlabCI) GetInput(name string) string {
return strings.TrimSpace(a.getenv(toEnvVar("ATLAS_INPUT_" + name)))
return strings.TrimSpace(a.getenv(toInputVarName(name)))
}

// SetOutput implements the Action interface.
func (a *gitlabCI) SetOutput(name, value string) {
f, err := os.OpenFile(".env", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
err := fprintln(".env", toOutputVar(a.getenv("ATLAS_ACTION_COMMAND"), name, value))
if err != nil {
return
a.Errorf("failed to write output to file .env: %v", err)
}
defer f.Close()
fmt.Fprintf(f, "%s=%s\n", name, value)
}

// GetTriggerContext implements the Action interface.
Expand Down
24 changes: 12 additions & 12 deletions atlasaction/testdata/circleci/migrate-lint.txtar
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# Mock the atlas command outputs
env ATLAS_PATH=$MOCK_ATLAS TEST_BATCH=./migrate-lint
# Setup the action input variables
env INPUT_CONFIG=file://testdata/config/atlas.hcl
env INPUT_ENV=test
env INPUT_DIR_NAME=pupisu
env INPUT_TAG=staging
env INPUT_VARS='{"var1":"value1","var2":"value2"}'
env INPUT_DIR=file://testdata/migrations
env INPUT_DEV_URL=sqlite://file?mode=memory
env INPUT_RUN=example
env ATLAS_INPUT_CONFIG=file://testdata/config/atlas.hcl
env ATLAS_INPUT_ENV=test
env ATLAS_INPUT_DIR_NAME=pupisu
env ATLAS_INPUT_TAG=staging
env ATLAS_INPUT_VARS='{"var1":"value1","var2":"value2"}'
env ATLAS_INPUT_DIR=file://testdata/migrations
env ATLAS_INPUT_DEV_URL=sqlite://file?mode=memory
env ATLAS_INPUT_RUN=example

# The action's output should append the existing outputs
cp output-pre.txt actions/output.txt
cp output-pre.sh actions/output.sh
atlas-action --action=migrate/lint
output output.txt
output output.sh

-- migrate-lint/1/args --
migrate lint -w --context {"repo":"atlas-orb","path":"file://testdata/migrations","commit":"1234567890"} --env test --config file://testdata/config/atlas.hcl --dev-url sqlite://file?mode=memory --dir file://testdata/migrations --base atlas://pupisu?tag=staging --var var1=value1 --var var2=value2 --format {{ json . }}
-- migrate-lint/1/stdout --
{"URL":"https://migration-lint-report-url"}
-- output-pre.txt --
-- output-pre.sh --
export FOO=bar
-- output.txt --
-- output.sh --
export FOO=bar
export ATLAS_OUTPUT_MIGRATE_LINT_REPORT_URL="https://migration-lint-report-url"
12 changes: 6 additions & 6 deletions atlasaction/testdata/gitlab/schema-plan-approve.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ stdout 'No schema plan found'

# One pending plan.
atlas-action --action=schema/plan/approve
output expected-output.env
output .env.expected-output

# Multiple pending plans.
! atlas-action --action=schema/plan/approve
stdout 'No plan URL provided, searching for the pending plan'
stdout 'Found schema plan: atlas://plans/1234'
stdout 'Found schema plan: atlas://plans/5678'
stdout 'found multiple schema plans, please approve or delete the existing plans'
output expected-output.env
output .env.expected-output

-- expected-output.env --
link=https://test.atlasgo.cloud/schemas/123/plans/456
plan=atlas://plans/1234
status=
-- .env.expected-output --
ATLAS_OUTPUT_SCHEMA_PLAN_APPROVE_LINK="https://test.atlasgo.cloud/schemas/123/plans/456"
ATLAS_OUTPUT_SCHEMA_PLAN_APPROVE_PLAN="atlas://plans/1234"
ATLAS_OUTPUT_SCHEMA_PLAN_APPROVE_STATUS=""
-- schema-plan-approve/1/args --
schema plan list --format {{ json . }} --context {"scmType":"GITLAB"} --pending --auto-approve

Expand Down
10 changes: 5 additions & 5 deletions atlasaction/testdata/gitlab/schema-plan.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ atlas-action --action=schema/plan
stdout 'Schema plan does not exist, creating a new one with name "pr-1-3RRRcLHF"'

cmp comments-expected/1 comments/1
output expected-output.env
output .env.expected-output

-- expected-output.env --
link=http://test.atlasgo.cloud/schemas/141733920769/plans/210453397511
plan=atlas://app/plans/20241010143904
status=PENDING
-- .env.expected-output --
ATLAS_OUTPUT_SCHEMA_PLAN_LINK="http://test.atlasgo.cloud/schemas/141733920769/plans/210453397511"
ATLAS_OUTPUT_SCHEMA_PLAN_PLAN="atlas://app/plans/20241010143904"
ATLAS_OUTPUT_SCHEMA_PLAN_STATUS="PENDING"
-- schema-plan/1/args --
schema plan list --format {{ json . }} --context {"repo":"my-project","branch":"test-branch","commit":"123","url":"https://gitlab.com/projects/my-project/merge_requests/1","username":"user","userID":"123","scmType":"GITLAB"} --pending --auto-approve

Expand Down

0 comments on commit 67c0c25

Please sign in to comment.