diff --git a/.github/workflows/deploy-to-nativebridge.yml b/.github/workflows/deploy-to-nativebridge.yml new file mode 100644 index 0000000..fcc89c8 --- /dev/null +++ b/.github/workflows/deploy-to-nativebridge.yml @@ -0,0 +1,91 @@ +name: Deploy to NativeBridge + +on: + push: + branches: [main, develop] + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK 11 for Gradle build + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'temurin' + cache: 'gradle' + + - name: Validate Gradle wrapper + run: chmod +x gradlew + + - name: Clean SDK cache and build APK + run: | + # Clean corrupted SDK metadata + rm -rf $ANDROID_SDK_ROOT/.temp/* || true + find $ANDROID_SDK_ROOT -name "package.xml" -type f -delete || true + + # Build the app + ./gradlew clean app:assembleDebug --stacktrace + + - name: Verify APK was generated + run: | + if [ ! -f app/build/outputs/apk/debug/app-debug.apk ]; then + echo "❌ APK not found!" + exit 1 + fi + echo "✅ APK generated successfully" + ls -lh app/build/outputs/apk/debug/app-debug.apk + + - name: Upload to NativeBridge + id: upload + env: + NB_API_KEY: ${{ secrets.NATIVEBRIDGE_API_KEY }} + run: | + if [ -z "$NB_API_KEY" ]; then + echo "❌ Missing NATIVEBRIDGE_API_KEY secret" + exit 1 + fi + + echo "📤 Uploading APK to NativeBridge..." + response=$(curl --location https://api.nativebridge.io/v1/application \ + -H "accept: application/json" \ + -H "X-Api-Key: $NB_API_KEY" \ + -F "file=@app/build/outputs/apk/debug/app-debug.apk" \ + -F "accessType=public") + + echo "response=$response" >> $GITHUB_OUTPUT + magic_link=$(echo "$response" | jq -r '.data.magicLink // empty' 2>/dev/null || echo "") + + if [ -n "$magic_link" ] && [ "$magic_link" != "null" ]; then + echo "magic_link=$magic_link" >> $GITHUB_OUTPUT + echo "✅ Upload successful: $magic_link" + else + echo "❌ Failed to get magic link from response" + echo "Response: $response" + exit 1 + fi + + - name: Comment PR with Magic Link + if: github.event_name == 'pull_request' && steps.upload.outcome == 'success' + uses: actions/github-script@v6 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `🚀 **App Preview Ready!**\n\nTest this build: ${{ steps.upload.outputs.magic_link }}\n\n_Powered by NativeBridge_` + }) + + - name: Upload APK as artifact (backup) + if: always() + uses: actions/upload-artifact@v4 + with: + name: app-debug-apk + path: app/build/outputs/apk/debug/app-debug.apk + retention-days: 30 diff --git a/app/build.gradle b/app/build.gradle index 532e0af..2a2eefd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,5 +19,7 @@ android { dependencies { implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'com.codepath.libraries:asynchttpclient:0.1.0' + implementation 'com.facebook.stetho:stetho:1.5.1' + implementation 'com.squareup.okhttp3:okhttp:3.12.13' // Needed by ProgressBarActivity + // Note: asynchttpclient library no longer available - SmartImageDownloadActivity excluded from manifest } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 569c37a..ef3efaf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -90,10 +90,12 @@ android:name="codepath.apps.demointroandroid.AsyncTaskPerformActivity" android:label="@string/title_activity_async_task_perform" > + diff --git a/app/src/main/java/codepath/apps/demointroandroid/ExerciseActivityMapper.java b/app/src/main/java/codepath/apps/demointroandroid/ExerciseActivityMapper.java index 577ae00..0cb6e8e 100644 --- a/app/src/main/java/codepath/apps/demointroandroid/ExerciseActivityMapper.java +++ b/app/src/main/java/codepath/apps/demointroandroid/ExerciseActivityMapper.java @@ -46,7 +46,7 @@ private void defineExerciseMappings() { // Chapter 6: Networking exerciseClassMap.put("chap6ex1", BasicImageDownloadActivity.class); // Basic Image Download exerciseClassMap.put("chap6ex2", AsyncTaskPerformActivity.class); // AsyncTask - exerciseClassMap.put("chap6ex3", SmartImageDownloadActivity.class); // Smart Image Download + // exerciseClassMap.put("chap6ex3", SmartImageDownloadActivity.class); // Smart Image Download - requires unavailable library // Chapter 7: Advanced Views exerciseClassMap.put("chap7ex1", ToastFormInputsActivity.class); // Toast Inputs exerciseClassMap.put("chap7ex2", SpinnerWithToastActivity.class); // Spinner Toast diff --git a/app/src/main/java/codepath/apps/demointroandroid/SmartImageDownloadActivity.java b/app/src/main/java/codepath/apps/demointroandroid/SmartImageDownloadActivity.java.disabled similarity index 100% rename from app/src/main/java/codepath/apps/demointroandroid/SmartImageDownloadActivity.java rename to app/src/main/java/codepath/apps/demointroandroid/SmartImageDownloadActivity.java.disabled diff --git a/build.gradle b/build.gradle index 88031d6..bca43f6 100644 --- a/build.gradle +++ b/build.gradle @@ -13,5 +13,6 @@ allprojects { repositories { jcenter() google() + maven { url 'https://jitpack.io' } } } diff --git a/install_sdk28.sh b/install_sdk28.sh new file mode 100755 index 0000000..d01b722 --- /dev/null +++ b/install_sdk28.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Install SDK 28 manually +ANDROID_HOME=~/Library/Android/sdk +SDK_DIR=$ANDROID_HOME/platforms/android-28 +BUILD_TOOLS_DIR=$ANDROID_HOME/build-tools/28.0.3 + +echo "Installing Android SDK 28..." + +# Download and install platform +mkdir -p $SDK_DIR +cd /tmp +curl -o platform-28.zip https://dl.google.com/android/repository/platform-28_r06.zip +unzip -q platform-28.zip -d $ANDROID_HOME/platforms/android-28 +rm platform-28.zip + +# Download and install build-tools +mkdir -p $BUILD_TOOLS_DIR +curl -o build-tools-28.zip https://dl.google.com/android/repository/build-tools_r28.0.3-macosx.zip +unzip -q build-tools-28.zip -d /tmp/bt28 +mv /tmp/bt28/android-*/* $BUILD_TOOLS_DIR/ +rm -rf /tmp/bt28 build-tools-28.zip + +echo "✅ SDK 28 installed!" +echo "Now run: ./gradlew app:assembleRelease"