Windows compatibility fixes #1152

Merged
mfenniak merged 16 commits from windows/runner:feature/windows-specific-fixes into main 2025-11-16 15:56:57 +00:00
Contributor

This PR contains two fixes to the production code:

  • 20d56ace53adf26f66e7eb14f3f899087aec70eb fixes the hashFile function in an action misinterpreting paths on Windows
  • 4e2609329dc2e3e630a67c3237e38a92dd7dc784 fixes the validate command outputting full paths due to OS-unspecific path trimming logic

The remaining changes adopt tests to properly deal with

  • Docker with Linux containers not being available on standard Windows runners c492fe121e2f2d2eb6dbc8fd5b1cef543437fa99
  • Windows paths (6781d823683428d5cf8b9bac4753a458882b5994), (8ca14d0f4d4274e808fb027e021bac701279381e), (eb70aca72c89c08cdc03c35dd26f3e57bdeaacac), (4e2609329dc2e3e630a67c3237e38a92dd7dc784), (c00d4e0a81634c098086b822884eb6b525ebe933)
  • Revert a change causing a test-runner panic on Windows (6608fec705f7e7ed48c7ffed3839f2b4c4c1defb)
  • Exclude the daemon suicide test because it cannot be properly observed on Windows (3ef33b93b6c3422ce47325bc5330d2d954998cf4)

or in one case separate dedicated Windows and Linux test setups (709a1d3fdbfc8a6149a57fcf00570e842ef4d040)

I tried to keep the changes as minimal as possible and focussed on getting the tests to run again.
I only added skips for tests that I could not get to run due to the Docker requirements, or the different shutdown behaviors on Linux and Windows.

In the future, I will investigate why the defensive chdir in linux_container_environment_extensions_test.go (6608fec705f7e7ed48c7ffed3839f2b4c4c1defb) is necessary and whether I can get all of the docker tests (c492fe121e2f2d2eb6dbc8fd5b1cef543437fa99) to run on GitHub Actions

The passing of all tests on windows has been confirmed here.

  • other
    • PR: Windows compatibility fixes
This PR contains two fixes to the production code: - 20d56ace53adf26f66e7eb14f3f899087aec70eb fixes the `hashFile` function in an action misinterpreting paths on Windows - 4e2609329dc2e3e630a67c3237e38a92dd7dc784 fixes the `validate` command outputting full paths due to OS-unspecific path trimming logic The remaining changes adopt tests to properly deal with - Docker with Linux containers not being available on standard Windows runners c492fe121e2f2d2eb6dbc8fd5b1cef543437fa99 - Windows paths (6781d823683428d5cf8b9bac4753a458882b5994), (8ca14d0f4d4274e808fb027e021bac701279381e), (eb70aca72c89c08cdc03c35dd26f3e57bdeaacac), (4e2609329dc2e3e630a67c3237e38a92dd7dc784), (c00d4e0a81634c098086b822884eb6b525ebe933) - Revert a change causing a test-runner panic on Windows (6608fec705f7e7ed48c7ffed3839f2b4c4c1defb) - Exclude the daemon suicide test because it cannot be properly observed on Windows (3ef33b93b6c3422ce47325bc5330d2d954998cf4) or in one case separate dedicated Windows and Linux test setups (709a1d3fdbfc8a6149a57fcf00570e842ef4d040) I tried to keep the changes as minimal as possible and focussed on getting the tests to run again. I only added skips for tests that I could not get to run due to the Docker requirements, or the different shutdown behaviors on Linux and Windows. In the future, I will investigate why the defensive `chdir` in `linux_container_environment_extensions_test.go` (6608fec705f7e7ed48c7ffed3839f2b4c4c1defb) is necessary and whether I can get all of the docker tests (c492fe121e2f2d2eb6dbc8fd5b1cef543437fa99) to run on GitHub Actions The passing of all tests on windows has been confirmed [here](https://github.com/Crown0815/Forgejo-runner-windows-builder/actions/runs/19344650459). <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - other - [PR](https://code.forgejo.org/forgejo/runner/pulls/1152): <!--number 1152 --><!--line 0 --><!--description V2luZG93cyBjb21wYXRpYmlsaXR5IGZpeGVz-->Windows compatibility fixes<!--description--> <!--end release-notes-assistant-->
Author
Contributor

Well, I guess I figured out the reason for 0520ff4e05 ...

Well, I guess I figured out [the reason](https://code.forgejo.org/forgejo/runner/actions/runs/12177/jobs/0/attempt/1#jobstep-8-193) for 0520ff4e05f2c4d21888fbc5afbff347ce096f17 ...
Author
Contributor

The issue is reproducible (on Windows) with just this test:

func TestPath(t *testing.T) {
	t.Chdir("/")
}

which will crash the test runner with: "testing.Chdir: chdir .: The system cannot find the path specified."

The issue is reproducible (on Windows) with just this test: ```go func TestPath(t *testing.T) { t.Chdir("/") } ``` which will crash the test runner with: "testing.Chdir: chdir .: The system cannot find the path specified."
viceice approved these changes 2025-11-13 20:56:58 +00:00
Dismissed
viceice left a comment

we should configure wine and run windows tests under it if zrypossible 🤔

we should configure wine and run windows tests under it if zrypossible 🤔
Owner

still a failing test

still a failing test
Author
Contributor

The issue is the os.Open(".") (in the implementation of t.Chdir()) is not behaving well on Windows:

func TestPath(t *testing.T) {
	oldwd, _ := os.Open(".")
	err := oldwd.Chdir()
	oldwd.Close()
	if err != nil {
		panic("testing.Chdir: " + err.Error())
	}
}

This test fails with panic: testing.Chdir: chdir .: The system cannot find the path specified. [recovered, repanicked].
This explains, why the original tests were the way they were.

The lint error in the build and test check is therefore incorrect.

How can I suppress it? I think I got it

The issue is the `os.Open(".")` (in the implementation of `t.Chdir()`) is not behaving well on Windows: ``` func TestPath(t *testing.T) { oldwd, _ := os.Open(".") err := oldwd.Chdir() oldwd.Close() if err != nil { panic("testing.Chdir: " + err.Error()) } } ``` This test fails with `panic: testing.Chdir: chdir .: The system cannot find the path specified. [recovered, repanicked]`. This explains, why the original tests were the way they were. The [lint error](https://code.forgejo.org/forgejo/runner/actions/runs/12177/jobs/0/attempt/1#jobstep-8-190) in the build and test check is therefore incorrect. ~~How can I suppress it?~~ I think I got it
Author
Contributor

@viceice wrote in #1152 (comment):

we should configure wine and run windows tests under it if zrypossible 🤔

Do you feel the tests run on GitHub are not sufficient? I was given to understand that this repository should remain free of Windows specific testing.

@viceice wrote in https://code.forgejo.org/forgejo/runner/pulls/1152#issuecomment-66459: > we should configure wine and run windows tests under it if zrypossible :thinking: Do you feel the tests run on [GitHub](https://github.com/Crown0815/Forgejo-runner-windows-builder/actions/runs/19344650459) are not sufficient? I was given to understand that this repository should remain free of Windows specific testing.
Crown0815 force-pushed feature/windows-specific-fixes from 251f29ba2e
Some checks failed
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
issue-labels / release-notes (pull_request_target) Successful in 5s
checks / validate mocks (pull_request) Failing after 30s
checks / build and test (pull_request) Failing after 42s
checks / validate pre-commit-hooks file (pull_request) Successful in 37s
checks / runner exec tests (pull_request) Has been skipped
checks / runner integration tests (pull_request) Has been skipped
example / docker-build-push-action-in-lxc (pull_request) Successful in 1m32s
Integration tests for the release process / release-simulation (pull_request) Successful in 4m29s
/ example-lxc-systemd (pull_request) Successful in 6m55s
checks / integration tests (pull_request) Successful in 12m20s
to bd79ed196c
Some checks failed
checks / build and test (pull_request) Failing after 45s
checks / validate mocks (pull_request) Failing after 32s
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
checks / validate pre-commit-hooks file (pull_request) Successful in 37s
issue-labels / release-notes (pull_request_target) Successful in 4s
example / docker-build-push-action-in-lxc (pull_request) Successful in 1m41s
Integration tests for the release process / release-simulation (pull_request) Successful in 5m13s
checks / runner exec tests (pull_request) Has been skipped
checks / runner integration tests (pull_request) Has been skipped
/ example-lxc-systemd (pull_request) Successful in 7m12s
checks / integration tests (pull_request) Successful in 12m12s
2025-11-13 21:34:11 +00:00
Compare
Crown0815 force-pushed feature/windows-specific-fixes from bd79ed196c
Some checks failed
checks / build and test (pull_request) Failing after 45s
checks / validate mocks (pull_request) Failing after 32s
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
checks / validate pre-commit-hooks file (pull_request) Successful in 37s
issue-labels / release-notes (pull_request_target) Successful in 4s
example / docker-build-push-action-in-lxc (pull_request) Successful in 1m41s
Integration tests for the release process / release-simulation (pull_request) Successful in 5m13s
checks / runner exec tests (pull_request) Has been skipped
checks / runner integration tests (pull_request) Has been skipped
/ example-lxc-systemd (pull_request) Successful in 7m12s
checks / integration tests (pull_request) Successful in 12m12s
to 919e5c9f1a
Some checks failed
example / docker-build-push-action-in-lxc (pull_request) Successful in 1m36s
checks / validate mocks (pull_request) Successful in 29s
checks / build and test (pull_request) Failing after 2m47s
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
issue-labels / release-notes (pull_request_target) Successful in 8s
checks / validate pre-commit-hooks file (pull_request) Successful in 37s
checks / runner exec tests (pull_request) Has been skipped
checks / runner integration tests (pull_request) Has been skipped
Integration tests for the release process / release-simulation (pull_request) Successful in 5m16s
/ example-lxc-systemd (pull_request) Successful in 6m59s
checks / integration tests (pull_request) Successful in 11m31s
2025-11-13 21:34:56 +00:00
Compare
Author
Contributor

Is this failure a problem with the runner or something I can influence?

Is [this failure](https://code.forgejo.org/forgejo/runner/actions/runs/12205/jobs/3/attempt/1#jobstep-5-1) a problem with the runner or something I can influence?
Crown0815 force-pushed feature/windows-specific-fixes from e3f3a3fe0b
Some checks failed
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
issue-labels / release-notes (pull_request_target) Successful in 6s
checks / validate mocks (pull_request) Successful in 1m11s
checks / validate pre-commit-hooks file (pull_request) Successful in 1m10s
example / docker-build-push-action-in-lxc (pull_request) Successful in 2m5s
checks / build and test (pull_request) Successful in 4m14s
checks / runner exec tests (pull_request) Successful in 38s
checks / runner integration tests (pull_request) Failing after 1m19s
Integration tests for the release process / release-simulation (pull_request) Successful in 6m14s
/ example-lxc-systemd (pull_request) Successful in 8m7s
checks / integration tests (pull_request) Successful in 13m47s
to 8029ba6983
All checks were successful
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
issue-labels / release-notes (pull_request_target) Successful in 5s
checks / validate mocks (pull_request) Successful in 30s
checks / validate pre-commit-hooks file (pull_request) Successful in 30s
checks / build and test (pull_request) Successful in 40s
checks / runner exec tests (pull_request) Successful in 26s
checks / runner integration tests (pull_request) Successful in 5m3s
checks / integration tests (pull_request) Successful in 10m23s
2025-11-14 08:59:01 +00:00
Compare
Owner

@Crown0815 wrote in #1152 (comment):

@viceice wrote in #1152 (comment):

we should configure wine and run windows tests under it if zrypossible 🤔

Do you feel the tests run on GitHub are not sufficient? I was given to understand that this repository should remain free of Windows specific testing.

Wine is free and a windows compabillity layer on linux to run windows programs.
So if you're interested in a ci job here which runs tests with wine and some e2e tests with forgejo (linux) and runner (windows, wine) then we can maybe official support compiling runner for windows on release. 🤔

@Crown0815 wrote in https://code.forgejo.org/forgejo/runner/pulls/1152#issuecomment-66462: > @viceice wrote in #1152 (comment): > > > we should configure wine and run windows tests under it if zrypossible :thinking: > > Do you feel the tests run on [GitHub](https://github.com/Crown0815/Forgejo-runner-windows-builder/actions/runs/19344650459) are not sufficient? I was given to understand that this repository should remain free of Windows specific testing. Wine is free and a windows compabillity layer on linux to run windows programs. So if you're interested in a ci job here which runs tests with wine and some e2e tests with forgejo (linux) and runner (windows, wine) then we can maybe official support compiling runner for windows on release. 🤔
viceice left a comment

otherwise LGTM

otherwise LGTM
@ -36,3 +36,3 @@
} {
if v.workDir != "" {
t.Chdir(v.workDir)
//nolint:usetesting
Owner

please add a comment why t.Chdir doesn't work on windows. So noboy tries to change this again 😉

please add a comment why `t.Chdir` doesn't work on windows. So noboy tries to change this again 😉
Author
Contributor

Good idea!

Good idea!
Crown0815 marked this conversation as resolved
Author
Contributor

@viceice wrote in #1152 (comment):

@Crown0815 wrote in #1152 (comment):

@viceice wrote in #1152 (comment):

we should configure wine and run windows tests under it if zrypossible 🤔

Do you feel the tests run on GitHub are not sufficient? I was given to understand that this repository should remain free of Windows specific testing.

Wine is free and a windows compabillity layer on linux to run windows programs. So if you're interested in a ci job here which runs tests with wine and some e2e tests with forgejo (linux) and runner (windows, wine) then we can maybe official support compiling runner for windows on release. 🤔

That would actually be cool. I'll look into this. My only experience with Wine so far was about 20 years ago on a MacBook, so I may be a little outdated 😅

@viceice wrote in https://code.forgejo.org/forgejo/runner/pulls/1152#issuecomment-66520: > @Crown0815 wrote in #1152 (comment): > > > @viceice wrote in #1152 (comment): > > > we should configure wine and run windows tests under it if zrypossible :thinking: > > > > > > Do you feel the tests run on [GitHub](https://github.com/Crown0815/Forgejo-runner-windows-builder/actions/runs/19344650459) are not sufficient? I was given to understand that this repository should remain free of Windows specific testing. > > Wine is free and a windows compabillity layer on linux to run windows programs. So if you're interested in a ci job here which runs tests with wine and some e2e tests with forgejo (linux) and runner (windows, wine) then we can maybe official support compiling runner for windows on release. :thinking: That would actually be cool. I'll look into this. My only experience with Wine so far was about 20 years ago on a MacBook, so I may be a little outdated 😅
Owner

@Crown0815 wrote in #1152 (comment):

@viceice wrote in #1152 (comment):

@Crown0815 wrote in #1152 (comment):

@viceice wrote in #1152 (comment):

we should configure wine and run windows tests under it if zrypossible 🤔

Do you feel the tests run on GitHub are not sufficient? I was given to understand that this repository should remain free of Windows specific testing.

Wine is free and a windows compabillity layer on linux to run windows programs. So if you're interested in a ci job here which runs tests with wine and some e2e tests with forgejo (linux) and runner (windows, wine) then we can maybe official support compiling runner for windows on release. 🤔

That would actually be cool. I'll look into this. My only experience with Wine so far was about 20 years ago on a MacBook, so I may be a little outdated 😅

Wine should be pretty straight to install and modern on trixie
https://wiki.debian.org/Wine

@Crown0815 wrote in https://code.forgejo.org/forgejo/runner/pulls/1152#issuecomment-66523: > @viceice wrote in #1152 (comment): > > > @Crown0815 wrote in #1152 (comment): > > > @viceice wrote in #1152 (comment): > > > > we should configure wine and run windows tests under it if zrypossible :thinking: > > > > > > > > > Do you feel the tests run on [GitHub](https://github.com/Crown0815/Forgejo-runner-windows-builder/actions/runs/19344650459) are not sufficient? I was given to understand that this repository should remain free of Windows specific testing. > > > > > > Wine is free and a windows compabillity layer on linux to run windows programs. So if you're interested in a ci job here which runs tests with wine and some e2e tests with forgejo (linux) and runner (windows, wine) then we can maybe official support compiling runner for windows on release. :thinking: > > That would actually be cool. I'll look into this. My only experience with Wine so far was about 20 years ago on a MacBook, so I may be a little outdated :sweat_smile: Wine should be pretty straight to install and modern on trixie https://wiki.debian.org/Wine
viceice approved these changes 2025-11-14 12:51:26 +00:00
@ -15,12 +17,13 @@ func init() {
}
func TestImageExistsLocally(t *testing.T) {
skip.If(t, runtime.GOOS != "linux") // Windows and macOS cannot natively run Linux containers
Owner

Would it make sense to copy the build tag from docker_images.go and use that to conditional compile the tests in the same manner? That seems a little more consistent between code and test to me, especially since the build tags are more complicated than this check.

(As an aside, the concept that we can't do this in Windows seems wrong to me -- this test doesn't require running a Linux container natively, it requires connecting to a Docker daemon to issues commands. But I'll leave that aside because the docker_images.go is conditional compiled so, might as well follow the same strategy for the tests.)

Would it make sense to copy the build tag from `docker_images.go` and use that to conditional compile the tests in the same manner? That seems a little more consistent between code and test to me, especially since the build tags are more complicated than this check. (As an aside, the concept that we can't do this in Windows seems wrong to me -- this test doesn't require running a Linux container natively, it requires connecting to a Docker daemon to issues commands. But I'll leave that aside because the `docker_images.go` is conditional compiled so, might as well follow the same strategy for the tests.)
Author
Contributor

(As an aside, the concept that we can't do this in Windows seems wrong to me -- this test doesn't require running a Linux container natively, it requires connecting to a Docker daemon to issues commands. But I'll leave that aside because the docker_images.go is conditional compiled so, might as well follow the same strategy for the tests.)

It is wrong. I plan to enable the docker tests on windows, but did not succeed yet. For the time being I wanted to ignore the tests.
Is it ok to leave it like this until I figure out a way to run the tests on windows?

> (As an aside, the concept that we can't do this in Windows seems wrong to me -- this test doesn't require running a Linux container natively, it requires connecting to a Docker daemon to issues commands. But I'll leave that aside because the docker_images.go is conditional compiled so, might as well follow the same strategy for the tests.) It is wrong. I plan to enable the docker tests on windows, but did not succeed yet. For the time being I wanted to ignore the tests. Is it ok to leave it like this until I figure out a way to run the tests on windows?
@ -23,6 +25,7 @@ import (
)
func TestDocker(t *testing.T) {
skip.If(t, runtime.GOOS != "linux") // Windows and macOS cannot natively run Linux containers
Owner

ditto, re: conditional compile via tags?

ditto, re: conditional compile via tags?
Author
Contributor

see here

see [here](https://code.forgejo.org/forgejo/runner/pulls/1152#issuecomment-66670)
@ -39,2 +40,4 @@
t.Fail()
}
}
Owner

Typical in tests to use require.NoError(t, err), rather than logging and failing; would updating it to that convention be OK?

Typical in tests to use `require.NoError(t, err)`, rather than logging and failing; would updating it to that convention be OK?
Crown0815 marked this conversation as resolved
@ -45,3 +49,4 @@
}
} else {
cwd, err := os.Getwd()
if err != nil {
Owner

Seems odd that this one doesn't fail the test on an error; that would make it easier to identify any later test failures caused by the cwd being unexpected. But not a big deal.

Seems odd that this one doesn't fail the test on an error; that would make it easier to identify any later test failures caused by the cwd being unexpected. But not a big deal.
Crown0815 marked this conversation as resolved
@ -21,3 +23,4 @@
//go:generate mockery --srcpkg=github.com/sirupsen/logrus --name=FieldLogger
func TestJobExecutor(t *testing.T) {
skip.If(t, runtime.GOOS != "linux") // Windows and macOS cannot natively run Linux containers
Owner

What would you think of abstracting this check into a utility method, like skip.If(t, util.NoDocker()), and then implement the NoDocker check with the same logic as the build tags? Then it doesn't require a comment because it's clear why it's being skipped, as the logic changes for different platforms it doesn't need to be done in different locations (eg. #1135), and if we do want to use a docker client against a remote daemon it would be possible to set up the environment and update NoDocker to check that environment (not necessary now).

What would you think of abstracting this check into a utility method, like `skip.If(t, util.NoDocker())`, and then implement the `NoDocker` check with the same logic as the build tags? Then it doesn't require a comment because it's clear why it's being skipped, as the logic changes for different platforms it doesn't need to be done in different locations (eg. #1135), and if we do want to use a docker client against a remote daemon it would be possible to set up the environment and update `NoDocker` to check that environment (not necessary now).
Author
Contributor

I agree, but believe it would be better to "just" make the tests work on Windows as well by making the docker daemon available.
(see here).

I'll see that this is the next thing I tackle.
In the end, using Docker on Windows will be very useful.

I agree, but believe it would be better to "just" make the tests work on Windows as well by making the docker daemon available. (see [here](https://code.forgejo.org/forgejo/runner/pulls/1152#issuecomment-66670)). I'll see that this is the next thing I tackle. In the end, using Docker on Windows will be very useful.
Crown0815 force-pushed feature/windows-specific-fixes from 2087e0eb3d
All checks were successful
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
issue-labels / release-notes (pull_request_target) Successful in 6s
checks / validate mocks (pull_request) Successful in 32s
checks / validate pre-commit-hooks file (pull_request) Successful in 33s
checks / build and test (pull_request) Successful in 41s
checks / runner exec tests (pull_request) Successful in 26s
checks / runner integration tests (pull_request) Successful in 4m51s
checks / integration tests (pull_request) Successful in 11m2s
to f2769d90e6
All checks were successful
checks / validate pre-commit-hooks file (pull_request) Successful in 48s
checks / validate mocks (pull_request) Successful in 55s
checks / build and test (pull_request) Successful in 1m10s
checks / runner exec tests (pull_request) Successful in 33s
checks / runner integration tests (pull_request) Successful in 6m50s
checks / integration tests (pull_request) Successful in 12m58s
cascade / forgejo (pull_request_target) Has been skipped
cascade / debug (pull_request_target) Has been skipped
cascade / end-to-end (pull_request_target) Has been skipped
issue-labels / release-notes (pull_request_target) Successful in 9s
2025-11-16 09:46:06 +00:00
Compare
Author
Contributor

@mfenniak, I implemented the changes (except for the non-Linux skips). Let me know if there is anything else.

@mfenniak, I implemented the changes (except for the _non-Linux skips_). Let me know if there is anything else.
mfenniak approved these changes 2025-11-16 15:56:52 +00:00
mfenniak referenced this pull request from a commit 2025-11-16 15:56:58 +00:00
Crown0815 deleted branch feature/windows-specific-fixes 2025-11-17 10:42:14 +00:00
mfenniak changed title from Windows-specific-fixes to Windows compatibility fixes 2025-11-21 16:10:05 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo/runner!1152
No description provided.