This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new bef364a1e feat: Chain wheel test/build and release workflows (#2483)
bef364a1e is described below

commit bef364a1e46afa5fcd6a2135335c0d0b19f2d864
Author: Emre Şafak <[email protected]>
AuthorDate: Sun Aug 17 10:41:38 2025 -0400

    feat: Chain wheel test/build and release workflows (#2483)
    
    ## What does this PR do?
    
    This commit refactors the Python wheel CI and release process to use a
    chained workflow model, ensuring that the exact same test and build
    process is run for both CI checks and releases.
    
    A new reusable workflow, `.github/workflows/build-and-test-core.yml`, is
    introduced. This workflow is triggered on `push` and `pull_request` for
    CI purposes, and can also be called by other workflows via
    `workflow_call`. It contains the full logic for building, testing, and
    packaging the Python wheel across a matrix of operating systems and
    Python versions.
    
    The `release.yaml` workflow is refactored to be an orchestrator. On a
    new tag, it now calls the `build-and-test-core.yml` workflow to run all
    tests. If the tests pass, it proceeds to a separate job to download the
    wheel artifacts produced by the test run and publish them to PyPI.
    
    This architecture ensures that every release is automatically and
    thoroughly tested in the exact same manner as pull requests, just before
    publication.
    ## Related issues
    
    #2472
    #2480
    
    ## Does this PR introduce any user-facing change?
    
    No
    
    ---------
    
    Co-authored-by: google-labs-jules[bot] 
<161369871+google-labs-jules[bot]@users.noreply.github.com>
    Co-authored-by: Shawn Yang <[email protected]>
---
 .../{sync.yml => build-wheels-for-pr.yaml}         |  38 +++--
 .../{sync.yml => build-wheels-for-release.yaml}    |  26 ++--
 .github/workflows/build-wheels.yaml                |  94 ++++++++++++
 .github/workflows/ci.yml                           |  26 ++--
 .github/workflows/release-java-snapshot.yaml       |   2 +-
 .github/workflows/release-python.yaml              |  63 +++++++++
 .github/workflows/release.yaml                     | 137 ------------------
 .github/workflows/sync.yml                         |   2 +-
 ci/build_manylinux_wheel.sh                        | 157 +++++++++++++++++++++
 9 files changed, 366 insertions(+), 179 deletions(-)

diff --git a/.github/workflows/sync.yml 
b/.github/workflows/build-wheels-for-pr.yaml
similarity index 56%
copy from .github/workflows/sync.yml
copy to .github/workflows/build-wheels-for-pr.yaml
index 46ed08d17..ec85455f8 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/build-wheels-for-pr.yaml
@@ -15,21 +15,33 @@
 # specific language governing permissions and limitations
 # under the License.
 
-name: Sync Files
-
+name: build wheels for pull request
 on:
   push:
     branches:
       - main
-
+    paths:
+      - 'python/**'
+      - 'cpp/**'
+      - 'bazel/**'
+      - 'BUILD'
+      - 'WORKSPACE'
+      - '.github/workflows/build-wheels*.yml'
+  pull_request:
+    paths:
+      - 'python/**'
+      - 'cpp/**'
+      - 'bazel/**'
+      - 'BUILD'
+      - 'WORKSPACE'
+      - '.github/workflows/build-wheels*.yml'
 jobs:
-  sync:
-    runs-on: ubuntu-latest
-    if: github.repository == 'apache/fory'
-    steps:
-      - uses: actions/checkout@v4
-      - name: Sync files
-        uses: BetaHuhn/repo-file-sync-action@v1
-        with:
-          GH_PAT: ${{ secrets.GH_PAT }}
-          SKIP_PR: true
+  build-wheels:
+    uses: ./.github/workflows/build-wheels.yaml
+    strategy:
+      matrix:
+        os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
+        python-version: ['3.8', '3.13']
+    with:
+      os: ${{ matrix.os }}
+      python-version: ${{ matrix.python-version }}
diff --git a/.github/workflows/sync.yml 
b/.github/workflows/build-wheels-for-release.yaml
similarity index 65%
copy from .github/workflows/sync.yml
copy to .github/workflows/build-wheels-for-release.yaml
index 46ed08d17..e1799e6de 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/build-wheels-for-release.yaml
@@ -15,21 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-name: Sync Files
-
+name: build wheels for release
 on:
   push:
-    branches:
-      - main
+    tags: ["v*"]
 
 jobs:
-  sync:
-    runs-on: ubuntu-latest
-    if: github.repository == 'apache/fory'
-    steps:
-      - uses: actions/checkout@v4
-      - name: Sync files
-        uses: BetaHuhn/repo-file-sync-action@v1
-        with:
-          GH_PAT: ${{ secrets.GH_PAT }}
-          SKIP_PR: true
+  build-wheels:
+    uses: ./.github/workflows/build-wheels.yaml
+    strategy:
+      matrix:
+        os: [ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-14, 
macos-latest, windows-latest]
+        python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
+    with:
+      os: ${{ matrix.os }}
+      python-version: ${{ matrix.python-version }}
+      bump-version: true
diff --git a/.github/workflows/build-wheels.yaml 
b/.github/workflows/build-wheels.yaml
new file mode 100644
index 000000000..554f4a006
--- /dev/null
+++ b/.github/workflows/build-wheels.yaml
@@ -0,0 +1,94 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Build Wheels
+
+on:
+  workflow_call:
+    inputs:
+      os:
+        required: true
+        type: string
+      python-version:
+        required: true
+        type: string
+      bump-version:
+        description: 'Whether to bump the version in setup.py'
+        required: false
+        type: boolean
+        default: false
+
+permissions:
+  contents: read
+  actions: write
+
+jobs:
+  build_and_test:
+    name: Build and Test
+    runs-on: ${{ inputs.os }}
+
+    steps:
+      - uses: actions/checkout@v5
+
+      - name: Set up Python ${{ inputs.python-version }}
+        uses: actions/setup-python@v5
+        with:
+          python-version: ${{ inputs.python-version }}
+
+      - name: Install bazel
+        if: "runner.os != 'Windows'"
+        run: ./ci/run_ci.sh install_bazel
+
+      - name: Install bazel
+        if: "runner.os == 'Windows'"
+        run: ./ci/run_ci.sh install_bazel_windows
+        shell: bash
+
+      - name: Update version in setup.py
+        if: "inputs.bump-version"
+        run: ./ci/deploy.sh bump_py_version
+
+      - name: Build a binary wheel (Linux, manylinux)
+        if: "runner.os == 'Linux'"
+        env:
+          manylinux_x86_64_image: ${{ env.manylinux_x86_64_image }}
+          manylinux_aarch64_image: ${{ env.manylinux_aarch64_image }}
+          GITHUB_WORKSPACE: ${{ github.workspace }}
+        run: |
+          ./ci/build_manylinux_wheel.sh --os "${{ runner.os }}" \
+            --arch "${{ runner.arch }}" \
+            --python "${{ inputs.python-version }}" \
+            --workspace "${GITHUB_WORKSPACE}"
+
+      - name: Build a binary wheel (native)
+        if: "runner.os != 'Linux'"
+        run: ./ci/deploy.sh build_pyfory
+        shell: bash
+
+      - name: Install and verify wheel
+        shell: bash
+        run: |
+          python -m pip install --upgrade pip
+          pip install dist/*.whl
+          python -c "import pyfory; print(pyfory.__version__)"
+
+      - name: Upload wheel
+#        if: ${{ inputs.bump-version }}
+        uses: actions/upload-artifact@v4
+        with:
+          name: pyfory-wheels-${{ inputs.os }}-${{ inputs.python-version }}${{ 
inputs.bump-version && '-tagged' || github.sha }}
+          path: dist/*.whl
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 11c92b32b..db261c1a6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -48,7 +48,7 @@ jobs:
       matrix:
         java-version: ["8", "11", "17", "21", "24"]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK ${{ matrix.java-version }}
         uses: actions/setup-java@v4
         with:
@@ -81,7 +81,7 @@ jobs:
         # String in openj9 1.8 share byte array by offset, fory doesn't allow 
it.
         java-version: ["21"]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK ${{ matrix.java-version }}
         uses: actions/setup-java@v4
         with:
@@ -107,7 +107,7 @@ jobs:
       matrix:
         java-version: ["21"]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK ${{ matrix.java-version }}
         uses: actions/setup-java@v4
         with:
@@ -128,7 +128,7 @@ jobs:
       matrix:
         java-version: ["17", "21", "23"]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - uses: graalvm/setup-graalvm@v1
         with:
           java-version: ${{ matrix.java-version }}
@@ -152,7 +152,7 @@ jobs:
       matrix:
         java-version: ["8", "11", "17", "21"]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK ${{ matrix.java-version }}
         uses: actions/setup-java@v4
         with:
@@ -171,7 +171,7 @@ jobs:
     name: Scala CI
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK8
         uses: actions/setup-java@v4
         with:
@@ -189,7 +189,7 @@ jobs:
     name: Integration Tests
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK8
         uses: actions/setup-java@v4
         with:
@@ -210,7 +210,7 @@ jobs:
         os: [ubuntu-latest, macos-13, windows-2022]
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Use Node.js ${{ matrix.node-version }}
         uses: actions/setup-node@v4
         with:
@@ -237,7 +237,7 @@ jobs:
     runs-on: ${{ matrix.os }}
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up Python 3.11
         uses: actions/setup-python@v5
         with:
@@ -252,7 +252,7 @@ jobs:
         os: [ubuntu-latest, macos-13, macos-14, windows-2022]  # macos-13: 
x86, macos-14: arm64
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up Python 3.11
         uses: actions/setup-python@v5
         with:
@@ -267,7 +267,7 @@ jobs:
         python-version: [3.8, 3.12, 3.13.3]
         os: [ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-14, windows-2022]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up Python ${{ matrix.python-version }}
         uses: actions/setup-python@v5
         with:
@@ -286,7 +286,7 @@ jobs:
       matrix:
         go-version: ["1.13", "1.18"]
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Setup Go ${{ matrix.go-version }}
         uses: actions/setup-go@v4
         with:
@@ -308,7 +308,7 @@ jobs:
     name: Code Style Check
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up JDK ${{ matrix.java-version }}
         uses: actions/setup-java@v4
         with:
diff --git a/.github/workflows/release-java-snapshot.yaml 
b/.github/workflows/release-java-snapshot.yaml
index 1292ccc1f..631975aac 100644
--- a/.github/workflows/release-java-snapshot.yaml
+++ b/.github/workflows/release-java-snapshot.yaml
@@ -28,7 +28,7 @@ jobs:
     runs-on: ubuntu-latest
     if: github.repository == 'apache/fory'
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Set up Maven Central Repository
         uses: actions/setup-java@v4
         with:
diff --git a/.github/workflows/release-python.yaml 
b/.github/workflows/release-python.yaml
new file mode 100644
index 000000000..938ef2e9a
--- /dev/null
+++ b/.github/workflows/release-python.yaml
@@ -0,0 +1,63 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Publish Python
+
+on:
+  workflow_run:
+    workflows: ["build wheels for release"]
+    types: [completed]
+
+permissions:
+  contents: read
+  id-token: write
+
+jobs:
+  publish-wheels:
+    name: Publish Wheels
+    if: ${{ github.event.workflow_run.conclusion == 'success' }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: Download all wheel artifacts
+        uses: actions/download-artifact@v5
+        with:
+          path: downloaded_wheels
+
+      - name: Move wheels to a single directory
+        shell: bash
+        run: |
+          mkdir dist
+          find downloaded_wheels -type f -name "*.whl" -exec mv {} dist/ \;
+          ls -R dist
+
+      - name: Publish to TestPyPI
+        uses: pypa/gh-action-pypi-publish@release/v1
+        if: startsWith(github.ref, 'refs/tags/') && contains(github.ref, '-')
+        with:
+          repository-url: https://test.pypi.org/legacy/
+          skip-existing: true
+          verbose: true
+          verify-metadata: false
+          packages-dir: dist
+
+      - name: Publish to PyPI
+        uses: pypa/gh-action-pypi-publish@release/v1
+        if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-')
+        with:
+          skip-existing: true
+          verify-metadata: false
+          packages-dir: dist
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
deleted file mode 100644
index 0d3728421..000000000
--- a/.github/workflows/release.yaml
+++ /dev/null
@@ -1,137 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: Publish Fory
-
-on:
-  push:
-    tags:
-      - "v*"
-
-permissions:
-  contents: read
-
-jobs:
-  build-wheels:
-    name: Build Wheels
-    runs-on: ${{ matrix.os }}
-    strategy:
-      matrix:
-        python-version: [3.8, 3.9, "3.10", 3.11, 3.12, 3.13]
-        os: [ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-14, 
windows-2022]  # macos-13: x86, macos-14: arm64
-    env:
-      manylinux_x86_64_image: quay.io/pypa/manylinux_2_28_x86_64
-      manylinux_aarch64_image: quay.io/pypa/manylinux_2_28_aarch64
-
-    steps:
-      - uses: actions/checkout@v4
-      - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v5
-        with:
-          python-version: ${{ matrix.python-version }}
-      - name: Install bazel (for macOS and Windows)
-        if: "!startsWith(matrix.os, 'ubuntu')"
-        shell: bash
-        run: |
-          if [ "$RUNNER_OS" == "Windows" ]; then
-              ./ci/run_ci.sh install_bazel_windows
-          else
-              ./ci/run_ci.sh install_bazel
-          fi
-      - name: Update version in setup.py
-        shell: bash
-        run: ci/deploy.sh bump_py_version
-       # --------- Use manylinux for Linux wheels ---------
-      - name: Build a binary wheel (Linux, manylinux)
-        if: startsWith(matrix.os, 'ubuntu')
-        shell: bash
-        run: |
-           DOCKER_IMAGE=""
-           PLAT=""
-           if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then
-             DOCKER_IMAGE="${{ env.manylinux_x86_64_image }}"
-             PLAT="manylinux_2_28_x86_64"
-           elif [[ "${{ matrix.os }}" == "ubuntu-24.04-arm" ]]; then
-             DOCKER_IMAGE="${{ env.manylinux_aarch64_image }}"
-             PLAT="manylinux_2_28_aarch64"
-           fi
-           PY_VERSION=${{ matrix.python-version }}
-           echo "PY_VERSION: $PY_VERSION"
-           PY_VERSION=${PY_VERSION//./}
-           echo "PY_VERSION without dots: $PY_VERSION"
-           docker run --rm -e PY_VERSION="$PY_VERSION" -e PLAT="$PLAT" \
-             -v ${{ github.workspace }}:/work \
-             -w /work "$DOCKER_IMAGE" \
-             bash -c "
-               set -e
-               yum install -y git sudo wget
-               git config --global --add safe.directory /work
-               ls -alh /opt/python
-               echo \"PY_VERSION: \$PY_VERSION\"
-               ls /opt/python/cp\${PY_VERSION}-cp\${PY_VERSION}
-               ls /opt/python/cp\${PY_VERSION}-cp\${PY_VERSION}/bin
-               export 
PATH=/opt/python/cp\${PY_VERSION}-cp\${PY_VERSION}/bin:\$PATH
-               echo \"PATH: \$PATH\"
-               echo \"Using Python from: \$(which python)\"
-               echo \"Python version: \$(python -V)\"
-               bash ci/run_ci.sh install_bazel
-               bash ci/deploy.sh build_pyfory
-             "
-
-       # --------- Native (not in container) for macOS and Windows ---------
-      - name: Build a binary wheel (native)
-        if: "!startsWith(matrix.os, 'ubuntu')"
-        shell: bash
-        run: |
-           ci/deploy.sh build_pyfory
-      - name: Upload Wheel Artifact
-        uses: actions/upload-artifact@v4
-        with:
-          name: pyfory-wheels-${{ matrix.os }}-${{ matrix.python-version }}
-          path: dist/*.whl
-
-  publish-wheels:
-    name: Publish Wheels
-    runs-on: ubuntu-latest
-    needs: build-wheels
-    permissions:
-      contents: read
-      id-token: write
-    steps:
-      - name: Download Wheel Artifacts
-        uses: actions/download-artifact@v4
-        with:
-          path: downloaded_wheels/
-          merge-multiple: true
-      - name: Display structure of downloaded files
-        run: ls -R downloaded_wheels
-      - name: Publish to TestPyPI
-        uses: pypa/gh-action-pypi-publish@release/v1
-        if: ${{ startsWith(github.ref, 'refs/tags/') && contains(github.ref, 
'-') }}
-        with:
-          repository-url: https://test.pypi.org/legacy/
-          skip-existing: true
-          verbose: true
-          verify-metadata: false
-          packages-dir: downloaded_wheels
-      - name: Publish to PyPI
-        uses: pypa/gh-action-pypi-publish@release/v1
-        if: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 
'-') }}
-        with:
-          skip-existing: true
-          verify-metadata: false
-          packages-dir: downloaded_wheels
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
index 46ed08d17..9f4c1b0fb 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/sync.yml
@@ -27,7 +27,7 @@ jobs:
     runs-on: ubuntu-latest
     if: github.repository == 'apache/fory'
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Sync files
         uses: BetaHuhn/repo-file-sync-action@v1
         with:
diff --git a/ci/build_manylinux_wheel.sh b/ci/build_manylinux_wheel.sh
new file mode 100755
index 000000000..58c8347dd
--- /dev/null
+++ b/ci/build_manylinux_wheel.sh
@@ -0,0 +1,157 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Usage:
+#   ./build_manylinux_wheel.sh --os <matrix.os> --python <python-version> \
+#     --arch <ARCH> [--workspace <path>] [--x86-image <image>] \
+#     [--aarch64-image <image>] [--docker-image <image>] [--dry-run]
+#
+# Examples:
+#   ./build_manylinux_wheel.sh --os ubuntu-latest --python 3.10 --arch X64
+#   ./build_manylinux_wheel.sh --os ubuntu-24.04-arm --python 3.11 --arch 
ARM64 \
+#     --aarch64-image quay.io/pypa/manylinux_2014_aarch64:latest
+#
+# Notes:
+#   --arch accepts values: X86, X64, ARM, or ARM64 (case-insensitive).
+#   This script requires --arch to be provided explicitly.
+set -euo pipefail
+
+print_usage() {
+  cat <<EOF
+Usage: $0 --os <matrix.os> --python <python-version> --arch <ARCH> [options]
+
+Required:
+  --os                matrix.os value (e.g. ubuntu-latest or ubuntu-24.04-arm)
+  --python            Python version (e.g. 3.10)
+  --arch              Architecture (X86, X64, ARM, or ARM64)
+
+Optional:
+  --workspace         Path to workspace to mount into container (default: cwd)
+  --x86-image         manylinux x86_64 docker image (overrides default env)
+  --aarch64-image     manylinux aarch64 docker image (overrides default env)
+  --docker-image      Explicit docker image to use (skips auto selection)
+  --dry-run           Print the docker command without executing it
+  -h, --help          Show this help
+EOF
+}
+
+# Defaults - can be overridden by options
+WORKSPACE="${GITHUB_WORKSPACE:-$(pwd)}"
+MANYLINUX_X86_64_IMAGE="${MANYLINUX_X86_64_IMAGE:-quay.io/pypa/manylinux_2_28_x86_64:latest}"
+MANYLINUX_AARCH64_IMAGE="${MANYLINUX_AARCH64_IMAGE:-quay.io/pypa/manylinux_2_28_aarch64:latest}"
+DOCKER_IMAGE=""
+ARCH=""
+DRY_RUN=0
+
+# Parse args
+while [[ $# -gt 0 ]]; do
+  case "$1" in
+    --os) MATRIX_OS="$2"; shift 2;;
+    --python) PY_VERSION_RAW="$2"; shift 2;;
+    --workspace) WORKSPACE="$2"; shift 2;;
+    --x86-image) MANYLINUX_X86_64_IMAGE="$2"; shift 2;;
+    --aarch64-image) MANYLINUX_AARCH64_IMAGE="$2"; shift 2;;
+    --docker-image) DOCKER_IMAGE="$2"; shift 2;;
+    --arch) ARCH="$2"; shift 2;;
+    --dry-run) DRY_RUN=1; shift;;
+    -h|--help) print_usage; exit 0;;
+    *) echo "Unknown argument: $1"; print_usage; exit 2;;
+  esac
+done
+
+if [[ -z "${MATRIX_OS:-}" ]] || [[ -z "${PY_VERSION_RAW:-}" ]] || [[ -z 
"${ARCH:-}" ]]; then
+  echo "Error: --os, --python and --arch are required."
+  print_usage
+  exit 2
+fi
+
+# Normalize ARCH to uppercase
+ARCH="${ARCH^^}"
+
+# Normalize Python version: remove dots (e.g. 3.10 -> 310)
+PY_VERSION_NO_DOTS="${PY_VERSION_RAW//./}"
+
+# Determine DOCKER_IMAGE and PLAT strictly from ARCH (unless --docker-image 
supplied)
+PLAT=""
+case "$ARCH" in
+  X86|X64)
+    PLAT="manylinux_2_28_x86_64"
+    DOCKER_IMAGE="${DOCKER_IMAGE:-$MANYLINUX_X86_64_IMAGE}"
+    ;;
+  ARM|ARM64)
+    PLAT="manylinux_2_28_aarch64"
+    DOCKER_IMAGE="${DOCKER_IMAGE:-$MANYLINUX_AARCH64_IMAGE}"
+    ;;
+  *)
+    echo "Error: Unsupported ARCH '$ARCH'. Use one of: X86, X64, ARM, ARM64."
+    exit 2
+    ;;
+esac
+
+echo "Matrix OS: $MATRIX_OS"
+echo "Arch (input): $ARCH"
+echo "Selected docker image: $DOCKER_IMAGE"
+echo "Platform (PLAT): $PLAT"
+echo "Python version (raw): $PY_VERSION_RAW"
+echo "PY_VERSION without dots: $PY_VERSION_NO_DOTS"
+echo "Workspace: $WORKSPACE"
+
+# Basic checks
+if ! command -v docker >/dev/null 2>&1; then
+  echo "Error: docker is required but not installed or not on PATH."
+  exit 3
+fi
+
+SCRIPT='set -e
+yum install -y git sudo wget || true
+git config --global --add safe.directory /work
+ls -alh /opt/python || true
+echo "PY_VERSION: $PY_VERSION"
+ls /opt/python/cp${PY_VERSION}-cp${PY_VERSION} || true
+ls /opt/python/cp${PY_VERSION}-cp${PY_VERSION}/bin || true
+export PATH=/opt/python/cp${PY_VERSION}-cp${PY_VERSION}/bin:$PATH
+echo "PATH: $PATH"
+echo "Using Python from: $(which python || echo not-found)"
+echo "Python version: $(python -V 2>&1 || true)"
+bash ci/run_ci.sh install_bazel
+bash ci/deploy.sh build_pyfory'
+
+DOCKER_CMD=(docker run --rm
+  -e "PY_VERSION=$PY_VERSION_NO_DOTS"
+  -e "PLAT=$PLAT"
+  -v "$WORKSPACE":/work
+  -w /work
+  "$DOCKER_IMAGE"
+  bash -lc "$SCRIPT"
+)
+
+# Show the final command (joined) for clarity
+echo
+echo "Docker command to be executed:"
+printf ' %q' "${DOCKER_CMD[@]}"
+echo
+echo
+
+if [[ $DRY_RUN -eq 1 ]]; then
+  echo "Dry run enabled; not executing docker command."
+  exit 0
+fi
+
+# Execute
+"${DOCKER_CMD[@]}"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to