vemulaanvesh opened a new pull request, #8810: URL: https://github.com/apache/incubator-devlake/pull/8810
## Summary ArgoCD [multi-source applications](https://argo-cd.readthedocs.io/en/stable/user-guide/multiple_sources/) (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 ```json // 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. Made with [Cursor](https://cursor.com) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
