diff --git a/go/extractor/cli/go-autobuilder/go-autobuilder.go b/go/extractor/cli/go-autobuilder/go-autobuilder.go index 756bd19b45e9..2531f72cf341 100644 --- a/go/extractor/cli/go-autobuilder/go-autobuilder.go +++ b/go/extractor/cli/go-autobuilder/go-autobuilder.go @@ -565,7 +565,7 @@ func installDependenciesAndBuild() { // Go tooling should install required Go versions as needed. if toolchain.GetEnvGoSemVer().IsOlderThan(toolchain.V1_21) && greatestGoVersion != nil && greatestGoVersion.IsNewerThan(toolchain.GetEnvGoSemVer()) { diagnostics.EmitNewerGoVersionNeeded(toolchain.GetEnvGoSemVer().String(), greatestGoVersion.String()) - if val, _ := os.LookupEnv("GITHUB_ACTIONS"); val == "true" { + if util.IsActionsWorkflow() { log.Printf( "A go.mod file requires version %s of Go, but version %s is installed. Consider adding an actions/setup-go step to your workflow.\n", greatestGoVersion, diff --git a/go/extractor/diagnostics/BUILD.bazel b/go/extractor/diagnostics/BUILD.bazel index 9b0c148db320..436cf15e8549 100644 --- a/go/extractor/diagnostics/BUILD.bazel +++ b/go/extractor/diagnostics/BUILD.bazel @@ -7,4 +7,5 @@ go_library( srcs = ["diagnostics.go"], importpath = "github.com/github/codeql-go/extractor/diagnostics", visibility = ["//visibility:public"], + deps = ["//go/extractor/util"], ) diff --git a/go/extractor/diagnostics/diagnostics.go b/go/extractor/diagnostics/diagnostics.go index 00179b98cca5..4a49347f0f76 100644 --- a/go/extractor/diagnostics/diagnostics.go +++ b/go/extractor/diagnostics/diagnostics.go @@ -7,6 +7,8 @@ import ( "os" "strings" "time" + + "github.com/github/codeql-go/extractor/util" ) type sourceStruct struct { @@ -154,14 +156,42 @@ func EmitCannotFindPackages(pkgPaths []string) { secondLine += fmt.Sprintf(" and %d more", numPkgPaths-maxNumPkgPaths) } + message := fmt.Sprintf( + "%d package%s could not be found:\n\n%s.\n\n"+ + "CodeQL is able to analyze your code without those packages, but definitions from them may not be recognized and "+ + "source files that use them may only be partially analyzed.\n\n"+ + "To ensure that you have comprehensive alert coverage, check that the paths are correct and make sure any private packages can be accessed by CodeQL. ", + numPkgPaths, + plural(len(pkgPaths), "", "s"), + secondLine, + ) + + // Depending on the environment we are running in, provide a different message for how to configure access to private registries. + if util.IsDynamicActionsWorkflow() { + // For GitHub-managed (dynamic) workflows, we offer built-in support for private registries that customers can set up. + message = message + + "Organizations [can grant access to private registries for GitHub security products](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). " + } else { + if util.IsActionsWorkflow() { + // For custom workflows, users can add a workflow step to set up credentials or environment variables. + message = message + + "To set up access to a private registry, add a step to your workflow which sets up the necessary credentials and environment variables. " + } else { + // Otherwise, we are running locally or in some other CI system. + message = message + + "To set up access to private registries, ensure that the necessary credentials and environment variables are set up for `go` to use. " + } + + // This should be less likely since we improved Go project discovery. We only include it in the message if we are not running in a + // GitHub-managed workflow, since users would not be able to act on this there. + message = message + + "If any of the packages are already present in the repository, but were not found, then you may need a [custom build command](https://docs.github.com/en/code-security/how-tos/scan-code-for-vulnerabilities/manage-your-configuration/codeql-code-scanning-for-compiled-languages)." + } + emitDiagnostic( "go/autobuilder/package-not-found", "Some packages could not be found", - fmt.Sprintf( - "%d package%s could not be found:\n\n%s.\n\nDefinitions in those packages may not be recognized by CodeQL, and files that use them may only be partially analyzed.\n\nCheck that the paths are correct and make sure any private packages can be accessed. If any of the packages are present in the repository then you may need a [custom build command](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages).", - numPkgPaths, - plural(len(pkgPaths), "", "s"), - secondLine), + message, severityWarning, fullVisibility, noLocation, diff --git a/go/extractor/util/util.go b/go/extractor/util/util.go index 5cb97a7bc1d6..0925d1439d87 100644 --- a/go/extractor/util/util.go +++ b/go/extractor/util/util.go @@ -312,3 +312,16 @@ func IsGolangVendorDirectory(dirPath string) bool { fileExists(filepath.Join(dirPath, "../Gopkg.lock")) || fileExists(filepath.Join(dirPath, "../vendor.conf"))) } + +// Returns true if the `GITHUB_ACTIONS` environment variable is set to `true`. +// This is the case in GitHub Actions workflows. +func IsActionsWorkflow() bool { + return os.Getenv("GITHUB_ACTIONS") == "true" +} + +// Returns true if the `GITHUB_EVENT_NAME` environment variable is set and suggests that +// we are running in a GitHub Actions workflow that was triggered by the `dynamic` event. +// This is the case for e.g. Default Setup. +func IsDynamicActionsWorkflow() bool { + return os.Getenv("GITHUB_EVENT_NAME") == "dynamic" +} diff --git a/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/diagnostics.expected b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/diagnostics.expected index 31204020a029..7af3c3a0cd00 100644 --- a/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/diagnostics.expected +++ b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/diagnostics.expected @@ -1,5 +1,5 @@ { - "markdownMessage": "110 packages could not be found:\n\n`github.com/nosuchorg/nosuchrepo000`, `github.com/nosuchorg/nosuchrepo001`, `github.com/nosuchorg/nosuchrepo002`, `github.com/nosuchorg/nosuchrepo003`, `github.com/nosuchorg/nosuchrepo004` and 105 more.\n\nDefinitions in those packages may not be recognized by CodeQL, and files that use them may only be partially analyzed.\n\nCheck that the paths are correct and make sure any private packages can be accessed. If any of the packages are present in the repository then you may need a [custom build command](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages).", + "markdownMessage": "110 packages could not be found:\n\n`github.com/nosuchorg/nosuchrepo000`, `github.com/nosuchorg/nosuchrepo001`, `github.com/nosuchorg/nosuchrepo002`, `github.com/nosuchorg/nosuchrepo003`, `github.com/nosuchorg/nosuchrepo004` and 105 more.\n\nCodeQL is able to analyze your code without those packages, but definitions from them may not be recognized and source files that use them may only be partially analyzed.\n\nTo ensure that you have comprehensive alert coverage, check that the paths are correct and make sure any private packages can be accessed by CodeQL. To set up access to a private registry, add a step to your workflow which sets up the necessary credentials and environment variables. If any of the packages are already present in the repository, but were not found, then you may need a [custom build command](https://docs.github.com/en/code-security/how-tos/scan-code-for-vulnerabilities/manage-your-configuration/codeql-code-scanning-for-compiled-languages).", "severity": "warning", "source": { "extractorName": "go", diff --git a/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/test.py b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/test.py index 1800c6ddda87..854924199691 100644 --- a/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/test.py +++ b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/test.py @@ -4,4 +4,10 @@ def test(codeql, go, check_build_environment): check_build_environment.source_root = "work" os.environ["LGTM_INDEX_IMPORT_PATH"] = "test" + + # The diagnostic message depends on the environment we are running in. To ensure consistent + # output, we set `GITHUB_ACTIONS` to `true` if we are not actually running in a workflow. + if (os.environ.get("GITHUB_ACTIONS", "") != "true"): + os.environ["GITHUB_ACTIONS"] = "true" + codeql.database.create(source_root="work") diff --git a/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/diagnostics.expected b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/diagnostics.expected index 4f3f4e643434..f39fb5b324c8 100644 --- a/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/diagnostics.expected +++ b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/diagnostics.expected @@ -1,5 +1,5 @@ { - "markdownMessage": "1 package could not be found:\n\n`github.com/linode/linode-docs-theme`.\n\nDefinitions in those packages may not be recognized by CodeQL, and files that use them may only be partially analyzed.\n\nCheck that the paths are correct and make sure any private packages can be accessed. If any of the packages are present in the repository then you may need a [custom build command](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages).", + "markdownMessage": "1 package could not be found:\n\n`github.com/linode/linode-docs-theme`.\n\nCodeQL is able to analyze your code without those packages, but definitions from them may not be recognized and source files that use them may only be partially analyzed.\n\nTo ensure that you have comprehensive alert coverage, check that the paths are correct and make sure any private packages can be accessed by CodeQL. To set up access to a private registry, add a step to your workflow which sets up the necessary credentials and environment variables. If any of the packages are already present in the repository, but were not found, then you may need a [custom build command](https://docs.github.com/en/code-security/how-tos/scan-code-for-vulnerabilities/manage-your-configuration/codeql-code-scanning-for-compiled-languages).", "severity": "warning", "source": { "extractorName": "go", diff --git a/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/test.py b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/test.py index 1800c6ddda87..854924199691 100644 --- a/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/test.py +++ b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/test.py @@ -4,4 +4,10 @@ def test(codeql, go, check_build_environment): check_build_environment.source_root = "work" os.environ["LGTM_INDEX_IMPORT_PATH"] = "test" + + # The diagnostic message depends on the environment we are running in. To ensure consistent + # output, we set `GITHUB_ACTIONS` to `true` if we are not actually running in a workflow. + if (os.environ.get("GITHUB_ACTIONS", "") != "true"): + os.environ["GITHUB_ACTIONS"] = "true" + codeql.database.create(source_root="work")