diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95d8f3808..0ffa82c37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -230,8 +230,6 @@ jobs: - name: Run CLI E2E tests env: LARK_CLI_BIN: ${{ github.workspace }}/lark-cli - LARKSUITE_CLI_APP_ID: ${{ env.TEST_BOT1_APP_ID }} - LARKSUITE_CLI_USER_ACCESS_TOKEN: ${{ env.TEST_USER_ACCESS_TOKEN }} run: | packages=$(go list ./tests/cli_e2e/... | grep -v '^github.com/larksuite/cli/tests/cli_e2e$' | grep -v '/demo$') if [ -z "$packages" ]; then diff --git a/tests/cli_e2e/core.go b/tests/cli_e2e/core.go index ab8c59e1a..1d5383979 100644 --- a/tests/cli_e2e/core.go +++ b/tests/cli_e2e/core.go @@ -84,6 +84,8 @@ type Request struct { Format string // WorkDir is optional and becomes the child process working directory when non-empty. WorkDir string + // Env adds or overrides environment variables for this one child process only. + Env map[string]string } // Result captures process execution output. @@ -121,6 +123,7 @@ func RunCmd(ctx context.Context, req Request) (*Result, error) { if req.WorkDir != "" { cmd.Dir = req.WorkDir } + cmd.Env = buildCommandEnv(req) var stdout bytes.Buffer var stderr bytes.Buffer @@ -143,6 +146,39 @@ func RunCmd(ctx context.Context, req Request) (*Result, error) { return result, nil } +func buildCommandEnv(req Request) []string { + env := append([]string{}, os.Environ()...) + overrides := map[string]string{} + for k, v := range req.Env { + overrides[k] = v + } + // Keep user-token injection scoped to user-only test commands so bot + // commands continue to use config-init credentials in the same process. + if req.DefaultAs == "user" { + if appID := os.Getenv("TEST_BOT1_APP_ID"); appID != "" { + if token := os.Getenv("TEST_USER_ACCESS_TOKEN"); token != "" { + overrides["LARKSUITE_CLI_APP_ID"] = appID + overrides["LARKSUITE_CLI_USER_ACCESS_TOKEN"] = token + } + } + } + for k, v := range overrides { + prefix := k + "=" + replaced := false + for i, item := range env { + if strings.HasPrefix(item, prefix) { + env[i] = prefix + v + replaced = true + break + } + } + if !replaced { + env = append(env, prefix+v) + } + } + return env +} + // RunCmdWithRetry reruns a command when the result matches the configured retry condition. func RunCmdWithRetry(ctx context.Context, req Request, opts RetryOptions) (*Result, error) { if opts.Attempts <= 0 { diff --git a/tests/cli_e2e/core_test.go b/tests/cli_e2e/core_test.go index c1feebe58..803d0ee74 100644 --- a/tests/cli_e2e/core_test.go +++ b/tests/cli_e2e/core_test.go @@ -210,6 +210,19 @@ func TestRunCmd(t *testing.T) { result.AssertExitCode(t, 0) assert.Equal(t, "hello from stdin\n", result.Stdout) }) + + t.Run("injects user token env only for user commands", func(t *testing.T) { + t.Setenv("TEST_BOT1_APP_ID", "cli_app_test") + t.Setenv("TEST_USER_ACCESS_TOKEN", "uat_test") + + env := buildCommandEnv(Request{DefaultAs: "user"}) + assert.Contains(t, env, "LARKSUITE_CLI_APP_ID=cli_app_test") + assert.Contains(t, env, "LARKSUITE_CLI_USER_ACCESS_TOKEN=uat_test") + + env = buildCommandEnv(Request{DefaultAs: "bot"}) + assert.NotContains(t, env, "LARKSUITE_CLI_APP_ID=cli_app_test") + assert.NotContains(t, env, "LARKSUITE_CLI_USER_ACCESS_TOKEN=uat_test") + }) } type fakeCLI struct {