Skip to content

Commit 01a882d

Browse files
authored
fix: do not fail on manifest-like yaml #21934 (#22043)
Signed-off-by: Moncef Abboud <[email protected]>
1 parent edf3683 commit 01a882d

4 files changed

Lines changed: 73 additions & 1 deletion

File tree

docs/user-guide/directory.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,28 @@ spec:
130130
exclude: '{config.json,env-usw2/*}'
131131
include: '*.yaml'
132132
```
133+
134+
### Skipping File Rendering
135+
136+
In some cases, repositories may contain YAML files that resemble Kubernetes manifests because they include fields like `apiVersion`, `kind`, and `metadata`, but are not intended to be rendered or applied as actual Kubernetes resources. Examples include Helm `values.yaml` files or configuration snippets used by CI/CD pipelines.
137+
138+
To prevent Argo CD from attempting to parse these files as manifests (which could result in errors), you can explicitly mark them to be skipped using a special comment directive:
139+
140+
```yaml
141+
# +argocd:skip-file-rendering
142+
```
143+
144+
When this comment is present anywhere in the file, Argo CD will ignore the file during manifest processing. This allows for safe coexistence of Kubernetes-like files that are not actual manifests.
145+
146+
#### Example
147+
148+
```yaml
149+
# +argocd:skip-file-rendering
150+
apiVersion: v1
151+
kind: ConfigMap
152+
metadata:
153+
name: example
154+
data:
155+
not-actually: a-manifest
156+
```
157+

reposerver/repository/repository.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const (
7171
repoSourceFile = ".argocd-source.yaml"
7272
appSourceFile = ".argocd-source-%s.yaml"
7373
ociPrefix = "oci://"
74+
skipFileRenderingMarker = "+argocd:skip-file-rendering"
7475
)
7576

7677
var ErrExceededMaxCombinedManifestFileSize = errors.New("exceeded max combined manifest file size")
@@ -1807,7 +1808,10 @@ func getObjsFromYAMLOrJSON(logCtx *log.Entry, manifestPath string, filename stri
18071808
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", filename, err)
18081809
}
18091810
// Read the whole file to check whether it looks like a manifest.
1810-
out, err := utfutil.ReadFile(manifestPath, utfutil.UTF8)
1811+
out, rerr := utfutil.ReadFile(manifestPath, utfutil.UTF8)
1812+
if rerr != nil {
1813+
return status.Errorf(codes.FailedPrecondition, "Failed to read %q: %v", filename, rerr)
1814+
}
18111815
// Otherwise, let's see if it looks like a resource, if yes, we return error
18121816
if bytes.Contains(out, []byte("apiVersion:")) &&
18131817
bytes.Contains(out, []byte("kind:")) &&
@@ -1906,6 +1910,15 @@ func getPotentiallyValidManifestFile(path string, f os.FileInfo, appPath, repoRo
19061910
return nil, "", nil
19071911
}
19081912

1913+
// Read the whole file to check whether it looks like a manifest.
1914+
out, rerr := utfutil.ReadFile(path, utfutil.UTF8)
1915+
if rerr != nil {
1916+
return nil, "", fmt.Errorf("failed to read %q: %w", relPath, rerr)
1917+
}
1918+
// skip file if it contains the skip-rendering marker
1919+
if bytes.Contains(out, []byte(skipFileRenderingMarker)) {
1920+
return nil, "", nil
1921+
}
19091922
return realFileInfo, "", nil
19101923
}
19111924

reposerver/repository/repository_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,17 @@ func TestInvalidManifestsInDir(t *testing.T) {
679679
require.Error(t, err)
680680
}
681681

682+
func TestSkippedInvalidManifestsInDir(t *testing.T) {
683+
service := newService(t, ".")
684+
685+
src := v1alpha1.ApplicationSource{Path: "./testdata/invalid-manifests-skipped", Directory: &v1alpha1.ApplicationSourceDirectory{Recurse: true}}
686+
687+
q := apiclient.ManifestRequest{Repo: &v1alpha1.Repository{}, ApplicationSource: &src}
688+
689+
_, err := service.GenerateManifest(t.Context(), &q)
690+
require.NoError(t, err)
691+
}
692+
682693
func TestInvalidMetadata(t *testing.T) {
683694
service := newService(t, ".")
684695

@@ -2815,6 +2826,13 @@ func Test_findManifests(t *testing.T) {
28152826
require.Error(t, err)
28162827
})
28172828

2829+
t.Run("invalid manifest containing '+argocd:skip-file-rendering' doesn't throw an error", func(t *testing.T) {
2830+
require.DirExists(t, "./testdata/invalid-manifests-skipped")
2831+
manifests, err := findManifests(logCtx, "./testdata/invalid-manifests-skipped", "./testdata/invalid-manifests-skipped", nil, noRecurse, nil, resource.MustParse("0"))
2832+
assert.Empty(t, manifests)
2833+
require.NoError(t, err)
2834+
})
2835+
28182836
t.Run("irrelevant YAML gets skipped, relevant YAML gets parsed", func(t *testing.T) {
28192837
manifests, err := findManifests(logCtx, "./testdata/irrelevant-yaml", "./testdata/irrelevant-yaml", nil, noRecurse, nil, resource.MustParse("0"))
28202838
assert.Len(t, manifests, 1)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# +argocd:skip-file-rendering
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ template "stuff.fullname" . }}-init
6+
labels:
7+
app: {{ template "stuff.name" . }}
8+
chart: {{ template "stuff.chart" . }}
9+
release: {{ .Release.Name }}
10+
heritage: {{ .Release.Service }}
11+
data:
12+
{{- $files := .Files }}
13+
{{- range tuple "init/init.sh" }}
14+
{{ . }}: |-
15+
{{ $files.Get . }}
16+
{{ end }}

0 commit comments

Comments
 (0)