-
Notifications
You must be signed in to change notification settings - Fork 435
Device runtime: run pushed Codename One apps on a phone #5561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
shai-almog
wants to merge
57
commits into
master
Choose a base branch
from
device-runtime
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+26,251
−167
Open
Changes from all commits
Commits
Show all changes
57 commits
Select commit
Hold shift + click to select a range
defe78e
Add a device runtime that runs pushed Codename One apps on a phone
shai-almog 4542c23
Add store metadata and a weekly build for the device runtime
shai-almog c6c6ada
Device runtime: move interp under impl, generate the shims, authentic…
shai-almog 3118d71
Give the probe programs the standard header
shai-almog 7e92c49
Markdown javadoc and a header the gates asked for
shai-almog d4d7ad9
Clear the SpotBugs findings in the push tool
shai-almog 1356d05
Answer the second review round
shai-almog 47fd057
Fix the two gates the guide and the CLDC build enforce
shai-almog 3155e0b
Add StackOverflowError to the CLDC11 stub
shai-almog 7a54e8f
Bring the device runtime chapter up to the guide's prose gate
shai-almog f86bfb2
Restore CRLF in AndroidImplementation
shai-almog 79950c6
Clear the LanguageTool gate for the device runtime chapter
shai-almog b91272a
Let the vtable spike translate under a strict native-signature check
shai-almog 58d244d
Clear PMD and Checkstyle for the interpreter
shai-almog fd6744b
Answer the third review round
shai-almog 9131f21
Fix a mangled identifier in the iOS symbol reader
shai-almog 5ce1185
Update the symbol-row test for the interfaces column
shai-almog 5fbf0a3
Answer the fourth review round
shai-almog 9b7d77f
Answer the fifth review round
shai-almog 273783f
Answer the sixth review round
shai-almog 9748ff8
Answer the seventh review round
shai-almog 4f9540b
Answer the eighth review round
shai-almog 110ac22
Answer the ninth review round
shai-almog 612a5af
Answer the tenth review round
shai-almog 26111b3
Answer the eleventh review round
shai-almog e5cde7d
Carry the native half of the subsystems worth a device
shai-almog dd981e8
Mock the subsystems that cannot be real, instead of excluding them
shai-almog a9c30b4
Answer the twelfth review round
shai-almog 0c0a846
Answer the thirteenth review round
shai-almog f242778
Answer the fourteenth review round
shai-almog 07913a3
Answer the fifteenth review round
shai-almog 1ccc6d7
Name only exceptions the device has
shai-almog 1929de4
Answer the sixteenth review round
shai-almog 525c99d
Only write java.io.File's native bodies where the class survives
shai-almog 44b22f9
Answer the seventeenth review round
shai-almog c448acc
Answer the eighteenth review round
shai-almog 6508109
Answer the nineteenth review round
shai-almog 20180da
Answer the twentieth review round
shai-almog 0af4958
Answer the twenty-first review round
shai-almog c260b3a
Answer the twenty-second review round
shai-almog 48fe18a
Answer the twenty-third review round
shai-almog dff7808
Answer the twenty-fourth review round
shai-almog a26a610
Answer the twenty-fifth review round
shai-almog 1b5ab70
Answer the twenty-sixth review round
shai-almog f88e517
Answer the twenty-seventh review round
shai-almog fcf6635
Answer the twenty-eighth review round
shai-almog da7dfea
Answer the twenty-ninth review round
shai-almog d817420
Answer the thirtieth review round
shai-almog 2a98bef
Answer the thirty-first review round
shai-almog 20fa329
Answer the thirty-second review round
shai-almog fd07b5f
Answer the thirty-third review round
shai-almog e1f0489
Answer the thirty-fourth review round
shai-almog 8593d2f
Answer the thirty-fifth review round
shai-almog 151e06e
Answer the thirty-sixth review round
shai-almog 1f4396d
Answer the thirty-seventh review round
shai-almog f0e9a6d
Answer the thirty-eighth review round
shai-almog 4dc4c12
Answer the thirty-ninth review round
shai-almog File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,262 @@ | ||
| # Weekly build of the device runtime for testers. | ||
| # | ||
| # Uploads to Google Play internal testing and to TestFlight. It does not promote | ||
| # to production and does not submit for App Store review -- see | ||
| # scripts/cn1-device-runtime/store/README.md for why that is deliberate. | ||
| # | ||
| # Without credentials the job reports what is missing and stops. It never | ||
| # publishes half of a release. | ||
| name: Device runtime store build | ||
|
|
||
| on: | ||
| schedule: | ||
| # Monday morning, so a failure has a working week in front of it. | ||
| - cron: '0 6 * * 1' | ||
| workflow_dispatch: | ||
| inputs: | ||
| dry_run: | ||
| description: 'Build and check credentials without uploading' | ||
| type: boolean | ||
| default: false | ||
|
|
||
| concurrency: | ||
| group: device-runtime-store | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| preflight: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| android: ${{ steps.check.outputs.android }} | ||
| ios: ${{ steps.check.outputs.ios }} | ||
| steps: | ||
| - id: check | ||
| name: Which stores are configured | ||
| env: | ||
| PLAY_JSON: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }} | ||
| KEYSTORE: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | ||
| KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} | ||
| KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | ||
| KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | ||
| IOS_CERT: ${{ secrets.IOS_DIST_CERT_P12 }} | ||
| IOS_CERT_PASSWORD: ${{ secrets.IOS_DIST_CERT_PASSWORD }} | ||
| IOS_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }} | ||
| ASC_KEY: ${{ secrets.APPSTORE_PRIVATE_KEY }} | ||
| ASC_KEY_ID: ${{ secrets.APPSTORE_KEY_ID }} | ||
| ASC_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }} | ||
| run: | | ||
| # Every secret the job will actually consume, not just the two that | ||
| # name the store. A partial configuration used to pass here, spend | ||
| # half an hour building, and then fail in the signing step -- which is | ||
| # the opposite of what a preflight is for. | ||
| android=true | ||
| ios=true | ||
| missing="" | ||
| for name in PLAY_JSON KEYSTORE KEYSTORE_PASSWORD KEY_ALIAS KEY_PASSWORD; do | ||
| if [ -z "${!name}" ]; then android=false; missing="$missing android:$name"; fi | ||
| done | ||
| for name in IOS_CERT IOS_CERT_PASSWORD IOS_PROFILE ASC_KEY ASC_KEY_ID ASC_ISSUER_ID; do | ||
| if [ -z "${!name}" ]; then ios=false; missing="$missing ios:$name"; fi | ||
| done | ||
| if [ -n "$missing" ]; then | ||
| echo "missing secrets:$missing" | ||
| fi | ||
| echo "android=$android" >> "$GITHUB_OUTPUT" | ||
| echo "ios=$ios" >> "$GITHUB_OUTPUT" | ||
| echo "### Device runtime store build" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "| Store | Configured |" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "|---|---|" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "| Google Play | $android |" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "| App Store | $ios |" >> "$GITHUB_STEP_SUMMARY" | ||
| if [ -n "$missing" ]; then | ||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "Secrets that are absent:\`$missing\`" >> "$GITHUB_STEP_SUMMARY" | ||
| fi | ||
| if [ "$android" = false ] && [ "$ios" = false ]; then | ||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "No publishing credentials are present, so nothing was uploaded." >> "$GITHUB_STEP_SUMMARY" | ||
| echo "The secrets each store needs are listed in" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "\`scripts/cn1-device-runtime/store/README.md\`." >> "$GITHUB_STEP_SUMMARY" | ||
| fi | ||
|
|
||
| android: | ||
| needs: preflight | ||
| if: needs.preflight.outputs.android == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: JDK 8 for the framework, JDK 17 for the Android port | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: | | ||
| 8 | ||
| 17 | ||
|
|
||
| - name: Build the framework and the Android port | ||
| env: | ||
| # setup-java makes the LAST version listed the default, so JAVA_HOME | ||
| # is 17 here despite the step name. The framework build wants 8 -- the | ||
| # newer JDK trips JaCoCo -- and the Android port wants 17, so each | ||
| # command names its own. | ||
| JAVA8: ${{ env.JAVA_HOME_8_X64 }} | ||
| run: | | ||
| export JAVA_HOME="$JAVA8" | ||
| export PATH="$JAVA_HOME/bin:$PATH" | ||
| cd maven | ||
| mvn -B -q -DskipTests install -pl core,parparvm -am | ||
| mvn -B -q -DskipTests -Pcompile-android install -pl android | ||
|
|
||
| - name: Verify the shim generator | ||
| # The app build generates the shims; this asserts the properties that | ||
| # build takes on faith. It fails if a shim will not compile, if a | ||
| # load-bearing shim is missing, or if generating twice differs -- all of | ||
| # which are release blockers. | ||
| run: scripts/generate-interp-shims.sh | ||
|
|
||
| - name: Build the app bundle | ||
| env: | ||
| JAVA17_HOME: ${{ env.JAVA_HOME_17_X64 }} | ||
| run: | | ||
| # A store rejects an upload that reuses a version code, and the app's | ||
| # version is a fixed 1.0 -- so every scheduled run after the first | ||
| # would be refused. The run number is monotonic and unique per repo, | ||
| # which is exactly what a build number has to be. It has to travel as | ||
| # codename1.arg.*: that is the prefix CN1BuildMojo copies into the | ||
| # BuildRequest, and android.versionCode is what the Gradle builder | ||
| # reads from it. | ||
| cd scripts/cn1-device-runtime | ||
| mvn -B -q package -DskipTests \ | ||
| -Dcodename1.platform=android \ | ||
| -Dcodename1.buildTarget=android-source \ | ||
| -Dcodename1.arg.android.versionCode=${{ github.run_number }} \ | ||
| -Dopen=false | ||
|
|
||
| - name: Sign and assemble | ||
| env: | ||
| KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | ||
| KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} | ||
| KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | ||
| KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | ||
| run: | | ||
| set -euo pipefail | ||
| gradle_dir="$(find scripts/cn1-device-runtime/android/target -maxdepth 1 \ | ||
| -name '*-android-source' -type d | head -1)" | ||
| [ -n "$gradle_dir" ] || { echo "no gradle project was generated" >&2; exit 1; } | ||
| echo "$KEYSTORE_B64" | base64 -d > "$gradle_dir/upload.keystore" | ||
| cd "$gradle_dir" | ||
| ./gradlew --no-daemon bundleRelease \ | ||
| -Pandroid.injected.signing.store.file=upload.keystore \ | ||
| -Pandroid.injected.signing.store.password="$KEYSTORE_PASSWORD" \ | ||
| -Pandroid.injected.signing.key.alias="$KEY_ALIAS" \ | ||
| -Pandroid.injected.signing.key.password="$KEY_PASSWORD" | ||
|
|
||
| - name: Upload to internal testing | ||
| if: ${{ !inputs.dry_run }} | ||
| uses: r0adkll/upload-google-play@v1 | ||
| with: | ||
| serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }} | ||
| packageName: com.codenameone.devruntime | ||
| releaseFiles: scripts/cn1-device-runtime/android/target/*-android-source/app/build/outputs/bundle/release/*.aab | ||
| track: internal | ||
| status: completed | ||
| whatsNewDirectory: scripts/cn1-device-runtime/fastlane/metadata/android/en-US/changelogs | ||
|
|
||
| ios: | ||
| needs: preflight | ||
| if: needs.preflight.outputs.ios == 'true' | ||
| runs-on: macos-14 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: JDK 8 for the framework, JDK 17 for the translator | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: | | ||
| 8 | ||
| 17 | ||
|
|
||
| - name: Build the framework, translator and iOS port | ||
| env: | ||
| JAVA8: ${{ env.JAVA_HOME_8_X64 }} | ||
| run: | | ||
| # As above: the last JDK listed to setup-java is the default, and the | ||
| # framework build wants 8. | ||
| export JAVA_HOME="$JAVA8" | ||
| export PATH="$JAVA_HOME/bin:$PATH" | ||
| cd maven | ||
| mvn -B -q -DskipTests install -pl core,parparvm,ios -am | ||
|
|
||
| - name: Verify the shim generator | ||
| run: scripts/generate-interp-shims.sh | ||
|
|
||
| - name: Translate to Xcode | ||
| env: | ||
| JAVA17_HOME: ${{ env.JAVA_HOME_17_X64 }} | ||
| run: | | ||
| cd scripts/cn1-device-runtime | ||
| # As on Android: TestFlight refuses a build number it has seen, and | ||
| # the app's version stays 1.0 between releases. ios.bundleVersion is | ||
| # the argument IPhoneBuilder reads for CFBundleVersion, and it has to | ||
| # be dotted numerics, so the run number becomes the third component. | ||
| mvn -B -q package -DskipTests \ | ||
| -Dcodename1.platform=ios \ | ||
| -Dcodename1.buildTarget=ios-source \ | ||
| -Dcodename1.arg.ios.interpHost=true \ | ||
| -Dcodename1.arg.ios.bundleVersion=1.0.${{ github.run_number }} \ | ||
| -Dopen=false | ||
|
|
||
| - name: Import signing material | ||
| env: | ||
| CERT_P12: ${{ secrets.IOS_DIST_CERT_P12 }} | ||
| CERT_PASSWORD: ${{ secrets.IOS_DIST_CERT_PASSWORD }} | ||
| PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }} | ||
| run: | | ||
| set -euo pipefail | ||
| keychain=build.keychain | ||
| security create-keychain -p actions "$keychain" | ||
| security default-keychain -s "$keychain" | ||
| security unlock-keychain -p actions "$keychain" | ||
| echo "$CERT_P12" | base64 -d > cert.p12 | ||
| security import cert.p12 -k "$keychain" -P "$CERT_PASSWORD" \ | ||
| -T /usr/bin/codesign | ||
| security set-key-partition-list -S apple-tool:,apple: -s -k actions "$keychain" | ||
| mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | ||
| echo "$PROFILE" | base64 -d > \ | ||
| ~/Library/MobileDevice/Provisioning\ Profiles/devruntime.mobileprovision | ||
|
|
||
| - name: Archive and export | ||
| run: | | ||
| set -euo pipefail | ||
| src="$(find scripts/cn1-device-runtime/ios/target -maxdepth 1 \ | ||
| -name '*-ios-source' -type d | head -1)" | ||
| [ -n "$src" ] || { echo "no Xcode project was generated" >&2; exit 1; } | ||
| # Resolved before the cd: the export options live at a fixed place in | ||
| # the repo, and the generated project's depth is not ours to predict. | ||
| export_options="$PWD/scripts/cn1-device-runtime/store/ExportOptions.plist" | ||
| cd "$src" | ||
| xcodebuild -workspace CN1DeviceRuntime.xcworkspace \ | ||
| -scheme CN1DeviceRuntime -configuration Release \ | ||
| -archivePath build/CN1DeviceRuntime.xcarchive archive | ||
| xcodebuild -exportArchive \ | ||
| -archivePath build/CN1DeviceRuntime.xcarchive \ | ||
| -exportPath build/ipa \ | ||
| -exportOptionsPlist "$export_options" | ||
|
|
||
| - name: Upload to TestFlight | ||
| if: ${{ !inputs.dry_run }} | ||
| env: | ||
| ASC_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }} | ||
| ASC_KEY_ID: ${{ secrets.APPSTORE_KEY_ID }} | ||
| ASC_PRIVATE_KEY: ${{ secrets.APPSTORE_PRIVATE_KEY }} | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p ~/private_keys | ||
| echo "$ASC_PRIVATE_KEY" > ~/private_keys/AuthKey_$ASC_KEY_ID.p8 | ||
| src="$(find scripts/cn1-device-runtime/ios/target -maxdepth 1 \ | ||
| -name '*-ios-source' -type d | head -1)" | ||
| xcrun altool --upload-app -f "$src"/build/ipa/*.ipa -t ios \ | ||
| --apiKey "$ASC_KEY_ID" --apiIssuer "$ASC_ISSUER_ID" | ||
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.