Skip to content

Commit 21d180f

Browse files
harshivcodesliliankasemCopilot
authored
Add go support (preview) (#5093)
* 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>
1 parent 956e953 commit 21d180f

54 files changed

Lines changed: 2464 additions & 58 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

eng/build/Minified.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<_LanguageWorkers Include="$(PublishDir)\workers\java" />
77
<_LanguageWorkers Include="$(PublishDir)\workers\powershell" />
88
<_LanguageWorkers Include="$(PublishDir)\workers\node" />
9+
<_LanguageWorkers Include="$(PublishDir)\workers\native" />
910
</ItemGroup>
1011

1112
<!-- Remove worker directories from minified builds -->

eng/build/Workers.Golang.targets

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project>
2+
3+
<!--
4+
Ships the Go (native) worker config alongside the published CLI so the host
5+
can discover the Go worker at workers/native/worker.config.json.
6+
-->
7+
<ItemGroup>
8+
<Content Include="$(RepoRoot)src\Cli\func\StaticResources\nativeWorkerConfig.json">
9+
<Link>workers\native\worker.config.json</Link>
10+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
11+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
12+
</Content>
13+
</ItemGroup>
14+
15+
</Project>

eng/ci/official-build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ variables:
3737
extends:
3838
template: v1/1ES.Official.PipelineTemplate.yml@1es
3939
parameters:
40+
# Route 'go' CLI traffic through the centralized internal Go module proxy
41+
# so GoZipTool builds can resolve modules in network-isolated CI agents.
42+
# See https://aka.ms/goproxy_for_how_to_onboard
43+
featureFlags:
44+
golang:
45+
internalModuleProxy:
46+
enabled: true
4047
pool:
4148
name: 1es-pool-azfunc
4249
image: 1es-windows-2022

eng/ci/public-build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ variables:
3232
extends:
3333
template: v1/1ES.Unofficial.PipelineTemplate.yml@1es
3434
parameters:
35+
# Route 'go' CLI traffic through the centralized internal Go module proxy
36+
# so unit tests / E2E tests / GoZipTool builds can resolve modules in
37+
# network-isolated CI agents. See https://aka.ms/goproxy_for_how_to_onboard
38+
featureFlags:
39+
golang:
40+
internalModuleProxy:
41+
enabled: true
3542
pool:
3643
name: 1es-pool-azfunc-public
3744
image: 1es-windows-2022

eng/ci/templates/jobs/test-e2e-linux.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,22 @@ jobs:
2525
custom_linux_x64:
2626
languageWorker: 'Custom'
2727
runtime: 'linux-x64'
28+
go_linux_x64:
29+
languageWorker: 'Go'
30+
runtime: 'linux-x64'
2831

2932
steps:
3033
- template: /eng/ci/templates/steps/install-tools.yml@self
3134

35+
# The 1es-ubuntu-24.04-min image doesn't ship npm. NodeTool@0 in install-tools.yml
36+
# installs Node into the agent user's tool cache, but start-emulators.ps1 runs
37+
# `sudo npm install -g azurite` and sudo's PATH doesn't include the tool cache.
38+
# Install npm system-wide via apt so azurite can be installed and launched as root.
3239
- bash: |
3340
sudo apt-get update
34-
sudo apt-get install -y npm golang
41+
sudo apt-get install -y npm
3542
npm --version
36-
go version
37-
displayName: 'Install npm and Go'
43+
displayName: 'Install npm'
3844
3945
- pwsh: ./eng/scripts/start-emulators.ps1
4046
displayName: 'Start emulators (NoWait)'

eng/ci/templates/jobs/test-e2e-osx.yml

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,40 @@ jobs:
2525
custom_osx_x64:
2626
languageWorker: 'Custom'
2727
runtime: 'osx-x64'
28+
go_osx_x64:
29+
languageWorker: 'Go'
30+
runtime: 'osx-x64'
2831

2932
steps:
3033
- pwsh: ./eng/scripts/start-emulators.ps1
3134
displayName: 'Start emulators (NoWait)'
3235

33-
- script: |
34-
brew install go
35-
go version
36-
displayName: 'Install Go'
37-
3836
- script: |
3937
sudo chown -R $(id -u):$(id -g) ~/.npm
4038
npm install -g @azure/functions
4139
displayName: 'Install @azure/functions'
4240
4341
- template: /eng/ci/templates/steps/install-tools.yml@self
4442

43+
# On macOS, GoTool@0 (in install-tools.yml) is skipped because it only
44+
# ships an amd64 Go binary, which can't run on Apple Silicon agents.
45+
# Install an arm64-native Go via Homebrew, pinned to the same major.minor
46+
# (1.24) used by GoTool@0 on Linux/Windows, so all three OSes test against
47+
# a consistent Go version.
48+
- bash: |
49+
set -euo pipefail
50+
brew install go@1.24
51+
GO_PREFIX="$(brew --prefix go@1.24)"
52+
GO_BIN="$GO_PREFIX/bin"
53+
GO_ROOT="$GO_PREFIX/libexec"
54+
# Pin GOROOT to the Homebrew install so the `go` binary doesn't pick up a
55+
# stale GOROOT inherited from the hosted agent image (which can point at a
56+
# different Go install and cause "package std not found" / version skew).
57+
echo "##vso[task.prependpath]$GO_BIN"
58+
echo "##vso[task.setvariable variable=GOROOT]$GO_ROOT"
59+
GOROOT="$GO_ROOT" "$GO_BIN/go" version
60+
displayName: 'Install Go 1.24 (Homebrew, arm64-native)'
61+
4562
- template: /eng/ci/templates/steps/restore-nuget.yml@self
4663

4764
- pwsh: |

eng/ci/templates/jobs/test-e2e-windows.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ jobs:
2525
custom_win_x64:
2626
languageWorker: 'Custom'
2727
runtime: 'win-x64'
28+
go_win_x64:
29+
languageWorker: 'Go'
30+
runtime: 'win-x64'
2831

2932
steps:
3033
- pwsh: ./eng/scripts/start-emulators.ps1 -NoWait

eng/ci/templates/public/jobs/test-unit-linux.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ jobs:
1919
sudo apt-get -y install fuse-zip
2020
displayName: 'Install fuse-zip'
2121
22+
- script: |
23+
set -e
24+
VERSION=1.24.2
25+
ARCHIVE=go${VERSION}.linux-amd64.tar.gz
26+
DEST="$AGENT_TOOLSDIRECTORY/go-${VERSION}"
27+
mkdir -p "$DEST"
28+
curl -fsSL "https://go.dev/dl/${ARCHIVE}" -o "$AGENT_TEMPDIRECTORY/${ARCHIVE}"
29+
tar -C "$DEST" -xzf "$AGENT_TEMPDIRECTORY/${ARCHIVE}"
30+
echo "##vso[task.prependpath]$DEST/go/bin"
31+
displayName: 'Install Go 1.24.2'
32+
2233
- template: /eng/ci/templates/steps/install-tools.yml@self
2334

2435
- template: /eng/ci/templates/steps/restore-nuget.yml@self

eng/ci/templates/steps/install-tools.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,31 @@ steps:
3838
inputs:
3939
packageType: sdk
4040
useGlobalJson: true
41+
42+
- pwsh: |
43+
$version = '1.24.2'
44+
if ($IsWindows) {
45+
$archive = "go$version.windows-amd64.zip"
46+
$url = "https://go.dev/dl/$archive"
47+
$dest = Join-Path $env:AGENT_TOOLSDIRECTORY "go-$version"
48+
New-Item -ItemType Directory -Force -Path $dest | Out-Null
49+
$zipPath = Join-Path $env:AGENT_TEMPDIRECTORY $archive
50+
Invoke-WebRequest -Uri $url -OutFile $zipPath
51+
Expand-Archive -Path $zipPath -DestinationPath $dest -Force
52+
$goBin = Join-Path $dest 'go\bin'
53+
} else {
54+
$archive = "go$version.linux-amd64.tar.gz"
55+
$url = "https://go.dev/dl/$archive"
56+
$dest = Join-Path $env:AGENT_TOOLSDIRECTORY "go-$version"
57+
New-Item -ItemType Directory -Force -Path $dest | Out-Null
58+
$tarPath = Join-Path $env:AGENT_TEMPDIRECTORY $archive
59+
Invoke-WebRequest -Uri $url -OutFile $tarPath
60+
& tar -C $dest -xzf $tarPath
61+
$goBin = Join-Path $dest 'go/bin'
62+
}
63+
Write-Host "##vso[task.prependpath]$goBin"
64+
Write-Host "Installed Go $version to $goBin"
65+
displayName: 'Install Go 1.24.2'
66+
# Skip on macOS: macOS-latest is arm64 (Apple Silicon). Mac jobs that need
67+
# Go install it via Homebrew themselves (see test-e2e-osx.yml).
68+
condition: ne(variables['Agent.OS'], 'Darwin')

release_notes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Azure Functions CLI 4.11.1
1+
# Azure Functions CLI 4.12.0
22

33
#### Host Version
44

@@ -11,3 +11,4 @@
1111

1212
- Fix `HttpsProxyAgent is not a constructor` error in `install.js` when installing behind a proxy (https-proxy-agent v9 requires a named import).
1313
- Remove `azure-functions-core-tools` from the `devDependencies` of generated function app templates (`package-js.json`, `package-js-v4.json`, `package-ts.json`, `package-ts-v4.json`). Users get the CLI from their system install; pulling it in again via `npm install` doubled disk usage and made every project's install fragile to Core Tools postinstall regressions.
14+
- Add **preview** Go language support to `func init`, `func start`, `func pack`, and `func publish` (#4875, #4892, #4943). Behaviour, build/publish flags, and deployment layout may change before GA.

0 commit comments

Comments
 (0)