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]