Skip to content

Commit

Permalink
feat(SCMC): Added capability for SCMC to be loaded from a file (#199)
Browse files Browse the repository at this point in the history
* added capability for SCMC to be loaded from a file

* fixed typo in scm tests

* updated deploy-engine to remove "generic" prefix
  • Loading branch information
cs-simental authored Oct 24, 2023
1 parent 4812ee4 commit 2eccbb1
Show file tree
Hide file tree
Showing 9 changed files with 1,584 additions and 105 deletions.
16 changes: 11 additions & 5 deletions cmd/deploy/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ type deployStartOptions struct {
targetFilters []string
context map[string]string
withSCM bool
withSCMFile string
waitForCompletion bool
}

type WithDeployConfiguration func(cmd *cobra.Command, options *deployStartOptions, scmc scm.Context, deployClient ArmoryDeployClient) (*de.StartPipelineResponse, *nethttp.Response, error)
type WithDeployConfiguration func(cmd *cobra.Command, options *deployStartOptions, scmc de.SCM, deployClient ArmoryDeployClient) (*de.StartPipelineResponse, *nethttp.Response, error)

type FormattableDeployStartResponse struct {
// The deployment's ID.
Expand Down Expand Up @@ -127,7 +128,8 @@ func NewDeployStartCmd(configuration *config.Configuration) *cobra.Command {
cmd.Flags().StringVarP(&options.application, "application", "n", "", "application name for deployment")
cmd.Flags().StringArrayVarP(&options.targetFilters, "targetFilters", "t", []string{}, "targets specified in the config file to include. Those not specified will be skipped. All specified in the config will be overridden")
cmd.Flags().StringToStringVar(&options.context, "add-context", map[string]string{}, "add context values to be used in strategy steps")
cmd.Flags().BoolVarP(&options.withSCM, "with-scm", "", false, "add source control context to be shown in ui")
cmd.Flags().BoolVar(&options.withSCM, "with-scm", false, "add source control context to be shown in ui")
cmd.Flags().StringVar(&options.withSCMFile, "with-scm-file", "", "add source control through a file path")
cmd.Flags().BoolVarP(&options.waitForCompletion, "watch", "w", false, "wait for deployment to complete")

return cmd
Expand Down Expand Up @@ -161,11 +163,15 @@ func start(cmd *cobra.Command, configuration *config.Configuration, options *dep
} else {
withConfiguration = WithLocalFile
}
var scmc scm.Context
var scmc de.SCM
if options.withSCM {
scmc, _ = scm.RetrieveContext(cmd.OutOrStdout(), scm.DefaultServiceProvider{Ctx: context.Background()})
}

if options.withSCMFile != "" {
scmc.GenericSCM, _ = scm.GetContextFromFile(cmd.OutOrStdout(), options.withSCMFile)
}

startResp, rawResp, err = withConfiguration(cmd, options, scmc, deployClient)

if err != nil {
Expand All @@ -182,7 +188,7 @@ func start(cmd *cobra.Command, configuration *config.Configuration, options *dep
return outputCommandResult(deploy, configuration)
}

func WithURL(cmd *cobra.Command, options *deployStartOptions, scmc scm.Context, deployClient ArmoryDeployClient) (*de.StartPipelineResponse, *nethttp.Response, error) {
func WithURL(cmd *cobra.Command, options *deployStartOptions, scmc de.SCM, deployClient ArmoryDeployClient) (*de.StartPipelineResponse, *nethttp.Response, error) {
if options.application != "" {
return nil, nil, ErrApplicationNameOverrideNotSupported
}
Expand Down Expand Up @@ -216,7 +222,7 @@ func prepareTargetFilters(options *deployStartOptions) []map[string]any {
return targetFilters
}

func WithLocalFile(cmd *cobra.Command, options *deployStartOptions, scmc scm.Context, deployClient ArmoryDeployClient) (*de.StartPipelineResponse, *nethttp.Response, error) {
func WithLocalFile(cmd *cobra.Command, options *deployStartOptions, scmc de.SCM, deployClient ArmoryDeployClient) (*de.StartPipelineResponse, *nethttp.Response, error) {
//in case this is running on a github instance
gitWorkspace, present := os.LookupEnv("GITHUB_WORKSPACE")
_, isATest := os.LookupEnv("ARMORY_CLI_TEST")
Expand Down
11 changes: 5 additions & 6 deletions cmd/deploy/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"errors"
scm "github.com/armory/armory-cli/cmd/sourceControl"
"github.com/armory/armory-cli/internal/clierr"
"github.com/armory/armory-cli/internal/clierr/exitcodes"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -171,7 +170,7 @@ func (suite *DeployStartTestSuite) TestDeployWithURLUsesExpectedOptions() {
deploymentFile: "http://mytesturl.com/deploy.yml",
waitForCompletion: false,
},
scm.GetEmptyMockSCMC(),
de.SCM{},
deployClient,
)

Expand All @@ -188,7 +187,7 @@ func (suite *DeployStartTestSuite) TestDeployWithURLUsesExpectedOptions() {
deploymentFile: "http://mytesturl.com/deploy.yml",
waitForCompletion: false,
},
scm.GetEmptyMockSCMC(),
de.SCM{},
deployClient,
)

Expand Down Expand Up @@ -219,7 +218,7 @@ func (suite *DeployStartTestSuite) TestDeployWithFileUsesExpectedOptions() {
deploymentFile: tempFile.Name(),
waitForCompletion: false,
},
scm.GetEmptyMockSCMC(),
de.SCM{},
deployClient,
)
dr := deployClient.RecordedStartPipelineOptions.UnstructuredDeployment
Expand Down Expand Up @@ -259,7 +258,7 @@ func (suite *DeployStartTestSuite) TestDeployWithPipelineValidation() {

for _, c := range cases {
suite.T().Run(c.name, func(t *testing.T) {
_, _, err := WithURL(cmd, c.options, scm.GetEmptyMockSCMC(), deployClient)
_, _, err := WithURL(cmd, c.options, de.SCM{}, deployClient)
assert.ErrorIs(t, err, c.expectedErr)
})
}
Expand All @@ -286,7 +285,7 @@ func (suite *DeployStartTestSuite) TestDeployWithPipelineIdUsesExpectedOptions()
deploymentFile: "armory::http://localhost:9099/pipelines/012345/config",
waitForCompletion: false,
},
scm.GetEmptyMockSCMC(),
de.SCM{},
deployClient,
)
suite.NoError(err)
Expand Down
55 changes: 25 additions & 30 deletions cmd/sourceControl/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ import (
)

type (
GithubContext struct {
de.GithubSCM
service GithubService
}

GithubService interface {
GetPR() (gh.PullRequest, error)
}
Expand All @@ -36,36 +31,36 @@ type (
}
)

func (gc GithubContext) GetContext() (Context, error) {
githubContext := GithubContext{
GithubSCM: de.GithubSCM{
SCM: de.SCM{
Type: de.Github,
Event: de.Event(os.Getenv(de.GithubEvent)),
Reference: de.Reference(os.Getenv(de.GithubRefType)),
ReferenceName: os.Getenv(de.GithubRefName),
Principal: os.Getenv(de.GithubActor),
TriggeringPrincipal: os.Getenv(de.GithubTriggeringActor),
SHA: os.Getenv(de.GithubSHA),
Repository: os.Getenv(de.GithubRepo),
Server: os.Getenv(de.GithubServer)},
GithubData: de.GithubData{
RunId: os.Getenv(de.GithubRunID),
Workflow: os.Getenv(de.GithubWorkflow),
}}}

pr, err := gc.service.GetPR()
func GetGithubContext(service GithubService) (de.GithubSCM, de.GithubData, error) {

githubSCM := de.GithubSCM{
Type: de.Github,
Event: de.Event(os.Getenv(de.GithubEvent)),
Reference: de.Reference(os.Getenv(de.GithubRefType)),
ReferenceName: os.Getenv(de.GithubRefName),
Principal: os.Getenv(de.GithubActor),
TriggeringPrincipal: os.Getenv(de.GithubTriggeringActor),
SHA: os.Getenv(de.GithubSHA),
Repository: os.Getenv(de.GithubRepo),
Server: os.Getenv(de.GithubServer),
}
githubData := de.GithubData{
RunId: os.Getenv(de.GithubRunID),
Workflow: os.Getenv(de.GithubWorkflow),
}

pr, err := service.GetPR()

if err != nil {
return githubContext, err
return githubSCM, githubData, err
}

githubContext.Source = pr.GetHead().GetRef()
githubContext.Target = pr.GetBase().GetRef()
githubContext.PRTitle = pr.GetTitle()
githubContext.PRUrl = getURL(pr.GetNumber())
githubSCM.Source = pr.GetHead().GetRef()
githubSCM.Target = pr.GetBase().GetRef()
githubSCM.PRTitle = pr.GetTitle()
githubSCM.PRUrl = getURL(pr.GetNumber())

return githubContext, err
return githubSCM, githubData, nil
}

func getURL(number int) string {
Expand Down
12 changes: 0 additions & 12 deletions cmd/sourceControl/mockSCM.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ type (
}
)

func (mock MockSmc) GetContext() (Context, error) {
scmc := MockSmc{
SCM: de.SCM{
Type: "mock"}}
return scmc, nil
}

func GetEmptyMockSCMC() Context {
scmc, _ := MockSmc{}.GetContext()
return scmc
}

func (m MockServiceProvider) GetGithubService() GithubService {
return m.service
}
Expand Down
64 changes: 58 additions & 6 deletions cmd/sourceControl/scm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package sourceControl
import (
"context"
"fmt"
de "github.com/armory-io/deploy-engine/pkg/api"
"github.com/fatih/color"
"gopkg.in/yaml.v3"
"io"
"os"
)

type (
Expand All @@ -21,20 +24,69 @@ type (
}
)

func RetrieveContext(out io.Writer, provider ServiceProvider) (Context, error) {
var scmc Context
func RetrieveContext(out io.Writer, provider ServiceProvider) (de.SCM, error) {
var scmc de.SCM
var err error

scmc, err = GithubContext{service: provider.GetGithubService()}.GetContext()
scmc.GithubSCM, scmc.GithubData, err = GetGithubContext(provider.GetGithubService())

ErrorLogger(out, err)

return scmc, err
}

func GetContextFromFile(out io.Writer, path string) (de.GenericSCM, error) {
var err error
genericSCM := de.GenericSCM{}

file, err := RetrieveFile(path)

if ErrorLogger(out, err) {
return genericSCM, err
}

genericSCM, err = Unmarshall(file)
ErrorLogger(out, err)

return genericSCM, err
}

func RetrieveFile(path string) ([]byte, error) {
var file []byte
var fullPath = path

//in case this is running on a github instance
gitWorkspace, present := os.LookupEnv("GITHUB_WORKSPACE")

if present {
fullPath = gitWorkspace + path
}

// read yaml file
file, err := os.ReadFile(fullPath)
if err != nil {
msg := color.New(color.FgYellow, color.Bold).Sprintln("\nscm warning: ")
fmt.Fprintf(out, "%s %s\n\n", msg, err)
return nil, err
}
return file, nil
}

return scmc, err
func Unmarshall(file []byte) (de.GenericSCM, error) {
var payload de.GenericSCM
if err := yaml.Unmarshal(file, &payload); err != nil {
return de.GenericSCM{}, err
}
return payload, nil
}

func (d DefaultServiceProvider) GetGithubService() GithubService {
return DefaultGithubService{client: &DefaultGithubClient{ctx: context.Background()}}
}

func ErrorLogger(out io.Writer, err error) bool {
if err != nil {
msg := color.New(color.FgYellow, color.Bold).Sprintln("\nscm warning: ")
fmt.Fprintf(out, "%s %s\n\n", msg, err)
return true
}
return false
}
Loading

0 comments on commit 2eccbb1

Please sign in to comment.