diff --git a/.github/workflows/ffi-builds.yml b/.github/workflows/ffi-builds.yml index 78547c303..5be4110ef 100644 --- a/.github/workflows/ffi-builds.yml +++ b/.github/workflows/ffi-builds.yml @@ -16,20 +16,53 @@ name: FFI on: push: branches: ["main"] - tags: - - "rust-sdks/livekit-ffi@*" workflow_dispatch: - workflow_call: inputs: - tag: + tag_name: + description: "Release tag (e.g. livekit-ffi/v0.12.49). Takes precedence over draft release lookup and creates a draft release." required: false type: string + dry_run: + description: "Dry run: build artifacts but skip release upload/publish." + required: false + type: boolean + default: false + workflow_call: + inputs: + dry_run: + description: "Dry run: build artifacts but skip release upload/publish." + required: false + type: boolean + default: false env: CARGO_TERM_COLOR: always - TAG_NAME: ${{ inputs.tag || github.ref_name }} jobs: + get-tag: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + - name: "Resolve tag" + run: | + MANUAL_TAG="${{ inputs.tag_name }}" + if [ -n "$MANUAL_TAG" ]; then + echo "Using manually provided tag: '${MANUAL_TAG}'" + gh release create "$MANUAL_TAG" --draft --title "$MANUAL_TAG" --generate-notes + echo "tag_name=${MANUAL_TAG}" >> $GITHUB_OUTPUT + else + TAG=$(gh release list --repo ${{ github.repository }} --json 'isDraft,tagName' --jq '[.[] | select(.isDraft and (.tagName | startswith("livekit-ffi/")))] | first | .tagName // empty') + echo "Resolved FFI draft release tag: '${TAG:-}'" + echo "tag_name=${TAG:-}" >> $GITHUB_OUTPUT + fi + env: + GH_TOKEN: ${{ github.token }} + id: get-tag + outputs: + tag_name: ${{ steps.get-tag.outputs.tag_name }} + build: strategy: fail-fast: false @@ -212,12 +245,12 @@ jobs: path: ${{ matrix.name }}.zip release: - name: Release to GH (Draft) + name: Upload artifacts and publish GH release runs-on: ubuntu-latest - needs: build + needs: [get-tag, build] permissions: contents: write - if: startsWith(inputs.tag || github.ref_name, 'rust-sdks/livekit-ffi@') + if: needs.get-tag.outputs.tag_name != '' && inputs.dry_run != true env: GH_TOKEN: ${{ github.token }} steps: @@ -230,7 +263,7 @@ jobs: merge-multiple: true path: ${{ github.workspace }}/ffi-builds - - name: Create draft release + - name: Upload artifacts and publish release run: | - gh release create ${{ env.TAG_NAME }} --draft --title "${{ env.TAG_NAME }}" - gh release upload ${{ env.TAG_NAME }} ${{ github.workspace }}/ffi-builds/* + gh release upload ${{ needs.get-tag.outputs.tag_name }} ${{ github.workspace }}/ffi-builds/* + gh release edit ${{ needs.get-tag.outputs.tag_name }} --draft=false diff --git a/.github/workflows/node-builds.yml b/.github/workflows/node-builds.yml index 6df37f05b..a6e29d4cb 100644 --- a/.github/workflows/node-builds.yml +++ b/.github/workflows/node-builds.yml @@ -6,7 +6,19 @@ permissions: on: workflow_dispatch: + inputs: + dry_run: + description: "Dry run: build artifacts but skip npm publish." + required: false + type: boolean + default: false workflow_call: + inputs: + dry_run: + description: "Dry run: build artifacts but skip npm publish." + required: false + type: boolean + default: false env: CARGO_TERM_COLOR: always @@ -46,7 +58,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: recursive - fetch-depth: 0 + - uses: pnpm/action-setup@v4 with: package_json_file: livekit-ffi-node-bindings/package.json @@ -123,7 +135,7 @@ jobs: cd /workspace cd livekit-ffi-node-bindings CI=true pnpm install - pnpm build --target $TARGET + pnpm build --target $TARGET " ' @@ -141,7 +153,6 @@ jobs: - name: Upload binary artifact uses: actions/upload-artifact@v4 - if: github.event_name != 'pull-request' with: name: native-bindings-${{ matrix.target }} path: livekit-ffi-node-bindings/${{ env.APP_NAME }}.*.node @@ -149,15 +160,15 @@ jobs: - name: Upload JS uses: actions/upload-artifact@v4 - if: ${{ github.event_name != 'pull-request' && matrix.os == 'macos-15' }} + if: ${{ matrix.os == 'macos-15' }} with: name: js-bindings path: livekit-ffi-node-bindings/native.* if-no-files-found: error - release: - needs: [build] - name: Release + publish: + needs: build + name: Publish to npm runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -196,6 +207,11 @@ jobs: run: ls -R ./livekit-ffi-node-bindings/npm shell: bash + - name: Echo changes + run: | + git status + git diff + - name: Publish working-directory: livekit-ffi-node-bindings - run: pnpm publish -r + run: pnpm publish -r ${{ inputs.dry_run == true && '--dry-run --no-git-checks' || '' }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25e24564f..e44f3aedc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,167 +1,50 @@ name: Release +on: + pull_request: + types: [closed] + branches: [main] + workflow_dispatch: + inputs: + dry_run: + description: "Dry run: build artifacts but skip publishing/releasing." + required: false + type: boolean + default: false + permissions: - id-token: write # Required for OIDC - pull-requests: write + id-token: write contents: write - actions: write - -on: - push: - branches: - - main jobs: - # Release unpublished packages. - release-plz-release: - name: Release-plz release + publish-crates: + if: (github.head_ref == 'knope/release' && github.event.pull_request.merged == true) || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'livekit' }} - permissions: - contents: write - outputs: - ffi_tag: ${{ steps.ffi.outputs.ffi_tag }} steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: - fetch-depth: 0 submodules: recursive - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - - name: Install VA-API/NVIDIA drivers and other dependencies for build - run: | - sudo apt update -y - sudo apt install \ - libnvidia-compute-570 \ - libnvidia-decode-570 \ - nvidia-cuda-dev \ - libasound2-dev \ - libssl-dev \ - libx11-dev \ - libgl1-mesa-dev \ - libxext-dev \ - libva-dev \ - libdrm-dev \ - libgbm-dev \ - libxfixes-dev \ - libxdamage-dev \ - libxrandr-dev \ - libxcomposite-dev \ - libglib2.0-dev -y - - name: Run release-plz - uses: release-plz/action@v0.5 - id: release-plz - with: - command: release + - uses: dtolnay/rust-toolchain@stable + + - name: Install cargo-release + run: cargo install cargo-release + + - name: Publish to crates.io + run: cargo release publish --workspace --no-confirm --no-verify ${{ inputs.dry_run != true && '--execute' || '' }} env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_TOKEN }} - - name: Extract ffi tag - id: ffi - env: - RELEASES: ${{ steps.release-plz.outputs.releases }} - run: | - set -e - ffi_tag=$(echo "$RELEASES" | jq -r '.[].tag' | grep 'rust-sdks/livekit-ffi@' || true) - echo "ffi_tag=$ffi_tag" - echo "ffi_tag=$ffi_tag" >> $GITHUB_OUTPUT call-ffi: name: Call FFI Builds - if: ${{ needs.release-plz-release.outputs.ffi_tag != '' }} + if: (github.head_ref == 'knope/release' && github.event.pull_request.merged == true) || github.event_name == 'workflow_dispatch' uses: ./.github/workflows/ffi-builds.yml - needs: release-plz-release with: - tag: ${{ needs.release-plz-release.outputs.ffi_tag }} + dry_run: ${{ inputs.dry_run || false }} call-node-ffi: - name: Call node FFI Builds - if: ${{ needs.release-plz-release.outputs.ffi_tag != '' }} + name: Call Node FFI Builds + if: (github.head_ref == 'knope/release' && github.event.pull_request.merged == true) || github.event_name == 'workflow_dispatch' uses: ./.github/workflows/node-builds.yml - needs: release-plz-release - - # Create a PR with the new versions and changelog, preparing the next release. - release-plz-pr: - name: Release-plz PR - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - concurrency: - group: release-plz-${{ github.ref }} - cancel-in-progress: false - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: recursive - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - - name: Install VA-API/NVIDIA drivers and other dependencies for build - run: | - sudo apt update -y - sudo apt install \ - libnvidia-compute-570 \ - libnvidia-decode-570 \ - nvidia-cuda-dev \ - libasound2-dev \ - libssl-dev \ - libx11-dev \ - libgl1-mesa-dev \ - libxext-dev \ - libva-dev \ - libdrm-dev \ - libgbm-dev \ - libxfixes-dev \ - libxdamage-dev \ - libxrandr-dev \ - libxcomposite-dev \ - libglib2.0-dev -y - - name: Run release-plz - uses: release-plz/action@v0.5 - id: release-plz - with: - command: release-pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_TOKEN }} - - - name: Sync node package.json versions to livekit-ffi - env: - PR: ${{ steps.release-plz.outputs.pr }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - set -euo pipefail - - HEAD_BRANCH=$(echo "$PR" | jq -r '.head_branch // empty') - if [ -z "$HEAD_BRANCH" ]; then - echo "No release PR, skipping" - exit 0 - fi - - git fetch origin "$HEAD_BRANCH" - git checkout "$HEAD_BRANCH" - - # Read version from Cargo.toml on the PR branch - FFI_VERSION=$(grep '^version = ' livekit-ffi/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') - CURRENT_VERSION=$(jq -r '.version' livekit-ffi-node-bindings/package.json) - - if [ "$FFI_VERSION" = "$CURRENT_VERSION" ]; then - echo "Versions already in sync ($FFI_VERSION)" - exit 0 - fi - - echo "Updating node packages: $CURRENT_VERSION -> $FFI_VERSION" - - for pkg in livekit-ffi-node-bindings/package.json livekit-ffi-node-bindings/npm/*/package.json; do - jq --arg v "$FFI_VERSION" '.version = $v' "$pkg" > tmp.json && mv tmp.json "$pkg" - done - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add livekit-ffi-node-bindings/package.json livekit-ffi-node-bindings/npm/*/package.json - git commit -m "sync node package.json versions to $FFI_VERSION" - git push origin "$HEAD_BRANCH" + with: + dry_run: ${{ inputs.dry_run || false }} diff --git a/knope.toml b/knope.toml new file mode 100644 index 000000000..2675868e0 --- /dev/null +++ b/knope.toml @@ -0,0 +1,85 @@ +[github] +owner = "livekit" +repo = "rust-sdks" + +[changes] +ignore_conventional_commits = true + +[bot.checks] +skip_labels = ["internal"] + +[bot.releases] +enabled = true + +# --- Package configuration --- + +[packages.soxr-sys] +versioned_files = ["soxr-sys/Cargo.toml"] +changelog = "soxr-sys/CHANGELOG.md" +scopes = ["soxr-sys", "soxr"] + +[packages.yuv-sys] +versioned_files = ["yuv-sys/Cargo.toml"] +changelog = "yuv-sys/CHANGELOG.md" +scopes = ["yuv-sys", "yuv"] + +[packages.imgproc] +versioned_files = ["imgproc/Cargo.toml"] +changelog = "imgproc/CHANGELOG.md" +scopes = ["imgproc"] + +[packages.webrtc-sys-build] +versioned_files = ["webrtc-sys/build/Cargo.toml"] +changelog = "webrtc-sys/build/CHANGELOG.md" +scopes = ["webrtc-sys-build"] + +[packages.webrtc-sys] +versioned_files = ["webrtc-sys/Cargo.toml"] +changelog = "webrtc-sys/CHANGELOG.md" +scopes = ["webrtc-sys"] + +[packages.livekit-protocol] +versioned_files = ["livekit-protocol/Cargo.toml"] +changelog = "livekit-protocol/CHANGELOG.md" +scopes = ["livekit-protocol", "protocol"] + +[packages.livekit-api] +versioned_files = ["livekit-api/Cargo.toml"] +changelog = "livekit-api/CHANGELOG.md" +scopes = ["livekit-api"] + +[packages.libwebrtc] +versioned_files = ["libwebrtc/Cargo.toml"] +changelog = "libwebrtc/CHANGELOG.md" +scopes = ["libwebrtc"] + +[packages.livekit] +versioned_files = ["livekit/Cargo.toml"] +changelog = "livekit/CHANGELOG.md" +scopes = ["livekit"] + +[packages.livekit-ffi] +versioned_files = [ + "livekit-ffi/Cargo.toml", + "livekit-ffi-node-bindings/package.json", + "livekit-ffi-node-bindings/npm/darwin-arm64/package.json", + "livekit-ffi-node-bindings/npm/darwin-x64/package.json", + "livekit-ffi-node-bindings/npm/linux-arm64-gnu/package.json", + "livekit-ffi-node-bindings/npm/linux-x64-gnu/package.json", + "livekit-ffi-node-bindings/npm/win32-x64-msvc/package.json", +] +changelog = "livekit-ffi/CHANGELOG.md" +# Assets makes knope create a draft release; CI uploads the actual binaries and publishes. +assets = "marker" +scopes = [ + "ffi", + "livekit-ffi", + # Aggregated from deps (mirrors release-plz changelog_include): + "livekit", + "soxr-sys", + "soxr", + "imgproc", + "livekit-protocol", + "protocol", + "webrtc-sys-build", +] diff --git a/livekit-ffi/Cargo.toml b/livekit-ffi/Cargo.toml index 6581dba5d..996ee97e2 100644 --- a/livekit-ffi/Cargo.toml +++ b/livekit-ffi/Cargo.toml @@ -6,6 +6,7 @@ license.workspace = true description = "FFI interface for bindings in other languages" repository.workspace = true readme = "README.md" +publish = false [features] default = ["rustls-tls-native-roots"] diff --git a/release-plz.toml b/release-plz.toml deleted file mode 100644 index f6365e082..000000000 --- a/release-plz.toml +++ /dev/null @@ -1,97 +0,0 @@ -[workspace] -publish = false -release = false -git_tag_name = "rust-sdks/{{ package }}@{{ version }}" - -[[package]] -name = "imgproc" -changelog_path = "imgproc/CHANGELOG.md" -publish = true -release = true - -[[package]] -name = "libwebrtc" -changelog_path = "libwebrtc/CHANGELOG.md" -publish = true -release = true - -[[package]] -name = "livekit-api" -changelog_path = "livekit-api/CHANGELOG.md" -publish = true -release = true - -[[package]] -name = "livekit-protocol" -changelog_path = "livekit-protocol/CHANGELOG.md" -publish = true -release = true - -# [[package]] -# name = "livekit-runtime" -# changelog_path = "livekit-runtime/CHANGELOG.md" -# publish = true -# release = true - -[[package]] -name = "livekit" -changelog_path = "livekit/CHANGELOG.md" -publish = true -release = true - -[[package]] -name = "webrtc-sys" -changelog_path = "webrtc-sys/CHANGELOG.md" -publish = true -publish_no_verify = true -release = true - -[[package]] -name = "webrtc-sys-build" -changelog_path = "webrtc-sys/build/CHANGELOG.md" -publish = true -release = true - -[[package]] -name = "yuv-sys" -changelog_path = "yuv-sys/CHANGELOG.md" -publish = true -publish_no_verify = true -release = true - -[[package]] -name = "soxr-sys" -changelog_path = "soxr-sys/CHANGELOG.md" -publish = true -release = true - -[[package]] -name = "livekit-ffi" -changelog_path = "livekit-ffi/CHANGELOG.md" -publish = false -publish_no_verify = true -release = true -git_only = true -git_release_enable = false # existing CI manages GitHub release -changelog_include = [ - "livekit", - "soxr-sys", - "imgproc", - "livekit-protocol", - "webrtc-sys-build", -] - -[[package]] -name = "livekit-uniffi" -changelog_path = "livekit-uniffi/CHANGELOG.md" -publish = false -publish_no_verify = true -release = false -git_only = true - -[[package]] -name = "rtc-node-ffi-bindings" -publish = false -publish_no_verify = true -release = false -git_only = true \ No newline at end of file