Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 119 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,97 @@ on:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
inputs:
run_macos_native:
description: 'Run macOS-only MAUI iOS and full KMP checks'
required: false
type: boolean
default: false

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
HUSKY: 0
NX_DAEMON: false
NX_NO_CLOUD: true
NX_DISABLE_DB: true

jobs:
js:
name: JS/TS packages
runs-on: ubuntu-latest
env:
HUSKY: 0
NX_DAEMON: false
NX_NO_CLOUD: true
NX_DISABLE_DB: true
runs-on: [self-hosted]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install --ignore-scripts
- run: npm ci --ignore-scripts
- run: npm run build
- run: npm run lint
- run: npm test

flutter:
name: Flutter package
runs-on: ubuntu-latest
runs-on: [self-hosted]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- uses: android-actions/setup-android@v3
with:
packages: tools platform-tools build-tools;35.0.0 platforms;android-35
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.x'
channel: 'stable'
- name: Trust Flutter SDK checkout
run: git config --global --add safe.directory "$FLUTTER_ROOT"
- run: cd packages/sdk-flutter && flutter pub get
- run: cd packages/sdk-flutter && flutter analyze

maui:
name: .NET MAUI SDK
maui-android:
name: .NET MAUI Android SDK
runs-on: [self-hosted]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- uses: android-actions/setup-android@v3
with:
packages: tools platform-tools build-tools;35.0.0 platforms;android-35
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Install MAUI workloads
run: dotnet workload install maui-android
- name: Restore
run: dotnet restore packages/sdk-maui/ScreebMaui.csproj -p:TargetFramework=net9.0-android
- name: Build Android
run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-android --no-restore
- name: Run unit tests
run: dotnet test packages/sdk-maui/tests/ScreebUtilsTests.csproj

maui-ios:
name: .NET MAUI iOS SDK
runs-on: macos-latest
if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_macos_native }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Install MAUI workloads
run: dotnet workload install android ios
run: dotnet workload install ios
- name: Download Screeb iOS XCFramework
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -56,9 +106,63 @@ jobs:
cp -r /tmp/screeb_ios/Screeb.xcframework packages/sdk-maui/native/ios/
- name: Restore
run: dotnet restore packages/sdk-maui/ScreebMaui.csproj
- name: Build Android
run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-android --no-restore
- name: Build iOS
run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-ios --no-restore
- name: Run unit tests
run: dotnet test packages/sdk-maui/tests/ScreebUtilsTests.csproj

kmp-android:
name: Kotlin Multiplatform Android SDK
runs-on: [self-hosted]
steps:
- uses: actions/checkout@v4
- name: Check native Android artifact
id: native-android
run: |
version=$(sed -n 's/^SCREEB_ANDROID_SDK_VERSION=//p' packages/sdk-kmp/gradle.properties | head -n1)
url="https://repo.maven.apache.org/maven2/app/screeb/sdk/survey/${version}/survey-${version}.pom"
echo "version=${version}" >> "$GITHUB_OUTPUT"
if curl -fsI "$url" >/dev/null; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "::warning::app.screeb.sdk:survey:${version} is not published yet; skipping KMP Android build."
echo "available=false" >> "$GITHUB_OUTPUT"
fi
- uses: actions/setup-java@v4
if: steps.native-android.outputs.available == 'true'
with:
java-version: '17'
distribution: 'temurin'
- uses: android-actions/setup-android@v3
if: steps.native-android.outputs.available == 'true'
with:
packages: tools platform-tools build-tools;35.0.0 platforms;android-35
- name: Make gradlew executable
if: steps.native-android.outputs.available == 'true'
run: chmod +x packages/sdk-kmp/gradlew
- name: Build Android target
if: steps.native-android.outputs.available == 'true'
run: cd packages/sdk-kmp && ./gradlew assembleRelease testDebugUnitTest --no-daemon

kmp-full:
name: Kotlin Multiplatform full SDK
runs-on: macos-latest
if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_macos_native }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Download Screeb iOS XCFramework
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
SCREEB_IOS_SDK_VERSION=$(grep '^SCREEB_IOS_SDK_VERSION=' packages/sdk-kmp/gradle.properties | cut -d= -f2)
mkdir -p packages/sdk-kmp/native/ios
gh release download "v${SCREEB_IOS_SDK_VERSION}" --repo ScreebApp/sdk-ios-public --pattern 'Screeb.zip' --output /tmp/Screeb.zip --clobber
unzip -q /tmp/Screeb.zip -d /tmp/screeb_ios
cp -r /tmp/screeb_ios/Screeb.xcframework packages/sdk-kmp/native/ios/
- name: Make gradlew executable
run: chmod +x packages/sdk-kmp/gradlew
- name: Build SDK
run: cd packages/sdk-kmp && ./gradlew clean build --no-daemon
48 changes: 48 additions & 0 deletions .github/workflows/publish-kmp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Publish Screeb KMP SDK

on:
push:
tags:
- 'sdk-kmp/v*'

jobs:
publish:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'

- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- run: npm run versions:check

- name: Download Screeb iOS XCFramework
run: |
set -euo pipefail
SCREEB_IOS_SDK_VERSION=$(grep '^SCREEB_IOS_SDK_VERSION=' packages/sdk-kmp/gradle.properties | cut -d= -f2)
SCREEB_IOS_URL=$(curl -sL "https://api.github.com/repos/ScreebApp/sdk-ios-public/releases/tags/v${SCREEB_IOS_SDK_VERSION}" \
| python3 -c "import sys,json; print(next(a['browser_download_url'] for a in json.load(sys.stdin)['assets'] if a['name']=='Screeb.zip'))")
curl -sL "$SCREEB_IOS_URL" -o /tmp/Screeb.zip
unzip -q /tmp/Screeb.zip -d /tmp/screeb_ios
mkdir -p packages/sdk-kmp/native/ios
cp -r /tmp/screeb_ios/Screeb.xcframework packages/sdk-kmp/native/ios/
test -d packages/sdk-kmp/native/ios/Screeb.xcframework || (echo "XCFramework not found after download" && exit 1)

- name: Make gradlew executable
run: chmod +x packages/sdk-kmp/gradlew

- name: Publish to Maven Central
working-directory: packages/sdk-kmp
env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
GPG_KEY: ${{ secrets.GPG_KEY }}
GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }}
run: ./gradlew publishAllPublicationsToOSSRHRepository --no-daemon
162 changes: 162 additions & 0 deletions docs/screeb-team-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Screeb team release workflow

Internal notes for updating wrapper versions and testing local native SDK changes before publishing.

## Version source of truth

Native and wrapper versions live in `sdk-versions.json`.

```bash
npm run versions:sync
npm run versions:check
```

Edit `sdk-versions.json`, then run `versions:sync` to update generated version references. Android and iOS native SDK versions are independent: use `native.android` for Maven Central and `native.ios` for CocoaPods/SPM.

## Local native SDK testing

Keep the repositories next to each other for the default local flow:

```text
Screeb/
sdk/
sdk-android/
sdk-ios/
```

Then build the wrapper or example with:

```bash
SCREEB_USE_LOCAL_SDK=true <normal build command>
```

Optional overrides:

```bash
SCREEB_ANDROID_SDK_PATH=/absolute/path/to/sdk-android
SCREEB_IOS_SDK_PATH=/absolute/path/to/sdk-ios
```

No native SDK release is required for this flow.

## Useful local commands

```bash
# Android native example
SCREEB_USE_LOCAL_SDK=true ./gradlew :app:assembleDebug --no-daemon \
-p examples/example-android

# React Native Android
cd examples/example-reactnative/android
SCREEB_USE_LOCAL_SDK=true ./gradlew :app:assembleDebug --no-daemon

# Flutter Android
cd examples/example-flutter/android
SCREEB_USE_LOCAL_SDK=true ./gradlew :app:assembleDebug --no-daemon

# Expo Android
cd examples/example-expo
SCREEB_USE_LOCAL_SDK=true npx expo prebuild --platform android --clean --no-install
cd android
SCREEB_USE_LOCAL_SDK=true ./gradlew :app:assembleDebug --no-daemon

# KMP
SCREEB_USE_LOCAL_SDK=true ./gradlew build --no-daemon \
-p packages/sdk-kmp

# MAUI package
SCREEB_USE_LOCAL_SDK=true dotnet build packages/sdk-maui/ScreebMaui.csproj \
-f net9.0-android
SCREEB_USE_LOCAL_SDK=true dotnet build packages/sdk-maui/ScreebMaui.csproj \
-f net9.0-ios
```

## How the local switch works

Android:

- Android and KMP Gradle builds use a local Gradle composite for `../sdk-android`.
- Flutter, React Native and Expo automatically publish `../sdk-android` to Maven local during native project configuration. This keeps their normal Maven dependency path while avoiding a manual release.
- MAUI builds the local Android AAR from `../sdk-android` and binds that AAR directly.

iOS:

- Flutter, React Native and Expo use the local `../sdk-ios` pod when `SCREEB_USE_LOCAL_SDK=true`.
- KMP and MAUI build a temporary `Screeb.xcframework` from `../sdk-ios` through `scripts/build-local-ios-xcframework.mjs`.
- Generated local artifacts stay under ignored build folders.

## SDK size report

To build wrapper artifacts and inspect local sizes:

```bash
npm run size:sdks
```

This is informational only. Use `npm run size:sdks -- --no-build` to read existing local artifacts without rebuilding.

Current iOS native release reference:

- full `Screeb.xcframework`: 1.36 MB
- iOS app embed impact: about 449.4 KB, because release apps embed only the device slice; the simulator slice is build-time only

## Public documentation references

Public API reference pages live in the docs repository:

```text
../screeb/docs/public/docs/<sdk>/reference.md
```

Regenerate them from the SDK source files after any public API, hook payload, wrapper, or documentation-link change:

```bash
npm run docs:reference:update
npm run docs:reference:check
npm run docs:reference:coverage
```

The generator is `scripts/update-public-docs-reference.mjs`. Keep extraction source-driven when possible; only edit the SDK-specific descriptions, groups, links, or known capability rules in that script.

Before publishing docs, validate the public docs app:

```bash
cd ../screeb/docs/public
pnpm typecheck
pnpm build
```

## Release validation

Run the release matrix before publishing native SDKs or wrappers:

```bash
npm run verify:release
```

To inspect the matrix without running it:

```bash
npm run verify:release -- --list
```

To run one area only:

```bash
npm run verify:release -- --scope=android
npm run verify:release -- --scope=flutter,react-native
```

The matrix uses `SCREEB_USE_LOCAL_SDK=true` by default and expects the `sdk`, `sdk-android`, and `sdk-ios` repositories to be siblings.
Set `SCREEB_IOS_TEST_DESTINATION` to override the simulator used by the iOS SDK test step.

## Release checklist

1. Bump the native SDK versions in `../sdk-android` and/or `../sdk-ios`.
2. Edit `sdk-versions.json`.
3. Run `npm run versions:sync`.
4. Run `npm run versions:check`.
5. Run `npm run verify:release`.
6. Run `npm run size:sdks`.
7. Release the native SDKs.
8. Release the public wrappers with the updated native dependency versions.
4 changes: 4 additions & 0 deletions examples/example-android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.gradle/
local.properties
build/
app/build/
Loading
Loading