diff --git a/docs/plugins/argocdapp.md b/docs/plugins/argocdapp.md index d89f3f4d4..f225f1294 100644 --- a/docs/plugins/argocdapp.md +++ b/docs/plugins/argocdapp.md @@ -72,3 +72,32 @@ In the example above: - We used `repo-scaffolding.golang-github`'s output as input for the `githubactions-golang` plugin. Pay attention to the `${{ xxx }}` part in the example. `${{ TOOL_NAME.PLUGIN.outputs.var}}` is the syntax for using an output. + +## Automatically Create Helm Configuration + +This plugin can push helm configuration automatically when your source.path helm config not exist, so you can use this plugin with helm configured alreay. For example: + +```yaml +--- +tools: +- name: go-webapp-argocd-deploy + plugin: argocdapp + dependsOn: ["repo-scaffolding.golang-github"] + options: + app: + name: hello + namespace: argocd + destination: + server: https://kubernetes.default.svc + namespace: default + source: + valuefile: values.yaml + path: charts/go-hello-http + repoURL: ${{repo-scaffolding.golang-github.outputs.repoURL}} + imageRepo: + url: http://test.barbor.com/library + user: test_owner + tag: "1.0.0" +``` + +This config will push default helm config to repo `${{repo-scaffolding.golang-github.outputs.repoURL}}`, and the generated config will use image `http://test.barbor.com/library/test_owner/hello:1.0.0` as inital image for helm. diff --git a/internal/pkg/configmanager/app.go b/internal/pkg/configmanager/app.go index 92fe1fba3..91e0684f7 100644 --- a/internal/pkg/configmanager/app.go +++ b/internal/pkg/configmanager/app.go @@ -5,6 +5,7 @@ import ( "github.com/devstream-io/devstream/pkg/util/log" "github.com/devstream-io/devstream/pkg/util/scm" + "github.com/devstream-io/devstream/pkg/util/scm/git" ) const ( @@ -23,41 +24,49 @@ type app struct { RepoTemplate *repoTemplate `yaml:"repoTemplate" mapstructure:"repoTemplate"` CIRawConfigs []pipelineRaw `yaml:"ci" mapstructure:"ci"` CDRawConfigs []pipelineRaw `yaml:"cd" mapstructure:"cd"` + + // these two variables is used internal for convince + // repoInfo is generated from Repo field with setDefault method + repoInfo *git.RepoInfo `yaml:"-" mapstructure:"-"` + // repoTemplateInfo is generated from RepoTemplate field with setDefault method + repoTemplateInfo *git.RepoInfo `yaml:"-" mapstructure:"-"` } func (a *app) getTools(vars map[string]any, templateMap map[string]string) (Tools, error) { - // generate app repo and template repo from scmInfo - a.setDefault() - repoScaffoldingTool, err := a.getRepoTemplateTool() - if err != nil { - return nil, fmt.Errorf("app[%s] can't get valid repo config: %w", a.Name, err) + // 1. set app default field repoInfo and repoTemplateInfo + if err := a.setDefault(); err != nil { + return nil, err } - // get ci/cd pipelineTemplates + // 2. get ci/cd pipelineTemplates appVars := a.Spec.merge(vars) tools, err := a.generateCICDTools(templateMap, appVars) if err != nil { return nil, fmt.Errorf("app[%s] get pipeline tools failed: %w", a.Name, err) } + + // 3. generate app repo and template repo from scmInfo + repoScaffoldingTool := a.generateRepoTemplateTool() if repoScaffoldingTool != nil { tools = append(tools, repoScaffoldingTool) } - log.Debugf("Have got %d tools from app %s.", len(tools), a.Name) - return tools, nil } -// getAppPipelineTool generate ci/cd tools from app config +// generateAppPipelineTool generate ci/cd tools from app config func (a *app) generateCICDTools(templateMap map[string]string, appVars map[string]any) (Tools, error) { allPipelineRaw := append(a.CIRawConfigs, a.CDRawConfigs...) var tools Tools + // pipelineGlobalVars is used to pass variable from ci/cd pipelines + pipelineGlobalVars := a.newPipelineGlobalOptionFromApp() for _, p := range allPipelineRaw { t, err := p.getPipelineTemplate(templateMap, appVars) if err != nil { return nil, err } - pipelineTool, err := t.generatePipelineTool(a) + t.updatePipelineVars(pipelineGlobalVars) + pipelineTool, err := t.generatePipelineTool(pipelineGlobalVars) if err != nil { return nil, err } @@ -67,41 +76,48 @@ func (a *app) generateCICDTools(templateMap map[string]string, appVars map[strin return tools, nil } -// getRepoTemplateTool will use repo-scaffolding plugin for app -func (a *app) getRepoTemplateTool() (*Tool, error) { - if a.Repo == nil { - return nil, fmt.Errorf("app.repo field can't be empty") - } - appRepo, err := a.Repo.BuildRepoInfo() - if err != nil { - return nil, fmt.Errorf("configmanager[app] parse repo failed: %w", err) - } - if a.RepoTemplate != nil { +// generateRepoTemplateTool will use repo-scaffolding plugin for app +func (a *app) generateRepoTemplateTool() *Tool { + if a.repoTemplateInfo != nil { + templateVars := make(RawOptions) // templateRepo doesn't need auth info - templateRepo, err := a.RepoTemplate.BuildRepoInfo() - templateRepo.NeedAuth = false - if err != nil { - return nil, fmt.Errorf("configmanager[app] parse repoTemplate failed: %w", err) - } if a.RepoTemplate.Vars == nil { - a.RepoTemplate.Vars = make(RawOptions) + templateVars = make(RawOptions) } return newTool( repoScaffoldingPluginName, a.Name, RawOptions{ - "destinationRepo": RawOptions(appRepo.Encode()), - "sourceRepo": RawOptions(templateRepo.Encode()), - "vars": a.RepoTemplate.Vars, + "destinationRepo": RawOptions(a.repoInfo.Encode()), + "sourceRepo": RawOptions(a.repoTemplateInfo.Encode()), + "vars": templateVars, }, - ), nil + ) } - return nil, nil + return nil } // setDefault will set repoName to appName if repo.name field is empty -func (a *app) setDefault() { - if a.Repo != nil && a.Repo.Name == "" { +func (a *app) setDefault() error { + if a.Repo == nil { + return fmt.Errorf("configmanager[app] is invalid, repo field must be configured") + } + if a.Repo.Name == "" { a.Repo.Name = a.Name } + appRepo, err := a.Repo.BuildRepoInfo() + if err != nil { + return fmt.Errorf("configmanager[app] parse repo failed: %w", err) + } + a.repoInfo = appRepo + if a.RepoTemplate != nil { + // templateRepo doesn't need auth info + templateRepo, err := a.RepoTemplate.BuildRepoInfo() + if err != nil { + return fmt.Errorf("configmanager[app] parse repoTemplate failed: %w", err) + } + templateRepo.NeedAuth = false + a.repoTemplateInfo = templateRepo + } + return nil } // since all plugin depends on code is deployed, get dependsOn for repoTemplate @@ -113,3 +129,13 @@ func (a *app) getRepoTemplateDependants() []string { } return dependsOn } + +// newPipelineGlobalOptionFromApp generate pipeline options used for pipeline option configuration +func (a *app) newPipelineGlobalOptionFromApp() *pipelineGlobalOption { + return &pipelineGlobalOption{ + RepoInfo: a.repoInfo, + AppSpec: a.Spec, + Scm: a.Repo, + AppName: a.Name, + } +} diff --git a/internal/pkg/configmanager/app_test.go b/internal/pkg/configmanager/app_test.go index 981644e67..18322ba03 100644 --- a/internal/pkg/configmanager/app_test.go +++ b/internal/pkg/configmanager/app_test.go @@ -1,8 +1,6 @@ package configmanager import ( - "fmt" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -29,7 +27,7 @@ var _ = Describe("app struct", func() { It("should return error", func() { _, err := a.getTools(vars, templateMap) Expect(err).Should(HaveOccurred()) - Expect(err.Error()).Should(ContainSubstring(fmt.Sprintf("app[%s] can't get valid repo config", appName))) + Expect(err.Error()).Should(ContainSubstring("configmanager[app] is invalid, repo field must be configured")) }) }) When("ci/cd template is not valid", func() { @@ -52,6 +50,57 @@ var _ = Describe("app struct", func() { Expect(err.Error()).Should(ContainSubstring("not found in pipelineTemplates")) }) }) + When("app repo template is empty", func() { + BeforeEach(func() { + a = &app{ + Name: appName, + Repo: &scm.SCMInfo{ + CloneURL: "http://test.com/test/test_app", + }, + } + }) + It("should return empty tools", func() { + tools, err := a.getTools(vars, templateMap) + Expect(err).ShouldNot(HaveOccurred()) + Expect(len(tools)).Should(Equal(0)) + }) + }) + When("repo url is not valid", func() { + BeforeEach(func() { + a = &app{ + Name: appName, + Repo: &scm.SCMInfo{ + CloneURL: "not_valid_url", + }, + } + }) + It("should return empty tools", func() { + _, err := a.getTools(vars, templateMap) + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("configmanager[app] parse repo failed")) + }) + }) + When("template repo url is not valid", func() { + BeforeEach(func() { + a = &app{ + Name: appName, + RepoTemplate: &repoTemplate{ + SCMInfo: &scm.SCMInfo{ + CloneURL: "not_valid_url", + }, + }, + Repo: &scm.SCMInfo{ + CloneURL: "http://test.com/test/test_app", + }, + } + }) + It("should return empty tools", func() { + _, err := a.getTools(vars, templateMap) + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(ContainSubstring("configmanager[app] parse repoTemplate failed")) + }) + }) + }) Context("generateCICDTools method", func() { diff --git a/internal/pkg/configmanager/appspec.go b/internal/pkg/configmanager/appspec.go index c5ff4c481..da678b41d 100644 --- a/internal/pkg/configmanager/appspec.go +++ b/internal/pkg/configmanager/appspec.go @@ -21,10 +21,7 @@ func (s *appSpec) merge(vars map[string]any) map[string]any { log.Warnf("appspec %+v decode failed: %+v", s, err) return map[string]any{} } - if err := mergo.Merge(&specMap, vars); err != nil { - log.Warnf("appSpec %+v merge map failed: %+v", s, err) - return vars - } + _ = mergo.Merge(&specMap, vars) return specMap } diff --git a/internal/pkg/configmanager/config.go b/internal/pkg/configmanager/config.go index e0097cab3..1b97b2bb6 100644 --- a/internal/pkg/configmanager/config.go +++ b/internal/pkg/configmanager/config.go @@ -2,8 +2,6 @@ package configmanager import ( "fmt" - - "gopkg.in/yaml.v3" ) // Config is a general config in DevStream. @@ -24,7 +22,7 @@ func (c *Config) renderInstanceIDtoOptions() { func (c *Config) validate() error { if c.Config.State == nil { - return fmt.Errorf("state is not defined") + return fmt.Errorf("config.state is not defined") } if err := c.Tools.validateAll(); err != nil { @@ -32,11 +30,3 @@ func (c *Config) validate() error { } return nil } - -func (c *Config) String() string { - bs, err := yaml.Marshal(c) - if err != nil { - return err.Error() - } - return string(bs) -} diff --git a/internal/pkg/configmanager/config_test.go b/internal/pkg/configmanager/config_test.go index 3c4b27476..46a93a4f7 100644 --- a/internal/pkg/configmanager/config_test.go +++ b/internal/pkg/configmanager/config_test.go @@ -1 +1,47 @@ package configmanager + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Config struct", func() { + var ( + c *Config + toolName, instanceID string + ) + BeforeEach(func() { + c = &Config{} + toolName = "test_tool" + instanceID = "test_instance" + }) + Context("renderInstanceIDtoOptions method", func() { + When("tool option is null", func() { + BeforeEach(func() { + c.Tools = Tools{ + {Name: toolName, InstanceID: instanceID}, + } + }) + It("should set nil to RawOptions", func() { + c.renderInstanceIDtoOptions() + Expect(len(c.Tools)).Should(Equal(1)) + tool := c.Tools[0] + Expect(tool.Options).Should(Equal(RawOptions{ + "instanceID": instanceID, + })) + }) + }) + }) + Context("validate method", func() { + When("config state is null", func() { + BeforeEach(func() { + c.Config.State = nil + }) + It("should return err", func() { + err := c.validate() + Expect(err).Should(HaveOccurred()) + Expect(err.Error()).Should(Equal("config.state is not defined")) + }) + }) + }) +}) diff --git a/internal/pkg/configmanager/configmanager_test.go b/internal/pkg/configmanager/configmanager_test.go index 3f1fd60cc..9280bff9a 100644 --- a/internal/pkg/configmanager/configmanager_test.go +++ b/internal/pkg/configmanager/configmanager_test.go @@ -8,7 +8,9 @@ import ( . "github.com/onsi/gomega" ) -const configFileStr = `--- +var _ = Describe("Manager struct", func() { + var tmpWorkDir string + const configFileStr = `--- config: state: backend: local @@ -96,185 +98,183 @@ pipelineTemplates: repoURL: ${{repo-scaffolding.myapp.outputs.repoURL}} ` -var tmpWorkDir string - -var _ = Describe("LoadConfig", func() { - - tool1 := &Tool{ - Name: "plugin1", - InstanceID: "default", - DependsOn: []string{}, - Options: RawOptions{ - "foo1": "bar1", - "instanceID": "default", - }, - } + Context("LoadConfig method", func() { + tool1 := &Tool{ + Name: "plugin1", + InstanceID: "default", + DependsOn: []string{}, + Options: RawOptions{ + "foo1": "bar1", + "instanceID": "default", + }, + } - tool2 := &Tool{ - Name: "plugin2", - InstanceID: "tluafed", - DependsOn: []string{}, - Options: RawOptions{ - "instanceID": "tluafed", - "foo": "bar", - "foo2": 123, - }, - } + tool2 := &Tool{ + Name: "plugin2", + InstanceID: "tluafed", + DependsOn: []string{}, + Options: RawOptions{ + "instanceID": "tluafed", + "foo": "bar", + "foo2": 123, + }, + } - tool3 := &Tool{ - Name: "github-actions", - InstanceID: "service-a", - DependsOn: []string{ - "repo-scaffolding.service-a", - "plugin1.default", - "plugin2.tluafed", - }, - Options: RawOptions{ - "instanceID": "service-a", - "pipeline": RawOptions{ - "language": RawOptions{ - "name": "python", - "framework": "django", - }, - "docker": RawOptions{ - "registry": RawOptions{ - "repository": "service-a", - "type": "dockerhub", - "username": "dockerUser1", + tool3 := &Tool{ + Name: "github-actions", + InstanceID: "service-a", + DependsOn: []string{ + "repo-scaffolding.service-a", + "plugin1.default", + "plugin2.tluafed", + }, + Options: RawOptions{ + "instanceID": "service-a", + "pipeline": RawOptions{ + "language": RawOptions{ + "name": "python", + "framework": "django", + }, + "docker": RawOptions{ + "registry": RawOptions{ + "repository": "service-a", + "type": "dockerhub", + "username": "dockerUser1", + }, }, + "branch": "main", + "configLocation": "https://raw.githubusercontent.com/devstream-io/ci-template/main/github-actions/workflows/main.yml", + }, + "scm": RawOptions{ + "apiURL": "gitlab.com/some/path/to/your/api", + "owner": "devstream-io", + "org": "devstream-io", + "name": "service-a", + "scmType": "github", + "url": "https://github.com/devstream-io/service-a", }, - "branch": "main", - "configLocation": "https://raw.githubusercontent.com/devstream-io/ci-template/main/github-actions/workflows/main.yml", - }, - "scm": RawOptions{ - "apiURL": "gitlab.com/some/path/to/your/api", - "owner": "devstream-io", - "org": "devstream-io", - "name": "service-a", - "scmType": "github", - "url": "https://github.com/devstream-io/service-a", }, - }, - } + } - tool4 := &Tool{ - Name: "argocdapp", - InstanceID: "service-a", - DependsOn: []string{ - "repo-scaffolding.service-a", - "plugin1.default", - "plugin2.tluafed", - }, - Options: RawOptions{ - "instanceID": "service-a", - "destination": RawOptions{ - "namespace": "devstream-io", - "server": "https://kubernetes.default.svc", - }, - "app": RawOptions{ - "namespace": "argocd", + tool4 := &Tool{ + Name: "argocdapp", + InstanceID: "service-a", + DependsOn: []string{ + "repo-scaffolding.service-a", + "plugin1.default", + "plugin2.tluafed", }, - "source": RawOptions{ - "valuefile": "values.yaml", - "path": "helm/service-a", - "repoURL": "${{repo-scaffolding.myapp.outputs.repoURL}}", + Options: RawOptions{ + "instanceID": "service-a", + "destination": RawOptions{ + "namespace": "devstream-io", + "server": "https://kubernetes.default.svc", + }, + "app": RawOptions{ + "namespace": "argocd", + }, + "source": RawOptions{ + "valuefile": "values.yaml", + "path": "helm/service-a", + "repoURL": "${{repo-scaffolding.myapp.outputs.repoURL}}", + }, }, - }, - } + } - tool5 := &Tool{ - Name: "repo-scaffolding", - InstanceID: "service-a", - DependsOn: []string{ - "plugin1.default", - "plugin2.tluafed", - }, - Options: RawOptions{ - "instanceID": "service-a", - "destinationRepo": RawOptions{ - "needAuth": true, - "org": "devstream-io", - "repo": "service-a", - "branch": "main", - "repoType": "github", - "url": "github.com/devstream-io/service-a", + tool5 := &Tool{ + Name: "repo-scaffolding", + InstanceID: "service-a", + DependsOn: []string{ + "plugin1.default", + "plugin2.tluafed", }, - "sourceRepo": RawOptions{ - "repoType": "github", - "url": "github.com/devstream-io/dtm-scaffolding-golang", - "org": "devstream-io", - "repo": "dtm-scaffolding-golang", - "branch": "main", + Options: RawOptions{ + "instanceID": "service-a", + "destinationRepo": RawOptions{ + "needAuth": true, + "org": "devstream-io", + "repo": "service-a", + "branch": "main", + "repoType": "github", + "url": "github.com/devstream-io/service-a", + }, + "sourceRepo": RawOptions{ + "repoType": "github", + "url": "github.com/devstream-io/dtm-scaffolding-golang", + "org": "devstream-io", + "repo": "dtm-scaffolding-golang", + "branch": "main", + }, + "vars": RawOptions{}, }, - "vars": RawOptions{}, - }, - } - - BeforeEach(func() { - tmpWorkDir = GinkgoT().TempDir() - err := os.WriteFile(filepath.Join(tmpWorkDir, "config.yaml"), []byte(configFileStr), 0644) - Expect(err).NotTo(HaveOccurred()) - }) + } - When("load a config file", func() { - It("should return tools", func() { - mgr := NewManager(filepath.Join(tmpWorkDir, "config.yaml")) - cfg, err := mgr.LoadConfig() + BeforeEach(func() { + tmpWorkDir = GinkgoT().TempDir() + err := os.WriteFile(filepath.Join(tmpWorkDir, "config.yaml"), []byte(configFileStr), 0644) Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) + }) - GinkgoWriter.Printf("Config: %v", cfg) + When("load a config file", func() { + It("should return tools", func() { + mgr := NewManager(filepath.Join(tmpWorkDir, "config.yaml")) + cfg, err := mgr.LoadConfig() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) - // config/state - Expect(*cfg.Config.State).To(Equal(State{ - Backend: "local", - Options: StateConfigOptions{ - StateFile: "devstream.state", - }, - })) + GinkgoWriter.Printf("Config: %v", cfg) - // vars - Expect(len(cfg.Vars)).To(Equal(5)) - Expect(cfg.Vars["foo1"]).To(Equal("bar1")) + // config/state + Expect(*cfg.Config.State).To(Equal(State{ + Backend: "local", + Options: StateConfigOptions{ + StateFile: "devstream.state", + }, + })) - // tools - Expect(len(cfg.Tools)).To(Equal(5)) - for _, t := range cfg.Tools { - switch t.Name { - case "plugin1": - Expect(t).Should(Equal(tool1)) - case "plugin2": - Expect(t).Should(Equal(tool2)) - case "github-actions": - Expect(t).Should(Equal(tool3)) - case "argocdapp": - Expect(t).Should(Equal(tool4)) - case "repo-scaffolding": - Expect(t).Should(Equal(tool5)) - default: - Fail("Unexpected plugin name.") + // vars + Expect(len(cfg.Vars)).To(Equal(5)) + Expect(cfg.Vars["foo1"]).To(Equal("bar1")) + + // tools + Expect(len(cfg.Tools)).To(Equal(5)) + for _, t := range cfg.Tools { + switch t.Name { + case "plugin1": + Expect(t).Should(Equal(tool1)) + case "plugin2": + Expect(t).Should(Equal(tool2)) + case "github-actions": + Expect(t).Should(Equal(tool3)) + case "argocdapp": + Expect(t).Should(Equal(tool4)) + case "repo-scaffolding": + Expect(t).Should(Equal(tool5)) + default: + Fail("Unexpected plugin name.") + } } - } + }) }) }) -}) - -var _ = Describe("getConfigFromFileWithGlobalVars", func() { - BeforeEach(func() { - tmpWorkDir = GinkgoT().TempDir() - err := os.WriteFile(filepath.Join(tmpWorkDir, "config.yaml"), []byte(configFileStr), 0644) - Expect(err).NotTo(HaveOccurred()) - }) - When("get config from file", func() { - It("should return a config", func() { - mgr := NewManager(filepath.Join(tmpWorkDir, "config.yaml")) - cfg, err := mgr.getConfigFromFileWithGlobalVars() + Context("getConfigFromFileWithGlobalVars method", func() { + BeforeEach(func() { + tmpWorkDir = GinkgoT().TempDir() + err := os.WriteFile(filepath.Join(tmpWorkDir, "config.yaml"), []byte(configFileStr), 0644) Expect(err).NotTo(HaveOccurred()) - Expect(cfg.Config.State.Backend).To(Equal("local")) - Expect(cfg.Vars["foo1"]).To(Equal("bar1")) - Expect(len(cfg.Tools)).To(Equal(5)) - Expect(cfg.Tools[1].Name).To(Equal("plugin2")) + }) + + When("get config from file", func() { + It("should return a config", func() { + mgr := NewManager(filepath.Join(tmpWorkDir, "config.yaml")) + cfg, err := mgr.getConfigFromFileWithGlobalVars() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg.Config.State.Backend).To(Equal("local")) + Expect(cfg.Vars["foo1"]).To(Equal("bar1")) + Expect(len(cfg.Tools)).To(Equal(5)) + Expect(cfg.Tools[1].Name).To(Equal("plugin2")) + }) }) }) }) diff --git a/internal/pkg/configmanager/pipelineDefault.go b/internal/pkg/configmanager/pipelineDefault.go index 51bc19536..e127d1bcc 100644 --- a/internal/pkg/configmanager/pipelineDefault.go +++ b/internal/pkg/configmanager/pipelineDefault.go @@ -2,8 +2,6 @@ package configmanager import ( "fmt" - - "github.com/devstream-io/devstream/pkg/util/log" ) var optionConfiguratorMap = map[string]pipelineOption{ @@ -13,8 +11,9 @@ var optionConfiguratorMap = map[string]pipelineOption{ "argocdapp": argocdApp, } -type pipelineOptionGenerator func(originOption RawOptions, app *app) RawOptions +type pipelineOptionGenerator func(originOption RawOptions, vars *pipelineGlobalOption) RawOptions +// pipelineOption is used for config different pipeline type's default config type pipelineOption struct { defaultConfigLocation string optionGeneratorFunc pipelineOptionGenerator @@ -41,8 +40,8 @@ var ( ) // jenkinsGenerator generate jenkins pipeline config -func jenkinsGenerator(options RawOptions, app *app) RawOptions { - newOptions := pipelineGeneralGenerator(options, app) +func jenkinsGenerator(options RawOptions, globalVars *pipelineGlobalOption) RawOptions { + newOptions := pipelineGeneralGenerator(options, globalVars) // extract jenkins config from options jenkinsOptions, exist := options["jenkins"] if exist { @@ -52,23 +51,23 @@ func jenkinsGenerator(options RawOptions, app *app) RawOptions { } // pipelineGeneralGenerator generate pipeline general options from RawOptions -func pipelineGeneralGenerator(options RawOptions, app *app) RawOptions { - if app.Spec != nil { - app.Spec.updatePiplineOption(options) +func pipelineGeneralGenerator(options RawOptions, globalVars *pipelineGlobalOption) RawOptions { + if globalVars.AppSpec != nil { + globalVars.AppSpec.updatePiplineOption(options) } // update image related config newOption := make(RawOptions) newOption["pipeline"] = options - newOption["scm"] = RawOptions(app.Repo.Encode()) + newOption["scm"] = RawOptions(globalVars.Scm.Encode()) return newOption } // pipelineArgocdAppGenerator generate argocdApp options from RawOptions -func pipelineArgocdAppGenerator(options RawOptions, app *app) RawOptions { +func pipelineArgocdAppGenerator(options RawOptions, globalVars *pipelineGlobalOption) RawOptions { // config app default options if _, exist := options["app"]; !exist { options["app"] = RawOptions{ - "name": app.Name, + "name": globalVars.AppName, "namespace": "argocd", } } @@ -80,22 +79,23 @@ func pipelineArgocdAppGenerator(options RawOptions, app *app) RawOptions { } } // config source default options - repoInfo, err := app.Repo.BuildRepoInfo() - if err != nil { - log.Errorf("parse argocd repoInfo failed: %+v", err) - return options - } if source, sourceExist := options["source"]; sourceExist { sourceMap := source.(RawOptions) if _, repoURLExist := sourceMap["repoURL"]; !repoURLExist { - sourceMap["repoURL"] = repoInfo.CloneURL + sourceMap["repoURL"] = globalVars.RepoInfo.CloneURL } options["source"] = sourceMap } else { options["source"] = RawOptions{ "valuefile": "values.yaml", - "path": fmt.Sprintf("helm/%s", app.Name), - "repoURL": repoInfo.CloneURL, + "path": fmt.Sprintf("helm/%s", globalVars.AppName), + "repoURL": globalVars.RepoInfo.CloneURL, + } + } + // config imageRepo default options + if _, imageRepoExist := options["imageRepo"]; !imageRepoExist { + if len(globalVars.ImageRepo) > 0 { + options["imageRepo"] = globalVars.ImageRepo } } return options diff --git a/internal/pkg/configmanager/pipelineDefault_test.go b/internal/pkg/configmanager/pipelineDefault_test.go new file mode 100644 index 000000000..3de31ea6f --- /dev/null +++ b/internal/pkg/configmanager/pipelineDefault_test.go @@ -0,0 +1,98 @@ +package configmanager + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/devstream-io/devstream/pkg/util/scm" + "github.com/devstream-io/devstream/pkg/util/scm/git" +) + +var _ = Describe("jenkinsGenerator func", func() { + var ( + jenkinsOptions RawOptions + pipelineOptions *pipelineGlobalOption + ) + BeforeEach(func() { + jenkinsOptions = RawOptions{ + "jenkins": RawOptions{ + "url": "test.jenkins.com", + }, + "imageRepo": RawOptions{ + "user": "test_user", + }, + } + pipelineOptions = &pipelineGlobalOption{ + AppSpec: &appSpec{ + Language: "test_language", + FrameWork: "test_framework", + }, + Scm: &scm.SCMInfo{ + CloneURL: "test.scm.com", + }, + } + }) + It("should config default options", func() { + opt := jenkinsGenerator(jenkinsOptions, pipelineOptions) + Expect(opt).Should(Equal(RawOptions{ + "pipeline": RawOptions{ + "language": RawOptions{ + "name": "test_language", + "framework": "test_framework", + }, + "jenkins": RawOptions{ + "url": "test.jenkins.com", + }, + "imageRepo": RawOptions{ + "user": "test_user", + }, + }, + "scm": RawOptions{ + "url": "test.scm.com", + }, + "jenkins": RawOptions{ + "url": "test.jenkins.com", + }, + })) + }) +}) + +var _ = Describe("pipelineArgocdAppGenerator func", func() { + var ( + options RawOptions + pipelineVars *pipelineGlobalOption + ) + BeforeEach(func() { + options = RawOptions{} + pipelineVars = &pipelineGlobalOption{ + ImageRepo: map[string]any{ + "owner": "test_user", + }, + RepoInfo: &git.RepoInfo{ + CloneURL: "scm.test.com", + }, + AppName: "test_app", + } + }) + It("should return options", func() { + opt := pipelineArgocdAppGenerator(options, pipelineVars) + Expect(opt).Should(Equal(RawOptions{ + "app": RawOptions{ + "name": "test_app", + "namespace": "argocd", + }, + "destination": RawOptions{ + "server": "https://kubernetes.default.svc", + "namespace": "default", + }, + "source": RawOptions{ + "valuefile": "values.yaml", + "path": "helm/test_app", + "repoURL": "scm.test.com", + }, + "imageRepo": RawOptions{ + "owner": "test_user", + }, + })) + }) +}) diff --git a/internal/pkg/configmanager/pipelinetemplate.go b/internal/pkg/configmanager/pipelinetemplate.go index 9613610f7..4d5d15d0a 100644 --- a/internal/pkg/configmanager/pipelinetemplate.go +++ b/internal/pkg/configmanager/pipelinetemplate.go @@ -7,6 +7,8 @@ import ( "gopkg.in/yaml.v3" "github.com/devstream-io/devstream/pkg/util/mapz" + "github.com/devstream-io/devstream/pkg/util/scm" + "github.com/devstream-io/devstream/pkg/util/scm/git" ) type ( @@ -17,11 +19,20 @@ type ( Options RawOptions `yaml:"options" mapstructure:"options"` Vars RawOptions `yaml:"vars" mapstructure:"vars"` } + // pipelineTemplate is valid pipeline format pipelineTemplate struct { Name string `yaml:"name"` Type string `yaml:"type"` Options RawOptions `yaml:"options"` } + // pipelineGlobalOption is used to pass variable between ci/cd pipeline + pipelineGlobalOption struct { + ImageRepo RawOptions + RepoInfo *git.RepoInfo + AppSpec *appSpec + Scm *scm.SCMInfo + AppName string + } ) // getPipelineTemplate will generate pipleinTemplate from pipelineRaw @@ -79,7 +90,7 @@ func (p *pipelineRaw) newPipelineFromTemplate(templateMap map[string]string, glo return &t, nil } -func (t *pipelineTemplate) generatePipelineTool(app *app) (*Tool, error) { +func (t *pipelineTemplate) generatePipelineTool(pipelineOption *pipelineGlobalOption) (*Tool, error) { const configLocationKey = "configLocation" // 1.set default options if t.Options == nil { @@ -97,6 +108,16 @@ func (t *pipelineTemplate) generatePipelineTool(app *app) (*Tool, error) { } } // 4. generate tool options - pipelineFinalOptions := pipelineConfigurator.optionGeneratorFunc(t.Options, app) - return newTool(t.Type, app.Name, pipelineFinalOptions), nil + pipelineFinalOptions := pipelineConfigurator.optionGeneratorFunc(t.Options, pipelineOption) + return newTool(t.Type, pipelineOption.AppName, pipelineFinalOptions), nil +} + +func (t *pipelineTemplate) updatePipelineVars(vars *pipelineGlobalOption) { + imageRepo, exist := t.Options["imageRepo"] + if exist { + imageRepoMap, ok := imageRepo.(RawOptions) + if ok { + vars.ImageRepo = imageRepoMap + } + } } diff --git a/internal/pkg/configmanager/pipelinetemplate_test.go b/internal/pkg/configmanager/pipelinetemplate_test.go index 30c36b6a9..7b5f79cec 100644 --- a/internal/pkg/configmanager/pipelinetemplate_test.go +++ b/internal/pkg/configmanager/pipelinetemplate_test.go @@ -187,7 +187,7 @@ var _ = Describe("PipelineTemplate struct", func() { s *scm.SCMInfo opts map[string]any appName, cloneURL string - a *app + globalOption *pipelineGlobalOption ) BeforeEach(func() { appName = "test_app" @@ -196,9 +196,9 @@ var _ = Describe("PipelineTemplate struct", func() { s = &scm.SCMInfo{ CloneURL: cloneURL, } - a = &app{ - Repo: s, - Name: appName, + globalOption = &pipelineGlobalOption{ + Scm: s, + AppName: appName, } }) Context("generatePipelineTool method", func() { @@ -207,7 +207,7 @@ var _ = Describe("PipelineTemplate struct", func() { t.Type = "not_exist" }) It("should return err", func() { - _, err := t.generatePipelineTool(a) + _, err := t.generatePipelineTool(globalOption) Expect(err).Error().Should(HaveOccurred()) Expect(err.Error()).Should(ContainSubstring("pipeline type [not_exist] not supported for now")) }) @@ -222,7 +222,7 @@ var _ = Describe("PipelineTemplate struct", func() { t.Options = opts }) It("should return tool", func() { - tool, err := t.generatePipelineTool(a) + tool, err := t.generatePipelineTool(globalOption) Expect(err).Error().ShouldNot(HaveOccurred()) Expect(tool).Should(Equal(&Tool{ Name: t.Type, @@ -241,4 +241,24 @@ var _ = Describe("PipelineTemplate struct", func() { }) }) }) + + Context("updatePipelineVars method", func() { + var pipelineOpt *pipelineGlobalOption + + BeforeEach(func() { + t.Options = RawOptions{ + "imageRepo": RawOptions{ + "user": "test_user", + }, + } + pipelineOpt = &pipelineGlobalOption{} + }) + It("should update global option", func() { + t.updatePipelineVars(pipelineOpt) + Expect(pipelineOpt.ImageRepo).ShouldNot(BeNil()) + Expect(pipelineOpt.ImageRepo).Should(Equal(RawOptions{ + "user": "test_user", + })) + }) + }) }) diff --git a/internal/pkg/plugin/argocdapp/create.go b/internal/pkg/plugin/argocdapp/create.go index 6abb07a26..d3be2f1b5 100644 --- a/internal/pkg/plugin/argocdapp/create.go +++ b/internal/pkg/plugin/argocdapp/create.go @@ -14,6 +14,7 @@ func Create(options configmanager.RawOptions) (statemanager.ResourceStatus, erro // Initialize Operator with Operations operator := &installer.Operator{ PreExecuteOperations: installer.PreExecuteOperations{ + setDefault, validate, }, ExecuteOperations: installer.ExecuteOperations{ diff --git a/internal/pkg/plugin/argocdapp/delete.go b/internal/pkg/plugin/argocdapp/delete.go index 1f4a20f1c..9fca8c148 100644 --- a/internal/pkg/plugin/argocdapp/delete.go +++ b/internal/pkg/plugin/argocdapp/delete.go @@ -11,6 +11,7 @@ func Delete(options configmanager.RawOptions) (bool, error) { // Initialize Operator with Operations operator := &installer.Operator{ PreExecuteOperations: installer.PreExecuteOperations{ + setDefault, validate, }, ExecuteOperations: installer.ExecuteOperations{ diff --git a/internal/pkg/plugin/argocdapp/options.go b/internal/pkg/plugin/argocdapp/options.go index 01264ddd5..5911530c6 100644 --- a/internal/pkg/plugin/argocdapp/options.go +++ b/internal/pkg/plugin/argocdapp/options.go @@ -1,6 +1,7 @@ package argocdapp import ( + "fmt" "path/filepath" "github.com/mitchellh/mapstructure" @@ -19,12 +20,13 @@ type options struct { App *app `mapstructure:"app" validate:"required"` Destination *destination `mapstructure:"destination"` Source *source `mapstructure:"source" validate:"required"` - ImageRepo imageRepo `mapstructure:"imageRepo"` + ImageRepo *imageRepo `mapstructure:"imageRepo"` } type imageRepo struct { - Address string `mapstructure:"address"` - Tag string `mapstructure:"tag"` + URL string `mapstructure:"url"` + User string `mapstructure:"user" validate:"required"` + InitalTag string `mapstructure:"initalTag"` } // app is the struct for an ArgoCD app. @@ -69,12 +71,16 @@ func (s *source) checkPathExist(scmClient scm.ClientOperation) (bool, error) { } func (o *options) getArgocdDefaultConfigFiles(configLocation downloader.ResourceLocation) (git.GitFileContentMap, error) { - // 1. get configs from remote url + // 1. check imageRepo is configured + if o.ImageRepo == nil { + return nil, fmt.Errorf("argocdapp create config need config imageRepo options") + } + // 2. get configs from remote url configFiles, err := configLocation.Download() if err != nil { return nil, err } - // 2. get file content + // 3. get file content fContentFunc := func(filePath string) ([]byte, error) { renderContent, err := template.New().FromLocalFile(filePath).SetDefaultRender("argocd config", o).Render() if err != nil { diff --git a/internal/pkg/plugin/argocdapp/options_test.go b/internal/pkg/plugin/argocdapp/options_test.go index adc190325..77035c4bf 100644 --- a/internal/pkg/plugin/argocdapp/options_test.go +++ b/internal/pkg/plugin/argocdapp/options_test.go @@ -85,6 +85,11 @@ var _ = Describe("options struct", func() { Path: "test_path", RepoURL: "https://test.com/owner/repo", }, + ImageRepo: &imageRepo{ + URL: "test.com", + User: "user", + InitalTag: "latest", + }, } pathName = "/configLoc" reqPath = fmt.Sprintf("%s%s", s.URL(), pathName) @@ -110,8 +115,12 @@ var _ = Describe("options struct", func() { When("all valid", func() { BeforeEach(func() { configFileContent := ` -app: - name: [[ .App.Name ]]` +image: + repository: [[ .ImageRepo.URL ]]/[[ .ImageRepo.User ]] + tag: [[ .ImageRepo.InitalTag ]] + pullPolicy: Always + +` s.RouteToHandler("GET", pathName, ghttp.CombineHandlers( ghttp.VerifyRequest("GET", pathName), ghttp.RespondWith(http.StatusOK, configFileContent), diff --git a/internal/pkg/plugin/argocdapp/read.go b/internal/pkg/plugin/argocdapp/read.go index 65983c4bf..5c54002fd 100644 --- a/internal/pkg/plugin/argocdapp/read.go +++ b/internal/pkg/plugin/argocdapp/read.go @@ -10,6 +10,7 @@ func Read(options configmanager.RawOptions) (statemanager.ResourceStatus, error) // Initialize Operator with Operations operator := &installer.Operator{ PreExecuteOperations: installer.PreExecuteOperations{ + setDefault, validate, }, GetStatusOperation: getDynamicStatus, diff --git a/internal/pkg/plugin/argocdapp/state_test.go b/internal/pkg/plugin/argocdapp/state_test.go new file mode 100644 index 000000000..b4d29edae --- /dev/null +++ b/internal/pkg/plugin/argocdapp/state_test.go @@ -0,0 +1,49 @@ +package argocdapp + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/devstream-io/devstream/internal/pkg/configmanager" + "github.com/devstream-io/devstream/internal/pkg/statemanager" +) + +var _ = Describe("getStaticStatus func", func() { + var option configmanager.RawOptions + BeforeEach(func() { + option = configmanager.RawOptions{ + "app": map[string]any{ + "name": "test", + "namespace": "test_namespace", + }, + "source": map[string]any{ + "repoURL": "test.com", + "path": "test_path", + "valueFile": "val_file", + }, + "destination": map[string]any{ + "server": "test_server", + "namespace": "dst_namespace", + }, + } + }) + It("should return status", func() { + state, err := getStaticStatus(option) + Expect(err).ShouldNot(HaveOccurred()) + Expect(state).Should(Equal(statemanager.ResourceStatus{ + "app": map[string]any{ + "namespace": "test_namespace", + "name": "test", + }, + "src": map[string]any{ + "repoURL": "test.com", + "path": "test_path", + "valueFile": "val_file", + }, + "dest": map[string]any{ + "server": "test_server", + "namespace": "dst_namespace", + }, + })) + }) +}) diff --git a/internal/pkg/plugin/argocdapp/validate.go b/internal/pkg/plugin/argocdapp/validate.go index ab5da4df4..ea76e9920 100644 --- a/internal/pkg/plugin/argocdapp/validate.go +++ b/internal/pkg/plugin/argocdapp/validate.go @@ -1,7 +1,11 @@ package argocdapp import ( + "fmt" + "strings" + "github.com/devstream-io/devstream/internal/pkg/configmanager" + "github.com/devstream-io/devstream/pkg/util/mapz" "github.com/devstream-io/devstream/pkg/util/validator" ) @@ -16,3 +20,21 @@ func validate(options configmanager.RawOptions) (configmanager.RawOptions, error } return options, nil } + +func setDefault(options configmanager.RawOptions) (configmanager.RawOptions, error) { + const defaultImageTag = "0.0.1" + opts, err := newOptions(options) + if err != nil { + return nil, err + } + // imageRepo initalTag use latest by default + if opts.ImageRepo != nil { + if opts.ImageRepo.InitalTag == "" { + opts.ImageRepo.InitalTag = defaultImageTag + } + if opts.ImageRepo.URL != "" && strings.HasSuffix(opts.ImageRepo.URL, "") { + opts.ImageRepo.URL = fmt.Sprintf("%s/", opts.ImageRepo.URL) + } + } + return mapz.DecodeStructToMap(opts) +} diff --git a/internal/pkg/plugin/argocdapp/validate_test.go b/internal/pkg/plugin/argocdapp/validate_test.go new file mode 100644 index 000000000..ff12bd017 --- /dev/null +++ b/internal/pkg/plugin/argocdapp/validate_test.go @@ -0,0 +1,38 @@ +package argocdapp + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/devstream-io/devstream/internal/pkg/configmanager" +) + +var _ = Describe("setDefault func", func() { + var option configmanager.RawOptions + + BeforeEach(func() { + option = configmanager.RawOptions{ + "imageRepo": map[string]any{ + "user": "test_user", + "url": "http://test.com", + }, + } + }) + It("should return with default value", func() { + var appOption *app + var sourceOption *source + var destinationOption *destination + opt, err := setDefault(option) + Expect(err).ShouldNot(HaveOccurred()) + Expect(opt).Should(Equal(configmanager.RawOptions{ + "app": appOption, + "destination": destinationOption, + "source": sourceOption, + "imageRepo": map[string]any{ + "url": "http://test.com/", + "user": "test_user", + "initalTag": "0.0.1", + }, + })) + }) +}) diff --git a/internal/pkg/plugin/installer/ci/cifile/state.go b/internal/pkg/plugin/installer/ci/cifile/state.go index 36b8cd783..186b00333 100644 --- a/internal/pkg/plugin/installer/ci/cifile/state.go +++ b/internal/pkg/plugin/installer/ci/cifile/state.go @@ -26,7 +26,7 @@ func GetCIFileStatus(options configmanager.RawOptions) (statemanager.ResourceSta return nil, err } - statusMap := make(map[string]interface{}) + statusMap := make(statemanager.ResourceStatus) for scmPath, content := range gitMap { localFileSHA := git.CalculateLocalFileSHA(content) // get remote file status @@ -34,7 +34,6 @@ func GetCIFileStatus(options configmanager.RawOptions) (statemanager.ResourceSta "localSHA": localFileSHA, "scm": getSCMFileStatus(client, scmPath), } - } return statusMap, nil } diff --git a/internal/pkg/plugin/installer/reposcaffolding/utils.go b/internal/pkg/plugin/installer/reposcaffolding/utils.go index beee4ab56..ed50bb270 100644 --- a/internal/pkg/plugin/installer/reposcaffolding/utils.go +++ b/internal/pkg/plugin/installer/reposcaffolding/utils.go @@ -49,6 +49,7 @@ func processRepoFileFunc(appName string, vars map[string]interface{}) file.DirFi log.Debugf("Walk: found file: %s.", filePath) // if file endswith tpl, render this file, else copy this file directly if strings.Contains(filePath, "tpl") { + log.Infof("--------> %s [%+v]", filePath, vars) fileContentStr, err := template.New().FromLocalFile(filePath).SetDefaultRender(appName, vars).Render() if err != nil { log.Warnf("repo render file failed: %s", err) diff --git a/internal/pkg/show/config/plugins/argocdapp.yaml b/internal/pkg/show/config/plugins/argocdapp.yaml index 978b9f99c..e2fafaa63 100644 --- a/internal/pkg/show/config/plugins/argocdapp.yaml +++ b/internal/pkg/show/config/plugins/argocdapp.yaml @@ -30,6 +30,7 @@ tools: # if repo doesn't contain path, use imageRepo to create a helm config imageRepo: # imageRepo address - address: IMAGE_REPO_ADDRESS - # image tag - tag: IMAGE_REPO_TAG + url: IMAGE_REPO_ADDRESS + user: IMAGE_REPO_OWNER + # config inital image tag + initalTag: IMAGE_REPO_TAG diff --git a/pkg/util/scm/scm.go b/pkg/util/scm/scm.go index b43b120e0..e68508458 100644 --- a/pkg/util/scm/scm.go +++ b/pkg/util/scm/scm.go @@ -68,13 +68,13 @@ func (s *SCMInfo) getRepoInfoFromURL() (*git.RepoInfo, error) { } gitlabBaseURL, err := gitlab.ExtractBaseURLfromRaw(apiURL) if err != nil { - return nil, fmt.Errorf("gitlab repo extract baseURL failed: %w", err) + return nil, err } repo.BaseURL = gitlabBaseURL } if err := repo.UpdateRepoPathByCloneURL(s.CloneURL); err != nil { - return nil, fmt.Errorf("git extract repo info failed: %w", err) + return nil, err } // if scm.branch is not configured, just use repo's default branch repo.Branch = repo.GetBranchWithDefault() diff --git a/test/e2e/yaml/e2e-apps.yaml b/test/e2e/yaml/e2e-apps.yaml index a9d9490a6..8ae2a96d5 100644 --- a/test/e2e/yaml/e2e-apps.yaml +++ b/test/e2e/yaml/e2e-apps.yaml @@ -23,9 +23,7 @@ apps: org: [[ repoOwner ]] scmType: github repoTemplate: - url: github.com/devstream-io/dtm-scaffolding-golang - vars: - imageRepo: [[ imageRepoOwner ]]/dtm-e2e-go + url: github.com/devstream-io/dtm-scaffolding-gin ci: - type: github-actions options: diff --git a/test/e2e/yaml/e2e-test-local.yaml b/test/e2e/yaml/e2e-test-local.yaml index 7f93f9b95..c52e50967 100644 --- a/test/e2e/yaml/e2e-test-local.yaml +++ b/test/e2e/yaml/e2e-test-local.yaml @@ -10,7 +10,7 @@ vars: repoName: dtm-e2e-test-golang dockerRegistryUserName: DOCKERUSERNAME argocdNameSpace: argocd-e2e-test - argocdDeployTimeout: 10m + githubActionConfigLocation: https://raw.githubusercontent.com/devstream-io/ci-template/main/github-actions/workflows/main.yml tools: - name: repo-scaffolding @@ -22,33 +22,26 @@ tools: repo: [[ repoName ]] branch: [[ defaultBranch ]] repoType: github - vars: - imageRepo: "[[ dockerhubUsername ]]/[[ repoName ]]" sourceRepo: org: devstream-io - repo: dtm-scaffolding-golang + repo: dtm-scaffolding-gin repoType: github -- name: githubactions-golang +- name: github-actions instanceID: default dependsOn: ["repo-scaffolding.golang-github"] options: - owner: ${{repo-scaffolding.golang-github.outputs.owner}} - repo: ${{repo-scaffolding.golang-github.outputs.repo}} - language: - name: go - version: "1.17" - branch: [[ defaultBranch ]] - build: - enable: True - test: - enable: True - coverage: - enable: True - docker: - enable: True - registry: - type: dockerhub - username: [[ dockerRegistryUserName ]] + pipeline: + configLocation: [[ githubActionConfigLocation ]] + imageRepo: + user: [[ dockerRegistryUserName ]] + language: + name: go + framework: gin + scm: + org: ${{repo-scaffolding.golang-github.outputs.owner}} + name: ${{repo-scaffolding.golang-github.outputs.repo}} + branch: [[ defaultBranch ]] + scmType: github - name: helm-installer instanceID: argocd-001 - name: argocdapp @@ -65,3 +58,5 @@ tools: valuefile: values.yaml path: helm/${{repo-scaffolding.golang-github.outputs.repo}} repoURL: ${{repo-scaffolding.golang-github.outputs.repoURL}} + imageRepo: + user: [[ dockerRegistryUserName ]] diff --git a/test/e2e/yaml/e2e-tools.yaml b/test/e2e/yaml/e2e-tools.yaml index ab91ddf1a..41178bff6 100644 --- a/test/e2e/yaml/e2e-tools.yaml +++ b/test/e2e/yaml/e2e-tools.yaml @@ -9,6 +9,7 @@ vars: githubOrganization: devstream-io repoName: dtme2epython dockerRegistryUserName: dtme2etest + githubActionConfigLocation: https://raw.githubusercontent.com/devstream-io/ci-template/main/github-actions/workflows/main.yml tools: - name: repo-scaffolding @@ -19,26 +20,26 @@ tools: repo: [[ repoName ]] branch: [[ defaultBranch ]] repoType: github - vars: - imageRepo: "[[ dockerRegistryUserName ]]/[[ repoName ]]" sourceRepo: org: devstream-io - repo: dtm-scaffolding-python + repo: dtm-scaffolding-flask repoType: github -- name: githubactions-python +- name: github-actions instanceID: default dependsOn: ["repo-scaffolding.python-github"] options: - org: [[ githubOrganization ]] - repo: [[ repoName ]] - language: - name: python - branch: [[ defaultBranch ]] - docker: - registry: - type: dockerhub - username: [[ dockerRegistryUserName ]] - repository: [[ repoName ]] + pipeline: + configLocation: [[ githubActionConfigLocation ]] + imageRepo: + user: [[ dockerRegistryUserName ]] + language: + name: python + framework: flask + scm: + org: [[ githubOrganization ]] + name: [[ repoName ]] + branch: [[ defaultBranch ]] + scmType: github - name: helm-installer instanceID: argocd - name: argocdapp @@ -55,3 +56,5 @@ tools: valuefile: values.yaml path: helm/[[ repoName ]] repoURL: ${{repo-scaffolding.python-github.outputs.repoURL}} + imageRepo: + user: [[ dockerRegistryUserName ]]