ci: release Kotlin and Swift SDKs with the platform release#4228
ci: release Kotlin and Swift SDKs with the platform release#4228shumkov wants to merge 4 commits into
Conversation
The monorepo versions and releases everything under a single vX.Y.Z tag, but the Kotlin SDK (kotlin-sdk-* tags) and Swift FFI (ffi-* tags) had independent release workflows in their own tag namespaces — neither of which was ever used (no such tag was ever pushed, nothing is on Maven Central). Consolidate them under the main release workflow: - publishing the platform GitHub release now also builds and attaches dash-sdk-android-<version>.aar and DashSDKFFI-<version>.xcframework.zip (+ SwiftPM checksum) to the same release, via two new reusable workflows called from release.yml (release-docker-image.yml pattern); - the Kotlin job additionally publishes org.dashj:dash-sdk-android under the platform version to Maven Central, with the publishing secrets scoped exclusively to the maven-central environment (v* tag policy); absorbs the hardened two-job publish flow from #4193 (tag force-move guard, no-asset-overwrite, all-or-nothing secrets gate, SHA-pinned deploy checkout) rewritten for the workflow_call context, plus an already-on-Central skip so re-runs are idempotent; - each reusable workflow keeps a workflow_dispatch path for re-running just the SDK release of an existing platform release; it must be dispatched at the tag ref and refuses branches, nonexistent tags, and tags without a published release; - the SDK jobs attach assets passing only tag_name + files, so the platform release's notes, title and prerelease flag are never touched; - kotlin-sdk-release.yml and swift-sdk-release.yml (and their tag triggers) are removed; docs updated (PUBLISHING.md CI path, release skill runbook, consolidation spec in docs/). Supersedes #4193 and #4220. Co-authored-by: bfoss765 <38437574+bfoss765@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughPlatform releases now trigger reusable Kotlin and Swift SDK workflows. Kotlin builds and attaches an AAR and conditionally deploys Maven artifacts; Swift builds and attaches an xcframework archive with checksum. Existing SDK release workflows are replaced, and release documentation describes validation and rerun procedures. ChangesPlatform release SDK publication
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant ReleaseOperator
participant GitHubRelease
participant ReleaseWorkflow
participant KotlinSDKWorkflow
participant SwiftSDKWorkflow
participant MavenCentral
ReleaseOperator->>GitHubRelease: Publish platform release
GitHubRelease->>ReleaseWorkflow: Emit release event
ReleaseWorkflow->>KotlinSDKWorkflow: Pass release tag
ReleaseWorkflow->>SwiftSDKWorkflow: Pass release tag
KotlinSDKWorkflow->>GitHubRelease: Attach versioned AAR
KotlinSDKWorkflow->>MavenCentral: Deploy signed Maven artifacts
SwiftSDKWorkflow->>GitHubRelease: Attach xcframework zip and checksum
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Final review complete — no blockers (commit a8867d1) |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
.github/workflows/release-swift-sdk.yml (2)
85-88: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winCheckout doesn't disable credential persistence (same as
release-kotlin-sdk.yml).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-swift-sdk.yml around lines 85 - 88, Update the repository checkout step in the release workflow to disable persisted credentials, matching the configuration used by the release-kotlin-sdk workflow; add the appropriate actions/checkout option alongside ref in the existing checkout step.Source: Linters/SAST tools
107-113: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDefault-enabled cargo cache in a release build (same cache-poisoning surface as
release-kotlin-sdk.yml).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-swift-sdk.yml around lines 107 - 113, Update the “Cache cargo registry” step in the release workflow to disable or remove the default-enabled Cargo cache, matching the safer behavior used by the Kotlin release workflow. Preserve the existing release build while eliminating the cache-poisoning surface from the actions/cache configuration.Source: Linters/SAST tools
.github/workflows/release-kotlin-sdk.yml (2)
113-119: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winCheckout doesn't disable credential persistence.
Both checkouts keep
persist-credentialsat its default (true), leaving the job'scontents: write-scoped token in the local git config for the remainder of the job — including the multi-hour native/Gradle build. Settingpersist-credentials: falselimits blast radius if a build dependency is compromised.🔒 Proposed fix
- name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ steps.release-ref.outputs.checkout_ref }} + persist-credentials: falseAlso applies to: 313-321
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-kotlin-sdk.yml around lines 113 - 119, Update both checkout steps in the release workflow, including the step identified by the repository checkout configuration and the other checkout referenced in the comment, to set persist-credentials to false. Keep the existing validated ref and checkout behavior unchanged.Source: Linters/SAST tools
149-159: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDefault-enabled caching in a release build (cache poisoning surface).
actions/cache@v4(cargo) andgradle/actions/setup-gradle@v4cache-write by default. The cargo cache'srestore-keysexplicitly falls back tokotlin-sdk-cargo-, which reads like the prefix used by the regular CI build workflow — if that workflow's cache-writing trigger can be influenced by less-trusted contexts, this release build could restore a poisoned cache entry into a build that gets attached to a public release and published to Maven Central.I can't confirm the actual trigger/permissions of the sibling CI build workflow (
kotlin-sdk-build.yml) from the files in this diff. Could you confirm what triggers populate thekotlin-sdk-cargo-/kotlin-sdk-release-cargo-cache keys, and whether any of those triggers run with write access to the default-branch cache scope in a context influenced by external contributors?Also applies to: 176-177
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-kotlin-sdk.yml around lines 149 - 159, Review the cache configuration in the release workflow, including the cargo cache restore step and the Gradle setup step, and confirm which workflows populate the kotlin-sdk-cargo- and kotlin-sdk-release-cargo- key prefixes. Restrict release builds to trusted cache sources by removing the fallback to the regular CI prefix and disabling cache writes or otherwise enforcing read-only behavior unless the triggering context is trusted; verify the sibling build workflow’s triggers and permissions do not allow externally influenced runs to populate the default-branch cache scope.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/skills/release/SKILL.md:
- Line 97: Update the SDK rerun guidance in the release workflow instructions to
require explicit confirmation from the release owner immediately before running
either release-kotlin-sdk.yml or release-swift-sdk.yml. Keep the existing
tag-ref dispatch commands and clarify that confirmation is required because
reruns may attach assets or deploy to Maven Central.
In @.github/workflows/release-kotlin-sdk.yml:
- Around line 45-47: Update the concurrency group in the release Kotlin SDK
workflow to use the normalized tag produced by
steps.release-ref.outputs.tag_name instead of the raw inputs.tag, and apply the
same normalization to both deploy and build concurrency groups so refs/tags and
plain-tag release paths serialize together.
In @.github/workflows/release-swift-sdk.yml:
- Around line 38-40: Normalize the accepted tag input before constructing the
concurrency group in the release workflow, removing the optional refs/tags/
prefix so both dispatch forms produce the same key. Update the concurrency group
expression associated with inputs.tag while preserving cancel-in-progress:
false.
---
Nitpick comments:
In @.github/workflows/release-kotlin-sdk.yml:
- Around line 113-119: Update both checkout steps in the release workflow,
including the step identified by the repository checkout configuration and the
other checkout referenced in the comment, to set persist-credentials to false.
Keep the existing validated ref and checkout behavior unchanged.
- Around line 149-159: Review the cache configuration in the release workflow,
including the cargo cache restore step and the Gradle setup step, and confirm
which workflows populate the kotlin-sdk-cargo- and kotlin-sdk-release-cargo- key
prefixes. Restrict release builds to trusted cache sources by removing the
fallback to the regular CI prefix and disabling cache writes or otherwise
enforcing read-only behavior unless the triggering context is trusted; verify
the sibling build workflow’s triggers and permissions do not allow externally
influenced runs to populate the default-branch cache scope.
In @.github/workflows/release-swift-sdk.yml:
- Around line 85-88: Update the repository checkout step in the release workflow
to disable persisted credentials, matching the configuration used by the
release-kotlin-sdk workflow; add the appropriate actions/checkout option
alongside ref in the existing checkout step.
- Around line 107-113: Update the “Cache cargo registry” step in the release
workflow to disable or remove the default-enabled Cargo cache, matching the
safer behavior used by the Kotlin release workflow. Preserve the existing
release build while eliminating the cache-poisoning surface from the
actions/cache configuration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: fb67b49e-1993-4eb8-851b-9c41f944dcb1
📒 Files selected for processing (8)
.claude/skills/release/SKILL.md.github/workflows/kotlin-sdk-release.yml.github/workflows/release-kotlin-sdk.yml.github/workflows/release-swift-sdk.yml.github/workflows/release.yml.github/workflows/swift-sdk-release.ymldocs/RELEASE_WORKFLOWS_CONSOLIDATION_SPEC.mdpackages/kotlin-sdk/PUBLISHING.md
💤 Files with no reviewable changes (2)
- .github/workflows/kotlin-sdk-release.yml
- .github/workflows/swift-sdk-release.yml
thepastaclaw
left a comment
There was a problem hiding this comment.
Preliminary review — Codex only
The consolidation generally preserves credential isolation and validates release tags correctly, but exact-head verification confirms three blocking release-integrity and operability gaps. Existing GitHub assets are not tied to the Maven build, accepted tag aliases bypass all same-release concurrency locks, and the documented v4.1.0-rc.1 verification dispatch cannot load workflows absent from that tag; the SDK rerun guidance should also require explicit release-owner confirmation.
Validated blockers were found in the Codex precheck. Sonnet is deferred until a fresh Codex revalidation clears the blocker gate.
Review provenance
- Codex reviewers:
gpt-5.6-sol— general (completed),gpt-5.6-sol— ffi-engineer (completed) - Verifier:
gpt-5.6-sol— verifier - Sonnet: not run (deferred by blocker gate)
🔴 3 blocking | 🟡 1 suggestion(s)
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `.github/workflows/release-kotlin-sdk.yml`:
- [BLOCKING] .github/workflows/release-kotlin-sdk.yml:211-215: An existing AAR is not tied to the build Maven Central will publish
This guard identifies a previous AAR only by filename, but the workflow always uploads the current build's JNI libraries and the deploy job checks out the current build SHA to assemble the Maven artifacts. If an earlier run attached an AAR from commit A, the tag is later force-moved, and a recovery run builds commit B, this step leaves A's GitHub asset untouched while Maven Central receives B under the same platform version. The current tag guard proves only that the new run built the tag's current commit; it provides no provenance for the existing asset. Persist and validate a commit or artifact digest alongside the release asset, or make deployment consume and verify the exact build represented by the attached AAR.
- [BLOCKING] .github/workflows/release-kotlin-sdk.yml:45-47: Raw tag aliases bypass the per-release concurrency locks
Both SDK workflows accept `vX.Y.Z` and `refs/tags/vX.Y.Z`, but their job-level concurrency keys use the unnormalized input. Those spellings therefore create separate locks for the same release in the Kotlin build, Kotlin deploy, and Swift build jobs. Concurrent runs can both pass the asset-exists guards; the pinned `softprops/action-gh-release` action defaults `overwrite_files` to true and explicitly resolves same-name upload races by deleting and re-uploading the competing asset. On Swift, that can leave the zip and checksum sourced from different runs, while parallel Kotlin deploy jobs can both attempt the same immutable Maven version. Derive the locks from one canonical identity such as the run's validated tag ref, enforce that a dispatch input matches that ref, and disable release-asset overwrites as a final defense.
In `docs/RELEASE_WORKFLOWS_CONSOLIDATION_SPEC.md`:
- [BLOCKING] docs/RELEASE_WORKFLOWS_CONSOLIDATION_SPEC.md:257-262: The documented v4.1.0-rc.1 dispatch cannot load these workflows
The `v4.1.0-rc.1` tag resolves to `08152ea51e`, and that tree contains neither `release-kotlin-sdk.yml` nor `release-swift-sdk.yml`; both files are introduced by this PR. A `workflow_dispatch --ref` run uses the workflow at the selected branch or tag, so the proposed post-merge dispatches at `v4.1.0-rc.1` cannot start. This also makes the advertised emergency path unavailable for every platform tag predating the consolidation. Provide a secure rerun path whose workflow definition exists at the dispatch ref, or explicitly restrict reruns to tags containing these workflows and replace the rc.1 verification plan with an executable test.
In `.claude/skills/release/SKILL.md`:
- [SUGGESTION] .claude/skills/release/SKILL.md:97: Require release-owner confirmation before SDK reruns
The newly documented commands can attach public release assets and, for Kotlin, automatically publish an irrevocable Maven Central version because the environment has no approval gate. Unlike the initial release command, this rerun guidance does not require human confirmation immediately before execution. Require explicit confirmation from the release owner before dispatching either SDK workflow, while retaining the existing tag-ref commands.
- reject refs/tags/ alias spellings of the dispatch tag input in both SDK release workflows: the per-tag concurrency groups key on the raw inputs.tag (GHA expressions cannot normalize strings), so aliases minted separate locks and could race the asset-exists guards; attach steps also pass overwrite_files: false so a residual same-name race fails loudly - tie the attached AAR to the commit Maven Central will publish: the AAR now attaches together with a dash-sdk-android-<version>.commit.txt provenance asset, and a recovery run may proceed to the Maven deploy only when the recorded commit equals its own built commit (mismatched or half-attached pairs hard-fail), so a force-moved tag can no longer ship different commits to the two channels - skip the Maven deploy job on non-tag run refs instead of failing at the environment tag policy, making a dev-branch dispatch (the only way to attach assets for tags predating these workflow files) run green - docs: dispatch input is the plain tag name only; the re-run path exists only for post-consolidation tags (older tags: branch dispatch attaches assets, Maven via the manual runbook); require release-owner confirmation before SDK re-run dispatches; fix the spec's dry-run plan accordingly Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/release-kotlin-sdk.yml (1)
77-95: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse one strict platform-tag regex in both SDK workflows. The current expression accepts values outside the documented
vX.Y.Z[-pre.N]contract, allowing invalid SDK/Maven versions.
.github/workflows/release-kotlin-sdk.yml#L77-L95: replace the permissive[.-]suffix matcher with a hyphen-delimited SemVer prerelease matcher..github/workflows/release-swift-sdk.yml#L58-L76: apply the identical strict matcher so Kotlin and Swift accept the same tags.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release-kotlin-sdk.yml around lines 77 - 95, Replace the permissive tag-validation regex in .github/workflows/release-kotlin-sdk.yml lines 77-95 with a strict hyphen-delimited SemVer prerelease matcher for the documented vX.Y.Z[-pre.N] contract, preserving plain-tag and multiline-input rejection. Apply the identical matcher in .github/workflows/release-swift-sdk.yml lines 58-76 so both SDK workflows accept exactly the same platform tags.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release-swift-sdk.yml:
- Around line 196-203: Update the Swift release asset guard before the “Attach
XCFramework to the platform release” step to include a
DashSDKFFI-<version>.commit.txt provenance asset alongside the existing
zip/checksum checks. Validate that this commit file matches the current release
commit, and only then set steps.tag-guard.outputs.asset_exists to true;
otherwise allow the workflow to upload the current XCFramework and persist its
commit provenance, mirroring the Kotlin workflow.
---
Outside diff comments:
In @.github/workflows/release-kotlin-sdk.yml:
- Around line 77-95: Replace the permissive tag-validation regex in
.github/workflows/release-kotlin-sdk.yml lines 77-95 with a strict
hyphen-delimited SemVer prerelease matcher for the documented vX.Y.Z[-pre.N]
contract, preserving plain-tag and multiline-input rejection. Apply the
identical matcher in .github/workflows/release-swift-sdk.yml lines 58-76 so both
SDK workflows accept exactly the same platform tags.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 061338b6-bab4-4d6d-9763-0bbf5e7da250
📒 Files selected for processing (5)
.claude/skills/release/SKILL.md.github/workflows/release-kotlin-sdk.yml.github/workflows/release-swift-sdk.ymldocs/RELEASE_WORKFLOWS_CONSOLIDATION_SPEC.mdpackages/kotlin-sdk/PUBLISHING.md
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/kotlin-sdk/PUBLISHING.md
…ssets Mirror the Kotlin AAR guard: the zip attaches together with a DashSDKFFI-<version>.commit.txt recording the built commit, and existing assets are reused only when that recorded commit equals the commit the current run built — so a tag force-moved after the original attach fails the re-run loudly instead of leaving a green run whose assets came from a different commit. A partial asset set (interrupted attach) also hard-fails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
thepastaclaw
left a comment
There was a problem hiding this comment.
Preliminary review — Codex only
All four carried-forward findings are fixed at the current head: Kotlin asset provenance is validated, tag aliases are rejected, pre-consolidation reruns have an executable branch-ref path, and release-owner confirmation is required. The current head also resolves CodeRabbit's Swift provenance finding by treating the zip, checksum, and commit record as one validated asset set. However, the latest delta introduces one new blocking authorization gap because Maven deployment accepts any tag run ref instead of requiring the run ref to match the release tag being published.
Validated blockers were found in the Codex precheck. Sonnet is deferred until a fresh Codex revalidation clears the blocker gate.
Review provenance
- Codex reviewers:
gpt-5.6-sol— general (completed),gpt-5.6-sol— ffi-engineer (completed) - Verifier:
gpt-5.6-sol— verifier - Sonnet: not run (deferred by blocker gate)
🔴 1 blocking
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `.github/workflows/release-kotlin-sdk.yml`:
- [BLOCKING] .github/workflows/release-kotlin-sdk.yml:295: Require the deploy ref to match the target release tag
This condition verifies only that the workflow run uses some tag ref; it does not bind that ref to `inputs.tag`, which controls the checked-out commit and Maven version. A manual dispatch can therefore run the workflow from tag A while passing tag B, causing the protected `maven-central` job to publish B under authorization granted by A's `v*` environment policy. This also bypasses the documented restriction for pre-consolidation tags: an operator can select a newer tag containing the workflow and publish an older input tag through CI instead of using the manual runbook. Maven versions are immutable, so require the run ref to equal the exact target tag.
The deploy job gate accepted any tag ref, so a workflow_dispatch started at tag A with tag B as input could publish B under the environment authorization earned by A's ref. Require github.ref to equal refs/tags/<inputs.tag> exactly; branch-ref dispatches still skip cleanly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Codex + Sonnet
The only carried-forward blocking finding (prior-1: Maven deploy job must bind to the exact target release tag, not merely any tag ref) is verified fixed at head a8867d1 — release-kotlin-sdk.yml:297 now reads github.ref == format('refs/tags/{0}', inputs.tag). The CodeRabbit Swift provenance finding was likewise already fixed in an earlier commit (54dfd52) and remains correct at head. The latest delta (54dfd52..a8867d1) introduces no new defects — it is a single-line hardening of the Maven deploy guard. One suggestion-level architecture observation carries over from the FFI review round: the Kotlin AAR attached to the GitHub release and the AAR staged for Maven Central are two independent Gradle builds with no byte-parity check between them, though the native .so boundary is pinned identical via a shared artifact upload.
Review provenance
- Codex reviewers:
gpt-5.6-sol— general (completed),gpt-5.6-sol— ffi-engineer (completed) - Verifier:
claude-sonnet-5— final-verifier - Sonnet reviewers:
claude-sonnet-5— general (failed),claude-sonnet-5— ffi-engineer (failed),claude-sonnet-5— general (completed),claude-sonnet-5— ffi-engineer (completed)
🟡 1 suggestion(s)
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `.github/workflows/release-kotlin-sdk.yml`:
- [SUGGESTION] .github/workflows/release-kotlin-sdk.yml:188-409: GitHub-attached AAR and Maven Central AAR are independently rebuilt, not reused byte-for-byte
The `build-and-release` job runs `./gradlew :sdk:assembleRelease` (line 188) to produce the AAR attached to the GitHub release. The `maven-central-deploy` job checks out the same commit, restores the same native `.so` files via `actions/download-artifact` (lines 384-387), but re-invokes Gradle from scratch (`:sdk:publishReleasePublicationToStagingRepository`, lines 407-409) to build the AAR actually staged and pushed to Maven Central. These are two separate AGP `bundleReleaseAar` invocations on two different runners. `verifyStagedAarForRemotePublish` only checks that the staged AAR contains the required JNI `.so` entries — it never compares the staged AAR against the GitHub-attached one. Since the native `.so` boundary is explicitly pinned identical via the shared artifact, the exposure is limited to non-native packaging (classes.jar, resources, R.txt, POM/manifest), so this is unlikely to break the FFI contract in practice, but there is no guarantee today that a consumer verifying the GitHub asset gets byte-parity with the immutable Maven Central artifact.
Issue being fixed or feature implemented
The monorepo versions and releases everything under a single
vX.Y.Ztag, but the Kotlin SDK (kotlin-sdk-*tags) and Swift FFI (ffi-*tags) had independent release workflows in their own tag namespaces. Neither was ever used — no such tag was ever pushed and nothing is published to Maven Central — while the actual SDK releases should carry the platform version like every other artifact.What was done?
Publishing the platform GitHub release for
vX.Y.Z[-pre.N]now also:dash-sdk-android-<version>.aarto that same release and publishesorg.dashj:dash-sdk-android:<version>to Maven Central,DashSDKFFI-<version>.xcframework.zip+ its SwiftPM checksum,via two new reusable workflows (
release-kotlin-sdk.yml,release-swift-sdk.yml) called fromrelease.yml, following the existingrelease-docker-image.ymlpattern. The standalonekotlin-sdk-release.yml/swift-sdk-release.ymland their tag triggers are removed.Details:
workflow_callcontext: unprotected build job → deploy job whose fiveJRELEASER_*secrets exist only as environment secrets on themaven-centralenvironment (deployment tag policyv*, already configured). Guards kept: tag force-move check, never-overwrite-attached-asset, all-or-nothing secrets gate (skip-with-notice when unconfigured, hard-fail when partial), deploy checkout pinned to the built SHA. New: skip-with-notice when the version is already on Maven Central, so re-runs are idempotent.workflow_dispatchfor re-releasing just one SDK for an existing platform release — must be dispatched at the tag ref (gh workflow run release-kotlin-sdk.yml --ref vX.Y.Z -f tag=vX.Y.Z); refuses branches, nonexistent tags, and tags without a published release (it can never create one). Per-tag concurrency groups prevent same-tag races.tag_name+files— the platform release's notes, title and prerelease flag are never touched. Caller jobs elevatepermissions: contents: writejob-level only; nosecrets: inherit(the SDK builds need no repo/org secrets; environment secrets resolve via the deploy job'senvironment:declaration).softprops/action-gh-releaseis pinned to a commit SHA (v2.6.2).PUBLISHING.mdCI-path section (incl. docs(kotlin-sdk): maven-central environment infra runbook (infra half of #4193) #4220's environment/secrets guidance adapted to platform tags), release skill runbook, and the design spec (docs/RELEASE_WORKFLOWS_CONSOLIDATION_SPEC.md).Supersedes #4193 and #4220 (workflow code absorbed with credit; the standalone tag namespace is retired).
How Has This Been Tested?
actionlintclean on both new workflow files (remainingrelease.ymlfindings are pre-existing, untouched sections).v4.1.0-rc.1tag ref — assets attach to that release without modifying its notes; Maven deploy skips-with-notice until the environment secrets are installed, publishes once they are. The next published prerelease exercises therelease: publishedpath end-to-end.Breaking Changes
None for consumers (no
ffi-*/kotlin-sdk-*tag was ever released). Operationally: SDK releases now happen only via the platform release;release.yml's manual dispatch path intentionally skips the SDK jobs (dispatch runs at a branch ref, which themaven-centraltag policy rejects — use the per-SDK dispatch instead).Checklist:
For repository code-owners and collaborators only
🤖 Generated with Claude Code
Summary by CodeRabbit