Fix uniffi release: run from release.yml and publish the draft#1256
Fix uniffi release: run from release.yml and publish the draft#1256pblazej wants to merge 1 commit into
Conversation
uniffi-packages.yml triggered on push:main, which fired the moment the knope/release PR merged and raced knope's draft-release creation. resolve-tag's gh release list ran before the draft was visible, resolved <none>, and skipped every job — so the draft was never published and the livekit-uniffi/v* tag was never cut (v0.1.4 and v0.1.5 were both stranded this way). Two fixes, mirroring the working ffi-builds.yml / node-builds.yml pattern: - Invoke uniffi-packages.yml as a reusable workflow from release.yml on the knope/release merge (workflow_call), instead of push:main. Same reliable trigger node-builds uses. Add a short retry to the draft lookup to absorb the release-list API's propagation lag. - Add a finalize job that flips the draft to a published release (gh release edit --draft=false) once the swift/android/cdylib jobs succeed. Publishing the draft is what creates the git tag; this step was missing entirely (ffi-builds.yml has it, uniffi-packages.yml did not). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| - name: Publish release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: gh release edit "${{ needs.resolve-tag.outputs.tag_name }}" --repo "${{ github.repository }}" --draft=false |
There was a problem hiding this comment.
🟨 Unsanitized expression interpolation in shell command allows script injection
The finalize job interpolates needs.resolve-tag.outputs.tag_name directly into a run shell script (uniffi-packages.yml:123). This value originates from inputs.tag_name (line 51) when triggered via workflow_dispatch. A repository collaborator could craft a malicious tag name containing shell metacharacters (e.g. $(malicious_cmd)) that would be executed. The same pattern exists at line 51 (MANUAL_TAG="${{ inputs.tag_name }}"). While exploitation requires repo write access (limiting severity), using ${{ }} in run blocks is a known GitHub Actions anti-pattern.
Was this helpful? React with 👍 or 👎 to provide feedback.
| permissions: | ||
| contents: write | ||
| steps: | ||
| - name: Publish release |
There was a problem hiding this comment.
This is now a manual step for other packages, right?
|
@ladvoc feel free to close it, there must be some more elegant solution to both this and normal ffi |
Problem
The
livekit-uniffi/v0.1.5release never got a git tag and the uniffi publish jobs "didn't run" for the last release (4724cbb1, #1237). Same forv0.1.4before it — both drafts are stranded, unpublished.Two independent defects in
uniffi-packages.yml:Trigger race. It ran on
push: main, which fires the instant theknope/releasePR merges — concurrently with knope creating the draft release.resolve-tag'sgh release listran ~5s after the draft was created (createdAt 22:30:10vs query22:30:15) but GitHub's release-list API hadn't propagated it yet, so it resolved<none>and all jobs were skipped (the run shows "success" because skipped jobs don't fail).No publish step. Even when it does find the draft, nothing flips it to published. A GitHub draft release doesn't create the git tag until it's published (
gh release edit --draft=false).uniffi-packages.ymlhad no such step — onlyresolve-tag → swift / android / cdylib(which just upload). The siblingffi-builds.yml(the otherassets = "marker"package,livekit-ffi) has it; uniffi didn't.Fix
Mirror the working
ffi-builds.yml/node-builds.ymlpattern:release.ymlas a reusable workflow (workflow_call) on theknope/releasemerge, instead ofpush: main— the same reliable triggernode-builds.ymluses, so it no longer races the draft creation. A short retry on the draft lookup absorbs any residual list-API lag.finalizejob that publishes the draft (gh release edit --draft=false) onceswift/android/cdylibsucceed. This is what cuts thelivekit-uniffi/v*tag.assets = "marker"inknope.tomlis kept intentionally — the draft cleanly signals "livekit-uniffi was released this cycle" (so non-uniffi releases skip) and lets us publish only after the cdylibs are attached (no assetless-release window for the Dart build-hook download).workflow_dispatchis retained for manual re-runs.Validated with
actionlint(clean).Note on the stranded v0.1.5
This fixes future releases. To publish the existing
v0.1.5draft now, rununiffi-packages.ymlviaworkflow_dispatchwithtag_name: livekit-uniffi/v0.1.5(and clean up the stalev0.1.4draft).🤖 Generated with Claude Code