-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle "environments" folders for new GitOps directory structures (#73)
Adjust for /environments/env-name/ at top of GitOps repository structure.
- Loading branch information
Showing
13 changed files
with
517 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,10 +23,35 @@ $ ./services promote --from https://github.com/organisation/first-environment.gi | |
|
||
If the `commit-name` and `commit-email` are not provided, it will attempt to find them in `~/.gitconfig`, otherwise it will fail. | ||
|
||
|
||
This will _copy_ all files under `/services/service-a/base/config/*` in `first-environment` to `second-environment`, commit and push, and open a PR for the change. | ||
|
||
|
||
## Using environments | ||
|
||
|
||
If an `environments` folder exists in the GitOps repository you are promoting into, and that only has one folder, the files will be copied into the destination repository's `/environments/<the only folder>` directory. | ||
|
||
Future support is planned for an `--env` like flag which will allow us to promote from/to different repositories with multiple environments. | ||
|
||
## Testing | ||
|
||
Linting should be done first (this is done on Travis, and what's good locally should be good there too) | ||
|
||
Grab the linter if you haven't already: | ||
|
||
```shell | ||
GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/[email protected] | ||
``` | ||
|
||
Then you can do: | ||
|
||
```shell | ||
golangci-lint run | ||
``` | ||
|
||
Run the unit tests: | ||
|
||
```shell | ||
$ go test ./... | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,15 +37,15 @@ func TestPromoteWithSuccessCustomMsg(t *testing.T) { | |
func promoteWithSuccess(t *testing.T, keepCache bool, repoType string, tlsVerify bool, msg string) { | ||
dstBranch := "test-branch" | ||
author := &git.Author{Name: "Testing User", Email: "[email protected]", Token: "test-token"} | ||
devRepo, stagingRepo := mock.New("/dev", "master"), mock.New("/staging", "master") | ||
devRepo, stagingRepo := mock.New("environments/dev", "master"), mock.New("environments/staging", "master") | ||
repos := map[string]*mock.Repository{ | ||
mustAddCredentials(t, dev, author): devRepo, | ||
mustAddCredentials(t, staging, author): stagingRepo, | ||
} | ||
sm := New("tmp", author) | ||
sm.repoType = repoType | ||
sm.tlsVerify = tlsVerify | ||
sm.clientFactory = func(s, ty, r string, v bool) *scm.Client { | ||
sm.clientFactory = func(s, ty, r string, v bool) *scm.Client { | ||
client, _ := fakescm.NewDefault() | ||
if r != repoType { | ||
t.Fatalf("repoType doesn't match %s != %s\n", r, repoType) | ||
|
@@ -61,8 +61,8 @@ func promoteWithSuccess(t *testing.T, keepCache bool, repoType string, tlsVerify | |
} | ||
return git.Repo(repos[url]), nil | ||
} | ||
devRepo.AddFiles("/services/my-service/base/config/myfile.yaml") | ||
|
||
devRepo.AddFiles("services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AddFiles("") | ||
err := sm.Promote("my-service", dev, staging, dstBranch, msg, keepCache) | ||
if err != nil { | ||
t.Fatal(err) | ||
|
@@ -71,11 +71,11 @@ func promoteWithSuccess(t *testing.T, keepCache bool, repoType string, tlsVerify | |
expectedCommitMsg := msg | ||
if msg == "" { | ||
commit := devRepo.GetCommitID() | ||
expectedCommitMsg = fmt.Sprintf("Promoting service `my-service` at commit `%s` from branch `master` in `%s`.", commit, dev) | ||
expectedCommitMsg = fmt.Sprintf("Promoting service my-service at commit %s from branch master in %s.", commit, dev) | ||
} | ||
|
||
stagingRepo.AssertBranchCreated(t, "master", dstBranch) | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "/dev/services/my-service/base/config/myfile.yaml", "/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "environments/dev/services/my-service/base/config/myfile.yaml", "environments/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertCommit(t, dstBranch, expectedCommitMsg, author) | ||
stagingRepo.AssertPush(t, dstBranch) | ||
|
||
|
@@ -103,11 +103,11 @@ func TestPromoteLocalWithSuccessCustomMsg(t *testing.T) { | |
func promoteLocalWithSuccess(t *testing.T, keepCache bool, msg string) { | ||
dstBranch := "test-branch" | ||
author := &git.Author{Name: "Testing User", Email: "[email protected]", Token: "test-token"} | ||
stagingRepo := mock.New("/staging", "master") | ||
stagingRepo := mock.New("environments", "master") | ||
devRepo := NewLocal("/dev") | ||
|
||
sm := New("tmp", author) | ||
sm.clientFactory = func(s, t, r string, v bool) *scm.Client { | ||
sm.clientFactory = func(s, t, r string, v bool) *scm.Client { | ||
client, _ := fakescm.NewDefault() | ||
return client | ||
} | ||
|
@@ -118,7 +118,8 @@ func promoteLocalWithSuccess(t *testing.T, keepCache bool, msg string) { | |
return git.Source(devRepo) | ||
} | ||
sm.debug = true | ||
devRepo.AddFiles("/config/myfile.yaml") | ||
devRepo.AddFiles("config/myfile.yaml") | ||
stagingRepo.AddFiles("staging") | ||
|
||
err := sm.Promote("my-service", ldev, staging, dstBranch, msg, keepCache) | ||
if err != nil { | ||
|
@@ -127,11 +128,11 @@ func promoteLocalWithSuccess(t *testing.T, keepCache bool, msg string) { | |
|
||
expectedCommitMsg := msg | ||
if expectedCommitMsg == "" { | ||
expectedCommitMsg = "Promotion of service `my-service` from local filesystem directory `/root/repo`." | ||
expectedCommitMsg = "Promotion of service my-service from local filesystem directory /root/repo." | ||
} | ||
|
||
stagingRepo.AssertBranchCreated(t, "master", dstBranch) | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "/dev/config/myfile.yaml", "/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "/dev/config/myfile.yaml", "environments/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertCommit(t, dstBranch, expectedCommitMsg, author) | ||
stagingRepo.AssertPush(t, dstBranch) | ||
|
||
|
@@ -142,6 +143,70 @@ func promoteLocalWithSuccess(t *testing.T, keepCache bool, msg string) { | |
} | ||
} | ||
|
||
func TestPromoteLocalWithSuccessOneEnvAndIsUsed(t *testing.T) { | ||
// Destination repo (GitOps repo) to have /environments/staging | ||
// Promotion should copy files into that staging directory | ||
dstBranch := "test-branch" | ||
author := &git.Author{Name: "Testing User", Email: "[email protected]", Token: "test-token"} | ||
stagingRepo := mock.New("environments", "master") | ||
devRepo := NewLocal("/dev") | ||
|
||
sm := New("tmp", author) | ||
sm.clientFactory = func(s, t, r string, v bool) *scm.Client { | ||
client, _ := fakescm.NewDefault() | ||
return client | ||
} | ||
sm.repoFactory = func(url, _ string, _ bool, _ bool) (git.Repo, error) { | ||
return git.Repo(stagingRepo), nil | ||
} | ||
sm.localFactory = func(path string, _ bool) git.Source { | ||
return git.Source(devRepo) | ||
} | ||
sm.debug = true | ||
devRepo.AddFiles("/config/myfile.yaml") | ||
stagingRepo.AddFiles("/staging") | ||
|
||
err := sm.Promote("my-service", ldev, staging, dstBranch, "", false) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
expectedCommitMsg := "Promotion of service my-service from local filesystem directory /root/repo." | ||
|
||
stagingRepo.AssertBranchCreated(t, "master", dstBranch) | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "/dev/config/myfile.yaml", "environments/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertCommit(t, dstBranch, expectedCommitMsg, author) | ||
stagingRepo.AssertPush(t, dstBranch) | ||
} | ||
|
||
func TestPromoteErrorsIfMultipleEnvironments(t *testing.T) { | ||
dstBranch := "test-branch" | ||
author := &git.Author{Name: "Testing User", Email: "[email protected]", Token: "test-token"} | ||
devRepo, stagingRepo := mock.New("/", "master"), mock.New("/environments", "master") | ||
|
||
stagingRepo.AddFiles("/staging") | ||
stagingRepo.AddFiles("/prod") | ||
|
||
repos := map[string]*mock.Repository{ | ||
mustAddCredentials(t, dev, author): devRepo, | ||
mustAddCredentials(t, staging, author): stagingRepo, | ||
} | ||
sm := New("tmp", author) | ||
sm.clientFactory = func(s, ty, r string, v bool) *scm.Client { | ||
client, _ := fakescm.NewDefault() | ||
return client | ||
} | ||
sm.repoFactory = func(url, _ string, v bool, _ bool) (git.Repo, error) { | ||
return git.Repo(repos[url]), nil | ||
} | ||
devRepo.AddFiles("services/my-service/base/config/myfile.yaml") | ||
|
||
msg := "foo message" | ||
err := sm.Promote("my-service", dev, staging, dstBranch, msg, false) | ||
if err == nil { | ||
t.Fail() | ||
} | ||
} | ||
|
||
func TestAddCredentials(t *testing.T) { | ||
testUser := &git.Author{Name: "Test User", Email: "[email protected]", Token: "test-token"} | ||
tests := []struct { | ||
|
@@ -177,32 +242,33 @@ func mustAddCredentials(t *testing.T, repoURL string, a *git.Author) string { | |
func TestPromoteWithCacheDeletionFailure(t *testing.T) { | ||
dstBranch := "test-branch" | ||
author := &git.Author{Name: "Testing User", Email: "[email protected]", Token: "test-token"} | ||
devRepo, stagingRepo := mock.New("/dev", "master"), mock.New("/staging", "master") | ||
devRepo, stagingRepo := mock.New("environments", "master"), mock.New("environments", "master") | ||
stagingRepo.DeleteErr = errors.New("failed test delete") | ||
repos := map[string]*mock.Repository{ | ||
mustAddCredentials(t, dev, author): devRepo, | ||
mustAddCredentials(t, staging, author): stagingRepo, | ||
} | ||
sm := New("tmp", author) | ||
sm.clientFactory = func(s, t, r string, v bool) *scm.Client { | ||
sm.clientFactory = func(s, t, r string, v bool) *scm.Client { | ||
client, _ := fakescm.NewDefault() | ||
return client | ||
} | ||
sm.repoFactory = func(url, _ string, _ bool, _ bool) (git.Repo, error) { | ||
return git.Repo(repos[url]), nil | ||
} | ||
devRepo.AddFiles("/services/my-service/base/config/myfile.yaml") | ||
devRepo.AddFiles("dev/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AddFiles("staging") | ||
|
||
err := sm.Promote("my-service", dev, staging, dstBranch, "", false) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
commit := devRepo.GetCommitID() | ||
expectedCommitMsg := fmt.Sprintf("Promoting service `my-service` at commit `%s` from branch `master` in `%s`.", commit, dev) | ||
expectedCommitMsg := fmt.Sprintf("Promoting service my-service at commit %s from branch master in %s.", commit, dev) | ||
|
||
stagingRepo.AssertBranchCreated(t, "master", dstBranch) | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "/dev/services/my-service/base/config/myfile.yaml", "/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertFileCopiedInBranch(t, dstBranch, "environments/dev/services/my-service/base/config/myfile.yaml", "environments/staging/services/my-service/base/config/myfile.yaml") | ||
stagingRepo.AssertCommit(t, dstBranch, expectedCommitMsg, author) | ||
stagingRepo.AssertPush(t, dstBranch) | ||
|
||
|
@@ -298,7 +364,7 @@ func TestRepositoryCloneErrorOmitsToken(t *testing.T) { | |
dstBranch := "test-branch" | ||
author := &git.Author{Name: "Testing User", Email: "[email protected]", Token: "test-token"} | ||
client, _ := fakescm.NewDefault() | ||
fakeClientFactory := func(s, t, r string, v bool) *scm.Client { | ||
fakeClientFactory := func(s, t, r string, v bool) *scm.Client { | ||
return client | ||
} | ||
sm := New("tmp", author) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.