diff --git a/.github/workflows/preview-release.yml b/.github/workflows/preview-release.yml index 54ea63d..52002c0 100644 --- a/.github/workflows/preview-release.yml +++ b/.github/workflows/preview-release.yml @@ -1,4 +1,4 @@ -name: Preview Release +name: Fork Package Release on: release: @@ -9,8 +9,12 @@ permissions: id-token: write jobs: - publish-preview: - if: github.event.release.prerelease == true && startsWith(github.event.release.tag_name, 'v1.5.4-preview.') + publish-fork-package: + if: >- + (github.event.release.prerelease == true && + startsWith(github.event.release.tag_name, 'v1.5.4-preview.')) || + (github.event.release.prerelease == false && + github.event.release.tag_name == 'v1.5.4') runs-on: ubuntu-latest environment: nuget-preview @@ -21,16 +25,28 @@ jobs: fetch-depth: 0 ref: ${{ github.event.release.tag_name }} - - name: Set preview version + - name: Set package version and release mode shell: bash run: | version="${{ github.event.release.tag_name }}" version="${version#v}" - if [[ ! "$version" =~ ^1\.5\.4-preview\.[0-9]+$ ]]; then - echo "Unexpected preview version: $version" >&2 + + if [[ "$version" =~ ^1\.5\.4-preview\.[0-9]+$ ]]; then + fork_preview=true + fork_release=false + elif [[ "$version" == "1.5.4" ]]; then + fork_preview=false + fork_release=true + else + echo "Unexpected fork package version: $version" >&2 exit 1 fi - echo "PREVIEW_VERSION=$version" >> "$GITHUB_ENV" + + { + echo "PACKAGE_VERSION=$version" + echo "FORK_PREVIEW=$fork_preview" + echo "FORK_RELEASE=$fork_release" + } >> "$GITHUB_ENV" - name: Setup .NET SDK uses: actions/setup-dotnet@v5 @@ -48,9 +64,10 @@ jobs: /m:1 /p:BuildType=Full /p:CI=false - /p:ForkPreview=true - /p:Version=${{ env.PREVIEW_VERSION }} - /p:PackageVersion=${{ env.PREVIEW_VERSION }} + /p:ForkPreview="$FORK_PREVIEW" + /p:ForkRelease="$FORK_RELEASE" + /p:Version="$PACKAGE_VERSION" + /p:PackageVersion="$PACKAGE_VERSION" /p:UseSharedCompilation=false - name: Test @@ -62,60 +79,63 @@ jobs: --logger "console;verbosity=quiet" /p:BuildType=Full /p:CI=false - /p:ForkPreview=true + /p:ForkPreview="$FORK_PREVIEW" + /p:ForkRelease="$FORK_RELEASE" /p:DoesNotReturnAttribute=DoesNotReturnAttribute - - name: Pack preview packages + - name: Pack fork packages shell: bash run: | - mkdir -p artifacts/preview + mkdir -p artifacts/fork-release common_args=( --configuration Release --no-build --no-restore - --output artifacts/preview + --output artifacts/fork-release /m:1 /p:BuildType=Full /p:CI=false - /p:ForkPreview=true - /p:PreviewPack=true - /p:Version="$PREVIEW_VERSION" - /p:PackageVersion="$PREVIEW_VERSION" + /p:ForkPreview="$FORK_PREVIEW" + /p:ForkRelease="$FORK_RELEASE" + /p:ForkPack=true + /p:Version="$PACKAGE_VERSION" + /p:PackageVersion="$PACKAGE_VERSION" ) dotnet pack DuckDB.NET.Bindings/Bindings.csproj "${common_args[@]}" dotnet restore DuckDB.NET.Data/Data.csproj \ - --source artifacts/preview \ + --source artifacts/fork-release \ --source https://api.nuget.org/v3/index.json \ /p:BuildType=Full \ /p:CI=false \ - /p:ForkPreview=true \ - /p:PreviewPack=true \ - /p:Version="$PREVIEW_VERSION" \ - /p:PackageVersion="$PREVIEW_VERSION" + /p:ForkPreview="$FORK_PREVIEW" \ + /p:ForkRelease="$FORK_RELEASE" \ + /p:ForkPack=true \ + /p:Version="$PACKAGE_VERSION" \ + /p:PackageVersion="$PACKAGE_VERSION" dotnet pack DuckDB.NET.Data/Data.csproj "${common_args[@]}" - name: Validate and smoke-test packages - run: ./scripts/validate-preview-packages.sh artifacts/preview "$PREVIEW_VERSION" + run: ./scripts/validate-fork-packages.sh artifacts/fork-release "$PACKAGE_VERSION" - name: Generate checksums - working-directory: artifacts/preview + working-directory: artifacts/fork-release run: sha256sum *.nupkg > SHA256SUMS - name: Upload workflow artifacts uses: actions/upload-artifact@v7 with: - name: duckdb-net-${{ env.PREVIEW_VERSION }} + name: duckdb-net-${{ github.event.release.tag_name }} path: | - artifacts/preview/*.nupkg - artifacts/preview/SHA256SUMS + artifacts/fork-release/*.nupkg + artifacts/fork-release/SHA256SUMS if-no-files-found: error - - name: Attach packages to GitHub prerelease + - name: Attach packages to GitHub release env: GH_TOKEN: ${{ github.token }} - run: gh release upload "${{ github.event.release.tag_name }}" artifacts/preview/* --clobber + run: gh release upload "${{ github.event.release.tag_name }}" artifacts/fork-release/* --clobber - name: Authenticate to NuGet.org uses: NuGet/login@v1 @@ -123,9 +143,9 @@ jobs: with: user: skuirrels - - name: Publish preview packages to NuGet.org + - name: Publish fork packages to NuGet.org run: >- - dotnet nuget push "artifacts/preview/*.nupkg" + dotnet nuget push "artifacts/fork-release/*.nupkg" --api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/Directory.Build.props b/Directory.Build.props index 90d83fa..603223b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -19,13 +19,15 @@ Giorgi Dalakishvili Copyright © 2020 - $(Year) Giorgi Dalakishvili - Skuirrels. + true + Skuirrels. DuckDB.NET.$(MSBuildProjectName) $(ForkPackagePrefix)DuckDB.NET.$(MSBuildProjectName) DuckDB;ADO.NET;Database;Olap;Embedded Logo.jpg README.md README-PREVIEW.md + README-FORK.md MIT true @@ -40,7 +42,7 @@ - + https://github.com/skuirrels/DuckDB.NET https://github.com/skuirrels/DuckDB.NET @@ -74,13 +76,21 @@ True + + True + + - + + - + + diff --git a/DuckDB.NET.Bindings/Bindings.csproj b/DuckDB.NET.Bindings/Bindings.csproj index 0528820..cb88a77 100644 --- a/DuckDB.NET.Bindings/Bindings.csproj +++ b/DuckDB.NET.Bindings/Bindings.csproj @@ -7,6 +7,8 @@ Unofficial preview build of the DuckDB native bindings from the skuirrels DuckDB.NET fork. Unofficial preview bindings for the consolidated DuckDB.NET performance work, bundling DuckDB v1.5.4. + Unofficial stable build of the DuckDB native bindings from the skuirrels DuckDB.NET fork. + Stable fork bindings for the consolidated DuckDB.NET performance work, bundling DuckDB v1.5.4. DuckDB.NET.Native win-x64;win-arm64;linux-x64;linux-arm64;osx https://github.com/duckdb/duckdb/releases/download/v1.5.4 diff --git a/DuckDB.NET.Data/Data.csproj b/DuckDB.NET.Data/Data.csproj index 36a1442..0154d74 100644 --- a/DuckDB.NET.Data/Data.csproj +++ b/DuckDB.NET.Data/Data.csproj @@ -13,6 +13,8 @@ Fixes: Unofficial preview build of the DuckDB ADO.NET provider from the skuirrels DuckDB.NET fork. Unofficial preview of the consolidated DuckDB.NET performance work for DuckDB v1.5.4. Do not reference this package alongside the official DuckDB.NET packages. + Unofficial stable build of the DuckDB ADO.NET provider from the skuirrels DuckDB.NET fork. + Stable fork release of the consolidated DuckDB.NET performance work for DuckDB v1.5.4. Do not reference this package alongside the official DuckDB.NET packages. True ..\keyPair.snk true @@ -40,11 +42,11 @@ Fixes: - + - + diff --git a/DuckDB.NET.Test/Test.csproj b/DuckDB.NET.Test/Test.csproj index 37ced06..25a2753 100644 --- a/DuckDB.NET.Test/Test.csproj +++ b/DuckDB.NET.Test/Test.csproj @@ -1,7 +1,7 @@  - net8.0 + net8.0;net10.0 false true diff --git a/README-FORK.md b/README-FORK.md new file mode 100644 index 0000000..0ddb544 --- /dev/null +++ b/README-FORK.md @@ -0,0 +1,33 @@ +# Skuirrels DuckDB.NET fork + +This is an unofficial stable build from the +[`skuirrels/DuckDB.NET`](https://github.com/skuirrels/DuckDB.NET) fork. It +packages the consolidated performance work for DuckDB v1.5.4 under distinct +`Skuirrels.DuckDB.NET.*` package IDs. + +Install the bundled provider explicitly: + +```shell +dotnet add package Skuirrels.DuckDB.NET.Data.Full --version 1.5.4 +``` + +NuGet packages: + +- [`Skuirrels.DuckDB.NET.Data.Full`](https://www.nuget.org/packages/Skuirrels.DuckDB.NET.Data.Full/) +- [`Skuirrels.DuckDB.NET.Bindings.Full`](https://www.nuget.org/packages/Skuirrels.DuckDB.NET.Bindings.Full/) + +The package keeps the official `DuckDB.NET.Data` namespaces and assembly names, +so application source code does not need to change. Do not reference this fork +package and the official `DuckDB.NET.Data.Full` package in the same dependency +graph because they contain assemblies with the same identities. + +This release bundles DuckDB v1.5.4 and includes the consolidated appender, +parameter binding, prepared-command, result materialisation, and scoped-writer +optimisations from the fork. When equivalent upstream changes are released, +move back to the official `DuckDB.NET.Data.Full` package. + +The original DuckDB.NET and DuckDB licences and attribution are included in the +package. + +Report fork-specific problems in the +[`skuirrels/DuckDB.NET` issue tracker](https://github.com/skuirrels/DuckDB.NET/issues/new). diff --git a/scripts/validate-fork-packages.sh b/scripts/validate-fork-packages.sh new file mode 100755 index 0000000..269189c --- /dev/null +++ b/scripts/validate-fork-packages.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -ne 2 ]]; then + echo "Usage: $0 " >&2 + exit 2 +fi + +package_directory=$(cd "$1" && pwd) +package_version=$2 +data_package="$package_directory/Skuirrels.DuckDB.NET.Data.Full.$package_version.nupkg" +bindings_package="$package_directory/Skuirrels.DuckDB.NET.Bindings.Full.$package_version.nupkg" + +if [[ "$package_version" == *-preview.* ]]; then + expected_readme=README-PREVIEW.md +else + expected_readme=README-FORK.md +fi + +[[ -f "$data_package" ]] || { echo "Missing $data_package" >&2; exit 1; } +[[ -f "$bindings_package" ]] || { echo "Missing $bindings_package" >&2; exit 1; } + +validation_directory=$(mktemp -d) +trap 'rm -rf "$validation_directory"' EXIT + +unzip -p "$data_package" '*.nuspec' > "$validation_directory/data.nuspec" +unzip -p "$bindings_package" '*.nuspec' > "$validation_directory/bindings.nuspec" +unzip -Z1 "$data_package" > "$validation_directory/data-files.txt" +unzip -Z1 "$bindings_package" > "$validation_directory/bindings-files.txt" + +grep -Fq 'Skuirrels.DuckDB.NET.Data.Full' "$validation_directory/data.nuspec" +grep -Fq "$package_version" "$validation_directory/data.nuspec" +grep -Fq "Skuirrels.DuckDB.NET.Bindings.Full' "$validation_directory/bindings.nuspec" +grep -Fq "$package_version" "$validation_directory/bindings.nuspec" +grep -Fq "$expected_readme" "$validation_directory/data.nuspec" +grep -Fq "$expected_readme" "$validation_directory/bindings.nuspec" +grep -Fxq "$expected_readme" "$validation_directory/data-files.txt" +grep -Fxq "$expected_readme" "$validation_directory/bindings-files.txt" +grep -Fq 'https://github.com/skuirrels/DuckDB.NET' "$validation_directory/data.nuspec" +grep -Fq 'https://github.com/skuirrels/DuckDB.NET' "$validation_directory/bindings.nuspec" + +for native_asset in \ + runtimes/win-x64/native/duckdb.dll \ + runtimes/win-arm64/native/duckdb.dll \ + runtimes/linux-x64/native/libduckdb.so \ + runtimes/linux-arm64/native/libduckdb.so \ + runtimes/osx/native/libduckdb.dylib +do + grep -Fxq "$native_asset" "$validation_directory/bindings-files.txt" +done + +for target_framework in net8.0 net10.0 +do + smoke_directory="$validation_directory/smoke-$target_framework" + mkdir -p "$smoke_directory" + + cat > "$smoke_directory/ForkPackageSmoke.csproj" < + + Exe + $target_framework + enable + enable + + + + + +EOF + + cat > "$smoke_directory/NuGet.config" < + + + + + + + + + + + + + + + +EOF + + cat > "$smoke_directory/Program.cs" <<'EOF' +using DuckDB.NET.Data; + +using var connection = new DuckDBConnection("Data Source=:memory:"); +connection.Open(); + +using (var command = connection.CreateCommand()) +{ + command.CommandText = "CREATE TABLE fork_package_smoke(value INTEGER)"; + command.ExecuteNonQuery(); +} + +using (var appender = connection.CreateAppender("fork_package_smoke")) +{ + appender.AppendRowScoped(42, + static (ref DuckDBAppenderRowWriter writer, int value) => writer.AppendValue(value)); +} + +using var verification = connection.CreateCommand(); +verification.CommandText = "SELECT version(), sum(value) FROM fork_package_smoke"; +using var reader = verification.ExecuteReader(); +if (!reader.Read() || !reader.GetString(0).Contains("v1.5.4", StringComparison.Ordinal) || reader.GetInt64(1) != 42) +{ + throw new InvalidOperationException("Fork package smoke test failed."); +} + +Console.WriteLine($"Fork package smoke passed with {reader.GetString(0)}"); +EOF + + dotnet restore "$smoke_directory/ForkPackageSmoke.csproj" \ + --configfile "$smoke_directory/NuGet.config" \ + --packages "$validation_directory/packages-$target_framework" + dotnet run --project "$smoke_directory/ForkPackageSmoke.csproj" --configuration Release --no-restore +done + +echo "Validated fork packages at version $package_version" diff --git a/scripts/validate-preview-packages.sh b/scripts/validate-preview-packages.sh index 9a24ed6..b770b25 100755 --- a/scripts/validate-preview-packages.sh +++ b/scripts/validate-preview-packages.sh @@ -1,112 +1,5 @@ #!/usr/bin/env bash set -euo pipefail -if [[ $# -ne 2 ]]; then - echo "Usage: $0 " >&2 - exit 2 -fi - -package_directory=$(cd "$1" && pwd) -preview_version=$2 -data_package="$package_directory/Skuirrels.DuckDB.NET.Data.Full.$preview_version.nupkg" -bindings_package="$package_directory/Skuirrels.DuckDB.NET.Bindings.Full.$preview_version.nupkg" - -[[ -f "$data_package" ]] || { echo "Missing $data_package" >&2; exit 1; } -[[ -f "$bindings_package" ]] || { echo "Missing $bindings_package" >&2; exit 1; } - -validation_directory=$(mktemp -d) -trap 'rm -rf "$validation_directory"' EXIT - -unzip -p "$data_package" '*.nuspec' > "$validation_directory/data.nuspec" -unzip -p "$bindings_package" '*.nuspec' > "$validation_directory/bindings.nuspec" -unzip -Z1 "$bindings_package" > "$validation_directory/bindings-files.txt" - -grep -Fq 'Skuirrels.DuckDB.NET.Data.Full' "$validation_directory/data.nuspec" -grep -Fq "$preview_version" "$validation_directory/data.nuspec" -grep -Fq "Skuirrels.DuckDB.NET.Bindings.Full' "$validation_directory/bindings.nuspec" -grep -Fq "$preview_version" "$validation_directory/bindings.nuspec" -grep -Fq 'https://github.com/skuirrels/DuckDB.NET' "$validation_directory/data.nuspec" -grep -Fq 'https://github.com/skuirrels/DuckDB.NET' "$validation_directory/bindings.nuspec" - -for native_asset in \ - runtimes/win-x64/native/duckdb.dll \ - runtimes/win-arm64/native/duckdb.dll \ - runtimes/linux-x64/native/libduckdb.so \ - runtimes/linux-arm64/native/libduckdb.so \ - runtimes/osx/native/libduckdb.dylib -do - grep -Fxq "$native_asset" "$validation_directory/bindings-files.txt" -done - -smoke_directory="$validation_directory/smoke" -mkdir -p "$smoke_directory" - -cat > "$smoke_directory/PreviewSmoke.csproj" < - - Exe - net8.0 - enable - enable - - - - - -EOF - -cat > "$smoke_directory/NuGet.config" < - - - - - - - - - - - - - - - -EOF - -cat > "$smoke_directory/Program.cs" <<'EOF' -using DuckDB.NET.Data; - -using var connection = new DuckDBConnection("Data Source=:memory:"); -connection.Open(); - -using (var command = connection.CreateCommand()) -{ - command.CommandText = "CREATE TABLE preview_smoke(value INTEGER)"; - command.ExecuteNonQuery(); -} - -using (var appender = connection.CreateAppender("preview_smoke")) -{ - appender.AppendRowScoped(42, - static (ref DuckDBAppenderRowWriter writer, int value) => writer.AppendValue(value)); -} - -using var verification = connection.CreateCommand(); -verification.CommandText = "SELECT version(), sum(value) FROM preview_smoke"; -using var reader = verification.ExecuteReader(); -if (!reader.Read() || !reader.GetString(0).Contains("v1.5.4", StringComparison.Ordinal) || reader.GetInt64(1) != 42) -{ - throw new InvalidOperationException("Preview package smoke test failed."); -} - -Console.WriteLine($"Preview smoke passed with {reader.GetString(0)}"); -EOF - -dotnet restore "$smoke_directory/PreviewSmoke.csproj" \ - --configfile "$smoke_directory/NuGet.config" \ - --packages "$validation_directory/packages" -dotnet run --project "$smoke_directory/PreviewSmoke.csproj" --configuration Release --no-restore - -echo "Validated preview packages at version $preview_version" +script_directory=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +exec "$script_directory/validate-fork-packages.sh" "$@"