From 32f49ab35c1f01e3443709a84a5da13efd3a0a61 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 19:57:51 +0400 Subject: [PATCH 01/23] ci: build on ubuntu 22.04 --- .github/workflows/release.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4cd02ee..8d6cc32 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,7 +96,7 @@ jobs: publish-encoderfile: needs: create-tag - runs-on: ubuntu-24.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -113,7 +113,7 @@ jobs: upload-install-script: needs: create-tag - runs-on: ubuntu-24.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Upload artifact @@ -133,9 +133,9 @@ jobs: target: x86_64-apple-darwin - runner: macos-14 target: aarch64-apple-darwin - - runner: ubuntu-24.04 + - runner: ubuntu-22.04 target: x86_64-unknown-linux-gnu - - runner: ubuntu-24.04-arm + - runner: ubuntu-22.04-arm target: aarch64-unknown-linux-gnu steps: - uses: actions/checkout@v4 @@ -180,9 +180,9 @@ jobs: target: x86_64-apple-darwin - runner: macos-14 target: aarch64-apple-darwin - - runner: ubuntu-24.04 + - runner: ubuntu-22.04 target: x86_64-unknown-linux-gnu - - runner: ubuntu-24.04-arm + - runner: ubuntu-22.04-arm target: aarch64-unknown-linux-gnu steps: - uses: actions/checkout@v4 @@ -249,7 +249,7 @@ jobs: runner: ubuntu-latest - arch: arm64 platform: linux/arm64 - runner: ubuntu-24.04-arm + runner: ubuntu-22.04-arm steps: - uses: actions/checkout@v4 From 8d1d2d6823edc75082513ec508582585e88bb8e6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:01:06 +0400 Subject: [PATCH 02/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-beta.7=20(#225)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.6 to 0.4.0-beta.7. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 4 ++-- encoderfile-runtime/Cargo.toml | 4 ++-- encoderfile/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63e4861..6cf2c24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.6" +version = "0.4.0-beta.7" dependencies = [ "anyhow", "axum", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.6" +version = "0.4.0-beta.7" dependencies = [ "anyhow", "clap", diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index d50208f..d7164b2 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.6" +version = "0.4.0-beta.7" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.6" +version = "0.4.0-beta.7" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index ca86003..c105f17 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -49,7 +49,7 @@ required-features = ["dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.6" +version = "0.4.0-beta.7" edition = "2024" license = "Apache-2.0" readme = "../README.md" From 85ca5d69deed398c5bde0cbe718413ad65ca13db Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:11:29 +0400 Subject: [PATCH 03/23] ci: fix release targets --- .github/workflows/release.yml | 65 ++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8d6cc32..22a4d7a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,7 +96,7 @@ jobs: publish-encoderfile: needs: create-tag - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -113,7 +113,7 @@ jobs: upload-install-script: needs: create-tag - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Upload artifact @@ -133,9 +133,9 @@ jobs: target: x86_64-apple-darwin - runner: macos-14 target: aarch64-apple-darwin - - runner: ubuntu-22.04 + - runner: ubuntu-24.04 target: x86_64-unknown-linux-gnu - - runner: ubuntu-22.04-arm + - runner: ubuntu-24.04-arm target: aarch64-unknown-linux-gnu steps: - uses: actions/checkout@v4 @@ -170,7 +170,7 @@ jobs: name: encoderfile-runtime-${{ matrix.platform.target }} path: encoderfile-runtime-${{ matrix.platform.target }}.tar.gz - build-encoderfile: + build-encoderfile-macos: needs: create-tag runs-on: ${{ matrix.platform.runner }} strategy: @@ -180,9 +180,50 @@ jobs: target: x86_64-apple-darwin - runner: macos-14 target: aarch64-apple-darwin - - runner: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Project setup + uses: ./.github/actions/project-setup + + - name: Install target + run: rustup target add ${{ matrix.platform.target }} + + - name: Build + run: cargo build --bin encoderfile --release --target ${{ matrix.platform.target }} + + - name: Create release tarball + run: | + VERSION="${{ needs.create-tag.outputs.version }}" + TARGET="${{ matrix.platform.target }}" + mkdir -p dist + + cp target/${TARGET}/release/encoderfile dist/encoderfile + cp README.md dist/README.md + cp LICENSE dist/LICENSE + test -f THIRDPARTY.md && cp THIRDPARTY.md dist/THIRDPARTY.md + + TAR="encoderfile-${TARGET}.tar.gz" + tar -czf "$TAR" -C dist . + echo "Created $TAR" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: encoderfile-${{ matrix.platform.target }} + path: encoderfile-${{ matrix.platform.target }}.tar.gz + + build-encoderfile-linux: + needs: create-tag + runs-on: ${{ matrix.platform.runner }} + container: + image: debian:bookworm + strategy: + matrix: + platform: + - runner: ubuntu-24.04 target: x86_64-unknown-linux-gnu - - runner: ubuntu-22.04-arm + - runner: ubuntu-24.04-arm target: aarch64-unknown-linux-gnu steps: - uses: actions/checkout@v4 @@ -218,7 +259,13 @@ jobs: path: encoderfile-${{ matrix.platform.target }}.tar.gz create-release: - needs: [create-tag, build-encoderfile, publish-encoderfile, upload-install-script, build-encoderfile-runtime] + needs: + - create-tag + - build-encoderfile-linux + - build-encoderfile-macos + - publish-encoderfile + - upload-install-script + - build-encoderfile-runtime runs-on: ubuntu-latest steps: - name: Download all artifacts @@ -249,7 +296,7 @@ jobs: runner: ubuntu-latest - arch: arm64 platform: linux/arm64 - runner: ubuntu-22.04-arm + runner: ubuntu-24.04-arm steps: - uses: actions/checkout@v4 From 9672659877f8875052954a2fb0822b9ac1420bba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:12:52 +0400 Subject: [PATCH 04/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-beta.8=20(#226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.7 to 0.4.0-beta.8. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 4 ++-- encoderfile-runtime/Cargo.toml | 4 ++-- encoderfile/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6cf2c24..042ec9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.7" +version = "0.4.0-beta.8" dependencies = [ "anyhow", "axum", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.7" +version = "0.4.0-beta.8" dependencies = [ "anyhow", "clap", diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index d7164b2..c3a48c0 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.7" +version = "0.4.0-beta.8" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.7" +version = "0.4.0-beta.8" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index c105f17..fd3231e 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -49,7 +49,7 @@ required-features = ["dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.7" +version = "0.4.0-beta.8" edition = "2024" license = "Apache-2.0" readme = "../README.md" From 43e8d72b33670e1d72ffd0013daf7f941da45821 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:17:44 +0400 Subject: [PATCH 05/23] ci: fix release targets --- .github/actions/project-setup/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index 4291282..8818fc7 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -38,6 +38,7 @@ runs: libssl-dev \ pkg-config \ cmake \ + curl \ zlib1g-dev \ libdw-dev \ binutils-dev \ From 9505c57a1cb1ef7441928cd0f05ca241138b9c5c Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:20:02 +0400 Subject: [PATCH 06/23] ci: fix release targets --- .github/workflows/release.yml | 46 +++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22a4d7a..6487555 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -123,7 +123,7 @@ jobs: name: install path: install.sh - build-encoderfile-runtime: + build-encoderfile-runtime-macos: needs: create-tag runs-on: ${{ matrix.platform.runner }} strategy: @@ -133,6 +133,47 @@ jobs: target: x86_64-apple-darwin - runner: macos-14 target: aarch64-apple-darwin + steps: + - uses: actions/checkout@v4 + + - name: Project setup + uses: ./.github/actions/project-setup + + - name: Install target + run: rustup target add ${{ matrix.platform.target }} + + - name: Build + run: cargo build --bin encoderfile-runtime --release --target ${{ matrix.platform.target }} + + - name: Create release tarball + run: | + VERSION="${{ needs.create-tag.outputs.version }}" + TARGET="${{ matrix.platform.target }}" + mkdir -p dist + + cp target/${TARGET}/release/encoderfile-runtime dist/encoderfile-runtime + cp README.md dist/README.md + cp LICENSE dist/LICENSE + test -f THIRDPARTY.md && cp THIRDPARTY.md dist/THIRDPARTY.md + + TAR="encoderfile-runtime-${TARGET}.tar.gz" + tar -czf "$TAR" -C dist . + echo "Created $TAR" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: encoderfile-runtime-${{ matrix.platform.target }} + path: encoderfile-runtime-${{ matrix.platform.target }}.tar.gz + + build-encoderfile-runtime-linux: + needs: create-tag + runs-on: ${{ matrix.platform.runner }} + container: + image: debian:bookworm + strategy: + matrix: + platform: - runner: ubuntu-24.04 target: x86_64-unknown-linux-gnu - runner: ubuntu-24.04-arm @@ -265,7 +306,8 @@ jobs: - build-encoderfile-macos - publish-encoderfile - upload-install-script - - build-encoderfile-runtime + - build-encoderfile-runtime-linux + - build-encoderfile-runtime-macos runs-on: ubuntu-latest steps: - name: Download all artifacts From 2b36fbf9e22b62be868965b38bb5898a9f9711b3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:21:19 +0400 Subject: [PATCH 07/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-beta.9=20(#227)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.8 to 0.4.0-beta.9. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 4 ++-- encoderfile-runtime/Cargo.toml | 4 ++-- encoderfile/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 042ec9d..8aabe8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.8" +version = "0.4.0-beta.9" dependencies = [ "anyhow", "axum", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.8" +version = "0.4.0-beta.9" dependencies = [ "anyhow", "clap", diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index c3a48c0..a55acd5 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.8" +version = "0.4.0-beta.9" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.8" +version = "0.4.0-beta.9" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index fd3231e..87cb550 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -49,7 +49,7 @@ required-features = ["dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.8" +version = "0.4.0-beta.9" edition = "2024" license = "Apache-2.0" readme = "../README.md" From b961894681a37c23c2edd23abd070057c2483605 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:23:01 +0400 Subject: [PATCH 08/23] ci: fix release targets --- .github/actions/project-setup/action.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index 8818fc7..88ba0f2 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -14,17 +14,6 @@ inputs: runs: using: "composite" steps: - # Rust toolchain - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: ${{ inputs.toolchain }} - target: ${{ inputs.target }} - - # Python - - uses: actions/setup-python@v5 - with: - python-version: "3.13" - # ----- OS-Specific System Dependencies ----- # Linux deps @@ -59,6 +48,17 @@ runs: libelf \ binutils || true # binutils conflicts with Apple toolchain, so ignore failure + # Rust toolchain + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ inputs.toolchain }} + target: ${{ inputs.target }} + + # Python + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + # ----- Universal steps ----- - name: Install uv From a7231997644cde0c08aa0fc92eadffb7756b0d55 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:24:37 +0400 Subject: [PATCH 09/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-beta.10=20(#228)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.9 to 0.4.0-beta.10. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 4 ++-- encoderfile-runtime/Cargo.toml | 4 ++-- encoderfile/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8aabe8f..b5b8d67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.9" +version = "0.4.0-beta.10" dependencies = [ "anyhow", "axum", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.9" +version = "0.4.0-beta.10" dependencies = [ "anyhow", "clap", diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index a55acd5..7a0797d 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.9" +version = "0.4.0-beta.10" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.9" +version = "0.4.0-beta.10" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index 87cb550..fa4e1ce 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -49,7 +49,7 @@ required-features = ["dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.9" +version = "0.4.0-beta.10" edition = "2024" license = "Apache-2.0" readme = "../README.md" From 70307658a8cee2b7c916bdc1322eb76d3db112b6 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:27:02 +0400 Subject: [PATCH 10/23] remove sudo for runners --- .github/actions/project-setup/action.yml | 4 ++-- .github/workflows/release.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index 88ba0f2..b22d6c0 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -21,8 +21,8 @@ runs: if: runner.os == 'Linux' shell: bash run: | - sudo apt-get update - sudo apt-get install -y \ + apt-get update + apt-get install -y \ protobuf-compiler \ libssl-dev \ pkg-config \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6487555..ad28a9c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,6 +97,8 @@ jobs: publish-encoderfile: needs: create-tag runs-on: ubuntu-24.04 + container: + image: debian:bookworm steps: - uses: actions/checkout@v4 From b46bfcc25fe47e7b563a532ee7ff798e774a8fe0 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:30:33 +0400 Subject: [PATCH 11/23] ci: remove sudo for runners --- .github/actions/project-setup/action.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index b22d6c0..9ba418b 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -21,8 +21,14 @@ runs: if: runner.os == 'Linux' shell: bash run: | - apt-get update - apt-get install -y \ + if command -v sudo >/dev/null 2>&1; then + SUDO=sudo + else + SUDO= + fi + + $SUDO apt-get update + $SUDO apt-get install -y \ protobuf-compiler \ libssl-dev \ pkg-config \ @@ -31,7 +37,9 @@ runs: zlib1g-dev \ libdw-dev \ binutils-dev \ - libelf-dev + libelf-dev \ + ca-certificates \ + build-essential # macOS deps (Homebrew) - name: Install system dependencies (macOS) From b259667e9febbea9ba18d35dcf9dbf1e398ca0d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:31:51 +0400 Subject: [PATCH 12/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-beta.11=20(#229)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.10 to 0.4.0-beta.11. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 4 ++-- encoderfile-runtime/Cargo.toml | 4 ++-- encoderfile/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5b8d67..381b0b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.10" +version = "0.4.0-beta.11" dependencies = [ "anyhow", "axum", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.10" +version = "0.4.0-beta.11" dependencies = [ "anyhow", "clap", diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index 7a0797d..b7f0bf4 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.10" +version = "0.4.0-beta.11" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.10" +version = "0.4.0-beta.11" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index fa4e1ce..d1c3dad 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -49,7 +49,7 @@ required-features = ["dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.10" +version = "0.4.0-beta.11" edition = "2024" license = "Apache-2.0" readme = "../README.md" From 52c566e3696005e25f0121add7ad65087307b5e8 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:38:17 +0400 Subject: [PATCH 13/23] ci: update python deps --- .github/actions/project-setup/action.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index 9ba418b..ab0a049 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -62,11 +62,20 @@ runs: toolchain: ${{ inputs.toolchain }} target: ${{ inputs.target }} - # Python + # Python Native runners (macOS, non-container Linux) - uses: actions/setup-python@v5 + if: runner.os != 'Linux' with: python-version: "3.13" + # Python Container Linux + - name: Install Python (container) + shell: bash + if: runner.os == 'Linux' + run: | + apt-get update + apt-get install -y python3 python3-venv python3-pip + # ----- Universal steps ----- - name: Install uv From db9652752327c280553b8339206505564dd69003 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:40:06 +0400 Subject: [PATCH 14/23] ci: update python deps --- .github/actions/project-setup/action.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index ab0a049..fed55bc 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -73,8 +73,13 @@ runs: shell: bash if: runner.os == 'Linux' run: | - apt-get update - apt-get install -y python3 python3-venv python3-pip + if command -v sudo >/dev/null 2>&1; then + SUDO=sudo + else + SUDO= + fi + $SUDO apt-get update + $SUDO apt-get install -y python3 python3-venv python3-pip # ----- Universal steps ----- From ce1b22e0ccf158c227d1612a355cdbf5731f83e7 Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Mon, 12 Jan 2026 20:50:52 +0400 Subject: [PATCH 15/23] ci: reset release.yml --- .github/actions/project-setup/action.yml | 51 ++---- .github/workflows/release.yml | 204 +++++------------------ 2 files changed, 57 insertions(+), 198 deletions(-) diff --git a/.github/actions/project-setup/action.yml b/.github/actions/project-setup/action.yml index fed55bc..4291282 100644 --- a/.github/actions/project-setup/action.yml +++ b/.github/actions/project-setup/action.yml @@ -14,6 +14,17 @@ inputs: runs: using: "composite" steps: + # Rust toolchain + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ inputs.toolchain }} + target: ${{ inputs.target }} + + # Python + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + # ----- OS-Specific System Dependencies ----- # Linux deps @@ -21,25 +32,16 @@ runs: if: runner.os == 'Linux' shell: bash run: | - if command -v sudo >/dev/null 2>&1; then - SUDO=sudo - else - SUDO= - fi - - $SUDO apt-get update - $SUDO apt-get install -y \ + sudo apt-get update + sudo apt-get install -y \ protobuf-compiler \ libssl-dev \ pkg-config \ cmake \ - curl \ zlib1g-dev \ libdw-dev \ binutils-dev \ - libelf-dev \ - ca-certificates \ - build-essential + libelf-dev # macOS deps (Homebrew) - name: Install system dependencies (macOS) @@ -56,31 +58,6 @@ runs: libelf \ binutils || true # binutils conflicts with Apple toolchain, so ignore failure - # Rust toolchain - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: ${{ inputs.toolchain }} - target: ${{ inputs.target }} - - # Python Native runners (macOS, non-container Linux) - - uses: actions/setup-python@v5 - if: runner.os != 'Linux' - with: - python-version: "3.13" - - # Python Container Linux - - name: Install Python (container) - shell: bash - if: runner.os == 'Linux' - run: | - if command -v sudo >/dev/null 2>&1; then - SUDO=sudo - else - SUDO= - fi - $SUDO apt-get update - $SUDO apt-get install -y python3 python3-venv python3-pip - # ----- Universal steps ----- - name: Install uv diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ad28a9c..4991c60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,33 +55,33 @@ jobs: run: | # 1) If manual workflow_dispatch override given, use that if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && \ - [[ -n "${{ github.event.inputs.version_override }}" ]]; then - VERSION="${{ github.event.inputs.version_override }}" - PRE="false" - echo "Using manual override: $VERSION" - + [[ -n "${{ github.event.inputs.version_override }}" ]]; then + VERSION="${{ github.event.inputs.version_override }}" + PRE="false" + echo "Using manual override: $VERSION" else - # 2) Extract version from Cargo metadata - VERSION=$( - cargo metadata --no-deps --format-version=1 \ - | jq -r '.packages[] - | select(.name == "encoderfile") - | .version' - ) - - [ -n "$VERSION" ] || { echo "encoderfile not found"; exit 1; } - - # 3) Determine prerelease type from PR labels - if [[ "${{ contains(github.event.pull_request.labels.*.name, 'beta') }}" == "true" ]] || \ - [[ "${{ contains(github.event.pull_request.labels.*.name, 'rc') }}" == "true" ]]; then + # 2) Extract version from pyproject.toml or Cargo.toml + if [ -f "pyproject.toml" ]; then + VERSION=$(grep '^version = "' pyproject.toml | cut -d'"' -f2) + elif [ -f "ptolemy-py/Cargo.toml" ]; then + VERSION=$(grep '^version = "' ptolemy-py/Cargo.toml | head -1 | cut -d'"' -f2 | sed 's/+.*//') + else + echo "Could not find version file." + exit 1 + fi + + # 3) Determine prerelease type + if [[ "${{ contains(github.event.pull_request.labels.*.name, 'beta') }}" == "true" ]]; then + PRE="true" + elif [[ "${{ contains(github.event.pull_request.labels.*.name, 'rc') }}" == "true" ]]; then PRE="true" else PRE="false" fi fi - echo "VERSION=${VERSION}" >> "$GITHUB_OUTPUT" - echo "PRERELEASE=${PRE}" >> "$GITHUB_OUTPUT" + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT + echo "PRERELEASE=${PRE}" >> $GITHUB_OUTPUT - name: Create tag if missing run: | @@ -94,126 +94,56 @@ jobs: git push origin "v${VERSION}" fi - publish-encoderfile: + publish-encoderfile-core: needs: create-tag runs-on: ubuntu-24.04 - container: - image: debian:bookworm steps: - uses: actions/checkout@v4 - name: Project setup uses: ./.github/actions/project-setup - - name: Cargo publish (dry-run) - run: cargo publish -p encoderfile --dry-run + - name: Publish encoderfile-core (dry-run) + run: cargo publish -p encoderfile-core --dry-run - - name: Cargo publish - run: cargo publish -p encoderfile + - name: Publish encoderfile-core env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish -p encoderfile-core - upload-install-script: - needs: create-tag - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - name: Upload artifact + - name: Wait for crates.io index + run: sleep 30 - uses: actions/upload-artifact@v4 - with: - name: install - path: install.sh - - build-encoderfile-runtime-macos: - needs: create-tag - runs-on: ${{ matrix.platform.runner }} - strategy: - matrix: - platform: - - runner: macos-14 - target: x86_64-apple-darwin - - runner: macos-14 - target: aarch64-apple-darwin + publish-encoderfile: + needs: publish-encoderfile-core + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Project setup uses: ./.github/actions/project-setup - - name: Install target - run: rustup target add ${{ matrix.platform.target }} - - - name: Build - run: cargo build --bin encoderfile-runtime --release --target ${{ matrix.platform.target }} - - - name: Create release tarball - run: | - VERSION="${{ needs.create-tag.outputs.version }}" - TARGET="${{ matrix.platform.target }}" - mkdir -p dist - - cp target/${TARGET}/release/encoderfile-runtime dist/encoderfile-runtime - cp README.md dist/README.md - cp LICENSE dist/LICENSE - test -f THIRDPARTY.md && cp THIRDPARTY.md dist/THIRDPARTY.md - - TAR="encoderfile-runtime-${TARGET}.tar.gz" - tar -czf "$TAR" -C dist . - echo "Created $TAR" + - name: Cargo publish (dry-run) + run: cargo publish -p encoderfile --dry-run - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: encoderfile-runtime-${{ matrix.platform.target }} - path: encoderfile-runtime-${{ matrix.platform.target }}.tar.gz + - name: Cargo publish + run: cargo publish -p encoderfile + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - build-encoderfile-runtime-linux: + upload-install-script: needs: create-tag - runs-on: ${{ matrix.platform.runner }} - container: - image: debian:bookworm - strategy: - matrix: - platform: - - runner: ubuntu-24.04 - target: x86_64-unknown-linux-gnu - - runner: ubuntu-24.04-arm - target: aarch64-unknown-linux-gnu + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - - name: Project setup - uses: ./.github/actions/project-setup - - - name: Install target - run: rustup target add ${{ matrix.platform.target }} - - - name: Build - run: cargo build --bin encoderfile-runtime --release --target ${{ matrix.platform.target }} - - - name: Create release tarball - run: | - VERSION="${{ needs.create-tag.outputs.version }}" - TARGET="${{ matrix.platform.target }}" - mkdir -p dist - - cp target/${TARGET}/release/encoderfile-runtime dist/encoderfile-runtime - cp README.md dist/README.md - cp LICENSE dist/LICENSE - test -f THIRDPARTY.md && cp THIRDPARTY.md dist/THIRDPARTY.md - - TAR="encoderfile-runtime-${TARGET}.tar.gz" - tar -czf "$TAR" -C dist . - echo "Created $TAR" - - name: Upload artifact + uses: actions/upload-artifact@v4 with: - name: encoderfile-runtime-${{ matrix.platform.target }} - path: encoderfile-runtime-${{ matrix.platform.target }}.tar.gz + name: install + path: install.sh - build-encoderfile-macos: + build-encoderfile: needs: create-tag runs-on: ${{ matrix.platform.runner }} strategy: @@ -223,47 +153,6 @@ jobs: target: x86_64-apple-darwin - runner: macos-14 target: aarch64-apple-darwin - steps: - - uses: actions/checkout@v4 - - - name: Project setup - uses: ./.github/actions/project-setup - - - name: Install target - run: rustup target add ${{ matrix.platform.target }} - - - name: Build - run: cargo build --bin encoderfile --release --target ${{ matrix.platform.target }} - - - name: Create release tarball - run: | - VERSION="${{ needs.create-tag.outputs.version }}" - TARGET="${{ matrix.platform.target }}" - mkdir -p dist - - cp target/${TARGET}/release/encoderfile dist/encoderfile - cp README.md dist/README.md - cp LICENSE dist/LICENSE - test -f THIRDPARTY.md && cp THIRDPARTY.md dist/THIRDPARTY.md - - TAR="encoderfile-${TARGET}.tar.gz" - tar -czf "$TAR" -C dist . - echo "Created $TAR" - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: encoderfile-${{ matrix.platform.target }} - path: encoderfile-${{ matrix.platform.target }}.tar.gz - - build-encoderfile-linux: - needs: create-tag - runs-on: ${{ matrix.platform.runner }} - container: - image: debian:bookworm - strategy: - matrix: - platform: - runner: ubuntu-24.04 target: x86_64-unknown-linux-gnu - runner: ubuntu-24.04-arm @@ -302,14 +191,7 @@ jobs: path: encoderfile-${{ matrix.platform.target }}.tar.gz create-release: - needs: - - create-tag - - build-encoderfile-linux - - build-encoderfile-macos - - publish-encoderfile - - upload-install-script - - build-encoderfile-runtime-linux - - build-encoderfile-runtime-macos + needs: [create-tag, build-encoderfile, publish-encoderfile, upload-install-script] runs-on: ubuntu-latest steps: - name: Download all artifacts From a8785106e2296f620e110e432c1161f6bef1ff8f Mon Sep 17 00:00:00 2001 From: Raz Besaleli <80226248+besaleli@users.noreply.github.com> Date: Tue, 13 Jan 2026 00:40:37 +0400 Subject: [PATCH 16/23] ci(release): Update release.yml (#230) --- .github/workflows/release.yml | 317 +++++++++++++++++----------------- Dockerfile | 3 +- 2 files changed, 161 insertions(+), 159 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4991c60..94a7013 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,13 +3,15 @@ name: release on: pull_request: types: [closed] - branches: - - main + branches: [main] + workflow_dispatch: inputs: - version_override: - description: "Manually specify the release version (e.g. 1.2.3)" - required: false + dry_run: + description: Dry run + required: true + default: true + type: boolean permissions: contents: write @@ -17,201 +19,185 @@ permissions: id-token: write jobs: + compute-dry-run: + runs-on: ubuntu-latest + outputs: + is_dry_run: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' }} + + steps: + - name: Compute effective dry-run + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ] \ + && [ "${{ github.event.inputs.dry_run }}" = "true" ]; then + echo "Running in DRY-RUN mode" + else + echo "Running in LIVE mode" + fi + create-tag: if: > github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && - github.event.pull_request.merged == true && - (contains(github.event.pull_request.labels.*.name, 'beta') || - contains(github.event.pull_request.labels.*.name, 'rc') || - contains(github.event.pull_request.labels.*.name, 'release') || - contains(github.event.pull_request.labels.*.name, 'patch') || - contains(github.event.pull_request.labels.*.name, 'minor') || - contains(github.event.pull_request.labels.*.name, 'major'))) + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) runs-on: ubuntu-latest + needs: ["compute-dry-run"] outputs: - version: ${{ steps.versioning.outputs.VERSION }} - prerelease: ${{ steps.versioning.outputs.PRERELEASE }} + version: ${{ steps.version.outputs.VERSION }} + prerelease: ${{ steps.version.outputs.PRERELEASE }} steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Set up Git - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" + - uses: actions/checkout@v4 + with: { fetch-depth: 0 } - name: Determine version - id: versioning + id: version run: | - # 1) If manual workflow_dispatch override given, use that - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && \ - [[ -n "${{ github.event.inputs.version_override }}" ]]; then - VERSION="${{ github.event.inputs.version_override }}" - PRE="false" - echo "Using manual override: $VERSION" - else - # 2) Extract version from pyproject.toml or Cargo.toml - if [ -f "pyproject.toml" ]; then - VERSION=$(grep '^version = "' pyproject.toml | cut -d'"' -f2) - elif [ -f "ptolemy-py/Cargo.toml" ]; then - VERSION=$(grep '^version = "' ptolemy-py/Cargo.toml | head -1 | cut -d'"' -f2 | sed 's/+.*//') - else - echo "Could not find version file." - exit 1 - fi + set -euo pipefail + + # Extract version from Cargo metadata + VERSION=$( + cargo metadata --no-deps --format-version=1 \ + | jq -r '.packages[] + | select(.name == "encoderfile") + | .version' + ) + + if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then + echo "encoderfile package not found in cargo metadata" + exit 1 + fi - # 3) Determine prerelease type - if [[ "${{ contains(github.event.pull_request.labels.*.name, 'beta') }}" == "true" ]]; then - PRE="true" - elif [[ "${{ contains(github.event.pull_request.labels.*.name, 'rc') }}" == "true" ]]; then + # Determine prerelease (PRs only) + PRE="false" + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + if [[ "${{ contains(github.event.pull_request.labels.*.name, 'alpha') }}" == "true" ]] || \ + [[ "${{ contains(github.event.pull_request.labels.*.name, 'beta') }}" == "true" ]] || \ + [[ "${{ contains(github.event.pull_request.labels.*.name, 'rc') }}" == "true" ]]; then PRE="true" - else - PRE="false" fi fi - echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - echo "PRERELEASE=${PRE}" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" + echo "PRERELEASE=$PRE" >> "$GITHUB_OUTPUT" - - name: Create tag if missing - run: | - VERSION="${{ steps.versioning.outputs.VERSION }}" - if git rev-parse "v${VERSION}" >/dev/null 2>&1; then - echo "Tag v${VERSION} already exists." - else - git tag -a "v${VERSION}" -m "Version ${VERSION}" - git push origin "v${VERSION}" - fi - - publish-encoderfile-core: - needs: create-tag - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - - name: Project setup - uses: ./.github/actions/project-setup + - name: Create git tag + if: needs.compute-dry-run.outputs.is_dry_run != 'true' + run: | + VERSION=${{ steps.version.outputs.VERSION }} + git tag -a "v$VERSION" -m "Version $VERSION" || true + git push origin "v$VERSION" || true - - name: Publish encoderfile-core (dry-run) - run: cargo publish -p encoderfile-core --dry-run + - name: Dry-run tag + if: needs.compute-dry-run.outputs.is_dry_run == 'true' + run: echo "[DRY RUN] would create tag v${{ steps.version.outputs.VERSION }}" - - name: Publish encoderfile-core - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish -p encoderfile-core - - - name: Wait for crates.io index - run: sleep 30 + build-macos: + needs: [create-tag, compute-dry-run] + runs-on: macos-14 + strategy: + matrix: + target: + - x86_64-apple-darwin + - aarch64-apple-darwin - publish-encoderfile: - needs: publish-encoderfile-core - runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 + - uses: ./.github/actions/project-setup - - name: Project setup - uses: ./.github/actions/project-setup - - - name: Cargo publish (dry-run) - run: cargo publish -p encoderfile --dry-run - - - name: Cargo publish - run: cargo publish -p encoderfile - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + - run: rustup target add ${{ matrix.target }} - upload-install-script: - needs: create-tag - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - name: Upload artifact + - name: Build + run: | + cargo build --release --target ${{ matrix.target }} + mkdir -p dist + cp target/${{ matrix.target }}/release/encoderfile dist/ + cp target/${{ matrix.target }}/release/encoderfile-runtime dist/ - uses: actions/upload-artifact@v4 + - name: Package + run: | + mkdir pkg + cp dist/* README.md LICENSE pkg/ + test -f THIRDPARTY.md && cp THIRDPARTY.md pkg/ + tar -czf encoderfile-${{ matrix.target }}.tar.gz -C pkg . + tar -czf encoderfile-runtime-${{ matrix.target }}.tar.gz -C pkg . + + - uses: actions/upload-artifact@v4 + if: needs.compute-dry-run.outputs.is_dry_run != 'true' with: - name: install - path: install.sh + name: macos-${{ matrix.target }} + path: "*.tar.gz" + + build-linux: + needs: [create-tag, compute-dry-run] + runs-on: ${{ matrix.runner }} - build-encoderfile: - needs: create-tag - runs-on: ${{ matrix.platform.runner }} strategy: + fail-fast: false matrix: - platform: - - runner: macos-14 - target: x86_64-apple-darwin - - runner: macos-14 - target: aarch64-apple-darwin - - runner: ubuntu-24.04 + include: + - arch: amd64 + platform: linux/amd64 + runner: ubuntu-latest target: x86_64-unknown-linux-gnu - - runner: ubuntu-24.04-arm + - arch: arm64 + platform: linux/arm64 + runner: ubuntu-24.04-arm target: aarch64-unknown-linux-gnu + steps: - uses: actions/checkout@v4 - - name: Project setup - uses: ./.github/actions/project-setup - - - name: Install target - run: rustup target add ${{ matrix.platform.target }} - - - name: Build - run: cargo build --bin encoderfile --release --target ${{ matrix.platform.target }} - - - name: Create release tarball + - name: Build (bookworm, ${{ matrix.arch }}) run: | - VERSION="${{ needs.create-tag.outputs.version }}" - TARGET="${{ matrix.platform.target }}" + docker build \ + -f Dockerfile \ + --target build \ + --load \ + -t encoderfile-build:${{ matrix.arch }} \ + . + + CID=$(docker create encoderfile-build:${{ matrix.arch }}) mkdir -p dist + docker cp "$CID:/app/target/release/encoderfile" dist/ + docker cp "$CID:/app/target/release/encoderfile-runtime" dist/ + docker rm "$CID" - cp target/${TARGET}/release/encoderfile dist/encoderfile - cp README.md dist/README.md - cp LICENSE dist/LICENSE - test -f THIRDPARTY.md && cp THIRDPARTY.md dist/THIRDPARTY.md + - name: Package + run: | + mkdir pkg + cp dist/* README.md LICENSE pkg/ + test -f THIRDPARTY.md && cp THIRDPARTY.md pkg/ - TAR="encoderfile-${TARGET}.tar.gz" - tar -czf "$TAR" -C dist . - echo "Created $TAR" + tar -czf encoderfile-${{ matrix.target }}.tar.gz -C pkg . + tar -czf encoderfile-runtime-${{ matrix.target }}.tar.gz -C pkg . - - name: Upload artifact - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v4 + if: needs.compute-dry-run.outputs.is_dry_run != 'true' with: - name: encoderfile-${{ matrix.platform.target }} - path: encoderfile-${{ matrix.platform.target }}.tar.gz + name: linux-${{ matrix.arch }} + path: "*.tar.gz" - create-release: - needs: [create-tag, build-encoderfile, publish-encoderfile, upload-install-script] + release: + needs: [create-tag, build-macos, build-linux, compute-dry-run] runs-on: ubuntu-latest + steps: - - name: Download all artifacts - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v4 with: path: dist - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + - uses: softprops/action-gh-release@v2 + if: needs.compute-dry-run.outputs.is_dry_run != 'true' with: tag_name: v${{ needs.create-tag.outputs.version }} name: v${{ needs.create-tag.outputs.version }} prerelease: ${{ needs.create-tag.outputs.prerelease }} - files: | - dist/**/*.tar.gz - dist/install/install.sh + files: dist/**/*.tar.gz generate_release_notes: true docker-build: - needs: [create-release, create-tag] + needs: [release, create-tag, compute-dry-run] runs-on: ${{ matrix.runner }} strategy: fail-fast: false @@ -227,8 +213,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Log in to GHCR - uses: docker/login-action@v3 + - uses: docker/login-action@v3 + if: needs.compute-dry-run.outputs.is_dry_run != 'true' with: registry: ghcr.io username: ${{ github.actor }} @@ -242,40 +228,57 @@ jobs: . - name: Push image + if: needs.compute-dry-run.outputs.is_dry_run != 'true' run: | - docker push ghcr.io/${{ github.repository_owner }}/encoderfile:${{ matrix.arch }}-${{ needs.create-tag.outputs.version }} + docker push \ + ghcr.io/${{ github.repository_owner }}/encoderfile:${{ matrix.arch }}-${{ needs.create-tag.outputs.version }} docker-manifest: - needs: [docker-build, create-tag] + needs: [docker-build, create-tag, compute-dry-run] + runs-on: ubuntu-latest steps: - - name: Set up Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - - name: Log in to GHCR - uses: docker/login-action@v3 + - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ github.token }} - - name: Create multi-arch manifest + - name: Bundle dockerfiles + if: needs.compute-dry-run.outputs.is_dry_run != 'true' run: | VERSION=${{ needs.create-tag.outputs.version }} PRE=${{ needs.create-tag.outputs.prerelease }} if [[ "$PRE" == "true" ]]; then - echo "Prerelease detected — skipping latest tag" docker buildx imagetools create \ -t ghcr.io/${{ github.repository_owner }}/encoderfile:${VERSION} \ ghcr.io/${{ github.repository_owner }}/encoderfile:amd64-${VERSION} \ ghcr.io/${{ github.repository_owner }}/encoderfile:arm64-${VERSION} else - echo "Stable release — tagging latest" docker buildx imagetools create \ -t ghcr.io/${{ github.repository_owner }}/encoderfile:${VERSION} \ -t ghcr.io/${{ github.repository_owner }}/encoderfile:latest \ ghcr.io/${{ github.repository_owner }}/encoderfile:amd64-${VERSION} \ ghcr.io/${{ github.repository_owner }}/encoderfile:arm64-${VERSION} fi + + publish-encoderfile: + needs: [release, compute-dry-run] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/project-setup + + - name: Cargo publish (dry-run) + run: cargo publish -p encoderfile --dry-run + + - name: Cargo publish + if: needs.compute-dry-run.outputs.is_dry_run != 'true' + run: cargo publish -p encoderfile + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/Dockerfile b/Dockerfile index e81b260..0134872 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,8 +36,7 @@ COPY encoderfile ./encoderfile COPY encoderfile-runtime ./encoderfile-runtime # Build release binary. -RUN cargo build --bin encoderfile --release - +RUN cargo build --release # ---- Final stage ------------------------------------------------------------ FROM debian:bookworm-slim AS final From c8cf66ab94929bb1b299d38dcb2051ee2ca80bbb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 00:42:02 +0400 Subject: [PATCH 17/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-beta.12=20(#231)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.11 to 0.4.0-beta.12. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 8 ++++---- encoderfile-runtime/Cargo.toml | 4 ++-- encoderfile/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 381b0b8..a350f6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.11" +version = "0.4.0-beta.12" dependencies = [ "anyhow", "axum", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.11" +version = "0.4.0-beta.12" dependencies = [ "anyhow", "clap", @@ -3620,9 +3620,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index b7f0bf4..aa56696 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.11" +version = "0.4.0-beta.12" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.11" +version = "0.4.0-beta.12" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index d1c3dad..319e9a5 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -49,7 +49,7 @@ required-features = ["dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.11" +version = "0.4.0-beta.12" edition = "2024" license = "Apache-2.0" readme = "../README.md" From 70613f40792c250119ad28695674adb9214bfe0e Mon Sep 17 00:00:00 2001 From: Raz Besaleli <80226248+besaleli@users.noreply.github.com> Date: Wed, 14 Jan 2026 17:25:55 +0400 Subject: [PATCH 18/23] ci: update cargo goose workflows to use action (#237) --- .github/workflows/release.yml | 44 +++++---------------- .github/workflows/version.yml | 74 ++++++++++++++++------------------- 2 files changed, 43 insertions(+), 75 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 94a7013..d34ff62 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,55 +42,29 @@ jobs: needs: ["compute-dry-run"] outputs: - version: ${{ steps.version.outputs.VERSION }} - prerelease: ${{ steps.version.outputs.PRERELEASE }} + version: ${{ steps.version.outputs.version }} + prerelease: ${{ steps.version.outputs.is_prerelease == 'true' }} steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } - - - name: Determine version + + - name: Get current version id: version - run: | - set -euo pipefail - - # Extract version from Cargo metadata - VERSION=$( - cargo metadata --no-deps --format-version=1 \ - | jq -r '.packages[] - | select(.name == "encoderfile") - | .version' - ) - - if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then - echo "encoderfile package not found in cargo metadata" - exit 1 - fi - - # Determine prerelease (PRs only) - PRE="false" - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - if [[ "${{ contains(github.event.pull_request.labels.*.name, 'alpha') }}" == "true" ]] || \ - [[ "${{ contains(github.event.pull_request.labels.*.name, 'beta') }}" == "true" ]] || \ - [[ "${{ contains(github.event.pull_request.labels.*.name, 'rc') }}" == "true" ]]; then - PRE="true" - fi - fi - - echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" - echo "PRERELEASE=$PRE" >> "$GITHUB_OUTPUT" - + uses: mozilla-ai/cargo-goose/actions/current-version@v1 + with: + force-single-version: true - name: Create git tag if: needs.compute-dry-run.outputs.is_dry_run != 'true' run: | - VERSION=${{ steps.version.outputs.VERSION }} + VERSION=${{ steps.version.outputs.version }} git tag -a "v$VERSION" -m "Version $VERSION" || true git push origin "v$VERSION" || true - name: Dry-run tag if: needs.compute-dry-run.outputs.is_dry_run == 'true' - run: echo "[DRY RUN] would create tag v${{ steps.version.outputs.VERSION }}" + run: echo "[DRY RUN] would create tag v${{ steps.version.outputs.version }}" build-macos: needs: [create-tag, compute-dry-run] diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index d3dc7f4..7f9cef1 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -67,26 +67,15 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - - name: Setup project - uses: ./.github/actions/project-setup - - - name: Install cargo-goose - run: cargo install cargo-goose - + - name: Get current version id: current_version - run: | - VERSION=$(cargo metadata --no-deps --format-version=1 \ - | jq -r '.packages[] - | select(.name == "encoderfile") - | .version') - - [ -n "$VERSION" ] || { echo "encoderfile not found"; exit 1; } - - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - - - name: Bump version + uses: mozilla-ai/cargo-goose/actions/current-version@v1 + with: + force-single-version: true + + - name: Compute cargo-goose args + id: goose_args run: | ACTION="${{ github.event.inputs.action }}" LEVEL="${{ github.event.inputs.level }}" @@ -94,33 +83,38 @@ jobs: case "$ACTION" in bump-version) - cargo goose bump version "$LEVEL" + ARGS="bump version $LEVEL" ;; start-prerelease) - cargo goose bump version "$LEVEL" "$STAGE" + ARGS="bump version $LEVEL $STAGE" ;; bump-prerelease) - cargo goose bump prerelease + ARGS="bump prerelease" ;; transition-prerelease) - cargo goose bump prerelease "$STAGE" + ARGS="bump prerelease $STAGE" ;; finalize) - cargo goose bump release + ARGS="bump release" + ;; + *) + echo "Invalid action" + exit 1 ;; esac - - name: Get new version - id: new_version - run: | - VERSION=$(cargo metadata --no-deps --format-version=1 \ - | jq -r '.packages[] - | select(.name == "encoderfile") - | .version') + echo "args=$ARGS" >> "$GITHUB_OUTPUT" - [ -n "$VERSION" ] || { echo "encoderfile not found"; exit 1; } + - name: Bump version + uses: mozilla-ai/cargo-goose/actions/cargo-goose@v1 + with: + args: ${{ steps.goose_args.outputs.args }} - echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Get new version + id: new_version + uses: mozilla-ai/cargo-goose/actions/current-version@v1 + with: + force-single-version: true - name: Abort if version did not change run: | @@ -133,20 +127,20 @@ jobs: - name: Update Cargo.lock run: cargo generate-lockfile - - name: Generate PR labels + - name: Generate labels id: labels run: | ACTION="${{ github.event.inputs.action }}" LEVEL="${{ github.event.inputs.level }}" - STAGE="${{ github.event.inputs.stage }}" - - LABELS="auto-generated\nversion-bump\n$ACTION" + IS_PRE="${{ steps.new_version.outputs.is_prerelease }}" + PRE="${{ steps.new_version.outputs.pre }}" - [ -n "$LEVEL" ] && LABELS="$LABELS\n$LEVEL" - [ -n "$STAGE" ] && LABELS="$LABELS\n$STAGE\nprerelease" + LABELS="version-bump\nauto-generated\n$ACTION" - if [ "$ACTION" = "finalize" ]; then - LABELS="$LABELS\nrelease" + if [ "$IS_PRE" = "true" ]; then + LABELS="$LABELS\nprerelease\n$PRE" + else + [ -n "$LEVEL" ] && LABELS="$LABELS\n$LEVEL" fi echo "labels<> "$GITHUB_OUTPUT" From a1583c3e2c59fe4f9ebf1678c6319a1cf686f658 Mon Sep 17 00:00:00 2001 From: Raz Besaleli <80226248+besaleli@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:08:31 +0200 Subject: [PATCH 19/23] ci: only run benchmarks selectively (#244) --- .github/workflows/benchmark.yml | 71 +++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 49 ----------------------- 2 files changed, 71 insertions(+), 49 deletions(-) create mode 100644 .github/workflows/benchmark.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 0000000..62ad303 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,71 @@ +name: benchmark + +on: + push: + branches: [main] + paths-ignore: + - .github/** + - docs/** + - CONTRIBUTING.md + - CODE_OF_CONDUCT.md + - README.md + - mkdocs.yml + - examples/** + - .vscode/** + - scripts/** + pull_request: + types: [opened, reopened, labeled, unlabeled] + workflow_dispatch: + +jobs: + run_benchmarks: + runs-on: ubuntu-latest + if: > + contains(github.event.pull_request.labels.*.name, 'benchmark') || + github.event_name == 'workflow_dispatch' + + steps: + - uses: actions/checkout@v4 + + # - name: Cache cargo + # uses: actions/cache@v4 + # with: + # path: | + # ~/.cargo/registry + # ~/.cargo/git + # target + # key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + # - name: Cargo clean if target too large + # run: make clean + + - name: Cache uv + uses: actions/cache@v4 + with: + path: ~/.cache/uv + key: ${{ runner.os }}-uv-${{ hashFiles('pyproject.toml') }} + + # - name: Cache cargo binaries + # uses: actions/cache@v4 + # with: + # path: ~/.cargo/bin + # key: ${{ runner.os }}-cargo-bins + + - name: Project setup + uses: ./.github/actions/project-setup + + - name: Install test dependencies + run: make setup + + - name: Install codspeed + run: cargo binstall cargo-codspeed --no-confirm --force + + - name: Build the benchmark target(s) + run: cargo codspeed build --all-features + + - name: Run the benchmarks + uses: CodSpeedHQ/action@v4 + with: + mode: simulation + run: cargo codspeed run + token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9002432..b48b81c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,55 +27,6 @@ on: workflow_dispatch: jobs: - run_benchmarks: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - # - name: Cache cargo - # uses: actions/cache@v4 - # with: - # path: | - # ~/.cargo/registry - # ~/.cargo/git - # target - # key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - # - name: Cargo clean if target too large - # run: make clean - - - name: Cache uv - uses: actions/cache@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-uv-${{ hashFiles('pyproject.toml') }} - - # - name: Cache cargo binaries - # uses: actions/cache@v4 - # with: - # path: ~/.cargo/bin - # key: ${{ runner.os }}-cargo-bins - - - name: Project setup - uses: ./.github/actions/project-setup - - - name: Install test dependencies - run: make setup - - - name: Install codspeed - run: cargo binstall cargo-codspeed --no-confirm --force - - - name: Build the benchmark target(s) - run: cargo codspeed build --all-features - - - name: Run the benchmarks - uses: CodSpeedHQ/action@v4 - with: - mode: simulation - run: cargo codspeed run - token: ${{ secrets.CODSPEED_TOKEN }} - run_unit_tests: runs-on: ubuntu-latest From 18c9ac0a5da73c6d05b61c229ff08870777d552c Mon Sep 17 00:00:00 2001 From: Raz Besaleli <80226248+besaleli@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:39:51 +0200 Subject: [PATCH 20/23] tests: E2E test for building encoderfiles (#242) --- encoderfile/Cargo.toml | 5 + encoderfile/src/build_cli/cli/build.rs | 33 +++- encoderfile/src/build_cli/cli/mod.rs | 5 +- encoderfile/tests/integration/test_build.rs | 176 ++++++++++++++++++++ 4 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 encoderfile/tests/integration/test_build.rs diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index 319e9a5..151ec96 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -47,6 +47,11 @@ required-features = ["dev-utils"] name = "test_services" required-features = ["dev-utils"] +[[test]] +name = "test_build_encoderfile" +path = "tests/integration/test_build.rs" +required-features = ["cli", "dev-utils"] + [package] name = "encoderfile" version = "0.4.0-beta.12" diff --git a/encoderfile/src/build_cli/cli/build.rs b/encoderfile/src/build_cli/cli/build.rs index 1f91d62..189aea5 100644 --- a/encoderfile/src/build_cli/cli/build.rs +++ b/encoderfile/src/build_cli/cli/build.rs @@ -11,7 +11,7 @@ use crate::{ }, generated::manifest::Backend, }; -use anyhow::Result; +use anyhow::{Context, Result}; use std::{ borrow::Cow, fs::File, @@ -130,12 +130,22 @@ impl BuildArgs { // initialize final binary terminal::info("Writing encoderfile..."); let output_path = config.encoderfile.output_path(); - let out = File::create(output_path.clone())?; + let out = File::create(output_path.clone()).context(format!( + "Failed to create final encoderfile at {:?}", + output_path.as_path() + ))?; + let mut out = BufWriter::new(out); - let mut base = File::open(base_path)?; + let mut base = File::open(base_path.as_path()).context(format!( + "Failed to open base binary at {:?}", + base_path.as_path() + ))?; // copy base binary to out - std::io::copy(&mut base, &mut out)?; + std::io::copy(&mut base, &mut out).context(format!( + "Failed to copy base binary to {:?}", + output_path.as_path() + ))?; // get metadata start position let payload_start = out.stream_position()?; @@ -163,3 +173,18 @@ impl BuildArgs { Ok(()) } } + +#[cfg(feature = "dev-utils")] +pub fn test_build_args( + config: impl Into, + base_binary_path: impl Into, +) -> BuildArgs { + BuildArgs { + config: config.into(), + output_path: None, + base_binary_path: Some(base_binary_path.into()), + platform: None, + version: None, + no_download: true, + } +} diff --git a/encoderfile/src/build_cli/cli/mod.rs b/encoderfile/src/build_cli/cli/mod.rs index 61312be..1752e78 100644 --- a/encoderfile/src/build_cli/cli/mod.rs +++ b/encoderfile/src/build_cli/cli/mod.rs @@ -6,6 +6,9 @@ use clap_derive::{Args, Parser, Subcommand}; mod build; mod runtime; +#[cfg(feature = "dev-utils")] +pub use build::test_build_args; + #[derive(Debug, Parser)] pub struct Cli { #[command(subcommand)] @@ -15,7 +18,7 @@ pub struct Cli { pub global_args: GlobalArguments, } -#[derive(Debug, Clone, Args)] +#[derive(Debug, Default, Clone, Args)] pub struct GlobalArguments { #[arg( long = "cache-dir", diff --git a/encoderfile/tests/integration/test_build.rs b/encoderfile/tests/integration/test_build.rs new file mode 100644 index 0000000..f6a9577 --- /dev/null +++ b/encoderfile/tests/integration/test_build.rs @@ -0,0 +1,176 @@ +use anyhow::{Context, Result, bail}; + +use encoderfile::build_cli::cli::GlobalArguments; +use std::{ + fs, + path::Path, + process::{Child, Command}, + thread::sleep, + time::{Duration, Instant}, +}; +use tempfile::tempdir; + +const BINARY_NAME: &str = "test.encoderfile"; + +fn config(model_path: &Path, output_path: &Path) -> String { + format!( + r##" +encoderfile: + name: test-model + path: {:?} + model_type: token_classification + output_path: {:?} + transform: | + --- Applies a softmax across token classification logits. + --- Each token classification is normalized independently. + --- + --- Args: + --- arr (Tensor): A tensor of shape [batch_size, n_tokens, n_labels]. + --- The softmax is applied along the third axis (n_labels). + --- + --- Returns: + --- Tensor: The input tensor with softmax-normalized embeddings. + ---@param arr Tensor + ---@return Tensor + function Postprocess(arr) + return arr:softmax(3) + end + "##, + model_path, output_path + ) +} + +const MODEL_ASSETS_PATH: &str = "../models/token_classification"; + +#[test] +fn test_build_encoderfile() -> Result<()> { + let dir = tempdir()?; + let path = dir + .path() + .canonicalize() + .expect("Failed to canonicalize temp path"); + + let tmp_model_path = path.join("models").join("token_classification"); + + let ef_config_path = path.join("encoderfile.yml"); + let encoderfile_path = path.join(BINARY_NAME); + + // copy model assets to temp dir + copy_dir_all(MODEL_ASSETS_PATH, tmp_model_path.as_path()) + .expect("Failed to copy model assets to temp directory"); + + if !tmp_model_path.join("model.onnx").exists() { + bail!( + "Path {:?} does not exist", + tmp_model_path.join("model.onnx") + ); + } + + // compile base binary and copy to temp dir + let _ = Command::new("cargo") + .args(["build", "-p", "encoderfile-runtime"]) + .status() + .expect("Failed to build encoderfile-runtime"); + + let base_binary_path = fs::canonicalize("../target/debug/encoderfile-runtime") + .expect("Failed to canonicalize base binary path"); + + // write encoderfile config + let config = config(tmp_model_path.as_path(), encoderfile_path.as_path()); + + fs::write(ef_config_path.as_path(), config.as_bytes()) + .expect("Failed to write encoderfile config"); + + let build_args = + encoderfile::build_cli::cli::test_build_args(ef_config_path.as_path(), base_binary_path); + + // build encoderfile + let global_args = GlobalArguments::default(); + + build_args + .run(&global_args) + .context("Failed to build encoderfile")?; + + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perms = fs::metadata(encoderfile_path.as_path()) + .expect("Failed to get path for built encoderfile") + .permissions(); + + perms.set_mode(0o755); + fs::set_permissions(encoderfile_path.as_path(), perms).expect("Failed to set permissions"); + } + + // serve encoderfile + let mut child = spawn_encoderfile( + encoderfile_path + .to_str() + .expect("Failed to create encoderfile binary path"), + )?; + + wait_for_http("http://localhost:8080/health", Duration::from_secs(10))?; + + child.kill()?; + child.wait().ok(); + + Ok(()) +} + +fn wait_for_http(url: &str, timeout: Duration) -> Result<()> { + let client = reqwest::blocking::Client::new(); + let start = Instant::now(); + + loop { + if start.elapsed() > timeout { + anyhow::bail!("server did not become ready in time"); + } + + if let Ok(resp) = client.get(url).send() + && resp.status().is_success() + { + return Ok(()); + } + + sleep(Duration::from_millis(200)); + } +} + +fn spawn_encoderfile(path: &str) -> Result { + Command::new(path) + .arg("serve") + .arg("--disable-grpc") + .arg("--http-port") + .arg("8080") + .spawn() + .context("failed to spawn encoderfile process") +} + +fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> anyhow::Result<()> { + let src = src.as_ref(); + let dst = dst.as_ref(); + + fs::create_dir_all(dst).context(format!("Failed to create directory {:?}", &dst))?; + + for entry in fs::read_dir(src)? { + let entry = entry?; + let ty = entry.file_type()?; + let dest_path = dst.join(entry.file_name()); + + if ty.is_dir() { + copy_dir_all(entry.path(), dest_path.as_path()).context(format!( + "Failed to copy {:?} to {:?}", + entry.path(), + dest_path.as_path() + ))?; + } else { + fs::copy(entry.path(), dest_path.as_path()).context(format!( + "Failed to copy {:?} to {:?}", + entry.path(), + dest_path.as_path() + ))?; + } + } + + Ok(()) +} From 60cb5ae43a91ce55edcc813169869957ae54073f Mon Sep 17 00:00:00 2001 From: Raz Besaleli <80226248+besaleli@users.noreply.github.com> Date: Sat, 24 Jan 2026 18:28:52 +0200 Subject: [PATCH 21/23] feat(refactor): Simpler serve functions (#248) --- encoderfile-runtime/src/main.rs | 16 +- encoderfile/benches/postprocessing.rs | 16 +- encoderfile/src/dev_utils/mod.rs | 16 +- encoderfile/src/runtime/mod.rs | 2 +- encoderfile/src/runtime/state.rs | 50 ++-- encoderfile/src/services/embedding.rs | 6 +- .../src/services/sentence_embedding.rs | 11 +- .../src/services/sequence_classification.rs | 6 +- encoderfile/src/transport/grpc/mod.rs | 4 +- encoderfile/src/transport/server.rs | 223 ++++++++---------- 10 files changed, 145 insertions(+), 205 deletions(-) diff --git a/encoderfile-runtime/src/main.rs b/encoderfile-runtime/src/main.rs index d569c5e..85e3971 100644 --- a/encoderfile-runtime/src/main.rs +++ b/encoderfile-runtime/src/main.rs @@ -2,19 +2,17 @@ use parking_lot::Mutex; use std::{ fs::File, io::{BufReader, Read, Seek}, - sync::Arc, }; use anyhow::Result; use clap::Parser; use encoderfile::{ - AppState, common::{ ModelType, model_type::{Embedding, SentenceEmbedding, SequenceClassification, TokenClassification}, }, format::codec::EncoderfileCodec, - runtime::EncoderfileLoader, + runtime::{EncoderfileLoader, EncoderfileState}, transport::cli::Cli, }; @@ -33,17 +31,19 @@ async fn main() -> Result<()> { macro_rules! run_cli { ($model_type:ident, $cli:expr, $config:expr, $session:expr, $tokenizer:expr, $model_config:expr) => {{ - let state = AppState::<$model_type>::new($config, $session, $tokenizer, $model_config); + let state = + EncoderfileState::<$model_type>::new($config, $session, $tokenizer, $model_config) + .into(); $cli.command.execute(state).await }}; } async fn entrypoint<'a, R: Read + Seek>(loader: &mut EncoderfileLoader<'a, R>) -> Result<()> { let cli = Cli::parse(); - let session = Arc::new(Mutex::new(loader.session()?)); - let model_config = Arc::new(loader.model_config()?); - let tokenizer = Arc::new(loader.tokenizer()?); - let config = Arc::new(loader.encoderfile_config()?); + let session = Mutex::new(loader.session()?); + let model_config = loader.model_config()?; + let tokenizer = loader.tokenizer()?; + let config = loader.encoderfile_config()?; match loader.model_type() { ModelType::Embedding => run_cli!(Embedding, cli, config, session, tokenizer, model_config), diff --git a/encoderfile/benches/postprocessing.rs b/encoderfile/benches/postprocessing.rs index 93a4cc8..dbb6681 100644 --- a/encoderfile/benches/postprocessing.rs +++ b/encoderfile/benches/postprocessing.rs @@ -16,7 +16,7 @@ fn main() { #[divan::bench(args = [(8, 16, 384), (16, 128, 768), (64, 512, 1024)])] fn embedding_postprocess(b: Bencher, dim: (usize, usize, usize)) { - let tokenizer = embedding_state().tokenizer; + let tokenizer = &embedding_state().tokenizer; let (batch, tokens, hidden) = dim; // Random embeddings @@ -27,7 +27,7 @@ fn embedding_postprocess(b: Bencher, dim: (usize, usize, usize)) { let outputs = Array::from_shape_vec((batch, tokens, hidden), data).unwrap(); // Dummy encodings - let encodings = generate_dummy_encodings(&tokenizer, batch, tokens); + let encodings = generate_dummy_encodings(tokenizer, batch, tokens); b.bench(|| embedding::postprocess(outputs.clone(), encodings.clone())); } @@ -35,7 +35,7 @@ fn embedding_postprocess(b: Bencher, dim: (usize, usize, usize)) { #[divan::bench(args = [8, 16, 64])] fn sequence_classification_postprocess(b: Bencher, batch: usize) { let state = sequence_classification_state(); - let config = state.model_config; + let config = &state.model_config; let n_labels = config.id2label.clone().unwrap().len(); let mut rng = rand::rng(); @@ -45,16 +45,16 @@ fn sequence_classification_postprocess(b: Bencher, batch: usize) { let outputs = Array::from_shape_vec((batch, n_labels), data).unwrap(); - b.bench(|| sequence_classification::postprocess(outputs.clone(), &config)); + b.bench(|| sequence_classification::postprocess(outputs.clone(), config)); } #[divan::bench(args = [(8, 16), (16, 128), (64, 512)])] fn token_classification_postprocess(b: Bencher, dim: (usize, usize)) { let state = token_classification_state(); - let config = state.model_config; + let config = &state.model_config; let n_labels = config.id2label.clone().unwrap().len(); - let tokenizer = embedding_state().tokenizer; + let tokenizer = &embedding_state().tokenizer; let (batch, tokens) = dim; // Random embeddings @@ -65,9 +65,9 @@ fn token_classification_postprocess(b: Bencher, dim: (usize, usize)) { let outputs = Array::from_shape_vec((batch, tokens, n_labels), data).unwrap(); // Dummy encodings - let encodings = generate_dummy_encodings(&tokenizer, batch, tokens); + let encodings = generate_dummy_encodings(tokenizer, batch, tokens); - b.bench(|| token_classification::postprocess(outputs.clone(), encodings.clone(), &config)); + b.bench(|| token_classification::postprocess(outputs.clone(), encodings.clone(), config)); } fn generate_dummy_encodings( diff --git a/encoderfile/src/dev_utils/mod.rs b/encoderfile/src/dev_utils/mod.rs index c875400..5c88fa1 100644 --- a/encoderfile/src/dev_utils/mod.rs +++ b/encoderfile/src/dev_utils/mod.rs @@ -3,30 +3,30 @@ use crate::{ Config, ModelConfig, TokenizerConfig, model_type::{self, ModelTypeSpec}, }, - runtime::AppState, + runtime::{AppState, EncoderfileState}, }; use ort::session::Session; use parking_lot::Mutex; use std::str::FromStr; -use std::{fs::File, io::BufReader, sync::Arc}; +use std::{fs::File, io::BufReader}; const EMBEDDING_DIR: &str = "../models/embedding"; const SEQUENCE_CLASSIFICATION_DIR: &str = "../models/sequence_classification"; const TOKEN_CLASSIFICATION_DIR: &str = "../models/token_classification"; pub fn get_state(dir: &str) -> AppState { - let config = Arc::new(Config { + let config = Config { name: "my-model".to_string(), version: "0.0.1".to_string(), model_type: T::enum_val(), transform: None, - }); + }; - let model_config = Arc::new(get_model_config(dir)); - let tokenizer = Arc::new(get_tokenizer(dir)); - let session = Arc::new(get_model(dir)); + let model_config = get_model_config(dir); + let tokenizer = get_tokenizer(dir); + let session = get_model(dir); - AppState::new(config, session, tokenizer, model_config) + EncoderfileState::new(config, session, tokenizer, model_config).into() } pub fn embedding_state() -> AppState { diff --git a/encoderfile/src/runtime/mod.rs b/encoderfile/src/runtime/mod.rs index 5ae6b81..d77ae5f 100644 --- a/encoderfile/src/runtime/mod.rs +++ b/encoderfile/src/runtime/mod.rs @@ -6,7 +6,7 @@ mod state; mod tokenizer; pub use loader::EncoderfileLoader; -pub use state::{AppState, InferenceState}; +pub use state::{AppState, EncoderfileState}; pub use tokenizer::TokenizerService; pub type Model<'a> = MutexGuard<'a, Session>; diff --git a/encoderfile/src/runtime/state.rs b/encoderfile/src/runtime/state.rs index af448f3..6b084c9 100644 --- a/encoderfile/src/runtime/state.rs +++ b/encoderfile/src/runtime/state.rs @@ -1,52 +1,32 @@ use std::{marker::PhantomData, sync::Arc}; use ort::session::Session; -use parking_lot::{Mutex, RawMutex, lock_api::MutexGuard}; +use parking_lot::Mutex; use crate::{ common::{Config, ModelConfig, ModelType, model_type::ModelTypeSpec}, runtime::TokenizerService, }; -pub trait InferenceState { - fn config(&self) -> &Arc; - fn session(&self) -> MutexGuard<'_, RawMutex, Session>; - fn tokenizer(&self) -> &Arc; - fn model_config(&self) -> &Arc; -} - -impl InferenceState for AppState { - fn config(&self) -> &Arc { - &self.config - } - fn session(&self) -> MutexGuard<'_, RawMutex, Session> { - self.session.lock() - } - fn tokenizer(&self) -> &Arc { - &self.tokenizer - } - fn model_config(&self) -> &Arc { - &self.model_config - } -} +pub type AppState = Arc>; -#[derive(Debug, Clone)] -pub struct AppState { - pub config: Arc, - pub session: Arc>, - pub tokenizer: Arc, - pub model_config: Arc, +#[derive(Debug)] +pub struct EncoderfileState { + pub config: Config, + pub session: Mutex, + pub tokenizer: TokenizerService, + pub model_config: ModelConfig, _marker: PhantomData, } -impl AppState { +impl EncoderfileState { pub fn new( - config: Arc, - session: Arc>, - tokenizer: Arc, - model_config: Arc, - ) -> AppState { - AppState { + config: Config, + session: Mutex, + tokenizer: TokenizerService, + model_config: ModelConfig, + ) -> EncoderfileState { + EncoderfileState { config, session, tokenizer, diff --git a/encoderfile/src/services/embedding.rs b/encoderfile/src/services/embedding.rs index bf885ae..d03de78 100644 --- a/encoderfile/src/services/embedding.rs +++ b/encoderfile/src/services/embedding.rs @@ -2,7 +2,7 @@ use crate::{ common::{EmbeddingRequest, EmbeddingResponse, model_type}, error::ApiError, inference, - runtime::{AppState, InferenceState}, + runtime::AppState, transforms::EmbeddingTransform, }; @@ -15,13 +15,11 @@ impl Inference for AppState { fn inference(&self, request: impl Into) -> Result { let request = request.into(); - let session = self.session(); - let encodings = self.tokenizer.encode_text(request.inputs)?; let transform = EmbeddingTransform::new(self.transform_str())?; - let results = inference::embedding::embedding(session, &transform, encodings)?; + let results = inference::embedding::embedding(self.session.lock(), &transform, encodings)?; Ok(EmbeddingResponse { results, diff --git a/encoderfile/src/services/sentence_embedding.rs b/encoderfile/src/services/sentence_embedding.rs index 0391221..f04223a 100644 --- a/encoderfile/src/services/sentence_embedding.rs +++ b/encoderfile/src/services/sentence_embedding.rs @@ -2,7 +2,7 @@ use crate::{ common::{SentenceEmbeddingRequest, SentenceEmbeddingResponse, model_type}, error::ApiError, inference, - runtime::{AppState, InferenceState}, + runtime::AppState, transforms::SentenceEmbeddingTransform, }; @@ -15,14 +15,15 @@ impl Inference for AppState { fn inference(&self, request: impl Into) -> Result { let request = request.into(); - let session = self.session(); - let encodings = self.tokenizer.encode_text(request.inputs)?; let transform = SentenceEmbeddingTransform::new(self.transform_str())?; - let results = - inference::sentence_embedding::sentence_embedding(session, &transform, encodings)?; + let results = inference::sentence_embedding::sentence_embedding( + self.session.lock(), + &transform, + encodings, + )?; Ok(SentenceEmbeddingResponse { results, diff --git a/encoderfile/src/services/sequence_classification.rs b/encoderfile/src/services/sequence_classification.rs index 4a2bdf0..0550a3d 100644 --- a/encoderfile/src/services/sequence_classification.rs +++ b/encoderfile/src/services/sequence_classification.rs @@ -2,7 +2,7 @@ use crate::{ common::{SequenceClassificationRequest, SequenceClassificationResponse, model_type}, error::ApiError, inference, - runtime::{AppState, InferenceState}, + runtime::AppState, transforms::SequenceClassificationTransform, }; @@ -15,14 +15,12 @@ impl Inference for AppState { fn inference(&self, request: impl Into) -> Result { let request = request.into(); - let session = self.session(); - let encodings = self.tokenizer.encode_text(request.inputs)?; let transform = SequenceClassificationTransform::new(self.transform_str())?; let results = inference::sequence_classification::sequence_classification( - session, + self.session.lock(), &transform, &self.model_config, encodings, diff --git a/encoderfile/src/transport/grpc/mod.rs b/encoderfile/src/transport/grpc/mod.rs index 0445d09..0aaaf85 100644 --- a/encoderfile/src/transport/grpc/mod.rs +++ b/encoderfile/src/transport/grpc/mod.rs @@ -11,7 +11,7 @@ pub trait GrpcRouter: ModelTypeSpec where Self: Sized, { - fn router(state: AppState) -> axum::Router; + fn grpc_router(state: AppState) -> axum::Router; } pub struct GrpcService { @@ -35,7 +35,7 @@ macro_rules! generate_grpc_server { $server_type:ident ) => { impl GrpcRouter for model_type::$model_type { - fn router(state: AppState) -> axum::Router { + fn grpc_router(state: AppState) -> axum::Router { tonic::service::Routes::builder() .routes() .add_service($generated_mod::$server_mod::$server_type::new( diff --git a/encoderfile/src/transport/server.rs b/encoderfile/src/transport/server.rs index 7d3e5a3..c55fdaf 100644 --- a/encoderfile/src/transport/server.rs +++ b/encoderfile/src/transport/server.rs @@ -5,8 +5,9 @@ use crate::{ transport::{grpc::GrpcRouter, http::HttpRouter}, }; use anyhow::Result; +use axum::extract::connect_info::IntoMakeServiceWithConnectInfo; use axum_server::tls_rustls::RustlsConfig; -use std::path::Path; +use std::{net::SocketAddr, path::Path}; use tower_http::trace::DefaultOnResponse; pub async fn run_grpc( @@ -16,58 +17,23 @@ pub async fn run_grpc( maybe_key_file: Option, state: AppState, ) -> Result<()> { - let addr = format!("{}:{}", &hostname, &port); - - let model_type = T::enum_val(); - - let router = T::router(state) - .layer( - tower_http::trace::TraceLayer::new_for_grpc() - .on_response(DefaultOnResponse::new().level(tracing::Level::INFO)), - ) - .into_make_service_with_connect_info::(); - - tracing::debug!( - "TLS configuration: cert file: {:?}, cert key: {:?}", + serve_with_optional_tls( + hostname, + port, maybe_cert_file, - maybe_key_file - ); - - tracing::info!("Running {:?} gRPC server on {}", model_type, &addr); - - match (maybe_cert_file, maybe_key_file) { - (Some(cert_file), Some(key_file)) => { - // ref: https://github.com/tokio-rs/axum/blob/main/examples/tls-rustls/src/main.rs#L45 - // configure certificate and private key used by https - let config = - RustlsConfig::from_pem_file(Path::new(&cert_file), Path::new(&key_file)).await?; - - let socket_addr = addr.parse()?; - - axum_server::bind_rustls(socket_addr, config) - .serve(router) - .await? - } - (None, Some(_)) => { - return Err(crate::error::ApiError::ConfigError( - "Both cert and key file need to be set. Only the key file has been set.", - ))?; - } - (Some(_), None) => { - return Err(crate::error::ApiError::ConfigError( - "Both cert and key file need to be set. Only the cert file has been set.", - ))?; - } - (None, None) => { - let listener = tokio::net::TcpListener::bind(&addr) - .await - .expect("Invalid address: {addr}"); - - axum::serve(listener, router).await?; - } - } - - Ok(()) + maybe_key_file, + "gRPC", + state, + |state| { + T::grpc_router(state) + .layer( + tower_http::trace::TraceLayer::new_for_grpc() + .on_response(DefaultOnResponse::new().level(tracing::Level::INFO)), + ) + .into_make_service_with_connect_info::() + }, + ) + .await } pub async fn run_http( @@ -80,51 +46,23 @@ pub async fn run_http( where AppState: Inference, { - let addr = format!("{}:{}", &hostname, &port); - - let model_type = T::enum_val(); - - let router = T::http_router(state) - .layer( - tower_http::trace::TraceLayer::new_for_http() - .on_response(DefaultOnResponse::new().level(tracing::Level::INFO)), - ) - .into_make_service_with_connect_info::(); - - tracing::info!( - "TLS configuration: cert file: {:?}, cert key: {:?}", + serve_with_optional_tls( + hostname, + port, maybe_cert_file, - maybe_key_file - ); - - match (maybe_cert_file, maybe_key_file) { - (Some(cert_file), Some(key_file)) => { - tracing::info!("Running {:?} HTTPS server on {}", model_type, &addr); - - // ref: https://github.com/tokio-rs/axum/blob/main/examples/tls-rustls/src/main.rs#L45 - // configure certificate and private key used by https - let config = RustlsConfig::from_pem_file(Path::new(&cert_file), Path::new(&key_file)) - .await - .unwrap(); - - let socket_addr = addr.parse()?; - - axum_server::bind_rustls(socket_addr, config) - .serve(router) - .await? - } - _ => { - tracing::info!("Running {:?} HTTP server on {}", model_type, &addr); - - let listener = tokio::net::TcpListener::bind(&addr) - .await - .expect("Invalid address: {addr}"); - - axum::serve(listener, router).await?; - } - } - - Ok(()) + maybe_key_file, + "HTTP", + state, + |state| { + T::http_router(state) + .layer( + tower_http::trace::TraceLayer::new_for_http() + .on_response(DefaultOnResponse::new().level(tracing::Level::INFO)), + ) + .into_make_service_with_connect_info::() + }, + ) + .await } pub async fn run_mcp( @@ -134,51 +72,76 @@ pub async fn run_mcp( maybe_key_file: Option, state: AppState, ) -> Result<()> { - let addr = format!("{}:{}", &hostname, &port); + serve_with_optional_tls( + hostname, + port, + maybe_cert_file, + maybe_key_file, + "MCP", + state, + |state| { + T::mcp_router(state) + .layer( + tower_http::trace::TraceLayer::new_for_http() + // TODO check if otel is enabled + // .make_span_with(crate::middleware::format_span) + .on_response(DefaultOnResponse::new().level(tracing::Level::INFO)), + ) + .into_make_service_with_connect_info::() + }, + ) + .await +} - // FIXME add otel around here - let model_type = T::enum_val(); +async fn serve_with_optional_tls( + hostname: String, + port: String, + maybe_cert_file: Option, + maybe_key_file: Option, + server_type_str: &str, + state: AppState, + into_service_fn: impl Fn(AppState) -> IntoMakeServiceWithConnectInfo, +) -> Result<()> { + let addr = format!("{}:{}", &hostname, &port); - let router = T::mcp_router(state) - .layer( - tower_http::trace::TraceLayer::new_for_http() - // TODO check if otel is enabled - // .make_span_with(crate::middleware::format_span) - .on_response(DefaultOnResponse::new().level(tracing::Level::INFO)), - ) - .into_make_service_with_connect_info::(); + let router = into_service_fn(state); - tracing::info!( - "TLS configuration: cert file: {:?}, cert key: {:?}", - maybe_cert_file, - maybe_key_file - ); + let model_type = T::enum_val(); match (maybe_cert_file, maybe_key_file) { - (Some(cert_file), Some(key_file)) => { - tracing::info!("Running {:?} MPC-on-TLS server on {}", model_type, &addr); - - // ref: https://github.com/tokio-rs/axum/blob/main/examples/tls-rustls/src/main.rs#L45 - // configure certificate and private key used by https - let config = RustlsConfig::from_pem_file(Path::new(&cert_file), Path::new(&key_file)) - .await - .unwrap(); - + (Some(cert), Some(key)) => { + tracing::debug!( + "TLS configuration: cert file: {:?}, cert key: {:?}", + cert.as_str(), + key.as_str() + ); + + tracing::info!( + "Running {:?} {:?} server with TLS on {}", + model_type, + server_type_str, + &addr + ); + + let config = RustlsConfig::from_pem_file(Path::new(&cert), Path::new(&key)).await?; let socket_addr = addr.parse()?; - axum_server::bind_rustls(socket_addr, config) .serve(router) - .await? + .await?; } - _ => { - tracing::info!("Running {:?} MCP server on {}", model_type, &addr); - - let listener = tokio::net::TcpListener::bind(&addr) - .await - .expect("Invalid address: {addr}"); - + (None, None) => { + tracing::info!( + "Running {:?} {:?} server on {}", + model_type, + server_type_str, + &addr + ); + let listener = tokio::net::TcpListener::bind(addr).await?; axum::serve(listener, router).await?; } + _ => { + anyhow::bail!("Both cert and key file must be set when TLS is enabled"); + } } Ok(()) From 722bce74bdb65e200bdd16ddcaae41698b5d034f Mon Sep 17 00:00:00 2001 From: Raz Besaleli Date: Sat, 24 Jan 2026 17:34:09 +0100 Subject: [PATCH 22/23] ci: only run release with version-bump label on pr close --- .github/workflows/release.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d34ff62..e2720a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,13 @@ permissions: jobs: compute-dry-run: runs-on: ubuntu-latest + # only run if workflow dispatch or pull request merged *with* tag 'version-bump' + if: > + github.event_name == 'workflow_dispatch' || + ( + github.event.pull_request.merged == true && + contains(github.event.pull_request.labels.*.name, 'version-bump') + ) outputs: is_dry_run: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' }} From 5972161e34f75c3bf17a3249a772bd296403caae Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 17:36:01 +0100 Subject: [PATCH 23/23] =?UTF-8?q?version:=20Version=20Bump=20=F0=9F=9A=80?= =?UTF-8?q?=200.4.0-rc.1=20(#249)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version bumped from 0.4.0-beta.12 to 0.4.0-rc.1. ### 🔄 Changes - 📝 Updated version in Cargo.toml - 🔒 Updated Cargo.lock ✨ This PR was automatically generated by the Version Management workflow ✨ ![version bump](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjJmOXBxbGh2Z3BiYXM1NnJhMHdtbmNoaTFxN2xjOGZjZnd1ZGhuMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oEjI53nBYOOEQgDcY/giphy.gif) Co-authored-by: besaleli --- Cargo.lock | 156 ++++++++++++++++----------------- encoderfile-runtime/Cargo.toml | 4 +- encoderfile/Cargo.toml | 2 +- 3 files changed, 81 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a350f6c..a323db9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,9 +148,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.2" +version = "1.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" +checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" dependencies = [ "aws-lc-sys", "zeroize", @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.35.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" +checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a" dependencies = [ "cc", "cmake", @@ -320,9 +320,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.52" +version = "1.2.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" dependencies = [ "find-msvc-tools", "jobserver", @@ -350,9 +350,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "js-sys", @@ -398,9 +398,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "cmake" @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "codspeed" -version = "4.2.1" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0d98d97fd75ca4489a1a0997820a6521531085e7c8a98941bd0e1264d567dd" +checksum = "38c2eb3388ebe26b5a0ab6bf4969d9c4840143d7f6df07caa3cc851b0606cef6" dependencies = [ "anyhow", "cc", @@ -431,9 +431,9 @@ dependencies = [ [[package]] name = "codspeed-divan-compat" -version = "4.2.1" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4179ec5518e79efcd02ed50aa483ff807902e43c85146e87fff58b9cffc06078" +checksum = "b2de65b7489a59709724d489070c6d05b7744039e4bf751d0a2006b90bb5593d" dependencies = [ "clap", "codspeed", @@ -444,9 +444,9 @@ dependencies = [ [[package]] name = "codspeed-divan-compat-macros" -version = "4.2.1" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15eaee97aa5bceb32cc683fe25cd6373b7fc48baee5c12471996b58b6ddf0d7c" +checksum = "56ca01ce4fd22b8dcc6c770dcd6b74343642e842482b94e8920d14e10c57638d" dependencies = [ "divan-macros", "itertools 0.14.0", @@ -458,9 +458,9 @@ dependencies = [ [[package]] name = "codspeed-divan-compat-walltime" -version = "4.2.1" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38671153aa73be075d6019cab5ab1e6b31d36644067c1ac4cef73bf9723ce33" +checksum = "720ab9d0714718afe5f5832be6e5f5eb5ce97836e24ca7bf7042eea4308b9fb8" dependencies = [ "cfg-if", "clap", @@ -815,7 +815,7 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoderfile" -version = "0.4.0-beta.12" +version = "0.4.0-rc.1" dependencies = [ "anyhow", "axum", @@ -851,7 +851,7 @@ dependencies = [ "tar", "tempfile", "test-log", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokenizers", "tokio", "tonic", @@ -872,7 +872,7 @@ dependencies = [ [[package]] name = "encoderfile-runtime" -version = "0.4.0-beta.12" +version = "0.4.0-rc.1" dependencies = [ "anyhow", "clap", @@ -964,21 +964,20 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", ] [[package]] name = "find-msvc-tools" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" [[package]] name = "fixedbitset" @@ -1587,9 +1586,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -1662,9 +1661,9 @@ dependencies = [ [[package]] name = "luajit-src" -version = "210.6.5+7152e15" +version = "210.6.6+707c12b" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e64ac463f01a02ee793423f9b351369cf244c5ee8bb9e2729a75b2eb404181" +checksum = "a86cc925d4053d0526ae7f5bc765dbd0d7a5d1a63d43974f4966cb349ca63295" dependencies = [ "cc", "which", @@ -1989,9 +1988,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-probe" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" @@ -2015,7 +2014,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -2045,7 +2044,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest 0.12.28", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tonic", "tracing", @@ -2093,7 +2092,7 @@ dependencies = [ "opentelemetry", "percent-encoding", "rand 0.9.2", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2297,9 +2296,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -2404,7 +2403,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -2426,7 +2425,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -2448,9 +2447,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -2479,7 +2478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.4", + "rand_core 0.9.5", ] [[package]] @@ -2499,7 +2498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.4", + "rand_core 0.9.5", ] [[package]] @@ -2513,9 +2512,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1b3bc831f92381018fd9c6350b917c7b21f1eed35a65a51900e0e55a3d7afa" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -2583,7 +2582,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2759,7 +2758,7 @@ dependencies = [ "serde", "serde_json", "sse-stream", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", @@ -2821,7 +2820,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe 0.2.0", + "openssl-probe 0.2.1", "rustls-pki-types", "schannel", "security-framework 3.5.1", @@ -2838,9 +2837,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -2875,9 +2874,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "aws-lc-rs", "ring", @@ -3135,9 +3134,9 @@ checksum = "51d44cfb396c3caf6fbfd0ab422af02631b69ddd96d2eff0b0f0724f9024051b" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -3332,11 +3331,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -3352,9 +3351,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -3423,7 +3422,7 @@ dependencies = [ "serde", "serde_json", "spm_precompiled", - "thiserror 2.0.17", + "thiserror 2.0.18", "unicode-normalization-alignments", "unicode-segmentation", "unicode_categories", @@ -3976,18 +3975,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -3998,11 +3997,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -4011,9 +4011,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4021,9 +4021,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ "bumpalo", "proc-macro2", @@ -4034,9 +4034,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -4056,9 +4056,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -4452,9 +4452,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" @@ -4583,6 +4583,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac93432f5b761b22864c774aac244fa5c0fd877678a4c37ebf6cf42208f9c9ec" +checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" diff --git a/encoderfile-runtime/Cargo.toml b/encoderfile-runtime/Cargo.toml index aa56696..7009b19 100644 --- a/encoderfile-runtime/Cargo.toml +++ b/encoderfile-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encoderfile-runtime" -version = "0.4.0-beta.12" +version = "0.4.0-rc.1" edition = "2024" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies.encoderfile] path = "../encoderfile" -version = "0.4.0-beta.12" +version = "0.4.0-rc.1" features = ["transport"] default-features = false diff --git a/encoderfile/Cargo.toml b/encoderfile/Cargo.toml index 151ec96..447f9c2 100644 --- a/encoderfile/Cargo.toml +++ b/encoderfile/Cargo.toml @@ -54,7 +54,7 @@ required-features = ["cli", "dev-utils"] [package] name = "encoderfile" -version = "0.4.0-beta.12" +version = "0.4.0-rc.1" edition = "2024" license = "Apache-2.0" readme = "../README.md"