From 32aa6ef50272106df4e44454d1c1d65c70e5ca36 Mon Sep 17 00:00:00 2001 From: Daniel Alome Date: Thu, 8 Jan 2026 11:28:05 +0100 Subject: [PATCH 1/2] Add PluginBuilder Gradle plugin for .cgp file generation --- .github/workflows/release.yml | 25 ++++-- .gitignore | 7 +- .../androidide/plugins/build/PluginBuilder.kt | 78 +++++++++++++++++++ .../plugins/build/PluginBuilderExtension.kt | 7 ++ 4 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilder.kt create mode 100644 plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilderExtension.kt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b12946e5f..a154af988a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,13 @@ permissions: on: schedule: - cron: '0 12 * * *' # Daily at 12:00 PM UTC - workflow_dispatch: # + workflow_dispatch: + inputs: + branch: + description: 'Branch to build from (leave empty for normal stage->main merge flow)' + required: false + default: '' + type: string env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -35,6 +41,7 @@ jobs: name: Merge stage to main runs-on: self-hosted timeout-minutes: 10 + if: ${{ github.event.inputs.branch == '' }} steps: - name: Cancel previous runs @@ -143,12 +150,13 @@ jobs: runs-on: self-hosted timeout-minutes: 10 needs: merge_stage_to_main + if: ${{ always() && (needs.merge_stage_to_main.result == 'success' || needs.merge_stage_to_main.result == 'skipped') }} steps: - name: Checkout repository uses: actions/checkout@v4 with: - ref: main + ref: ${{ github.event.inputs.branch || 'main' }} - name: Check if Nix is installed id: check_nix @@ -266,7 +274,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - ref: main + ref: ${{ github.event.inputs.branch || 'main' }} - name: Authenticate to Google Cloud for Drive access id: auth_drive @@ -426,6 +434,7 @@ jobs: runs-on: self-hosted timeout-minutes: 60 needs: [merge_stage_to_main, download_assets, download_documentation] + if: ${{ always() && (needs.merge_stage_to_main.result == 'success' || needs.merge_stage_to_main.result == 'skipped') && needs.download_assets.result == 'success' && needs.download_documentation.result == 'success' }} strategy: matrix: include: @@ -440,12 +449,16 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - ref: main + ref: ${{ github.event.inputs.branch || 'main' }} - - name: Set branch to main for build + - name: Set branch for build id: determine_branch run: | - echo "BRANCH_TO_CHECKOUT=main" >> $GITHUB_OUTPUT + BRANCH="${{ github.event.inputs.branch }}" + if [ -z "$BRANCH" ]; then + BRANCH="main" + fi + echo "BRANCH_TO_CHECKOUT=$BRANCH" >> $GITHUB_OUTPUT - name: Download release assets uses: actions/download-artifact@v4 diff --git a/.gitignore b/.gitignore index a35ab1b49a..2163e9dfae 100755 --- a/.gitignore +++ b/.gitignore @@ -128,11 +128,16 @@ tests/test-home /sample-plugin/build/ /keystore-generator-plugin/build/ /keystore-generator-plugin/.kotlin/ -**/build +**/build/ +!**/src/**/build/ # Release files *.zim +# Plugin build artifacts +plugin-api.jar +plugin-artifacts.zip + # Other IDEs .cursor/ .vscode/ diff --git a/plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilder.kt b/plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilder.kt new file mode 100644 index 0000000000..48b6b19583 --- /dev/null +++ b/plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilder.kt @@ -0,0 +1,78 @@ +package com.itsaky.androidide.plugins.build + +import org.gradle.api.Plugin +import org.gradle.api.Project +import java.io.File + +class PluginBuilder : Plugin { + + override fun apply(target: Project) { + val extension = target.extensions.create( + "pluginBuilder", + PluginBuilderExtension::class.java + ) + + target.afterEvaluate { + createDebugTask(target, extension) + createReleaseTask(target, extension) + } + } + + private fun createDebugTask(project: Project, extension: PluginBuilderExtension) { + val task = project.tasks.create("assemblePluginDebug") + task.group = "build" + task.description = "Assembles the debug plugin and creates .cgp file" + task.dependsOn("assembleDebug") + + task.doLast(object : org.gradle.api.Action { + override fun execute(t: org.gradle.api.Task) { + val pluginName = extension.pluginName.getOrElse(project.name) + val apkDir = File(project.buildDir, "outputs/apk/debug") + val outputDir = File(project.buildDir, "plugin") + outputDir.mkdirs() + + project.logger.lifecycle("Looking for APK in: ${apkDir.absolutePath}") + + val apkFile = apkDir.listFiles()?.firstOrNull { it.extension == "apk" } + if (apkFile == null) { + project.logger.warn("No APK found in ${apkDir.absolutePath}") + return + } + + val outputFile = File(outputDir, "$pluginName-debug.cgp") + apkFile.copyTo(outputFile, overwrite = true) + apkFile.delete() + project.logger.lifecycle("Plugin assembled: ${outputFile.absolutePath}") + } + }) + } + + private fun createReleaseTask(project: Project, extension: PluginBuilderExtension) { + val task = project.tasks.create("assemblePlugin") + task.group = "build" + task.description = "Assembles the release plugin and creates .cgp file" + task.dependsOn("assembleRelease") + + task.doLast(object : org.gradle.api.Action { + override fun execute(t: org.gradle.api.Task) { + val pluginName = extension.pluginName.getOrElse(project.name) + val apkDir = File(project.buildDir, "outputs/apk/release") + val outputDir = File(project.buildDir, "plugin") + outputDir.mkdirs() + + project.logger.lifecycle("Looking for APK in: ${apkDir.absolutePath}") + + val apkFile = apkDir.listFiles()?.firstOrNull { it.extension == "apk" } + if (apkFile == null) { + project.logger.warn("No APK found in ${apkDir.absolutePath}") + return + } + + val outputFile = File(outputDir, "$pluginName.cgp") + apkFile.copyTo(outputFile, overwrite = true) + apkFile.delete() + project.logger.lifecycle("Plugin assembled: ${outputFile.absolutePath}") + } + }) + } +} \ No newline at end of file diff --git a/plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilderExtension.kt b/plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilderExtension.kt new file mode 100644 index 0000000000..5a27f6032e --- /dev/null +++ b/plugin-api/plugin-builder/src/main/kotlin/com/itsaky/androidide/plugins/build/PluginBuilderExtension.kt @@ -0,0 +1,7 @@ +package com.itsaky.androidide.plugins.build + +import org.gradle.api.provider.Property + +abstract class PluginBuilderExtension { + abstract val pluginName: Property +} \ No newline at end of file From 3988d8a84af17db098a8b5342ab09ac68a94c92a Mon Sep 17 00:00:00 2001 From: Daniel Alome Date: Thu, 8 Jan 2026 12:06:34 +0100 Subject: [PATCH 2/2] revert release.yml --- .github/workflows/release.yml | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a154af988a..79a2a52beb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,13 +8,7 @@ permissions: on: schedule: - cron: '0 12 * * *' # Daily at 12:00 PM UTC - workflow_dispatch: - inputs: - branch: - description: 'Branch to build from (leave empty for normal stage->main merge flow)' - required: false - default: '' - type: string + workflow_dispatch: # env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -41,7 +35,6 @@ jobs: name: Merge stage to main runs-on: self-hosted timeout-minutes: 10 - if: ${{ github.event.inputs.branch == '' }} steps: - name: Cancel previous runs @@ -150,13 +143,12 @@ jobs: runs-on: self-hosted timeout-minutes: 10 needs: merge_stage_to_main - if: ${{ always() && (needs.merge_stage_to_main.result == 'success' || needs.merge_stage_to_main.result == 'skipped') }} steps: - name: Checkout repository uses: actions/checkout@v4 with: - ref: ${{ github.event.inputs.branch || 'main' }} + ref: main - name: Check if Nix is installed id: check_nix @@ -274,7 +266,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - ref: ${{ github.event.inputs.branch || 'main' }} + ref: main - name: Authenticate to Google Cloud for Drive access id: auth_drive @@ -434,7 +426,6 @@ jobs: runs-on: self-hosted timeout-minutes: 60 needs: [merge_stage_to_main, download_assets, download_documentation] - if: ${{ always() && (needs.merge_stage_to_main.result == 'success' || needs.merge_stage_to_main.result == 'skipped') && needs.download_assets.result == 'success' && needs.download_documentation.result == 'success' }} strategy: matrix: include: @@ -449,16 +440,12 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - ref: ${{ github.event.inputs.branch || 'main' }} + ref: main - - name: Set branch for build + - name: Set branch to main for build id: determine_branch run: | - BRANCH="${{ github.event.inputs.branch }}" - if [ -z "$BRANCH" ]; then - BRANCH="main" - fi - echo "BRANCH_TO_CHECKOUT=$BRANCH" >> $GITHUB_OUTPUT + echo "BRANCH_TO_CHECKOUT=main" >> $GITHUB_OUTPUT - name: Download release assets uses: actions/download-artifact@v4 @@ -665,10 +652,10 @@ jobs: COMMIT_AUTHOR: ${{ steps.commit_info.outputs.COMMIT_AUTHOR }} COMMIT_MSG: ${{ steps.commit_info.outputs.COMMIT_MSG }} FIREBASE_CONSOLE_URL: ${{ steps.firebase_upload.outputs.FIREBASE_CONSOLE_URL }} - run: | + run: | BRANCH_NAME="${{ env.BRANCH_NAME }}" BUILD_TYPE="${{ matrix.build_type }}" - + jq -n \ --arg commit_msg "$COMMIT_MSG" \ --arg build_type "$BUILD_TYPE" \ @@ -752,4 +739,4 @@ jobs: if: always() run: | rm -f app/google-services.json - echo "google-services.json cleaned up successfully" + echo "google-services.json cleaned up successfully" \ No newline at end of file