From a912fb02059371e29055b108aecf0143f2f77919 Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 14:00:37 -0400 Subject: [PATCH 1/8] add the rust publish ci. Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 179 +++++++++++++++++++++++++++ rust/tvm-ffi-macros/Cargo.toml | 1 + rust/tvm-ffi-sys/Cargo.toml | 1 + rust/tvm-ffi/Cargo.toml | 2 + 4 files changed, 183 insertions(+) create mode 100644 .github/workflows/publish_crates.yml diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml new file mode 100644 index 000000000..fa61c8316 --- /dev/null +++ b/.github/workflows/publish_crates.yml @@ -0,0 +1,179 @@ +# 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 crates + +on: + release: + types: [published] + workflow_dispatch: + inputs: + tag: + description: "Release tag to publish (e.g. v0.1.15 or v0.1.15-rc0)" + required: true + type: string + +permissions: + contents: read + +concurrency: + group: publish-crates-${{ inputs.tag || github.event.release.tag_name }} + cancel-in-progress: false + +env: + CARGO_TERM_COLOR: always + RELEASE_TAG: ${{ inputs.tag || github.event.release.tag_name }} + +jobs: + build_crates: + name: ${{ matrix.os }} (${{ matrix.arch }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Keep the OS/architecture matrix in sync with publish_wheel.yml. + include: + - {os: ubuntu-latest, arch: x86_64} + - {os: ubuntu-24.04-arm, arch: aarch64} + - {os: windows-latest, arch: AMD64} + - {os: macos-14, arch: arm64} + + steps: + - name: Check out release source + uses: actions/checkout@v5 + with: + ref: refs/tags/${{ inputs.tag || github.event.release.tag_name }} + submodules: recursive + fetch-depth: 0 + fetch-tags: true + + - name: Set up uv + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + with: + python-version: "3.13" + activate-environment: true + + # Workspace publishing and dry-runs require Cargo 1.90 or newer. + - name: Set up Rust + run: rustup toolchain install stable --profile minimal + + - uses: ./.github/actions/detect-env-vars + id: env_vars + + # tvm-ffi-sys locates libtvm_ffi through tvm-ffi-config on PATH. + - name: Build and install TVM FFI + env: + CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }} + run: uv pip install --verbose . + + # Apply the release version after the Python build so setuptools-scm sees a clean tree. + - name: Set crate versions from Git + shell: bash + run: &set_crate_versions | + uv run --no-project --with tomlkit python - <<'PY' + from __future__ import annotations + + import os + import re + import subprocess + from pathlib import Path + + import tomlkit + + tag = subprocess.check_output( + ["git", "describe", "--tags", "--exact-match", "--match", os.environ["RELEASE_TAG"]], + text=True, + ).strip() + version = tag.removeprefix("v") + # Normalize the repository's RC tags to numeric SemVer prerelease identifiers. + version = re.sub(r"-(alpha|beta|rc)(\d+)$", r"-\1.\2", version) + crates = ("tvm-ffi", "tvm-ffi-sys", "tvm-ffi-macros") + for crate in crates: + path = Path("rust") / crate / "Cargo.toml" + manifest = tomlkit.parse(path.read_text(encoding="utf-8")) + manifest["package"]["version"] = version + for section in ("dependencies", "dev-dependencies", "build-dependencies"): + for name, dependency in manifest.get(section, {}).items(): + if name in crates: + dependency["version"] = version + path.write_text(tomlkit.dumps(manifest), encoding="utf-8") + print(f"{crate}: {version}") + PY + # Cargo validates the derived SemVer and the updated dependency requirements. + cargo +stable metadata --manifest-path rust/Cargo.toml --no-deps --format-version 1 > /dev/null + + - name: Build crates + working-directory: rust + run: cargo +stable build --release --workspace + + - name: Test crates + working-directory: rust + run: cargo +stable test --release --workspace + + - name: Package and verify crates + working-directory: rust + # Only the release-version edits above are uncommitted in this checkout. + run: cargo +stable package --workspace --registry crates-io --allow-dirty + + - name: Upload crate artifacts + uses: actions/upload-artifact@v4 + with: + name: crates-${{ matrix.os }}-${{ matrix.arch }} + path: rust/target/package/*.crate + if-no-files-found: error + + upload_crates: + needs: [build_crates] + runs-on: ubuntu-latest + environment: crates-io + steps: + - name: Check out release source + uses: actions/checkout@v5 + with: + ref: refs/tags/${{ inputs.tag || github.event.release.tag_name }} + submodules: recursive + fetch-depth: 0 + fetch-tags: true + + - name: Set up uv + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + with: + python-version: "3.13" + activate-environment: true + + - name: Set up Rust + run: rustup toolchain install stable --profile minimal + + - uses: ./.github/actions/detect-env-vars + id: env_vars + + - name: Build and install TVM FFI + env: + CMAKE_BUILD_PARALLEL_LEVEL: ${{ steps.env_vars.outputs.cpu_count }} + run: uv pip install --verbose . + + - name: Set crate versions from Git + shell: bash + run: *set_crate_versions + + # Cargo publishes the workspace in dependency order and waits for the registry index. + # Configure a crates.io API token with publish access to all three crates. + - name: Publish crates to crates.io + working-directory: rust + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo +stable publish --workspace --registry crates-io --allow-dirty diff --git a/rust/tvm-ffi-macros/Cargo.toml b/rust/tvm-ffi-macros/Cargo.toml index f8d29d406..6c646904d 100644 --- a/rust/tvm-ffi-macros/Cargo.toml +++ b/rust/tvm-ffi-macros/Cargo.toml @@ -19,6 +19,7 @@ name = "tvm-ffi-macros" description = "Procedural macro crate for tvm-ffi" +# Development placeholder; publish_crates.yml sets the release version from the Git tag. version = "0.1.0-alpha.0" edition = "2021" license = "Apache-2.0" diff --git a/rust/tvm-ffi-sys/Cargo.toml b/rust/tvm-ffi-sys/Cargo.toml index 5ae2d9542..04ad17441 100644 --- a/rust/tvm-ffi-sys/Cargo.toml +++ b/rust/tvm-ffi-sys/Cargo.toml @@ -19,6 +19,7 @@ name = "tvm-ffi-sys" description = "Low-level sys crate for tvm-ffi" +# Development placeholder; publish_crates.yml sets the release version from the Git tag. version = "0.1.0-alpha.0" edition = "2021" license = "Apache-2.0" diff --git a/rust/tvm-ffi/Cargo.toml b/rust/tvm-ffi/Cargo.toml index 3df4eaf98..1fbd1c8a4 100644 --- a/rust/tvm-ffi/Cargo.toml +++ b/rust/tvm-ffi/Cargo.toml @@ -19,6 +19,7 @@ name = "tvm-ffi" description = "tvm-ffi rust support" +# Development placeholder; publish_crates.yml sets the release version from the Git tag. version = "0.1.0-alpha.0" edition = "2021" license = "Apache-2.0" @@ -30,6 +31,7 @@ crate-type = ["lib"] [dependencies] paste = "1.0" +# Release CI also updates the internal dependency versions, including dev-dependencies. tvm-ffi-sys = { version = "0.1.0-alpha.0", path = "../tvm-ffi-sys" } tvm-ffi-macros = { version = "0.1.0-alpha.0", path = "../tvm-ffi-macros" } From 59c2c737c1b8cc72f55aaafc31901114eb90081e Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 14:09:29 -0400 Subject: [PATCH 2/8] test dryrun. Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml index fa61c8316..e997b6487 100644 --- a/.github/workflows/publish_crates.yml +++ b/.github/workflows/publish_crates.yml @@ -18,25 +18,28 @@ name: Publish crates on: - release: - types: [published] workflow_dispatch: inputs: tag: - description: "Release tag to publish (e.g. v0.1.15 or v0.1.15-rc0)" + description: "Tag to publish (manual run, e.g. v0.1.15 or v0.1.15-rc0)" required: true type: string + dry_run: + description: "Build and verify crates without publishing to crates.io" + required: true + type: boolean + default: true permissions: contents: read concurrency: - group: publish-crates-${{ inputs.tag || github.event.release.tag_name }} + group: publish-crates-${{ inputs.tag }} cancel-in-progress: false env: CARGO_TERM_COLOR: always - RELEASE_TAG: ${{ inputs.tag || github.event.release.tag_name }} + RELEASE_TAG: ${{ inputs.tag }} jobs: build_crates: @@ -56,7 +59,7 @@ jobs: - name: Check out release source uses: actions/checkout@v5 with: - ref: refs/tags/${{ inputs.tag || github.event.release.tag_name }} + ref: refs/tags/${{ inputs.tag }} submodules: recursive fetch-depth: 0 fetch-tags: true @@ -136,15 +139,21 @@ jobs: path: rust/target/package/*.crate if-no-files-found: error + - name: Dry-run crate publication + if: inputs.dry_run + working-directory: rust + run: cargo +stable publish --dry-run --workspace --registry crates-io --allow-dirty + upload_crates: needs: [build_crates] runs-on: ubuntu-latest environment: crates-io + if: github.event_name == 'workflow_dispatch' && !inputs.dry_run steps: - name: Check out release source uses: actions/checkout@v5 with: - ref: refs/tags/${{ inputs.tag || github.event.release.tag_name }} + ref: refs/tags/${{ inputs.tag }} submodules: recursive fetch-depth: 0 fetch-tags: true From 69cebc3584074f0a9e1f776d65ed6111be7a4a70 Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 14:41:34 -0400 Subject: [PATCH 3/8] support va.b.c-postd Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 46 ++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml index e997b6487..05336165c 100644 --- a/.github/workflows/publish_crates.yml +++ b/.github/workflows/publish_crates.yml @@ -21,7 +21,7 @@ on: workflow_dispatch: inputs: tag: - description: "Tag to publish (manual run, e.g. v0.1.15 or v0.1.15-rc0)" + description: "Tag to publish (manual run, e.g. v0.1.15, v0.1.15-rc0 or v0.1.14-post1)" required: true type: string dry_run: @@ -101,9 +101,30 @@ jobs: ["git", "describe", "--tags", "--exact-match", "--match", os.environ["RELEASE_TAG"]], text=True, ).strip() - version = tag.removeprefix("v") - # Normalize the repository's RC tags to numeric SemVer prerelease identifiers. - version = re.sub(r"-(alpha|beta|rc)(\d+)$", r"-\1.\2", version) + # Accept only the repository's release tag forms and map them onto SemVer: + # v0.1.15 -> 0.1.15 + # v0.1.15-rc0 -> 0.1.15-rc.0 (likewise alpha/beta) + # v0.1.14-post1 -> 0.1.15-post.1 (PEP 440 post releases sort above their base + # release, so they become a prerelease of the + # next patch rather than of the same one) + match = re.fullmatch( + r"v(?P\d+)\.(?P\d+)\.(?P\d+)" + r"(?:-(?Palpha|beta|rc|post)(?P\d+))?", + tag, + ) + if match is None: + raise SystemExit( + f"unsupported release tag {tag!r}: " + "expected vX.Y.Z, vX.Y.Z-(alpha|beta|rc)N or vX.Y.Z-postN" + ) + major, minor, patch = (int(match[name]) for name in ("major", "minor", "patch")) + kind, num = match["kind"], match["num"] + if kind == "post": + version = f"{major}.{minor}.{patch + 1}-post.{num}" + elif kind: + version = f"{major}.{minor}.{patch}-{kind}.{num}" + else: + version = f"{major}.{minor}.{patch}" crates = ("tvm-ffi", "tvm-ffi-sys", "tvm-ffi-macros") for crate in crates: path = Path("rust") / crate / "Cargo.toml" @@ -115,6 +136,8 @@ jobs: dependency["version"] = version path.write_text(tomlkit.dumps(manifest), encoding="utf-8") print(f"{crate}: {version}") + with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as env_file: + env_file.write(f"CRATE_VERSION={version}\n") PY # Cargo validates the derived SemVer and the updated dependency requirements. cargo +stable metadata --manifest-path rust/Cargo.toml --no-deps --format-version 1 > /dev/null @@ -179,10 +202,21 @@ jobs: shell: bash run: *set_crate_versions - # Cargo publishes the workspace in dependency order and waits for the registry index. + # Publish in dependency order; each publish waits for the registry index before returning. + # A version that is already on crates.io is skipped, so a run that stopped part-way can be + # repeated and resumes with the crates that are still missing. # Configure a crates.io API token with publish access to all three crates. - name: Publish crates to crates.io working-directory: rust + shell: bash env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo +stable publish --workspace --registry crates-io --allow-dirty + run: | + for crate in tvm-ffi-macros tvm-ffi-sys tvm-ffi; do + if cargo +stable info --registry crates-io "${crate}@${CRATE_VERSION}" > /dev/null 2>&1; then + echo "${crate}@${CRATE_VERSION} is already on crates.io; skipping." + continue + fi + echo "Publishing ${crate}@${CRATE_VERSION}" + cargo +stable publish --package "${crate}" --registry crates-io --allow-dirty + done From 5e214589acbf2ede51e740354354eebc40a8fc6f Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 15:07:10 -0400 Subject: [PATCH 4/8] update the verification and error report. Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml index 05336165c..9a85fbfda 100644 --- a/.github/workflows/publish_crates.yml +++ b/.github/workflows/publish_crates.yml @@ -202,6 +202,12 @@ jobs: shell: bash run: *set_crate_versions + # Package and verify all three crates before anything is uploaded, so a crate that fails + # verification cannot leave an earlier one irrevocably published. + - name: Package and verify crates + working-directory: rust + run: cargo +stable package --workspace --registry crates-io --allow-dirty + # Publish in dependency order; each publish waits for the registry index before returning. # A version that is already on crates.io is skipped, so a run that stopped part-way can be # repeated and resumes with the crates that are still missing. @@ -213,9 +219,15 @@ jobs: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: | for crate in tvm-ffi-macros tvm-ffi-sys tvm-ffi; do - if cargo +stable info --registry crates-io "${crate}@${CRATE_VERSION}" > /dev/null 2>&1; then + if lookup=$(cargo +stable info --registry crates-io "${crate}@${CRATE_VERSION}" 2>&1); then echo "${crate}@${CRATE_VERSION} is already on crates.io; skipping." continue + elif ! grep -q "could not find" <<< "${lookup}"; then + # Anything other than a definite "not found" (network, index, auth) must not be + # mistaken for an unpublished crate. + echo "${lookup}" + echo "::error::Could not determine whether ${crate}@${CRATE_VERSION} is on crates.io" + exit 1 fi echo "Publishing ${crate}@${CRATE_VERSION}" cargo +stable publish --package "${crate}" --registry crates-io --allow-dirty From a53147b738688260e26d3cfd0aa8fb307f0a1cfa Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 15:23:35 -0400 Subject: [PATCH 5/8] update. Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 29 +++++++++++----------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml index 9a85fbfda..5ce57a03f 100644 --- a/.github/workflows/publish_crates.yml +++ b/.github/workflows/publish_crates.yml @@ -101,21 +101,17 @@ jobs: ["git", "describe", "--tags", "--exact-match", "--match", os.environ["RELEASE_TAG"]], text=True, ).strip() - # Accept only the repository's release tag forms and map them onto SemVer: - # v0.1.15 -> 0.1.15 - # v0.1.15-rc0 -> 0.1.15-rc.0 (likewise alpha/beta) - # v0.1.14-post1 -> 0.1.15-post.1 (PEP 440 post releases sort above their base - # release, so they become a prerelease of the - # next patch rather than of the same one) + # v0.1.15 -> 0.1.15, v0.1.15-rc0 -> 0.1.15-rc.0, v0.1.14-post1 -> 0.1.15-post.1 + # (a post release sorts above its base, so it becomes a prerelease of the next patch). match = re.fullmatch( r"v(?P\d+)\.(?P\d+)\.(?P\d+)" - r"(?:-(?Palpha|beta|rc|post)(?P\d+))?", + r"(?:-(?Prc|post)(?P\d+))?", tag, ) if match is None: raise SystemExit( f"unsupported release tag {tag!r}: " - "expected vX.Y.Z, vX.Y.Z-(alpha|beta|rc)N or vX.Y.Z-postN" + "expected vX.Y.Z, vX.Y.Z-rcN or vX.Y.Z-postN" ) major, minor, patch = (int(match[name]) for name in ("major", "minor", "patch")) kind, num = match["kind"], match["num"] @@ -133,7 +129,8 @@ jobs: for section in ("dependencies", "dev-dependencies", "build-dependencies"): for name, dependency in manifest.get(section, {}).items(): if name in crates: - dependency["version"] = version + # Exact pin: the three crates ship together. + dependency["version"] = f"={version}" path.write_text(tomlkit.dumps(manifest), encoding="utf-8") print(f"{crate}: {version}") with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as env_file: @@ -202,16 +199,13 @@ jobs: shell: bash run: *set_crate_versions - # Package and verify all three crates before anything is uploaded, so a crate that fails - # verification cannot leave an earlier one irrevocably published. + # Verify all three crates before anything is uploaded; the publishes below skip re-verifying. - name: Package and verify crates working-directory: rust run: cargo +stable package --workspace --registry crates-io --allow-dirty - # Publish in dependency order; each publish waits for the registry index before returning. - # A version that is already on crates.io is skipped, so a run that stopped part-way can be - # repeated and resumes with the crates that are still missing. - # Configure a crates.io API token with publish access to all three crates. + # Publish in dependency order, skipping versions already on crates.io so a partial run can be + # repeated. Needs a crates.io token with publish access to all three crates. - name: Publish crates to crates.io working-directory: rust shell: bash @@ -223,12 +217,11 @@ jobs: echo "${crate}@${CRATE_VERSION} is already on crates.io; skipping." continue elif ! grep -q "could not find" <<< "${lookup}"; then - # Anything other than a definite "not found" (network, index, auth) must not be - # mistaken for an unpublished crate. + # Only a definite "not found" may fall through to publishing. echo "${lookup}" echo "::error::Could not determine whether ${crate}@${CRATE_VERSION} is on crates.io" exit 1 fi echo "Publishing ${crate}@${CRATE_VERSION}" - cargo +stable publish --package "${crate}" --registry crates-io --allow-dirty + cargo +stable publish --package "${crate}" --registry crates-io --allow-dirty --no-verify done From 499ad071de62c2c7be447558b73fb372572a7e53 Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 16:29:21 -0400 Subject: [PATCH 6/8] fix. Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml index 5ce57a03f..98ee33d37 100644 --- a/.github/workflows/publish_crates.yml +++ b/.github/workflows/publish_crates.yml @@ -21,7 +21,7 @@ on: workflow_dispatch: inputs: tag: - description: "Tag to publish (manual run, e.g. v0.1.15, v0.1.15-rc0 or v0.1.14-post1)" + description: "Tag to publish (manual run)" required: true type: string dry_run: @@ -139,18 +139,20 @@ jobs: # Cargo validates the derived SemVer and the updated dependency requirements. cargo +stable metadata --manifest-path rust/Cargo.toml --no-deps --format-version 1 > /dev/null - - name: Build crates - working-directory: rust - run: cargo +stable build --release --workspace - - name: Test crates working-directory: rust run: cargo +stable test --release --workspace - - name: Package and verify crates + # Packages and verifies the crates; only the release-version edits above are uncommitted. + - name: Dry-run crate publication working-directory: rust - # Only the release-version edits above are uncommitted in this checkout. - run: cargo +stable package --workspace --registry crates-io --allow-dirty + run: cargo +stable publish --dry-run --workspace --registry crates-io --allow-dirty + + # The dry run keeps its .crate files in a temporary directory; write them out again, + # without re-verifying, for the artifact upload. + - name: Package crates + working-directory: rust + run: cargo +stable package --workspace --registry crates-io --allow-dirty --no-verify - name: Upload crate artifacts uses: actions/upload-artifact@v4 @@ -159,11 +161,6 @@ jobs: path: rust/target/package/*.crate if-no-files-found: error - - name: Dry-run crate publication - if: inputs.dry_run - working-directory: rust - run: cargo +stable publish --dry-run --workspace --registry crates-io --allow-dirty - upload_crates: needs: [build_crates] runs-on: ubuntu-latest From ed83c605585dff30c00e126f7639fdbf48cbfd91 Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 16:48:07 -0400 Subject: [PATCH 7/8] simplify. Signed-off-by: yuchuan --- .github/workflows/publish_crates.yml | 38 ++++++---------------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/.github/workflows/publish_crates.yml b/.github/workflows/publish_crates.yml index 98ee33d37..a8f0afff1 100644 --- a/.github/workflows/publish_crates.yml +++ b/.github/workflows/publish_crates.yml @@ -87,40 +87,20 @@ jobs: - name: Set crate versions from Git shell: bash run: &set_crate_versions | + # The crate version is the tag without its "v": 0.1.15, 0.1.15-rc0 or 0.1.14-post1. + if [[ ! "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-(rc|post)[0-9]+)?$ ]]; then + echo "::error::unsupported release tag '$RELEASE_TAG': expected vX.Y.Z, vX.Y.Z-rcN or vX.Y.Z-postN" + exit 1 + fi + export CRATE_VERSION="${RELEASE_TAG#v}" + echo "CRATE_VERSION=$CRATE_VERSION" >> "$GITHUB_ENV" uv run --no-project --with tomlkit python - <<'PY' - from __future__ import annotations - import os - import re - import subprocess from pathlib import Path import tomlkit - tag = subprocess.check_output( - ["git", "describe", "--tags", "--exact-match", "--match", os.environ["RELEASE_TAG"]], - text=True, - ).strip() - # v0.1.15 -> 0.1.15, v0.1.15-rc0 -> 0.1.15-rc.0, v0.1.14-post1 -> 0.1.15-post.1 - # (a post release sorts above its base, so it becomes a prerelease of the next patch). - match = re.fullmatch( - r"v(?P\d+)\.(?P\d+)\.(?P\d+)" - r"(?:-(?Prc|post)(?P\d+))?", - tag, - ) - if match is None: - raise SystemExit( - f"unsupported release tag {tag!r}: " - "expected vX.Y.Z, vX.Y.Z-rcN or vX.Y.Z-postN" - ) - major, minor, patch = (int(match[name]) for name in ("major", "minor", "patch")) - kind, num = match["kind"], match["num"] - if kind == "post": - version = f"{major}.{minor}.{patch + 1}-post.{num}" - elif kind: - version = f"{major}.{minor}.{patch}-{kind}.{num}" - else: - version = f"{major}.{minor}.{patch}" + version = os.environ["CRATE_VERSION"] crates = ("tvm-ffi", "tvm-ffi-sys", "tvm-ffi-macros") for crate in crates: path = Path("rust") / crate / "Cargo.toml" @@ -133,8 +113,6 @@ jobs: dependency["version"] = f"={version}" path.write_text(tomlkit.dumps(manifest), encoding="utf-8") print(f"{crate}: {version}") - with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as env_file: - env_file.write(f"CRATE_VERSION={version}\n") PY # Cargo validates the derived SemVer and the updated dependency requirements. cargo +stable metadata --manifest-path rust/Cargo.toml --no-deps --format-version 1 > /dev/null From df9478ca8a611dd5b8162ff2709515682445abab Mon Sep 17 00:00:00 2001 From: yuchuan Date: Mon, 5 Oct 2026 19:22:34 -0400 Subject: [PATCH 8/8] update doc dependency. Signed-off-by: yuchuan --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 68c9480af..105953b22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,8 @@ dev = [ ] docs = [ "autodocsumm", - "breathe", + # 5.0.0 breaks C++ template specializations and constexpr constructors. + "breathe!=5.0.0", "exhale", "linkify-it-py", "matplotlib",