diff --git a/docs/content/en/docs/references/yaml/main.js b/docs/content/en/docs/references/yaml/main.js
index 6f850275472..fc9e106659e 100644
--- a/docs/content/en/docs/references/yaml/main.js
+++ b/docs/content/en/docs/references/yaml/main.js
@@ -193,9 +193,14 @@ function* template(definitions, parentDefinition, ref, ident, parent) {
// This definition is an array
if (definition.items && definition.items.$ref) {
- yield html`
- ${template(definitions, definition, definition.items.$ref, ident + 1, path)}
- `;
+ // don't infinitely recurse into nested tagger components
+ if (definition.items.$ref === "#/definitions/TaggerComponent") {
+ yield html ``;
+ } else {
+ yield html`
+ ${template(definitions, definition, definition.items.$ref, ident + 1, path)}
+ `;
+ }
}
}
}
diff --git a/docs/content/en/schemas/v2beta6.json b/docs/content/en/schemas/v2beta6.json
index 74046c58b32..32438e34588 100755
--- a/docs/content/en/schemas/v2beta6.json
+++ b/docs/content/en/schemas/v2beta6.json
@@ -2117,6 +2117,45 @@
"description": "specifies which local files to sync to remote folders.",
"x-intellij-html-description": "specifies which local files to sync to remote folders."
},
+ "TagPolicy": {
+ "properties": {
+ "customTemplate": {
+ "$ref": "#/definitions/CustomTemplateTagger",
+ "description": "*beta* tags images with a configurable template string *composed of other taggers*.",
+ "x-intellij-html-description": "beta tags images with a configurable template string composed of other taggers."
+ },
+ "dateTime": {
+ "$ref": "#/definitions/DateTimeTagger",
+ "description": "*beta* tags images with the build timestamp.",
+ "x-intellij-html-description": "beta tags images with the build timestamp."
+ },
+ "envTemplate": {
+ "$ref": "#/definitions/EnvTemplateTagger",
+ "description": "*beta* tags images with a configurable template string.",
+ "x-intellij-html-description": "beta tags images with a configurable template string."
+ },
+ "gitCommit": {
+ "$ref": "#/definitions/GitTagger",
+ "description": "*beta* tags images with the git tag or commit of the artifact's workspace.",
+ "x-intellij-html-description": "beta tags images with the git tag or commit of the artifact's workspace."
+ },
+ "sha256": {
+ "$ref": "#/definitions/ShaTagger",
+ "description": "*beta* tags images with their sha256 digest.",
+ "x-intellij-html-description": "beta tags images with their sha256 digest."
+ }
+ },
+ "preferredOrder": [
+ "gitCommit",
+ "sha256",
+ "envTemplate",
+ "dateTime",
+ "customTemplate"
+ ],
+ "additionalProperties": false,
+ "description": "contains all the configuration for the tagging step.",
+ "x-intellij-html-description": "contains all the configuration for the tagging step."
+ },
"TaggerComponent": {
"anyOf": [
{
diff --git a/hack/schemas/main.go b/hack/schemas/main.go
index ecefc3a9948..3e02cb64a86 100644
--- a/hack/schemas/main.go
+++ b/hack/schemas/main.go
@@ -77,8 +77,9 @@ type Definition struct {
Examples []string `json:"examples,omitempty"`
Enum []string `json:"enum,omitempty"`
- inlines []*Definition
- tags string
+ inlines []*Definition
+ tags string
+ skipTrim bool
}
func main() {
@@ -238,7 +239,8 @@ func (g *schemaGenerator) newDefinition(name string, t ast.Expr, comment string,
if strings.Contains(field.Tag.Value, "inline") {
def.PreferredOrder = append(def.PreferredOrder, "")
def.inlines = append(def.inlines, &Definition{
- Ref: defPrefix + field.Type.(*ast.Ident).Name,
+ Ref: defPrefix + field.Type.(*ast.Ident).Name,
+ skipTrim: strings.Contains(field.Tag.Value, "skipTrim"),
})
continue
}
@@ -354,6 +356,9 @@ func (g *schemaGenerator) Apply(inputPath string) ([]byte, error) {
}
for _, inlineStruct := range def.inlines {
+ if inlineStruct.skipTrim {
+ continue
+ }
ref := strings.TrimPrefix(inlineStruct.Ref, defPrefix)
inlines = append(inlines, ref)
}
@@ -435,7 +440,13 @@ func (g *schemaGenerator) Apply(inputPath string) ([]byte, error) {
}
for _, ref := range inlines {
- delete(definitions, ref)
+ existingDef, ok := definitions[ref]
+ if !ok {
+ continue
+ }
+ if !existingDef.skipTrim {
+ delete(definitions, ref)
+ }
}
schema := Schema{
diff --git a/pkg/skaffold/schema/latest/config.go b/pkg/skaffold/schema/latest/config.go
index 9ead532f4dd..d5cc062d6a1 100644
--- a/pkg/skaffold/schema/latest/config.go
+++ b/pkg/skaffold/schema/latest/config.go
@@ -191,7 +191,7 @@ type TaggerComponent struct {
Name string `yaml:"name,omitempty"`
// Component is a tagging strategy to be used in CustomTemplateTagger.
- Component TagPolicy `yaml:",inline"`
+ Component TagPolicy `yaml:",inline" yamltags:"skipTrim"`
}
// BuildType contains the specific implementation and parameters needed
diff --git a/pkg/skaffold/yamltags/tags.go b/pkg/skaffold/yamltags/tags.go
index b3c4c7cbbaf..35a4869d2b9 100644
--- a/pkg/skaffold/yamltags/tags.go
+++ b/pkg/skaffold/yamltags/tags.go
@@ -72,6 +72,10 @@ func processTags(yamltags string, val reflect.Value, parentStruct reflect.Value,
Field: field,
Parent: parentStruct,
}
+ case "skipTrim":
+ yt = &skipTrimTag{
+ Field: field,
+ }
default:
logrus.Panicf("unknown yaml tag in %s", yamltags)
}
@@ -166,6 +170,24 @@ func (oot *oneOfTag) Process(val reflect.Value) error {
return nil
}
+type skipTrimTag struct {
+ Field reflect.StructField
+}
+
+func (tag *skipTrimTag) Load(s []string) error {
+ return nil
+}
+
+func (tag *skipTrimTag) Process(val reflect.Value) error {
+ if isZeroValue(val) {
+ if tags, ok := tag.Field.Tag.Lookup("yaml"); ok {
+ return fmt.Errorf("skipTrim value not set: %s", strings.Split(tags, ",")[0])
+ }
+ return fmt.Errorf("skipTrim value not set: %s", tag.Field.Name)
+ }
+ return nil
+}
+
func isZeroValue(val reflect.Value) bool {
if val.Kind() == reflect.Invalid {
return true