diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml index cdee1393..d0289276 100644 --- a/.github/workflows/go-test.yml +++ b/.github/workflows/go-test.yml @@ -2,6 +2,12 @@ name: Lint & Test on: pull_request: workflow_call: + push: + branches: + - master + +env: + CGO_ENABLED: 1 jobs: lint: @@ -9,27 +15,16 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + pull-requests: read steps: - name: Configure git - run: git config --global core.autocrlf false # required on Windows + run: git config --global core.autocrlf false - uses: actions/checkout@v5 - uses: actions/setup-go@v5 with: - go-version: ${{ matrix.go-version }} + go-version: '1.24' - uses: golangci/golangci-lint-action@v7 with: skip-cache: true test: - name: Test - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/checkout@v5 - - uses: actions/setup-go@v5 - with: - go-version: 1.23 - - name: Test - uses: n8maninger/action-golang-test@v2 - with: - args: -race;-failfast + uses: SiaFoundation/workflows/.github/workflows/go-test.yml@master diff --git a/sia/multipart.go b/sia/multipart.go index c22336eb..ce67b07d 100644 --- a/sia/multipart.go +++ b/sia/multipart.go @@ -199,11 +199,9 @@ func (s *Sia) UploadPart(ctx context.Context, accessKeyID, bucket, object string } // sync parent directory - if dir, err := os.Open(partDir); errors.Is(err, os.ErrNotExist) { + if err := syncDir(partDir); errors.Is(err, os.ErrNotExist) { return nil, s3errs.ErrNoSuchUpload } else if err != nil { - return nil, fmt.Errorf("failed to open part directory: %w", err) - } else if err := errors.Join(dir.Sync(), dir.Close()); err != nil { return nil, fmt.Errorf("failed to sync part directory: %w", err) } @@ -312,11 +310,9 @@ func (s *Sia) UploadPartCopy(ctx context.Context, accessKeyID, srcBucket, srcObj } // sync parent directory - if dir, err := os.Open(partDir); errors.Is(err, os.ErrNotExist) { + if err := syncDir(partDir); errors.Is(err, os.ErrNotExist) { return nil, s3errs.ErrNoSuchUpload } else if err != nil { - return nil, fmt.Errorf("failed to open part directory: %w", err) - } else if err := errors.Join(dir.Sync(), dir.Close()); err != nil { return nil, fmt.Errorf("failed to sync part directory: %w", err) } diff --git a/sia/objects.go b/sia/objects.go index edb90576..04e15d79 100644 --- a/sia/objects.go +++ b/sia/objects.go @@ -45,7 +45,7 @@ func (s *Sia) openUpload(bucket, name string, obj *objects.Object, offset int64) uploadDir := filepath.Join(s.uploadDir(), *obj.FileName) return objects.NewReader(uploadDir, parts, offset) } - f, err := os.Open(filepath.Join(s.uploadDir(), *obj.FileName)) + f, err := openFileAllowDelete(filepath.Join(s.uploadDir(), *obj.FileName)) if err != nil { return nil, err } diff --git a/sia/os_nonwindows.go b/sia/os_nonwindows.go new file mode 100644 index 00000000..9dbbd6fb --- /dev/null +++ b/sia/os_nonwindows.go @@ -0,0 +1,20 @@ +//go:build !windows + +package sia + +import ( + "errors" + "os" +) + +func openFileAllowDelete(path string) (*os.File, error) { + return os.Open(path) +} + +func syncDir(path string) error { + dir, err := os.Open(path) + if err != nil { + return err + } + return errors.Join(dir.Sync(), dir.Close()) +} diff --git a/sia/os_windows.go b/sia/os_windows.go new file mode 100644 index 00000000..d2152a7d --- /dev/null +++ b/sia/os_windows.go @@ -0,0 +1,34 @@ +//go:build windows + +package sia + +import ( + "os" + "syscall" +) + +func openFileAllowDelete(path string) (*os.File, error) { + p, err := syscall.UTF16PtrFromString(path) + if err != nil { + return nil, err + } + + h, err := syscall.CreateFile( + p, + syscall.GENERIC_READ, + syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, + nil, + syscall.OPEN_EXISTING, + syscall.FILE_ATTRIBUTE_NORMAL, + 0, + ) + if err != nil { + return nil, err + } + + return os.NewFile(uintptr(h), path), nil +} + +func syncDir(path string) error { + return nil +} diff --git a/sia/persist/sqlite/objects_test.go b/sia/persist/sqlite/objects_test.go index 33a4249a..0ac9cc65 100644 --- a/sia/persist/sqlite/objects_test.go +++ b/sia/persist/sqlite/objects_test.go @@ -164,6 +164,7 @@ func TestListObjects(t *testing.T) { if err != nil { t.Fatal(err) } + t.Cleanup(func() { store.Close() }) // prepare a bucket bucket := "foo" @@ -375,6 +376,7 @@ func TestListObjectsMatch(t *testing.T) { if err != nil { t.Fatal(err) } + t.Cleanup(func() { store.Close() }) // prepare a bucket bucket := "foo" @@ -483,6 +485,7 @@ func TestListObjectsWalk(t *testing.T) { if err != nil { t.Fatal(err) } + t.Cleanup(func() { store.Close() }) // prepare a bucket bucket := "foo" @@ -579,6 +582,7 @@ func BenchmarkListObjects(b *testing.B) { if err != nil { b.Fatal(err) } + b.Cleanup(func() { store.Close() }) // prepare a bucket bucket := "foo"