mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-29 17:05:46 +08:00
Merge pull request #2206 from crazy-max/test-os
ci: test-unit job matrix for win/macos/ubuntu
This commit is contained in:
commit
827622421e
94
.github/workflows/build.yml
vendored
94
.github/workflows/build.yml
vendored
@ -24,9 +24,13 @@ env:
|
|||||||
REPO_SLUG: "docker/buildx-bin"
|
REPO_SLUG: "docker/buildx-bin"
|
||||||
DESTDIR: "./bin"
|
DESTDIR: "./bin"
|
||||||
TEST_CACHE_SCOPE: "test"
|
TEST_CACHE_SCOPE: "test"
|
||||||
|
TESTFLAGS: "-v --parallel=6 --timeout=30m"
|
||||||
|
GOTESTSUM_FORMAT: "standard-verbose"
|
||||||
|
GO_VERSION: "1.21.6"
|
||||||
|
GOTESTSUM_VERSION: "v1.9.0" # same as one in Dockerfile
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
prepare-test:
|
prepare-test-integration:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
@ -51,14 +55,12 @@ jobs:
|
|||||||
*.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
*.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
||||||
*.cache-to=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
*.cache-to=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
||||||
|
|
||||||
test:
|
test-integration:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs:
|
needs:
|
||||||
- prepare-test
|
- prepare-test-integration
|
||||||
env:
|
env:
|
||||||
TESTFLAGS: "-v --parallel=6 --timeout=30m"
|
|
||||||
TESTFLAGS_DOCKER: "-v --parallel=1 --timeout=30m"
|
TESTFLAGS_DOCKER: "-v --parallel=1 --timeout=30m"
|
||||||
GOTESTSUM_FORMAT: "standard-verbose"
|
|
||||||
TEST_IMAGE_BUILD: "0"
|
TEST_IMAGE_BUILD: "0"
|
||||||
TEST_IMAGE_ID: "buildx-tests"
|
TEST_IMAGE_ID: "buildx-tests"
|
||||||
strategy:
|
strategy:
|
||||||
@ -71,9 +73,6 @@ jobs:
|
|||||||
- remote
|
- remote
|
||||||
pkg:
|
pkg:
|
||||||
- ./tests
|
- ./tests
|
||||||
include:
|
|
||||||
- pkg: ./...
|
|
||||||
skip-integration-tests: 1
|
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
@ -101,19 +100,19 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Test
|
name: Test
|
||||||
run: |
|
run: |
|
||||||
export TEST_REPORT_SUFFIX=-${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')
|
export TEST_REPORT_SUFFIX=-${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')
|
||||||
./hack/test
|
./hack/test
|
||||||
env:
|
env:
|
||||||
TEST_DOCKERD: "${{ startsWith(matrix.worker, 'docker') && '1' || '0' }}"
|
TEST_DOCKERD: "${{ startsWith(matrix.worker, 'docker') && '1' || '0' }}"
|
||||||
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker\\+containerd') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
|
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker\\+containerd') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
|
||||||
TESTPKGS: "${{ matrix.pkg }}"
|
TESTPKGS: "${{ matrix.pkg }}"
|
||||||
SKIP_INTEGRATION_TESTS: "${{ matrix.skip-integration-tests }}"
|
|
||||||
-
|
-
|
||||||
name: Send to Codecov
|
name: Send to Codecov
|
||||||
if: always()
|
if: always()
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
directory: ./bin/testreports
|
directory: ./bin/testreports
|
||||||
|
flags: integration
|
||||||
-
|
-
|
||||||
name: Generate annotations
|
name: Generate annotations
|
||||||
if: always()
|
if: always()
|
||||||
@ -128,6 +127,75 @@ jobs:
|
|||||||
name: test-reports
|
name: test-reports
|
||||||
path: ./bin/testreports
|
path: ./bin/testreports
|
||||||
|
|
||||||
|
test-unit:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-22.04
|
||||||
|
- macos-12
|
||||||
|
- windows-2022
|
||||||
|
env:
|
||||||
|
SKIP_INTEGRATION_TESTS: 1
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: "${{ env.GO_VERSION }}"
|
||||||
|
-
|
||||||
|
name: Prepare
|
||||||
|
run: |
|
||||||
|
testreportsBaseDir=./bin/testreports
|
||||||
|
testreportsDir=$testreportsBaseDir/unit-${{ matrix.os }}
|
||||||
|
echo "TESTREPORTS_BASEDIR=$testreportsBaseDir" >> $GITHUB_ENV
|
||||||
|
echo "TESTREPORTS_DIR=$testreportsDir" >> $GITHUB_ENV
|
||||||
|
mkdir -p $testreportsDir
|
||||||
|
shell: bash
|
||||||
|
-
|
||||||
|
name: Install gotestsum
|
||||||
|
run: |
|
||||||
|
go install gotest.tools/gotestsum@${{ env.GOTESTSUM_VERSION }}
|
||||||
|
-
|
||||||
|
name: Test
|
||||||
|
env:
|
||||||
|
TMPDIR: ${{ runner.temp }}
|
||||||
|
run: |
|
||||||
|
gotestsum \
|
||||||
|
--jsonfile="${{ env.TESTREPORTS_DIR }}/go-test-report.json" \
|
||||||
|
--junitfile="${{ env.TESTREPORTS_DIR }}/junit-report.xml" \
|
||||||
|
--packages="./..." \
|
||||||
|
-- \
|
||||||
|
"-mod=vendor" \
|
||||||
|
"-coverprofile" "${{ env.TESTREPORTS_DIR }}/coverage.txt" \
|
||||||
|
"-covermode" "atomic" ${{ env.TESTFLAGS }}
|
||||||
|
shell: bash
|
||||||
|
-
|
||||||
|
name: Send to Codecov
|
||||||
|
if: always()
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
directory: ${{ env.TESTREPORTS_DIR }}
|
||||||
|
env_vars: RUNNER_OS
|
||||||
|
flags: unit
|
||||||
|
-
|
||||||
|
name: Generate annotations
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/.github/.github/actions/gotest-annotations@1a64ea6d01db9a48aa61954cb20e265782c167d9
|
||||||
|
with:
|
||||||
|
directory: ${{ env.TESTREPORTS_DIR }}
|
||||||
|
-
|
||||||
|
name: Upload test reports
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: test-reports
|
||||||
|
path: ${{ env.TESTREPORTS_BASEDIR }}
|
||||||
|
|
||||||
prepare-binaries:
|
prepare-binaries:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
outputs:
|
outputs:
|
||||||
@ -192,7 +260,8 @@ jobs:
|
|||||||
bin-image:
|
bin-image:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs:
|
needs:
|
||||||
- test
|
- test-integration
|
||||||
|
- test-unit
|
||||||
if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/buildx' }}
|
if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/buildx' }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
@ -244,7 +313,8 @@ jobs:
|
|||||||
release:
|
release:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs:
|
needs:
|
||||||
- test
|
- test-integration
|
||||||
|
- test-unit
|
||||||
- binaries
|
- binaries
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
|
19
build/git.go
19
build/git.go
@ -46,9 +46,9 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
|||||||
if filepath.IsAbs(contextPath) {
|
if filepath.IsAbs(contextPath) {
|
||||||
wd = contextPath
|
wd = contextPath
|
||||||
} else {
|
} else {
|
||||||
cwd, _ := os.Getwd()
|
wd, _ = filepath.Abs(filepath.Join(getWd(), contextPath))
|
||||||
wd, _ = filepath.Abs(filepath.Join(cwd, contextPath))
|
|
||||||
}
|
}
|
||||||
|
wd = gitutil.SanitizePath(wd)
|
||||||
|
|
||||||
gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd))
|
gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,8 +104,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
|||||||
dockerfilePath = filepath.Join(wd, "Dockerfile")
|
dockerfilePath = filepath.Join(wd, "Dockerfile")
|
||||||
}
|
}
|
||||||
if !filepath.IsAbs(dockerfilePath) {
|
if !filepath.IsAbs(dockerfilePath) {
|
||||||
cwd, _ := os.Getwd()
|
dockerfilePath = filepath.Join(getWd(), dockerfilePath)
|
||||||
dockerfilePath = filepath.Join(cwd, dockerfilePath)
|
|
||||||
}
|
}
|
||||||
if r, err := filepath.Rel(root, dockerfilePath); err == nil && !strings.HasPrefix(r, "..") {
|
if r, err := filepath.Rel(root, dockerfilePath); err == nil && !strings.HasPrefix(r, "..") {
|
||||||
res["label:"+DockerfileLabel] = r
|
res["label:"+DockerfileLabel] = r
|
||||||
@ -125,9 +124,21 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if lp, err := getLongPathName(dir); err == nil {
|
||||||
|
dir = lp
|
||||||
|
}
|
||||||
|
dir = gitutil.SanitizePath(dir)
|
||||||
if r, err := filepath.Rel(root, dir); err == nil && !strings.HasPrefix(r, "..") {
|
if r, err := filepath.Rel(root, dir); err == nil && !strings.HasPrefix(r, "..") {
|
||||||
so.FrontendAttrs["vcs:localdir:"+k] = r
|
so.FrontendAttrs["vcs:localdir:"+k] = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getWd() string {
|
||||||
|
wd, _ := os.Getwd()
|
||||||
|
if lp, err := getLongPathName(wd); err == nil {
|
||||||
|
return lp
|
||||||
|
}
|
||||||
|
return wd
|
||||||
|
}
|
||||||
|
9
build/git_unix.go
Normal file
9
build/git_unix.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package build
|
||||||
|
|
||||||
|
// getLongPathName is a no-op on non-Windows platforms.
|
||||||
|
func getLongPathName(path string) (string, error) {
|
||||||
|
return path, nil
|
||||||
|
}
|
26
build/git_windows.go
Normal file
26
build/git_windows.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
|
// getLongPathName converts Windows short pathnames to full pathnames.
|
||||||
|
// For example C:\Users\ADMIN~1 --> C:\Users\Administrator.
|
||||||
|
func getLongPathName(path string) (string, error) {
|
||||||
|
// See https://groups.google.com/forum/#!topic/golang-dev/1tufzkruoTg
|
||||||
|
p, err := windows.UTF16FromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
b := p // GetLongPathName says we can reuse buffer
|
||||||
|
n, err := windows.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if n > uint32(len(b)) {
|
||||||
|
b = make([]uint16, n)
|
||||||
|
_, err = windows.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return windows.UTF16ToString(b), nil
|
||||||
|
}
|
2
go.mod
2
go.mod
@ -46,6 +46,7 @@ require (
|
|||||||
go.opentelemetry.io/otel/trace v1.19.0
|
go.opentelemetry.io/otel/trace v1.19.0
|
||||||
golang.org/x/mod v0.11.0
|
golang.org/x/mod v0.11.0
|
||||||
golang.org/x/sync v0.3.0
|
golang.org/x/sync v0.3.0
|
||||||
|
golang.org/x/sys v0.15.0
|
||||||
golang.org/x/term v0.15.0
|
golang.org/x/term v0.15.0
|
||||||
google.golang.org/grpc v1.58.3
|
google.golang.org/grpc v1.58.3
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
@ -152,7 +153,6 @@ require (
|
|||||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
||||||
golang.org/x/net v0.17.0 // indirect
|
golang.org/x/net v0.17.0 // indirect
|
||||||
golang.org/x/oauth2 v0.10.0 // indirect
|
golang.org/x/oauth2 v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.15.0 // indirect
|
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.10.0 // indirect
|
golang.org/x/tools v0.10.0 // indirect
|
||||||
|
@ -70,7 +70,7 @@ func (c *Git) RootDir() (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return sanitizePath(root), nil
|
return SanitizePath(root), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Git) GitDir() (string, error) {
|
func (c *Git) GitDir() (string, error) {
|
||||||
|
@ -45,7 +45,7 @@ func gitPath(wd string) (string, error) {
|
|||||||
|
|
||||||
var windowsPathRegex = regexp.MustCompile(`^[A-Za-z]:[\\/].*$`)
|
var windowsPathRegex = regexp.MustCompile(`^[A-Za-z]:[\\/].*$`)
|
||||||
|
|
||||||
func sanitizePath(path string) string {
|
func SanitizePath(path string) string {
|
||||||
// If we're running in WSL, we need to convert Windows paths to Unix paths.
|
// If we're running in WSL, we need to convert Windows paths to Unix paths.
|
||||||
// This is because the git binary can be invoked through `git.exe` and
|
// This is because the git binary can be invoked through `git.exe` and
|
||||||
// therefore returns Windows paths.
|
// therefore returns Windows paths.
|
@ -10,10 +10,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSanitizePathUnix(t *testing.T) {
|
func TestSanitizePathUnix(t *testing.T) {
|
||||||
assert.Equal(t, "/home/foobar", sanitizePath("/home/foobar"))
|
assert.Equal(t, "/home/foobar", SanitizePath("/home/foobar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSanitizePathWSL(t *testing.T) {
|
func TestSanitizePathWSL(t *testing.T) {
|
||||||
t.Setenv("WSL_DISTRO_NAME", "Ubuntu")
|
t.Setenv("WSL_DISTRO_NAME", "Ubuntu")
|
||||||
assert.Equal(t, "/mnt/c/Users/foobar", sanitizePath("C:\\Users\\foobar"))
|
assert.Equal(t, "/mnt/c/Users/foobar", SanitizePath("C:\\Users\\foobar"))
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ func gitPath(wd string) (string, error) {
|
|||||||
return exec.LookPath("git.exe")
|
return exec.LookPath("git.exe")
|
||||||
}
|
}
|
||||||
|
|
||||||
func sanitizePath(path string) string {
|
func SanitizePath(path string) string {
|
||||||
return filepath.ToSlash(filepath.Clean(path))
|
return filepath.ToSlash(filepath.Clean(path))
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,28 @@
|
|||||||
package gitutil
|
package gitutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSanitizePathWindows(t *testing.T) {
|
func TestSanitizePathWindows(t *testing.T) {
|
||||||
assert.Equal(t, "C:\\Users\\foobar", sanitizePath("C:/Users/foobar"))
|
expected := "C:\\Users\\foobar"
|
||||||
|
if isGitBash() {
|
||||||
|
expected = "C:/Users/foobar"
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, SanitizePath("C:/Users/foobar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func isGitBash() bool {
|
||||||
|
// The MSYSTEM environment variable is used in MSYS2 environments,
|
||||||
|
// including Git Bash, to select the active environment. This variable
|
||||||
|
// dictates the environment in which the shell operates, influencing
|
||||||
|
// factors like the path prefixes, default compilers, and system libraries
|
||||||
|
// used: https://www.msys2.org/docs/environments/
|
||||||
|
if _, ok := os.LookupEnv("MSYSTEM"); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user