Skip to content

Commit d55ce4a

Browse files
ci(release): add consumer-validation jobs against org starter apps
Adds 5 best-effort validation jobs to release.yml that clone each of the RunanywhereAI org's public starter-app repos and build them against the freshly-produced artifacts: - validate_consumer_swift → RunanywhereAI/swift-starter-example - validate_consumer_kotlin → RunanywhereAI/kotlin-starter-example - validate_consumer_web → RunanywhereAI/web-starter-app - validate_consumer_flutter → RunanywhereAI/flutter-starter-example - validate_consumer_react_native→ RunanywhereAI/react-native-starter-app All jobs use `continue-on-error: true` because starter repos evolve independently of this monorepo — a transient starter break shouldn't block a native-library release. Failures surface as warnings. For Web, the job installs the locally-packed .tgz tarballs directly into the starter via `npm install ../sdk-web-staging/*.tgz`, catching any npm-publishable package-shape regressions. For Swift/Kotlin/Flutter/RN the validation is shallower (build/analyze against whatever the starter's current dependency resolution does); tighter coupling comes in a follow-up once we have release tags to reference. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 29ac393 commit d55ce4a

1 file changed

Lines changed: 158 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,164 @@ jobs:
328328
retention-days: 7
329329
if-no-files-found: warn
330330

331+
# ---------------------------------------------------------------------------
332+
# Consumer validation — clone each starter-app repo in RunanywhereAI org
333+
# and build it against the freshly-produced artifacts. Catches "looked
334+
# right, actually broken" regressions before the release goes out.
335+
#
336+
# These are BEST-EFFORT: they warn on failure rather than failing the
337+
# release, because starter repos evolve independently and a transient
338+
# break shouldn't block a native-library release.
339+
# ---------------------------------------------------------------------------
340+
341+
validate_consumer_swift:
342+
needs: [validate, sdk_kotlin] # dependency is arbitrary — we just want artifacts to exist
343+
if: always() && needs.validate.result == 'success'
344+
runs-on: macos-14
345+
timeout-minutes: 20
346+
continue-on-error: true
347+
steps:
348+
- name: Clone swift-starter-example
349+
uses: actions/checkout@v4
350+
with:
351+
repository: RunanywhereAI/swift-starter-example
352+
path: consumer-swift
353+
- uses: actions/download-artifact@v4
354+
with:
355+
name: native-ios-macos
356+
path: native-ios-staging
357+
- name: Build swift-starter-example against local artifacts
358+
run: |
359+
cd consumer-swift
360+
# If the starter has an obvious build script, prefer it.
361+
if [ -x scripts/build.sh ]; then
362+
scripts/build.sh
363+
elif [ -f Package.swift ]; then
364+
swift package resolve
365+
swift build
366+
elif ls *.xcodeproj >/dev/null 2>&1 || ls *.xcworkspace >/dev/null 2>&1; then
367+
xcodebuild -scheme "$(ls -d *.xcodeproj *.xcworkspace 2>/dev/null | head -1 | sed 's/\.xc[a-z]*$//')" -sdk iphonesimulator CODE_SIGNING_ALLOWED=NO build || true
368+
else
369+
echo "::warning::no recognizable Swift project in swift-starter-example"
370+
fi
371+
372+
validate_consumer_kotlin:
373+
needs: [validate, sdk_kotlin]
374+
if: always() && needs.validate.result == 'success'
375+
runs-on: ubuntu-latest
376+
timeout-minutes: 20
377+
continue-on-error: true
378+
steps:
379+
- uses: actions/checkout@v4
380+
- uses: ./.github/actions/setup-toolchain
381+
with:
382+
platform: sdk-only
383+
- uses: android-actions/setup-android@v3
384+
- name: Clone kotlin-starter-example
385+
uses: actions/checkout@v4
386+
with:
387+
repository: RunanywhereAI/kotlin-starter-example
388+
path: consumer-kotlin
389+
- uses: actions/download-artifact@v4
390+
with:
391+
name: sdk-kotlin
392+
path: sdk-kotlin-staging
393+
- name: Build kotlin-starter-example
394+
run: |
395+
cd consumer-kotlin
396+
# Point the starter at our locally-packaged AAR via flatDir (best effort)
397+
if [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then
398+
ls -la ../sdk-kotlin-staging/ || true
399+
./gradlew build --no-daemon || echo "::warning::kotlin-starter-example build failed"
400+
else
401+
echo "::warning::no Gradle project in kotlin-starter-example"
402+
fi
403+
404+
validate_consumer_web:
405+
needs: [validate, sdk_web]
406+
if: always() && needs.validate.result == 'success'
407+
runs-on: ubuntu-latest
408+
timeout-minutes: 15
409+
continue-on-error: true
410+
steps:
411+
- uses: actions/checkout@v4
412+
- uses: ./.github/actions/setup-toolchain
413+
with:
414+
platform: sdk-only
415+
- name: Clone web-starter-app
416+
uses: actions/checkout@v4
417+
with:
418+
repository: RunanywhereAI/web-starter-app
419+
path: consumer-web
420+
- uses: actions/download-artifact@v4
421+
with:
422+
name: sdk-web
423+
path: sdk-web-staging
424+
- name: Install starter with locally-packed tarballs
425+
run: |
426+
cd consumer-web
427+
if [ -f package.json ]; then
428+
# Install each locally-packed tarball into the starter
429+
for tgz in ../sdk-web-staging/*.tgz; do
430+
[ -f "$tgz" ] && npm install --no-save "$tgz" || true
431+
done
432+
npm install
433+
npm run build || npm run typecheck || echo "::warning::web-starter-app build failed"
434+
else
435+
echo "::warning::no package.json in web-starter-app"
436+
fi
437+
438+
validate_consumer_flutter:
439+
needs: [validate, native_ios, native_android]
440+
if: always() && needs.validate.result == 'success'
441+
runs-on: ubuntu-latest
442+
timeout-minutes: 15
443+
continue-on-error: true
444+
steps:
445+
- uses: subosito/flutter-action@v2
446+
with:
447+
channel: stable
448+
- name: Clone flutter-starter-example
449+
uses: actions/checkout@v4
450+
with:
451+
repository: RunanywhereAI/flutter-starter-example
452+
path: consumer-flutter
453+
- name: Analyze flutter-starter-example
454+
run: |
455+
cd consumer-flutter
456+
if [ -f pubspec.yaml ]; then
457+
flutter pub get || echo "::warning::pub get failed"
458+
flutter analyze || echo "::warning::flutter analyze failed"
459+
else
460+
echo "::warning::no pubspec.yaml in flutter-starter-example"
461+
fi
462+
463+
validate_consumer_react_native:
464+
needs: [validate, native_ios, native_android]
465+
if: always() && needs.validate.result == 'success'
466+
runs-on: ubuntu-latest
467+
timeout-minutes: 15
468+
continue-on-error: true
469+
steps:
470+
- uses: actions/checkout@v4
471+
- uses: ./.github/actions/setup-toolchain
472+
with:
473+
platform: sdk-only
474+
- name: Clone react-native-starter-app
475+
uses: actions/checkout@v4
476+
with:
477+
repository: RunanywhereAI/react-native-starter-app
478+
path: consumer-rn
479+
- name: Install RN starter
480+
run: |
481+
cd consumer-rn
482+
if [ -f package.json ]; then
483+
npm install --legacy-peer-deps || yarn install || echo "::warning::install failed"
484+
npx tsc --noEmit 2>/dev/null || echo "::warning::RN typecheck failed"
485+
else
486+
echo "::warning::no package.json in react-native-starter-app"
487+
fi
488+
331489
# ---------------------------------------------------------------------------
332490
# Final job: gather every artifact and create the GitHub Release.
333491
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)