Skip to content

Update workflow to release spannerlib-python to PyPI#682

Closed
bhatt4982 wants to merge 10 commits intomainfrom
BRP-publish
Closed

Update workflow to release spannerlib-python to PyPI#682
bhatt4982 wants to merge 10 commits intomainfrom
BRP-publish

Conversation

@bhatt4982
Copy link
Contributor

Verified on

  • test.pypi.org
  • pypi.org

bhatt4982 and others added 10 commits December 9, 2025 05:12
…directories and update artifact naming conventions.
…#675)

* feat: Add GitHub Actions workflows for building shared SpannerLib binaries and a Python wrapper, including support for Linux ARM64 and macOS AMD64.

* feat: Add GitHub Actions workflows for Python Spanner library wrapper linting, unit, and system tests.

* feat: Refactor shared library build process to support additional architectures, improve cross-compilation, and centralize build logic. (#677)
@bhatt4982 bhatt4982 requested a review from a team as a code owner December 9, 2025 07:36
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @bhatt4982, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on enhancing the build and release workflow for the spannerlib-python package to PyPI. It introduces expanded support for various operating system and CPU architectures for the underlying shared library, streamlines the Python wrapper's build process by centralizing binary compilation, and updates the Python module to correctly load architecture-specific libraries. A key change also includes renaming the Python package for better PyPI representation.

Highlights

  • Expanded Architecture Support: The shared library build script (build-binaries.sh) has been significantly refactored to support a wider range of architectures, including Linux ARM64 and macOS AMD64, in addition to the existing Linux x64, macOS ARM64, and Windows x64. This enhances the portability and compatibility of the spannerlib shared library.
  • Streamlined Python Wrapper Build: The Python wrapper's build process (build-shared-lib.sh) now delegates the core binary compilation to the centralized build-binaries.sh script. This simplifies maintenance and ensures consistency across different build environments, including CI/CD pipelines.
  • Dynamic Library Loading: The Python spannerlib module now dynamically determines the correct shared library filename based on both the operating system and the CPU architecture (e.g., linux-x64/spannerlib.so). This ensures that the Python wrapper loads the appropriate binary for the host system.
  • Noxfile Refactoring: The noxfile.py has been updated to use new helper functions (run_bash_script, _build_artifacts) for building and copying artifacts. This improves the robustness of the build process, especially on Windows, and removes redundant logic.
  • PyPI Package Renaming: The Python package name in pyproject.toml has been changed from spannerlib to spannerlib-python, which is a crucial step for clarity and proper identification when releasing to PyPI.
Ignored Files
  • Ignored by pattern: .github/workflows/** (5)
    • .github/workflows/build-shared-spanner-lib.yml
    • .github/workflows/python-spanner-lib-wrapper-lint.yml
    • .github/workflows/python-spanner-lib-wrapper-system-tests.yml
    • .github/workflows/python-spanner-lib-wrapper-unit-tests.yml
    • .github/workflows/release-python-spanner-lib-wrapper.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly refactors the shared library build process for spannerlib, expanding support to include linux/arm64 and darwin/amd64 in addition to existing linux/x64, darwin/arm64, and windows/x64 targets. The build-binaries.sh script was modularized with log and build_artifact functions, and improved logic for native vs. cross-compilation, including checks for required cross-compilers. The build-shared-lib.sh script for the Python wrapper was updated to delegate fully to build-binaries.sh and now copies artifacts directly to an architecture-specific google/cloud/spannerlib/internal/lib directory, removing an intermediate ARTIFACTS_DIR. Correspondingly, spannerlib.py was modified to dynamically determine the shared library filename based on both OS and architecture (e.g., linux-x64/spannerlib.so), and unit tests were updated to reflect these new paths. The noxfile.py was refactored to use a new _build_artifacts helper, which calls the updated build-shared-lib.sh script, and includes a run_bash_script helper for Windows compatibility. The pyproject.toml file was updated to change the project name to spannerlib-python. A review comment highlighted a potential issue in setup.py where the removal of has_ext_modules=lambda: True might lead to the generation of platform-agnostic Python wheels, which is problematic for a package containing platform-specific binaries. Another review comment suggested simplifying the Linux cross-compilation logic in build-binaries.sh to only attempt cross-compilation if the toolchain is present, avoiding confusing fallback attempts.

Comment on lines 5 to 7
setup(
has_ext_modules=lambda: True,
include_package_data=True,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The removal of has_ext_modules=lambda: True is likely to cause setuptools to generate a platform-agnostic 'pure Python' wheel (e.g., ...-py3-none-any.whl). Since this package bundles a pre-compiled, platform-specific shared library, this is incorrect. Such a wheel would install on any platform but only run on the one it was built for, causing runtime errors for other users.

To ensure pip can install the correct wheel for a user's OS and architecture, the generated wheel must be tagged as platform-specific. The has_ext_modules argument is a known way to force this behavior. Please restore it or ensure that platform-specific wheels are being generated through another mechanism.

Suggested change
setup(
has_ext_modules=lambda: True,
include_package_data=True,
)
setup(
has_ext_modules=lambda: True,
include_package_data=True,
)

Comment on lines +71 to +82
if [ -z "$SKIP_LINUX_CROSS_COMPILE" ]; then
# Check for cross-compiler
if command -v x86_64-unknown-linux-gnu-gcc >/dev/null 2>&1; then
build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "x86_64-unknown-linux-gnu-gcc"
else
log "WARNING: x86_64-unknown-linux-gnu-gcc not found. Skipping Linux x64 cross-compile."
fi
elif [ -z "$SKIP_LINUX" ]; then
# Fallback to standard build if cross-compile explicitly skipped but Linux not skipped
# This might fail if no suitable compiler is found, but we'll try.
build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" ""
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic in this block for handling Linux cross-compilation can be simplified and made more robust. The elif block attempts a fallback build that will likely fail on a non-Linux host (like macOS) if a C cross-compiler isn't available, as go build for a c-shared library requires one. This can lead to confusing build failures.

A better approach is to only attempt cross-compilation if the toolchain is present and SKIP_LINUX_CROSS_COMPILE is not set. If cross-compilation is skipped on a non-Linux host, the Linux build for that architecture should also be skipped.

Suggested change
if [ -z "$SKIP_LINUX_CROSS_COMPILE" ]; then
# Check for cross-compiler
if command -v x86_64-unknown-linux-gnu-gcc >/dev/null 2>&1; then
build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "x86_64-unknown-linux-gnu-gcc"
else
log "WARNING: x86_64-unknown-linux-gnu-gcc not found. Skipping Linux x64 cross-compile."
fi
elif [ -z "$SKIP_LINUX" ]; then
# Fallback to standard build if cross-compile explicitly skipped but Linux not skipped
# This might fail if no suitable compiler is found, but we'll try.
build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" ""
fi
if [ -z "$SKIP_LINUX_CROSS_COMPILE" ]; then
# Check for cross-compiler
if command -v x86_64-unknown-linux-gnu-gcc >/dev/null 2>&1; then
build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "x86_64-unknown-linux-gnu-gcc"
else
log "WARNING: x86_64-unknown-linux-gnu-gcc not found. Skipping Linux x64 cross-compile."
fi
fi

@bhatt4982 bhatt4982 closed this Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant