Skip to content

Commit

Permalink
feat(werft): add application version param support
Browse files Browse the repository at this point in the history
Implements werf#6390

The current implementation scope:

	* Add `applicationVersion` global param support to `werf.yml`
	* Add `applicationVersionFile` global param support to `werf.yml`
        * Plain/text, JSON, YAML files can be used as `applicationVersionFile` params
	* Giterminism is enforced for `applicationVersionFile` param
	* Gitemenis dev mode is supported for `applicationVersionFile` param
	* Handle corner case when both `applicationVersion` and `applicationVersionFile` params are set
	* `applicationVersion` value is available in nelm templates by using `$.Values.werf.applicationVersion` variable

`werf.yaml` file content:
```
project: demo-app
configVersion: 1
applicationVersion: v0.0.1

---
image: backend
dockerfile: backend.Dockerfile

---
image: frontend
dockerfile: frontend.Dockerfile

```

`werf.yaml` file content:
```
project: demo-app
configVersion: 1
applicationVersionFile: ./version.json

---
image: backend
dockerfile: backend.Dockerfile

---
image: frontend
dockerfile: frontend.Dockerfile

```
`./version.json` file content:
```
{
    "version": "v0.0.1"
}
```

`werf.yaml` file content:
```
project: demo-app
configVersion: 1
applicationVersionFile: ./version.yaml

---
image: backend
dockerfile: backend.Dockerfile

---
image: frontend
dockerfile: frontend.Dockerfile

```
`./version.yaml` file content:
```
version: v0.0.1
```

`werf.yaml` file content:
```
project: demo-app
configVersion: 1
applicationVersionFile: ./version

---
image: backend
dockerfile: backend.Dockerfile

---
image: frontend
dockerfile: frontend.Dockerfile

```
`./version` file content:
```
v0.0.1
```
  • Loading branch information
drey committed Nov 24, 2024
1 parent 720e3d3 commit d750249
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 32 deletions.
7 changes: 4 additions & 3 deletions cmd/werf/bundle/publish/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,10 @@ func runPublish(ctx context.Context, imageNameListFromArgs []string) error {
}

if vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepo, imagesInfoGetters, helpers.ServiceValuesOptions{
Env: *commonCmdData.Environment,
CommitHash: headHash,
CommitDate: headTime,
ApplicationVersion: werfConfig.Meta.ApplicationVersion,
Env: *commonCmdData.Environment,
CommitHash: headHash,
CommitDate: headTime,
}); err != nil {
return fmt.Errorf("error creating service values: %w", err)
} else {
Expand Down
18 changes: 10 additions & 8 deletions cmd/werf/converge/converge.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,16 @@ func run(
return fmt.Errorf("get HEAD commit time: %w", err)
}

if vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepo, imagesInfoGetters, helpers.ServiceValuesOptions{
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
SetDockerConfigJsonValue: *commonCmdData.SetDockerConfigJsonValue,
DockerConfigPath: filepath.Dir(registryCredentialsPath),
CommitHash: headHash,
CommitDate: headTime,
}); err != nil {
if vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepo, imagesInfoGetters,
helpers.ServiceValuesOptions{
ApplicationVersion: werfConfig.Meta.ApplicationVersion,
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
SetDockerConfigJsonValue: *commonCmdData.SetDockerConfigJsonValue,
DockerConfigPath: filepath.Dir(registryCredentialsPath),
CommitHash: headHash,
CommitDate: headTime,
}); err != nil {
return fmt.Errorf("get service values: %w", err)
} else {
wc.SetServiceValues(vals)
Expand Down
11 changes: 6 additions & 5 deletions cmd/werf/helm/get_autogenerated_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,12 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
}

vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepository, imagesInfoGetters, helpers.ServiceValuesOptions{
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
IsStub: isStub,
DisableEnvStub: true,
StubImageNameList: stubImageNameList, SetDockerConfigJsonValue: *commonCmdData.SetDockerConfigJsonValue,
ApplicationVersion: werfConfig.Meta.ApplicationVersion,
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
IsStub: isStub,
DisableEnvStub: true,
StubImageNameList: stubImageNameList, SetDockerConfigJsonValue: *commonCmdData.SetDockerConfigJsonValue,
DockerConfigPath: filepath.Dir(registryCredentialsPath),
CommitHash: headHash,
CommitDate: headTime,
Expand Down
1 change: 1 addition & 0 deletions cmd/werf/plan/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ func run(
}

if vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepository, imagesInfoGetters, helpers.ServiceValuesOptions{
ApplicationVersion: werfConfig.Meta.ApplicationVersion,
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
IsStub: isStub,
Expand Down
1 change: 1 addition & 0 deletions cmd/werf/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ func runRender(ctx context.Context, imageNameListFromArgs []string) error {
}

if vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepository, imagesInfoGetters, helpers.ServiceValuesOptions{
ApplicationVersion: werfConfig.Meta.ApplicationVersion,
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
IsStub: isStub,
Expand Down
14 changes: 8 additions & 6 deletions pkg/config/meta.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package config

type Meta struct {
ConfigVersion int
Project string
Deploy MetaDeploy
Cleanup MetaCleanup
GitWorktree MetaGitWorktree
Build MetaBuild
ApplicationVersion string
ApplicationVersionFile string
ConfigVersion int
Project string
Deploy MetaDeploy
Cleanup MetaCleanup
GitWorktree MetaGitWorktree
Build MetaBuild
}
78 changes: 78 additions & 0 deletions pkg/config/parser.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package config

import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -116,6 +118,15 @@ func GetWerfConfig(ctx context.Context, customWerfConfigRelPath, customWerfConfi
return "", nil, fmt.Errorf(format, defaultProjectName)
}

if meta.ApplicationVersionFile != "" {
applicationVersion, err := getApplicationVersionFromFile(meta.ApplicationVersionFile, giterminismManager)
if err != nil {
return "", nil, err
}

meta.ApplicationVersion = applicationVersion
}

werfConfig, err := prepareWerfConfig(giterminismManager, rawStapelImages, rawImagesFromDockerfile, meta)
if err != nil {
return "", nil, err
Expand All @@ -142,6 +153,65 @@ func GetDefaultProjectName(ctx context.Context, giterminismManager giterminism_m
return slug.Project(name), nil
}

func getApplicationVersionFromFile(path string, giterminismManager giterminism_manager.Interface) (string, error) {
absolutePath := util.GetAbsoluteFilepath(path)
if !util.IsSubpathOfBasePath(giterminismManager.LocalGitRepo().GetWorkTreeDir(), path) && !giterminismManager.Dev() {
return "", fmt.Errorf("application version file %q must be in the project git work tree %q", path, giterminismManager.LocalGitRepo().GetWorkTreeDir())
}

r, err := os.Open(absolutePath)
if err != nil {
return "", fmt.Errorf("cannot read applicationVersionFile %s: %w", absolutePath, err)
}
defer r.Close()

type versionFileType struct {
Version string `yaml:"version" json:"version"`
}

var applicationVersion string

switch filepath.Ext(absolutePath) {
case ".yaml", ".yml":
var data versionFileType

err = yaml.NewDecoder(r).Decode(&data)
if err != nil {
return "", fmt.Errorf("cannot read application version from applicationVersionFile %s: %w", absolutePath, err)
}

applicationVersion = data.Version
case ".json":
var data versionFileType

err = json.NewDecoder(r).Decode(&data)
if err != nil {
return "", fmt.Errorf("cannot read application version from applicationVersionFile %s: %w", absolutePath, err)
}

applicationVersion = data.Version
case "":
scanner := bufio.NewScanner(r)

if scanner.Scan() {
applicationVersion = scanner.Text()
}

err = scanner.Err()
if err != nil {
return "", fmt.Errorf("cannot read application version from applicationVersionFile %s", absolutePath)
}
default:
return "", fmt.Errorf("applicationVersionFile %s has unsupported file extension", absolutePath)
}

if len(applicationVersion) == 0 {
return "", fmt.Errorf("applicationVersionFile %s does not specify application version", absolutePath)
}

return applicationVersion, nil
}

func writeWerfConfigRender(werfConfigRenderContent, werfConfigRenderPath string) error {
werfConfigRenderFile, err := os.OpenFile(werfConfigRenderPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644)
if err != nil {
Expand Down Expand Up @@ -596,6 +666,14 @@ func isMetaDoc(h map[string]interface{}) bool {
return true
}

if _, ok := h["applicationVersion"]; ok {
return true
}

if _, ok := h["applicationVersionFile"]; ok {
return true
}

return false
}

Expand Down
26 changes: 20 additions & 6 deletions pkg/config/raw_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (
)

type rawMeta struct {
ConfigVersion *int `yaml:"configVersion,omitempty"`
Project *string `yaml:"project,omitempty"`
Build *rawMetaBuild `yaml:"build,omitempty"`
Deploy *rawMetaDeploy `yaml:"deploy,omitempty"`
Cleanup *rawMetaCleanup `yaml:"cleanup,omitempty"`
GitWorktree *rawMetaGitWorktree `yaml:"gitWorktree,omitempty"`
ApplicationVersion *string `yaml:"applicationVersion,omitempty"`
ApplicationVersionFile *string `yaml:"applicationVersionFile,omitempty"`
ConfigVersion *int `yaml:"configVersion,omitempty"`
Project *string `yaml:"project,omitempty"`
Build *rawMetaBuild `yaml:"build,omitempty"`
Deploy *rawMetaDeploy `yaml:"deploy,omitempty"`
Cleanup *rawMetaCleanup `yaml:"cleanup,omitempty"`
GitWorktree *rawMetaGitWorktree `yaml:"gitWorktree,omitempty"`

doc *doc `yaml:"-"` // parent

Expand Down Expand Up @@ -41,6 +43,10 @@ func (c *rawMeta) UnmarshalYAML(unmarshal func(interface{}) error) error {
return newDetailedConfigError("'project' field cannot be empty!", nil, c.doc)
}

if c.ApplicationVersion != nil && c.ApplicationVersionFile != nil {
return newDetailedConfigError("use either 'applicationVersion' or 'applicationVersionFile' config param", nil, c.doc)
}

if err := slug.ValidateProject(*c.Project); err != nil {
return newDetailedConfigError(fmt.Sprintf("bad project name %q specified in config: %s", *c.Project, err), nil, c.doc)
}
Expand All @@ -55,6 +61,14 @@ func (c *rawMeta) toMeta() *Meta {
meta.ConfigVersion = *c.ConfigVersion
}

if c.ApplicationVersion != nil {
meta.ApplicationVersion = *c.ApplicationVersion
}

if c.ApplicationVersionFile != nil {
meta.ApplicationVersionFile = *c.ApplicationVersionFile
}

if c.Project != nil {
werfProjectName := os.Getenv("WERF_PROJECT_NAME")
if werfProjectName != "" {
Expand Down
13 changes: 9 additions & 4 deletions pkg/deploy/helm/chart_extender/helpers/service_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ func (d *ChartExtenderServiceValuesData) SetServiceValues(vals map[string]interf
}

type ServiceValuesOptions struct {
Namespace string
Env string
IsStub bool
StubImageNameList []string
ApplicationVersion string
Namespace string
Env string
IsStub bool
StubImageNameList []string
// disable env stub used in the werf-render command
DisableEnvStub bool
CommitHash string
Expand Down Expand Up @@ -82,6 +83,10 @@ func GetServiceValues(ctx context.Context, projectName, repo string, imageInfoGe
},
}

if opts.ApplicationVersion != "" {
werfInfo["applicationVersion"] = opts.ApplicationVersion
}

if opts.Env != "" {
globalInfo["env"] = opts.Env
werfInfo["env"] = opts.Env
Expand Down

0 comments on commit d750249

Please sign in to comment.