Skip to content

fix(argocd): extract revision from multi-source application revisions[]#8810

Open
vemulaanvesh wants to merge 2 commits intoapache:mainfrom
vemulaanvesh:fix/argocd-multi-source-revision
Open

fix(argocd): extract revision from multi-source application revisions[]#8810
vemulaanvesh wants to merge 2 commits intoapache:mainfrom
vemulaanvesh:fix/argocd-multi-source-revision

Conversation

@vemulaanvesh
Copy link
Copy Markdown

@vemulaanvesh vemulaanvesh commented Mar 25, 2026

Summary

ArgoCD multi-source applications (those using spec.sources[] instead of spec.source) store one revision per source in a revisions[] array on both history entries and operationState. The existing extractor only read the single-source revision field, which is always empty for multi-source apps.

Impact: cicd_deployment_commits was never populated for multi-source apps, so ArgoCD deployments were invisible to DORA Deployment Frequency and Lead Time for Changes metrics.

Relates to: #5207

Root cause

// Multi-source history entry from ArgoCD API
{
  "id": 41,
  "deployedAt": "2026-03-19T18:07:59Z",
  "revision": "",          ← always empty for multi-source
  "revisions": [
    "2.6.2",               ← Helm chart version (GCS/OCI)
    "5dd95b4efd7e9b668c361bbddb8d7f1e56c32ac1"  ← git commit SHA (GitHub)
  ],
  "sources": [
    {"repoURL": "gs://charts-example/infra/stable", "chart": "generic-service"},
    {"repoURL": "https://github.com/example/my-repo"}
  ]
}

The extractor set syncOp.Revision = apiOp.Revision (empty string), causing convertSyncOperations to skip the cicd_deployment_commits write (if syncOp.Revision != "").

Changes

sync_operation_extractor.go

  • Add Revisions []string and Sources []ArgocdApiSyncSource to ArgocdApiSyncOperation struct.
  • Add Revisions []string to the SyncResult nested struct for operationState entries.
  • When revision is empty, call resolveMultiSourceRevision() before any skip logic.
  • resolveMultiSourceRevision() — picks the git commit SHA from revisions[]:
    • Pass 1: prefers the revision whose corresponding source URL belongs to a known git hosting service (GitHub, GitLab, Bitbucket, Azure DevOps, Gitea, Forgejo).
    • Pass 2: falls back to any 40-hex string regardless of source type (covers self-hosted instances).

application_extractor.go

  • Add Sources []ArgocdApiApplicationSource to ArgocdApiApplication.
  • When spec.source.repoURL is empty, resolve the primary source from spec.sources[] using the same git-host heuristic so ArgocdApplication.RepoURL is set to the browsable git repo URL rather than a Helm registry address.

Tests added (sync_operation_extractor_test.go)

Test Scenario
TestResolveMultiSourceRevision_GitHubSourceWins GCS chart + GitHub values repo → picks GitHub SHA
TestResolveMultiSourceRevision_GitLabSourceWins OCI chart + GitLab → picks GitLab SHA
TestResolveMultiSourceRevision_FallbackToAnySHA Gitea host in list → picked by heuristic
TestResolveMultiSourceRevision_EmptyRevisions nil / empty input → returns ""
TestResolveMultiSourceRevision_AllSemver all semver tags, no git SHA → returns ""
TestResolveMultiSourceRevision_SingleGitSHA single-element revisions slice
TestIsCommitSHA 40-hex validation edge cases
TestIsGitHostedURL git host detection, chart registries return false

Backward compatibility

  • Single-source apps are unaffected: revision is non-empty so resolveMultiSourceRevision is not called.
  • The new struct fields are purely additive JSON tags; existing serialised raw data without these fields deserialises to zero values without error.

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. pr-type/bug-fix This PR fixes a bug labels Mar 25, 2026
ArgoCD multi-source applications (spec.sources[]) store one revision per
source in a revisions[] array on history entries and operationState.
The existing extractor only read the single-source revision field, which
is always empty for multi-source apps, so cicd_deployment_commits was
never populated and ArgoCD deployments were invisible to DORA metrics.

Changes:
- sync_operation_extractor.go
  - Add Revisions []string and Sources []ArgocdApiSyncSource fields to
    ArgocdApiSyncOperation to deserialise multi-source payloads.
  - Add Revisions []string to SyncResult for operationState entries.
  - Call resolveMultiSourceRevision() when revision is empty, both for
    history entries and for operationState.
  - Add resolveMultiSourceRevision(): prefers the revision whose source URL
    belongs to a known git hosting service (GitHub, GitLab, Bitbucket, Azure
    DevOps, Gitea, Forgejo); falls back to any 40-hex commit SHA.
  - Add isGitHostedURL() and isCommitSHA() helpers.

- application_extractor.go
  - Add Sources []ArgocdApiApplicationSource to ArgocdApiApplication so
    multi-source app metadata is deserialised.
  - Resolve the primary git-hosted source from spec.sources[] when
    spec.source.repoURL is empty, ensuring ArgocdApplication.RepoURL is
    a browsable repository URL rather than a Helm chart registry address.

Fixes: multi-source ArgoCD apps produce 0 rows in cicd_deployment_commits
Relates-to: apache#5207
Made-with: Cursor
@vemulaanvesh vemulaanvesh force-pushed the fix/argocd-multi-source-revision branch from cfc0c3d to 80f81ac Compare March 27, 2026 15:22
…n-hosts list

gitea.internal.corp contains 'gitea.' which matches the known git host
heuristic, so the test was actually hitting Pass 1, not the fallback.
Replace with git.acme-corp.internal which has no known-host prefix,
no chart-registry prefix, and no .git suffix, so resolveMultiSourceRevision
genuinely falls through to the SHA-shape fallback (Pass 2).

Made-with: Cursor
@rbstp
Copy link
Copy Markdown
Contributor

rbstp commented Mar 28, 2026

lgtm

@vemulaanvesh
Copy link
Copy Markdown
Author

@rbstp can merge this ?

@rbstp
Copy link
Copy Markdown
Contributor

rbstp commented Mar 28, 2026

@rbstp can merge this ?

I am not sure if a maintainer wants to have a look first @klesh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-type/bug-fix This PR fixes a bug size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants