Przeglądaj źródła

tool: add go toolchain wrapper for Windows

go.cmd lets you run just "./tool/go" on Windows the same as Linux/Darwin.

The batch script (go.md) then just invokes PowerShell which is more
powerful than batch.

I wanted this while debugging Windows CI performance by reproducing slow
tests on my local Windows laptop.

Updates tailscale/corp#28679

Change-Id: I6e520968da3cef3032091c1c4f4237f663cefcab
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 8 miesięcy temu
rodzic
commit
bb085cfa3e
3 zmienionych plików z 81 dodań i 1 usunięć
  1. 15 1
      .github/workflows/test.yml
  2. 2 0
      tool/go.cmd
  3. 64 0
      tool/go.ps1

+ 15 - 1
.github/workflows/test.yml

@@ -220,6 +220,8 @@ jobs:
         include:
         include:
           - key: "win-bench"
           - key: "win-bench"
             name: "benchmarks"
             name: "benchmarks"
+          - key: "win-tool-go"
+            name: "./tool/go"
           - key: "win-shard-1-2"
           - key: "win-shard-1-2"
             shard: "1/2"
             shard: "1/2"
           - key: "win-shard-2-2"
           - key: "win-shard-2-2"
@@ -231,12 +233,14 @@ jobs:
         path: src
         path: src
 
 
     - name: Install Go
     - name: Install Go
+      if: matrix.key != 'win-tool-go'
       uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
       uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
       with:
       with:
         go-version-file: src/go.mod
         go-version-file: src/go.mod
         cache: false
         cache: false
 
 
     - name: Restore Go module cache
     - name: Restore Go module cache
+      if: matrix.key != 'win-tool-go'
       uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
       uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
       with:
       with:
         path: gomodcache
         path: gomodcache
@@ -244,6 +248,7 @@ jobs:
         enableCrossOsArchive: true
         enableCrossOsArchive: true
 
 
     - name: Restore Cache
     - name: Restore Cache
+      if: matrix.key != 'win-tool-go'
       uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
       uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
       with:
       with:
         path: |
         path: |
@@ -255,10 +260,17 @@ jobs:
         restore-keys: |
         restore-keys: |
           ${{ github.job }}-${{ matrix.key }}-go-2-${{ hashFiles('**/go.sum') }}
           ${{ github.job }}-${{ matrix.key }}-go-2-${{ hashFiles('**/go.sum') }}
           ${{ github.job }}-${{ matrix.key }}-go-2-
           ${{ github.job }}-${{ matrix.key }}-go-2-
+
+    - name: test-tool-go
+      if: matrix.key == 'win-tool-go'
+      working-directory: src
+      run: ./tool/go version
+
     - name: test
     - name: test
-      if: matrix.key != 'win-bench' # skip on bench builder
+      if: matrix.key != 'win-bench' && matrix.key != 'win-tool-go' # skip on bench builder
       working-directory: src
       working-directory: src
       run: go run ./cmd/testwrapper sharded:${{ matrix.shard }}
       run: go run ./cmd/testwrapper sharded:${{ matrix.shard }}
+
     - name: bench all
     - name: bench all
       if: matrix.key == 'win-bench'
       if: matrix.key == 'win-bench'
       working-directory: src
       working-directory: src
@@ -266,7 +278,9 @@ jobs:
       # Somewhere in the layers (powershell?)
       # Somewhere in the layers (powershell?)
       # the equals signs cause great confusion.
       # the equals signs cause great confusion.
       run: go test ./... -bench . -benchtime 1x -run "^$"
       run: go test ./... -bench . -benchtime 1x -run "^$"
+
     - name: Tidy cache
     - name: Tidy cache
+      if: matrix.key != 'win-tool-go'
       working-directory: src
       working-directory: src
       shell: bash
       shell: bash
       run: |
       run: |

+ 2 - 0
tool/go.cmd

@@ -0,0 +1,2 @@
+@echo off
+powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0go.ps1" %*

+ 64 - 0
tool/go.ps1

@@ -0,0 +1,64 @@
+<#
+  go.ps1 – Tailscale Go toolchain fetching wrapper for Windows/PowerShell
+  • Reads go.toolchain.rev one dir above this script
+  • If the requested commit hash isn't cached, downloads and unpacks
+    https://github.com/tailscale/go/releases/download/build-${REV}/${OS}-${ARCH}.tar.gz
+  • Finally execs the toolchain's "go" binary, forwarding all args & exit-code
+#>
+
+param(
+    [Parameter(ValueFromRemainingArguments = $true)]
+    [string[]] $Args
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+if ($env:CI -eq 'true' -and $env:NODEBUG -ne 'true') {
+    $VerbosePreference = 'Continue'
+}
+
+$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..')
+$REV      = (Get-Content (Join-Path $repoRoot 'go.toolchain.rev') -Raw).Trim()
+
+if ([IO.Path]::IsPathRooted($REV)) {
+    $toolchain = $REV
+} else {
+    if (-not [string]::IsNullOrWhiteSpace($env:TSGO_CACHE_ROOT)) {
+        $cacheRoot = $env:TSGO_CACHE_ROOT
+    } else {
+        $cacheRoot = Join-Path $env:USERPROFILE '.cache\tsgo'
+    }
+
+    $toolchain = Join-Path $cacheRoot $REV
+    $marker    = "$toolchain.extracted"
+
+    if (-not (Test-Path $marker)) {
+        Write-Host "# Downloading Go toolchain $REV" -ForegroundColor Cyan
+        if (Test-Path $toolchain) { Remove-Item -Recurse -Force $toolchain }
+
+        # Removing the marker file again (even though it shouldn't still exist)
+        # because the equivalent Bash script also does so (to guard against
+        # concurrent cache fills?).
+        # TODO(bradfitz): remove this and add some proper locking instead?
+        if (Test-Path $marker   ) { Remove-Item -Force $marker    }
+
+        New-Item -ItemType Directory -Path $cacheRoot -Force | Out-Null
+
+        $url  = "https://github.com/tailscale/go/releases/download/build-$REV/windows-amd64.tar.gz"
+        $tgz  = "$toolchain.tar.gz"
+        Invoke-WebRequest -Uri $url -OutFile $tgz -UseBasicParsing -ErrorAction Stop
+
+        New-Item -ItemType Directory -Path $toolchain -Force | Out-Null
+        tar --strip-components=1 -xzf $tgz -C $toolchain
+        Remove-Item $tgz
+        Set-Content -Path $marker -Value $REV
+    }
+}
+
+$goExe = Join-Path $toolchain 'bin\go.exe'
+if (-not (Test-Path $goExe)) { throw "go executable not found at $goExe" }
+
+& $goExe @Args
+exit $LASTEXITCODE
+