Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
tests: ${{ steps.filter.outputs.tests }}
docs: ${{ steps.filter.outputs.docs }}
cpp_checks: ${{ steps.filter.outputs.cpp_checks }}
rust_release_check: ${{ steps.filter.outputs.rust_release_check }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
Expand Down Expand Up @@ -83,6 +84,8 @@ jobs:
- .clang-tidy
- .github/workflows/ci.yml
- .github/workflows/cpp-checks.yml
rust_release_check:
- client-sdk-rust

builds:
name: Builds
Expand Down Expand Up @@ -116,6 +119,15 @@ jobs:
if: ${{ needs.changes.outputs.docs == 'true' || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/generate-docs.yml

# Only runs on a client-sdk-rust submodule bump. Runs in parallel and is not a
# dependency of builds/tests, so developer iteration against an unreleased
# Rust commit still gets full build feedback in CI.
rust-release-check:
name: Rust Release Check
needs: changes
if: ${{ needs.changes.outputs.rust_release_check == 'true' || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/rust-release-check.yml

# Context: GitHub repository rulesets "required checks" actually need a job name to list.
# This job is an aggregate job
ci:
Expand All @@ -129,6 +141,7 @@ jobs:
- license-check
- cpp-checks
- generate-docs
- rust-release-check
if: always()
steps:
- name: Verify required CI jobs
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/rust-release-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Rust Release Check

# Called by top-level ci.yml. Verifies that the pinned client-sdk-rust
# submodule commit corresponds to a published release in the Rust SDK repo,
# so the C++ SDK is never released on a stray (unreleased) Rust commit.
on:
workflow_call: {}
workflow_dispatch: {}

permissions:
contents: read

jobs:
rust-release-check:
name: Rust Release Check
runs-on: ubuntu-latest
steps:
- name: Checkout (with submodules)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive
fetch-depth: 1

- name: Resolve Rust submodule SHA
id: rust_sha
shell: bash
run: echo "sha=$(git -C client-sdk-rust rev-parse HEAD)" >> "$GITHUB_OUTPUT"

- name: Verify Rust commit has an associated release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
RUST_REPO: livekit/client-sdk-rust
RUST_SHA: ${{ steps.rust_sha.outputs.sha }}
run: |
set -euo pipefail
echo "Pinned client-sdk-rust commit: ${RUST_SHA}"

# Published (non-draft) releases -> their tag names.
gh api --paginate "repos/${RUST_REPO}/releases" \
Comment thread
stephen-derosa marked this conversation as resolved.
--jq '.[] | select(.draft == false) | .tag_name' \
| sort -u > release_tags.txt

# All tags -> "tag<TAB>commit_sha"; .commit.sha is the dereferenced
# target commit, so annotated and lightweight tags are handled alike.
gh api --paginate "repos/${RUST_REPO}/tags" \
--jq '.[] | [.name, .commit.sha] | @tsv' > all_tags.tsv

# A match is a tag that points at the pinned commit AND is released.
match="$(awk -v sha="${RUST_SHA}" '
NR == FNR { released[$0] = 1; next }
($2 == sha) && ($1 in released) { print $1 }
' release_tags.txt all_tags.tsv | head -n 1)"

if [[ -z "${match}" ]]; then
echo "::error::client-sdk-rust commit ${RUST_SHA} is not associated with any published release in ${RUST_REPO}."
echo "Bump the submodule to a released commit before merging; the C++ SDK must not release on a stray Rust commit."
exit 1
fi

echo "client-sdk-rust commit ${RUST_SHA} is covered by release tag '${match}'."
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,12 @@ all filtered stages; normal pull requests and pushes use the path filters.
- `.github/workflows/cpp-checks.yml` — Reusable `clang-format` and
`clang-tidy` checks.
- `.github/workflows/generate-docs.yml` — Reusable Doxygen docs validation.
- `.github/workflows/rust-release-check.yml` — Reusable check that the pinned
`client-sdk-rust` submodule commit maps to a published release. Gated by the
`rust_submodule` path filter so it only runs on a submodule bump, runs in
parallel, and is intentionally not a dependency of `builds`/`tests` so
developer iteration against an unreleased Rust commit still gets build
feedback.
- `.github/workflows/license_check.yml` — Cheap license check, run on every CI
invocation.
- `.github/workflows/docker-images.yml` — Docker image build/publish workflow,
Expand Down
2 changes: 1 addition & 1 deletion client-sdk-rust
Loading