From 160eccd2407c3b6f5bab0adefc483e9e72ea3527 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 03:45:39 +0000 Subject: [PATCH 01/19] ci: add PyPI nightly wheel build and publish to nightly workflow Build two sets of wheels in build-wheel: - gh-pages wheel: amd_mori with version+sha, linux_x86_64 tag - PyPI wheel: amd_mori_nightly without +sha, auditwheel-repaired to manylinux tag New stages after promote-latest: - test-pypi-wheel: install PyPI wheel, verify import works - publish-pypi: upload to PyPI using PYPI_API_TOKEN secret Same-day re-runs gracefully skip PyPI upload (version already exists). --- .github/workflows/nightly.yml | 104 ++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 019ae0af..1cc5c047 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -43,31 +43,62 @@ jobs: - name: Build CI image run: $CT build --network=host --build-arg BASE_IMAGE=${{ matrix.base_image }} -t $IMAGE -f docker/Dockerfile.dev . - - name: Build wheel + - name: Build wheels run: | BASE_VER=$(git describe --tags --abbrev=0 | sed 's/^v//') DATE=$(date +%Y%m%d) SHA=$(git rev-parse --short HEAD) - VERSION="${BASE_VER}.dev${DATE}+${SHA}" + GH_VERSION="${BASE_VER}.dev${DATE}+${SHA}" + PYPI_VERSION="${BASE_VER}.dev${DATE}" $CT run --rm --network=host \ -v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE -w $GITHUB_WORKSPACE \ -v ${{ runner.temp }}/dist:/tmp/dist \ $IMAGE bash -c " git config --global --add safe.directory '*' - echo 'Building wheel for Python ${{ matrix.python }}, version=${VERSION}' - SETUPTOOLS_SCM_PRETEND_VERSION=${VERSION} \ + + echo '=== Building gh-pages wheel (amd_mori ${GH_VERSION}) ===' + SETUPTOOLS_SCM_PRETEND_VERSION=${GH_VERSION} \ + python3 -m pip wheel --no-deps -w /tmp/dist . + + echo '=== Building PyPI wheel (amd_mori_nightly ${PYPI_VERSION}) ===' + sed -i 's/name = \"amd_mori\"/name = \"amd_mori_nightly\"/' pyproject.toml + SETUPTOOLS_SCM_PRETEND_VERSION=${PYPI_VERSION} \ python3 -m pip wheel --no-deps -w /tmp/dist . + git checkout pyproject.toml " echo "=== produced ===" ls -lh ${{ runner.temp }}/dist/ - - name: Upload wheel + - name: Repair PyPI wheels (manylinux tag) + run: | + pip install --user auditwheel patchelf 2>/dev/null || true + export PATH="$HOME/.local/bin:$PATH" + mkdir -p ${{ runner.temp }}/dist-pypi + for whl in ${{ runner.temp }}/dist/amd_mori_nightly-*.whl; do + PLAT=$(python3 -m auditwheel show "$whl" 2>&1 | grep -o 'manylinux_[0-9_]*_x86_64' | head -1) + if [ -n "$PLAT" ]; then + python3 -m auditwheel repair "$whl" --plat "$PLAT" -w ${{ runner.temp }}/dist-pypi/ + else + cp "$whl" ${{ runner.temp }}/dist-pypi/ + fi + done + echo "=== PyPI wheels ===" + ls -lh ${{ runner.temp }}/dist-pypi/ + + - name: Upload gh-pages wheel uses: actions/upload-artifact@v4 with: name: wheel-cp${{ matrix.python }} - path: ${{ runner.temp }}/dist/*.whl + path: ${{ runner.temp }}/dist/amd_mori-*.whl + retention-days: 30 + + - name: Upload PyPI wheel + uses: actions/upload-artifact@v4 + with: + name: pypi-wheel-cp${{ matrix.python }} + path: ${{ runner.temp }}/dist-pypi/amd_mori_nightly-*.whl retention-days: 30 - name: Cleanup @@ -800,3 +831,64 @@ jobs: git diff --cached --quiet && echo "No changes" && exit 0 git commit -m "nightly: promote tested wheels to latest $(date +%Y-%m-%d)" git push + + # ── Stage 5: Test PyPI wheel (install + import verification) ─────────────── + test-pypi-wheel: + name: test pypi wheel (py${{ matrix.python }}) + needs: [promote-latest] + if: github.event_name != 'pull_request' + runs-on: [self-hosted, MI355X-AINIC-TW] + strategy: + fail-fast: false + matrix: + include: + - python: "3.10" + base_image: rocm/pytorch:rocm7.2.1_ubuntu22.04_py3.10_pytorch_release_2.8.0 + - python: "3.12" + base_image: rocm/pytorch:rocm7.2.1_ubuntu24.04_py3.12_pytorch_release_2.8.0 + env: + IMAGE: rocm/mori:ci-py${{ matrix.python }} + steps: + - name: Download PyPI wheel + uses: actions/download-artifact@v4 + with: + name: pypi-wheel-cp${{ matrix.python }} + path: ${{ runner.temp }}/pypi-wheel + + - name: Build CI image + run: $CT build --network=host --build-arg BASE_IMAGE=${{ matrix.base_image }} -t $IMAGE -f docker/Dockerfile.dev . + + - name: Test PyPI wheel + run: | + $CT run --rm --network=host \ + -v ${{ runner.temp }}/pypi-wheel:/tmp/wheel:ro \ + $IMAGE bash -c " + pip install /tmp/wheel/*.whl + python3 -c 'import mori; print(\"amd-mori-nightly \" + mori.__version__ + \" OK\")' + python3 -c 'from mori import ops; print(\"mori.ops OK\")' + " + + # ── Stage 6: Publish to PyPI ─────────────────────────────────────────────── + publish-pypi: + name: publish to PyPI + needs: [test-pypi-wheel] + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Download PyPI wheels + uses: actions/download-artifact@v4 + with: + pattern: pypi-wheel-* + merge-multiple: true + path: ./dist + + - name: List wheels + run: ls -lh ./dist/ + + - name: Upload to PyPI + run: | + pip install twine + python3 -m twine upload ./dist/*.whl || echo "Upload failed (version may already exist)" + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} From 42bb9c97fbfcd36fba96fefe5c565351703c8cbc Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 03:56:25 +0000 Subject: [PATCH 02/19] chore: skip CI for nightly validation [skip ci] From d8a12a6cb1bebd24a61f4828f1634065c230ccfe Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 04:28:34 +0000 Subject: [PATCH 03/19] ci: add GPU device access to test-pypi-wheel container mori.ops loads GPU libraries that require /dev/kfd and /dev/dri. Without GPU device access the HIP runtime aborts on import. --- .github/workflows/nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 1cc5c047..7c86b918 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -861,6 +861,7 @@ jobs: - name: Test PyPI wheel run: | $CT run --rm --network=host \ + --device=/dev/kfd --device=/dev/dri \ -v ${{ runner.temp }}/pypi-wheel:/tmp/wheel:ro \ $IMAGE bash -c " pip install /tmp/wheel/*.whl From f7e4bf44c3814e06086c2e954e8fe110e5dc674a Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 04:29:57 +0000 Subject: [PATCH 04/19] ci: run auditwheel repair inside matching Docker container auditwheel was running on the host (Ubuntu 22.04), bundling 22.04 system libs into the py3.12 wheel that was compiled on Ubuntu 24.04. This caused libpci version mismatch at import time. Run auditwheel inside the same $IMAGE container used for building, so bundled libs match the compilation environment. --- .github/workflows/nightly.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 7c86b918..25d613f7 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -73,17 +73,21 @@ jobs: - name: Repair PyPI wheels (manylinux tag) run: | - pip install --user auditwheel patchelf 2>/dev/null || true - export PATH="$HOME/.local/bin:$PATH" mkdir -p ${{ runner.temp }}/dist-pypi - for whl in ${{ runner.temp }}/dist/amd_mori_nightly-*.whl; do - PLAT=$(python3 -m auditwheel show "$whl" 2>&1 | grep -o 'manylinux_[0-9_]*_x86_64' | head -1) - if [ -n "$PLAT" ]; then - python3 -m auditwheel repair "$whl" --plat "$PLAT" -w ${{ runner.temp }}/dist-pypi/ - else - cp "$whl" ${{ runner.temp }}/dist-pypi/ - fi - done + $CT run --rm \ + -v ${{ runner.temp }}/dist:/tmp/dist:ro \ + -v ${{ runner.temp }}/dist-pypi:/tmp/dist-pypi \ + $IMAGE bash -c " + pip install auditwheel patchelf -q + for whl in /tmp/dist/amd_mori_nightly-*.whl; do + PLAT=\$(auditwheel show \"\$whl\" 2>&1 | grep -o 'manylinux_[0-9_]*_x86_64' | head -1) + if [ -n \"\$PLAT\" ]; then + auditwheel repair \"\$whl\" --plat \"\$PLAT\" -w /tmp/dist-pypi/ + else + cp \"\$whl\" /tmp/dist-pypi/ + fi + done + " echo "=== PyPI wheels ===" ls -lh ${{ runner.temp }}/dist-pypi/ From ba645f63445db233c691f9184695aff02911425a Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 04:31:07 +0000 Subject: [PATCH 05/19] chore: skip CI [skip ci] From 3f65b70cb237170191afc1ce1adb8ecdd84db6b7 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 04:33:38 +0000 Subject: [PATCH 06/19] ci: retag wheels instead of auditwheel repair auditwheel repair fails because mori's internal .so files reference each other and it can't locate them as external libraries. Since mori depends on ROCm system libraries anyway, just retag the platform from linux_x86_64 to manylinux_2_XX using wheel unpack/pack. --- .github/workflows/nightly.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 25d613f7..50cfd546 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -71,21 +71,24 @@ jobs: echo "=== produced ===" ls -lh ${{ runner.temp }}/dist/ - - name: Repair PyPI wheels (manylinux tag) + - name: Retag PyPI wheels (manylinux platform tag) run: | mkdir -p ${{ runner.temp }}/dist-pypi $CT run --rm \ -v ${{ runner.temp }}/dist:/tmp/dist:ro \ -v ${{ runner.temp }}/dist-pypi:/tmp/dist-pypi \ $IMAGE bash -c " - pip install auditwheel patchelf -q + pip install auditwheel -q for whl in /tmp/dist/amd_mori_nightly-*.whl; do PLAT=\$(auditwheel show \"\$whl\" 2>&1 | grep -o 'manylinux_[0-9_]*_x86_64' | head -1) - if [ -n \"\$PLAT\" ]; then - auditwheel repair \"\$whl\" --plat \"\$PLAT\" -w /tmp/dist-pypi/ - else - cp \"\$whl\" /tmp/dist-pypi/ - fi + if [ -z \"\$PLAT\" ]; then PLAT=linux_x86_64; fi + NEWNAME=\$(basename \"\$whl\" | sed \"s/linux_x86_64/\$PLAT/\") + pip install wheel -q + cd /tmp && python3 -m wheel unpack \"\$whl\" + UNPACKED=\$(ls -d /tmp/amd_mori_nightly-*/ | head -1) + sed -i \"s/linux_x86_64/\$PLAT/\" \"\$UNPACKED\"/*.dist-info/WHEEL + python3 -m wheel pack \"\$UNPACKED\" -d /tmp/dist-pypi/ + rm -rf \"\$UNPACKED\" done " echo "=== PyPI wheels ===" From 8b57301c1112516329f6c56301f5e9d2b098a88e Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 04:33:47 +0000 Subject: [PATCH 07/19] chore: [skip ci] From 03261ec8345262483018ea7ad8c5342f08f0a11d Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:16:47 +0000 Subject: [PATCH 08/19] ci: revert PyPI version to dev${DATE}, pin twine<6 for metadata compat - twine 6.x rejects license-expression/license-file metadata from older setuptools; pin to twine<6 until metadata is updated - Use --skip-existing instead of || echo for cleaner error handling - Keep PyPI version as dev${DATE} (no run number suffix) --- .github/workflows/nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 50cfd546..080b7267 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -895,8 +895,8 @@ jobs: - name: Upload to PyPI run: | - pip install twine - python3 -m twine upload ./dist/*.whl || echo "Upload failed (version may already exist)" + pip install "twine<6" + python3 -m twine upload --skip-existing ./dist/*.whl env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} From 10cd7564180e6bd20a6e82d419c40c3d922175fc Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:16:49 +0000 Subject: [PATCH 09/19] chore: [skip ci] From 91f11ffe5291ec282e290969bfd9d7e0e803a19b Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:21:54 +0000 Subject: [PATCH 10/19] ci: temporarily skip tests to validate pypi publish flow [skip ci] --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 080b7267..2b702948 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -723,7 +723,7 @@ jobs: # ── Stage 4: Promote to latest/ after all tests pass ─────────────────────── promote-latest: name: promote to latest - needs: [deploy-staging, test-wheel, test-wheel-internode] + needs: [deploy-staging] # TODO: restore [deploy-staging, test-wheel, test-wheel-internode] if: github.event_name != 'pull_request' runs-on: ubuntu-latest permissions: From 8cc333b4889fe2fe5ff25504db6097f6f3fe04a1 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:28:14 +0000 Subject: [PATCH 11/19] ci: disable test-wheel jobs to free runners [skip ci] --- .github/workflows/nightly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2b702948..6f8ed9b2 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -270,6 +270,7 @@ jobs: test-wheel: name: intranode test (${{ matrix.platform }}, py${{ matrix.python }}) needs: deploy-staging + if: false # TODO: remove — temporarily disabled to validate pypi flow runs-on: ${{ matrix.runner }} strategy: fail-fast: false @@ -441,6 +442,7 @@ jobs: test-wheel-internode: name: internode test (${{ matrix.platform }}, py${{ matrix.python }}) needs: deploy-staging + if: false # TODO: remove — temporarily disabled to validate pypi flow runs-on: ${{ matrix.runner }} strategy: fail-fast: false From e737d0dc6216e4ae8ebf6c97abb27564defda2e0 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:40:18 +0000 Subject: [PATCH 12/19] =?UTF-8?q?ci:=20fix=20retag=20=E2=80=94=20use=20zip?= =?UTF-8?q?-level=20edit=20instead=20of=20wheel=20unpack/pack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wheel pack with old setuptools drops METADATA fields, causing twine to reject the wheel. Replace with direct zip manipulation that only modifies the WHEEL file's platform tag, preserving all other metadata. --- .github/workflows/nightly.yml | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 6f8ed9b2..2222c7b2 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -83,12 +83,28 @@ jobs: PLAT=\$(auditwheel show \"\$whl\" 2>&1 | grep -o 'manylinux_[0-9_]*_x86_64' | head -1) if [ -z \"\$PLAT\" ]; then PLAT=linux_x86_64; fi NEWNAME=\$(basename \"\$whl\" | sed \"s/linux_x86_64/\$PLAT/\") - pip install wheel -q - cd /tmp && python3 -m wheel unpack \"\$whl\" - UNPACKED=\$(ls -d /tmp/amd_mori_nightly-*/ | head -1) - sed -i \"s/linux_x86_64/\$PLAT/\" \"\$UNPACKED\"/*.dist-info/WHEEL - python3 -m wheel pack \"\$UNPACKED\" -d /tmp/dist-pypi/ - rm -rf \"\$UNPACKED\" + python3 -c \" +import zipfile, shutil, os, sys +src = '\$whl' +dst = '/tmp/dist-pypi/\$NEWNAME' +shutil.copy2(src, dst) +with zipfile.ZipFile(dst, 'r') as zin: + names = zin.namelist() + wheel_file = [n for n in names if n.endswith('/WHEEL')][0] + content = zin.read(wheel_file).decode() +fixed = content.replace('linux_x86_64', '\$PLAT') +import tempfile +tmpfd, tmppath = tempfile.mkstemp(suffix='.whl') +os.close(tmpfd) +with zipfile.ZipFile(dst, 'r') as zin, zipfile.ZipFile(tmppath, 'w') as zout: + for item in zin.infolist(): + data = zin.read(item.filename) + if item.filename == wheel_file: + data = fixed.encode() + zout.writestr(item, data) +shutil.move(tmppath, dst) +print(f'Retagged: {os.path.basename(dst)}') +\" done " echo "=== PyPI wheels ===" From b5df72d0692d97115cf258a27836e2794ffccd23 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:40:20 +0000 Subject: [PATCH 13/19] chore: [skip ci] From eb801a3f0c0af92791bacaa98e526bbd4e3b787f Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:42:17 +0000 Subject: [PATCH 14/19] =?UTF-8?q?ci:=20fix=20YAML=20syntax=20=E2=80=94=20m?= =?UTF-8?q?ove=20retag=20script=20to=20temp=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline Python code broke YAML parsing (import at column 0 was parsed as a mapping key). Write the retag script to a temp file and mount it into the Docker container instead. --- .github/workflows/nightly.yml | 43 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2222c7b2..5dfab98c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -74,37 +74,36 @@ jobs: - name: Retag PyPI wheels (manylinux platform tag) run: | mkdir -p ${{ runner.temp }}/dist-pypi + cat > ${{ runner.temp }}/retag.py << 'PYEOF' + import zipfile, shutil, os, sys, tempfile + src, dst, plat = sys.argv[1], sys.argv[2], sys.argv[3] + shutil.copy2(src, dst) + with zipfile.ZipFile(dst, 'r') as zin: + wheel_file = [n for n in zin.namelist() if n.endswith('/WHEEL')][0] + content = zin.read(wheel_file).decode() + fixed = content.replace('linux_x86_64', plat) + tmpfd, tmppath = tempfile.mkstemp(suffix='.whl') + os.close(tmpfd) + with zipfile.ZipFile(dst, 'r') as zin, zipfile.ZipFile(tmppath, 'w') as zout: + for item in zin.infolist(): + data = zin.read(item.filename) + if item.filename == wheel_file: + data = fixed.encode() + zout.writestr(item, data) + shutil.move(tmppath, dst) + print(f'Retagged: {os.path.basename(dst)}') + PYEOF $CT run --rm \ -v ${{ runner.temp }}/dist:/tmp/dist:ro \ -v ${{ runner.temp }}/dist-pypi:/tmp/dist-pypi \ + -v ${{ runner.temp }}/retag.py:/tmp/retag.py:ro \ $IMAGE bash -c " pip install auditwheel -q for whl in /tmp/dist/amd_mori_nightly-*.whl; do PLAT=\$(auditwheel show \"\$whl\" 2>&1 | grep -o 'manylinux_[0-9_]*_x86_64' | head -1) if [ -z \"\$PLAT\" ]; then PLAT=linux_x86_64; fi NEWNAME=\$(basename \"\$whl\" | sed \"s/linux_x86_64/\$PLAT/\") - python3 -c \" -import zipfile, shutil, os, sys -src = '\$whl' -dst = '/tmp/dist-pypi/\$NEWNAME' -shutil.copy2(src, dst) -with zipfile.ZipFile(dst, 'r') as zin: - names = zin.namelist() - wheel_file = [n for n in names if n.endswith('/WHEEL')][0] - content = zin.read(wheel_file).decode() -fixed = content.replace('linux_x86_64', '\$PLAT') -import tempfile -tmpfd, tmppath = tempfile.mkstemp(suffix='.whl') -os.close(tmpfd) -with zipfile.ZipFile(dst, 'r') as zin, zipfile.ZipFile(tmppath, 'w') as zout: - for item in zin.infolist(): - data = zin.read(item.filename) - if item.filename == wheel_file: - data = fixed.encode() - zout.writestr(item, data) -shutil.move(tmppath, dst) -print(f'Retagged: {os.path.basename(dst)}') -\" + python3 /tmp/retag.py \"\$whl\" \"/tmp/dist-pypi/\$NEWNAME\" \"\$PLAT\" done " echo "=== PyPI wheels ===" From 06ef63b8ec331355ce5515cd5ec6b2b7600e1412 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:42:19 +0000 Subject: [PATCH 15/19] chore: [skip ci] From 7f25dd3ba155f24a7229cf3b1e9bad0d2e8b9f87 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:44:31 +0000 Subject: [PATCH 16/19] ci: fix permission on retag wheels (root-owned from Docker) [skip ci] --- .github/workflows/nightly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5dfab98c..849a3d3a 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -106,6 +106,8 @@ jobs: python3 /tmp/retag.py \"\$whl\" \"/tmp/dist-pypi/\$NEWNAME\" \"\$PLAT\" done " + $CT run --rm -v ${{ runner.temp }}/dist-pypi:/tmp/dist-pypi $IMAGE \ + chown -R $(id -u):$(id -g) /tmp/dist-pypi echo "=== PyPI wheels ===" ls -lh ${{ runner.temp }}/dist-pypi/ From c021c7625eb9de9b999571d29f58cdf607b735ef Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 05:54:49 +0000 Subject: [PATCH 17/19] ci: use twine 6.x (supports Metadata-Version 2.4) [skip ci] --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 849a3d3a..bd798083 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -914,7 +914,7 @@ jobs: - name: Upload to PyPI run: | - pip install "twine<6" + pip install twine python3 -m twine upload --skip-existing ./dist/*.whl env: TWINE_USERNAME: __token__ From f0ef9e5ffafe1d0c27e5af3a222d524404a9cb10 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 06:06:01 +0000 Subject: [PATCH 18/19] ci: upgrade packaging>=24.2 for PEP 639 metadata support [skip ci] --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bd798083..1e3d208c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -914,7 +914,7 @@ jobs: - name: Upload to PyPI run: | - pip install twine + pip install twine "packaging>=24.2" python3 -m twine upload --skip-existing ./dist/*.whl env: TWINE_USERNAME: __token__ From e666c288f7147952f7a0b4fc6d78e2051addb7d9 Mon Sep 17 00:00:00 2001 From: jhchouuu Date: Wed, 20 May 2026 06:15:48 +0000 Subject: [PATCH 19/19] ci: restore test-wheel jobs and promote-latest dependencies Re-enable test-wheel and test-wheel-internode (were disabled for PyPI publish flow validation). Restore promote-latest to gate on all tests passing. --- .github/workflows/nightly.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 1e3d208c..6054dd51 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -287,7 +287,6 @@ jobs: test-wheel: name: intranode test (${{ matrix.platform }}, py${{ matrix.python }}) needs: deploy-staging - if: false # TODO: remove — temporarily disabled to validate pypi flow runs-on: ${{ matrix.runner }} strategy: fail-fast: false @@ -459,7 +458,6 @@ jobs: test-wheel-internode: name: internode test (${{ matrix.platform }}, py${{ matrix.python }}) needs: deploy-staging - if: false # TODO: remove — temporarily disabled to validate pypi flow runs-on: ${{ matrix.runner }} strategy: fail-fast: false @@ -742,7 +740,7 @@ jobs: # ── Stage 4: Promote to latest/ after all tests pass ─────────────────────── promote-latest: name: promote to latest - needs: [deploy-staging] # TODO: restore [deploy-staging, test-wheel, test-wheel-internode] + needs: [deploy-staging, test-wheel, test-wheel-internode] if: github.event_name != 'pull_request' runs-on: ubuntu-latest permissions: