Go detection runs when one of the following files is found in the project:
go.modorgo.sum
- All go.mod are parsed to detect dependencies. This parsing doesn't depend on presence of
go cli.
- If a
go.sumfile is found, detector first checks if go version in the adjacentgo.mod≥1.17. If it is≥1.17, the file is skipped. If it is< 1.17, the detector proceeds as follows. Read Go Module Changes in Go 1.17 to understand why1.17is relevant. - If
go cliis found and not disabled,go listcommand is preferred over parsinggo.sumfile sincego.sumfiles contains history of dependencies and including these dependencies can lead to over-reporting. - If
go listwas not used or did not run successfully, detector falls back to parsinggo.summanually.
Full dependency graph generation is supported if Go v1.11+ is present on the build agent. To generate the graph, the command go mod graph is executed. This only adds edges between the components that were already registered.
The Go detector’s default behavior is optimized to reduce over-reporting by leveraging improvements introduced in Go 1.17.
- When a go.mod file declares a Go version ≥ 1.17, the detector analyzes only the go.mod file to determine dependencies.
- If the go.mod file specifies a Go version < 1.17, the detector uses a fallback strategy to ensure coverage. Read more about this in the Fallback Detection Strategy
The fallback detection strategy is used when the default strategy (based on go.mod files with Go 1.17 or later) cannot be applied.
In this mode, the detector uses Go CLI or manually parses go.sum to resolve dependencies. This strategy is known to overreport (see the known limitations). Read through the troubleshooting-section for tips on how to ensure that the newer, more accurate default detection strategy runs successfully.
To force the fallback detection strategy, set the environment variable: DisableGoCliScan=true
Go detection is performed by parsing any go.mod files, and either invoking the Go CLI or manually parsing go.sum files found under the scan directory.
Only root dependency information is generated in the fallback detection strategy. The full graph is not detected.
Go detection is performed by only scanning the go.mod files. This
reduces over reporting dependencies. The go.mod file contains all
dependencies, including transitive ones. 3
Similarly, no graph is generated.
The fallback detection strategy is known to overreport by nature of
parsing go.sum files which contain historical component information.
If you are experiencing overdetection from go.sum files or have
otherwise been made aware that you are using the fallback Go detection
strategy, search Component Detection output for the following to determine
what action is needed:
| CD output | Solution |
|---|---|
Go CLI was not found in the system |
Ensure that Go v1.17+ is installed |
#[error]Go CLI command "go list -m -json all" failed with error: |
Resolve go list errors |
Go cli scan was manually disabled, fallback strategy performed. |
Remove the DisableGoCliScan environment variable |
| Timeouts in Go detection | Fetch Go modules |
If you do not believe that Go is used in your project but Go detection is running, it is likely that you need to clean up extraneous build files.
Install Go CLI tools v1.17+ and ensure that it is available at the Component Detection step.
If Go CLI tools are installed in a prior build step but Component Detection is not finding them, ensure that they are not cleaned up or installed inside a container.
Errors are logged in the Component Detection build task output and begin with
#[error]Go CLI command "go list -m -json all" failed with error:. These errors
are typically caused by version resolution problems or incorrectly formatted go.mod
files.
The variable should not be set or should be set to false.
If modules are not fetched, go list will pull the modules and may
negatively impact performance at detection time.
If you are still experiencing timouts, the fallback strategy might be more appropriate for your project:
- Set
DisableGoCli=true. - Run
go mod tidyto clean yourgo.modandgo.sums to reduce overreporting. - Install Go v1.17+ to bypass go.sum scanning.
Go detection runs when a go.sum or go.mod file is encountered. If
you do not use Go in your project, search for the following in Component
Detection build output to find the paths to the Go files CD has detected.
Component Detection must be running in debug mode to see these logs:
##[debug]Found Go.mod: or
##[debug]Found Go.sum:
When you have found the affected files, you may:
- Delete the files if they exist but are not necessary in your project.
- Add a clean-up step to your build to remove the files if they are generated prior to the Component Detection build step but are not related to your project.
- Exclude the directory if it should not be scanned by Component Detection.
-
If the default strategy is used and go modules are not present in the system before the detector is executed, the go cli will fetch all modules to generate the dependency graph. This will incur additional detector time execution.
-
Dev dependency tagging is not supported.
-
Go detection will fallback if no Go v1.11+ is present.
-
(Prior to Go 1.17) Due to the nature of
go.sumcontaining references for all dependencies, including historical, no-longer-needed dependencies; the fallback strategy can result in over detection. Executing go mod tidy before detection via the fallback strategy is encouraged. -
Some legacy dependencies may report stale transitive dependencies in their manifests, in this case you can remove them safely from your binaries by using exclude directive.
If the environment variable DisableGoCliScan is set to true, the
Go detector forcibly executes the fallback strategy.
In the Go programming language, go.mod and go.sum files play a
vital role in managing dependencies and ensuring the reproducibility
and security of a Go project. These files are central to Go's module
system, introduced in Go version 1.11, which revolutionized how Go
manages external packages and dependencies.
The go.mod file, short for "module file," is a fundamental component
of Go's module system.4 It serves several crucial purposes:
-
Module Definition: The
go.modfile defines the module name, which uniquely identifies the project. The module name typically follows the format of a version control repository URL or a custom path, such asexample.com/myproject. -
Dependency Declaration: Inside the
go.modfile, you declare the specific versions of dependencies your project relies on. Dependencies are listed with their module paths and version constraints.go module example.com/myproject go 1.17 require ( github.com/somepackage v1.2.3 golang.org/x/someotherpackage v0.4.0 )Here,
github.com/somepackageandgolang.org/x/someotherpackageare declared as project dependencies with specific version constraints. -
Semantic Versioning: Go uses Semantic Versioning (Semver) to specify version constraints for dependencies. You can specify constraints such as
v1.2.3(exact version) or>=1.2.0, <2.0.0(range of versions). -
Dependency Resolution: When you build your project or import new dependencies, Go uses the
go.modfile to resolve and download the exact versions of dependencies that satisfy the specified constraints. -
Dependency Graph: The
go.modfile implicitly constructs a dependency graph of your project's dependencies, allowing Go to ensure that all dependencies are compatible and can be built together.
The go.sum file, short for "checksum file," is used for ensuring the
integrity and security of dependencies. It contains checksums
(cryptographic hashes) of specific versions of packages listed in the
go.mod file.5 The go.sum file serves the following purposes:
-
Cryptographic Verification: When Go downloads a package specified in the
go.modfile, it verifies the downloaded package's integrity by comparing its checksum with the checksum recorded in thego.sumfile. If they don't match, it signals a potential security breach or data corruption. -
Dependency Pinning: The
go.sumfile pins the exact versions of dependencies used in the project. It ensures that the same package versions are consistently used across different builds and development environments, which aids in reproducibility. -
Security: By including checksums, the
go.sumfile helps protect against tampering with packages during transit or in case of compromised repositories. It adds a layer of trust in the packages being used.
Here's a simplified example of entries in a go.sum file:
github.com/somepackage v1.2.3 h1:jh2u3r9z0wokljwesdczryhtnu1xf6wl4h7h2us9rj0=
github.com/anotherpackage v0.4.0 h1:rn2iw0z7liy6d87dwygfawxqvx86jxd4m8hkw6yaj88=
Each line contains the package path, version, and a cryptographic hash of the package contents.
-
Dependency Resolution: Dependency scanners use the information in
go.modto understand which packages and versions a Go project depends on. -
Security and Trust: The
go.sumfile ensures that dependencies are downloaded securely and have not been tampered with during transit. -
Build Reproducibility:
go.modandgo.sumfiles contribute to build reproducibility by pinning exact versions of dependencies, making it possible to recreate the same build environment consistently.
Prior to Go 1.17, the go.mod file primarily contained information
about direct dependencies, but it didn't include information about
transitive (indirect) dependencies. This made it challenging to
accurately detect and manage all dependencies in a project.
In Go 1.17 and later, Go introduced an important change: the go.mod
file now includes information about both direct and transitive
dependencies. This improvement enhances the clarity and completeness
of dependency information within the go.mod file.
The completeness of go.mod file in ≥1.17 allows the detector to skip go.sum files entirely.
-
Accuracy of Dependency Detection: Checking the Go version in the
go.modfile allows the Go Component Detector to determine whether the project is using the enhanced module system introduced in Go 1.17. If the Go version is 1.17 or higher, it indicates that thego.modfile contains information about transitive dependencies. Processing this updatedgo.modfile provides a more accurate and comprehensive view of the project's dependencies. -
Avoiding Over-Reporting: In projects using Go 1.17 and later, transitive dependencies are already listed in the
go.modfile, and processing the correspondinggo.sumfile could lead to over-reporting components. By not processing thego.sumfile when it's not necessary (i.e., when thego.modfile includes transitive dependencies), the detector avoids redundant or incorrect component detection. -
Minimizing Noise: Over-reporting components can result in unnecessary noise in the scan results.
The changes in the Go detector were validated by:
-
Unit tests: Sample
go.modandgo.sumfiles were created and placed as unit tests. Other unit tests for go version less than 1.17 were still maintained to ensure there were no regressions. -
Local testing: Real
go.modandgo.sumfrom the go CLI were created from a real test codebase and verified manually.
The main change for the go detector was not in the parsing of the
go.mod files, but rather simply filtering go.sum files if an
adjacent go.mod file specified a version higher than 1.17.