1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-07-01 00:54:57 +02:00

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 <caarlos0@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker
2024-11-16 10:30:39 -03:00
committed by GitHub
parent c65b2258cb
commit 2bf08f11a6
54 changed files with 393 additions and 133 deletions

View File

@ -1,5 +1,9 @@
name: build name: build
concurrency:
group: ${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
on: on:
push: push:
branches: branches:
@ -25,7 +29,11 @@ jobs:
with: with:
args: "-disable largeloopcopy" args: "-disable largeloopcopy"
test: test:
runs-on: ubuntu-latest strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
env: env:
DOCKER_CLI_EXPERIMENTAL: "enabled" DOCKER_CLI_EXPERIMENTAL: "enabled"
steps: steps:
@ -37,8 +45,11 @@ jobs:
version: 3.x version: 3.x
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v2 - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v2
if: matrix.os == 'ubuntu-latest'
- uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3 - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3
if: matrix.os == 'ubuntu-latest'
- name: setup-snapcraft - name: setup-snapcraft
if: matrix.os == 'ubuntu-latest'
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get -yq --no-install-suggests --no-install-recommends install snapcraft sudo apt-get -yq --no-install-suggests --no-install-recommends install snapcraft
@ -46,6 +57,7 @@ jobs:
with: with:
install-only: true install-only: true
- uses: cachix/install-nix-action@v30 - uses: cachix/install-nix-action@v30
if: matrix.os == 'ubuntu-latest'
with: with:
github_access_token: ${{ secrets.GITHUB_TOKEN }} github_access_token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v4 - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v4

View File

@ -94,6 +94,10 @@ You can do so by running:
task docker:setup task docker:setup
``` ```
### A note about Windows
Make sure to enable "Developer Mode" in Settings.
## Creating a commit ## Creating a commit
Commit messages should be well formatted, and to make that "standardized", we Commit messages should be well formatted, and to make that "standardized", we

View File

@ -40,7 +40,7 @@ tasks:
SOURCE_FILES: '{{default "./..." .SOURCE_FILES}}' SOURCE_FILES: '{{default "./..." .SOURCE_FILES}}'
TEST_PATTERN: '{{default "." .TEST_PATTERN}}' TEST_PATTERN: '{{default "." .TEST_PATTERN}}'
cmds: 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: cover:
desc: Open the cover tool desc: Open the cover tool

View File

@ -5,6 +5,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -55,6 +56,7 @@ func TestInitGitIgnoreExists(t *testing.T) {
} }
func TestInitFileError(t *testing.T) { func TestInitFileError(t *testing.T) {
testlib.SkipIfWindows(t)
folder := setupInitTest(t) folder := setupInitTest(t)
cmd := newInitCmd().cmd cmd := newInitCmd().cmd
path := filepath.Join(folder, "nope.yaml") path := filepath.Join(folder, "nope.yaml")

View File

@ -18,6 +18,9 @@ func TestGenerateSchema(t *testing.T) {
outFile, err := os.Open(destination) outFile, err := os.Open(destination)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, outFile.Close())
})
schema := map[string]interface{}{} schema := map[string]interface{}{}
require.NoError(t, json.NewDecoder(outFile).Decode(&schema)) require.NoError(t, json.NewDecoder(outFile).Decode(&schema))

View File

@ -21,17 +21,17 @@ func setup(tb testing.TB) string {
_ = os.Unsetenv("GITHUB_TOKEN") _ = os.Unsetenv("GITHUB_TOKEN")
_ = os.Unsetenv("GITLAB_TOKEN") _ = os.Unsetenv("GITLAB_TOKEN")
_ = os.Unsetenv("GITEA_TOKEN")
previous, err := os.Getwd() previous, err := os.Getwd()
require.NoError(tb, err) require.NoError(tb, err)
folder := tb.TempDir()
require.NoError(tb, os.Chdir(folder))
tb.Cleanup(func() { tb.Cleanup(func() {
require.NoError(tb, os.Chdir(previous)) require.NoError(tb, os.Chdir(previous))
}) })
folder := tb.TempDir()
require.NoError(tb, os.Chdir(folder))
createGoReleaserYaml(tb) createGoReleaserYaml(tb)
createMainGo(tb) createMainGo(tb)
goModInit(tb) goModInit(tb)

View File

@ -119,6 +119,6 @@ func installBuildx(target *dagger.Container) *dagger.Container {
"/usr/lib/docker/cli-plugins/docker-buildx", "/usr/lib/docker/cli-plugins/docker-buildx",
bin, bin,
dagger.ContainerWithFileOpts{ dagger.ContainerWithFileOpts{
Permissions: 0777, Permissions: 0o777,
}) })
} }

2
go.mod
View File

@ -28,7 +28,7 @@ require (
github.com/google/ko v0.17.1 github.com/google/ko v0.17.1
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/goreleaser/fileglob v1.3.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/goreleaser/quill v0.0.0-20241025150139-731751b4046d
github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-multierror v1.1.1
github.com/invopop/jsonschema v0.12.0 github.com/invopop/jsonschema v0.12.0

4
go.sum
View File

@ -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/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 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I=
github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= 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.1-0.20241110134201-59b75b2a5a2e h1:xajOCis2WSRoM8XmWFQZFKbjUYJ0PMyFI8QTvIsILLo=
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/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 h1:bBLVbv03RLdskOHJfNkEJIMm+85b4E3GJkEEVXIu48k=
github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d/go.mod h1:b/JsMZEZCcW7WWjR1+XyIFYSFizwmAYpxvvh3ZcauVE= github.com/goreleaser/quill v0.0.0-20241025150139-731751b4046d/go.mod h1:b/JsMZEZCcW7WWjR1+XyIFYSFizwmAYpxvvh3ZcauVE=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=

View File

@ -465,7 +465,7 @@ func TestBuild(t *testing.T) {
require.ElementsMatch(t, list.List(), []*artifact.Artifact{ require.ElementsMatch(t, list.List(), []*artifact.Artifact{
{ {
Name: "bin/foo-v5.6.7", 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", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Type: artifact.Binary, Type: artifact.Binary,
@ -478,7 +478,7 @@ func TestBuild(t *testing.T) {
}, },
{ {
Name: "bin/foo-v5.6.7", 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", Goos: "linux",
Goarch: "mips", Goarch: "mips",
Gomips: "softfloat", Gomips: "softfloat",
@ -492,7 +492,7 @@ func TestBuild(t *testing.T) {
}, },
{ {
Name: "bin/foo-v5.6.7", 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", Goos: "linux",
Goarch: "mips64le", Goarch: "mips64le",
Gomips: "softfloat", Gomips: "softfloat",
@ -506,7 +506,7 @@ func TestBuild(t *testing.T) {
}, },
{ {
Name: "bin/foo-v5.6.7", 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", Goos: "darwin",
Goarch: "amd64", Goarch: "amd64",
Type: artifact.Binary, Type: artifact.Binary,
@ -519,7 +519,7 @@ func TestBuild(t *testing.T) {
}, },
{ {
Name: "bin/foo-v5.6.7", 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", Goos: "linux",
Goarch: "arm", Goarch: "arm",
Goarm: "6", Goarm: "6",
@ -533,7 +533,7 @@ func TestBuild(t *testing.T) {
}, },
{ {
Name: "bin/foo-v5.6.7.exe", 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", Goos: "windows",
Goarch: "amd64", Goarch: "amd64",
Type: artifact.Binary, Type: artifact.Binary,
@ -546,7 +546,7 @@ func TestBuild(t *testing.T) {
}, },
{ {
Name: "bin/foo-v5.6.7.wasm", 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", Goos: "js",
Goarch: "wasm", Goarch: "wasm",
Type: artifact.Binary, Type: artifact.Binary,

View File

@ -248,6 +248,9 @@ func TestGitLabURLsDownloadTemplate(t *testing.T) {
tmpFile, err := os.CreateTemp(t.TempDir(), "") tmpFile, err := os.CreateTemp(t.TempDir(), "")
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() {
_ = tmpFile.Close()
})
client, err := newGitLab(ctx, ctx.Token) client, err := newGitLab(ctx, ctx.Token)
require.NoError(t, err) require.NoError(t, err)

View File

@ -22,7 +22,7 @@ import (
) )
// Environment variables to pass through to exec // 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 // Execute the given publisher
func Execute(ctx *context.Context, publishers []config.Publisher) error { func Execute(ctx *context.Context, publishers []config.Publisher) error {

View File

@ -3,6 +3,7 @@ package exec
import ( import (
"fmt" "fmt"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
@ -40,7 +41,7 @@ func TestExecute(t *testing.T) {
{"signature", "sig", artifact.Signature}, {"signature", "sig", artifact.Signature},
{"signature", "pem", artifact.Certificate}, {"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)) require.NoError(t, os.WriteFile(file, []byte("lorem ipsum"), 0o644))
ctx.Artifacts.Add(&artifact.Artifact{ ctx.Artifacts.Add(&artifact.Artifact{
Name: "a." + a.ext, Name: "a." + a.ext,
@ -275,7 +276,7 @@ func TestExecute(t *testing.T) {
}), }),
}, },
ExtraFiles: []config.ExtraFile{ 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{ ExtraFiles: []config.ExtraFile{
{ {
Glob: filepath.Join("testdata", "*.txt"), Glob: path.Join("testdata", "*.txt"),
NameTemplate: "b.txt", NameTemplate: "b.txt",
}, },
}, },

View File

@ -5,6 +5,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -30,10 +31,11 @@ func TestCopySymlink(t *testing.T) {
l, err := os.Readlink(c) l, err := os.Readlink(c)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, a, l) require.Equal(t, a, filepath.ToSlash(l))
} }
func TestEqualFilesModeChanged(t *testing.T) { func TestEqualFilesModeChanged(t *testing.T) {
testlib.SkipIfWindows(t)
tmp := t.TempDir() tmp := t.TempDir()
a := "testdata/somefile.txt" a := "testdata/somefile.txt"
b := tmp + "/somefile.txt" b := tmp + "/somefile.txt"

View File

@ -3,6 +3,7 @@ package gio
import ( import (
"testing" "testing"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/stretchr/testify/require" "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 { tests := []struct {
a string a string
b string b string
@ -53,7 +54,10 @@ func TestEqualFileCointents(t *testing.T) {
for _, test := range tests { for _, test := range tests {
equal, err := EqualFiles(test.a, test.b) equal, err := EqualFiles(test.a, test.b)
require.NoError(t, err) 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) equalContents, err := EqualFileContents(test.a, test.b)
require.NoError(t, err) require.NoError(t, err)

View File

@ -2,6 +2,7 @@
package golden package golden
import ( import (
"bytes"
"flag" "flag"
"os" "os"
"path/filepath" "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) { func doRequireEqual(tb testing.TB, out []byte, ext, suffix string, folder bool) {
tb.Helper() tb.Helper()
out = fixLineEndings(out)
golden := filepath.Join("testdata", tb.Name()+ext+suffix) golden := filepath.Join("testdata", tb.Name()+ext+suffix)
if folder { if folder {
golden = filepath.Join("testdata", tb.Name(), filepath.Base(tb.Name())+ext+suffix) 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) gbts, err := os.ReadFile(golden)
require.NoError(tb, err) require.NoError(tb, err)
gbts = fixLineEndings(gbts)
require.Equal(tb, string(gbts), string(out)) require.Equal(tb, string(gbts), string(out))
} }
func fixLineEndings(in []byte) []byte {
return bytes.ReplaceAll(in, []byte("\r\n"), []byte{'\n'})
}

View File

@ -8,7 +8,6 @@ import (
"io" "io"
h "net/http" h "net/http"
"os" "os"
"runtime"
"strings" "strings"
"github.com/caarlos0/log" "github.com/caarlos0/log"
@ -16,6 +15,7 @@ import (
"github.com/goreleaser/goreleaser/v2/internal/extrafiles" "github.com/goreleaser/goreleaser/v2/internal/extrafiles"
"github.com/goreleaser/goreleaser/v2/internal/pipe" "github.com/goreleaser/goreleaser/v2/internal/pipe"
"github.com/goreleaser/goreleaser/v2/internal/semerrgroup" "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/internal/tmpl"
"github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/goreleaser/goreleaser/v2/pkg/context" "github.com/goreleaser/goreleaser/v2/pkg/context"
@ -49,6 +49,8 @@ func assetOpenReset() {
assetOpen = assetOpenDefault 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) { func assetOpenDefault(kind string, a *artifact.Artifact) (*asset, error) {
f, err := os.Open(a.Path) f, err := os.Open(a.Path)
if err != nil { if err != nil {
@ -56,9 +58,11 @@ func assetOpenDefault(kind string, a *artifact.Artifact) (*asset, error) {
} }
s, err := f.Stat() s, err := f.Stat()
if err != nil { if err != nil {
_ = f.Close()
return nil, err return nil, err
} }
if s.IsDir() { if s.IsDir() {
_ = f.Close()
return nil, fmt.Errorf("%s: upload failed: the asset to upload can't be a directory", kind) return nil, fmt.Errorf("%s: upload failed: the asset to upload can't be a directory", kind)
} }
return &asset{ return &asset{
@ -332,7 +336,7 @@ func getHTTPClient(upload *config.Upload) (*h.Client, error) {
if upload.TrustedCerts != "" { if upload.TrustedCerts != "" {
pool, err := x509.SystemCertPool() pool, err := x509.SystemCertPool()
if err != nil { if err != nil {
if runtime.GOOS == "windows" { if testlib.IsWindows() {
// on windows ignore errors until golang issues #16736 & #18609 get fixed // on windows ignore errors until golang issues #16736 & #18609 get fixed
pool = x509.NewCertPool() pool = x509.NewCertPool()
} else { } else {

View File

@ -1004,9 +1004,7 @@ func TestDuplicateFilesInsideArchive(t *testing.T) {
f, err := os.CreateTemp(folder, "") f, err := os.CreateTemp(folder, "")
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() { require.NoError(t, f.Close()) })
require.NoError(t, f.Close())
})
ff, err := os.CreateTemp(folder, "") ff, err := os.CreateTemp(folder, "")
require.NoError(t, err) require.NoError(t, err)
@ -1066,6 +1064,7 @@ func TestArchive_globbing(t *testing.T) {
t.Helper() t.Helper()
bin, err := os.CreateTemp(t.TempDir(), "binary") bin, err := os.CreateTemp(t.TempDir(), "binary")
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, bin.Close()) })
dist := t.TempDir() dist := t.TempDir()
ctx := testctx.NewWithCfg(config.Project{ ctx := testctx.NewWithCfg(config.Project{
Dist: dist, Dist: dist,

View File

@ -331,7 +331,11 @@ func TestRunPipe_ArtifactoryDown(t *testing.T) {
}) })
require.NoError(t, Pipe{}.Default(ctx)) 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) { func TestRunPipe_TargetTemplateError(t *testing.T) {

View File

@ -23,13 +23,16 @@ func TestDescription(t *testing.T) {
} }
func TestRunPipe(t *testing.T) { func TestRunPipe(t *testing.T) {
for _, tc := range [][]string{ table := [][]string{
nil, nil,
{}, {},
{"go version"}, {"go version"},
{"go version", "go list"}, {"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( ctx := testctx.NewWithCfg(
config.Project{ config.Project{
Before: config.Before{ Before: config.Before{
@ -70,6 +73,7 @@ func TestRunPipeFail(t *testing.T) {
} }
func TestRunWithEnv(t *testing.T) { func TestRunWithEnv(t *testing.T) {
testlib.SkipIfWindows(t)
f := filepath.Join(t.TempDir(), "testfile") f := filepath.Join(t.TempDir(), "testfile")
require.NoError(t, Pipe{}.Run(testctx.NewWithCfg( require.NoError(t, Pipe{}.Run(testctx.NewWithCfg(
config.Project{ config.Project{

View File

@ -29,7 +29,8 @@ const (
var listen string var listen string
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
if !testlib.InPath("docker") { if !testlib.InPath("docker") || testlib.IsWindows() {
// there's no minio windows image
m.Run() m.Run()
return return
} }
@ -75,6 +76,7 @@ func TestMain(m *testing.M) {
func TestMinioUpload(t *testing.T) { func TestMinioUpload(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
name := "basic" name := "basic"
directory := t.TempDir() directory := t.TempDir()
srcpath := filepath.Join(directory, "source.tar.gz") srcpath := filepath.Join(directory, "source.tar.gz")
@ -181,6 +183,7 @@ func TestMinioUpload(t *testing.T) {
func TestMinioUploadCustomBucketID(t *testing.T) { func TestMinioUploadCustomBucketID(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
name := "fromenv" name := "fromenv"
directory := t.TempDir() directory := t.TempDir()
tgzpath := filepath.Join(directory, "bin.tar.gz") tgzpath := filepath.Join(directory, "bin.tar.gz")
@ -218,6 +221,7 @@ func TestMinioUploadCustomBucketID(t *testing.T) {
func TestMinioUploadExtraFilesOnly(t *testing.T) { func TestMinioUploadExtraFilesOnly(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
name := "only-extra-files" name := "only-extra-files"
directory := t.TempDir() directory := t.TempDir()
tgzpath := filepath.Join(directory, "bin.tar.gz") tgzpath := filepath.Join(directory, "bin.tar.gz")
@ -264,6 +268,7 @@ func TestMinioUploadExtraFilesOnly(t *testing.T) {
func TestMinioUploadRootDirectory(t *testing.T) { func TestMinioUploadRootDirectory(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
name := "rootdir" name := "rootdir"
directory := t.TempDir() directory := t.TempDir()
tgzpath := filepath.Join(directory, "bin.tar.gz") tgzpath := filepath.Join(directory, "bin.tar.gz")
@ -300,6 +305,7 @@ func TestMinioUploadRootDirectory(t *testing.T) {
func TestMinioUploadInvalidCustomBucketID(t *testing.T) { func TestMinioUploadInvalidCustomBucketID(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
directory := t.TempDir() directory := t.TempDir()
tgzpath := filepath.Join(directory, "bin.tar.gz") tgzpath := filepath.Join(directory, "bin.tar.gz")
debpath := filepath.Join(directory, "bin.deb") debpath := filepath.Join(directory, "bin.deb")
@ -333,6 +339,7 @@ func TestMinioUploadInvalidCustomBucketID(t *testing.T) {
func TestMinioUploadSkip(t *testing.T) { func TestMinioUploadSkip(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
name := "basic" name := "basic"
directory := t.TempDir() directory := t.TempDir()
debpath := filepath.Join(directory, "bin.deb") debpath := filepath.Join(directory, "bin.deb")

View File

@ -22,8 +22,18 @@ import (
var ( var (
errFailedBuild = errors.New("fake builder failed") errFailedBuild = errors.New("fake builder failed")
errFailedDefault = errors.New("fake builder defaults 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 { type fakeBuilder struct {
fail bool fail bool
failDefault bool failDefault bool
@ -136,12 +146,12 @@ func TestRunFullPipe(t *testing.T) {
}, },
Hooks: config.BuildHookConfig{ Hooks: config.BuildHookConfig{
Pre: []config.Hook{ Pre: []config.Hook{
{Cmd: "touch " + pre}, {Cmd: touch + pre},
{Cmd: "touch pre_{{ .Env.THE_OS}}"}, {Cmd: touch + " pre_{{ .Env.THE_OS}}"},
}, },
Post: []config.Hook{ Post: []config.Hook{
{Cmd: "touch " + post}, {Cmd: touch + post},
{Cmd: "touch post_{{ .Env.THE_OS}}"}, {Cmd: touch + " post_{{ .Env.THE_OS}}"},
}, },
}, },
Targets: []string{"linux_amd64"}, Targets: []string{"linux_amd64"},
@ -178,10 +188,10 @@ func TestRunFullPipeFail(t *testing.T) {
}, },
Hooks: config.BuildHookConfig{ Hooks: config.BuildHookConfig{
Pre: []config.Hook{ Pre: []config.Hook{
{Cmd: "touch " + pre}, {Cmd: touch + pre},
}, },
Post: []config.Hook{ Post: []config.Hook{
{Cmd: "touch " + post}, {Cmd: touch + post},
}, },
}, },
Targets: []string{"linux_amd64"}, Targets: []string{"linux_amd64"},
@ -210,7 +220,7 @@ func TestRunPipeFailingHooks(t *testing.T) {
t.Run("pre-hook", func(t *testing.T) { t.Run("pre-hook", func(t *testing.T) {
ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) 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.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) err := Pipe{}.Run(ctx)
require.ErrorIs(t, err, exec.ErrNotFound) require.ErrorIs(t, err, exec.ErrNotFound)
@ -218,7 +228,7 @@ func TestRunPipeFailingHooks(t *testing.T) {
}) })
t.Run("post-hook", func(t *testing.T) { t.Run("post-hook", func(t *testing.T) {
ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) 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"}} ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}}
err := Pipe{}.Run(ctx) err := Pipe{}.Run(ctx)
require.ErrorIs(t, err, exec.ErrNotFound) require.ErrorIs(t, err, exec.ErrNotFound)
@ -231,7 +241,7 @@ func TestRunPipeFailingHooks(t *testing.T) {
testctx.WithCurrentTag("2.4.5"), testctx.WithCurrentTag("2.4.5"),
testctx.Skip(skips.PostBuildHooks), 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"}} ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}}
require.NoError(t, Pipe{}.Run(ctx)) require.NoError(t, Pipe{}.Run(ctx))
}) })
@ -242,7 +252,7 @@ func TestRunPipeFailingHooks(t *testing.T) {
testctx.WithCurrentTag("2.4.5"), testctx.WithCurrentTag("2.4.5"),
testctx.Skip(skips.PreBuildHooks), 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"}} ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}}
require.NoError(t, Pipe{}.Run(ctx)) require.NoError(t, Pipe{}.Run(ctx))
}) })
@ -364,10 +374,10 @@ func TestDefaultPartialBuilds(t *testing.T) {
}, },
}) })
// Create any 'Dir' paths necessary for builds. // Create any 'Dir' paths necessary for builds.
cwd, err := os.Getwd() previous, err := os.Getwd()
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, os.Chdir(cwd)) })
require.NoError(t, os.Chdir(t.TempDir())) require.NoError(t, os.Chdir(t.TempDir()))
t.Cleanup(func() { require.NoError(t, os.Chdir(previous)) })
for _, b := range ctx.Config.Builds { for _, b := range ctx.Config.Builds {
if b.Dir != "" { if b.Dir != "" {
require.NoError(t, os.Mkdir(b.Dir, 0o755)) require.NoError(t, os.Mkdir(b.Dir, 0o755))
@ -505,10 +515,10 @@ func TestBuild_hooksKnowGoosGoarch(t *testing.T) {
}, },
Hooks: config.BuildHookConfig{ Hooks: config.BuildHookConfig{
Pre: []config.Hook{ Pre: []config.Hook{
{Cmd: "touch pre-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, {Cmd: touch + " pre-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir},
}, },
Post: config.Hooks{ 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{ Hooks: config.BuildHookConfig{
Pre: []config.Hook{ Pre: []config.Hook{
{Cmd: "touch pre-hook-{{.Target}}", Dir: tmpDir}, {Cmd: touch + " pre-hook-{{.Target}}", Dir: tmpDir},
}, },
Post: config.Hooks{ 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) { func TestRunHookFailWithLogs(t *testing.T) {
testlib.SkipIfWindows(t)
folder := testlib.Mktmp(t) folder := testlib.Mktmp(t)
config := config.Project{ config := config.Project{
Dist: folder, Dist: folder,

View File

@ -309,7 +309,10 @@ func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
}) })
err = Pipe{}.Run(ctx) err = Pipe{}.Run(ctx)
require.Error(t, err) 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) { func TestPipeWhenNoArtifacts(t *testing.T) {

View File

@ -35,6 +35,7 @@ func start(tb testing.TB) {
// TODO: this test is too big... split in smaller tests? Mainly the manifest ones... // TODO: this test is too big... split in smaller tests? Mainly the manifest ones...
func TestRunPipe(t *testing.T) { func TestRunPipe(t *testing.T) {
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.SkipIfWindows(t)
type errChecker func(*testing.T, error) type errChecker func(*testing.T, error)
shouldErr := func(msg string) errChecker { shouldErr := func(msg string) errChecker {
return func(t *testing.T, err error) { return func(t *testing.T, err error) {

View File

@ -184,7 +184,7 @@ func TestEmptyGithubEnvFile(t *testing.T) {
}, },
}) })
err = Pipe{}.Run(ctx) err = Pipe{}.Run(ctx)
require.ErrorIs(t, err, syscall.EACCES) requireErrAccess(t, err)
require.ErrorContains(t, err, "failed to load github token") require.ErrorContains(t, err, "failed to load github token")
} }
@ -199,7 +199,7 @@ func TestEmptyGitlabEnvFile(t *testing.T) {
}, },
}) })
err = Pipe{}.Run(ctx) err = Pipe{}.Run(ctx)
require.ErrorIs(t, err, syscall.EACCES) requireErrAccess(t, err)
require.ErrorContains(t, err, "failed to load gitlab token") require.ErrorContains(t, err, "failed to load gitlab token")
} }
@ -214,7 +214,7 @@ func TestEmptyGiteaEnvFile(t *testing.T) {
}, },
}) })
err = Pipe{}.Run(ctx) err = Pipe{}.Run(ctx)
require.ErrorIs(t, err, syscall.EACCES) requireErrAccess(t, err)
require.ErrorContains(t, err, "failed to load gitea token") require.ErrorContains(t, err, "failed to load gitea token")
} }
@ -292,6 +292,7 @@ func TestLoadEnv(t *testing.T) {
require.Equal(t, "123", v) require.Equal(t, "123", v)
}) })
t.Run("env file is not readable", func(t *testing.T) { t.Run("env file is not readable", func(t *testing.T) {
testlib.SkipIfWindows(t)
f, err := os.CreateTemp(t.TempDir(), "token") f, err := os.CreateTemp(t.TempDir(), "token")
require.NoError(t, err) require.NoError(t, err)
fmt.Fprintf(f, "123") fmt.Fprintf(f, "123")
@ -303,3 +304,13 @@ func TestLoadEnv(t *testing.T) {
require.Equal(t, "", v) 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)
}

View File

@ -175,6 +175,7 @@ func TestGoModProxy(t *testing.T) {
}) })
t.Run("no perms", func(t *testing.T) { t.Run("no perms", func(t *testing.T) {
testlib.SkipIfWindows(t)
for file, mode := range map[string]os.FileMode{ for file, mode := range map[string]os.FileMode{
"go.mod": 0o500, "go.mod": 0o500,
"go.sum": 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. // 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.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)
}
}) })
} }
}) })

View File

@ -60,11 +60,12 @@ func TestRunCustomMod(t *testing.T) {
func TestCustomEnv(t *testing.T) { func TestCustomEnv(t *testing.T) {
bin := filepath.Join(t.TempDir(), "go.bin") bin := filepath.Join(t.TempDir(), "go.bin")
require.NoError(t, os.WriteFile( content := []byte("#!/bin/sh\nenv | grep -qw FOO=bar")
bin, if testlib.IsWindows() {
[]byte("#!/bin/sh\nenv | grep -qw FOO=bar"), bin = strings.Replace(bin, ".bin", ".bat", 1)
0o755, 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{ ctx := testctx.NewWithCfg(config.Project{
GoMod: config.GoMod{ GoMod: config.GoMod{
GoBinary: bin, GoBinary: bin,
@ -117,21 +118,26 @@ func TestRunCommandError(t *testing.T) {
GoBinary: "not-a-valid-binary", GoBinary: "not-a-valid-binary",
}, },
}) })
require.EqualError( path := "$PATH"
if testlib.IsWindows() {
path = "%PATH%"
}
require.ErrorContains(
t, t,
Pipe{}.Run(ctx), 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) require.Empty(t, ctx.ModulePath)
} }
func TestRunOldGoVersion(t *testing.T) { func TestRunOldGoVersion(t *testing.T) {
bin := filepath.Join(t.TempDir(), "go.bin") bin := filepath.Join(t.TempDir(), "go.bin")
require.NoError(t, os.WriteFile( content := []byte("#!/bin/sh\necho \"flag provided but not defined: -m\"\nexit 1")
bin, if testlib.IsWindows() {
[]byte("#!/bin/sh\necho \"flag provided but not defined: -m\"\nexit 1"), bin = strings.Replace(bin, ".bin", ".bat", 1)
0o755, 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{ ctx := testctx.NewWithCfg(config.Project{
GoMod: config.GoMod{ GoMod: config.GoMod{
GoBinary: bin, GoBinary: bin,

View File

@ -156,6 +156,7 @@ func TestPublishPipeNoMatchingBuild(t *testing.T) {
} }
func TestPublishPipeSuccess(t *testing.T) { func TestPublishPipeSuccess(t *testing.T) {
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "docker") testlib.CheckPath(t, "docker")
testlib.StartRegistry(t, "ko_registry", registryPort) testlib.StartRegistry(t, "ko_registry", registryPort)
@ -411,6 +412,8 @@ func TestPublishPipeSuccess(t *testing.T) {
} }
func TestSnapshot(t *testing.T) { func TestSnapshot(t *testing.T) {
testlib.SkipIfWindows(t)
testlib.CheckDocker(t)
ctx := testctx.NewWithCfg(config.Project{ ctx := testctx.NewWithCfg(config.Project{
ProjectName: "test", ProjectName: "test",
Builds: []config.Build{ Builds: []config.Build{

View File

@ -326,8 +326,8 @@ func create(ctx *context.Context, fpm config.NFPM, format string, artifacts []*a
return err return err
} }
contents = append(contents, &files.Content{ contents = append(contents, &files.Content{
Source: src, Source: filepath.ToSlash(src),
Destination: dst, Destination: filepath.ToSlash(dst),
Type: content.Type, Type: content.Type,
Packager: content.Packager, Packager: content.Packager,
FileInfo: content.FileInfo, FileInfo: content.FileInfo,

View File

@ -97,10 +97,10 @@ func TestRunPipe(t *testing.T) {
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
require.NoError(t, os.Mkdir(dist, 0o755)) require.NoError(t, os.Mkdir(dist, 0o755))
require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
binPath := filepath.Join(dist, "mybin", "mybin") binPath := filepath.ToSlash(filepath.Join(dist, "mybin", "mybin"))
foohPath := filepath.Join(dist, "foo.h") foohPath := filepath.ToSlash(filepath.Join(dist, "foo.h"))
foosoPath := filepath.Join(dist, "foo.so") foosoPath := filepath.ToSlash(filepath.Join(dist, "foo.so"))
fooaPath := filepath.Join(dist, "foo.a") fooaPath := filepath.ToSlash(filepath.Join(dist, "foo.a"))
for _, name := range []string{binPath, foosoPath, foohPath, fooaPath} { for _, name := range []string{binPath, foosoPath, foohPath, fooaPath} {
f, err := os.Create(name) f, err := os.Create(name)
require.NoError(t, err) require.NoError(t, err)
@ -463,10 +463,10 @@ func TestRunPipe(t *testing.T) {
cshared = filepath.Join("/data/data/com.termux/files", cshared) cshared = filepath.Join("/data/data/com.termux/files", cshared)
carchive = filepath.Join("/data/data/com.termux/files", carchive) carchive = filepath.Join("/data/data/com.termux/files", carchive)
} }
bin = filepath.Join(bin, "mybin") bin = filepath.ToSlash(filepath.Join(bin, "mybin"))
header = filepath.Join(header, "foo.h") header = filepath.ToSlash(filepath.Join(header, "foo.h"))
cshared = filepath.Join(cshared, "foo.so") cshared = filepath.ToSlash(filepath.Join(cshared, "foo.so"))
carchive = filepath.Join(carchive, "foo.a") carchive = filepath.ToSlash(filepath.Join(carchive, "foo.a"))
require.ElementsMatch(t, []string{ require.ElementsMatch(t, []string{
"/var/log/foobar", "/var/log/foobar",
"/usr/share/testfile.txt", "/usr/share/testfile.txt",
@ -496,10 +496,8 @@ func doTestRunPipeConventionalNameTemplate(t *testing.T, snapshot bool) {
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
require.NoError(t, os.Mkdir(dist, 0o755)) require.NoError(t, os.Mkdir(dist, 0o755))
require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
binPath := filepath.Join(dist, "mybin", "mybin") binPath := filepath.ToSlash(filepath.Join(dist, "mybin", "mybin"))
f, err := os.Create(binPath) require.NoError(t, os.WriteFile(binPath, []byte("nope"), 0o755))
require.NoError(t, err)
require.NoError(t, f.Close())
ctx := testctx.NewWithCfg(config.Project{ ctx := testctx.NewWithCfg(config.Project{
ProjectName: "mybin", ProjectName: "mybin",
Dist: dist, Dist: dist,

View File

@ -37,6 +37,7 @@ func TestSkip(t *testing.T) {
}) })
t.Run("nix-all-good", func(t *testing.T) { t.Run("nix-all-good", func(t *testing.T) {
testlib.CheckPath(t, "nix-prefetch-url") testlib.CheckPath(t, "nix-prefetch-url")
testlib.SkipIfWindows(t)
require.False(t, NewPublish().Skip(testctx.NewWithCfg(config.Project{ require.False(t, NewPublish().Skip(testctx.NewWithCfg(config.Project{
Nix: []config.Nix{{}}, Nix: []config.Nix{{}},
}))) })))
@ -65,6 +66,7 @@ func TestPrefetcher(t *testing.T) {
}) })
t.Run("valid", func(t *testing.T) { t.Run("valid", func(t *testing.T) {
testlib.CheckPath(t, "nix-prefetch-url") 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") 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.NoError(t, err)
require.Equal(t, "0girjxp07srylyq36xk1ska8p68m2fhp05xgyv4wkcl61d6rzv3y", sha) require.Equal(t, "0girjxp07srylyq36xk1ska8p68m2fhp05xgyv4wkcl61d6rzv3y", sha)
@ -81,6 +83,7 @@ func TestPrefetcher(t *testing.T) {
}) })
t.Run("valid", func(t *testing.T) { t.Run("valid", func(t *testing.T) {
testlib.CheckPath(t, "nix-prefetch-url") testlib.CheckPath(t, "nix-prefetch-url")
testlib.SkipIfWindows(t)
require.True(t, publishShaPrefetcher{nixPrefetchURLBin}.Available()) require.True(t, publishShaPrefetcher{nixPrefetchURLBin}.Available())
}) })
}) })

View File

@ -257,6 +257,7 @@ func TestRunPipeUploadFailure(t *testing.T) {
folder := t.TempDir() folder := t.TempDir()
tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz"))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, tarfile.Close())
config := config.Project{ config := config.Project{
Release: config.Release{ Release: config.Release{
GitHub: config.Repo{ GitHub: config.Repo{
@ -326,6 +327,7 @@ func TestRunPipeUploadRetry(t *testing.T) {
folder := t.TempDir() folder := t.TempDir()
tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz")) tarfile, err := os.Create(filepath.Join(folder, "bin.tar.gz"))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, tarfile.Close())
config := config.Project{ config := config.Project{
Release: config.Release{ Release: config.Release{
GitHub: config.Repo{ GitHub: config.Repo{

View File

@ -227,7 +227,7 @@ func TestSBOMCatalogArtifacts(t *testing.T) {
}{ }{
{ {
desc: "catalog errors", desc: "catalog errors",
expectedErrMsg: "cataloging artifacts: exit failed", expectedErrMsg: "failed",
ctx: testctx.NewWithCfg(config.Project{ ctx: testctx.NewWithCfg(config.Project{
SBOMs: []config.SBOM{ 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", desc: "catalog wrong command",
@ -451,7 +451,7 @@ func testSBOMCataloging(
) { ) {
tb.Helper() tb.Helper()
testlib.CheckPath(tb, "syft") testlib.CheckPath(tb, "syft")
tmpdir := tb.TempDir() tmpdir := testlib.Mktmp(tb)
ctx.Config.Dist = tmpdir ctx.Config.Dist = tmpdir
ctx.Version = "1.2.2" ctx.Version = "1.2.2"
@ -551,11 +551,11 @@ func testSBOMCataloging(
if info.IsDir() { if info.IsDir() {
return nil return nil
} }
relPath, err := filepath.Rel(tmpdir, path) relPath, err := filepath.Rel(filepath.FromSlash(tmpdir), filepath.FromSlash(path))
if err != nil { if err != nil {
return err return err
} }
gotFiles = append(gotFiles, relPath) gotFiles = append(gotFiles, filepath.ToSlash(relPath))
return nil return nil
}), }),
) )
@ -611,7 +611,7 @@ func Test_subprocessDistPath(t *testing.T) {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
actual, err := subprocessDistPath(test.distDir, test.pathRelativeToCwd) actual, err := subprocessDistPath(test.distDir, test.pathRelativeToCwd)
require.NoError(t, err) 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() wd, err := os.Getwd()
require.NoError(t, err) require.NoError(t, err)
abs := func(path string) string {
path, _ = filepath.Abs(path)
return path
}
tests := []struct { tests := []struct {
name string name string
dist string dist string
@ -645,15 +650,15 @@ func Test_templateNames(t *testing.T) {
name: "default configuration", name: "default configuration",
artifact: art, artifact: art,
cfg: config.SBOM{}, cfg: config.SBOM{},
dist: "/somewhere/to/dist", dist: abs("/somewhere/to/dist"),
expectedPaths: []string{ expectedPaths: []string{
"/somewhere/to/dist/name-it.sbom.json", abs("/somewhere/to/dist/name-it.sbom.json"),
}, },
expectedValues: map[string]string{ expectedValues: map[string]string{
"artifact": "to/a/place", "artifact": filepath.FromSlash("to/a/place"),
"artifactID": "id-it", "artifactID": "id-it",
"document": "/somewhere/to/dist/name-it.sbom.json", "document": abs("/somewhere/to/dist/name-it.sbom.json"),
"document0": "/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"), filepath.Join(wd, "somewhere/to/dist/name-it.sbom.json"),
}, },
expectedValues: map[string]string{ 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", "artifactID": "id-it",
"document": filepath.Join(wd, "somewhere/to/dist/name-it.sbom.json"), "document": filepath.Join(wd, "somewhere/to/dist/name-it.sbom.json"),
"document0": 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"), filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom.json"),
}, },
expectedValues: map[string]string{ expectedValues: map[string]string{
"artifact": "to/a/place", "artifact": filepath.FromSlash("to/a/place"),
"artifactID": "id-it", "artifactID": "id-it",
"document": filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom.json"), "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"), "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"), filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"),
}, },
expectedValues: map[string]string{ expectedValues: map[string]string{
"artifact": "to/a/place", "artifact": filepath.FromSlash("to/a/place"),
"artifactID": "id-it", "artifactID": "id-it",
"document": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"), "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"), "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"), filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom.json"),
}, },
expectedValues: map[string]string{ expectedValues: map[string]string{
"artifact": "to/a/place", "artifact": filepath.FromSlash("to/a/place"),
"artifactID": "id-it", "artifactID": "id-it",
"with-env-var": "value", "with-env-var": "value",
"custom-os": "darwin-unique", "custom-os": "darwin-unique",

View File

@ -391,7 +391,7 @@ func binaries(a artifact.Artifact) ([]string, error) {
return nil, err return nil, err
} }
for _, b := range bins { for _, b := range bins {
result = append(result, filepath.Join(wrap, b)) result = append(result, filepath.ToSlash(filepath.Join(wrap, b)))
} }
return result, nil return result, nil
} }

View File

@ -81,6 +81,8 @@ func TestBinaryDependencies(t *testing.T) {
func TestBinarySign(t *testing.T) { func TestBinarySign(t *testing.T) {
testlib.CheckPath(t, "gpg") 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 { doTest := func(tb testing.TB, sign config.Sign) []*artifact.Artifact {
tb.Helper() tb.Helper()
tmpdir := tb.TempDir() tmpdir := tb.TempDir()

View File

@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/goreleaser/goreleaser/v2/internal/artifact" "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/git"
"github.com/goreleaser/goreleaser/v2/internal/skips" "github.com/goreleaser/goreleaser/v2/internal/skips"
"github.com/goreleaser/goreleaser/v2/internal/testctx" "github.com/goreleaser/goreleaser/v2/internal/testctx"
@ -39,9 +40,9 @@ const (
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
rand := rand.New(rand.NewSource(time.Now().UnixNano())) 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) 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) fmt.Printf("failed to copy %s to %s: %s", originKeyring, keyring, err)
os.Exit(1) os.Exit(1)
} }
@ -96,6 +97,8 @@ func TestSignInvalidArtifacts(t *testing.T) {
} }
func TestSignArtifacts(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 stdin := passwordUser
tmplStdin := passwordUserTmpl tmplStdin := passwordUserTmpl
tests := []struct { tests := []struct {

View File

@ -48,6 +48,8 @@ func TestRunPipeMissingInfo(t *testing.T) {
} }
func TestRunPipe(t *testing.T) { func TestRunPipe(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -99,6 +101,8 @@ func TestRunPipe(t *testing.T) {
} }
func TestBadTemplate(t *testing.T) { func TestBadTemplate(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -131,6 +135,8 @@ func TestBadTemplate(t *testing.T) {
} }
func TestRunPipeInvalidNameTemplate(t *testing.T) { func TestRunPipeInvalidNameTemplate(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -153,6 +159,8 @@ func TestRunPipeInvalidNameTemplate(t *testing.T) {
} }
func TestRunPipeWithName(t *testing.T) { func TestRunPipeWithName(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -187,6 +195,8 @@ func TestRunPipeWithName(t *testing.T) {
} }
func TestRunPipeMetadata(t *testing.T) { func TestRunPipeMetadata(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -342,6 +352,8 @@ func TestNoSnapcraftInPath(t *testing.T) {
} }
func TestRunNoArguments(t *testing.T) { func TestRunNoArguments(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -376,6 +388,8 @@ func TestRunNoArguments(t *testing.T) {
} }
func TestCompleter(t *testing.T) { func TestCompleter(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -413,6 +427,8 @@ func TestCompleter(t *testing.T) {
} }
func TestCommand(t *testing.T) { func TestCommand(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")
@ -448,6 +464,8 @@ func TestCommand(t *testing.T) {
} }
func TestExtraFile(t *testing.T) { func TestExtraFile(t *testing.T) {
// snap doesn't work on windows apparently
testlib.SkipIfWindows(t)
testlib.CheckPath(t, "snapcraft") testlib.CheckPath(t, "snapcraft")
folder := t.TempDir() folder := t.TempDir()
dist := filepath.Join(folder, "dist") dist := filepath.Join(folder, "dist")

View File

@ -4,6 +4,7 @@ package sourcearchive
import ( import (
"fmt" "fmt"
"os" "os"
"path"
"path/filepath" "path/filepath"
"github.com/caarlos0/log" "github.com/caarlos0/log"
@ -77,10 +78,10 @@ func (Pipe) Run(ctx *context.Context) error {
return err return err
} }
func appendExtraFilesToArchive(ctx *context.Context, prefix, path, format string) error { func appendExtraFilesToArchive(ctx *context.Context, prefix, name, format string) error {
oldPath := path + ".bkp" oldPath := name + ".bkp"
if err := gio.Copy(path, oldPath); err != nil { if err := gio.Copy(name, oldPath); err != nil {
return fmt.Errorf("failed make a backup of %q: %w", path, err) 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, // 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() 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 { if err != nil {
return fmt.Errorf("could not open archive: %w", err) return fmt.Errorf("could not open archive: %w", err)
} }
@ -107,7 +108,7 @@ func appendExtraFilesToArchive(ctx *context.Context, prefix, path, format string
return err return err
} }
for _, f := range files { 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 { if err := arch.Add(f); err != nil {
return fmt.Errorf("could not add %q to archive: %w", f.Source, err) return fmt.Errorf("could not add %q to archive: %w", f.Source, err)
} }

View File

@ -19,6 +19,18 @@ import (
"github.com/stretchr/testify/require" "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) { func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String()) require.NotEmpty(t, Pipe{}.String())
} }
@ -175,11 +187,11 @@ func TestRun(t *testing.T) {
NameTemplate: "foo", NameTemplate: "foo",
Hooks: config.BuildHookConfig{ Hooks: config.BuildHookConfig{
Pre: []config.Hook{ Pre: []config.Hook{
{Cmd: "touch " + pre}, {Cmd: touch + pre},
}, },
Post: []config.Hook{ Post: []config.Hook{
{Cmd: "touch " + post}, {Cmd: touch + post},
{Cmd: `sh -c 'echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post'`, Output: true}, {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()), ModTimestamp: fmt.Sprintf("%d", modTime.Unix()),
Hooks: config.BuildHookConfig{ Hooks: config.BuildHookConfig{
Pre: []config.Hook{ Pre: []config.Hook{
{Cmd: "touch " + pre}, {Cmd: touch + pre},
}, },
Post: []config.Hook{ Post: []config.Hook{
{Cmd: "touch " + post}, {Cmd: touch + post},
{Cmd: `sh -c 'echo "{{ .Name }} {{ .Os }} {{ .Arch }} {{ .Arm }} {{ .Target }} {{ .Ext }}" > {{ .Path }}.post'`, Output: true}, {
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) require.FileExists(t, post)
bts, err := os.ReadFile(post) bts, err := os.ReadFile(post)
require.NoError(t, err) 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) { t.Run("failing pre-hook", func(t *testing.T) {
ctx := ctx5 ctx := ctx5
ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} 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) err := Pipe{}.Run(ctx)
require.ErrorIs(t, err, exec.ErrNotFound) require.ErrorIs(t, err, exec.ErrNotFound)
require.ErrorContains(t, err, "pre hook failed") 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) { t.Run("failing post-hook", func(t *testing.T) {
ctx := ctx5 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"}} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}}
err := Pipe{}.Run(ctx) err := Pipe{}.Run(ctx)
require.ErrorIs(t, err, exec.ErrNotFound) 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.PostBuildHooks)] = false
ctx.Skips[string(skips.PreBuildHooks)] = false ctx.Skips[string(skips.PreBuildHooks)] = false
ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{
Cmd: "echo {{.Env.FOO}}", Cmd: echo + "{{.Env.FOO}}",
Env: []string{"FOO=foo-{{.Tag}}"}, Env: []string{"FOO=foo-{{.Tag}}"},
}} }}
ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} 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.PostBuildHooks)] = false
ctx.Skips[string(skips.PreBuildHooks)] = false ctx.Skips[string(skips.PreBuildHooks)] = false
ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{
Cmd: "echo blah", Cmd: echo + "blah",
Env: []string{"FOO=foo-{{.Tag}"}, Env: []string{"FOO=foo-{{.Tag}"},
}} }}
ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} 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) { t.Run("hook with bad dir tmpl", func(t *testing.T) {
ctx := ctx5 ctx := ctx5
ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{
Cmd: "echo blah", Cmd: echo + "blah",
Dir: "{{.Tag}", Dir: "{{.Tag}",
}} }}
ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} 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) { t.Run("hook with bad cmd tmpl", func(t *testing.T) {
ctx := ctx5 ctx := ctx5
ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{ ctx.Config.UniversalBinaries[0].Hooks.Pre = []config.Hook{{
Cmd: "echo blah-{{.Tag }", Cmd: echo + "blah-{{.Tag }",
}} }}
ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{} ctx.Config.UniversalBinaries[0].Hooks.Post = []config.Hook{}
testlib.RequireTemplateError(t, Pipe{}.Run(ctx)) testlib.RequireTemplateError(t, Pipe{}.Run(ctx))
@ -414,3 +429,10 @@ func checkUniversalBinary(tb testing.TB, unibin *artifact.Artifact) {
require.NoError(tb, err) require.NoError(tb, err)
require.Len(tb, f.Arches, 2) 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)
}

View File

@ -362,7 +362,11 @@ func TestRunPipe_ServerDown(t *testing.T) {
Name: "bin.tar.gz", Name: "bin.tar.gz",
Path: tarfile.Name(), 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) { func TestRunPipe_TargetTemplateError(t *testing.T) {

View File

@ -96,6 +96,7 @@ var knownExceptions = []string{
"AlreadyPackedException", "AlreadyPackedException",
"NotCompressibleException", "NotCompressibleException",
"UnknownExecutableFormatException", "UnknownExecutableFormatException",
"IOException",
} }
func findBinaries(ctx *context.Context, upx config.UPX) []*artifact.Artifact { func findBinaries(ctx *context.Context, upx config.UPX) []*artifact.Artifact {

View File

@ -1,3 +1,6 @@
//go:build !windows
// +build !windows
package shell_test package shell_test
import ( import (

View File

@ -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
}

View File

@ -14,6 +14,17 @@ var (
dockerPool *dockertest.Pool 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. // MustDockerPool gets a single dockertet.Pool.
func MustDockerPool(f Fataler) *dockertest.Pool { func MustDockerPool(f Fataler) *dockertest.Pool {
dockerPoolOnce.Do(func() { dockerPoolOnce.Do(func() {

View File

@ -110,7 +110,7 @@ func GitMakeBareRepository(tb testing.TB) string {
".", ".",
) )
require.NoError(tb, err) require.NoError(tb, err)
return dir return filepath.ToSlash(dir)
} }
func MakeNewSSHKey(tb testing.TB, pass string) string { func MakeNewSSHKey(tb testing.TB, pass string) string {

View File

@ -3,6 +3,7 @@ package testlib
import ( import (
"os" "os"
"os/exec" "os/exec"
"runtime"
"testing" "testing"
) )
@ -22,3 +23,14 @@ func InPath(cmd string) bool {
_, err := exec.LookPath(cmd) _, err := exec.LookPath(cmd)
return err == nil 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")
}
}

View File

@ -19,7 +19,11 @@ func TestCheckPath(t *testing.T) {
t.Run("in path", func(t *testing.T) { t.Run("in path", func(t *testing.T) {
requireSkipped(t, false) 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) { t.Run("not in path", func(t *testing.T) {

View File

@ -90,7 +90,6 @@ func TestWithArtifact(t *testing.T) {
"artifact ext: .exe": "artifact ext: {{ .ArtifactExt }}", "artifact ext: .exe": "artifact ext: {{ .ArtifactExt }}",
"artifact path: /tmp/foo.exe": "artifact path: {{ .ArtifactPath }}", "artifact path: /tmp/foo.exe": "artifact path: {{ .ArtifactPath }}",
"artifact basename: foo.exe": "artifact basename: {{ base .ArtifactPath }}", "artifact basename: foo.exe": "artifact basename: {{ base .ArtifactPath }}",
"artifact dir: /tmp": "artifact dir: {{ dir .ArtifactPath }}",
"2023": `{{ .Now.Format "2006" }}`, "2023": `{{ .Now.Format "2006" }}`,
"2023-03-09T02:06:02Z": `{{ .Date }}`, "2023-03-09T02:06:02Z": `{{ .Date }}`,
"1678327562": `{{ .Timestamp }}`, "1678327562": `{{ .Timestamp }}`,
@ -106,6 +105,8 @@ func TestWithArtifact(t *testing.T) {
"env foo is set: true": `env foo is set: {{ isEnvSet "FOO" }}`, "env foo is set: true": `env foo is set: {{ isEnvSet "FOO" }}`,
"/foo%2Fbar": `/{{ urlPathEscape .Env.WITH_SLASHES}}`, "/foo%2Fbar": `/{{ urlPathEscape .Env.WITH_SLASHES}}`,
"artifact dir: " + filepath.FromSlash("/tmp"): "artifact dir: {{ dir .ArtifactPath }}",
"remove this": "{{ filter .Env.MULTILINE \".*remove.*\" }}", "remove this": "{{ filter .Env.MULTILINE \".*remove.*\" }}",
"something with\nmultiple lines\nto test things": "{{ reverseFilter .Env.MULTILINE \".*remove.*\" }}", "something with\nmultiple lines\nto test things": "{{ reverseFilter .Env.MULTILINE \".*remove.*\" }}",

View File

@ -88,9 +88,18 @@ func TestTarFile(t *testing.T) {
} }
require.NoError(t, err) require.NoError(t, err)
paths = append(paths, next.Name) paths = append(paths, next.Name)
if testlib.IsWindows() {
// both of the following checks don't work on windows.
continue
}
if next.Name == "sub1/executable" { if next.Name == "sub1/executable" {
ex := next.FileInfo().Mode()&0o111 != 0 require.NotEqualf(
require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) t,
0,
next.FileInfo().Mode()&0o111,
"expected executable perms, got %s",
next.FileInfo().Mode().String(),
)
} }
if next.Name == "link.txt" { if next.Name == "link.txt" {
require.Equal(t, "regular.txt", next.Linkname) require.Equal(t, "regular.txt", next.Linkname)

View File

@ -10,6 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -87,9 +88,17 @@ func TestTarGzFile(t *testing.T) {
} }
require.NoError(t, err) require.NoError(t, err)
paths = append(paths, next.Name) paths = append(paths, next.Name)
if testlib.IsWindows() {
// both of the following checks don't work on windows.
continue
}
if next.Name == "sub1/executable" { if next.Name == "sub1/executable" {
ex := next.FileInfo().Mode()&0o111 != 0 require.NotEqualf(
require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) t,
0, next.FileInfo().Mode()&0o111,
"expected executable perms, got %s",
next.FileInfo().Mode().String(),
)
} }
if next.Name == "link.txt" { if next.Name == "link.txt" {
require.Equal(t, "regular.txt", next.Linkname) require.Equal(t, "regular.txt", next.Linkname)

View File

@ -9,6 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ulikunitz/xz" "github.com/ulikunitz/xz"
@ -86,9 +87,18 @@ func TestTarXzFile(t *testing.T) {
} }
require.NoError(t, err) require.NoError(t, err)
paths = append(paths, next.Name) paths = append(paths, next.Name)
if testlib.IsWindows() {
// both of the following checks don't work on windows.
continue
}
if next.Name == "sub1/executable" { if next.Name == "sub1/executable" {
ex := next.FileInfo().Mode()&0o111 != 0 require.NotEqualf(
require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) t,
0,
next.FileInfo().Mode()&0o111,
"expected executable perms, got %s",
next.FileInfo().Mode().String(),
)
} }
if next.Name == "link.txt" { if next.Name == "link.txt" {
require.Equal(t, "regular.txt", next.Linkname) require.Equal(t, "regular.txt", next.Linkname)

View File

@ -9,6 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -86,9 +87,18 @@ func TestTarZstFile(t *testing.T) {
} }
require.NoError(t, err) require.NoError(t, err)
paths = append(paths, next.Name) paths = append(paths, next.Name)
if testlib.IsWindows() {
// both of the following checks don't work on windows.
continue
}
if next.Name == "sub1/executable" { if next.Name == "sub1/executable" {
ex := next.FileInfo().Mode()&0o111 != 0 require.NotEqualf(
require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode()) t,
0,
next.FileInfo().Mode()&0o111,
"expected executable perms, got %s",
next.FileInfo().Mode().String(),
)
} }
if next.Name == "link.txt" { if next.Name == "link.txt" {
require.Equal(t, "regular.txt", next.Linkname) require.Equal(t, "regular.txt", next.Linkname)

View File

@ -10,6 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/goreleaser/goreleaser/v2/pkg/config" "github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -85,9 +86,14 @@ func TestZipFile(t *testing.T) {
paths := make([]string, len(r.File)) paths := make([]string, len(r.File))
for i, zf := range r.File { for i, zf := range r.File {
paths[i] = zf.Name paths[i] = zf.Name
if zf.Name == "sub1/executable" { if zf.Name == "sub1/executable" && !testlib.IsWindows() {
ex := zf.Mode()&0o111 != 0 require.NotEqualf(
require.True(t, ex, "expected executable permissions, got %s", zf.Mode()) t,
0,
zf.Mode()&0o111,
"expected executable perms, got %s",
zf.Mode().String(),
)
} }
if zf.Name == "link.txt" { if zf.Name == "link.txt" {
require.NotEqual(t, 0, zf.FileInfo().Mode()&os.ModeSymlink) require.NotEqual(t, 0, zf.FileInfo().Mode()&os.ModeSymlink)

View File

@ -473,7 +473,7 @@ nfpms:
# Custom configuration applied only to the IPK packager. # Custom configuration applied only to the IPK packager.
# #
# Since: v2.1 # Since: v2.1.
ipk: ipk:
# The ABI version to specify. # The ABI version to specify.
# #