From ef27d3c2507319b8e54f02eed623c0bb5b185e5a Mon Sep 17 00:00:00 2001 From: Justin Van Patten Date: Sat, 17 Dec 2022 22:31:44 -0500 Subject: [PATCH] [auto] Add SkipInstallDependencies option for remote workspaces --- ...ndencies-option-for-remote-workspaces.yaml | 4 ++ pkg/cmd/pulumi/util_remote.go | 12 +++++ sdk/go/auto/local_workspace.go | 45 ++++++++++++------- sdk/go/auto/remote_workspace.go | 10 +++++ sdk/go/auto/remote_workspace_test.go | 8 ++-- sdk/go/auto/stack.go | 6 +++ sdk/go/common/apitype/deployments.go | 9 ++++ sdk/nodejs/automation/localWorkspace.ts | 19 +++++++- sdk/nodejs/automation/remoteWorkspace.ts | 6 +++ .../tests/automation/remoteWorkspace.spec.ts | 1 + .../lib/pulumi/automation/_local_workspace.py | 4 ++ .../pulumi/automation/_remote_workspace.py | 6 +++ .../test/automation/test_remote_workspace.py | 11 +++-- 13 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 changelog/pending/20221218--auto-dotnet-go-nodejs-python--adds-skipinstalldependencies-option-for-remote-workspaces.yaml diff --git a/changelog/pending/20221218--auto-dotnet-go-nodejs-python--adds-skipinstalldependencies-option-for-remote-workspaces.yaml b/changelog/pending/20221218--auto-dotnet-go-nodejs-python--adds-skipinstalldependencies-option-for-remote-workspaces.yaml new file mode 100644 index 000000000000..dd89d6f52ef5 --- /dev/null +++ b/changelog/pending/20221218--auto-dotnet-go-nodejs-python--adds-skipinstalldependencies-option-for-remote-workspaces.yaml @@ -0,0 +1,4 @@ +changes: +- type: feat + scope: auto/go,nodejs,python + description: Adds SkipInstallDependencies option for Remote Workspaces diff --git a/pkg/cmd/pulumi/util_remote.go b/pkg/cmd/pulumi/util_remote.go index 5be62c2ae45b..f0bb1ee68bd1 100644 --- a/pkg/cmd/pulumi/util_remote.go +++ b/pkg/cmd/pulumi/util_remote.go @@ -152,6 +152,7 @@ type RemoteArgs struct { envVars []string secretEnvVars []string preRunCommands []string + skipInstallDependencies bool gitBranch string gitCommit string gitRepoDir string @@ -182,6 +183,9 @@ func (r *RemoteArgs) applyFlags(cmd *cobra.Command) { cmd.PersistentFlags().StringArrayVar( &r.preRunCommands, "remote-pre-run-command", []string{}, "[EXPERIMENTAL] Commands to run before the remote operation") + cmd.PersistentFlags().BoolVar( + &r.skipInstallDependencies, "remote-skip-install-dependencies", false, + "[EXPERIMENTAL] Whether to skip the default dependency installation step") cmd.PersistentFlags().StringVar( &r.gitBranch, "remote-git-branch", "", "[EXPERIMENTAL] Git branch to deploy; this is mutually exclusive with --remote-git-branch; "+ @@ -298,6 +302,13 @@ func runDeployment(ctx context.Context, opts display.Options, operation apitype. } } + var operationOptions *apitype.OperationContextOptions + if args.skipInstallDependencies { + operationOptions = &apitype.OperationContextOptions{ + SkipInstallDependencies: args.skipInstallDependencies, + } + } + req := apitype.CreateDeploymentRequest{ Source: &apitype.SourceContext{ Git: &apitype.SourceContextGit{ @@ -311,6 +322,7 @@ func runDeployment(ctx context.Context, opts display.Options, operation apitype. Operation: operation, PreRunCommands: args.preRunCommands, EnvironmentVariables: env, + Options: operationOptions, }, } err = cb.RunDeployment(ctx, stackRef, req, opts) diff --git a/sdk/go/auto/local_workspace.go b/sdk/go/auto/local_workspace.go index edbeba0f0b0f..d43730456687 100644 --- a/sdk/go/auto/local_workspace.go +++ b/sdk/go/auto/local_workspace.go @@ -45,16 +45,17 @@ import ( // alter the Workspace Pulumi.yaml file, and setting config on a Stack will modify the Pulumi..yaml file. // This is identical to the behavior of Pulumi CLI driven workspaces. type LocalWorkspace struct { - workDir string - pulumiHome string - program pulumi.RunFunc - envvars map[string]string - secretsProvider string - pulumiVersion semver.Version - repo *GitRepo - remote bool - remoteEnvVars map[string]EnvVarValue - preRunCommands []string + workDir string + pulumiHome string + program pulumi.RunFunc + envvars map[string]string + secretsProvider string + pulumiVersion semver.Version + repo *GitRepo + remote bool + remoteEnvVars map[string]EnvVarValue + preRunCommands []string + remoteSkipInstallDependencies bool } var settingsExtensions = []string{".yaml", ".yml", ".json"} @@ -650,13 +651,14 @@ func NewLocalWorkspace(ctx context.Context, opts ...LocalWorkspaceOption) (Works } l := &LocalWorkspace{ - workDir: workDir, - preRunCommands: lwOpts.PreRunCommands, - program: program, - pulumiHome: lwOpts.PulumiHome, - remote: lwOpts.Remote, - remoteEnvVars: lwOpts.RemoteEnvVars, - repo: lwOpts.Repo, + workDir: workDir, + preRunCommands: lwOpts.PreRunCommands, + program: program, + pulumiHome: lwOpts.PulumiHome, + remote: lwOpts.Remote, + remoteEnvVars: lwOpts.RemoteEnvVars, + remoteSkipInstallDependencies: lwOpts.RemoteSkipInstallDependencies, + repo: lwOpts.Repo, } // optOut indicates we should skip the version check. @@ -756,6 +758,8 @@ type localWorkspaceOptions struct { RemoteEnvVars map[string]EnvVarValue // PreRunCommands is an optional list of arbitrary commands to run before the remote Pulumi operation is invoked. PreRunCommands []string + // RemoteSkipInstallDependencies sets whether to skip the default dependency installation step + RemoteSkipInstallDependencies bool } // LocalWorkspaceOption is used to customize and configure a LocalWorkspace at initialization time. @@ -897,6 +901,13 @@ func preRunCommands(commands ...string) LocalWorkspaceOption { }) } +// remoteSkipInstallDependencies sets whether to skip the default dependency installation step. +func remoteSkipInstallDependencies(skipInstallDependencies bool) LocalWorkspaceOption { + return localWorkspaceOption(func(lo *localWorkspaceOptions) { + lo.RemoteSkipInstallDependencies = skipInstallDependencies + }) +} + // NewStackLocalSource creates a Stack backed by a LocalWorkspace created on behalf of the user, // from the specified WorkDir. This Workspace will pick up // any available Settings files (Pulumi.yaml, Pulumi..yaml). diff --git a/sdk/go/auto/remote_workspace.go b/sdk/go/auto/remote_workspace.go index 419ec8a81f38..27cbf9168a95 100644 --- a/sdk/go/auto/remote_workspace.go +++ b/sdk/go/auto/remote_workspace.go @@ -147,6 +147,7 @@ func remoteToLocalOptions(repo GitRepo, opts ...RemoteWorkspaceOption) ([]LocalW remote(true), remoteEnvVars(remoteOpts.EnvVars), preRunCommands(remoteOpts.PreRunCommands...), + remoteSkipInstallDependencies(remoteOpts.SkipInstallDependencies), Repo(repo), } return localOpts, nil @@ -158,6 +159,8 @@ type remoteWorkspaceOptions struct { EnvVars map[string]EnvVarValue // PreRunCommands is an optional list of arbitrary commands to run before the remote Pulumi operation is invoked. PreRunCommands []string + // SkipInstallDependencies sets whether to skip the default dependency installation step. Defaults to false. + SkipInstallDependencies bool } // LocalWorkspaceOption is used to customize and configure a LocalWorkspace at initialization time. @@ -187,6 +190,13 @@ func RemotePreRunCommands(commands ...string) RemoteWorkspaceOption { }) } +// RemoteSkipInstallDependencies sets whether to skip the default dependency installation step. Defaults to false. +func RemoteSkipInstallDependencies(skipInstallDependencies bool) RemoteWorkspaceOption { + return remoteWorkspaceOption(func(opts *remoteWorkspaceOptions) { + opts.SkipInstallDependencies = skipInstallDependencies + }) +} + // isFullyQualifiedStackName returns true if the stack is fully qualified, // i.e. has owner, project, and stack components. func isFullyQualifiedStackName(stackName string) bool { diff --git a/sdk/go/auto/remote_workspace_test.go b/sdk/go/auto/remote_workspace_test.go index 4bd723bd3df5..52a96d609946 100644 --- a/sdk/go/auto/remote_workspace_test.go +++ b/sdk/go/auto/remote_workspace_test.go @@ -135,9 +135,11 @@ func testRemoteStackGitSource(t *testing.T, fn func(ctx context.Context, stackNa } // initialize - s, err := fn(ctx, stackName, repo, RemotePreRunCommands( - fmt.Sprintf("pulumi config set bar abc --stack %s", stackName), - fmt.Sprintf("pulumi config set --secret buzz secret --stack %s", stackName))) + s, err := fn(ctx, stackName, repo, + RemotePreRunCommands( + fmt.Sprintf("pulumi config set bar abc --stack %s", stackName), + fmt.Sprintf("pulumi config set --secret buzz secret --stack %s", stackName)), + RemoteSkipInstallDependencies(true)) if err != nil { t.Errorf("failed to initialize stack, err: %v", err) t.FailNow() diff --git a/sdk/go/auto/stack.go b/sdk/go/auto/stack.go index 3439095192df..40d977f8dc60 100644 --- a/sdk/go/auto/stack.go +++ b/sdk/go/auto/stack.go @@ -949,11 +949,13 @@ func (s *Stack) remoteArgs() []string { var repo *GitRepo var preRunCommands []string var envvars map[string]EnvVarValue + var skipInstallDependencies bool if lws, isLocalWorkspace := s.Workspace().(*LocalWorkspace); isLocalWorkspace { remote = lws.remote repo = lws.repo preRunCommands = lws.preRunCommands envvars = lws.remoteEnvVars + skipInstallDependencies = lws.remoteSkipInstallDependencies } if !remote { return nil @@ -1006,6 +1008,10 @@ func (s *Stack) remoteArgs() []string { args = append(args, fmt.Sprintf("--remote-pre-run-command=%s", command)) } + if skipInstallDependencies { + args = append(args, "--remote-skip-install-dependencies") + } + return args } diff --git a/sdk/go/common/apitype/deployments.go b/sdk/go/common/apitype/deployments.go index 0f7e769a6f6d..209b11d53da2 100644 --- a/sdk/go/common/apitype/deployments.go +++ b/sdk/go/common/apitype/deployments.go @@ -123,6 +123,15 @@ type OperationContext struct { // EnvironmentVariables contains environment variables to be applied during the execution. EnvironmentVariables map[string]SecretValue `json:"environmentVariables"` + + // Options is a bag of settings to specify or override default behavior + Options *OperationContextOptions `json:"options,omitempty"` +} + +// OperationContextOptions is a bag of settings to specify or override default behavior in a deployment +type OperationContextOptions struct { + // SkipInstallDependencies sets whether to skip the default dependency installation step. Defaults to false. + SkipInstallDependencies bool `json:"skipInstallDependencies"` } // CreateDeploymentResponse defines the response given when a new Deployment is created. diff --git a/sdk/nodejs/automation/localWorkspace.ts b/sdk/nodejs/automation/localWorkspace.ts index 14e3111f8b82..f2de26b851dc 100644 --- a/sdk/nodejs/automation/localWorkspace.ts +++ b/sdk/nodejs/automation/localWorkspace.ts @@ -101,6 +101,11 @@ export class LocalWorkspace implements Workspace { */ private remoteEnvVars?: { [key: string]: string | { secret: string } }; + /** + * Whether to skip the default dependency installation step. + */ + private remoteSkipInstallDependencies?: boolean; + /** * Creates a workspace using the specified options. Used for maximal control and customization * of the underlying environment before any stacks are created or selected. @@ -246,7 +251,8 @@ export class LocalWorkspace implements Workspace { if (opts) { const { workDir, pulumiHome, program, envVars, secretsProvider, - remote, remoteGitProgramArgs, remotePreRunCommands, remoteEnvVars } = opts; + remote, remoteGitProgramArgs, remotePreRunCommands, remoteEnvVars, + remoteSkipInstallDependencies } = opts; if (workDir) { dir = workDir; } @@ -257,6 +263,7 @@ export class LocalWorkspace implements Workspace { this.remoteGitProgramArgs = remoteGitProgramArgs; this.remotePreRunCommands = remotePreRunCommands; this.remoteEnvVars = { ...remoteEnvVars }; + this.remoteSkipInstallDependencies = remoteSkipInstallDependencies; envs = { ...envVars }; } @@ -734,6 +741,10 @@ export class LocalWorkspace implements Workspace { args.push("--remote-pre-run-command", command); } + if (this.remoteSkipInstallDependencies) { + args.push("--remote-skip-install-dependencies"); + } + return args; } } @@ -823,6 +834,12 @@ export interface LocalWorkspaceOptions { * @internal */ remoteEnvVars?: { [key: string]: string | { secret: string } }; + /** + * Whether to skip the default dependency installation step. + * + * @internal + */ + remoteSkipInstallDependencies?: boolean; } /** diff --git a/sdk/nodejs/automation/remoteWorkspace.ts b/sdk/nodejs/automation/remoteWorkspace.ts index 00305134a814..444a58840238 100644 --- a/sdk/nodejs/automation/remoteWorkspace.ts +++ b/sdk/nodejs/automation/remoteWorkspace.ts @@ -145,6 +145,11 @@ export interface RemoteWorkspaceOptions { * An optional list of arbitrary commands to run before a remote Pulumi operation is invoked. */ preRunCommands?: string[]; + + /** + * Whether to skip the default dependency installation step. Defaults to false. + */ + skipInstallDependencies?: boolean; } async function createLocalWorkspace(args: RemoteGitProgramArgs, opts?: RemoteWorkspaceOptions): Promise { @@ -172,6 +177,7 @@ async function createLocalWorkspace(args: RemoteGitProgramArgs, opts?: RemoteWor remoteGitProgramArgs: args, remoteEnvVars: opts?.envVars, remotePreRunCommands: opts?.preRunCommands, + remoteSkipInstallDependencies: opts?.skipInstallDependencies, }; return await LocalWorkspace.create(localOpts); } diff --git a/sdk/nodejs/tests/automation/remoteWorkspace.spec.ts b/sdk/nodejs/tests/automation/remoteWorkspace.spec.ts index 2bf7d93a1845..92043c2bf6a6 100644 --- a/sdk/nodejs/tests/automation/remoteWorkspace.spec.ts +++ b/sdk/nodejs/tests/automation/remoteWorkspace.spec.ts @@ -184,6 +184,7 @@ async function testLifecycle(fn: (args: RemoteGitProgramArgs, opts?: RemoteWorks `pulumi config set bar abc --stack ${stackName}`, `pulumi config set --secret buzz secret --stack ${stackName}`, ], + skipInstallDependencies: true, }); // pulumi up diff --git a/sdk/python/lib/pulumi/automation/_local_workspace.py b/sdk/python/lib/pulumi/automation/_local_workspace.py index 5b86b0e6fa55..d602449a7298 100644 --- a/sdk/python/lib/pulumi/automation/_local_workspace.py +++ b/sdk/python/lib/pulumi/automation/_local_workspace.py @@ -97,6 +97,7 @@ class LocalWorkspace(Workspace): _remote: bool = False _remote_env_vars: Optional[Mapping[str, Union[str, Secret]]] _remote_pre_run_commands: Optional[List[str]] + _remote_skip_install_dependencies: Optional[bool] _remote_git_url: str _remote_git_project_path: Optional[str] _remote_git_branch: Optional[str] @@ -480,6 +481,9 @@ def _remote_args(self) -> List[str]: args.append("--remote-pre-run-command") args.append(command) + if self._remote_skip_install_dependencies: + args.append("--remote-skip-install-dependencies") + return args diff --git a/sdk/python/lib/pulumi/automation/_remote_workspace.py b/sdk/python/lib/pulumi/automation/_remote_workspace.py index 3765a3507242..96691f62ec1a 100644 --- a/sdk/python/lib/pulumi/automation/_remote_workspace.py +++ b/sdk/python/lib/pulumi/automation/_remote_workspace.py @@ -26,15 +26,18 @@ class RemoteWorkspaceOptions: env_vars: Optional[Mapping[str, Union[str, Secret]]] pre_run_commands: Optional[List[str]] + skip_install_dependencies: Optional[bool] def __init__( self, *, env_vars: Optional[Mapping[str, Union[str, Secret]]] = None, pre_run_commands: Optional[List[str]] = None, + skip_install_dependencies: Optional[bool] = None, ): self.env_vars = env_vars self.pre_run_commands = pre_run_commands + self.skip_install_dependencies = skip_install_dependencies class RemoteGitAuth: @@ -199,14 +202,17 @@ def _create_local_workspace( env_vars = None pre_run_commands = None + skip_install_dependencies = None if opts is not None: env_vars = opts.env_vars pre_run_commands = opts.pre_run_commands + skip_install_dependencies = opts.skip_install_dependencies ws = LocalWorkspace() ws._remote = True ws._remote_env_vars = env_vars ws._remote_pre_run_commands = pre_run_commands + ws._remote_skip_install_dependencies = skip_install_dependencies ws._remote_git_url = url ws._remote_git_project_path = project_path ws._remote_git_branch = branch diff --git a/sdk/python/lib/test/automation/test_remote_workspace.py b/sdk/python/lib/test/automation/test_remote_workspace.py index f0ed11b5a9ff..519279092812 100644 --- a/sdk/python/lib/test/automation/test_remote_workspace.py +++ b/sdk/python/lib/test/automation/test_remote_workspace.py @@ -86,10 +86,13 @@ def test_remote_workspace_stack_lifecycle(factory): url=test_repo, branch="refs/heads/master", project_path="goproj", - opts=RemoteWorkspaceOptions(pre_run_commands=[ - f"pulumi config set bar abc --stack {stack_name}", - f"pulumi config set --secret buzz secret --stack {stack_name}", - ]), + opts=RemoteWorkspaceOptions( + pre_run_commands=[ + f"pulumi config set bar abc --stack {stack_name}", + f"pulumi config set --secret buzz secret --stack {stack_name}", + ], + skip_install_dependencies=True, + ), ) # pulumi up