From ede5a9fea6f0eab1c100764611ad2520032d3dbe Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sat, 16 Nov 2024 00:02:04 +0200 Subject: [PATCH 1/9] fix: typo in the git SSH command constant (#5287) --- internal/client/git.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/client/git.go b/internal/client/git.go index db5ca9fbb..0739b5edd 100644 --- a/internal/client/git.go +++ b/internal/client/git.go @@ -22,8 +22,8 @@ import ( var gil sync.Mutex -// DefaulGitSSHCommand used for git over SSH. -const DefaulGitSSHCommand = `ssh -i "{{ .KeyPath }}" -o StrictHostKeyChecking=accept-new -F /dev/null` +// DefaultGitSSHCommand used for git over SSH. +const DefaultGitSSHCommand = `ssh -i "{{ .KeyPath }}" -o StrictHostKeyChecking=accept-new -F /dev/null` type gitClient struct { branch string @@ -70,7 +70,7 @@ func (g *gitClient) CreateFiles( sshcmd, err := tmpl.New(ctx).WithExtraFields(tmpl.Fields{ "KeyPath": key, - }).Apply(ordered.First(repo.GitSSHCommand, DefaulGitSSHCommand)) + }).Apply(ordered.First(repo.GitSSHCommand, DefaultGitSSHCommand)) if err != nil { return fmt.Errorf("git: failed to template ssh command: %w", err) } From c65b2258cb34ef66d0ce0e00b4497836edfb9eb5 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sat, 16 Nov 2024 15:16:54 +0200 Subject: [PATCH 2/9] fix: pass context.Context to HTTP requests (#5289) This PR adds using `context.Context` in HTTP requests. Changes are similar to #5232. Additionally, it enables `noctx` to automatically detect missing context: ``` internal/pipe/webhook/webhook.go:85:29: should rewrite http.NewRequestWithContext or add (*Request).WithContext (noctx) internal/pipe/linkedin/client.go:68:27: (*net/http.Client).Get must not be called (noctx) internal/pipe/linkedin/client.go:101:27: (*net/http.Client).Get must not be called (noctx) internal/pipe/linkedin/client.go:172:28: (*net/http.Client).Post must not be called (noctx) ``` --- .golangci.yaml | 6 +++++ internal/pipe/linkedin/client.go | 39 ++++++++++++++++++--------- internal/pipe/linkedin/client_test.go | 5 ++-- internal/pipe/linkedin/linkedin.go | 2 +- internal/pipe/webhook/webhook.go | 2 +- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index e797df9bb..1f5d88990 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -19,6 +19,7 @@ linters: - testifylint - gocritic - nolintlint + - noctx linters-settings: gocritic: disabled-checks: @@ -74,3 +75,8 @@ linters-settings: enable-all: true disable: - error-is-as # false positive +issues: + exclude-rules: + - path: _test\.go + linters: + - noctx diff --git a/internal/pipe/linkedin/client.go b/internal/pipe/linkedin/client.go index 67124da98..4d5224f05 100644 --- a/internal/pipe/linkedin/client.go +++ b/internal/pipe/linkedin/client.go @@ -2,6 +2,7 @@ package linkedin import ( "bytes" + stdctx "context" "encoding/json" "errors" "fmt" @@ -64,8 +65,12 @@ func createLinkedInClient(cfg oauthClientConfig) (client, error) { // POST Share API requires a Profile ID in the 'owner' field // Format must be in: 'urn:li:person:PROFILE_ID' // https://docs.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api#retrieve-current-members-profile -func (c client) getProfileIDLegacy() (string, error) { - resp, err := c.client.Get(c.baseURL + "/v2/me") +func (c client) getProfileIDLegacy(ctx stdctx.Context) (string, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+"/v2/me", http.NoBody) + if err != nil { + return "", fmt.Errorf("could not create GET request: %w", err) + } + resp, err := c.client.Do(req) if err != nil { return "", fmt.Errorf("could not GET /v2/me: %w", err) } @@ -97,8 +102,12 @@ func (c client) getProfileIDLegacy() (string, error) { // POST Share API requires a Profile ID in the 'owner' field // Format must be in: 'urn:li:person:PROFILE_SUB' // https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2#api-request-to-retreive-member-details -func (c client) getProfileSub() (string, error) { - resp, err := c.client.Get(c.baseURL + "/v2/userinfo") +func (c client) getProfileSub(ctx stdctx.Context) (string, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+"/v2/userinfo", http.NoBody) + if err != nil { + return "", fmt.Errorf("could not create GET request: %w", err) + } + resp, err := c.client.Do(req) if err != nil { return "", fmt.Errorf("could not GET /v2/userinfo: %w", err) } @@ -129,9 +138,9 @@ func (c client) getProfileSub() (string, error) { // Owner of the share. Required on create. // tries to get the profile sub (formally id) first, if it fails, it tries to get the profile id (legacy) // https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api?tabs=http#schema -func (c client) getProfileURN() (string, error) { +func (c client) getProfileURN(ctx stdctx.Context) (string, error) { // To build the URN, we need to get the profile sub (formally id) - profileSub, err := c.getProfileSub() + profileSub, err := c.getProfileSub(ctx) if err != nil { if !errors.Is(err, ErrLinkedinForbidden) { return "", fmt.Errorf("could not get profile sub: %w", err) @@ -139,7 +148,7 @@ func (c client) getProfileURN() (string, error) { log.Debug("could not get linkedin profile sub due to permission, getting profile id (legacy)") - profileSub, err = c.getProfileIDLegacy() + profileSub, err = c.getProfileIDLegacy(ctx) if err != nil { return "", fmt.Errorf("could not get profile id: %w", err) } @@ -148,28 +157,34 @@ func (c client) getProfileURN() (string, error) { return fmt.Sprintf("urn:li:person:%s", profileSub), nil } -func (c client) Share(message string) (string, error) { +func (c client) Share(ctx stdctx.Context, message string) (string, error) { // To get Owner of the share, we need to get the profile URN - profileURN, err := c.getProfileURN() + profileURN, err := c.getProfileURN(ctx) if err != nil { return "", fmt.Errorf("could not get profile URN: %w", err) } - req := postShareRequest{ + reqBody := postShareRequest{ Text: postShareText{ Text: message, }, Owner: profileURN, } - reqBytes, err := json.Marshal(req) + reqBodyBytes, err := json.Marshal(reqBody) if err != nil { return "", fmt.Errorf("could not marshal request: %w", err) } // Filling only required 'owner' and 'text' field is OK // https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api?tabs=http#sample-request-3 - resp, err := c.client.Post(c.baseURL+"/v2/shares", "application/json", bytes.NewReader(reqBytes)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+"/v2/shares", bytes.NewReader(reqBodyBytes)) + if err != nil { + return "", fmt.Errorf("could not create POST request: %w", err) + } + req.Header.Set("Content-Type", "application/json") + + resp, err := c.client.Do(req) if err != nil { return "", fmt.Errorf("could not POST /v2/shares: %w", err) } diff --git a/internal/pipe/linkedin/client_test.go b/internal/pipe/linkedin/client_test.go index a55bcb201..27050cbb6 100644 --- a/internal/pipe/linkedin/client_test.go +++ b/internal/pipe/linkedin/client_test.go @@ -1,6 +1,7 @@ package linkedin import ( + "context" "fmt" "io" "net/http" @@ -75,7 +76,7 @@ func TestClient_Share(t *testing.T) { c.baseURL = server.URL - link, err := c.Share("test") + link, err := c.Share(context.Background(), "test") if err != nil { t.Fatalf("could not share: %v", err) } @@ -110,7 +111,7 @@ func TestClientLegacyProfile_Share(t *testing.T) { c.baseURL = server.URL - link, err := c.Share("test") + link, err := c.Share(context.Background(), "test") if err != nil { t.Fatalf("could not share: %v", err) } diff --git a/internal/pipe/linkedin/linkedin.go b/internal/pipe/linkedin/linkedin.go index cc720a253..116f14130 100644 --- a/internal/pipe/linkedin/linkedin.go +++ b/internal/pipe/linkedin/linkedin.go @@ -47,7 +47,7 @@ func (Pipe) Announce(ctx *context.Context) error { return fmt.Errorf("linkedin: %w", err) } - url, err := c.Share(message) + url, err := c.Share(ctx, message) if err != nil { return fmt.Errorf("linkedin: %w", err) } diff --git a/internal/pipe/webhook/webhook.go b/internal/pipe/webhook/webhook.go index 81ac56ae4..139110307 100644 --- a/internal/pipe/webhook/webhook.go +++ b/internal/pipe/webhook/webhook.go @@ -82,7 +82,7 @@ func (p Pipe) Announce(ctx *context.Context) error { Transport: customTransport, } - req, err := http.NewRequest(http.MethodPost, endpointURL.String(), strings.NewReader(msg)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpointURL.String(), strings.NewReader(msg)) if err != nil { return fmt.Errorf("webhook: %w", err) } From 2bf08f11a640c4ffe50d5cb194d2ba1b7a27582c Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 16 Nov 2024 10:30:39 -0300 Subject: [PATCH 3/9] ci: run build/test workflow on windows too (#5263) Maybe 3rd time is the charm! This makes the CI build run on windows too, and fix broken tests/featuers on Windows. Most of the changes are related to ignoring certain tests on windows, or making sure to use the right path separators. More work to do in the future, probably! #4293 --------- Signed-off-by: Carlos Alexandro Becker --- .github/workflows/build.yml | 14 +++++- CONTRIBUTING.md | 4 ++ Taskfile.yml | 2 +- cmd/init_test.go | 2 + cmd/schema_test.go | 3 ++ cmd/util_test.go | 6 +-- dagger/test.go | 2 +- go.mod | 2 +- go.sum | 4 +- internal/builders/golang/build_test.go | 14 +++--- internal/client/gitlab_test.go | 3 ++ internal/exec/exec.go | 2 +- internal/exec/exec_test.go | 7 +-- internal/gio/copy_test.go | 4 +- internal/gio/hash_test.go | 8 +++- internal/golden/golden.go | 8 ++++ internal/http/http.go | 8 +++- internal/pipe/archive/archive_test.go | 5 +- internal/pipe/artifactory/artifactory_test.go | 6 ++- internal/pipe/before/before_test.go | 10 ++-- internal/pipe/blob/blob_minio_test.go | 9 +++- internal/pipe/build/build_test.go | 43 ++++++++++------- internal/pipe/checksums/checksums_test.go | 5 +- internal/pipe/docker/docker_test.go | 1 + internal/pipe/env/env_test.go | 17 +++++-- internal/pipe/gomod/gomod_proxy_test.go | 8 +++- internal/pipe/gomod/gomod_test.go | 30 +++++++----- internal/pipe/ko/ko_test.go | 3 ++ internal/pipe/nfpm/nfpm.go | 4 +- internal/pipe/nfpm/nfpm_test.go | 22 ++++----- internal/pipe/nix/nix_test.go | 3 ++ internal/pipe/release/release_test.go | 2 + internal/pipe/sbom/sbom_test.go | 35 ++++++++------ internal/pipe/scoop/scoop.go | 2 +- internal/pipe/sign/sign_binary_test.go | 2 + internal/pipe/sign/sign_test.go | 7 ++- internal/pipe/snapcraft/snapcraft_test.go | 18 +++++++ internal/pipe/sourcearchive/source.go | 13 ++--- .../universalbinary/universalbinary_test.go | 48 ++++++++++++++----- internal/pipe/upload/upload_test.go | 6 ++- internal/pipe/upx/upx.go | 1 + internal/shell/shell_test.go | 3 ++ internal/shell/shell_windows_test.go | 28 +++++++++++ internal/testlib/docker.go | 11 +++++ internal/testlib/git.go | 2 +- internal/testlib/path.go | 12 +++++ internal/testlib/path_test.go | 6 ++- internal/tmpl/tmpl_test.go | 3 +- pkg/archive/tar/tar_test.go | 13 ++++- pkg/archive/targz/targz_test.go | 13 ++++- pkg/archive/tarxz/tarxz_test.go | 14 +++++- pkg/archive/tarzst/tarzst_test.go | 14 +++++- pkg/archive/zip/zip_test.go | 12 +++-- www/docs/customization/nfpm.md | 2 +- 54 files changed, 393 insertions(+), 133 deletions(-) create mode 100644 internal/shell/shell_windows_test.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index def7baebe..e9c851e3c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,9 @@ name: build +concurrency: + group: ${{ github.head_ref || github.ref_name }} + cancel-in-progress: true + on: push: branches: @@ -25,7 +29,11 @@ jobs: with: args: "-disable largeloopcopy" test: - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} env: DOCKER_CLI_EXPERIMENTAL: "enabled" steps: @@ -37,8 +45,11 @@ jobs: version: 3.x repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v2 + if: matrix.os == 'ubuntu-latest' - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3 + if: matrix.os == 'ubuntu-latest' - name: setup-snapcraft + if: matrix.os == 'ubuntu-latest' run: | sudo apt-get update sudo apt-get -yq --no-install-suggests --no-install-recommends install snapcraft @@ -46,6 +57,7 @@ jobs: with: install-only: true - uses: cachix/install-nix-action@v30 + if: matrix.os == 'ubuntu-latest' with: github_access_token: ${{ secrets.GITHUB_TOKEN }} - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb7db1b09..601a5cba5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,6 +94,10 @@ You can do so by running: task docker:setup ``` +### A note about Windows + +Make sure to enable "Developer Mode" in Settings. + ## Creating a commit Commit messages should be well formatted, and to make that "standardized", we diff --git a/Taskfile.yml b/Taskfile.yml index 053c8d1b0..10baf54bf 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -40,7 +40,7 @@ tasks: SOURCE_FILES: '{{default "./..." .SOURCE_FILES}}' TEST_PATTERN: '{{default "." .TEST_PATTERN}}' cmds: - - go test {{.TEST_OPTIONS}} -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt {{.SOURCE_FILES}} -run {{.TEST_PATTERN}} -timeout=5m + - go test {{.TEST_OPTIONS}} -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt {{.SOURCE_FILES}} -run {{.TEST_PATTERN}} -timeout=15m cover: desc: Open the cover tool diff --git a/cmd/init_test.go b/cmd/init_test.go index 21ed8a936..a5aa22397 100644 --- a/cmd/init_test.go +++ b/cmd/init_test.go @@ -5,6 +5,7 @@ import ( "path/filepath" "testing" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/stretchr/testify/require" ) @@ -55,6 +56,7 @@ func TestInitGitIgnoreExists(t *testing.T) { } func TestInitFileError(t *testing.T) { + testlib.SkipIfWindows(t) folder := setupInitTest(t) cmd := newInitCmd().cmd path := filepath.Join(folder, "nope.yaml") diff --git a/cmd/schema_test.go b/cmd/schema_test.go index 32a96dae6..edefaa29f 100644 --- a/cmd/schema_test.go +++ b/cmd/schema_test.go @@ -18,6 +18,9 @@ func TestGenerateSchema(t *testing.T) { outFile, err := os.Open(destination) require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, outFile.Close()) + }) schema := map[string]interface{}{} require.NoError(t, json.NewDecoder(outFile).Decode(&schema)) diff --git a/cmd/util_test.go b/cmd/util_test.go index e754fa394..a769d8a35 100644 --- a/cmd/util_test.go +++ b/cmd/util_test.go @@ -21,17 +21,17 @@ func setup(tb testing.TB) string { _ = os.Unsetenv("GITHUB_TOKEN") _ = os.Unsetenv("GITLAB_TOKEN") + _ = os.Unsetenv("GITEA_TOKEN") previous, err := os.Getwd() require.NoError(tb, err) + folder := tb.TempDir() + require.NoError(tb, os.Chdir(folder)) tb.Cleanup(func() { require.NoError(tb, os.Chdir(previous)) }) - folder := tb.TempDir() - require.NoError(tb, os.Chdir(folder)) - createGoReleaserYaml(tb) createMainGo(tb) goModInit(tb) diff --git a/dagger/test.go b/dagger/test.go index e85b13aec..e3e2da4ef 100644 --- a/dagger/test.go +++ b/dagger/test.go @@ -119,6 +119,6 @@ func installBuildx(target *dagger.Container) *dagger.Container { "/usr/lib/docker/cli-plugins/docker-buildx", bin, dagger.ContainerWithFileOpts{ - Permissions: 0777, + Permissions: 0o777, }) } diff --git a/go.mod b/go.mod index 918f94801..e5bcf4a2f 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/google/ko v0.17.1 github.com/google/uuid v1.6.0 github.com/goreleaser/fileglob v1.3.0 - github.com/goreleaser/nfpm/v2 v2.41.0 + github.com/goreleaser/nfpm/v2 v2.41.1-0.20241110134201-59b75b2a5a2e github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d github.com/hashicorp/go-multierror v1.1.1 github.com/invopop/jsonschema v0.12.0 diff --git a/go.sum b/go.sum index a6cad7b86..b91f63bea 100644 --- a/go.sum +++ b/go.sum @@ -461,8 +461,8 @@ github.com/goreleaser/chglog v0.6.1 h1:NZKiX8l0FTQPRzBgKST7knvNZmZ04f7PEGkN2wInf github.com/goreleaser/chglog v0.6.1/go.mod h1:Bnnfo07jMZkaAb0uRNASMZyOsX6ROW6X1qbXqN3guUo= github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I= github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= -github.com/goreleaser/nfpm/v2 v2.41.0 h1:JyMzS/EwqaWbFs+7Z9oZ4Hkk4or00gUTqwm9Dgr8QYg= -github.com/goreleaser/nfpm/v2 v2.41.0/go.mod h1:VPc5kF5OgfA+BosV/A2aB+Vg34honjWvp0Vt8ogsSi0= +github.com/goreleaser/nfpm/v2 v2.41.1-0.20241110134201-59b75b2a5a2e h1:xajOCis2WSRoM8XmWFQZFKbjUYJ0PMyFI8QTvIsILLo= +github.com/goreleaser/nfpm/v2 v2.41.1-0.20241110134201-59b75b2a5a2e/go.mod h1:VPc5kF5OgfA+BosV/A2aB+Vg34honjWvp0Vt8ogsSi0= github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d h1:bBLVbv03RLdskOHJfNkEJIMm+85b4E3GJkEEVXIu48k= github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d/go.mod h1:b/JsMZEZCcW7WWjR1+XyIFYSFizwmAYpxvvh3ZcauVE= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= diff --git a/internal/builders/golang/build_test.go b/internal/builders/golang/build_test.go index 1a3e4cb46..f41df23f4 100644 --- a/internal/builders/golang/build_test.go +++ b/internal/builders/golang/build_test.go @@ -465,7 +465,7 @@ func TestBuild(t *testing.T) { require.ElementsMatch(t, list.List(), []*artifact.Artifact{ { Name: "bin/foo-v5.6.7", - Path: filepath.Join("dist", "linux_amd64", "bin", "foo-v5.6.7"), + Path: filepath.ToSlash(filepath.Join("dist", "linux_amd64", "bin", "foo-v5.6.7")), Goos: "linux", Goarch: "amd64", Type: artifact.Binary, @@ -478,7 +478,7 @@ func TestBuild(t *testing.T) { }, { Name: "bin/foo-v5.6.7", - Path: filepath.Join("dist", "linux_mips_softfloat", "bin", "foo-v5.6.7"), + Path: filepath.ToSlash(filepath.Join("dist", "linux_mips_softfloat", "bin", "foo-v5.6.7")), Goos: "linux", Goarch: "mips", Gomips: "softfloat", @@ -492,7 +492,7 @@ func TestBuild(t *testing.T) { }, { Name: "bin/foo-v5.6.7", - Path: filepath.Join("dist", "linux_mips64le_softfloat", "bin", "foo-v5.6.7"), + Path: filepath.ToSlash(filepath.Join("dist", "linux_mips64le_softfloat", "bin", "foo-v5.6.7")), Goos: "linux", Goarch: "mips64le", Gomips: "softfloat", @@ -506,7 +506,7 @@ func TestBuild(t *testing.T) { }, { Name: "bin/foo-v5.6.7", - Path: filepath.Join("dist", "darwin_amd64", "bin", "foo-v5.6.7"), + Path: filepath.ToSlash(filepath.Join("dist", "darwin_amd64", "bin", "foo-v5.6.7")), Goos: "darwin", Goarch: "amd64", Type: artifact.Binary, @@ -519,7 +519,7 @@ func TestBuild(t *testing.T) { }, { Name: "bin/foo-v5.6.7", - Path: filepath.Join("dist", "linux_arm_6", "bin", "foo-v5.6.7"), + Path: filepath.ToSlash(filepath.Join("dist", "linux_arm_6", "bin", "foo-v5.6.7")), Goos: "linux", Goarch: "arm", Goarm: "6", @@ -533,7 +533,7 @@ func TestBuild(t *testing.T) { }, { Name: "bin/foo-v5.6.7.exe", - Path: filepath.Join("dist", "windows_amd64", "bin", "foo-v5.6.7.exe"), + Path: filepath.ToSlash(filepath.Join("dist", "windows_amd64", "bin", "foo-v5.6.7.exe")), Goos: "windows", Goarch: "amd64", Type: artifact.Binary, @@ -546,7 +546,7 @@ func TestBuild(t *testing.T) { }, { Name: "bin/foo-v5.6.7.wasm", - Path: filepath.Join("dist", "js_wasm", "bin", "foo-v5.6.7.wasm"), + Path: filepath.ToSlash(filepath.Join("dist", "js_wasm", "bin", "foo-v5.6.7.wasm")), Goos: "js", Goarch: "wasm", Type: artifact.Binary, diff --git a/internal/client/gitlab_test.go b/internal/client/gitlab_test.go index 5195f47f2..2c385bc8b 100644 --- a/internal/client/gitlab_test.go +++ b/internal/client/gitlab_test.go @@ -248,6 +248,9 @@ func TestGitLabURLsDownloadTemplate(t *testing.T) { tmpFile, err := os.CreateTemp(t.TempDir(), "") require.NoError(t, err) + t.Cleanup(func() { + _ = tmpFile.Close() + }) client, err := newGitLab(ctx, ctx.Token) require.NoError(t, err) diff --git a/internal/exec/exec.go b/internal/exec/exec.go index 475c5a886..13debbdc0 100644 --- a/internal/exec/exec.go +++ b/internal/exec/exec.go @@ -22,7 +22,7 @@ import ( ) // Environment variables to pass through to exec -var passthroughEnvVars = []string{"HOME", "USER", "USERPROFILE", "TMPDIR", "TMP", "TEMP", "PATH"} +var passthroughEnvVars = []string{"HOME", "USER", "USERPROFILE", "TMPDIR", "TMP", "TEMP", "PATH", "SYSTEMROOT"} // Execute the given publisher func Execute(ctx *context.Context, publishers []config.Publisher) error { diff --git a/internal/exec/exec_test.go b/internal/exec/exec_test.go index 32e3993a3..68bc86396 100644 --- a/internal/exec/exec_test.go +++ b/internal/exec/exec_test.go @@ -3,6 +3,7 @@ package exec import ( "fmt" "os" + "path" "path/filepath" "strings" "testing" @@ -40,7 +41,7 @@ func TestExecute(t *testing.T) { {"signature", "sig", artifact.Signature}, {"signature", "pem", artifact.Certificate}, } { - file := filepath.Join(folder, "a."+a.ext) + file := filepath.ToSlash(filepath.Join(folder, "a."+a.ext)) require.NoError(t, os.WriteFile(file, []byte("lorem ipsum"), 0o644)) ctx.Artifacts.Add(&artifact.Artifact{ Name: "a." + a.ext, @@ -275,7 +276,7 @@ func TestExecute(t *testing.T) { }), }, ExtraFiles: []config.ExtraFile{ - {Glob: filepath.Join("testdata", "*.txt")}, + {Glob: path.Join("testdata", "*.txt")}, }, }, }, @@ -302,7 +303,7 @@ func TestExecute(t *testing.T) { }, ExtraFiles: []config.ExtraFile{ { - Glob: filepath.Join("testdata", "*.txt"), + Glob: path.Join("testdata", "*.txt"), NameTemplate: "b.txt", }, }, diff --git a/internal/gio/copy_test.go b/internal/gio/copy_test.go index 9ab513cfb..559fa695e 100644 --- a/internal/gio/copy_test.go +++ b/internal/gio/copy_test.go @@ -5,6 +5,7 @@ import ( "path/filepath" "testing" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/stretchr/testify/require" ) @@ -30,10 +31,11 @@ func TestCopySymlink(t *testing.T) { l, err := os.Readlink(c) require.NoError(t, err) - require.Equal(t, a, l) + require.Equal(t, a, filepath.ToSlash(l)) } func TestEqualFilesModeChanged(t *testing.T) { + testlib.SkipIfWindows(t) tmp := t.TempDir() a := "testdata/somefile.txt" b := tmp + "/somefile.txt" diff --git a/internal/gio/hash_test.go b/internal/gio/hash_test.go index 0c46b3e36..501e14156 100644 --- a/internal/gio/hash_test.go +++ b/internal/gio/hash_test.go @@ -3,6 +3,7 @@ package gio import ( "testing" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestEqualFiles(t *testing.T) { } } -func TestEqualFileCointents(t *testing.T) { +func TestEqualFileContents(t *testing.T) { tests := []struct { a string b string @@ -53,7 +54,10 @@ func TestEqualFileCointents(t *testing.T) { for _, test := range tests { equal, err := EqualFiles(test.a, test.b) require.NoError(t, err) - require.False(t, equal) + if !testlib.IsWindows() { + // this fails on windows due to perms being ignored + require.False(t, equal) + } equalContents, err := EqualFileContents(test.a, test.b) require.NoError(t, err) diff --git a/internal/golden/golden.go b/internal/golden/golden.go index 3941ddc7c..53ec70167 100644 --- a/internal/golden/golden.go +++ b/internal/golden/golden.go @@ -2,6 +2,7 @@ package golden import ( + "bytes" "flag" "os" "path/filepath" @@ -59,6 +60,8 @@ func RequireReadFile(tb testing.TB, path string) []byte { func doRequireEqual(tb testing.TB, out []byte, ext, suffix string, folder bool) { tb.Helper() + out = fixLineEndings(out) + golden := filepath.Join("testdata", tb.Name()+ext+suffix) if folder { golden = filepath.Join("testdata", tb.Name(), filepath.Base(tb.Name())+ext+suffix) @@ -70,6 +73,11 @@ func doRequireEqual(tb testing.TB, out []byte, ext, suffix string, folder bool) gbts, err := os.ReadFile(golden) require.NoError(tb, err) + gbts = fixLineEndings(gbts) require.Equal(tb, string(gbts), string(out)) } + +func fixLineEndings(in []byte) []byte { + return bytes.ReplaceAll(in, []byte("\r\n"), []byte{'\n'}) +} diff --git a/internal/http/http.go b/internal/http/http.go index cf200b60b..a36bc0f90 100644 --- a/internal/http/http.go +++ b/internal/http/http.go @@ -8,7 +8,6 @@ import ( "io" h "net/http" "os" - "runtime" "strings" "github.com/caarlos0/log" @@ -16,6 +15,7 @@ import ( "github.com/goreleaser/goreleaser/v2/internal/extrafiles" "github.com/goreleaser/goreleaser/v2/internal/pipe" "github.com/goreleaser/goreleaser/v2/internal/semerrgroup" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/goreleaser/goreleaser/v2/internal/tmpl" "github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/goreleaser/goreleaser/v2/pkg/context" @@ -49,6 +49,8 @@ func assetOpenReset() { assetOpen = assetOpenDefault } +// TODO: this should probably return a func()error always so we can properly +// handle closing the file. func assetOpenDefault(kind string, a *artifact.Artifact) (*asset, error) { f, err := os.Open(a.Path) if err != nil { @@ -56,9 +58,11 @@ func assetOpenDefault(kind string, a *artifact.Artifact) (*asset, error) { } s, err := f.Stat() if err != nil { + _ = f.Close() return nil, err } if s.IsDir() { + _ = f.Close() return nil, fmt.Errorf("%s: upload failed: the asset to upload can't be a directory", kind) } return &asset{ @@ -332,7 +336,7 @@ func getHTTPClient(upload *config.Upload) (*h.Client, error) { if upload.TrustedCerts != "" { pool, err := x509.SystemCertPool() if err != nil { - if runtime.GOOS == "windows" { + if testlib.IsWindows() { // on windows ignore errors until golang issues #16736 & #18609 get fixed pool = x509.NewCertPool() } else { diff --git a/internal/pipe/archive/archive_test.go b/internal/pipe/archive/archive_test.go index e5e49f01b..835243d06 100644 --- a/internal/pipe/archive/archive_test.go +++ b/internal/pipe/archive/archive_test.go @@ -1004,9 +1004,7 @@ func TestDuplicateFilesInsideArchive(t *testing.T) { f, err := os.CreateTemp(folder, "") require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, f.Close()) - }) + t.Cleanup(func() { require.NoError(t, f.Close()) }) ff, err := os.CreateTemp(folder, "") require.NoError(t, err) @@ -1066,6 +1064,7 @@ func TestArchive_globbing(t *testing.T) { t.Helper() bin, err := os.CreateTemp(t.TempDir(), "binary") require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, bin.Close()) }) dist := t.TempDir() ctx := testctx.NewWithCfg(config.Project{ Dist: dist, diff --git a/internal/pipe/artifactory/artifactory_test.go b/internal/pipe/artifactory/artifactory_test.go index faf01183a..a3592cbe3 100644 --- a/internal/pipe/artifactory/artifactory_test.go +++ b/internal/pipe/artifactory/artifactory_test.go @@ -331,7 +331,11 @@ func TestRunPipe_ArtifactoryDown(t *testing.T) { }) require.NoError(t, Pipe{}.Default(ctx)) - require.ErrorIs(t, Pipe{}.Publish(ctx), syscall.ECONNREFUSED) + err = Pipe{}.Publish(ctx) + require.Error(t, err) + if !testlib.IsWindows() { + require.ErrorIs(t, err, syscall.ECONNREFUSED) + } } func TestRunPipe_TargetTemplateError(t *testing.T) { diff --git a/internal/pipe/before/before_test.go b/internal/pipe/before/before_test.go index ded37137c..8d8c5df38 100644 --- a/internal/pipe/before/before_test.go +++ b/internal/pipe/before/before_test.go @@ -23,13 +23,16 @@ func TestDescription(t *testing.T) { } func TestRunPipe(t *testing.T) { - for _, tc := range [][]string{ + table := [][]string{ nil, {}, {"go version"}, {"go version", "go list"}, - {`bash -c "go version; echo \"lala spaces and such\""`}, - } { + } + if testlib.InPath("bash") { + table = append(table, []string{`bash -c "go version; echo \"lala spaces and such\""`}) + } + for _, tc := range table { ctx := testctx.NewWithCfg( config.Project{ Before: config.Before{ @@ -70,6 +73,7 @@ func TestRunPipeFail(t *testing.T) { } func TestRunWithEnv(t *testing.T) { + testlib.SkipIfWindows(t) f := filepath.Join(t.TempDir(), "testfile") require.NoError(t, Pipe{}.Run(testctx.NewWithCfg( config.Project{ diff --git a/internal/pipe/blob/blob_minio_test.go b/internal/pipe/blob/blob_minio_test.go index 4ccf74c88..7c722ff14 100644 --- a/internal/pipe/blob/blob_minio_test.go +++ b/internal/pipe/blob/blob_minio_test.go @@ -29,7 +29,8 @@ const ( var listen string func TestMain(m *testing.M) { - if !testlib.InPath("docker") { + if !testlib.InPath("docker") || testlib.IsWindows() { + // there's no minio windows image m.Run() return } @@ -75,6 +76,7 @@ func TestMain(m *testing.M) { func TestMinioUpload(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) name := "basic" directory := t.TempDir() srcpath := filepath.Join(directory, "source.tar.gz") @@ -181,6 +183,7 @@ func TestMinioUpload(t *testing.T) { func TestMinioUploadCustomBucketID(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) name := "fromenv" directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") @@ -218,6 +221,7 @@ func TestMinioUploadCustomBucketID(t *testing.T) { func TestMinioUploadExtraFilesOnly(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) name := "only-extra-files" directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") @@ -264,6 +268,7 @@ func TestMinioUploadExtraFilesOnly(t *testing.T) { func TestMinioUploadRootDirectory(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) name := "rootdir" directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") @@ -300,6 +305,7 @@ func TestMinioUploadRootDirectory(t *testing.T) { func TestMinioUploadInvalidCustomBucketID(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") debpath := filepath.Join(directory, "bin.deb") @@ -333,6 +339,7 @@ func TestMinioUploadInvalidCustomBucketID(t *testing.T) { func TestMinioUploadSkip(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) name := "basic" directory := t.TempDir() debpath := filepath.Join(directory, "bin.deb") diff --git a/internal/pipe/build/build_test.go b/internal/pipe/build/build_test.go index c16e8fc6a..8173625ea 100644 --- a/internal/pipe/build/build_test.go +++ b/internal/pipe/build/build_test.go @@ -22,8 +22,18 @@ import ( var ( errFailedBuild = errors.New("fake builder failed") errFailedDefault = errors.New("fake builder defaults failed") + + touch = "touch " + echo = "echo " ) +func init() { + if testlib.IsWindows() { + touch = "cmd.exe /c copy nul " + echo = "cmd.exe /c echo " + } +} + type fakeBuilder struct { fail bool failDefault bool @@ -136,12 +146,12 @@ func TestRunFullPipe(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: "touch " + pre}, - {Cmd: "touch pre_{{ .Env.THE_OS}}"}, + {Cmd: touch + pre}, + {Cmd: touch + " pre_{{ .Env.THE_OS}}"}, }, Post: []config.Hook{ - {Cmd: "touch " + post}, - {Cmd: "touch post_{{ .Env.THE_OS}}"}, + {Cmd: touch + post}, + {Cmd: touch + " post_{{ .Env.THE_OS}}"}, }, }, Targets: []string{"linux_amd64"}, @@ -178,10 +188,10 @@ func TestRunFullPipeFail(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: "touch " + pre}, + {Cmd: touch + pre}, }, Post: []config.Hook{ - {Cmd: "touch " + post}, + {Cmd: touch + post}, }, }, Targets: []string{"linux_amd64"}, @@ -210,7 +220,7 @@ func TestRunPipeFailingHooks(t *testing.T) { t.Run("pre-hook", func(t *testing.T) { ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} - ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "echo post"}} + ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: echo + " post"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) @@ -218,7 +228,7 @@ func TestRunPipeFailingHooks(t *testing.T) { }) t.Run("post-hook", func(t *testing.T) { ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) - ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "echo pre"}} + ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: echo + " pre"}} ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) @@ -231,7 +241,7 @@ func TestRunPipeFailingHooks(t *testing.T) { testctx.WithCurrentTag("2.4.5"), testctx.Skip(skips.PostBuildHooks), ) - ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "echo pre"}} + ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: echo + " pre"}} ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} require.NoError(t, Pipe{}.Run(ctx)) }) @@ -242,7 +252,7 @@ func TestRunPipeFailingHooks(t *testing.T) { testctx.WithCurrentTag("2.4.5"), testctx.Skip(skips.PreBuildHooks), ) - ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "echo pre"}} + ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: echo + " pre"}} ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} require.NoError(t, Pipe{}.Run(ctx)) }) @@ -364,10 +374,10 @@ func TestDefaultPartialBuilds(t *testing.T) { }, }) // Create any 'Dir' paths necessary for builds. - cwd, err := os.Getwd() + previous, err := os.Getwd() require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, os.Chdir(cwd)) }) require.NoError(t, os.Chdir(t.TempDir())) + t.Cleanup(func() { require.NoError(t, os.Chdir(previous)) }) for _, b := range ctx.Config.Builds { if b.Dir != "" { require.NoError(t, os.Mkdir(b.Dir, 0o755)) @@ -505,10 +515,10 @@ func TestBuild_hooksKnowGoosGoarch(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: "touch pre-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, + {Cmd: touch + " pre-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, }, Post: config.Hooks{ - {Cmd: "touch post-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, + {Cmd: touch + " post-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, }, }, } @@ -538,10 +548,10 @@ func TestPipeOnBuild_hooksRunPerTarget(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: "touch pre-hook-{{.Target}}", Dir: tmpDir}, + {Cmd: touch + " pre-hook-{{.Target}}", Dir: tmpDir}, }, Post: config.Hooks{ - {Cmd: "touch post-hook-{{.Target}}", Dir: tmpDir}, + {Cmd: touch + " post-hook-{{.Target}}", Dir: tmpDir}, }, }, } @@ -737,6 +747,7 @@ func TestBuildOptionsForTarget(t *testing.T) { } func TestRunHookFailWithLogs(t *testing.T) { + testlib.SkipIfWindows(t) folder := testlib.Mktmp(t) config := config.Project{ Dist: folder, diff --git a/internal/pipe/checksums/checksums_test.go b/internal/pipe/checksums/checksums_test.go index fbb06d994..3d1bc1ecc 100644 --- a/internal/pipe/checksums/checksums_test.go +++ b/internal/pipe/checksums/checksums_test.go @@ -309,7 +309,10 @@ func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) { }) err = Pipe{}.Run(ctx) require.Error(t, err) - require.ErrorIs(t, Pipe{}.Run(ctx), syscall.EACCES) + if !testlib.IsWindows() { + // this fails on windows + require.ErrorIs(t, Pipe{}.Run(ctx), syscall.EACCES) + } } func TestPipeWhenNoArtifacts(t *testing.T) { diff --git a/internal/pipe/docker/docker_test.go b/internal/pipe/docker/docker_test.go index d28647485..afc5d6796 100644 --- a/internal/pipe/docker/docker_test.go +++ b/internal/pipe/docker/docker_test.go @@ -35,6 +35,7 @@ func start(tb testing.TB) { // TODO: this test is too big... split in smaller tests? Mainly the manifest ones... func TestRunPipe(t *testing.T) { testlib.CheckPath(t, "docker") + testlib.SkipIfWindows(t) type errChecker func(*testing.T, error) shouldErr := func(msg string) errChecker { return func(t *testing.T, err error) { diff --git a/internal/pipe/env/env_test.go b/internal/pipe/env/env_test.go index 36b4ad9e4..06b7b1f98 100644 --- a/internal/pipe/env/env_test.go +++ b/internal/pipe/env/env_test.go @@ -184,7 +184,7 @@ func TestEmptyGithubEnvFile(t *testing.T) { }, }) err = Pipe{}.Run(ctx) - require.ErrorIs(t, err, syscall.EACCES) + requireErrAccess(t, err) require.ErrorContains(t, err, "failed to load github token") } @@ -199,7 +199,7 @@ func TestEmptyGitlabEnvFile(t *testing.T) { }, }) err = Pipe{}.Run(ctx) - require.ErrorIs(t, err, syscall.EACCES) + requireErrAccess(t, err) require.ErrorContains(t, err, "failed to load gitlab token") } @@ -214,7 +214,7 @@ func TestEmptyGiteaEnvFile(t *testing.T) { }, }) err = Pipe{}.Run(ctx) - require.ErrorIs(t, err, syscall.EACCES) + requireErrAccess(t, err) require.ErrorContains(t, err, "failed to load gitea token") } @@ -292,6 +292,7 @@ func TestLoadEnv(t *testing.T) { require.Equal(t, "123", v) }) t.Run("env file is not readable", func(t *testing.T) { + testlib.SkipIfWindows(t) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) fmt.Fprintf(f, "123") @@ -303,3 +304,13 @@ func TestLoadEnv(t *testing.T) { require.Equal(t, "", v) }) } + +func requireErrAccess(tb testing.TB, err error) { + tb.Helper() + require.Error(tb, err) + // unsupported + if testlib.IsWindows() { + return + } + require.ErrorIs(tb, err, syscall.EACCES) +} diff --git a/internal/pipe/gomod/gomod_proxy_test.go b/internal/pipe/gomod/gomod_proxy_test.go index 5afd06a62..849d02f38 100644 --- a/internal/pipe/gomod/gomod_proxy_test.go +++ b/internal/pipe/gomod/gomod_proxy_test.go @@ -175,6 +175,7 @@ func TestGoModProxy(t *testing.T) { }) t.Run("no perms", func(t *testing.T) { + testlib.SkipIfWindows(t) for file, mode := range map[string]os.FileMode{ "go.mod": 0o500, "go.sum": 0o500, @@ -203,7 +204,12 @@ func TestGoModProxy(t *testing.T) { // change perms of a file and run again, which should now fail on that file. require.NoError(t, os.Chmod(filepath.Join(dist, "proxy", "foo", file), mode)) - require.ErrorIs(t, ProxyPipe{}.Run(ctx), syscall.EACCES) + err := ProxyPipe{}.Run(ctx) + require.Error(t, err) + if !testlib.IsWindows() { + // this fails on windows + require.ErrorIs(t, err, syscall.EACCES) + } }) } }) diff --git a/internal/pipe/gomod/gomod_test.go b/internal/pipe/gomod/gomod_test.go index 9ed232c4e..7ea8bf252 100644 --- a/internal/pipe/gomod/gomod_test.go +++ b/internal/pipe/gomod/gomod_test.go @@ -60,11 +60,12 @@ func TestRunCustomMod(t *testing.T) { func TestCustomEnv(t *testing.T) { bin := filepath.Join(t.TempDir(), "go.bin") - require.NoError(t, os.WriteFile( - bin, - []byte("#!/bin/sh\nenv | grep -qw FOO=bar"), - 0o755, - )) + content := []byte("#!/bin/sh\nenv | grep -qw FOO=bar") + if testlib.IsWindows() { + bin = strings.Replace(bin, ".bin", ".bat", 1) + content = []byte("@echo off\r\nif not \"%FOO%\"==\"bar\" exit /b 1") + } + require.NoError(t, os.WriteFile(bin, content, 0o755)) ctx := testctx.NewWithCfg(config.Project{ GoMod: config.GoMod{ GoBinary: bin, @@ -117,21 +118,26 @@ func TestRunCommandError(t *testing.T) { GoBinary: "not-a-valid-binary", }, }) - require.EqualError( + path := "$PATH" + if testlib.IsWindows() { + path = "%PATH%" + } + require.ErrorContains( t, Pipe{}.Run(ctx), - `failed to get module path: exec: "not-a-valid-binary": executable file not found in $PATH: `, + `failed to get module path: exec: "not-a-valid-binary": executable file not found in `+path, ) require.Empty(t, ctx.ModulePath) } func TestRunOldGoVersion(t *testing.T) { bin := filepath.Join(t.TempDir(), "go.bin") - require.NoError(t, os.WriteFile( - bin, - []byte("#!/bin/sh\necho \"flag provided but not defined: -m\"\nexit 1"), - 0o755, - )) + content := []byte("#!/bin/sh\necho \"flag provided but not defined: -m\"\nexit 1") + if testlib.IsWindows() { + bin = strings.Replace(bin, ".bin", ".bat", 1) + content = []byte("@echo off\r\necho flag provided but not defined: -m\r\nexit /b 1") + } + require.NoError(t, os.WriteFile(bin, content, 0o755)) ctx := testctx.NewWithCfg(config.Project{ GoMod: config.GoMod{ GoBinary: bin, diff --git a/internal/pipe/ko/ko_test.go b/internal/pipe/ko/ko_test.go index 23b6a2d42..fb755c8d6 100644 --- a/internal/pipe/ko/ko_test.go +++ b/internal/pipe/ko/ko_test.go @@ -156,6 +156,7 @@ func TestPublishPipeNoMatchingBuild(t *testing.T) { } func TestPublishPipeSuccess(t *testing.T) { + testlib.SkipIfWindows(t) testlib.CheckPath(t, "docker") testlib.StartRegistry(t, "ko_registry", registryPort) @@ -411,6 +412,8 @@ func TestPublishPipeSuccess(t *testing.T) { } func TestSnapshot(t *testing.T) { + testlib.SkipIfWindows(t) + testlib.CheckDocker(t) ctx := testctx.NewWithCfg(config.Project{ ProjectName: "test", Builds: []config.Build{ diff --git a/internal/pipe/nfpm/nfpm.go b/internal/pipe/nfpm/nfpm.go index f60bbb0f2..b35cfa188 100644 --- a/internal/pipe/nfpm/nfpm.go +++ b/internal/pipe/nfpm/nfpm.go @@ -326,8 +326,8 @@ func create(ctx *context.Context, fpm config.NFPM, format string, artifacts []*a return err } contents = append(contents, &files.Content{ - Source: src, - Destination: dst, + Source: filepath.ToSlash(src), + Destination: filepath.ToSlash(dst), Type: content.Type, Packager: content.Packager, FileInfo: content.FileInfo, diff --git a/internal/pipe/nfpm/nfpm_test.go b/internal/pipe/nfpm/nfpm_test.go index c2705ce02..9a6957085 100644 --- a/internal/pipe/nfpm/nfpm_test.go +++ b/internal/pipe/nfpm/nfpm_test.go @@ -97,10 +97,10 @@ func TestRunPipe(t *testing.T) { dist := filepath.Join(folder, "dist") require.NoError(t, os.Mkdir(dist, 0o755)) require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) - binPath := filepath.Join(dist, "mybin", "mybin") - foohPath := filepath.Join(dist, "foo.h") - foosoPath := filepath.Join(dist, "foo.so") - fooaPath := filepath.Join(dist, "foo.a") + binPath := filepath.ToSlash(filepath.Join(dist, "mybin", "mybin")) + foohPath := filepath.ToSlash(filepath.Join(dist, "foo.h")) + foosoPath := filepath.ToSlash(filepath.Join(dist, "foo.so")) + fooaPath := filepath.ToSlash(filepath.Join(dist, "foo.a")) for _, name := range []string{binPath, foosoPath, foohPath, fooaPath} { f, err := os.Create(name) require.NoError(t, err) @@ -463,10 +463,10 @@ func TestRunPipe(t *testing.T) { cshared = filepath.Join("/data/data/com.termux/files", cshared) carchive = filepath.Join("/data/data/com.termux/files", carchive) } - bin = filepath.Join(bin, "mybin") - header = filepath.Join(header, "foo.h") - cshared = filepath.Join(cshared, "foo.so") - carchive = filepath.Join(carchive, "foo.a") + bin = filepath.ToSlash(filepath.Join(bin, "mybin")) + header = filepath.ToSlash(filepath.Join(header, "foo.h")) + cshared = filepath.ToSlash(filepath.Join(cshared, "foo.so")) + carchive = filepath.ToSlash(filepath.Join(carchive, "foo.a")) require.ElementsMatch(t, []string{ "/var/log/foobar", "/usr/share/testfile.txt", @@ -496,10 +496,8 @@ func doTestRunPipeConventionalNameTemplate(t *testing.T, snapshot bool) { dist := filepath.Join(folder, "dist") require.NoError(t, os.Mkdir(dist, 0o755)) require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) - binPath := filepath.Join(dist, "mybin", "mybin") - f, err := os.Create(binPath) - require.NoError(t, err) - require.NoError(t, f.Close()) + binPath := filepath.ToSlash(filepath.Join(dist, "mybin", "mybin")) + require.NoError(t, os.WriteFile(binPath, []byte("nope"), 0o755)) ctx := testctx.NewWithCfg(config.Project{ ProjectName: "mybin", Dist: dist, diff --git a/internal/pipe/nix/nix_test.go b/internal/pipe/nix/nix_test.go index 9f6524127..41cbc71f1 100644 --- a/internal/pipe/nix/nix_test.go +++ b/internal/pipe/nix/nix_test.go @@ -37,6 +37,7 @@ func TestSkip(t *testing.T) { }) t.Run("nix-all-good", func(t *testing.T) { testlib.CheckPath(t, "nix-prefetch-url") + testlib.SkipIfWindows(t) require.False(t, NewPublish().Skip(testctx.NewWithCfg(config.Project{ Nix: []config.Nix{{}}, }))) @@ -65,6 +66,7 @@ func TestPrefetcher(t *testing.T) { }) t.Run("valid", func(t *testing.T) { testlib.CheckPath(t, "nix-prefetch-url") + testlib.SkipIfWindows(t) sha, err := publishShaPrefetcher{nixPrefetchURLBin}.Prefetch("https://github.com/goreleaser/goreleaser/releases/download/v1.18.2/goreleaser_Darwin_arm64.tar.gz") require.NoError(t, err) require.Equal(t, "0girjxp07srylyq36xk1ska8p68m2fhp05xgyv4wkcl61d6rzv3y", sha) @@ -81,6 +83,7 @@ func TestPrefetcher(t *testing.T) { }) t.Run("valid", func(t *testing.T) { testlib.CheckPath(t, "nix-prefetch-url") + testlib.SkipIfWindows(t) require.True(t, publishShaPrefetcher{nixPrefetchURLBin}.Available()) }) }) diff --git a/internal/pipe/release/release_test.go b/internal/pipe/release/release_test.go index a788f9654..5fa0fd199 100644 --- a/internal/pipe/release/release_test.go +++ b/internal/pipe/release/release_test.go @@ -257,6 +257,7 @@ func TestRunPipeUploadFailure(t *testing.T) { folder := t.TempDir() tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) require.NoError(t, err) + require.NoError(t, tarfile.Close()) config := config.Project{ Release: config.Release{ GitHub: config.Repo{ @@ -326,6 +327,7 @@ func TestRunPipeUploadRetry(t *testing.T) { folder := t.TempDir() tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) require.NoError(t, err) + require.NoError(t, tarfile.Close()) config := config.Project{ Release: config.Release{ GitHub: config.Repo{ diff --git a/internal/pipe/sbom/sbom_test.go b/internal/pipe/sbom/sbom_test.go index f756d2dc4..44fa4f31a 100644 --- a/internal/pipe/sbom/sbom_test.go +++ b/internal/pipe/sbom/sbom_test.go @@ -227,7 +227,7 @@ func TestSBOMCatalogArtifacts(t *testing.T) { }{ { desc: "catalog errors", - expectedErrMsg: "cataloging artifacts: exit failed", + expectedErrMsg: "failed", ctx: testctx.NewWithCfg(config.Project{ SBOMs: []config.SBOM{ { @@ -407,7 +407,7 @@ func TestSBOMCatalogArtifacts(t *testing.T) { }, }, }), - expectedErrMsg: "cataloging artifacts: false failed: exit status 1: ", + expectedErrMsg: "cataloging artifacts: false failed: ", }, { desc: "catalog wrong command", @@ -451,7 +451,7 @@ func testSBOMCataloging( ) { tb.Helper() testlib.CheckPath(tb, "syft") - tmpdir := tb.TempDir() + tmpdir := testlib.Mktmp(tb) ctx.Config.Dist = tmpdir ctx.Version = "1.2.2" @@ -551,11 +551,11 @@ func testSBOMCataloging( if info.IsDir() { return nil } - relPath, err := filepath.Rel(tmpdir, path) + relPath, err := filepath.Rel(filepath.FromSlash(tmpdir), filepath.FromSlash(path)) if err != nil { return err } - gotFiles = append(gotFiles, relPath) + gotFiles = append(gotFiles, filepath.ToSlash(relPath)) return nil }), ) @@ -611,7 +611,7 @@ func Test_subprocessDistPath(t *testing.T) { t.Run(test.name, func(t *testing.T) { actual, err := subprocessDistPath(test.distDir, test.pathRelativeToCwd) require.NoError(t, err) - assert.Equal(t, test.expects, actual) + assert.Equal(t, filepath.ToSlash(test.expects), filepath.ToSlash(actual)) }) } } @@ -632,6 +632,11 @@ func Test_templateNames(t *testing.T) { wd, err := os.Getwd() require.NoError(t, err) + abs := func(path string) string { + path, _ = filepath.Abs(path) + return path + } + tests := []struct { name string dist string @@ -645,15 +650,15 @@ func Test_templateNames(t *testing.T) { name: "default configuration", artifact: art, cfg: config.SBOM{}, - dist: "/somewhere/to/dist", + dist: abs("/somewhere/to/dist"), expectedPaths: []string{ - "/somewhere/to/dist/name-it.sbom.json", + abs("/somewhere/to/dist/name-it.sbom.json"), }, expectedValues: map[string]string{ - "artifact": "to/a/place", + "artifact": filepath.FromSlash("to/a/place"), "artifactID": "id-it", - "document": "/somewhere/to/dist/name-it.sbom.json", - "document0": "/somewhere/to/dist/name-it.sbom.json", + "document": abs("/somewhere/to/dist/name-it.sbom.json"), + "document0": abs("/somewhere/to/dist/name-it.sbom.json"), }, }, { @@ -665,7 +670,7 @@ func Test_templateNames(t *testing.T) { filepath.Join(wd, "somewhere/to/dist/name-it.sbom.json"), }, expectedValues: map[string]string{ - "artifact": "to/a/place", // note: this is always relative to ${dist} + "artifact": filepath.FromSlash("to/a/place"), // note: this is always relative to ${dist} "artifactID": "id-it", "document": filepath.Join(wd, "somewhere/to/dist/name-it.sbom.json"), "document0": filepath.Join(wd, "somewhere/to/dist/name-it.sbom.json"), @@ -689,7 +694,7 @@ func Test_templateNames(t *testing.T) { filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom.json"), }, expectedValues: map[string]string{ - "artifact": "to/a/place", + "artifact": filepath.FromSlash("to/a/place"), "artifactID": "id-it", "document": filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom.json"), "document0": filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom.json"), @@ -709,7 +714,7 @@ func Test_templateNames(t *testing.T) { filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"), }, expectedValues: map[string]string{ - "artifact": "to/a/place", + "artifact": filepath.FromSlash("to/a/place"), "artifactID": "id-it", "document": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"), "document0": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"), @@ -734,7 +739,7 @@ func Test_templateNames(t *testing.T) { filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"), }, expectedValues: map[string]string{ - "artifact": "to/a/place", + "artifact": filepath.FromSlash("to/a/place"), "artifactID": "id-it", "with-env-var": "value", "custom-os": "darwin-unique", diff --git a/internal/pipe/scoop/scoop.go b/internal/pipe/scoop/scoop.go index 53ffd9e3a..3740db63f 100644 --- a/internal/pipe/scoop/scoop.go +++ b/internal/pipe/scoop/scoop.go @@ -391,7 +391,7 @@ func binaries(a artifact.Artifact) ([]string, error) { return nil, err } for _, b := range bins { - result = append(result, filepath.Join(wrap, b)) + result = append(result, filepath.ToSlash(filepath.Join(wrap, b))) } return result, nil } diff --git a/internal/pipe/sign/sign_binary_test.go b/internal/pipe/sign/sign_binary_test.go index 6e384fd70..6f536180c 100644 --- a/internal/pipe/sign/sign_binary_test.go +++ b/internal/pipe/sign/sign_binary_test.go @@ -81,6 +81,8 @@ func TestBinaryDependencies(t *testing.T) { func TestBinarySign(t *testing.T) { testlib.CheckPath(t, "gpg") + // dunno why this tries to use /usr/bin/gpg-agent on a windows machine + testlib.SkipIfWindows(t) doTest := func(tb testing.TB, sign config.Sign) []*artifact.Artifact { tb.Helper() tmpdir := tb.TempDir() diff --git a/internal/pipe/sign/sign_test.go b/internal/pipe/sign/sign_test.go index 5e947c3d9..00a7a6090 100644 --- a/internal/pipe/sign/sign_test.go +++ b/internal/pipe/sign/sign_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/goreleaser/goreleaser/v2/internal/artifact" + "github.com/goreleaser/goreleaser/v2/internal/gio" "github.com/goreleaser/goreleaser/v2/internal/git" "github.com/goreleaser/goreleaser/v2/internal/skips" "github.com/goreleaser/goreleaser/v2/internal/testctx" @@ -39,9 +40,9 @@ const ( func TestMain(m *testing.M) { rand := rand.New(rand.NewSource(time.Now().UnixNano())) - keyring = fmt.Sprintf("/tmp/gorel_gpg_test.%d", rand.Int()) + keyring = filepath.Join(os.TempDir(), fmt.Sprintf("gorel_gpg_test.%d", rand.Int())) fmt.Println("copying", originKeyring, "to", keyring) - if err := exec.Command("cp", "-Rf", originKeyring, keyring).Run(); err != nil { + if err := gio.Copy(originKeyring, keyring); err != nil { fmt.Printf("failed to copy %s to %s: %s", originKeyring, keyring, err) os.Exit(1) } @@ -96,6 +97,8 @@ func TestSignInvalidArtifacts(t *testing.T) { } func TestSignArtifacts(t *testing.T) { + // dunno why this tries to use /usr/bin/gpg-agent on a windows machine + testlib.SkipIfWindows(t) stdin := passwordUser tmplStdin := passwordUserTmpl tests := []struct { diff --git a/internal/pipe/snapcraft/snapcraft_test.go b/internal/pipe/snapcraft/snapcraft_test.go index 570dc3f0b..16da02f38 100644 --- a/internal/pipe/snapcraft/snapcraft_test.go +++ b/internal/pipe/snapcraft/snapcraft_test.go @@ -48,6 +48,8 @@ func TestRunPipeMissingInfo(t *testing.T) { } func TestRunPipe(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -99,6 +101,8 @@ func TestRunPipe(t *testing.T) { } func TestBadTemplate(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -131,6 +135,8 @@ func TestBadTemplate(t *testing.T) { } func TestRunPipeInvalidNameTemplate(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -153,6 +159,8 @@ func TestRunPipeInvalidNameTemplate(t *testing.T) { } func TestRunPipeWithName(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -187,6 +195,8 @@ func TestRunPipeWithName(t *testing.T) { } func TestRunPipeMetadata(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -342,6 +352,8 @@ func TestNoSnapcraftInPath(t *testing.T) { } func TestRunNoArguments(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -376,6 +388,8 @@ func TestRunNoArguments(t *testing.T) { } func TestCompleter(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -413,6 +427,8 @@ func TestCompleter(t *testing.T) { } func TestCommand(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -448,6 +464,8 @@ func TestCommand(t *testing.T) { } func TestExtraFile(t *testing.T) { + // snap doesn't work on windows apparently + testlib.SkipIfWindows(t) testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") diff --git a/internal/pipe/sourcearchive/source.go b/internal/pipe/sourcearchive/source.go index e41c23bbb..2136321a2 100644 --- a/internal/pipe/sourcearchive/source.go +++ b/internal/pipe/sourcearchive/source.go @@ -4,6 +4,7 @@ package sourcearchive import ( "fmt" "os" + "path" "path/filepath" "github.com/caarlos0/log" @@ -77,10 +78,10 @@ func (Pipe) Run(ctx *context.Context) error { return err } -func appendExtraFilesToArchive(ctx *context.Context, prefix, path, format string) error { - oldPath := path + ".bkp" - if err := gio.Copy(path, oldPath); err != nil { - return fmt.Errorf("failed make a backup of %q: %w", path, err) +func appendExtraFilesToArchive(ctx *context.Context, prefix, name, format string) error { + oldPath := name + ".bkp" + if err := gio.Copy(name, oldPath); err != nil { + return fmt.Errorf("failed make a backup of %q: %w", name, err) } // i could spend a lot of time trying to figure out how to append to a tar, @@ -91,7 +92,7 @@ func appendExtraFilesToArchive(ctx *context.Context, prefix, path, format string } defer of.Close() - af, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0o644) + af, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC, 0o644) if err != nil { return fmt.Errorf("could not open archive: %w", err) } @@ -107,7 +108,7 @@ func appendExtraFilesToArchive(ctx *context.Context, prefix, path, format string return err } for _, f := range files { - f.Destination = filepath.Join(prefix, f.Destination) + f.Destination = path.Join(prefix, f.Destination) if err := arch.Add(f); err != nil { return fmt.Errorf("could not add %q to archive: %w", f.Source, err) } diff --git a/internal/pipe/universalbinary/universalbinary_test.go b/internal/pipe/universalbinary/universalbinary_test.go index 61c57b1e1..05121c2c2 100644 --- a/internal/pipe/universalbinary/universalbinary_test.go +++ b/internal/pipe/universalbinary/universalbinary_test.go @@ -19,6 +19,18 @@ import ( "github.com/stretchr/testify/require" ) +var ( + echo = "echo " + touch = "touch " +) + +func init() { + if testlib.IsWindows() { + touch = "cmd.exe /c copy nul " + echo = "cmd.exe /c echo " + } +} + func TestDescription(t *testing.T) { require.NotEmpty(t, Pipe{}.String()) } @@ -175,11 +187,11 @@ func TestRun(t *testing.T) { NameTemplate: "foo", Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: "touch " + pre}, + {Cmd: touch + pre}, }, Post: []config.Hook{ - {Cmd: "touch " + post}, - {Cmd: `sh -c 'echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post'`, Output: true}, + {Cmd: touch + post}, + {Cmd: shc(`echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post`), Output: true}, }, }, }, @@ -208,11 +220,14 @@ func TestRun(t *testing.T) { ModTimestamp: fmt.Sprintf("%d", modTime.Unix()), Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: "touch " + pre}, + {Cmd: touch + pre}, }, Post: []config.Hook{ - {Cmd: "touch " + post}, - {Cmd: `sh -c 'echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post'`, Output: true}, + {Cmd: touch + post}, + { + Cmd: shc(`echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post`), + Output: true, + }, }, }, }, @@ -309,13 +324,13 @@ func TestRun(t *testing.T) { require.FileExists(t, post) bts, err := os.ReadFile(post) require.NoError(t, err) - require.Equal(t, "foo darwin all darwin_all \n", string(bts)) + require.Contains(t, string(bts), "foo darwin all darwin_all") }) t.Run("failing pre-hook", func(t *testing.T) { ctx := ctx5 ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} - ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: "echo post"}} + ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: echo + "post"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) require.ErrorContains(t, err, "pre hook failed") @@ -323,7 +338,7 @@ func TestRun(t *testing.T) { t.Run("failing post-hook", func(t *testing.T) { ctx := ctx5 - ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: "echo pre"}} + ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: echo + "pre"}} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) @@ -349,7 +364,7 @@ func TestRun(t *testing.T) { ctx.Skips[string(skips.PostBuildHooks)] = false ctx.Skips[string(skips.PreBuildHooks)] = false ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: "echo {{.Env.FOO}}", + Cmd: echo + "{{.Env.FOO}}", Env: []string{"FOO=foo-{{.Tag}}"}, }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} @@ -361,7 +376,7 @@ func TestRun(t *testing.T) { ctx.Skips[string(skips.PostBuildHooks)] = false ctx.Skips[string(skips.PreBuildHooks)] = false ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: "echo blah", + Cmd: echo + "blah", Env: []string{"FOO=foo-{{.Tag}"}, }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} @@ -371,7 +386,7 @@ func TestRun(t *testing.T) { t.Run("hook with bad dir tmpl", func(t *testing.T) { ctx := ctx5 ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: "echo blah", + Cmd: echo + "blah", Dir: "{{.Tag}", }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} @@ -381,7 +396,7 @@ func TestRun(t *testing.T) { t.Run("hook with bad cmd tmpl", func(t *testing.T) { ctx := ctx5 ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: "echo blah-{{.Tag }", + Cmd: echo + "blah-{{.Tag }", }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) @@ -414,3 +429,10 @@ func checkUniversalBinary(tb testing.TB, unibin *artifact.Artifact) { require.NoError(tb, err) require.Len(tb, f.Arches, 2) } + +func shc(cmd string) string { + if testlib.IsWindows() { + return fmt.Sprintf("cmd.exe /c '%s'", cmd) + } + return fmt.Sprintf("sh -c '%s'", cmd) +} diff --git a/internal/pipe/upload/upload_test.go b/internal/pipe/upload/upload_test.go index f10429137..f357c6e84 100644 --- a/internal/pipe/upload/upload_test.go +++ b/internal/pipe/upload/upload_test.go @@ -362,7 +362,11 @@ func TestRunPipe_ServerDown(t *testing.T) { Name: "bin.tar.gz", Path: tarfile.Name(), }) - require.ErrorIs(t, Pipe{}.Publish(ctx), syscall.ECONNREFUSED) + err = Pipe{}.Publish(ctx) + require.Error(t, err) + if !testlib.IsWindows() { + require.ErrorIs(t, err, syscall.ECONNREFUSED) + } } func TestRunPipe_TargetTemplateError(t *testing.T) { diff --git a/internal/pipe/upx/upx.go b/internal/pipe/upx/upx.go index 4154bb5d3..ba501fe71 100644 --- a/internal/pipe/upx/upx.go +++ b/internal/pipe/upx/upx.go @@ -96,6 +96,7 @@ var knownExceptions = []string{ "AlreadyPackedException", "NotCompressibleException", "UnknownExecutableFormatException", + "IOException", } func findBinaries(ctx *context.Context, upx config.UPX) []*artifact.Artifact { diff --git a/internal/shell/shell_test.go b/internal/shell/shell_test.go index 90d33d668..d074e285d 100644 --- a/internal/shell/shell_test.go +++ b/internal/shell/shell_test.go @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + package shell_test import ( diff --git a/internal/shell/shell_windows_test.go b/internal/shell/shell_windows_test.go new file mode 100644 index 000000000..1f3e01f41 --- /dev/null +++ b/internal/shell/shell_windows_test.go @@ -0,0 +1,28 @@ +//go:build windows +// +build windows + +package shell_test + +import ( + "testing" + + "github.com/goreleaser/goreleaser/v2/internal/shell" + "github.com/goreleaser/goreleaser/v2/internal/testctx" + "github.com/stretchr/testify/require" +) + +func TestRunCommandWindows(t *testing.T) { + t.Run("simple", func(t *testing.T) { + require.NoError(t, shell.Run(testctx.New(), "", []string{"cmd.exe", "/c", "echo", "oi"}, []string{}, false)) + }) + + t.Run("cmd failed", func(t *testing.T) { + require.EqualError( + t, + shell.Run(testctx.New(), "", []string{"cmd.exe", "/c", "exit /b 1"}, []string{}, false), + `shell: 'cmd.exe /c exit /b 1': exit status 1: [no output]`, + ) + }) + + // TODO: more tests for windows +} diff --git a/internal/testlib/docker.go b/internal/testlib/docker.go index 48b9a418a..41273979d 100644 --- a/internal/testlib/docker.go +++ b/internal/testlib/docker.go @@ -14,6 +14,17 @@ var ( dockerPool *dockertest.Pool ) +type skipper func(args ...any) + +func (s skipper) Fatal(...any) { + s("docker is not available") +} + +func CheckDocker(tb testing.TB) { + tb.Helper() + MustDockerPool(skipper(tb.Skip)) +} + // MustDockerPool gets a single dockertet.Pool. func MustDockerPool(f Fataler) *dockertest.Pool { dockerPoolOnce.Do(func() { diff --git a/internal/testlib/git.go b/internal/testlib/git.go index 0d176e78d..9d5efb87b 100644 --- a/internal/testlib/git.go +++ b/internal/testlib/git.go @@ -110,7 +110,7 @@ func GitMakeBareRepository(tb testing.TB) string { ".", ) require.NoError(tb, err) - return dir + return filepath.ToSlash(dir) } func MakeNewSSHKey(tb testing.TB, pass string) string { diff --git a/internal/testlib/path.go b/internal/testlib/path.go index 90c790dc1..7314274ee 100644 --- a/internal/testlib/path.go +++ b/internal/testlib/path.go @@ -3,6 +3,7 @@ package testlib import ( "os" "os/exec" + "runtime" "testing" ) @@ -22,3 +23,14 @@ func InPath(cmd string) bool { _, err := exec.LookPath(cmd) return err == nil } + +// IsWindows returns true if current OS is Windows. +func IsWindows() bool { return runtime.GOOS == "windows" } + +// SkipIfWindows skips the test if runtime OS is windows. +func SkipIfWindows(tb testing.TB) { + tb.Helper() + if IsWindows() { + tb.Skip("test skipped on windows") + } +} diff --git a/internal/testlib/path_test.go b/internal/testlib/path_test.go index d34557f5a..722c709e3 100644 --- a/internal/testlib/path_test.go +++ b/internal/testlib/path_test.go @@ -19,7 +19,11 @@ func TestCheckPath(t *testing.T) { t.Run("in path", func(t *testing.T) { requireSkipped(t, false) - CheckPath(t, "echo") + if IsWindows() { + CheckPath(t, "cmd.exe") + } else { + CheckPath(t, "echo") + } }) t.Run("not in path", func(t *testing.T) { diff --git a/internal/tmpl/tmpl_test.go b/internal/tmpl/tmpl_test.go index 6d59f045e..9f7e31d50 100644 --- a/internal/tmpl/tmpl_test.go +++ b/internal/tmpl/tmpl_test.go @@ -90,7 +90,6 @@ func TestWithArtifact(t *testing.T) { "artifact ext: .exe": "artifact ext: {{ .ArtifactExt }}", "artifact path: /tmp/foo.exe": "artifact path: {{ .ArtifactPath }}", "artifact basename: foo.exe": "artifact basename: {{ base .ArtifactPath }}", - "artifact dir: /tmp": "artifact dir: {{ dir .ArtifactPath }}", "2023": `{{ .Now.Format "2006" }}`, "2023-03-09T02:06:02Z": `{{ .Date }}`, "1678327562": `{{ .Timestamp }}`, @@ -106,6 +105,8 @@ func TestWithArtifact(t *testing.T) { "env foo is set: true": `env foo is set: {{ isEnvSet "FOO" }}`, "/foo%2Fbar": `/{{ urlPathEscape .Env.WITH_SLASHES}}`, + "artifact dir: " + filepath.FromSlash("/tmp"): "artifact dir: {{ dir .ArtifactPath }}", + "remove this": "{{ filter .Env.MULTILINE \".*remove.*\" }}", "something with\nmultiple lines\nto test things": "{{ reverseFilter .Env.MULTILINE \".*remove.*\" }}", diff --git a/pkg/archive/tar/tar_test.go b/pkg/archive/tar/tar_test.go index 1b0e526bf..03a2c681e 100644 --- a/pkg/archive/tar/tar_test.go +++ b/pkg/archive/tar/tar_test.go @@ -88,9 +88,18 @@ func TestTarFile(t *testing.T) { } require.NoError(t, err) paths = append(paths, next.Name) + if testlib.IsWindows() { + // both of the following checks don't work on windows. + continue + } if next.Name == "sub1/executable" { - ex := next.FileInfo().Mode()&0o111 != 0 - require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) + require.NotEqualf( + t, + 0, + next.FileInfo().Mode()&0o111, + "expected executable perms, got %s", + next.FileInfo().Mode().String(), + ) } if next.Name == "link.txt" { require.Equal(t, "regular.txt", next.Linkname) diff --git a/pkg/archive/targz/targz_test.go b/pkg/archive/targz/targz_test.go index 679ee2943..809a32ef4 100644 --- a/pkg/archive/targz/targz_test.go +++ b/pkg/archive/targz/targz_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/stretchr/testify/require" ) @@ -87,9 +88,17 @@ func TestTarGzFile(t *testing.T) { } require.NoError(t, err) paths = append(paths, next.Name) + if testlib.IsWindows() { + // both of the following checks don't work on windows. + continue + } if next.Name == "sub1/executable" { - ex := next.FileInfo().Mode()&0o111 != 0 - require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) + require.NotEqualf( + t, + 0, next.FileInfo().Mode()&0o111, + "expected executable perms, got %s", + next.FileInfo().Mode().String(), + ) } if next.Name == "link.txt" { require.Equal(t, "regular.txt", next.Linkname) diff --git a/pkg/archive/tarxz/tarxz_test.go b/pkg/archive/tarxz/tarxz_test.go index 033f18dfd..40925ab36 100644 --- a/pkg/archive/tarxz/tarxz_test.go +++ b/pkg/archive/tarxz/tarxz_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/stretchr/testify/require" "github.com/ulikunitz/xz" @@ -86,9 +87,18 @@ func TestTarXzFile(t *testing.T) { } require.NoError(t, err) paths = append(paths, next.Name) + if testlib.IsWindows() { + // both of the following checks don't work on windows. + continue + } if next.Name == "sub1/executable" { - ex := next.FileInfo().Mode()&0o111 != 0 - require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) + require.NotEqualf( + t, + 0, + next.FileInfo().Mode()&0o111, + "expected executable perms, got %s", + next.FileInfo().Mode().String(), + ) } if next.Name == "link.txt" { require.Equal(t, "regular.txt", next.Linkname) diff --git a/pkg/archive/tarzst/tarzst_test.go b/pkg/archive/tarzst/tarzst_test.go index 3f480ac1f..4ff863d42 100644 --- a/pkg/archive/tarzst/tarzst_test.go +++ b/pkg/archive/tarzst/tarzst_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/klauspost/compress/zstd" "github.com/stretchr/testify/require" @@ -86,9 +87,18 @@ func TestTarZstFile(t *testing.T) { } require.NoError(t, err) paths = append(paths, next.Name) + if testlib.IsWindows() { + // both of the following checks don't work on windows. + continue + } if next.Name == "sub1/executable" { - ex := next.FileInfo().Mode()&0o111 != 0 - require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) + require.NotEqualf( + t, + 0, + next.FileInfo().Mode()&0o111, + "expected executable perms, got %s", + next.FileInfo().Mode().String(), + ) } if next.Name == "link.txt" { require.Equal(t, "regular.txt", next.Linkname) diff --git a/pkg/archive/zip/zip_test.go b/pkg/archive/zip/zip_test.go index 46ad8e673..6f40ea0d8 100644 --- a/pkg/archive/zip/zip_test.go +++ b/pkg/archive/zip/zip_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/stretchr/testify/require" ) @@ -85,9 +86,14 @@ func TestZipFile(t *testing.T) { paths := make([]string, len(r.File)) for i, zf := range r.File { paths[i] = zf.Name - if zf.Name == "sub1/executable" { - ex := zf.Mode()&0o111 != 0 - require.True(t, ex, "expected executable permissions, got %s", zf.Mode()) + if zf.Name == "sub1/executable" && !testlib.IsWindows() { + require.NotEqualf( + t, + 0, + zf.Mode()&0o111, + "expected executable perms, got %s", + zf.Mode().String(), + ) } if zf.Name == "link.txt" { require.NotEqual(t, 0, zf.FileInfo().Mode()&os.ModeSymlink) diff --git a/www/docs/customization/nfpm.md b/www/docs/customization/nfpm.md index f1d43d13e..cb1781f2c 100644 --- a/www/docs/customization/nfpm.md +++ b/www/docs/customization/nfpm.md @@ -473,7 +473,7 @@ nfpms: # Custom configuration applied only to the IPK packager. # - # Since: v2.1 + # Since: v2.1. ipk: # The ABI version to specify. # From bc32cd6fbfd74d4ff5edd68926c4eea3ed434a71 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sat, 16 Nov 2024 15:31:22 +0200 Subject: [PATCH 4/9] ci: update golangci-lint to v1.62 (#5288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the version of golangci-lint to the latest [v1.62](https://github.com/golangci/golangci-lint/releases/tag/v1.62.0) and fixes appeared lint issues: ``` ❯ golangci-lint run internal/archivefiles/archivefiles.go:144:2: redefines-builtin-id: redefinition of the built-in function min (revive) var min int ^ internal/archivefiles/archivefiles.go:146:3: redefines-builtin-id: redefinition of the built-in function min (revive) min = len(b) ^ internal/archivefiles/archivefiles.go:148:3: redefines-builtin-id: redefinition of the built-in function min (revive) min = len(a) ^ cmd/root.go:152:29: redefines-builtin-id: redefinition of the built-in type rune (revive) func timedRunE(verb string, rune func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error { ^ internal/git/config_test.go:39:2: contains: use require.Contains (testifylint) require.True(t, strings.Contains(gitCfg, "branch.relative_branch.remote=.")) ^ ``` --- .github/workflows/lint.yml | 2 +- cmd/root.go | 4 ++-- internal/archivefiles/archivefiles.go | 2 ++ internal/git/config_test.go | 3 +-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index eaebffa8f..15b682509 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,4 +26,4 @@ jobs: uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: args: --timeout=5m - version: v1.60 + version: v1.62 diff --git a/cmd/root.go b/cmd/root.go index 2d10e73e6..a310204d4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -149,11 +149,11 @@ func deprecateWarn(ctx *context.Context) { } } -func timedRunE(verb string, rune func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error { +func timedRunE(verb string, runE func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { start := time.Now() - if err := rune(cmd, args); err != nil { + if err := runE(cmd, args); err != nil { return wrapError(err, boldStyle.Render(fmt.Sprintf("%s failed after %s", verb, time.Since(start).Truncate(time.Second)))) } diff --git a/internal/archivefiles/archivefiles.go b/internal/archivefiles/archivefiles.go index 4de1fca0a..331fc4c03 100644 --- a/internal/archivefiles/archivefiles.go +++ b/internal/archivefiles/archivefiles.go @@ -140,6 +140,8 @@ func longestCommonPrefix(strs []string) string { } // copied from nfpm +// +//nolint:revive // redefines-builtin-id func strlcp(a, b string) string { var min int if len(a) > len(b) { diff --git a/internal/git/config_test.go b/internal/git/config_test.go index add24ec6a..b7ebc2b19 100644 --- a/internal/git/config_test.go +++ b/internal/git/config_test.go @@ -2,7 +2,6 @@ package git_test import ( "context" - "strings" "testing" "github.com/goreleaser/goreleaser/v2/internal/git" @@ -36,7 +35,7 @@ func TestRelativeRemote(t *testing.T) { require.NoError(t, err) gitCfg, err := git.Run(ctx, "config", "--local", "--list") require.NoError(t, err) - require.True(t, strings.Contains(gitCfg, "branch.relative_branch.remote=.")) + require.Contains(t, gitCfg, "branch.relative_branch.remote=.") repo, err := git.ExtractRepoFromConfig(ctx) require.NoError(t, err) require.Equal(t, "goreleaser/goreleaser", repo.String()) From 0832d81c2d6ab4a2a4535332ed2d77a449ea9df5 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Sat, 16 Nov 2024 14:31:48 +0100 Subject: [PATCH 5/9] chore(aur): remove dead code about armv6 (#5280) Follows https://github.com/goreleaser/goreleaser/pull/4695, remove dead code about armv6. --- internal/pipe/aur/aur.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/pipe/aur/aur.go b/internal/pipe/aur/aur.go index 3e7641668..8dd5e26ac 100644 --- a/internal/pipe/aur/aur.go +++ b/internal/pipe/aur/aur.go @@ -272,8 +272,6 @@ func toPkgBuildArch(arch string) string { return "i686" case "arm64": return "aarch64" - case "arm6": - return "armv6h" case "arm7": return "armv7h" default: From cd1c5fb9928399c38729533e053c99897dc96a86 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 16 Nov 2024 10:33:19 -0300 Subject: [PATCH 6/9] chore(deps): update nfpm to v2.41.1 Signed-off-by: Carlos Alexandro Becker --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e5bcf4a2f..3b0c4cfb6 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/google/ko v0.17.1 github.com/google/uuid v1.6.0 github.com/goreleaser/fileglob v1.3.0 - github.com/goreleaser/nfpm/v2 v2.41.1-0.20241110134201-59b75b2a5a2e + github.com/goreleaser/nfpm/v2 v2.41.1 github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d github.com/hashicorp/go-multierror v1.1.1 github.com/invopop/jsonschema v0.12.0 diff --git a/go.sum b/go.sum index b91f63bea..bedc986c6 100644 --- a/go.sum +++ b/go.sum @@ -461,8 +461,8 @@ github.com/goreleaser/chglog v0.6.1 h1:NZKiX8l0FTQPRzBgKST7knvNZmZ04f7PEGkN2wInf github.com/goreleaser/chglog v0.6.1/go.mod h1:Bnnfo07jMZkaAb0uRNASMZyOsX6ROW6X1qbXqN3guUo= github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I= github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= -github.com/goreleaser/nfpm/v2 v2.41.1-0.20241110134201-59b75b2a5a2e h1:xajOCis2WSRoM8XmWFQZFKbjUYJ0PMyFI8QTvIsILLo= -github.com/goreleaser/nfpm/v2 v2.41.1-0.20241110134201-59b75b2a5a2e/go.mod h1:VPc5kF5OgfA+BosV/A2aB+Vg34honjWvp0Vt8ogsSi0= +github.com/goreleaser/nfpm/v2 v2.41.1 h1:4tyZ9b817msLuyGKw53ed3suZNApkGHVZDekdGe8ZEE= +github.com/goreleaser/nfpm/v2 v2.41.1/go.mod h1:VPc5kF5OgfA+BosV/A2aB+Vg34honjWvp0Vt8ogsSi0= github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d h1:bBLVbv03RLdskOHJfNkEJIMm+85b4E3GJkEEVXIu48k= github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d/go.mod h1:b/JsMZEZCcW7WWjR1+XyIFYSFizwmAYpxvvh3ZcauVE= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= From 3c55f2bb77c5b0ebf217c16871595df9e5f0b651 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 16 Nov 2024 10:57:48 -0300 Subject: [PATCH 7/9] test: improving tests on windows Signed-off-by: Carlos Alexandro Becker --- cmd/init_test.go | 2 +- internal/pipe/before/before_test.go | 5 +-- internal/pipe/blob/blob_minio_test.go | 12 +++--- internal/pipe/build/build_test.go | 40 +++++++---------- internal/pipe/docker/docker_test.go | 2 +- internal/pipe/env/env_test.go | 2 +- internal/pipe/gomod/gomod_proxy_test.go | 2 +- internal/pipe/ko/ko_test.go | 4 +- internal/pipe/nix/nix_test.go | 6 +-- internal/pipe/sign/sign_binary_test.go | 3 +- internal/pipe/sign/sign_test.go | 3 +- internal/pipe/snapcraft/snapcraft_test.go | 27 ++++-------- .../universalbinary/universalbinary_test.go | 43 ++++++------------- internal/shell/shell_test.go | 27 ++++++++---- internal/shell/shell_windows_test.go | 28 ------------ internal/testlib/path.go | 38 +++++++++++++++- 16 files changed, 109 insertions(+), 135 deletions(-) delete mode 100644 internal/shell/shell_windows_test.go diff --git a/cmd/init_test.go b/cmd/init_test.go index a5aa22397..28ca1ab58 100644 --- a/cmd/init_test.go +++ b/cmd/init_test.go @@ -56,7 +56,7 @@ func TestInitGitIgnoreExists(t *testing.T) { } func TestInitFileError(t *testing.T) { - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "windows permissions don't work the same way") folder := setupInitTest(t) cmd := newInitCmd().cmd path := filepath.Join(folder, "nope.yaml") diff --git a/internal/pipe/before/before_test.go b/internal/pipe/before/before_test.go index 8d8c5df38..98fd11609 100644 --- a/internal/pipe/before/before_test.go +++ b/internal/pipe/before/before_test.go @@ -73,7 +73,6 @@ func TestRunPipeFail(t *testing.T) { } func TestRunWithEnv(t *testing.T) { - testlib.SkipIfWindows(t) f := filepath.Join(t.TempDir(), "testfile") require.NoError(t, Pipe{}.Run(testctx.NewWithCfg( config.Project{ @@ -81,7 +80,7 @@ func TestRunWithEnv(t *testing.T) { "TEST_FILE=" + f, }, Before: config.Before{ - Hooks: []string{"touch {{ .Env.TEST_FILE }}"}, + Hooks: []string{testlib.Touch("{{ .Env.TEST_FILE }}")}, }, }, ))) @@ -92,7 +91,7 @@ func TestInvalidTemplate(t *testing.T) { testlib.RequireTemplateError(t, Pipe{}.Run(testctx.NewWithCfg( config.Project{ Before: config.Before{ - Hooks: []string{"touch {{ .fasdsd }"}, + Hooks: []string{"doesnt-matter {{ .fasdsd }"}, }, }, ))) diff --git a/internal/pipe/blob/blob_minio_test.go b/internal/pipe/blob/blob_minio_test.go index 7c722ff14..d0c626615 100644 --- a/internal/pipe/blob/blob_minio_test.go +++ b/internal/pipe/blob/blob_minio_test.go @@ -76,7 +76,7 @@ func TestMain(m *testing.M) { func TestMinioUpload(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "minio image not available for windows") name := "basic" directory := t.TempDir() srcpath := filepath.Join(directory, "source.tar.gz") @@ -183,7 +183,7 @@ func TestMinioUpload(t *testing.T) { func TestMinioUploadCustomBucketID(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "minio image not available for windows") name := "fromenv" directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") @@ -221,7 +221,7 @@ func TestMinioUploadCustomBucketID(t *testing.T) { func TestMinioUploadExtraFilesOnly(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "minio image not available for windows") name := "only-extra-files" directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") @@ -268,7 +268,7 @@ func TestMinioUploadExtraFilesOnly(t *testing.T) { func TestMinioUploadRootDirectory(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "minio image not available for windows") name := "rootdir" directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") @@ -305,7 +305,7 @@ func TestMinioUploadRootDirectory(t *testing.T) { func TestMinioUploadInvalidCustomBucketID(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "minio image not available for windows") directory := t.TempDir() tgzpath := filepath.Join(directory, "bin.tar.gz") debpath := filepath.Join(directory, "bin.deb") @@ -339,7 +339,7 @@ func TestMinioUploadInvalidCustomBucketID(t *testing.T) { func TestMinioUploadSkip(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "minio image not available for windows") name := "basic" directory := t.TempDir() debpath := filepath.Join(directory, "bin.deb") diff --git a/internal/pipe/build/build_test.go b/internal/pipe/build/build_test.go index 8173625ea..b658a82f0 100644 --- a/internal/pipe/build/build_test.go +++ b/internal/pipe/build/build_test.go @@ -22,18 +22,8 @@ import ( var ( errFailedBuild = errors.New("fake builder failed") errFailedDefault = errors.New("fake builder defaults failed") - - touch = "touch " - echo = "echo " ) -func init() { - if testlib.IsWindows() { - touch = "cmd.exe /c copy nul " - echo = "cmd.exe /c echo " - } -} - type fakeBuilder struct { fail bool failDefault bool @@ -146,12 +136,12 @@ func TestRunFullPipe(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: touch + pre}, - {Cmd: touch + " pre_{{ .Env.THE_OS}}"}, + {Cmd: testlib.Touch(pre)}, + {Cmd: testlib.Touch("pre_{{ .Env.THE_OS}}")}, }, Post: []config.Hook{ - {Cmd: touch + post}, - {Cmd: touch + " post_{{ .Env.THE_OS}}"}, + {Cmd: testlib.Touch(post)}, + {Cmd: testlib.Touch("post_{{ .Env.THE_OS}}")}, }, }, Targets: []string{"linux_amd64"}, @@ -188,10 +178,10 @@ func TestRunFullPipeFail(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: touch + pre}, + {Cmd: testlib.Touch(pre)}, }, Post: []config.Hook{ - {Cmd: touch + post}, + {Cmd: testlib.Touch(post)}, }, }, Targets: []string{"linux_amd64"}, @@ -220,7 +210,7 @@ func TestRunPipeFailingHooks(t *testing.T) { t.Run("pre-hook", func(t *testing.T) { ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} - ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: echo + " post"}} + ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: testlib.Echo("post")}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) @@ -228,7 +218,7 @@ func TestRunPipeFailingHooks(t *testing.T) { }) t.Run("post-hook", func(t *testing.T) { ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) - ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: echo + " pre"}} + ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: testlib.Echo("pre")}} ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) @@ -241,7 +231,7 @@ func TestRunPipeFailingHooks(t *testing.T) { testctx.WithCurrentTag("2.4.5"), testctx.Skip(skips.PostBuildHooks), ) - ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: echo + " pre"}} + ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: testlib.Echo("pre")}} ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} require.NoError(t, Pipe{}.Run(ctx)) }) @@ -252,7 +242,7 @@ func TestRunPipeFailingHooks(t *testing.T) { testctx.WithCurrentTag("2.4.5"), testctx.Skip(skips.PreBuildHooks), ) - ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: echo + " pre"}} + ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: testlib.Echo("pre")}} ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} require.NoError(t, Pipe{}.Run(ctx)) }) @@ -515,10 +505,10 @@ func TestBuild_hooksKnowGoosGoarch(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: touch + " pre-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, + {Cmd: testlib.Touch("pre-hook-{{.Arch}}-{{.Os}}"), Dir: tmpDir}, }, Post: config.Hooks{ - {Cmd: touch + " post-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, + {Cmd: testlib.Touch(" post-hook-{{.Arch}}-{{.Os}}"), Dir: tmpDir}, }, }, } @@ -548,10 +538,10 @@ func TestPipeOnBuild_hooksRunPerTarget(t *testing.T) { }, Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: touch + " pre-hook-{{.Target}}", Dir: tmpDir}, + {Cmd: testlib.Touch("pre-hook-{{.Target}}"), Dir: tmpDir}, }, Post: config.Hooks{ - {Cmd: touch + " post-hook-{{.Target}}", Dir: tmpDir}, + {Cmd: testlib.Touch("post-hook-{{.Target}}"), Dir: tmpDir}, }, }, } @@ -747,7 +737,7 @@ func TestBuildOptionsForTarget(t *testing.T) { } func TestRunHookFailWithLogs(t *testing.T) { - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "subshells don't work in windows") folder := testlib.Mktmp(t) config := config.Project{ Dist: folder, diff --git a/internal/pipe/docker/docker_test.go b/internal/pipe/docker/docker_test.go index afc5d6796..e7f0493c2 100644 --- a/internal/pipe/docker/docker_test.go +++ b/internal/pipe/docker/docker_test.go @@ -35,7 +35,7 @@ func start(tb testing.TB) { // TODO: this test is too big... split in smaller tests? Mainly the manifest ones... func TestRunPipe(t *testing.T) { testlib.CheckPath(t, "docker") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "images only available for windows") type errChecker func(*testing.T, error) shouldErr := func(msg string) errChecker { return func(t *testing.T, err error) { diff --git a/internal/pipe/env/env_test.go b/internal/pipe/env/env_test.go index 06b7b1f98..3366f39e3 100644 --- a/internal/pipe/env/env_test.go +++ b/internal/pipe/env/env_test.go @@ -292,7 +292,7 @@ func TestLoadEnv(t *testing.T) { require.Equal(t, "123", v) }) t.Run("env file is not readable", func(t *testing.T) { - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "permissions work differently in windows") f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) fmt.Fprintf(f, "123") diff --git a/internal/pipe/gomod/gomod_proxy_test.go b/internal/pipe/gomod/gomod_proxy_test.go index 849d02f38..38e54da9c 100644 --- a/internal/pipe/gomod/gomod_proxy_test.go +++ b/internal/pipe/gomod/gomod_proxy_test.go @@ -175,7 +175,7 @@ func TestGoModProxy(t *testing.T) { }) t.Run("no perms", func(t *testing.T) { - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "windows permissions work differently") for file, mode := range map[string]os.FileMode{ "go.mod": 0o500, "go.sum": 0o500, diff --git a/internal/pipe/ko/ko_test.go b/internal/pipe/ko/ko_test.go index fb755c8d6..ccf7e5cec 100644 --- a/internal/pipe/ko/ko_test.go +++ b/internal/pipe/ko/ko_test.go @@ -156,7 +156,7 @@ func TestPublishPipeNoMatchingBuild(t *testing.T) { } func TestPublishPipeSuccess(t *testing.T) { - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "ko doesn't work in windows") testlib.CheckPath(t, "docker") testlib.StartRegistry(t, "ko_registry", registryPort) @@ -412,7 +412,7 @@ func TestPublishPipeSuccess(t *testing.T) { } func TestSnapshot(t *testing.T) { - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "ko doesn't work in windows") testlib.CheckDocker(t) ctx := testctx.NewWithCfg(config.Project{ ProjectName: "test", diff --git a/internal/pipe/nix/nix_test.go b/internal/pipe/nix/nix_test.go index 41cbc71f1..fb655b1cb 100644 --- a/internal/pipe/nix/nix_test.go +++ b/internal/pipe/nix/nix_test.go @@ -37,7 +37,7 @@ func TestSkip(t *testing.T) { }) t.Run("nix-all-good", func(t *testing.T) { testlib.CheckPath(t, "nix-prefetch-url") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "nix doesn't work on windows") require.False(t, NewPublish().Skip(testctx.NewWithCfg(config.Project{ Nix: []config.Nix{{}}, }))) @@ -66,7 +66,7 @@ func TestPrefetcher(t *testing.T) { }) t.Run("valid", func(t *testing.T) { testlib.CheckPath(t, "nix-prefetch-url") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "nix doesn't work on windows") sha, err := publishShaPrefetcher{nixPrefetchURLBin}.Prefetch("https://github.com/goreleaser/goreleaser/releases/download/v1.18.2/goreleaser_Darwin_arm64.tar.gz") require.NoError(t, err) require.Equal(t, "0girjxp07srylyq36xk1ska8p68m2fhp05xgyv4wkcl61d6rzv3y", sha) @@ -83,7 +83,7 @@ func TestPrefetcher(t *testing.T) { }) t.Run("valid", func(t *testing.T) { testlib.CheckPath(t, "nix-prefetch-url") - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "nix doesn't work on windows") require.True(t, publishShaPrefetcher{nixPrefetchURLBin}.Available()) }) }) diff --git a/internal/pipe/sign/sign_binary_test.go b/internal/pipe/sign/sign_binary_test.go index 6f536180c..39e5db594 100644 --- a/internal/pipe/sign/sign_binary_test.go +++ b/internal/pipe/sign/sign_binary_test.go @@ -81,8 +81,7 @@ func TestBinaryDependencies(t *testing.T) { func TestBinarySign(t *testing.T) { testlib.CheckPath(t, "gpg") - // dunno why this tries to use /usr/bin/gpg-agent on a windows machine - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "tries to use /usr/bin/gpg-agent") doTest := func(tb testing.TB, sign config.Sign) []*artifact.Artifact { tb.Helper() tmpdir := tb.TempDir() diff --git a/internal/pipe/sign/sign_test.go b/internal/pipe/sign/sign_test.go index 00a7a6090..3b4f5098c 100644 --- a/internal/pipe/sign/sign_test.go +++ b/internal/pipe/sign/sign_test.go @@ -97,8 +97,7 @@ func TestSignInvalidArtifacts(t *testing.T) { } func TestSignArtifacts(t *testing.T) { - // dunno why this tries to use /usr/bin/gpg-agent on a windows machine - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "tries to use /usr/bin/gpg-agent") stdin := passwordUser tmplStdin := passwordUserTmpl tests := []struct { diff --git a/internal/pipe/snapcraft/snapcraft_test.go b/internal/pipe/snapcraft/snapcraft_test.go index 16da02f38..f5498d270 100644 --- a/internal/pipe/snapcraft/snapcraft_test.go +++ b/internal/pipe/snapcraft/snapcraft_test.go @@ -48,8 +48,7 @@ func TestRunPipeMissingInfo(t *testing.T) { } func TestRunPipe(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -101,8 +100,7 @@ func TestRunPipe(t *testing.T) { } func TestBadTemplate(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -135,8 +133,7 @@ func TestBadTemplate(t *testing.T) { } func TestRunPipeInvalidNameTemplate(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -159,8 +156,7 @@ func TestRunPipeInvalidNameTemplate(t *testing.T) { } func TestRunPipeWithName(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -195,8 +191,7 @@ func TestRunPipeWithName(t *testing.T) { } func TestRunPipeMetadata(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -352,8 +347,7 @@ func TestNoSnapcraftInPath(t *testing.T) { } func TestRunNoArguments(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -388,8 +382,7 @@ func TestRunNoArguments(t *testing.T) { } func TestCompleter(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -427,8 +420,7 @@ func TestCompleter(t *testing.T) { } func TestCommand(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") @@ -464,8 +456,7 @@ func TestCommand(t *testing.T) { } func TestExtraFile(t *testing.T) { - // snap doesn't work on windows apparently - testlib.SkipIfWindows(t) + testlib.SkipIfWindows(t, "snap doesn't work in windows") testlib.CheckPath(t, "snapcraft") folder := t.TempDir() dist := filepath.Join(folder, "dist") diff --git a/internal/pipe/universalbinary/universalbinary_test.go b/internal/pipe/universalbinary/universalbinary_test.go index 05121c2c2..56ad36b1d 100644 --- a/internal/pipe/universalbinary/universalbinary_test.go +++ b/internal/pipe/universalbinary/universalbinary_test.go @@ -19,18 +19,6 @@ import ( "github.com/stretchr/testify/require" ) -var ( - echo = "echo " - touch = "touch " -) - -func init() { - if testlib.IsWindows() { - touch = "cmd.exe /c copy nul " - echo = "cmd.exe /c echo " - } -} - func TestDescription(t *testing.T) { require.NotEmpty(t, Pipe{}.String()) } @@ -187,11 +175,11 @@ func TestRun(t *testing.T) { NameTemplate: "foo", Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: touch + pre}, + {Cmd: testlib.Touch(pre)}, }, Post: []config.Hook{ - {Cmd: touch + post}, - {Cmd: shc(`echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post`), Output: true}, + {Cmd: testlib.Touch(post)}, + {Cmd: testlib.ShC(`echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post`), Output: true}, }, }, }, @@ -220,12 +208,12 @@ func TestRun(t *testing.T) { ModTimestamp: fmt.Sprintf("%d", modTime.Unix()), Hooks: config.BuildHookConfig{ Pre: []config.Hook{ - {Cmd: touch + pre}, + {Cmd: testlib.Touch(pre)}, }, Post: []config.Hook{ - {Cmd: touch + post}, + {Cmd: testlib.Touch(post)}, { - Cmd: shc(`echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post`), + Cmd: testlib.ShC(`echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post`), Output: true, }, }, @@ -330,7 +318,7 @@ func TestRun(t *testing.T) { t.Run("failing pre-hook", func(t *testing.T) { ctx := ctx5 ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} - ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: echo + "post"}} + ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: "doesnt-matter"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) require.ErrorContains(t, err, "pre hook failed") @@ -338,7 +326,7 @@ func TestRun(t *testing.T) { t.Run("failing post-hook", func(t *testing.T) { ctx := ctx5 - ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: echo + "pre"}} + ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: testlib.Echo("pre")}} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} err := Pipe{}.Run(ctx) require.ErrorIs(t, err, exec.ErrNotFound) @@ -364,7 +352,7 @@ func TestRun(t *testing.T) { ctx.Skips[string(skips.PostBuildHooks)] = false ctx.Skips[string(skips.PreBuildHooks)] = false ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: echo + "{{.Env.FOO}}", + Cmd: testlib.Echo("{{.Env.FOO}}"), Env: []string{"FOO=foo-{{.Tag}}"}, }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} @@ -376,7 +364,7 @@ func TestRun(t *testing.T) { ctx.Skips[string(skips.PostBuildHooks)] = false ctx.Skips[string(skips.PreBuildHooks)] = false ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: echo + "blah", + Cmd: testlib.Echo("blah"), Env: []string{"FOO=foo-{{.Tag}"}, }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} @@ -386,7 +374,7 @@ func TestRun(t *testing.T) { t.Run("hook with bad dir tmpl", func(t *testing.T) { ctx := ctx5 ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: echo + "blah", + Cmd: testlib.Echo("blah"), Dir: "{{.Tag}", }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} @@ -396,7 +384,7 @@ func TestRun(t *testing.T) { t.Run("hook with bad cmd tmpl", func(t *testing.T) { ctx := ctx5 ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ - Cmd: echo + "blah-{{.Tag }", + Cmd: testlib.Echo("blah-{{.Tag }"), }} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) @@ -429,10 +417,3 @@ func checkUniversalBinary(tb testing.TB, unibin *artifact.Artifact) { require.NoError(tb, err) require.Len(tb, f.Arches, 2) } - -func shc(cmd string) string { - if testlib.IsWindows() { - return fmt.Sprintf("cmd.exe /c '%s'", cmd) - } - return fmt.Sprintf("sh -c '%s'", cmd) -} diff --git a/internal/shell/shell_test.go b/internal/shell/shell_test.go index d074e285d..69ff01055 100644 --- a/internal/shell/shell_test.go +++ b/internal/shell/shell_test.go @@ -1,31 +1,39 @@ -//go:build !windows -// +build !windows - package shell_test import ( "path/filepath" + "strings" "testing" "github.com/goreleaser/goreleaser/v2/internal/shell" "github.com/goreleaser/goreleaser/v2/internal/testctx" + "github.com/goreleaser/goreleaser/v2/internal/testlib" "github.com/stretchr/testify/require" ) func TestRunCommand(t *testing.T) { t.Run("simple", func(t *testing.T) { - require.NoError(t, shell.Run(testctx.New(), "", []string{"echo", "oi"}, []string{}, false)) + require.NoError(t, shell.Run( + testctx.New(), + "", + strings.Fields(testlib.Echo("oi")), + []string{}, + false, + )) }) t.Run("cmd failed", func(t *testing.T) { - require.EqualError( - t, - shell.Run(testctx.New(), "", []string{"sh", "-c", "exit 1"}, []string{}, false), - `shell: 'sh -c exit 1': exit status 1: [no output]`, - ) + require.Error(t, shell.Run( + testctx.New(), + "", + strings.Fields(testlib.Exit(1)), + []string{}, + false, + )) }) t.Run("cmd with output", func(t *testing.T) { + testlib.SkipIfWindows(t, "what would be a similar behavior in windows?") require.EqualError( t, shell.Run(testctx.New(), "", []string{"sh", "-c", `echo something; exit 1`}, []string{}, true), @@ -34,6 +42,7 @@ func TestRunCommand(t *testing.T) { }) t.Run("with env and dir", func(t *testing.T) { + testlib.SkipIfWindows(t, "what would be a similar behavior in windows?") dir := t.TempDir() require.NoError(t, shell.Run(testctx.New(), dir, []string{"sh", "-c", "touch $FOO"}, []string{"FOO=bar"}, false)) require.FileExists(t, filepath.Join(dir, "bar")) diff --git a/internal/shell/shell_windows_test.go b/internal/shell/shell_windows_test.go deleted file mode 100644 index 1f3e01f41..000000000 --- a/internal/shell/shell_windows_test.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build windows -// +build windows - -package shell_test - -import ( - "testing" - - "github.com/goreleaser/goreleaser/v2/internal/shell" - "github.com/goreleaser/goreleaser/v2/internal/testctx" - "github.com/stretchr/testify/require" -) - -func TestRunCommandWindows(t *testing.T) { - t.Run("simple", func(t *testing.T) { - require.NoError(t, shell.Run(testctx.New(), "", []string{"cmd.exe", "/c", "echo", "oi"}, []string{}, false)) - }) - - t.Run("cmd failed", func(t *testing.T) { - require.EqualError( - t, - shell.Run(testctx.New(), "", []string{"cmd.exe", "/c", "exit /b 1"}, []string{}, false), - `shell: 'cmd.exe /c exit /b 1': exit status 1: [no output]`, - ) - }) - - // TODO: more tests for windows -} diff --git a/internal/testlib/path.go b/internal/testlib/path.go index 7314274ee..713981b35 100644 --- a/internal/testlib/path.go +++ b/internal/testlib/path.go @@ -1,6 +1,7 @@ package testlib import ( + "fmt" "os" "os/exec" "runtime" @@ -28,9 +29,42 @@ func InPath(cmd string) bool { func IsWindows() bool { return runtime.GOOS == "windows" } // SkipIfWindows skips the test if runtime OS is windows. -func SkipIfWindows(tb testing.TB) { +func SkipIfWindows(tb testing.TB, args ...any) { tb.Helper() if IsWindows() { - tb.Skip("test skipped on windows") + tb.Skip(args...) } } + +// Echo returns a `echo s` command, handling it on windows. +func Echo(s string) string { + if IsWindows() { + return "cmd.exe /c echo " + s + } + return "echo " + s +} + +// Touch returns a `touch name` command, handling it on windows. +func Touch(name string) string { + if IsWindows() { + return "cmd.exe /c copy nul " + name + } + return "touch " + name +} + +// ShC returns the command line for the given cmd wrapped into a `sh -c` in +// linux/mac, and the cmd.exe command in windows. +func ShC(cmd string) string { + if IsWindows() { + return fmt.Sprintf("cmd.exe /c '%s'", cmd) + } + return fmt.Sprintf("sh -c '%s'", cmd) +} + +// Exit returns a command that exits the given status, handling windows. +func Exit(status int) string { + if IsWindows() { + return fmt.Sprintf("cmd.exe /c exit /b %d", status) + } + return fmt.Sprintf("exit %d", status) +} From bb438ba34e265b655f85653635dc2eb8e346ec5a Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 16 Nov 2024 11:14:59 -0300 Subject: [PATCH 8/9] test: fix build test --- internal/pipe/build/build_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pipe/build/build_test.go b/internal/pipe/build/build_test.go index b658a82f0..9ba662101 100644 --- a/internal/pipe/build/build_test.go +++ b/internal/pipe/build/build_test.go @@ -242,8 +242,8 @@ func TestRunPipeFailingHooks(t *testing.T) { testctx.WithCurrentTag("2.4.5"), testctx.Skip(skips.PreBuildHooks), ) - ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: testlib.Echo("pre")}} ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} + ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: testlib.Echo("pre")}} require.NoError(t, Pipe{}.Run(ctx)) }) } From 9b3b1e4b06de75a1a863c69d0c4931e70b908ac2 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sun, 17 Nov 2024 12:31:50 -0300 Subject: [PATCH 9/9] docs: fix static/run script signature check on nightlies closes #5290 Signed-off-by: Carlos Alexandro Becker --- www/docs/static/run | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/docs/static/run b/www/docs/static/run index 72f5e274d..1fcfdf9d6 100755 --- a/www/docs/static/run +++ b/www/docs/static/run @@ -50,8 +50,12 @@ TAR_FILE="${FILE_BASENAME}_${OS}_${ARCH}.tar.gz" sha256sum --ignore-missing --quiet --check checksums.txt if command -v cosign >/dev/null 2>&1; then echo "Verifying signatures..." + REF="refs/tags/$VERSION" + if test "$VERSION" = "nightly"; then + REF="refs/heads/main" + fi cosign verify-blob \ - --certificate-identity-regexp "https://github.com/goreleaser/goreleaser.*/.github/workflows/.*.yml@refs/tags/$VERSION" \ + --certificate-identity-regexp "https://github.com/goreleaser/goreleaser.*/.github/workflows/.*.yml@$REF" \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ --cert "$RELEASES_URL/download/$VERSION/checksums.txt.pem" \ --signature "$RELEASES_URL/download/$VERSION/checksums.txt.sig" \