Skip to content

Commit

Permalink
[auto] Add SkipInstallDependencies option for remote workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
justinvp committed Dec 19, 2022
1 parent 184e579 commit ef27d3c
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 25 deletions.
@@ -0,0 +1,4 @@
changes:
- type: feat
scope: auto/go,nodejs,python
description: Adds SkipInstallDependencies option for Remote Workspaces
12 changes: 12 additions & 0 deletions pkg/cmd/pulumi/util_remote.go
Expand Up @@ -152,6 +152,7 @@ type RemoteArgs struct {
envVars []string
secretEnvVars []string
preRunCommands []string
skipInstallDependencies bool
gitBranch string
gitCommit string
gitRepoDir string
Expand Down Expand Up @@ -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; "+
Expand Down Expand Up @@ -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{
Expand All @@ -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)
Expand Down
45 changes: 28 additions & 17 deletions sdk/go/auto/local_workspace.go
Expand Up @@ -45,16 +45,17 @@ import (
// alter the Workspace Pulumi.yaml file, and setting config on a Stack will modify the Pulumi.<stack>.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"}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.<stack>.yaml).
Expand Down
10 changes: 10 additions & 0 deletions sdk/go/auto/remote_workspace.go
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 5 additions & 3 deletions sdk/go/auto/remote_workspace_test.go
Expand Up @@ -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()
Expand Down
6 changes: 6 additions & 0 deletions sdk/go/auto/stack.go
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down
9 changes: 9 additions & 0 deletions sdk/go/common/apitype/deployments.go
Expand Up @@ -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.
Expand Down
19 changes: 18 additions & 1 deletion sdk/nodejs/automation/localWorkspace.ts
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
Expand All @@ -257,6 +263,7 @@ export class LocalWorkspace implements Workspace {
this.remoteGitProgramArgs = remoteGitProgramArgs;
this.remotePreRunCommands = remotePreRunCommands;
this.remoteEnvVars = { ...remoteEnvVars };
this.remoteSkipInstallDependencies = remoteSkipInstallDependencies;
envs = { ...envVars };
}

Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions sdk/nodejs/automation/remoteWorkspace.ts
Expand Up @@ -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<LocalWorkspace> {
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions sdk/nodejs/tests/automation/remoteWorkspace.spec.ts
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions sdk/python/lib/pulumi/automation/_local_workspace.py
Expand Up @@ -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]
Expand Down Expand Up @@ -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


Expand Down
6 changes: 6 additions & 0 deletions sdk/python/lib/pulumi/automation/_remote_workspace.py
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions sdk/python/lib/test/automation/test_remote_workspace.py
Expand Up @@ -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
Expand Down

0 comments on commit ef27d3c

Please sign in to comment.