Files
atlantis/server/events/pre_workflow_hooks_command_runner.go
KevinSnyderCodes 1a8344489f fix: add path to WorkingDir methods (#2180)
* fix: add path to WorkingDir methods

`WorkingDirLocker` and `WorkingDir` are closely related -- the former acquires a lock, which ensures that the latter can safely operate on a given file path.

In #2131 we added `path` to the `WorkingDirLocker` lock key, but neglected to add the same to `WorkingDir`.

This commit adds `path` as an argument to certain `WorkingDir` methods, and includes `path` in the directory that we use to clone the repository for a given project.

Since `path` can include certain special characters such as `/`, we encode `path` as base32 when using it as part of a file path. This should ensure no special characters are used in the filesystem, and that the value can be decoded if desired (unlike hashes such as md5).

Additional changes:

- All calls to changed methods have been updated, including unit tests
- Mocks have been regenerated for `WorkingDir` and `WorkingDirLocker`
- `working_dir_test.go`
  - Commands that operate on filesystem paths have been updated to include the base32 encoded `path` value
  - When running `git init`, we include `-b master` as additional arguments, to ensure that `master` is our default branch (expected by the unit tests)

* Try fixing E2E tests

* Fix DefaultPendingPlanFinder

In addition to iterating over `workspaceDirs`, also iterate over `pathDirs`, and use both `workspace` and `path` to build `repoDir`.

* Fix DefaultPendingPlanFinder unit tests

* Fix DefaultProjectCommandBuilder unit tests

Co-authored-by: Kevin Snyder <kevinsnyder@KevinSnydersMBP.lan>
Co-authored-by: Kevin Snyder <kevinsnyder@ip-192-168-1-188.ec2.internal>
2022-04-08 11:55:35 -07:00

96 lines
2.5 KiB
Go

package events
import (
"github.com/runatlantis/atlantis/server/core/config/valid"
"github.com/runatlantis/atlantis/server/core/runtime"
"github.com/runatlantis/atlantis/server/events/command"
"github.com/runatlantis/atlantis/server/events/models"
"github.com/runatlantis/atlantis/server/events/vcs"
)
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_pre_workflows_hooks_command_runner.go PreWorkflowHooksCommandRunner
type PreWorkflowHooksCommandRunner interface {
RunPreHooks(ctx *command.Context) error
}
// DefaultPreWorkflowHooksCommandRunner is the first step when processing a workflow hook commands.
type DefaultPreWorkflowHooksCommandRunner struct {
VCSClient vcs.Client
WorkingDirLocker WorkingDirLocker
WorkingDir WorkingDir
GlobalCfg valid.GlobalCfg
PreWorkflowHookRunner runtime.PreWorkflowHookRunner
}
// RunPreHooks runs pre_workflow_hooks when PR is opened or updated.
func (w *DefaultPreWorkflowHooksCommandRunner) RunPreHooks(
ctx *command.Context,
) error {
pull := ctx.Pull
baseRepo := pull.BaseRepo
headRepo := ctx.HeadRepo
user := ctx.User
log := ctx.Log
preWorkflowHooks := make([]*valid.WorkflowHook, 0)
for _, repo := range w.GlobalCfg.Repos {
if repo.IDMatches(baseRepo.ID()) && len(repo.PreWorkflowHooks) > 0 {
preWorkflowHooks = append(preWorkflowHooks, repo.PreWorkflowHooks...)
}
}
// short circuit any other calls if there are no pre-hooks configured
if len(preWorkflowHooks) == 0 {
return nil
}
log.Debug("pre-hooks configured, running...")
unlockFn, err := w.WorkingDirLocker.TryLock(baseRepo.FullName, pull.Num, DefaultWorkspace, DefaultRepoRelDir)
if err != nil {
return err
}
log.Debug("got workspace lock")
defer unlockFn()
repoDir, _, err := w.WorkingDir.Clone(log, headRepo, pull, DefaultWorkspace, DefaultRepoRelDir)
if err != nil {
return err
}
err = w.runHooks(
models.WorkflowHookCommandContext{
BaseRepo: baseRepo,
HeadRepo: headRepo,
Log: log,
Pull: pull,
User: user,
Verbose: false,
},
preWorkflowHooks, repoDir)
if err != nil {
return err
}
return nil
}
func (w *DefaultPreWorkflowHooksCommandRunner) runHooks(
ctx models.WorkflowHookCommandContext,
preWorkflowHooks []*valid.WorkflowHook,
repoDir string,
) error {
for _, hook := range preWorkflowHooks {
_, err := w.PreWorkflowHookRunner.Run(ctx, hook.RunCommand, repoDir)
if err != nil {
return err
}
}
return nil
}