Skip to content

Commit

Permalink
Separate workflow gen cli/pkg (#2)
Browse files Browse the repository at this point in the history
* Separate workflow gen cli/pkg

* remove files

* make sure to copy inputs

* handle empty string variables
  • Loading branch information
bfoley13 authored May 13, 2024
1 parent 9f9b02f commit e41dee6
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 62 deletions.
51 changes: 50 additions & 1 deletion cmd/generate-workflow.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package cmd

import (
"fmt"
"strings"

"github.com/manifoldco/promptui"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/exp/maps"

"github.com/Azure/draft/pkg/prompts"
"github.com/Azure/draft/pkg/templatewriter"
"github.com/Azure/draft/pkg/templatewriter/writers"
"github.com/Azure/draft/pkg/workflows"
"github.com/Azure/draft/template"
)

type generateWorkflowCmd struct {
Expand Down Expand Up @@ -34,7 +41,7 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop
flagValuesMap = gwCmd.workflowConfig.SetFlagValuesToMap()
}
log.Info("--> Generating Github workflow")
if err := workflows.CreateWorkflows(gwCmd.dest, gwCmd.deployType, gwCmd.flagVariables, gwCmd.templateWriter, flagValuesMap); err != nil {
if err := gwCmd.generateWorkflows(gwCmd.dest, gwCmd.deployType, gwCmd.flagVariables, gwCmd.templateWriter, flagValuesMap); err != nil {
return err
}

Expand All @@ -61,3 +68,45 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop
func init() {
rootCmd.AddCommand(newGenerateWorkflowCmd())
}

func (gwc *generateWorkflowCmd) generateWorkflows(dest string, deployType string, flagVariables []string, templateWriter templatewriter.TemplateWriter, flagValuesMap map[string]string) error {
if flagValuesMap == nil {
return fmt.Errorf("flagValuesMap is nil")
}
var err error
for _, flagVar := range flagVariables {
flagVarName, flagVarValue, ok := strings.Cut(flagVar, "=")
if !ok {
return fmt.Errorf("invalid variable format: %s", flagVar)
}
flagValuesMap[flagVarName] = flagVarValue
log.Debugf("flag variable %s=%s", flagVarName, flagVarValue)
}

if deployType == "" {
selection := &promptui.Select{
Label: "Select k8s Deployment Type",
Items: []string{"helm", "kustomize", "manifests"},
}

_, deployType, err = selection.Run()
if err != nil {
return err
}
}

workflow := workflows.CreateWorkflowsFromEmbedFS(template.Workflows, dest)
workflowConfig, err := workflow.GetConfig(deployType)
if err != nil {
return fmt.Errorf("get config: %w", err)
}

customInputs, err := prompts.RunPromptsFromConfigWithSkips(workflowConfig, maps.Keys(flagValuesMap))
if err != nil {
return err
}

maps.Copy(customInputs, flagVariablesMap)

return workflow.CreateWorkflowFiles(deployType, customInputs, templateWriter)
}
4 changes: 2 additions & 2 deletions example/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ func TestWriteDockerfile(t *testing.T) {
expectError: false,
},
{
name: "Test Invalid Go Dockerfile Generation",
name: "Test Valid Go Dockerfile Generation with deafult",
inputVariables: map[string]string{
"PORT": "8080",
},
generationLanguage: "go",
expectError: true,
expectError: false,
},
{
name: "Test Invalid GenerationLanguage",
Expand Down
4 changes: 3 additions & 1 deletion pkg/config/draftconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ func (d *DraftConfig) GetNameOverride(path string) string {
// ApplyDefaultVariables will apply the defaults to variables that are not already set
func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) {
for _, variable := range d.VariableDefaults {
if _, ok := customConfig[variable.Name]; !ok {
// handle where variable is not set or is set to an empty string from cli handling
if defaultVal, ok := customConfig[variable.Name]; !ok || defaultVal == "" {
log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Value)
customConfig[variable.Name] = variable.Value
}
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/languages/languages.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func (l *Languages) CreateDockerfileForLanguage(lang string, customInputs map[st
draftConfig, ok := l.configs[lang]
if !ok {
draftConfig = nil
} else {
draftConfig.ApplyDefaultVariables(customInputs)
}

if err := osutil.CopyDir(l.dockerfileTemplates, srcDir, l.dest, draftConfig, customInputs, templateWriter); err != nil {
Expand Down
63 changes: 12 additions & 51 deletions pkg/workflows/workflows.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,18 @@ import (
"io/ioutil"
"os"
"path"
"strings"

"golang.org/x/exp/maps"
"gopkg.in/yaml.v3"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/client-go/kubernetes/scheme"

"github.com/manifoldco/promptui"
log "github.com/sirupsen/logrus"

"github.com/Azure/draft/pkg/config"
"github.com/Azure/draft/pkg/embedutils"
"github.com/Azure/draft/pkg/osutil"
"github.com/Azure/draft/pkg/prompts"
"github.com/Azure/draft/pkg/templatewriter"
"github.com/Azure/draft/template"
)

const (
Expand All @@ -39,50 +34,6 @@ type Workflows struct {
workflowTemplates fs.FS
}

func CreateWorkflows(dest string, deployType string, flagVariables []string, templateWriter templatewriter.TemplateWriter, flagValuesMap map[string]string) error {
if flagValuesMap == nil {
return fmt.Errorf("flagValuesMap is nil")
}
var err error
for _, flagVar := range flagVariables {
flagVarName, flagVarValue, ok := strings.Cut(flagVar, "=")
if !ok {
return fmt.Errorf("invalid variable format: %s", flagVar)
}
flagValuesMap[flagVarName] = flagVarValue
log.Debugf("flag variable %s=%s", flagVarName, flagVarValue)
}

if deployType == "" {
selection := &promptui.Select{
Label: "Select k8s Deployment Type",
Items: []string{"helm", "kustomize", "manifests"},
}

_, deployType, err = selection.Run()
if err != nil {
return err
}
}

workflow := createWorkflowsFromEmbedFS(template.Workflows, dest)
workflowConfig, ok := workflow.configs[deployType]
if !ok {
return errors.New("invalid deployment type")
}
customInputs, err := prompts.RunPromptsFromConfigWithSkips(workflowConfig, maps.Keys(flagValuesMap))
if err != nil {
return err
}

maps.Copy(customInputs, flagValuesMap)

if err = updateProductionDeployments(deployType, dest, customInputs, templateWriter); err != nil {
return err
}
return workflow.createWorkflowFiles(deployType, customInputs, templateWriter)
}

func updateProductionDeployments(deployType, dest string, flagValuesMap map[string]string, templateWriter templatewriter.TemplateWriter) error {
productionImage := fmt.Sprintf("%s.azurecr.io/%s", flagValuesMap["AZURECONTAINERREGISTRY"], flagValuesMap["CONTAINERNAME"])
switch deployType {
Expand Down Expand Up @@ -176,7 +127,15 @@ func (w *Workflows) loadConfig(deployType string) (*config.DraftConfig, error) {
return &draftConfig, nil
}

func createWorkflowsFromEmbedFS(workflowTemplates embed.FS, dest string) *Workflows {
func (w *Workflows) GetConfig(deployType string) (*config.DraftConfig, error) {
val, ok := w.configs[deployType]
if !ok {
return nil, fmt.Errorf("deploy type %s unsupported", deployType)
}
return val, nil
}

func CreateWorkflowsFromEmbedFS(workflowTemplates embed.FS, dest string) *Workflows {
deployMap, err := embedutils.EmbedFStoMap(workflowTemplates, parentDirName)
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -204,7 +163,7 @@ func (w *Workflows) populateConfigs() {
}
}

func (w *Workflows) createWorkflowFiles(deployType string, customInputs map[string]string, templateWriter templatewriter.TemplateWriter) error {
func (w *Workflows) CreateWorkflowFiles(deployType string, customInputs map[string]string, templateWriter templatewriter.TemplateWriter) error {
val, ok := w.workflows[deployType]
if !ok {
return fmt.Errorf("deployment type: %s is not currently supported", deployType)
Expand All @@ -214,6 +173,8 @@ func (w *Workflows) createWorkflowFiles(deployType string, customInputs map[stri
workflowConfig, ok := w.configs[deployType]
if !ok {
workflowConfig = nil
} else {
workflowConfig.ApplyDefaultVariables(customInputs)
}

if err := osutil.CopyDir(w.workflowTemplates, srcDir, w.dest, workflowConfig, customInputs, templateWriter); err != nil {
Expand Down
14 changes: 7 additions & 7 deletions pkg/workflows/workflows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
func TestCreateWorkflows(t *testing.T) {
dest := "."
deployType := "helm"
flagVariables := []string{}
templatewriter := &writers.LocalFSWriter{}
flagValuesMap := map[string]string{"AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "RESOURCEGROUP": "testRG", "CLUSTERNAME": "testCluster", "BRANCHNAME": "testBranch", "BUILDCONTEXTPATH": "."}
flagValuesMapNoRoot := map[string]string{"AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "RESOURCEGROUP": "testRG", "CLUSTERNAME": "testCluster", "BRANCHNAME": "testBranch", "BUILDCONTEXTPATH": "test"}
Expand Down Expand Up @@ -108,11 +107,12 @@ func TestCreateWorkflows(t *testing.T) {
err := createTempDeploymentFile("charts", "charts/production.yaml", "../../test/templates/helm/charts/production.yaml")
assert.Nil(t, err)

err = CreateWorkflows(dest, deployType, flagVariables, templatewriter, flagValuesMap)
workflows := CreateWorkflowsFromEmbedFS(template.Workflows, dest)
err = workflows.CreateWorkflowFiles(deployType, flagValuesMap, templatewriter)
if err != nil {
t.Errorf("Default Build Context CreateWorkflows() error = %v, wantErr %v", err, tt.shouldError)
}
err = CreateWorkflows(dest, deployType, flagVariables, templatewriter, flagValuesMapNoRoot)
err = workflows.CreateWorkflowFiles(deployType, flagValuesMapNoRoot, templatewriter)
if err != nil {
t.Errorf("Custom Build Context CreateWorkflows() error = %v, wantErr %v", err, tt.shouldError)
}
Expand Down Expand Up @@ -248,18 +248,18 @@ func TestCreateWorkflowFiles(t *testing.T) {

mockWF.populateConfigs()

err = mockWF.createWorkflowFiles("fakeDeployType", customInputs, templatewriter)
err = mockWF.CreateWorkflowFiles("fakeDeployType", customInputs, templatewriter)
assert.NotNil(t, err)

err = mockWF.createWorkflowFiles("helm", customInputs, templatewriter)
err = mockWF.CreateWorkflowFiles("helm", customInputs, templatewriter)
assert.Nil(t, err)
os.RemoveAll(".github")

err = mockWF.createWorkflowFiles("helm", customInputsNoRoot, templatewriter)
err = mockWF.CreateWorkflowFiles("helm", customInputsNoRoot, templatewriter)
assert.Nil(t, err)
os.RemoveAll(".github")

err = mockWF.createWorkflowFiles("helm", badInputs, templatewriter)
err = mockWF.CreateWorkflowFiles("helm", badInputs, templatewriter)
assert.NotNil(t, err)
os.RemoveAll(".github")
}
Expand Down

0 comments on commit e41dee6

Please sign in to comment.