Skip to content

Commit 4312a19

Browse files
committed
final pass
1 parent 618bdab commit 4312a19

23 files changed

Lines changed: 629 additions & 40 deletions

.github/workflows/ci.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ jobs:
3939
run: make test.static
4040

4141
- name: Race test
42-
run: go test -race ./...
42+
run: |
43+
set -euo pipefail
44+
if [ "$(go env GOOS)" = "darwin" ]; then
45+
shared="libdatafusion_go.dylib"
46+
else
47+
shared="libdatafusion_go.so"
48+
fi
49+
DATAFUSION_GO_LIBRARY="$PWD/internal/native/lib/$(go env GOOS)-$(go env GOARCH)/${shared}" go test -race ./...
4350
4451
- name: Vet
4552
run: go vet ./...
@@ -106,7 +113,7 @@ jobs:
106113

107114
- name: Race test
108115
shell: msys2 {0}
109-
run: go test -race ./...
116+
run: DATAFUSION_GO_LIBRARY="$PWD/internal/native/lib/windows-amd64/datafusion_go.dll" go test -race ./...
110117

111118
- name: Vet
112119
shell: msys2 {0}

.github/workflows/release.yml

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ jobs:
7878
CARGO_BUILD_TARGET: x86_64-pc-windows-gnu
7979
run: make test
8080

81-
- name: Upload native archive
81+
- name: Upload native libraries
8282
uses: actions/upload-artifact@v4
8383
with:
8484
name: native-${{ matrix.platform }}
85-
path: internal/native/lib/${{ matrix.platform }}/libdatafusion_go.a
85+
path: internal/native/lib/${{ matrix.platform }}/*datafusion_go*
8686
if-no-files-found: error
8787

8888
release:
@@ -130,10 +130,12 @@ jobs:
130130
for dir in internal/native/lib/native-*; do
131131
platform="${dir##*/native-}"
132132
mkdir -p "internal/native/lib/${platform}"
133-
mv "${dir}/libdatafusion_go.a" "internal/native/lib/${platform}/libdatafusion_go.a"
133+
find "${dir}" -maxdepth 1 -type f -print | while read -r file; do
134+
mv "${file}" "internal/native/lib/${platform}/$(basename "${file}")"
135+
done
134136
rmdir "${dir}"
135137
done
136-
find internal/native/lib -name libdatafusion_go.a -print | sort
138+
find internal/native/lib -type f -print | sort
137139
138140
- name: Generate checksums
139141
run: make checksums
@@ -144,6 +146,23 @@ jobs:
144146
- name: Verify downloaded release artifacts
145147
run: make verify.release.downloaded
146148

149+
- name: Stage release assets
150+
run: |
151+
set -euo pipefail
152+
tag="${{ steps.version.outputs.release_tag }}"
153+
rm -rf dist
154+
mkdir -p dist
155+
while IFS= read -r file; do
156+
platform="$(basename "$(dirname "${file}")")"
157+
base="$(basename "${file}")"
158+
cp "${file}" "dist/datafusion-go-${tag}-${platform}-${base}"
159+
done < <(find internal/native/lib -mindepth 2 -maxdepth 2 -type f \( -name 'libdatafusion_go.a' -o -name 'libdatafusion_go.so' -o -name 'libdatafusion_go.dylib' -o -name 'datafusion_go.dll' \) -print | sort)
160+
cd dist
161+
shasum -a 256 datafusion-go-* > SHA256SUMS
162+
shasum -a 256 -c SHA256SUMS
163+
cd ..
164+
cp dist/SHA256SUMS internal/native/lib/SHA256SUMS
165+
147166
- name: Prepare release notes
148167
id: notes
149168
run: |
@@ -162,6 +181,20 @@ jobs:
162181
fi
163182
echo "path=${notes_file}" >> "$GITHUB_OUTPUT"
164183
184+
- name: Commit release checksum manifest
185+
if: ${{ inputs.publish }}
186+
run: |
187+
set -euo pipefail
188+
git config user.name "github-actions[bot]"
189+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
190+
git add -f internal/native/lib/SHA256SUMS
191+
if git diff --cached --quiet; then
192+
echo "release checksum manifest is unchanged"
193+
else
194+
git commit -m "chore: prepare ${{ steps.version.outputs.release_tag }} native checksums"
195+
git push origin "HEAD:${GITHUB_REF_NAME}"
196+
fi
197+
165198
- name: Tag release
166199
if: ${{ inputs.publish }}
167200
run: |
@@ -177,10 +210,10 @@ jobs:
177210
GH_TOKEN: ${{ github.token }}
178211
run: |
179212
set -euo pipefail
180-
assets=(internal/native/lib/SHA256SUMS)
213+
assets=(dist/SHA256SUMS)
181214
while IFS= read -r file; do
182215
assets+=("$file")
183-
done < <(find internal/native/lib -name libdatafusion_go.a -print | sort)
216+
done < <(find dist -type f -name 'datafusion-go-*' -print | sort)
184217
gh release create "${{ steps.version.outputs.release_tag }}" \
185218
--title "${{ steps.version.outputs.release_tag }}" \
186219
--notes-file "${{ steps.notes.outputs.path }}" \

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ temp/
1414
*.o
1515
*.obj
1616
*.wasm
17-
internal/native/lib/
17+
internal/native/lib/*
18+
!internal/native/lib/SHA256SUMS
1819
rust/target/
1920

2021
# Go test, coverage, and profiling artifacts

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ changes incompatibly with the Go native wrapper.
6767

6868
## Native Libraries
6969

70-
The Rust crate under `rust/` builds `libdatafusion_go.a`. The default Go build links the platform-specific archive from `internal/native/lib/<goos>-<goarch>/libdatafusion_go.a`.
70+
The Rust crate under `rust/` builds a static archive and a shared library. The default Go build loads the platform-specific shared library at runtime from `DATAFUSION_GO_LIBRARY`, from `internal/native/lib/<goos>-<goarch>` in source checkouts, or from the checksum-verified release-asset cache. The explicit `datafusion_use_bundled` mode links the platform-specific static archive from `internal/native/lib/<goos>-<goarch>/libdatafusion_go.a`.
7171

7272
Use `make bundle` only when you intend to copy the current host build into `internal/native/lib`. Release verification uses `make verify.release.downloaded` so downloaded matrix artifacts are not overwritten by the release runner.
7373

@@ -81,5 +81,5 @@ Go/Rust/no-cgo tests, and runs a clean consumer-module smoke test without
8181
tagging or creating a GitHub release.
8282

8383
When the dry run succeeds, rerun the same workflow with `publish=true`. It tags
84-
the checked-out commit with the derived release tag and uploads the generated
85-
native archives plus checksums.
84+
commits the release-asset checksum manifest, tags that commit with the derived
85+
release tag, and uploads the generated native libraries plus checksums.

Makefile

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ NATIVE_LIB_DIR := internal/native/lib/$(NATIVE_PLATFORM)
66
NATIVE_LIB := $(NATIVE_LIB_DIR)/libdatafusion_go.a
77
CARGO_BUILD_TARGET ?=
88

9+
ifeq ($(GOOS),windows)
10+
NATIVE_SHARED_NAME := datafusion_go.dll
11+
else ifeq ($(GOOS),darwin)
12+
NATIVE_SHARED_NAME := libdatafusion_go.dylib
13+
else
14+
NATIVE_SHARED_NAME := libdatafusion_go.so
15+
endif
16+
17+
NATIVE_SHARED := $(NATIVE_LIB_DIR)/$(NATIVE_SHARED_NAME)
18+
919
ifeq ($(GOOS)-$(GOARCH),windows-amd64)
1020
CARGO_BUILD_TARGET := $(or $(CARGO_BUILD_TARGET),x86_64-pc-windows-gnu)
1121
endif
@@ -18,11 +28,18 @@ RUST_TARGET_FLAG :=
1828
RUST_TARGET_RELEASE_DIR := rust/target/release
1929
endif
2030

31+
RUST_SHARED_LIB := $(RUST_TARGET_RELEASE_DIR)/$(NATIVE_SHARED_NAME)
32+
2133
ifeq ($(GOOS),darwin)
2234
RUST_BUILD_ENV := MACOSX_DEPLOYMENT_TARGET=$(MACOSX_DEPLOYMENT_TARGET) CFLAGS="$(strip $(CFLAGS) -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET))"
35+
STRIP_SHARED := strip -x
36+
else ifeq ($(GOOS),linux)
37+
STRIP_SHARED := strip --strip-unneeded
38+
else ifeq ($(GOOS),windows)
39+
STRIP_SHARED := strip --strip-unneeded
2340
endif
2441

25-
.PHONY: generate generate.check rust bundle checksums verify.checksums test test.bundled test.source test.static consumer.smoke lint verify.release verify.release.downloaded clean
42+
.PHONY: generate generate.check rust bundle checksums verify.checksums test test.dynamic test.bundled test.source test.static consumer.smoke lint verify.release verify.release.downloaded clean
2643

2744
generate:
2845
go run ./internal/tools/genversions
@@ -38,20 +55,26 @@ rust: generate.check
3855
bundle: rust
3956
mkdir -p $(NATIVE_LIB_DIR)
4057
cp $(RUST_TARGET_RELEASE_DIR)/libdatafusion_go.a $(NATIVE_LIB)
58+
cp $(RUST_SHARED_LIB) $(NATIVE_SHARED)
59+
if [ -n "$(STRIP_SHARED)" ]; then $(STRIP_SHARED) $(NATIVE_SHARED); fi
4160

4261
checksums:
4362
mkdir -p internal/native/lib
44-
cd internal/native/lib && find . -name libdatafusion_go.a -print | sed 's#^\./##' | sort | while read -r file; do shasum -a 256 "$$file"; done > SHA256SUMS
63+
cd internal/native/lib && find . -type f \( -name libdatafusion_go.a -o -name libdatafusion_go.so -o -name libdatafusion_go.dylib -o -name datafusion_go.dll \) -print | sed 's#^\./##' | sort | while read -r file; do shasum -a 256 "$$file"; done > SHA256SUMS
4564

4665
verify.checksums:
4766
test -s internal/native/lib/SHA256SUMS
4867
cd internal/native/lib && shasum -a 256 -c SHA256SUMS
4968

5069
test: bundle
70+
$(MAKE) test.dynamic
5171
$(MAKE) test.bundled
5272

73+
test.dynamic:
74+
DATAFUSION_GO_LIBRARY=$(CURDIR)/$(NATIVE_SHARED) go test ./...
75+
5376
test.bundled:
54-
go test ./...
77+
go test -tags=datafusion_use_bundled ./...
5578

5679
test.source: rust
5780
go test -tags=datafusion_use_source ./...
@@ -82,23 +105,23 @@ consumer.smoke:
82105
' if err := db.QueryRowContext(context.Background(), "select 1").Scan(&value); err != nil { panic(err) }' \
83106
' if value != 1 { panic(fmt.Sprintf("got %d, want 1", value)) }' \
84107
'}' > main.go; \
85-
go run .
108+
DATAFUSION_GO_LIBRARY=$(CURDIR)/$(NATIVE_SHARED) go run .
86109

87110
lint: generate.check
88111
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest run
89112
cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings
90113
cargo fmt --manifest-path rust/Cargo.toml -- --check
91114

92115
verify.release: test test.source test.static
93-
go test -race ./...
116+
DATAFUSION_GO_LIBRARY=$(CURDIR)/$(NATIVE_SHARED) go test -race ./...
94117
go vet ./...
95118
cargo test --manifest-path rust/Cargo.toml --release
96119
CGO_ENABLED=0 go test ./...
97120
$(MAKE) checksums
98121
$(MAKE) verify.checksums
99122

100123
verify.release.downloaded: verify.checksums test.bundled consumer.smoke test.source test.static
101-
go test -race ./...
124+
DATAFUSION_GO_LIBRARY=$(CURDIR)/$(NATIVE_SHARED) go test -race ./...
102125
go vet ./...
103126
cargo test --manifest-path rust/Cargo.toml --release
104127
CGO_ENABLED=0 go test ./...

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Build and bundle the Rust shim before running Go tests:
2929
make test
3030
```
3131

32-
That target copies the generated native archive to `internal/native/lib/<goos>-<goarch>/libdatafusion_go.a`, which is the default static-link path. Native archives are build outputs and are not committed to Git.
32+
That target copies the generated native archive and shared library to `internal/native/lib/<goos>-<goarch>/`. Native libraries are build outputs and are not committed to Git.
3333

3434
To link directly from `rust/target/release` during local development:
3535

@@ -52,17 +52,20 @@ db, err := sql.Open("datafusion", "")
5252

5353
## Linking Modes
5454

55-
Default builds use a generated static library selected from `internal/native/lib/<goos>-<goarch>`. Source checkouts should run `make bundle` or `make test` before invoking `go test` directly.
55+
Default builds use cgo but do not link a DataFusion native library at Go link time. At runtime, the driver loads a shared `libdatafusion_go` from `DATAFUSION_GO_LIBRARY`, from `internal/native/lib/<goos>-<goarch>` in source checkouts, or from the checksum-verified cache populated from the matching GitHub Release asset.
56+
57+
Source checkouts should run `make bundle` or `make test` before invoking Go tests that open the driver directly. To disable automatic release-asset downloads, set `DATAFUSION_GO_NO_DOWNLOAD=1`.
5658

5759
Development modes:
5860

5961
```sh
6062
make rust
63+
go test -tags=datafusion_use_bundled ./...
6164
go test -tags=datafusion_use_source ./...
6265
go test -tags=datafusion_use_static_lib ./...
6366
```
6467

65-
`datafusion_use_source` and `datafusion_use_static_lib` link from `rust/target/release`, so run `make rust` first. On `windows-amd64`, `make rust` targets `x86_64-pc-windows-gnu` and the link path is `rust/target/x86_64-pc-windows-gnu/release`.
68+
`datafusion_use_bundled` links the static archive from `internal/native/lib/<goos>-<goarch>`. `datafusion_use_source` and `datafusion_use_static_lib` link from `rust/target/release`, so run `make rust` first. On `windows-amd64`, `make rust` targets `x86_64-pc-windows-gnu` and the link path is `rust/target/x86_64-pc-windows-gnu/release`.
6669

6770
Shared-library mode links with `-ldatafusion_go` and requires `libdatafusion_go` to be on the system linker path:
6871

@@ -200,6 +203,6 @@ Nested and complex Arrow values such as lists, structs, maps, unions, dictionari
200203

201204
## Current Distribution Status
202205

203-
Native archives are generated by the build and intentionally kept out of Git because the static archives exceed GitHub's normal file-size limits. Release automation builds archives for `darwin-arm64`, `darwin-amd64`, `linux-amd64`, `linux-arm64`, and `windows-amd64`, writes `internal/native/lib/SHA256SUMS`, verifies it without rebundling the current runner's local archive, and can run as a dry run before publishing. When `publish` is enabled, it tags the source commit and uploads the generated archives plus checksums to the GitHub release.
206+
Native libraries are generated by the build and intentionally kept out of Git because the static archives exceed GitHub's normal file-size limits and Go module zips have a 500 MiB source limit. Release automation builds static archives and shared libraries for `darwin-arm64`, `darwin-amd64`, `linux-amd64`, `linux-arm64`, and `windows-amd64`, verifies them without rebundling the current runner's local output, writes the release-asset `SHA256SUMS` manifest into the tagged tree, and uploads the generated native files plus checksums to the GitHub release.
204207

205-
Windows arm64 is not currently a bundled target. Before a public release, run the release workflow once with `publish=false`, verify that all release-runner labels are available in GitHub Actions, and confirm the generated native archives link from a clean consumer module on each target platform.
208+
Windows arm64 is not currently a bundled target. Before a public release, run the release workflow once with `publish=false`, verify that all release-runner labels are available in GitHub Actions, and confirm the generated native libraries load from a clean consumer module on each target platform.

0 commit comments

Comments
 (0)