Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: bot-for-go[bot] <199222863+bot-for-go[bot]@users.noreply.github.com>
Date: Wed, 24 Sep 2025 12:46:04 +0100
Subject: [PATCH] Add deprecation warnings for specific crypto backends

Add deprecation warnings for opensslcrypto, cngcrypto, and darwincrypto
GOEXPERIMENT values in CI environments (GitHub Actions and Azure DevOps).
These specific backend experiments are deprecated in favor of systemcrypto,
which automatically selects the appropriate backend for the target platform.

The warnings use CI-specific formats:
- GitHub Actions: ::warning:: annotation
- Azure DevOps: ##vso[task.logissue type=warning] command

Warnings are only emitted when:
1. Building in a detected CI environment
2. The deprecated backend was explicitly specified by the user
(not auto-selected by systemcrypto)

This helps users migrate away from the specific backend experiments without
breaking existing tooling that might parse stdout/stderr, and avoids
warning when systemcrypto automatically selects a backend.
---
src/cmd/go/main.go | 3 ++
src/internal/buildcfg/exp.go | 67 ++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+)

diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 67dbcb2e7a3cb9..1730261a3b1ba6 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -305,6 +305,9 @@ func invoke(cmd *base.Command, args []string) {
}
}

+ // Check for deprecated crypto backends and emit warnings in CI environments
+ buildcfg.CheckDeprecatedCryptoBackends()
+
// Set environment (GOOS, GOARCH, etc) explicitly.
// In theory all the commands we invoke should have
// the same default computation of these as we do,
diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go
index 9ea95a9df726d1..2a96ad274329f9 100644
--- a/src/internal/buildcfg/exp.go
+++ b/src/internal/buildcfg/exp.go
@@ -7,6 +7,7 @@ package buildcfg
import (
"errors"
"fmt"
+ "os"
"reflect"
"slices"
"strings"
@@ -235,6 +236,72 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) {
return flags, nil
}

+// CheckDeprecatedCryptoBackends emits deprecation warnings for specific crypto backends
+// in CI environments when the user explicitly specified those backends.
+// This should be called once at the start of the go command.
+func CheckDeprecatedCryptoBackends() {
+ goexp := os.Getenv("GOEXPERIMENT")
+ if goexp == "" {
+ // No explicit GOEXPERIMENT set, so systemcrypto is the default
+ // No need to warn about auto-selection
+ return
+ }
+
+ // Check each deprecated backend that might be explicitly specified
+ deprecatedBackends := []string{"opensslcrypto", "cngcrypto", "darwincrypto"}
+
+ for _, backend := range deprecatedBackends {
+ if isBackendExplicitlySpecified(backend, goexp) {
+ emitDeprecationWarning(backend)
+ }
+ }
+}
+
+// isBackendExplicitlySpecified checks if the specific backend was explicitly
+// specified in the GOEXPERIMENT string
+func isBackendExplicitlySpecified(backend, goexperiment string) bool {
+ // Parse the comma-separated GOEXPERIMENT string
+ for f := range strings.SplitSeq(goexperiment, ",") {
+ if f == backend {
+ return true
+ }
+ }
+ return false
+}
+
+// emitDeprecationWarning outputs a deprecation warning in CI environments
+func emitDeprecationWarning(backend string) {
+ if isGitHubActions() {
+ fmt.Fprintf(os.Stderr,
+ "::warning title=GOEXPERIMENT_DEPRECATED::GOEXPERIMENT=%s is deprecated. Use GOEXPERIMENT=systemcrypto instead, or remove GOEXPERIMENT entirely as systemcrypto is now the default.\n",
+ backend)
+ } else if isAzureDevOps() {
+ fmt.Fprintf(os.Stderr,
+ "##vso[task.logissue type=warning;code=GOEXPERIMENT_DEPRECATED;]GOEXPERIMENT=%s is deprecated. Use GOEXPERIMENT=systemcrypto instead, or remove GOEXPERIMENT entirely as systemcrypto is now the default.\n",
+ backend)
+ }
+ // For other environments, we don't emit warnings to avoid breaking
+ // users who might be parsing stdout/stderr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this logic holds: I would expect child processes to inherit the variables, so e.g. even if isAzureDevOps() is true, there might be a wrapper process doing parsing.

+}
+
+// isGitHubActions detects if we're running in GitHub Actions
+func isGitHubActions() bool {
+ return os.Getenv("GITHUB_ACTIONS") == "true"
+}
+
+// isAzureDevOps detects if we're running in Azure DevOps
+func isAzureDevOps() bool {
+ // Azure DevOps sets TF_BUILD=True
+ tfBuild := os.Getenv("TF_BUILD")
+ if tfBuild == "True" || tfBuild == "true" {
+ return true
+ }
+
+ // Also check for SYSTEM_TEAMFOUNDATIONCOLLECTIONURI which is commonly set
+ tfsUri := os.Getenv("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI")
+ return tfsUri != ""
+}
+
// String returns the canonical GOEXPERIMENT string to enable this experiment
// configuration. (Experiments in the same state as in the baseline are elided.)
func (exp *ExperimentFlags) String() string {
Loading