Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

First implementation of misc in hooks. #84

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion commands/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ func (v SourcesMock) RetrieveSha1ForProject(branch string) (string, error) {
}

func (v SourcesMock) Diff(deployedSha1 string, sha1ToDeploy string) (*services.Changes, error) {
return &services.Changes{}, nil
var commits = []services.Commits{}
commits = append(commits, services.Commits{DisplayId: "DisplayId1", AuthorFullName: "AuthorFullName1", AuthorSlug: "AuthorSlug1", Title: "Title1"})
commits = append(commits, services.Commits{DisplayId: "DisplayId2", AuthorFullName: "AuthorFullName2", AuthorSlug: "AuthorSlug2", Title: "Title2"})

return &services.Changes{
Commits: commits,
}, nil
}

type BinariesMock struct{}
Expand Down
36 changes: 34 additions & 2 deletions commands/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/remyLemeunier/contactkey/context"
"github.com/remyLemeunier/contactkey/deployers"
"github.com/remyLemeunier/contactkey/hooks"
"github.com/remyLemeunier/contactkey/utils"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -122,9 +123,18 @@ func (d *Deploy) execute() error {
return errors.New(fmt.Sprintf("Version %q is already deployed.", sha1ToDeploy))
}

misc := d.getDiff(sha1ToDeploy)
hookinformation := hooks.HookInformation{
userName,
d.Env,
d.Service,
podVersion,
misc,
}

log.Println(fmt.Sprintf("Going to deploy pod version %q \n", podVersion))
for _, hook := range d.Context.Hooks {
err = hook.PreDeployment(userName, d.Env, d.Service, podVersion)
err = hook.PreDeployment(hookinformation)
if hook.StopOnError() == true && err != nil {
return errors.New(fmt.Sprintf("Predeployment failed: %q", err))
} else if err != nil {
Expand All @@ -146,7 +156,7 @@ func (d *Deploy) execute() error {
}

for _, hook := range d.Context.Hooks {
err = hook.PostDeployment(userName, d.Env, d.Service, podVersion)
err = hook.PostDeployment(hookinformation)
if err != nil {
log.Debugln(fmt.Sprintf("PostDeployment failed: %q", err))
}
Expand All @@ -168,3 +178,25 @@ func (d *Deploy) fill(context *context.Context, service string, env string) {
d.Context = context
d.Writer = os.Stdout
}

func (d *Deploy) getDiff(sha1ToDeploy string) []string {
var diff []string
uniqueVersions, err := deployers.ListUniqueVcsVersions(d.Context.Deployer, d.Env)
if err != nil {
log.Debugln("Impossible to retrieve unique vcs version: %q", err.Error())
}

for _, uniqueVersion := range uniqueVersions {
changes, err := d.Context.Vcs.Diff(uniqueVersion, sha1ToDeploy)
if err != nil {
log.Debugln("Error during diff: %q", err.Error())
}

for _, change := range changes.Commits {
displayString := change.AuthorFullName + ":" + change.DisplayId
diff = append(diff, displayString)
}
}

return diff
}
30 changes: 30 additions & 0 deletions commands/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,33 @@ func TestUpdateSlow(t *testing.T) {
}
ggnCmd.Wait()
}

func TestGetDiff(t *testing.T) {
// Catch stdout
out := new(bytes.Buffer)
writer := io.Writer(out)
log.SetOutput(writer)

d := &Deploy{
Context: &context.Context{
Deployer: &DeployerMockGgn{},
Vcs: &SourcesMock{},
Binaries: &BinariesMock{},
Metrics: utils.NewBlackholeMetricsRegistry(),
},
Writer: out,
}

diff := d.getDiff("abcde")
if len(diff) != 2 {
t.Fatalf("diff len should be 2 insead got %s", len(diff))
}

if diff[0] != "AuthorFullName1:DisplayId1" {
t.Errorf("Error found %s", diff[0])
}

if diff[1] != "AuthorFullName2:DisplayId2" {
t.Errorf("Error found %s", diff[1])
}
}
19 changes: 3 additions & 16 deletions commands/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/olekukonko/tablewriter"
"github.com/remyLemeunier/contactkey/context"
"github.com/remyLemeunier/contactkey/deployers"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -38,23 +39,9 @@ func (d Diff) execute() error {
return errors.New(fmt.Sprintf("No sha1 found for service %q \n", d.Service))
}

versions, err := d.Context.Deployer.ListVcsVersions(d.Env)
uniqueVersions, err := deployers.ListUniqueVcsVersions(d.Context.Deployer, d.Env)
if err != nil {
return errors.New(fmt.Sprintf("Failed to list versions with error %q \n", err))
}

if len(versions) == 0 {
return errors.New(fmt.Sprintf("No service (%q) versions found for the Env: %q \n", d.Service, d.Env))
}

// Retrieve only unique versions
encountered := map[string]bool{}
for v := range versions {
encountered[versions[v]] = true
}
uniqueVersions := []string{}
for key := range encountered {
uniqueVersions = append(uniqueVersions, key)
return err
}

for _, uniqueVersion := range uniqueVersions {
Expand Down
29 changes: 29 additions & 0 deletions deployers/deployer.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package deployers

import (
"errors"
"fmt"
)

type State struct {
Step string
Progress int
Expand All @@ -18,3 +23,27 @@ type Deployer interface {
ListVcsVersions(env string) ([]string, error)
Deploy(env string, podVersion string, c chan State) error
}

func ListUniqueVcsVersions(d Deployer, env string) ([]string, error) {
uniqueVersions := []string{}
versions, err := d.ListVcsVersions(env)
if err != nil {
return uniqueVersions, errors.New(fmt.Sprintf("Failed to list versions with error %q \n", err))
}

if len(versions) == 0 {
return uniqueVersions, errors.New(fmt.Sprintf("No versions found for the Env: %q \n", env))
}

// Retrieve only unique versions
encountered := map[string]bool{}
for v := range versions {
encountered[versions[v]] = true
}

for key := range encountered {
uniqueVersions = append(uniqueVersions, key)
}

return uniqueVersions, nil
}
25 changes: 25 additions & 0 deletions deployers/deployer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,28 @@ import (

func TestDeployerRegistry(t *testing.T) {
}

func TestListUniqueVcsVersions(t *testing.T) {
envs := make(map[string]string)
envs["staging"] = "staging"
execCommand = mockggn
d := DeployerGgn{
Service: "webhooks",
Pod: "pod-webhooks",
Environments: envs,
VcsRegexp: "-(.+)",
}

uniqueVersions, err := ListUniqueVcsVersions(&d, "staging")
if err != nil {
t.Fatalf("Error trying to retrieve unique version: %q", err)
}

if len(uniqueVersions) != 1 {
t.Fatalf("uniqueVersions len should be 1 instead got %s", len(uniqueVersions))
}

if uniqueVersions[0] != "1" {
t.Error("uniqueVersion should \"1\" instead got %s", uniqueVersions[0])
}
}
4 changes: 2 additions & 2 deletions hooks/exec_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ func (e ExecCommand) Init() error {
return executeCommands(e.OnInit)
}

func (e ExecCommand) PreDeployment(username string, env string, service string, podVersion string) error {
func (e ExecCommand) PreDeployment(hookinformation HookInformation) error {
return executeCommands(e.OnPreDeploy)
}

func (e ExecCommand) PostDeployment(username string, env string, service string, podVersion string) error {
func (e ExecCommand) PostDeployment(hookinformation HookInformation) error {
return executeCommands(e.OnPostDeploy)
}

Expand Down
12 changes: 10 additions & 2 deletions hooks/hooks.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package hooks

type HookInformation struct {
UserName string
Env string
Service string
PodVersion string
Miscellaneous []string
}

type Hooks interface {
Init() error
PreDeployment(userName string, env string, service string, podVersion string) error
PostDeployment(userName string, env string, service string, podVersion string) error
PreDeployment(hookinformation HookInformation) error
PostDeployment(hookinformation HookInformation) error
StopOnError() bool
}
17 changes: 11 additions & 6 deletions hooks/newrelic.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ func (c NewRelicClient) Init() error {
return nil
}

func (c NewRelicClient) PreDeployment(userName string, env string, service string, podVersion string) error {
func (c NewRelicClient) PreDeployment(hookinformation HookInformation) error {
var filter bytes.Buffer
filterTmpl, err := template.New("filter").Parse(c.ApplicationFilter)
if err != nil {
return err
}

if err := filterTmpl.Execute(&filter, struct{ env string }{env}); err != nil {
if err := filterTmpl.Execute(&filter, struct{ env string }{hookinformation.Env}); err != nil {
}

appId, err := c.findApplicationId(filter.String())
Expand All @@ -58,16 +58,21 @@ func (c NewRelicClient) PreDeployment(userName string, env string, service strin
}
c.ApplicationId = appId

description := fmt.Sprintf("Deploying %s %s on %s", service, podVersion, env)
var changelog string
for _, line := range hookinformation.Miscellaneous {
changelog = changelog + " " + line + "\n"
}
description := fmt.Sprintf("Deploying %s %s on %s", hookinformation.Service, hookinformation.PodVersion, hookinformation.Env)
d := &NewRelicDeployment{
description: description,
revision: podVersion,
user: userName,
revision: hookinformation.PodVersion,
user: hookinformation.UserName,
changelog: changelog,
}
return c.CreateDeployment(d)
}

func (c NewRelicClient) PostDeployment(userName string, env string, service string, podVersion string) error {
func (c NewRelicClient) PostDeployment(hookinformation HookInformation) error {
return nil
}

Expand Down
24 changes: 20 additions & 4 deletions hooks/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,28 @@ func (s Slack) Init() error {
}

// @TODO Later we could pass directly messages and use the go templater instead.
func (s Slack) PreDeployment(username string, env string, service string, podVersion string) error {
return s.postMessage(fmt.Sprintf("[%q]Start, update service %q version %q %q", env, service, podVersion, username))
func (s Slack) PreDeployment(hookinformation HookInformation) error {
return s.postMessage(
fmt.Sprintf(
"[%q]Start, update service %q version %q %q",
hookinformation.Env,
hookinformation.Service,
hookinformation.PodVersion,
hookinformation.UserName,
),
)
}

func (s Slack) PostDeployment(username string, env string, service string, podVersion string) error {
return s.postMessage(fmt.Sprintf("[%q]End, update service %q version %q by %q", env, service, podVersion, username))
func (s Slack) PostDeployment(hookinformation HookInformation) error {
return s.postMessage(
fmt.Sprintf(
"[%q]End, update service %q version %q by %q",
hookinformation.Env,
hookinformation.Service,
hookinformation.PodVersion,
hookinformation.UserName,
),
)
}

func (s Slack) postMessage(message string) error {
Expand Down