Skip to content

Commit 22394eb

Browse files
while1forkdmjb
andauthored
Add Windows support to Taskfiles (#1304)
My original motivation for this PR was that I was working on a different PR, wanted to manually test changes on Windows, and found that task build wouldn't even run. Therefore, this PR follows the "80/20 rule" to deliver the most improvement for the most users for a reasonable amount of effort. In other words, this does not fix every Windows issue in the project, but it does make sure the vast majority of tasks defined in the Taskfiles do now run correctly on both Windows and MacOS. Changes were tested on MacOS and Windows (given that Linux and MacOS have nearly the same command set, and no commands that actually run on MacOS were changed, so any tasks that ran correctly on Linux before should continue to). See details at the end of this description. This PR replaces Linux/MacOS-specific commands in Taskfile.yml and cmd/thv-operator/Taskfile.yml with cross-platform templating functions built into go-task (where possible) or platform-specific commands for both *nix and Windows where unavoidable. Note that the scope of these changes is limited to: ensuring that the task commands run correctly once dependencies are installed - for example, task test-e2e will fail if ginkgo is not installed (the same is true on MacOS) ensuring that the task commands run correctly on Windows, not that they necessarily run successfully ensuring that (nearly) all task commands which run correctly on MacOS also run correctly on Windows - some tasks were found to fail with the same errors on MacOS and Windows, and so were left as is Example 1: Before this change, on Windows, task test exited without running any tests. After this change, on Windows, task test runs unit tests ... but several of them fail. (This is an opportunity for further Windows improvements.) Example 2: task operator-test exits with "shell": executable file not found in $PATH on Windows. However, it exits with the same error on MacOS, so this was not addressed as it is outside the scope of making the Taskfiles cross-platform. Specific Notes / Exceptions: task lint: Fails with 8 lint issues on Windows task test: Several failing tests on Windows task test-e2e: 10 failing specs on Windows task operator-deploy-local: This is the big exception mentioned above. This looked like it would be a lot of effort, due to the lack of a tail equivalent in Windows, and also is a task that would probably only be used by a small number of fairly advanced developers who would know how to get this to work manually. For now, keeping the 80/20 rule in mind, at least this task is restricted to Linux and MacOS platforms, so rather than just exiting with an error, a user running this test on Windows will get a message that it isn't supported on Windows. Hopefully some advanced Windows / Kubernetes developer will fix this if they run into it. task operator-test: Exits with "shell": executable file not found in $PATH on Windows, but this is also the case on MacOS task operator-e2e-test: 1 test fails on Windows, but this is also the case on MacOS task crdref-gen: This task wasn't working on either Windows or MacOS, due to incorrect config file paths. This has now been fixed. looks like this is intended for CI, rather than local development, given that it's now failing there. Reverting. Closes #1217. Signed-off-by: Chris Gernon <[email protected]> Co-authored-by: Don Browne <[email protected]>
1 parent 386710d commit 22394eb

File tree

3 files changed

+196
-24
lines changed

3 files changed

+196
-24
lines changed

Taskfile.yml

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,93 @@ tasks:
3434
cmds:
3535
- golangci-lint run --fix ./...
3636

37-
test:
38-
desc: Run unit tests (excluding e2e tests)
37+
test-unixlike:
38+
desc: Run unit tests (excluding e2e tests) on Linux and macOS
39+
platforms: [linux, darwin]
40+
internal: true
3941
cmds:
4042
- go test -v $(go list ./... | grep -v '/test/e2e')
4143

42-
test-coverage:
43-
desc: Run unit tests with coverage analysis (excluding e2e tests)
44+
test-windows:
45+
desc: Run unit tests (excluding e2e tests) on Windows
46+
platforms: [windows]
47+
internal: true
48+
vars:
49+
DIR_LIST:
50+
sh: go list ./... | findstr -V "\/test\/e2e"
51+
cmds:
52+
- go test -v {{.DIR_LIST | catLines}}
53+
54+
test:
55+
desc: Run unit tests (excluding e2e tests)
56+
cmds:
57+
- task: test-unixlike
58+
platforms: [linux, darwin]
59+
- task: test-windows
60+
platforms: [windows]
61+
62+
test-coverage-unixlike:
63+
desc: Run unit tests with coverage analysis (excluding e2e tests) on Linux and macOS
64+
platforms: [linux, darwin]
65+
internal: true
4466
cmds:
45-
- mkdir -p coverage
67+
- cmd: mkdir -p coverage
68+
platforms: [linux, darwin]
4669
- go test -coverprofile=coverage/coverage.out $(go list ./... | grep -v '/test/e2e')
4770
- go tool cover -func=coverage/coverage.out
4871
- echo "Generating HTML coverage report in coverage/coverage.html"
4972
- go tool cover -html=coverage/coverage.out -o coverage/coverage.html
5073

74+
test-coverage-windows:
75+
desc: Run unit tests with coverage analysis (excluding e2e tests) on Windows
76+
platforms: [windows]
77+
internal: true
78+
vars:
79+
DIR_LIST:
80+
sh: go list ./... | findstr -V "\/test\/e2e"
81+
cmds:
82+
- cmd: cmd.exe /c mkdir coverage
83+
ignore_error: true # Windows has no mkdir -p, so just ignore error if it exists
84+
- go test -coverprofile=coverage/coverage.out {{.DIR_LIST | catLines}}
85+
- go tool cover -func=coverage/coverage.out
86+
- echo "Generating HTML coverage report in coverage/coverage.html"
87+
- go tool cover -html=coverage/coverage.out -o coverage/coverage.html
88+
89+
test-coverage:
90+
desc: Run unit tests with coverage analysis (excluding e2e tests)
91+
cmds:
92+
- task: test-coverage-unixlike
93+
platforms: [linux, darwin]
94+
- task: test-coverage-windows
95+
platforms: [windows]
96+
97+
test-e2e-unixlike:
98+
desc: Run end-to-end tests on Linux and macOS
99+
platforms: [linux, darwin]
100+
internal: true
101+
env:
102+
THV_BINARY: "{{.PWD}}/bin/thv"
103+
cmds:
104+
- ./test/e2e/run_tests.sh
105+
106+
test-e2e-windows:
107+
desc: Run end-to-end tests on Windows
108+
platforms: [windows]
109+
internal: true
110+
env:
111+
THV_BINARY: "{{.ROOT_DIR}}\\bin\\thv.exe"
112+
cmds:
113+
- cmd: .\\test\\e2e\\run_tests.bat
114+
51115
test-e2e:
52116
desc: Run end-to-end tests
53117
deps: [build]
54-
env:
55-
THV_BINARY: "{{.PWD}}/bin/thv"
56118
cmds:
57119
- go install github.com/onsi/ginkgo/v2/ginkgo
58-
- ./test/e2e/run_tests.sh
120+
- task: test-e2e-unixlike
121+
platforms: [linux, darwin]
122+
- task: test-e2e-windows
123+
platforms: [windows]
59124

60125
test-all:
61126
desc: Run all tests (unit and e2e)
@@ -68,12 +133,17 @@ tasks:
68133
sh: git describe --tags --always --dirty --match "v*" || echo "dev"
69134
COMMIT:
70135
sh: git rev-parse --short HEAD || echo "unknown"
71-
BUILD_DATE:
72-
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
136+
BUILD_DATE: '{{dateInZone "2006-01-02T15:04:05Z" (now) "UTC"}}'
73137
cmds:
74-
- mkdir -p bin
75-
- go build -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -o bin/thv ./cmd/thv
76-
138+
- cmd: mkdir -p bin
139+
platforms: [linux, darwin]
140+
- cmd: go build -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -o bin/thv ./cmd/thv
141+
platforms: [linux, darwin]
142+
- cmd: cmd.exe /c mkdir bin
143+
platforms: [windows]
144+
ignore_error: true # Windows has no mkdir -p, so just ignore error if it exists
145+
- cmd: go build -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -o bin/thv.exe ./cmd/thv
146+
platforms: [windows]
77147

78148
install:
79149
desc: Install the thv binary to GOPATH/bin
@@ -82,8 +152,7 @@ tasks:
82152
sh: git describe --tags --always --dirty --match "v*" || echo "dev"
83153
COMMIT:
84154
sh: git rev-parse --short HEAD || echo "unknown"
85-
BUILD_DATE:
86-
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
155+
BUILD_DATE: '{{dateInZone "2006-01-02T15:04:05Z" (now) "UTC"}}'
87156
cmds:
88157
- go install -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -v ./cmd/thv
89158

cmd/thv-operator/Taskfile.yml

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ version: '3'
22

33
vars:
44
CRD_DIR: config/crd/bases
5+
# Don't change the following 2 paths - they fail locally, but are needed for CI in Github
56
DOCS_OUT: ../../docs/operator/crd-api.md
67
CRDREF_CONFIG: ../../docs/operator/crd-ref-config.yaml
78
OCP_REGISTRY_ROUTE:
@@ -35,7 +36,10 @@ tasks:
3536
desc: Destroy a local Kind cluster
3637
cmds:
3738
- kind delete cluster --name toolhive
38-
- rm kconfig.yaml
39+
- cmd: rm kconfig.yaml
40+
platforms: [linux, darwin]
41+
- cmd: cmd.exe /c "del kconfig.yaml"
42+
platforms: [windows]
3943

4044
kind-ingress-setup:
4145
desc: Setup Nginx Ingress Controller in a local Kind cluster
@@ -74,11 +78,17 @@ tasks:
7478
sh: git describe --tags --always --dirty || echo "dev"
7579
COMMIT:
7680
sh: git rev-parse --short HEAD || echo "unknown"
77-
BUILD_DATE:
78-
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
81+
BUILD_DATE: '{{dateInZone "2006-01-02T15:04:05Z" (now) "UTC"}}'
7982
cmds:
80-
- mkdir -p bin
81-
- go build -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -o bin/thv-operator ./cmd/thv-operator
83+
- cmd: mkdir -p bin
84+
platforms: [linux, darwin]
85+
- cmd: go build -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -o bin/thv-operator ./cmd/thv-operator
86+
platforms: [linux, darwin]
87+
- cmd: cmd.exe /c mkdir bin
88+
platforms: [windows]
89+
ignore_error: true # Windows has no mkdir -p, so just ignore error if it exists
90+
- cmd: go build -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -o bin/thv-operator.exe ./cmd/thv-operator
91+
platforms: [windows]
8292

8393
install-operator:
8494
desc: Install the thv-operator binary to GOPATH/bin
@@ -87,8 +97,7 @@ tasks:
8797
sh: git describe --tags --always --dirty || echo "dev"
8898
COMMIT:
8999
sh: git rev-parse --short HEAD || echo "unknown"
90-
BUILD_DATE:
91-
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
100+
BUILD_DATE: '{{dateInZone "2006-01-02T15:04:05Z" (now) "UTC"}}'
92101
cmds:
93102
- go install -ldflags "-s -w -X github.com/stacklok/toolhive/pkg/versions.Version={{.VERSION}} -X github.com/stacklok/toolhive/pkg/versions.Commit={{.COMMIT}} -X github.com/stacklok/toolhive/pkg/versions.BuildDate={{.BUILD_DATE}}" -v ./cmd/thv-operator
94103

@@ -114,6 +123,7 @@ tasks:
114123

115124
operator-deploy-local:
116125
desc: Build the ToolHive runtime and Operator image locally and deploy it to the K8s cluster
126+
platforms: [linux, darwin]
117127
vars:
118128
OPERATOR_IMAGE:
119129
sh: KO_DOCKER_REPO=kind.local ko build --local -B ./cmd/thv-operator | tail -n 1
@@ -142,14 +152,22 @@ tasks:
142152
operator-generate:
143153
desc: Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations
144154
cmds:
145-
- mkdir -p bin
155+
- cmd: mkdir -p bin
156+
platforms: [linux, darwin]
157+
- cmd: cmd.exe /c mkdir bin
158+
platforms: [windows]
159+
ignore_error: true # Windows has no mkdir -p, so just ignore error if it exists
146160
- go install sigs.k8s.io/controller-tools/cmd/[email protected]
147161
- $(go env GOPATH)/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./cmd/thv-operator/..."
148162

149163
operator-manifests:
150164
desc: Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects
151165
cmds:
152-
- mkdir -p bin
166+
- cmd: mkdir -p bin
167+
platforms: [linux, darwin]
168+
- cmd: cmd.exe /c mkdir bin
169+
platforms: [windows]
170+
ignore_error: true # Windows has no mkdir -p, so just ignore error if it exists
153171
- go install sigs.k8s.io/controller-tools/cmd/[email protected]
154172
- $(go env GOPATH)/bin/controller-gen crd webhook paths="./cmd/thv-operator/..." output:crd:artifacts:config=deploy/charts/operator-crds/templates
155173
- $(go env GOPATH)/bin/controller-gen rbac:roleName=toolhive-operator-manager-role paths="./cmd/thv-operator/..." output:rbac:artifacts:config=deploy/charts/operator/templates/clusterrole

test/e2e/run_tests.bat

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
@echo off
2+
setlocal enabledelayedexpansion
3+
4+
REM E2E Test Runner for ToolHive
5+
REM This script sets up the environment and runs the e2e tests
6+
7+
REM Set error handling
8+
set "EXIT_CODE=0"
9+
10+
echo ToolHive E2E Test Runner
11+
echo ================================
12+
13+
REM Set TOOLHIVE_DEV environment variable to true
14+
set "TOOLHIVE_DEV=true"
15+
16+
REM Check if thv binary exists
17+
if "%THV_BINARY%"=="" (
18+
set "THV_BINARY=thv.exe"
19+
where "%THV_BINARY%" >nul 2>&1
20+
) else (
21+
dir "%THV_BINARY%" >nul 2>&1
22+
)
23+
if %errorlevel% neq 0 (
24+
echo Error: thv binary not found in PATH
25+
echo Please build the binary first with: task build
26+
echo Or set THV_BINARY environment variable to the binary path
27+
exit /b 1
28+
)
29+
30+
echo ✓ Found thv binary: %THV_BINARY%
31+
32+
REM Check if container runtime is available
33+
set "CONTAINER_RUNTIME="
34+
where docker >nul 2>&1
35+
if %errorlevel% equ 0 (
36+
set "CONTAINER_RUNTIME=docker"
37+
echo ✓ Found container runtime: docker
38+
) else (
39+
where podman >nul 2>&1
40+
if %errorlevel% equ 0 (
41+
set "CONTAINER_RUNTIME=podman"
42+
echo ✓ Found container runtime: podman
43+
) else (
44+
echo Error: Neither docker nor podman found
45+
echo Please install docker or podman to run MCP servers
46+
exit /b 1
47+
)
48+
)
49+
50+
REM Set test timeout
51+
if "%TEST_TIMEOUT%"=="" set "TEST_TIMEOUT=20m"
52+
echo ✓ Test timeout: %TEST_TIMEOUT%
53+
54+
REM Export environment variables for tests
55+
set "THV_BINARY=%THV_BINARY%"
56+
set "TEST_TIMEOUT=%TEST_TIMEOUT%"
57+
58+
echo.
59+
echo Running E2E Tests...
60+
echo.
61+
62+
REM Run the tests
63+
cd /d "%~dp0"
64+
65+
REM Build ginkgo command with conditional GitHub output flag
66+
set "GINKGO_CMD=ginkgo run --timeout=%TEST_TIMEOUT%"
67+
if defined GITHUB_ACTIONS (
68+
echo ✓ GitHub Actions detected, enabling GitHub output format
69+
set "GINKGO_CMD=%GINKGO_CMD% --github-output"
70+
) else (
71+
set "GINKGO_CMD=%GINKGO_CMD% --vv --show-node-events --trace"
72+
)
73+
set "GINKGO_CMD=%GINKGO_CMD% ."
74+
75+
REM Execute the ginkgo command
76+
%GINKGO_CMD%
77+
if %errorlevel% equ 0 (
78+
echo.
79+
echo ✓ All E2E tests passed!
80+
exit /b 0
81+
) else (
82+
echo.
83+
echo ✗ Some E2E tests failed
84+
exit /b 1
85+
)

0 commit comments

Comments
 (0)