1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2024-12-25 01:32:21 +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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
54 changed files with 393 additions and 133 deletions

View File

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

View File

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

View File

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

View File

@ -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")

View File

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

View File

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

View File

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

2
go.mod
View File

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

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/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=

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {

View File

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

View File

@ -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")

View File

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

View File

@ -309,8 +309,11 @@ func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
})
err = Pipe{}.Run(ctx)
require.Error(t, err)
if !testlib.IsWindows() {
// this fails on windows
require.ErrorIs(t, Pipe{}.Run(ctx), syscall.EACCES)
}
}
func TestPipeWhenNoArtifacts(t *testing.T) {
ctx := testctx.New()

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...
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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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",

View File

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

View File

@ -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()

View File

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

View File

@ -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")

View File

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

View File

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

View File

@ -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) {

View File

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

View File

@ -1,3 +1,6 @@
//go:build !windows
// +build !windows
package shell_test
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
)
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() {

View File

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

View File

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

View File

@ -19,7 +19,11 @@ func TestCheckPath(t *testing.T) {
t.Run("in path", func(t *testing.T) {
requireSkipped(t, false)
if IsWindows() {
CheckPath(t, "cmd.exe")
} else {
CheckPath(t, "echo")
}
})
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 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.*\" }}",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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.
#