Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions civisibility/constants/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
package constants

const (
// CIJobID indicates the id of the CI job.
CIJobID = "ci.job.id"

// CIJobName indicates the name of the CI job.
CIJobName = "ci.job.name"

Expand Down
6 changes: 6 additions & 0 deletions civisibility/constants/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,10 @@ const (

// CIVisibilityInternalParallelEarlyFlakeDetectionEnabled indicates if the internal parallel early flake detection feature is enabled.
CIVisibilityInternalParallelEarlyFlakeDetectionEnabled = "DD_CIVISIBILITY_INTERNAL_PARALLEL_EARLY_FLAKE_DETECTION_ENABLED"

// CIVisibilitySubtestFeaturesEnabled indicates if subtest-specific management and retry features are enabled.
CIVisibilitySubtestFeaturesEnabled = "DD_CIVISIBILITY_SUBTEST_FEATURES_ENABLED"

// CIVisibilityUseNoopTracer indicates if the ci visibility mode must set a noop tracer (avoid change current test behaviors over the noop tracer implementation)
CIVisibilityUseNoopTracer = "DD_CIVISIBILITY_USE_NOOP_TRACER"
)
29 changes: 28 additions & 1 deletion civisibility/constants/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,38 @@ const (
GitTag = "git.tag"

// GitHeadCommit indicates the GIT head commit hash.
GitHeadCommit = "git.commit.head_sha"
GitHeadCommit = "git.commit.head.sha"

// GitHeadMessage indicates the GIT head commit message.
GitHeadMessage = "git.commit.head.message"

// GitHeadAuthorDate indicates the GIT head commit author date.
GitHeadAuthorDate = "git.commit.head.author.date"

// GitHeadAuthorEmail indicates the GIT head commit author email.
GitHeadAuthorEmail = "git.commit.head.author.email"

// GitHeadAuthorName indicates the GIT head commit author name.
GitHeadAuthorName = "git.commit.head.author.name"

// GitHeadCommitterDate indicates the GIT head commit committer date.
GitHeadCommitterDate = "git.commit.head.committer.date"

// GitHeadCommitterEmail indicates the GIT head commit committer email.
GitHeadCommitterEmail = "git.commit.head.committer.email"

// GitHeadCommitterName indicates the GIT head commit committer name.
GitHeadCommitterName = "git.commit.head.committer.name"

// GitPrBaseCommit indicates the GIT PR base commit hash.
GitPrBaseCommit = "git.pull_request.base_branch_sha"

// GitPrBaseHeadCommit indicates the GIT PR base branch head commit hash.
GitPrBaseHeadCommit = "git.pull_request.base_branch_head_sha"

// GitPrBaseBranch indicates the GIT PR base branch name.
GitPrBaseBranch = "git.pull_request.base_branch"

// PrNumber indicates the pull request number.
PrNumber = "pr.number"
)
74 changes: 54 additions & 20 deletions civisibility/integrations/civisibility_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os"
"slices"
"sync"
"time"

"github.com/DataDog/ddtest/civisibility"
"github.com/DataDog/ddtest/civisibility/constants"
Expand Down Expand Up @@ -83,45 +84,56 @@ func ensureSettingsInitialization(serviceName string) {
// upload the repository changes
var uploadChannel = make(chan struct{})
go func() {
defer func() {
close(uploadChannel)
}()
bytes, err := uploadRepositoryChanges()
if err != nil {
slog.Error("civisibility: error uploading repository changes:", "error", err.Error())
} else {
slog.Debug("civisibility: uploaded bytes in pack files", "count", bytes)
}
uploadChannel <- struct{}{}
}()

//Wait for the upload with timeout func
waitUpload := func(timeout time.Duration) bool {
select {
case <-uploadChannel:
// All ok, upload succeeded
return true
case <-time.After(timeout):
slog.Warn("civisibility: timeout waiting for upload repository changes")
return false
}
}
// returns a closure suitable for PushCiVisibilityCloseAction that will wait
// for the upload to complete (or time out) using the given timeout.
waitUploadFactory := func(timeout time.Duration) func() {
return func() { waitUpload(timeout) }
}

// Get the CI Visibility settings payload for this test session
ciSettings, err := ciVisibilityClient.GetSettings()
if err != nil || ciSettings == nil {
slog.Error("civisibility: error getting CI visibility settings", "error", err.Error())
slog.Debug("civisibility: no need to wait for the git upload to finish")
// Enqueue a close action to wait for the upload to finish before finishing the process
PushCiVisibilityCloseAction(func() {
<-uploadChannel
})
PushCiVisibilityCloseAction(waitUploadFactory(time.Minute))
return
}

// check if we need to wait for the upload to finish and repeat the settings request or we can just continue
if ciSettings.RequireGit {
slog.Debug("civisibility: waiting for the git upload to finish and repeating the settings request")
<-uploadChannel
if !waitUpload(1 * time.Minute) {
slog.Error("civisibility: error getting CI visibility settings due to timeout")
return
}
ciSettings, err = ciVisibilityClient.GetSettings()
if err != nil {
slog.Error("civisibility: error getting CI visibility settings", "error", err.Error())
return
}
} else if ciSettings.ImpactedTestsEnabled {
slog.Debug("civisibility: impacted tests is enabled we need to wait for the upload to finish (for the unshallow process)")
<-uploadChannel
} else {
slog.Debug("civisibility: no need to wait for the git upload to finish")
// Enqueue a close action to wait for the upload to finish before finishing the process
PushCiVisibilityCloseAction(func() {
<-uploadChannel
})
}

// check if we need to disable EFD because known tests is not enabled
Expand All @@ -138,6 +150,12 @@ func ensureSettingsInitialization(serviceName string) {
ciSettings.FlakyTestRetriesEnabled = false
}

// check if impacted tests is disabled by env-vars
if ciSettings.ImpactedTestsEnabled && !civisibility.BoolEnv(constants.CIVisibilityImpactedTestsDetectionEnabled, true) {
slog.Warn("civisibility: impacted tests was disabled by the environment variable")
ciSettings.ImpactedTestsEnabled = false
}

// check if test management is disabled by env-vars
if ciSettings.TestManagement.Enabled && !civisibility.BoolEnv(constants.CIVisibilityTestManagementEnabledEnvironmentVariable, true) {
slog.Warn("civisibility: test management was disabled by the environment variable")
Expand All @@ -150,6 +168,23 @@ func ensureSettingsInitialization(serviceName string) {
ciSettings.TestManagement.AttemptToFixRetries = testManagementAttemptToFixRetriesEnv
}

// determine if subtest-specific features are enabled via environment variables
subtestFeaturesEnabled := civisibility.BoolEnv(constants.CIVisibilitySubtestFeaturesEnabled, true)
if !subtestFeaturesEnabled {
slog.Debug("civisibility: subtest test management features disabled by environment variable")
}
ciSettings.SubtestFeaturesEnabled = subtestFeaturesEnabled

// check if we need to wait for the upload to finish before continuing
if ciSettings.ImpactedTestsEnabled {
slog.Debug("civisibility: impacted tests is enabled we need to wait for the upload to finish (for the unshallow process)")
waitUpload(30 * time.Second)
} else {
slog.Debug("civisibility: no need to wait for the git upload to finish")
// Enqueue a close action to wait for the upload to finish before finishing the process
PushCiVisibilityCloseAction(waitUploadFactory(time.Minute))
}

// set the ciVisibilitySettings with the settings from the backend
ciVisibilitySettings = *ciSettings
})
Expand Down Expand Up @@ -184,7 +219,7 @@ func ensureAdditionalFeaturesInitialization(_ string) {
additionalTags[constants.LibraryCapabilitiesTestImpactAnalysis] = "1"
additionalTags[constants.LibraryCapabilitiesTestManagementQuarantine] = "1"
additionalTags[constants.LibraryCapabilitiesTestManagementDisable] = "1"
additionalTags[constants.LibraryCapabilitiesTestManagementAttemptToFix] = "2"
additionalTags[constants.LibraryCapabilitiesTestManagementAttemptToFix] = "5"

// mutex to protect the additional tags map
var aTagsMutex sync.Mutex
Expand Down Expand Up @@ -258,8 +293,7 @@ func ensureAdditionalFeaturesInitialization(_ string) {
}

// if wheter the settings response or the env var is true we load the impacted tests analyzer
if currentSettings.ImpactedTestsEnabled ||
civisibility.BoolEnv(constants.CIVisibilityImpactedTestsDetectionEnabled, false) {
if currentSettings.ImpactedTestsEnabled {
wg.Add(1)
go func() {
defer wg.Done()
Expand Down Expand Up @@ -324,7 +358,7 @@ func uploadRepositoryChanges() (bytes int64, err error) {
// get the search commits response
initialCommitData, err := getSearchCommits()
if err != nil {
return 0, fmt.Errorf("civisibility: error getting the search commits response: %s", err.Error())
return 0, fmt.Errorf("civisibility: error getting the search commits response: %s", err)
}

// let's check if we could retrieve commit data
Expand Down Expand Up @@ -363,11 +397,11 @@ func uploadRepositoryChanges() (bytes int64, err error) {
// after unshallowing the repository we need to get the search commits to calculate the missing commits again
commitsData, err := getSearchCommits()
if err != nil {
return 0, fmt.Errorf("civisibility: error getting the search commits response: %s", err.Error())
return 0, fmt.Errorf("civisibility: error getting the search commits response: %s", err)
}

// let's check if we could retrieve commit data
if !initialCommitData.IsOk {
if !commitsData.IsOk {
return 0, nil
}

Expand Down
Loading
Loading