Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gitlab: prefix outputs with action's name #289

Merged
merged 2 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading