Make release template to work on `needs` (#2099)
It turned out that Helmfile has never had support for release template on `needs`. This adds that, along with the new end-to-end test suite to verify helmfile template output with snapshot testing involving a real `helmfile build` command. Ref #2098
This commit is contained in:
		
							parent
							
								
									0105ed4df3
								
							
						
					
					
						commit
						dbc40f68b8
					
				|  | @ -73,6 +73,7 @@ jobs: | ||||||
|           - go-mod-cache-v1- |           - go-mod-cache-v1- | ||||||
|       - run: make check |       - run: make check | ||||||
|       - run: make pristine |       - run: make pristine | ||||||
|  |       - run: make -C .circleci helm | ||||||
|       - run: make test |       - run: make test | ||||||
| 
 | 
 | ||||||
|   # thanks to https://raw.githubusercontent.com/weaveworks/launcher/master/.circleci/config.yml |   # thanks to https://raw.githubusercontent.com/weaveworks/launcher/master/.circleci/config.yml | ||||||
|  |  | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
| dist/ | dist/ | ||||||
| .idea/ | .idea/ | ||||||
| helmfile | /helmfile | ||||||
| helmfile.lock | /helmfile.lock | ||||||
| /diff-yamls | /diff-yamls | ||||||
| /yamldiff | /yamldiff | ||||||
| test/integration/tmp | test/integration/tmp$ | ||||||
| vendor/ | vendor/ | ||||||
| *.log | *.log | ||||||
| .vagrant/ | .vagrant/ | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										1
									
								
								Makefile
								
								
								
								
							|  | @ -23,6 +23,7 @@ build-test-tools: | ||||||
| .PHONY: build-test-tools | .PHONY: build-test-tools | ||||||
| 
 | 
 | ||||||
| test: | test: | ||||||
|  | 	go build -o helmfile . | ||||||
| 	go test -v ${PKGS} -cover -race -p=1 | 	go test -v ${PKGS} -cover -race -p=1 | ||||||
| .PHONY: test | .PHONY: test | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										1
									
								
								go.mod
								
								
								
								
							|  | @ -25,6 +25,7 @@ require ( | ||||||
| 	github.com/pierrec/lz4 v2.3.0+incompatible // indirect | 	github.com/pierrec/lz4 v2.3.0+incompatible // indirect | ||||||
| 	github.com/r3labs/diff v1.1.0 | 	github.com/r3labs/diff v1.1.0 | ||||||
| 	github.com/spf13/cobra v1.1.1 | 	github.com/spf13/cobra v1.1.1 | ||||||
|  | 	github.com/stretchr/testify v1.7.0 // indirect | ||||||
| 	github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939 | 	github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939 | ||||||
| 	github.com/urfave/cli v1.22.5 | 	github.com/urfave/cli v1.22.5 | ||||||
| 	github.com/variantdev/chartify v0.9.1 | 	github.com/variantdev/chartify v0.9.1 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							|  | @ -655,6 +655,8 @@ github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 | ||||||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||||
| github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | ||||||
| github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
|  | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||||||
|  | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
| github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= | ||||||
| github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939 h1:BhIUXV2ySTLrKgh/Hnts+QTQlIbWtomXt3LMdzME0A0= | github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939 h1:BhIUXV2ySTLrKgh/Hnts+QTQlIbWtomXt3LMdzME0A0= | ||||||
| github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939/go.mod h1:omGxs4/6hNjxPKUTjmaNkPzehSnNJOJN6pMEbrlYIT4= | github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939/go.mod h1:omGxs4/6hNjxPKUTjmaNkPzehSnNJOJN6pMEbrlYIT4= | ||||||
|  |  | ||||||
|  | @ -188,6 +188,14 @@ func (r ReleaseSpec) ExecuteTemplateExpressions(renderer *tmpl.FileRenderer) (*R | ||||||
| 		result.SetValues = append(newvals, result.SetValues...) | 		result.SetValues = append(newvals, result.SetValues...) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	for i, n := range result.Needs { | ||||||
|  | 		s, err := renderer.RenderTemplateContentToBuffer([]byte(n)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("failed executing template expressions in release \"%s\".needs[%d] = \"%s\": %v", r.Name, i, n, err) | ||||||
|  | 		} | ||||||
|  | 		result.Needs[i] = s.String() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return result, nil | 	return result, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,50 @@ | ||||||
|  | package helmfile | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"os" | ||||||
|  | 	"os/exec" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"runtime" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestHelmfileTemplateWithBuildCommand(t *testing.T) { | ||||||
|  | 	_, filename, _, _ := runtime.Caller(0) | ||||||
|  | 	projectRoot := filepath.Join(filepath.Dir(filename), "..", "..", "..", "..") | ||||||
|  | 	helmfileBin := filepath.Join(projectRoot, "helmfile") | ||||||
|  | 	testdataDir := "testdata" | ||||||
|  | 
 | ||||||
|  | 	entries, err := os.ReadDir(testdataDir) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	for _, e := range entries { | ||||||
|  | 		if !e.IsDir() { | ||||||
|  | 			t.Fatalf("Unexpected type of entry at %s", e.Name()) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		name := e.Name() | ||||||
|  | 
 | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			inputFile := filepath.Join(testdataDir, name, "input.yaml") | ||||||
|  | 
 | ||||||
|  | 			want, err := os.ReadFile(filepath.Join(testdataDir, name, "output.yaml")) | ||||||
|  | 			require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||||||
|  | 			defer cancel() | ||||||
|  | 
 | ||||||
|  | 			cmd := exec.CommandContext(ctx, helmfileBin, "-f", inputFile, "build") | ||||||
|  | 			got, err := cmd.CombinedOutput() | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Logf("%s", string(got)) | ||||||
|  | 			} | ||||||
|  | 			require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 			require.Equal(t, string(want), string(got)) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								test/e2e/template/helmfile/testdata/issue_2098_release_template_needs/input.yaml
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										27
									
								
								test/e2e/template/helmfile/testdata/issue_2098_release_template_needs/input.yaml
								
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,27 @@ | ||||||
|  | repositories: | ||||||
|  |   - name: aservo | ||||||
|  |     url: https://aservo.github.io/charts | ||||||
|  | 
 | ||||||
|  | environments: | ||||||
|  |   default: | ||||||
|  | 
 | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | templates: | ||||||
|  |   defaults: &defaults | ||||||
|  |     name: "{{ .Environment.Name }}-{{`{{ .Release.Labels.service }}`}}" | ||||||
|  |     namespace: "{{ .Environment.Name }}" | ||||||
|  | 
 | ||||||
|  | releases: | ||||||
|  |   - chart: aservo/util | ||||||
|  |     version: 0.0.1 | ||||||
|  |     labels: | ||||||
|  |       service: shared-resources | ||||||
|  |     <<: *defaults | ||||||
|  |   - chart: aservo/util | ||||||
|  |     version: 0.0.1 | ||||||
|  |     labels: | ||||||
|  |       service: release-resources | ||||||
|  |     <<: *defaults | ||||||
|  |     needs: | ||||||
|  |       - "{{`{{ .Release.Namespace }}`}}-shared-resources" | ||||||
							
								
								
									
										30
									
								
								test/e2e/template/helmfile/testdata/issue_2098_release_template_needs/output.yaml
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										30
									
								
								test/e2e/template/helmfile/testdata/issue_2098_release_template_needs/output.yaml
								
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | --- | ||||||
|  | #  Source: input.yaml | ||||||
|  | 
 | ||||||
|  | filepath: input.yaml | ||||||
|  | helmBinary: helm | ||||||
|  | environments: | ||||||
|  |   default: {} | ||||||
|  | repositories: | ||||||
|  | - name: aservo | ||||||
|  |   url: https://aservo.github.io/charts | ||||||
|  | releases: | ||||||
|  | - chart: aservo/util | ||||||
|  |   version: 0.0.1 | ||||||
|  |   name: default-shared-resources | ||||||
|  |   namespace: default | ||||||
|  |   labels: | ||||||
|  |     service: shared-resources | ||||||
|  | - chart: aservo/util | ||||||
|  |   version: 0.0.1 | ||||||
|  |   needs: | ||||||
|  |   - default-shared-resources | ||||||
|  |   name: default-release-resources | ||||||
|  |   namespace: default | ||||||
|  |   labels: | ||||||
|  |     service: release-resources | ||||||
|  | templates: | ||||||
|  |   defaults: | ||||||
|  |     name: default-{{ .Release.Labels.service }} | ||||||
|  |     namespace: default | ||||||
|  | renderedvalues: {} | ||||||
		Loading…
	
		Reference in New Issue