Skip to content

Commit 022f935

Browse files
k4r1chzar
andauthored
feat: Add basic support for git tag path prefixes (#27290)
Signed-off-by: Karl Taylor <16408267+k4r1@users.noreply.github.com> Co-authored-by: Cameron Harrell <cameron.harrell@laerdal.com>
1 parent d6b2be8 commit 022f935

31 files changed

Lines changed: 2637 additions & 853 deletions

assets/swagger.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/util/app.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type AppOptions struct {
3434
chart string
3535
env string
3636
revision string
37+
tagPrefix string
3738
revisionHistoryLimit int
3839
destName string
3940
destServer string
@@ -107,6 +108,7 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) {
107108
command.Flags().StringVar(&opts.chart, "helm-chart", "", "Helm Chart name")
108109
command.Flags().StringVar(&opts.env, "env", "", "Application environment to monitor")
109110
command.Flags().StringVar(&opts.revision, "revision", "", "The tracking source branch, tag, commit or Helm chart version the application will sync to")
111+
command.Flags().StringVar(&opts.tagPrefix, "tag-prefix", "", "Filter git tags by this prefix before evaluating targetRevision as a semver constraint")
110112
command.Flags().StringVar(&opts.drySourceRepo, "dry-source-repo", "", "Repository URL of the app dry source")
111113
command.Flags().StringVar(&opts.drySourceRevision, "dry-source-revision", "", "Revision of the app dry source")
112114
command.Flags().StringVar(&opts.drySourcePath, "dry-source-path", "", "Path in repository to the app directory for the dry source")
@@ -686,6 +688,8 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl
686688
source.Chart = appOpts.chart
687689
case "revision":
688690
source.TargetRevision = appOpts.revision
691+
case "tag-prefix":
692+
source.TagPrefix = appOpts.tagPrefix
689693
case "values":
690694
setHelmOpt(source, helmOpts{valueFiles: appOpts.valuesFiles})
691695
case "ignore-missing-value-files":

docs/user-guide/commands/argocd_admin_app_generate-spec.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/user-guide/commands/argocd_app_add-source.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/user-guide/commands/argocd_app_create.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/user-guide/commands/argocd_app_set.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/user-guide/tracking_strategies.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,49 @@ comparison/sync.
6262
But if you're using semantic versioning you can set the constraint in your service revision
6363
and Argo CD will get the latest version following the constraint rules.
6464

65+
> [!NOTE]
66+
> Semver constraints (those containing `*`, `>`, `<`, `>=`, `<=`, `~`, `^`, or range expressions like `>=1.0.0 <2.0.0`) are **only matched against tags**, never branches. This is by design - semver resolution uses the list of Git tags exclusively.
67+
68+
#### Prefixed Tags
69+
70+
Argo CD supports hierarchical tag prefixes, allowing you to organize tags by application, environment, cluster, or any other criteria. This is particularly useful for:
71+
72+
- **Monorepos** - Tag each application separately (e.g., `app1/v1.0.0`, `app2/v2.0.0`)
73+
- **Multi-cluster deployments** - Organize by application, cluster, and environment for use with ApplicationSet generators
74+
75+
Set `tagPrefix` to the prefix string. Argo CD will filter tags to only those with that prefix, strip the prefix before evaluating `targetRevision` as a semver constraint, and re-add it to the resolved version.
76+
77+
| Tags in repo | `tagPrefix` | `targetRevision` | Resolves to |
78+
|-|-|-|-|
79+
| `app1/v1.0.0`, `app1/v1.0.1` | `app1/` | `v1.0.*` | `app1/v1.0.1` |
80+
| `app2/v1.0.0`, `app2/v2.0.0` | `app2/` | `v1.*` | `app2/v1.0.0` |
81+
| `app1/cluster1/prod/v1.0.0` | `app1/cluster1/prod/` | `v1.*` | `app1/cluster1/prod/v1.0.0` |
82+
83+
**Examples:**
84+
85+
```yaml
86+
# Monorepo: Track patch releases for a specific application
87+
spec:
88+
source:
89+
targetRevision: v1.0.*
90+
tagPrefix: app1/
91+
92+
# Multi-cluster: Track versions for a specific app/cluster/environment
93+
spec:
94+
source:
95+
targetRevision: v1.*
96+
tagPrefix: app1/cluster1/prod/
97+
98+
# ApplicationSet generator example - use template variables in the prefix
99+
spec:
100+
source:
101+
targetRevision: v1.*
102+
tagPrefix: "{{.app}}/{{.cluster}}/{{.env}}/"
103+
```
104+
105+
> [!NOTE]
106+
> For prerelease versions, use the `-0` suffix: `tagPrefix: app1/` with `targetRevision: ">=v1.0.0-0"` will match prerelease tags like `app1/v1.0.0-rc.1`.
107+
65108
### Commit Pinning
66109

67110
If a Git commit SHA is specified, the app is effectively pinned to the manifests defined at

0 commit comments

Comments
 (0)