Skip to content

Fix syntax error in ai_core_manager.sh at line 184 #13

Fix syntax error in ai_core_manager.sh at line 184

Fix syntax error in ai_core_manager.sh at line 184 #13

name: Android APK Build Preparation
on:
push:
branches: [ main, 'copilot/**' ]
paths:
- 'scripts/**'
- 'docs/ANDROID_INTEGRATION.md'
- 'android/**'
- '.github/workflows/android-apk-build.yml'
pull_request:
branches: [ main ]
paths:
- 'scripts/**'
- 'docs/ANDROID_INTEGRATION.md'
- 'android/**'
- '.github/workflows/android-apk-build.yml'
release:
types: [published]
workflow_dispatch:
inputs:
build_type:
description: 'Build type (debug/release)'
required: true
default: 'debug'
type: choice
options:
- debug
- release
action:
description: 'Action to perform'
required: true
default: 'prepare'
type: choice
options:
- prepare
- build
notify_completion:
description: 'Send notification when complete'
required: false
default: true
type: boolean
env:
JAVA_VERSION: '17'
ANDROID_API_LEVEL: '34'
ANDROID_BUILD_TOOLS_VERSION: '34.0.0'
GRADLE_VERSION: '8.4'
jobs:
prepare-build:
runs-on: ubuntu-latest
timeout-minutes: 45
outputs:
preparation-status: ${{ steps.prepare.outputs.status }}
build-ready: ${{ steps.prepare.outputs.build-ready }}
environment-hash: ${{ steps.prepare.outputs.env-hash }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Java JDK
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'temurin'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
api-level: ${{ env.ANDROID_API_LEVEL }}
build-tools: ${{ env.ANDROID_BUILD_TOOLS_VERSION }}
- name: Create Android Project Structure
run: |
echo "Creating Android project structure..."
mkdir -p android/app/src/main/{java/com/spiralgang/filesystemds,res/{layout,values,drawable}}
mkdir -p android/app/src/main/assets
# Create build.gradle (Project level)
cat > android/build.gradle << 'EOF'
buildscript {
ext.kotlin_version = "1.9.20"
dependencies {
classpath 'com.android.tools.build:gradle:8.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
EOF
# Create build.gradle (App level)
cat > android/app/build.gradle << 'EOF'
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.spiralgang.filesystemds'
compileSdk 34
defaultConfig {
applicationId "com.spiralgang.filesystemds"
minSdk 24
targetSdk 34
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
debug {
debuggable true
applicationIdSuffix ".debug"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.10.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
EOF
# Create gradle.properties
cat > android/gradle.properties << 'EOF'
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official
android.nonTransitiveRClass=true
EOF
# Create settings.gradle
cat > android/settings.gradle << 'EOF'
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "FileSystemds"
include ':app'
EOF
- name: Create Android Manifest
run: |
cat > android/app/src/main/AndroidManifest.xml << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FileSystemds"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
EOF
- name: Create Android Source Files
run: |
# Create MainActivity.kt
cat > android/app/src/main/java/com/spiralgang/filesystemds/MainActivity.kt << 'EOF'
package com.spiralgang.filesystemds
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.textView)
textView.text = "FileSystemds Mobile Platform\nVersion: ${BuildConfig.VERSION_NAME}"
}
}
EOF
# Create layout
cat > android/app/src/main/res/layout/activity_main.xml << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FileSystemds Mobile Platform"
android:textSize="18sp"
android:textStyle="bold"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
EOF
# Create strings.xml
cat > android/app/src/main/res/values/strings.xml << 'EOF'
<resources>
<string name="app_name">FileSystemds</string>
</resources>
EOF
# Create themes.xml
cat > android/app/src/main/res/values/themes.xml << 'EOF'
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.FileSystemds" parent="Theme.Material3.DayNight">
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorError">@color/red_600</item>
<item name="colorOnError">@color/white</item>
<item name="colorSurface">@color/white</item>
<item name="colorOnSurface">@color/black</item>
<item name="status_bar_color" tools:targetApi="l">?attr/colorPrimaryVariant</item>
</style>
</resources>
EOF
# Create colors.xml
cat > android/app/src/main/res/values/colors.xml << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="red_600">#FFE53E3E</color>
</resources>
EOF
# Copy platform scripts to assets
mkdir -p android/app/src/main/assets/scripts
cp scripts/*.sh android/app/src/main/assets/scripts/ || echo "No scripts to copy yet"
- name: Setup Gradle Wrapper
run: |
cd android
gradle wrapper --gradle-version ${{ env.GRADLE_VERSION }}
chmod +x gradlew
- name: Cache Gradle Dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
android/.gradle
key: ${{ runner.os }}-gradle-${{ hashFiles('android/**/*.gradle*', 'android/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Prepare or Build APK
id: prepare
run: |
cd android
BUILD_TYPE="${{ github.event.inputs.build_type || 'debug' }}"
ACTION="${{ github.event.inputs.action || 'prepare' }}"
echo "Action: $ACTION"
echo "Build Type: $BUILD_TYPE"
# Always prepare the environment first
echo "Preparing Android build environment..."
# Validate Android project structure
if [ ! -f "build.gradle" ] || [ ! -f "app/build.gradle" ]; then
echo "❌ Android project structure validation failed"
echo "status=failed" >> $GITHUB_OUTPUT
echo "build-ready=false" >> $GITHUB_OUTPUT
exit 1
fi
# Check dependencies and setup
echo "✓ Android project structure validated"
echo "✓ Gradle wrapper configured"
echo "✓ Dependencies cached"
# Generate environment hash for tracking
ENV_HASH=$(echo "$BUILD_TYPE-$(date +%Y%m%d)" | sha256sum | cut -d' ' -f1 | head -c 8)
echo "env-hash=$ENV_HASH" >> $GITHUB_OUTPUT
# Create preparation manifest
cat > preparation_manifest.json << EOF
{
"preparation_id": "$ENV_HASH",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"commit_sha": "${{ github.sha }}",
"build_type": "$BUILD_TYPE",
"status": "prepared",
"build_ready": true,
"trigger_required": true,
"environment_validated": true,
"dependencies_cached": true
}
EOF
if [ "$ACTION" = "build" ]; then
echo "🏗️ Building APK as requested..."
if [ "$BUILD_TYPE" = "release" ]; then
./gradlew assembleRelease
APK_PATH="app/build/outputs/apk/release/app-release.apk"
APK_NAME="filesystemds-mobile-$(date +%Y%m%d-%H%M%S)-release.apk"
else
./gradlew assembleDebug
APK_PATH="app/build/outputs/apk/debug/app-debug.apk"
APK_NAME="filesystemds-mobile-$(date +%Y%m%d-%H%M%S)-debug.apk"
fi
# Check if APK was built successfully
if [ -f "$APK_PATH" ]; then
echo "✅ APK built successfully: $APK_PATH"
# Rename APK with timestamp
mv "$APK_PATH" "app/build/outputs/apk/$APK_NAME"
# Set outputs for successful build
echo "apk-path=android/app/build/outputs/apk/$APK_NAME" >> $GITHUB_OUTPUT
echo "apk-name=$APK_NAME" >> $GITHUB_OUTPUT
echo "status=build-complete" >> $GITHUB_OUTPUT
echo "build-ready=true" >> $GITHUB_OUTPUT
# Get APK info
aapt dump badging "app/build/outputs/apk/$APK_NAME" || echo "Could not get APK info"
else
echo "❌ APK build failed"
echo "status=build-failed" >> $GITHUB_OUTPUT
echo "build-ready=false" >> $GITHUB_OUTPUT
exit 1
fi
else
echo "📋 Environment prepared successfully!"
echo "🚨 APK BUILD READY - Manual trigger required"
echo ""
echo "To build the APK, run:"
echo " - Go to Actions tab"
echo " - Select 'Android APK Build Preparation'"
echo " - Click 'Run workflow'"
echo " - Select action: 'build'"
echo " - Select build type: '$BUILD_TYPE'"
echo ""
# Update manifest for preparation only
sed -i 's/"status": "prepared"/"status": "ready-for-build"/' preparation_manifest.json
echo "status=ready-for-build" >> $GITHUB_OUTPUT
echo "build-ready=true" >> $GITHUB_OUTPUT
fi
- name: Upload Preparation Manifest
uses: actions/upload-artifact@v4
with:
name: preparation-manifest-${{ steps.prepare.outputs.env-hash }}
path: android/preparation_manifest.json
retention-days: 7
- name: Upload APK Artifact
if: github.event.inputs.action == 'build' && steps.prepare.outputs.status == 'build-complete'
uses: actions/upload-artifact@v4
with:
name: ${{ steps.prepare.outputs.apk-name }}
path: ${{ steps.prepare.outputs.apk-path }}
retention-days: 30
- name: Create Release APK
if: github.event_name == 'release' && github.event.inputs.action == 'build' && steps.prepare.outputs.status == 'build-complete'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ${{ steps.prepare.outputs.apk-path }}
asset_name: ${{ steps.prepare.outputs.apk-name }}
asset_content_type: application/vnd.android.package-archive
notify-completion:
runs-on: ubuntu-latest
needs: prepare-build
if: always() && (github.event.inputs.notify_completion == 'true' || github.event.inputs.notify_completion == '')
steps:
- name: Notify Preparation/Build Status
run: |
STATUS="${{ needs.prepare-build.outputs.preparation-status }}"
BUILD_READY="${{ needs.prepare-build.outputs.build-ready }}"
ENV_HASH="${{ needs.prepare-build.outputs.environment-hash }}"
ACTION="${{ github.event.inputs.action || 'prepare' }}"
if [ "$ACTION" = "build" ]; then
if [ "$STATUS" = "build-complete" ]; then
echo "🎉 APK Build Completed Successfully!"
echo "Status: Build Complete"
echo "Environment: $ENV_HASH"
echo "APK is ready for download from GitHub Actions artifacts."
else
echo "❌ APK Build Failed"
echo "Status: $STATUS"
echo "Please check the build logs for details."
fi
else
if [ "$BUILD_READY" = "true" ]; then
echo "📋 APK Build Environment Prepared Successfully!"
echo "🚨 READY TO BUILD APK - MANUAL TRIGGER REQUIRED"
echo ""
echo "Status: $STATUS"
echo "Environment Hash: $ENV_HASH"
echo "Build Ready: $BUILD_READY"
echo ""
echo "Next Steps:"
echo "1. Go to the Actions tab in GitHub"
echo "2. Select 'Android APK Build Preparation'"
echo "3. Click 'Run workflow'"
echo "4. Select action: 'build'"
echo "5. Choose your build type"
echo "6. Click 'Run workflow' to build the APK"
echo ""
echo "The environment is fully prepared and validated."
echo "All dependencies are cached and ready."
echo "The APK build will complete in ~2-3 minutes once triggered."
else
echo "❌ APK Build Preparation Failed"
echo "Status: $STATUS"
echo "Please check the preparation logs for details."
fi
fi
- name: Create Build Ready Comment
if: github.event_name == 'pull_request' && needs.prepare-build.outputs.build-ready == 'true' && github.event.inputs.action != 'build'
uses: actions/github-script@v7
with:
script: |
const status = '${{ needs.prepare-build.outputs.preparation-status }}';
const envHash = '${{ needs.prepare-build.outputs.environment-hash }}';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 📋 APK Build Environment Ready!
**Status:** ${status}
**Environment Hash:** \`${envHash}\`
**Build Ready:** ✅ Yes
### 🚨 Manual APK Build Trigger Required
The Android build environment has been prepared and validated. All dependencies are cached and the project structure is ready.
**To build the APK:**
1. Go to [Actions tab](https://github.com/${{ github.repository }}/actions/workflows/android-apk-build.yml)
2. Click "Run workflow"
3. Select action: **build**
4. Choose build type: debug or release
5. Click "Run workflow"
The APK build will complete in ~2-3 minutes once triggered.
**Build Details:**
- Commit: ${{ github.sha }}
- Branch: ${{ github.ref_name }}
- Preparation Time: $(date)
Ready to build when you are! 🚀`
})
- name: Create APK Download Comment
if: github.event_name == 'pull_request' && needs.prepare-build.outputs.preparation-status == 'build-complete'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 📱 APK Build Completed Successfully!
**APK Name:** \`${{ needs.prepare-build.outputs.apk-name }}\`
**Download Link:** [Download APK Artifact](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
**Build Details:**
- Build Type: ${{ github.event.inputs.build_type || 'debug' }}
- Commit: ${{ github.sha }}
- Branch: ${{ github.ref_name }}
The APK has been built and is ready for testing!`
})