ci: pin every version CI depends on - #17
Draft
dsnsgithub wants to merge 6 commits into
Draft
Conversation
CI was breaking on changes nobody made here: an upstream MMKVCore release, a new Xcode on the macOS image, a floating action tag. Pin the whole toolchain so a green run stays reproducible. Workflows: - runs-on macos-26 / ubuntu-24.04 instead of the *-latest aliases, which follow new OS releases and swap Xcode, simulator runtimes and CocoaPods underneath an unchanged build - third-party actions pinned to full commit SHAs instead of floating major tags, with the version in a trailing comment - move shared toolchain setup into .github/actions/setup so all pinned versions live in one file: Bun 1.3.14, Node 24.18.0 (macOS) / 22.23.2 (Ubuntu), Temurin 21.0.11+10, Xcode 26.6, CocoaPods 1.17.0, Maestro 2.8.0 - select Xcode explicitly rather than inheriting the image default, and fail with the list of installed versions if the pinned one is gone - force the pinned CocoaPods through a PATH shim; EAS resolves `pod` from PATH, so pinning the gem alone loses to a newer preinstalled version - fetch Maestro as an immutable release asset instead of piping get.maestro.mobile.dev, which installs whatever is newest - pin the iOS simulator runtime (26.5) as well as the device model Dependencies: - exact versions everywhere, no carets or tildes. bun ci is already frozen, but ranges still let a plain `bun install` drift, and they silently break patchedDependencies: react-native-mmkv floating to 3.3.4 would drop the app-group path patch with nothing failing until a widget misbehaved - turbo: latest -> 2.7.1 (the version the lockfile already resolved) - pin EAS CLI to 22.0.0 in the mobile scripts and eas.json - bun.lock workspace ranges updated to match; no resolutions changed Adds .github/README.md documenting where each pin lives, how to bump one, and what still can't be pinned. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
dsnsgithub
marked this pull request as draft
August 20, 2026 12:04
Use exact patch tags (@v6.1.0) instead of commit SHAs. A tag can be force-moved by the maintainer where a SHA cannot, but exact tags are far easier to read and bump and still close the floating-major hole that broke CI in the first place. futureware-tech/simulator-action only publishes major tags, so @v4 stays as the most specific pin available. Drop the .github/actions/setup composite and inline its steps, keeping the action list to the five already in use. Each workflow now declares its own tool versions in a top-level env: block. This also drops actions/setup-node, so Node is no longer pinned explicitly. Pinning the runner image label pins it in practice — the major version can't change within a given image — but patch bumps land. Recorded in .github/README.md alongside the other things that can't be fully pinned. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC
Audited every native dependency on both platforms. iOS, resolved from the CocoaPods CDN rather than node_modules: - PostHog was the one real gap. posthog-react-native-session-replay's podspec asks for `~> 3.21`, which today resolves to 3.69.8 — 115 published versions satisfy that range and the newest landed yesterday. Pin it in the app target's Podfile, same mechanism as MMKVCore. - Everything else is local: react-native-mmkv compiles MMKV from vendored source, NotifeeCore builds from a local subspec, and Quick/Nimble/ OHHTTPStubs/ExpoModulesTestCore are test_spec-only so they are never installed. Android, verified already deterministic: - app.notifee:core:+ resolves against notifee's bundled file repo, which ships exactly one version (202108261754) and is published to no remote. - com.facebook.react:react-native:+ is substituted by the RN Gradle plugin to the exact react-native version. - org.webkit:android-jsc:+ has a single Maven Central artifact (r174650, 2015) and jsc-android is not installed. - Kotlin/Compose/Coil/Fresco versions interpolate from properties fixed inside their own packages. Verified the Podfile change by running `expo prebuild --platform ios`: the pin lands inside `target 'Scheduli'` and the MMKV block is intact. Also drops the comments from the workflows and the .github/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC
`21.0.11+10` came from the Adoptium API release name, but setup-java matches against its own list where the same build reads `21.0.11+10.0.LTS`. When the requested version carries build metadata setup-java requires an exact compareBuild match, so `+10` never matched `+10.0.LTS` and every macOS job failed at Install Java. Use `21.0.11`. With no build metadata setup-java falls through to a normal semver range, which ignores build metadata and resolves to the single available 21.0.11 build. Still an exact JDK patch pin, and it does not depend on how Adoptium renders the build suffix — which is what broke. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC
main moved android builds to ubuntu (#14) and setup-java to v5 (#15), both touching the two android workflows this branch rewrote. Kept main's decisions and re-applied the pinning on top: - android runners are ubuntu, pinned to ubuntu-24.04 rather than ubuntu-latest - setup-java is v5, pinned to v5.7.0 rather than the floating v5 - test-ios.yml carries setup-java too, so it moves to v5.7.0 as well for consistency, though it did not conflict Verified before resolving that java-version 21.0.11 still holds: v5.7.0's isVersionSatisfies keeps the same semantics for a range without build metadata, and Temurin jdk-21.0.11+10 is published for linux x64, which the move to ubuntu now requires. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC
Drop the per-workflow env: blocks. Every version now sits at its use site, like the action tags already did. Select Xcode is one line: xcode-select --switch already exits non-zero on a path that is not there, so the existence check and the error message were restating the failure it produces anyway. Pin CocoaPods is one line. The PATH shim it replaces only mattered if a future runner image ships CocoaPods newer than the pin, since `pod` resolves to the newest installed version. Install Maestro is three lines: fetch the pinned release asset, unzip, add to PATH. The launcher is a Gradle start script that resolves its own location, so extracting outside ~/.maestro is fine, and curl -f already fails on a version that does not exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CI was breaking on changes nobody made here: an upstream MMKVCore release, a new Xcode on the macOS image, a floating action tag. Pin everything CI depends on so a green run stays reproducible.
Workflows
*-latestaliases, which follow new OS releases and swap Xcode, simulator runtimes and CocoaPods underneath an unchanged build:macos-26for iOS,ubuntu-24.04elsewhere.@v6.1.0) instead of floating majors (@v6).futureware-tech/simulator-actiononly publishes major tags, so@v4is the most specific pin available there.xcode-select --switchexits non-zero on a missing path, so a retired Xcode fails the job outright instead of silently falling through to whatever the image ships.get.maestro.mobile.dev, which installs whatever is newest from a script that can itself change.26.5) is pinned alongside the device model.JavaScript dependencies
bun ciis already frozen, but ranges still let a plainbun installdrift, and they silently breakpatchedDependencies:react-native-mmkvfloating to 3.3.4 would drop the app-group path patch with nothing failing until a widget misbehaved.turbo: latest→2.7.1, the version the lockfile had already resolved.eas.json.bun.lockworkspace ranges updated to match; no resolutions changed.Native dependencies
Audited every podspec and
build.gradlein the tree for versions resolved from a remote registry rather than fromnode_modules.posthog-react-native-session-replay's podspec asks forPostHog ~> 3.21, satisfied by 115 published versions and currently resolving to 3.69.8. Now pinned in the app target's Podfile, same mechanism as MMKVCore.react-native-mmkvcompiles MMKV from vendored source,NotifeeCorebuilds from a local subspec, and Quick/Nimble/OHHTTPStubs/ExpoModulesTestCore aretest_spec-only so they are never installed.app.notifee:core:+resolves against notifee's bundled file repo, which ships exactly one version and is published to neither Maven Central nor Google Maven;com.facebook.react:react-native:+is substituted by the RN Gradle plugin to the exact react-native version;org.webkit:android-jsc:+has a single Maven Central artifact from 2015; and the Kotlin/Compose/Coil/Fresco interpolations read properties fixed inside their own packages.Merge with main
mainmoved android builds to ubuntu (#14) and setup-java to v5 (#15) while this was open. Both decisions are kept, with the pinning re-applied on top: android runs onubuntu-24.04rather thanubuntu-latest, and setup-java is@v5.7.0rather than the floating@v5.Verification
Every job is green on this branch: lint, typecheck, test-web, test-android on
ubuntu-24.04, and the full iOS run onmacos-26including the Maestro suite. Between them they exercise the Xcode select, the CocoaPods pin, the Maestro download, the simulator runtime pin, and the PostHog pod resolving duringpod install.What still isn't pinned
gem install cocoapods -v 1.17.0guarantees that version is present, butpodresolves to the newest installed, and EAS callspodfrom PATH. Todaymacos-26ships exactly 1.17.0 so the pin holds; a future image shipping newer CocoaPods would win.macos-26orubuntu-24.04goes, the job fails immediately with an unknown-label error rather than drifting — that is the intended failure mode, but it does mean re-pinning Xcode and CocoaPods to whatever the next image ships.android/project requests, which is set by the pinned Expo/React Native versions.Claude-Session: https://claude.ai/code/session_01QRXxEuKNzgWvK2RxJjQ8TC