Add Go language support to func init - #4875
Conversation
Co-authored-by: Lilian Kasem <likasem@microsoft.com>
Lilian Kasem (liliankasem)
left a comment
There was a problem hiding this comment.
A couple of smaller follow-ups on how Go is wired into InitAction — most of the per-runtime branching here matches what Python/Node/etc. already do, so no concern there. Two spots stood out though:
1. FUNCTIONS_WORKER_RUNTIME mapping.
GetRuntimeMoniker(WorkerRuntime.Go) returns "go", but the value we actually need to write into local.settings.json is "native". Right now that mapping lives inline in WriteLocalSettingsJson:
string workerRuntimeSetting = workerRuntime == WorkerRuntime.Go
? "native"
: WorkerRuntimeLanguageHelper.GetRuntimeMoniker(workerRuntime);Could we move that into WorkerRuntimeLanguageHelper (e.g. a GetFunctionsWorkerRuntimeSetting(workerRuntime) helper)? Every other runtime round-trips between the moniker and the host-facing setting, so anyone else who needs the host value will reach for GetRuntimeMoniker and silently get the wrong string. Centralizing it keeps the divergence in one place.
2. Dispatch in InitFunctionAppProject.
Every other runtime flows through InitLanguageSpecificArtifacts (which has its own internal switch). Go is the first to be handled with a sibling branch at the call site:
if (ResolvedWorkerRuntime == WorkerRuntime.Go)
{
await GoHelpers.SetupProject(...);
}
else
{
await InitLanguageSpecificArtifacts(...);
}Could we add a case WorkerRuntime.Go: inside InitLanguageSpecificArtifacts that calls GoHelpers.SetupProject instead? Keeps the dispatch in one place and matches the existing shape. Small thing but it's the difference between "Go fits the pattern" and "Go is the exception that splits dispatch in two."
The enum name (p.Key.ToString()) is auto-appended to each runtime's alias list when building _normalizeMap with StringComparer.OrdinalIgnoreCase. Having `go` as an explicit alias AND relying on the auto-appended `Go` enum name produced duplicate keys, throwing TypeInitializationException on any code path that touched WorkerRuntimeLanguageHelper (e.g. InitAction.ParseArgs). Drop the redundant `go` alias; `go`/`Go` still normalize to WorkerRuntime.Go via the auto-appended enum name under case-insensitive comparison. Matches the convention used by every other runtime entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Ship a templated go.mod with the SDK require pinned; drop the explicit `go mod init`/`go get ...@version` steps and let `go mod tidy` resolve it. Bumping the SDK now only requires editing template files. - Remove GoWorkerModule/GoWorkerModuleVersion C# constants in favor of the template-based pin. - Fail with a CliException when --docker is used with the Go runtime instead of warning and silently skipping Dockerfile creation. - Update E2E test accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Aishwarya Bhandari (aishwaryabh)
left a comment
There was a problem hiding this comment.
I don't see this test running in the pipeline. You would need to add the following to all of the test-e2e-*.yml
- name: Go
languageWorker: 'Go'
- Add GoTool@0 (Go 1.24.2) to install-tools.yml, matching the pattern used for Node, Python, and .NET - Add Go matrix entry to linux/osx/windows E2E pipelines - Remove ad hoc apt-get/brew Go installs in favor of the pinned shared task Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move the 'Docker support for Go is not yet available' check to the start of InitAction.RunAsync so the failure is reported before any project setup work runs (previously it was reachable only after 'go mod tidy', which on offline/restricted CI agents could fail first with an unrelated error). - Remove Init_WithGo_ScaffoldedProjectCompiles. No other language has a 'scaffold compiles after init' E2E test; the pattern across Node/Python/.NET/PowerShell is that 'func init' writes the scaffold and any package install is best-effort with a warning. Requiring outbound module-proxy access at test time is inconsistent with that contract and breaks on network-restricted CI agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GoTool@0 in install-tools.yml fails to make 'go' resolvable on the macOS-latest hosted agent (E2E tests reported 'Could not find a Go installation'). The brew-based install was working previously; restoring it keeps GoTool@0 in place for Windows/Linux and addresses the OSX-specific failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Each Azure Pipelines step runs in its own shell, so PATH mutations inside a 'script:' block do not propagate. Use '##vso[task.prependpath]' so the dotnet test step (and any other downstream steps) can resolve 'go' on the macOS-latest agent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GoTool@0 in install-tools.yml ran after the brew install on macOS-latest and clobbered the brew Go on PATH (the brew install step's verification succeeded, but tests later failed with 'Could not find a Go installation'). Move the task to the linux and windows pipelines explicitly so OSX picks up brew Go only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GoTool@0 fetches from go.dev which is unreachable from 1ES Linux agents. The 'golang-1.24' package is available in the Ubuntu 24.04 noble-updates pocket (reachable via the cached apt mirror), and ships at /usr/lib/go-1.24/bin/go. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
a438537 to
6a6a087
Compare
Reverts the Go E2E pipeline matrix and related Go installation steps from test-e2e-linux/osx/windows.yml and install-tools.yml. The pipeline enablement will be tracked in a follow-up PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Aishwarya Bhandari (aishwaryabh)
left a comment
There was a problem hiding this comment.
approving to unblock PR. Pipeline changes should be addressed in a future PR
916a5eb
into
feature/go-support
* feat: Add Go language support to func init via Native worker runtime * Add TryNormalizeLanguage to preserve language inference for existing runtimes * fix: add missing FluentAssertions using in NativeGoInitTests * Address pr feedback * Address pr feedback * Move init logic behind worker runtime go * Fix local settings * Create main.go with sdk and sample code * Address PR review: pin Go worker SDK and surface go command stderr * Update src/Cli/func/Helpers/WorkerRuntimeLanguageHelper.cs Co-authored-by: Lilian Kasem <likasem@microsoft.com> * Fix WorkerRuntimeLanguageHelper static init crash for Go The enum name (p.Key.ToString()) is auto-appended to each runtime's alias list when building _normalizeMap with StringComparer.OrdinalIgnoreCase. Having `go` as an explicit alias AND relying on the auto-appended `Go` enum name produced duplicate keys, throwing TypeInitializationException on any code path that touched WorkerRuntimeLanguageHelper (e.g. InitAction.ParseArgs). Drop the redundant `go` alias; `go`/`Go` still normalize to WorkerRuntime.Go via the auto-appended enum name under case-insensitive comparison. Matches the convention used by every other runtime entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: template-owned go.mod and loud failure on --docker - Ship a templated go.mod with the SDK require pinned; drop the explicit `go mod init`/`go get ...@version` steps and let `go mod tidy` resolve it. Bumping the SDK now only requires editing template files. - Remove GoWorkerModule/GoWorkerModuleVersion C# constants in favor of the template-based pin. - Fail with a CliException when --docker is used with the Go runtime instead of warning and silently skipping Dockerfile creation. - Update E2E test accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enable Go E2E tests in CI pipelines - Add GoTool@0 (Go 1.24.2) to install-tools.yml, matching the pattern used for Node, Python, and .NET - Add Go matrix entry to linux/osx/windows E2E pipelines - Remove ad hoc apt-get/brew Go installs in favor of the pinned shared task Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate --docker for Go up-front; remove scaffold-compiles E2E test - Move the 'Docker support for Go is not yet available' check to the start of InitAction.RunAsync so the failure is reported before any project setup work runs (previously it was reachable only after 'go mod tidy', which on offline/restricted CI agents could fail first with an unrelated error). - Remove Init_WithGo_ScaffoldedProjectCompiles. No other language has a 'scaffold compiles after init' E2E test; the pattern across Node/Python/.NET/PowerShell is that 'func init' writes the scaffold and any package install is best-effort with a warning. Requiring outbound module-proxy access at test time is inconsistent with that contract and breaks on network-restricted CI agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore brew install go on OSX E2E pipeline GoTool@0 in install-tools.yml fails to make 'go' resolvable on the macOS-latest hosted agent (E2E tests reported 'Could not find a Go installation'). The brew-based install was working previously; restoring it keeps GoTool@0 in place for Windows/Linux and addresses the OSX-specific failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prepend brew Go bin path so subsequent steps can find go Each Azure Pipelines step runs in its own shell, so PATH mutations inside a 'script:' block do not propagate. Use '##vso[task.prependpath]' so the dotnet test step (and any other downstream steps) can resolve 'go' on the macOS-latest agent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move GoTool@0 out of install-tools.yml so OSX uses brew exclusively GoTool@0 in install-tools.yml ran after the brew install on macOS-latest and clobbered the brew Go on PATH (the brew install step's verification succeeded, but tests later failed with 'Could not find a Go installation'). Move the task to the linux and windows pipelines explicitly so OSX picks up brew Go only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Install Go via apt instead of GoTool@0 on Linux pipeline GoTool@0 fetches from go.dev which is unreachable from 1ES Linux agents. The 'golang-1.24' package is available in the Ubuntu 24.04 noble-updates pocket (reachable via the cached apt mirror), and ships at /usr/lib/go-1.24/bin/go. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Go diagnostics on OSX E2E pipeline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Diagnose Go from pwsh on OSX (matches test step shell) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert pipeline changes (will be done in separate PR) Reverts the Go E2E pipeline matrix and related Go installation steps from test-e2e-linux/osx/windows.yml and install-tools.yml. The pipeline enablement will be tracked in a follow-up PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Lilian Kasem <likasem@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: Add Go language support to func init via Native worker runtime * Add TryNormalizeLanguage to preserve language inference for existing runtimes * fix: add missing FluentAssertions using in NativeGoInitTests * Address pr feedback * Address pr feedback * Move init logic behind worker runtime go * Fix local settings * Create main.go with sdk and sample code * Address PR review: pin Go worker SDK and surface go command stderr * Update src/Cli/func/Helpers/WorkerRuntimeLanguageHelper.cs Co-authored-by: Lilian Kasem <likasem@microsoft.com> * Fix WorkerRuntimeLanguageHelper static init crash for Go The enum name (p.Key.ToString()) is auto-appended to each runtime's alias list when building _normalizeMap with StringComparer.OrdinalIgnoreCase. Having `go` as an explicit alias AND relying on the auto-appended `Go` enum name produced duplicate keys, throwing TypeInitializationException on any code path that touched WorkerRuntimeLanguageHelper (e.g. InitAction.ParseArgs). Drop the redundant `go` alias; `go`/`Go` still normalize to WorkerRuntime.Go via the auto-appended enum name under case-insensitive comparison. Matches the convention used by every other runtime entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: template-owned go.mod and loud failure on --docker - Ship a templated go.mod with the SDK require pinned; drop the explicit `go mod init`/`go get ...@version` steps and let `go mod tidy` resolve it. Bumping the SDK now only requires editing template files. - Remove GoWorkerModule/GoWorkerModuleVersion C# constants in favor of the template-based pin. - Fail with a CliException when --docker is used with the Go runtime instead of warning and silently skipping Dockerfile creation. - Update E2E test accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enable Go E2E tests in CI pipelines - Add GoTool@0 (Go 1.24.2) to install-tools.yml, matching the pattern used for Node, Python, and .NET - Add Go matrix entry to linux/osx/windows E2E pipelines - Remove ad hoc apt-get/brew Go installs in favor of the pinned shared task Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate --docker for Go up-front; remove scaffold-compiles E2E test - Move the 'Docker support for Go is not yet available' check to the start of InitAction.RunAsync so the failure is reported before any project setup work runs (previously it was reachable only after 'go mod tidy', which on offline/restricted CI agents could fail first with an unrelated error). - Remove Init_WithGo_ScaffoldedProjectCompiles. No other language has a 'scaffold compiles after init' E2E test; the pattern across Node/Python/.NET/PowerShell is that 'func init' writes the scaffold and any package install is best-effort with a warning. Requiring outbound module-proxy access at test time is inconsistent with that contract and breaks on network-restricted CI agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore brew install go on OSX E2E pipeline GoTool@0 in install-tools.yml fails to make 'go' resolvable on the macOS-latest hosted agent (E2E tests reported 'Could not find a Go installation'). The brew-based install was working previously; restoring it keeps GoTool@0 in place for Windows/Linux and addresses the OSX-specific failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prepend brew Go bin path so subsequent steps can find go Each Azure Pipelines step runs in its own shell, so PATH mutations inside a 'script:' block do not propagate. Use '##vso[task.prependpath]' so the dotnet test step (and any other downstream steps) can resolve 'go' on the macOS-latest agent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move GoTool@0 out of install-tools.yml so OSX uses brew exclusively GoTool@0 in install-tools.yml ran after the brew install on macOS-latest and clobbered the brew Go on PATH (the brew install step's verification succeeded, but tests later failed with 'Could not find a Go installation'). Move the task to the linux and windows pipelines explicitly so OSX picks up brew Go only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Install Go via apt instead of GoTool@0 on Linux pipeline GoTool@0 fetches from go.dev which is unreachable from 1ES Linux agents. The 'golang-1.24' package is available in the Ubuntu 24.04 noble-updates pocket (reachable via the cached apt mirror), and ships at /usr/lib/go-1.24/bin/go. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Go diagnostics on OSX E2E pipeline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Diagnose Go from pwsh on OSX (matches test step shell) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert pipeline changes (will be done in separate PR) Reverts the Go E2E pipeline matrix and related Go installation steps from test-e2e-linux/osx/windows.yml and install-tools.yml. The pipeline enablement will be tracked in a follow-up PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Lilian Kasem <likasem@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: Add Go language support to func init via Native worker runtime * Add TryNormalizeLanguage to preserve language inference for existing runtimes * fix: add missing FluentAssertions using in NativeGoInitTests * Address pr feedback * Address pr feedback * Move init logic behind worker runtime go * Fix local settings * Create main.go with sdk and sample code * Address PR review: pin Go worker SDK and surface go command stderr * Update src/Cli/func/Helpers/WorkerRuntimeLanguageHelper.cs Co-authored-by: Lilian Kasem <likasem@microsoft.com> * Fix WorkerRuntimeLanguageHelper static init crash for Go The enum name (p.Key.ToString()) is auto-appended to each runtime's alias list when building _normalizeMap with StringComparer.OrdinalIgnoreCase. Having `go` as an explicit alias AND relying on the auto-appended `Go` enum name produced duplicate keys, throwing TypeInitializationException on any code path that touched WorkerRuntimeLanguageHelper (e.g. InitAction.ParseArgs). Drop the redundant `go` alias; `go`/`Go` still normalize to WorkerRuntime.Go via the auto-appended enum name under case-insensitive comparison. Matches the convention used by every other runtime entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: template-owned go.mod and loud failure on --docker - Ship a templated go.mod with the SDK require pinned; drop the explicit `go mod init`/`go get ...@version` steps and let `go mod tidy` resolve it. Bumping the SDK now only requires editing template files. - Remove GoWorkerModule/GoWorkerModuleVersion C# constants in favor of the template-based pin. - Fail with a CliException when --docker is used with the Go runtime instead of warning and silently skipping Dockerfile creation. - Update E2E test accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enable Go E2E tests in CI pipelines - Add GoTool@0 (Go 1.24.2) to install-tools.yml, matching the pattern used for Node, Python, and .NET - Add Go matrix entry to linux/osx/windows E2E pipelines - Remove ad hoc apt-get/brew Go installs in favor of the pinned shared task Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate --docker for Go up-front; remove scaffold-compiles E2E test - Move the 'Docker support for Go is not yet available' check to the start of InitAction.RunAsync so the failure is reported before any project setup work runs (previously it was reachable only after 'go mod tidy', which on offline/restricted CI agents could fail first with an unrelated error). - Remove Init_WithGo_ScaffoldedProjectCompiles. No other language has a 'scaffold compiles after init' E2E test; the pattern across Node/Python/.NET/PowerShell is that 'func init' writes the scaffold and any package install is best-effort with a warning. Requiring outbound module-proxy access at test time is inconsistent with that contract and breaks on network-restricted CI agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore brew install go on OSX E2E pipeline GoTool@0 in install-tools.yml fails to make 'go' resolvable on the macOS-latest hosted agent (E2E tests reported 'Could not find a Go installation'). The brew-based install was working previously; restoring it keeps GoTool@0 in place for Windows/Linux and addresses the OSX-specific failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prepend brew Go bin path so subsequent steps can find go Each Azure Pipelines step runs in its own shell, so PATH mutations inside a 'script:' block do not propagate. Use '##vso[task.prependpath]' so the dotnet test step (and any other downstream steps) can resolve 'go' on the macOS-latest agent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move GoTool@0 out of install-tools.yml so OSX uses brew exclusively GoTool@0 in install-tools.yml ran after the brew install on macOS-latest and clobbered the brew Go on PATH (the brew install step's verification succeeded, but tests later failed with 'Could not find a Go installation'). Move the task to the linux and windows pipelines explicitly so OSX picks up brew Go only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Install Go via apt instead of GoTool@0 on Linux pipeline GoTool@0 fetches from go.dev which is unreachable from 1ES Linux agents. The 'golang-1.24' package is available in the Ubuntu 24.04 noble-updates pocket (reachable via the cached apt mirror), and ships at /usr/lib/go-1.24/bin/go. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Go diagnostics on OSX E2E pipeline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Diagnose Go from pwsh on OSX (matches test step shell) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert pipeline changes (will be done in separate PR) Reverts the Go E2E pipeline matrix and related Go installation steps from test-e2e-linux/osx/windows.yml and install-tools.yml. The pipeline enablement will be tracked in a follow-up PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Lilian Kasem <likasem@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add Go language support to func init (#4875) * feat: Add Go language support to func init via Native worker runtime * Add TryNormalizeLanguage to preserve language inference for existing runtimes * fix: add missing FluentAssertions using in NativeGoInitTests * Address pr feedback * Address pr feedback * Move init logic behind worker runtime go * Fix local settings * Create main.go with sdk and sample code * Address PR review: pin Go worker SDK and surface go command stderr * Update src/Cli/func/Helpers/WorkerRuntimeLanguageHelper.cs Co-authored-by: Lilian Kasem <likasem@microsoft.com> * Fix WorkerRuntimeLanguageHelper static init crash for Go The enum name (p.Key.ToString()) is auto-appended to each runtime's alias list when building _normalizeMap with StringComparer.OrdinalIgnoreCase. Having `go` as an explicit alias AND relying on the auto-appended `Go` enum name produced duplicate keys, throwing TypeInitializationException on any code path that touched WorkerRuntimeLanguageHelper (e.g. InitAction.ParseArgs). Drop the redundant `go` alias; `go`/`Go` still normalize to WorkerRuntime.Go via the auto-appended enum name under case-insensitive comparison. Matches the convention used by every other runtime entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: template-owned go.mod and loud failure on --docker - Ship a templated go.mod with the SDK require pinned; drop the explicit `go mod init`/`go get ...@version` steps and let `go mod tidy` resolve it. Bumping the SDK now only requires editing template files. - Remove GoWorkerModule/GoWorkerModuleVersion C# constants in favor of the template-based pin. - Fail with a CliException when --docker is used with the Go runtime instead of warning and silently skipping Dockerfile creation. - Update E2E test accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enable Go E2E tests in CI pipelines - Add GoTool@0 (Go 1.24.2) to install-tools.yml, matching the pattern used for Node, Python, and .NET - Add Go matrix entry to linux/osx/windows E2E pipelines - Remove ad hoc apt-get/brew Go installs in favor of the pinned shared task Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate --docker for Go up-front; remove scaffold-compiles E2E test - Move the 'Docker support for Go is not yet available' check to the start of InitAction.RunAsync so the failure is reported before any project setup work runs (previously it was reachable only after 'go mod tidy', which on offline/restricted CI agents could fail first with an unrelated error). - Remove Init_WithGo_ScaffoldedProjectCompiles. No other language has a 'scaffold compiles after init' E2E test; the pattern across Node/Python/.NET/PowerShell is that 'func init' writes the scaffold and any package install is best-effort with a warning. Requiring outbound module-proxy access at test time is inconsistent with that contract and breaks on network-restricted CI agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore brew install go on OSX E2E pipeline GoTool@0 in install-tools.yml fails to make 'go' resolvable on the macOS-latest hosted agent (E2E tests reported 'Could not find a Go installation'). The brew-based install was working previously; restoring it keeps GoTool@0 in place for Windows/Linux and addresses the OSX-specific failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prepend brew Go bin path so subsequent steps can find go Each Azure Pipelines step runs in its own shell, so PATH mutations inside a 'script:' block do not propagate. Use '##vso[task.prependpath]' so the dotnet test step (and any other downstream steps) can resolve 'go' on the macOS-latest agent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move GoTool@0 out of install-tools.yml so OSX uses brew exclusively GoTool@0 in install-tools.yml ran after the brew install on macOS-latest and clobbered the brew Go on PATH (the brew install step's verification succeeded, but tests later failed with 'Could not find a Go installation'). Move the task to the linux and windows pipelines explicitly so OSX picks up brew Go only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Install Go via apt instead of GoTool@0 on Linux pipeline GoTool@0 fetches from go.dev which is unreachable from 1ES Linux agents. The 'golang-1.24' package is available in the Ubuntu 24.04 noble-updates pocket (reachable via the cached apt mirror), and ships at /usr/lib/go-1.24/bin/go. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Go diagnostics on OSX E2E pipeline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Diagnose Go from pwsh on OSX (matches test step shell) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert pipeline changes (will be done in separate PR) Reverts the Go E2E pipeline matrix and related Go installation steps from test-e2e-linux/osx/windows.yml and install-tools.yml. The pipeline enablement will be tracked in a follow-up PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Lilian Kasem <likasem@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add func start support for Go (#4892) * Add func start support for Go * Address pr review * Address pr feedback --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> * Adds func pack and func publish support for Golang (#4943) * Add func pack + func publish support for Go * fix file format error * Use Homebrew Go on macOS E2E pipeline GoTool@0 only ships an amd64 Go binary. macOS-latest hosted agents are Apple Silicon (arm64); without Rosetta 2 the cached binary fails to execute, which func surfaces as 'Could not find a Go installation'. Install an arm64-native Go via Homebrew after install-tools.yml runs. Later task.prependpath calls win, so brew's go takes precedence over the GoTool@0 path on macOS only. Linux/Windows pipelines are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Pin macOS brew Go to go@1.24 to match GoTool@0 Unversioned 'brew install go' tracks latest stable (currently 1.26.2), which drifts macOS away from the 1.24.2 GoTool@0 pin used on Linux and Windows. It also collides with GoTool@0's exported GOROOT, producing: compile: version 'go1.24.2' does not match go tool version 'go1.26.2' Switch to the keg-only go@1.24 formula so all three OSes test against the same Go major.minor and the GOROOT inherited from GoTool@0 stays compatible with brew's go driver. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Override GOROOT to brew's go@1.24 toolchain on macOS GoTool@0 exports GOROOT pointing at its own 1.24.2 cache. brew's go@1.24 resolves to the latest 1.24.x patch (e.g. 1.24.13), and brew's go driver reads the inherited GOROOT, finds the older compile tool there, and aborts: compile: version 'go1.24.2' does not match go tool version 'go1.24.13' Query brew's matching GOROOT via 'go env GOROOT' and override the pipeline variable so subsequent steps (Publish CLI, dotnet test) use a self- consistent toolchain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Skip GoTool@0 on macOS; let Homebrew be the sole Go installer GoTool@0 only ships an amd64 Go binary and exports GOROOT pointing at its own toolchain. On Apple Silicon agents (macOS-latest is arm64) it can't execute, and even when bypassed by a brew install on PATH the inherited GOROOT causes downstream 'go build' invocations (e.g. GoZipTool's MSBuild Exec target during dotnet publish) to mix toolchain versions: compile: version 'go1.24.2' does not match go tool version 'go1.24.13' Gate the GoTool@0 task on non-Darwin so the brew-installed go@1.24 is the only Go on macOS and there is no GOROOT to fight. The brew step in test-e2e-osx.yml is correspondingly simplified (no more GOROOT override). Linux/Windows pipelines are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * capture full stdout from short lived cmds * update Go ordering in core tools * Apply fixes * Fix file format for build * Address Go bug-bash findings (A1, A2, A4, A5) A1: Leave AzureWebJobsStorage empty in the Go init template so 'func azure functionapp publish -i -y' cannot silently overwrite a production app's storage with 'UseDevelopmentStorage=true'. Other runtimes are unchanged. A2: 'func pack --output <path>.zip' now creates the file at <path>.zip (creating parent directories as needed) instead of treating the value as a directory and writing <projname>.zip inside it. Paths without a .zip suffix still resolve to a containing directory. A4: 'func start' skips invoking 'go build' when the worker binary is newer than every .go source file plus go.mod/go.sum. Avoids a redundant rebuild on warm reruns. New IsBinaryUpToDate helper covers nested sources and missing-binary cases. Also: when 'go build' fails with a stale-modules signature ('missing go.sum entry', 'no required module provides package', 'inconsistent vendoring'), emit a hint pointing the user at 'go mod tidy' before re-running func start. A5: 'func new' on a Go-init folder now short-circuits cleanly with an actionable message ('Go uses programmatic registration -- add functions by editing main.go (app.HTTP(...), app.Timer(...), etc.)') instead of falling into the templates code path and rendering a garbled prompt. Mirrors the existing Java early-exit pattern. Tests: - PackHelpersTests: 4 new tests covering ResolveOutputPath (default, .zip file path, .ZIP uppercase, directory). - GoHelperTests: 5 new tests covering IsBinaryUpToDate (missing binary, binary newer, source newer, go.mod newer, nested source newer). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix SA1518 trailing newline in PackHelpersTests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #4943 review feedback and bug-bash findings Executable output drain: - Cap async stdout/stderr drain at 5s after process exit - Call no-arg WaitForExit() to actually flush async handlers - Verbose-only warning on timeout instead of blocking forever Go build output to bin/ (aligned with dotnet-isolated pattern): - Build to bin/app instead of app, matching how dotnet-isolated builds to bin/output so build artifacts are already gitignored - Update worker.config.json defaultExecutablePath to bin/app - Removes need for Go-specific .gitignore entries (bin/ already ignored) Native worker runtime resolution: - Extract shared ResolveNativeWorkerRuntime to WorkerRuntimeLanguageHelper - Gate native->Go on go.mod presence (extensible for future native languages) - Replace private StartHostAction method; add calls in PackAction and PublishAction ResolveOutputPath scoping: - Revert PackHelpers.ResolveOutputPath to original behavior for all runtimes - Add virtual hook on PackSubcommandAction; Go override adds existing-file guard Other review items: - GoPackSubcommandAction.RunAsync() throws NotSupportedException - --list-included-files annotates pre-build paths - Pin GOROOT for Homebrew Go in macOS pipeline - IsBinaryUpToDate scans all files (handles //go:embed), excludes vendor/, *_test.go, hidden dirs, root-level bin/ - Fix zip executable bit using forward-slash entry names (cross-platform) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove IsBinaryUpToDate build cache optimization Removes the timestamp-based build cache for func start. Always runs go build to avoid risk of silently running stale code during local development. Go's own build cache (GOCACHE) still provides fast incremental rebuilds when sources haven't changed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix ResolveNativeWorkerRuntime failing on non-Go projects SecretsManager.GetSecrets() throws when invoked from a directory without host.json or local.settings.json (e.g., func pack with a relative path argument). Guard the GetSecrets() call with try/catch so ResolveNativeWorkerRuntime is a safe no-op for non-native runtimes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #4943 review feedback: exec bit assertion, test isolation, output path cleanup - ZipHelperTests: add assertion verifying Unix exec bit (0x49) on bin/app zip entry to guard against regression that would break Linux deploys - InitActionGoTests: replace Environment.CurrentDirectory mutation with FileSystemHelpers.Override pattern for parallel-safe test isolation - GoPackSubcommandAction: remove dead Path.Combine local in ResolveOutputPath; inline the File.Exists guard Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove duplicate GoTool@0 1.21 from Linux unit test pipeline install-tools.yml already installs Go 1.24.2 via GoTool@0. The stale 1.21 entry ran first and set GOROOT/PATH to an older Go, causing GoHelperTests.WorkerInfoRuntimeShouldBeGo to fail on Linux CI agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Go discovery in Linux unit test pipeline - Replace stale GoTool@0 1.21 with GoTool@0 1.24.2 in test-unit-linux.yml to match the version required by GoHelpers.AssertGoVersion - Harden SkipIfGoNonExistFact to actually run 'go version' instead of only checking if the binary exists on PATH. A broken or misconfigured Go installation now causes the test to skip gracefully rather than fail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Place Go binary at zip root for deployment; keep native worker in minified builds The Azure Functions host expects the Go binary at the zip root ('app'), not under 'bin/app'. Locally the binary is still built to bin/ for .gitignore convenience, but the deployment zip now maps it to the root. Also stop stripping workers/native/ from minified builds — the native worker config is a single JSON file the host needs for func start. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix func pack failing with FUNCTIONS_WORKER_RUNTIME=native for Go PackAction resolved "native" + go.mod to Go, then overwrote it with GetCurrentWorkerRuntimeLanguage which can't normalize "native" and returned None, surfacing a misleading "Unable to determine the worker runtime" error. Have ResolveNativeWorkerRuntime return the resolved runtime and use it in PackAction. Add regression test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix GoHelpers.GetVersion racing async stdout drain on Linux Executable's async output pump can lag behind process exit for very short-lived commands like `go version`; on Linux CI this left GetVersion parsing an empty StringBuilder and returning null, failing GoHelperTests.InterpreterShouldHaveMajorVersion. Mirror the PythonHelpers.VerifyVersion polling retry to wait briefly for the output to materialize before parsing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use synchronous stdout for Go version detection to fix macOS E2E flake Executable's async event-based stdout pump can race past Process.WaitForExit for sub-second commands like 'go version' on macOS/Linux agents under load. The earlier polling retry helped on Linux unit tests but wasn't sufficient for macOS E2E (GoInitTests.Init_WithGolangAlias_ResolvesToGo failed while sibling tests in the same job using the same code path passed). Rewrite GetVersion to use Process directly with synchronous StandardOutput.ReadToEndAsync — same pattern SkipIfGoNonExistFact already uses reliably across all three OSes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add --go and --golang shortcut flags to func init Matches the existing --python, --node, --dotnet, --powershell, --custom, etc. shortcuts. GlobalCoreToolsSettings.Init now recognizes --go and --golang and sets CurrentWorkerRuntime to Go, letting users run 'func init --go' instead of 'func init --worker-runtime go'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Block func new on Go projects without mutating local.settings.json ResolveWorkerRuntimeAsync didn't normalize FUNCTIONS_WORKER_RUNTIME=native, so the existing Go guard never fired in Go workspaces. func new then hung on the template/language wizard and could overwrite FUNCTIONS_WORKER_RUNTIME from 'native' to 'go'. Resolve native -> concrete runtime via ResolveNativeWorkerRuntime before falling back to the global. Add E2E coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Drop ARM64 TODO from BuildForLinux doc comment Core Tools' Go pipeline targets linux/amd64 by design. The prior TODO implied future arch support that isn't planned. Replace with a concise statement of current behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Unpin azure-functions-golang-worker SDK in go.mod template Drop the explicit require line so 'go mod tidy' resolves the latest available SDK tag from main.go's imports. Users get the newest SDK without contributors needing to bump a pinned version in this repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: fold native resolution into GetCurrentWorkerRuntimeLanguage Per PR #4943 review feedback from @liliankasem: - Fold ResolveNativeWorkerRuntime into GetCurrentWorkerRuntimeLanguage so PackAction / PublishFunctionAppAction / CreateFunctionAction / StartHostAction each call a single method. 'native' -> project-marker resolution happens inside the helper; callers no longer juggle two reads of GetSecrets nor catch CliException for the dual-read race. Private ResolveNativeFromProjectMarkers does the file inspection only. - Wrap Executable.DrainAsyncOutput body in try/catch for InvalidOperationException and Win32Exception so a best-effort drain failure doesn't mask the captured exit code. - Soften 'func new' Go message to 'not yet supported'. - Update tests to exercise the new combined entry point. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enable 1ES centralized Go module proxy for Go-using pipelines public-build.yml (unit tests, E2E tests, GoZipTool) and official-build.yml (production CLI build, GoZipTool) invoke 'go' CLI commands that need to resolve external modules. Network-isolated 1ES agents block direct Go proxy access; opt in to the internal proxy via the documented feature flag so 'go mod tidy' / 'go build' can resolve azure-functions-golang-worker. Skipped for host-, linux-, and consolidate-artifacts pipelines — those consume pre-built artifacts and don't run any Go tooling. See https://aka.ms/goproxy_for_how_to_onboard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align GoFuncNewTests assertions with 'not yet supported' wording Followup to commit 578fda3 which softened the func new Go message per PR review. The E2E test assertions still referenced the old 'is not supported' wording, causing the macOS E2E pipeline to fail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use sync Process I/O in GoHelpers.GetVersion for Linux reliability Async Process I/O (ReadToEndAsync / WaitForExitAsync) intermittently returned null on Linux CI for 'go version'. Switch to sync ReadToEnd + WaitForExit(5s) and surface failure reasons to stderr. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add FUNCTIONS_CLI_GO_PREVIEW opt-in flag for Go CLI detection (#4966) Adds a CLI-only preview flag so the resolver can identify Go projects without scanning for go.mod. Read precedence: env var > local.settings.json > legacy native+go.mod fallback. func init writes the flag for new Go projects. Resolver and init tests covered; both test classes moved into a serial xUnit collection to prevent env-var races against StartHostActionTests. * Prep release 4.12.0-preview.1 (#5040) * Include native worker in minified builds (#5062) * Bump version to 4.12.0 * Improve Go support: preview signposting, async drain fix, and test coverage (#5102) Improve Go support: preview signposting, async drain fix, and test coverage ---- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Lilian Kasem <likasem@microsoft.com> --------- Co-authored-by: Harshitha Akkaraju <hakkaraj@microsoft.com> Co-authored-by: Lilian Kasem <likasem@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changes
worker runtime.