Summary
The nightly "Update Dependencies" workflow opens PRs that bump the sentry-cocoa submodule, but it never regenerates the auto-generated C# bindings. Whenever the new Cocoa release changes its public API, the bindings drift and the .NET (macos) CI job fails on the dirty-check. Fixing it is pure grunt work (clone, build Cocoa from source, regenerate, commit) that we repeat on every API-changing bump. This issue proposes automating it.
Most recent instance: #5264 (Cocoa 9.18.0), which failed because 9.18.0 added SentrySDK.extendAppLaunch / finishExtendedAppLaunch.
Root cause
- The bump PRs are created by
.github/workflows/update-deps.yml, which calls the shared getsentry/github-workflows/updater action in a matrix on ubuntu-latest. For Cocoa it only moves the modules/sentry-cocoa submodule pointer.
- Regenerating bindings (
scripts/generate-cocoa-bindings.ps1) hard-requires macOS — it needs Xcode, Objective Sharpie and Xamarin.iOS, and explicitly errors out when !$IsMacOS.
- So regeneration cannot happen on the Linux updater job. Today it happens nowhere, and the macOS CI build is simply the first thing to detect the drift via
dirty-check.ps1, which fails the build by design:
src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj(152,5): error MSB3073:
The command "pwsh ../../scripts/dirty-check.ps1 ... Sentry.Bindings.Cocoa/" exited with code 1.
...
Write-Error: scripts/dirty-check.ps1:14 | Dirty files detected.
The dirty files are always src/Sentry.Bindings.Cocoa/ApiDefinitions.cs and/or StructsAndEnums.cs.
Proposed plan (preferred): use the updater's post-update-script hook on a macOS runner
The getsentry/github-workflows/updater action exposes a built-in input:
post-update-script — "Optional script to run after successful dependency update. Can be a bash script (.sh) or PowerShell script (.ps1). The script will be executed in the caller-repo directory before PR creation."
Since it's a composite action, it runs on the calling job's runner. So the fix is two coordinated tweaks to update-deps.yml:
- Move only the Cocoa matrix leg to a macOS runner (e.g.
runs-on: ${{ matrix.os || 'ubuntu-latest' }} with the Cocoa entry setting os: macos-15). Java / Native / CLI stay on Linux.
- Give the Cocoa entry a
post-update-script that initialises the submodule, builds the Cocoa SDK from source, and runs the binding generator (effectively the _SetupCocoaSDK MSBuild target, or a thin wrapper around scripts/build-sentry-cocoa.sh + scripts/generate-cocoa-bindings.ps1).
Because the hook runs before PR creation, in the repo dir, the regenerated ApiDefinitions.cs / StructsAndEnums.cs are folded into the same commit/PR the updater already makes. No second commit, no push-back, no loop, no extra auth. The PR opens already-green. changelog-entry: false is already set, so the binding churn stays out of the changelog.
Caveats / acceptance criteria
- The script must reproduce CI's path exactly (build from the submodule source →
Carthage/Headers), or the dirty-check will still differ. That's the ~17 min Xcode build — acceptable for a nightly, and only the Cocoa leg pays it.
- macOS runners bill at a higher multiplier and are slower; this only runs once a night and only when a Cocoa bump actually lands (the hook runs only "after successful dependency update").
- Runner needs Xcode + Sharpie + Xamarin.iOS. The generator already auto-installs Sharpie (brew) and the pinned Xamarin.iOS pkg, and the existing macOS CI build proves
macos-15 can do the whole thing.
- The wrapper likely needs
git submodule update --init modules/sentry-cocoa before building, since the updater only moves the pointer.
- Done when: a Cocoa bump that changes public API produces a single PR that is green on
.NET (macos) with no manual intervention.
Summary
The nightly "Update Dependencies" workflow opens PRs that bump the
sentry-cocoasubmodule, but it never regenerates the auto-generated C# bindings. Whenever the new Cocoa release changes its public API, the bindings drift and the.NET (macos)CI job fails on thedirty-check. Fixing it is pure grunt work (clone, build Cocoa from source, regenerate, commit) that we repeat on every API-changing bump. This issue proposes automating it.Most recent instance: #5264 (Cocoa 9.18.0), which failed because 9.18.0 added
SentrySDK.extendAppLaunch/finishExtendedAppLaunch.Root cause
.github/workflows/update-deps.yml, which calls the sharedgetsentry/github-workflows/updateraction in a matrix onubuntu-latest. For Cocoa it only moves themodules/sentry-cocoasubmodule pointer.scripts/generate-cocoa-bindings.ps1) hard-requires macOS — it needs Xcode, Objective Sharpie and Xamarin.iOS, and explicitly errors out when!$IsMacOS.dirty-check.ps1, which fails the build by design:The dirty files are always
src/Sentry.Bindings.Cocoa/ApiDefinitions.csand/orStructsAndEnums.cs.Proposed plan (preferred): use the updater's
post-update-scripthook on a macOS runnerThe
getsentry/github-workflows/updateraction exposes a built-in input:Since it's a composite action, it runs on the calling job's runner. So the fix is two coordinated tweaks to
update-deps.yml:runs-on: ${{ matrix.os || 'ubuntu-latest' }}with the Cocoa entry settingos: macos-15). Java / Native / CLI stay on Linux.post-update-scriptthat initialises the submodule, builds the Cocoa SDK from source, and runs the binding generator (effectively the_SetupCocoaSDKMSBuild target, or a thin wrapper aroundscripts/build-sentry-cocoa.sh+scripts/generate-cocoa-bindings.ps1).Because the hook runs before PR creation, in the repo dir, the regenerated
ApiDefinitions.cs/StructsAndEnums.csare folded into the same commit/PR the updater already makes. No second commit, no push-back, no loop, no extra auth. The PR opens already-green.changelog-entry: falseis already set, so the binding churn stays out of the changelog.Caveats / acceptance criteria
Carthage/Headers), or the dirty-check will still differ. That's the ~17 min Xcode build — acceptable for a nightly, and only the Cocoa leg pays it.macos-15can do the whole thing.git submodule update --init modules/sentry-cocoabefore building, since the updater only moves the pointer..NET (macos)with no manual intervention.