diff --git a/.github/workflows/integrations_android.yaml b/.github/workflows/integrations_android.yaml index 1bf38c9c..91352b22 100644 --- a/.github/workflows/integrations_android.yaml +++ b/.github/workflows/integrations_android.yaml @@ -13,8 +13,8 @@ on: required: true type: string jobs: - build-capture-timber: - name: Build Capture Timber + build-gradle-libraries: + name: Build Gradle Libraries runs-on: ubuntu-latest defaults: run: @@ -31,17 +31,45 @@ jobs: cache: gradle - name: Install Rust target run: rustup update && rustup target add aarch64-linux-android && rustup target add x86_64-linux-android - - name: Build artifacts with Gradle + - name: Build Timber artifacts with Gradle run: ./gradlew :capture-timber:publish -PVERSION_NAME="${{ inputs.version }}" --info env: SKIP_PROTO_GEN: 1 - - name: Compress artifacts + - name: Build Apollo artifacts with Gradle + run: ./gradlew :capture-apollo3:publish -PVERSION_NAME="${{ inputs.version }}" --info + env: + SKIP_PROTO_GEN: 1 + - name: Build Gradle Plugin artifacts with Gradle + run: ./gradlew :capture-plugin:publish -PVERSION_NAME="${{ inputs.version }}" --info + env: + SKIP_PROTO_GEN: 1 + - name: Compress Timber artifacts run: | readonly dir=$(pwd) (cd capture-timber/build/repos/releases/io/bitdrift/capture-timber/${{ inputs.version }} && zip -r "$dir/capture-timber.zip" ./*) - - name: Upload artifacts + - name: Compress Apollo artifacts + run: | + readonly dir=$(pwd) + (cd capture-apollo3/build/repos/releases/io/bitdrift/capture-apollo3/${{ inputs.version }} && zip -r "$dir/capture-apollo3.zip" ./*) + - name: Compress Android Plugin artifacts + run: | + readonly dir=$(pwd) + (cd capture-plugin/build/repos/releases/io/bitdrift/capture-plugin/${{ inputs.version }} && zip -r "$dir/capture-plugin.zip" ./*) + - name: Upload Timber artifacts uses: actions/upload-artifact@v4 with: name: capture-timber.zip path: platform/jvm/capture-timber.zip if-no-files-found: error + - name: Upload Apollo artifacts + uses: actions/upload-artifact@v4 + with: + name: capture-apollo3.zip + path: platform/jvm/capture-apollo3.zip + if-no-files-found: error + - name: Upload Gradle Plugin artifacts + uses: actions/upload-artifact@v4 + with: + name: capture-plugin.zip + path: platform/jvm/capture-plugin.zip + if-no-files-found: error diff --git a/.github/workflows/release_gh.yaml b/.github/workflows/release_gh.yaml index 73a8aa4c..8df4998d 100644 --- a/.github/workflows/release_gh.yaml +++ b/.github/workflows/release_gh.yaml @@ -198,6 +198,12 @@ jobs: - uses: actions/download-artifact@v4 with: name: capture-timber.zip + - uses: actions/download-artifact@v4 + with: + name: capture-apollo3.zip + - uses: actions/download-artifact@v4 + with: + name: capture-plugin.zip - name: Prepare Android artifacts run: ./ci/gh_prepare_android_artifacts.sh "$VERSION" env: @@ -223,7 +229,9 @@ jobs: "Capture-$VERSION.android.zip" \ "example-apps.ios.zip" \ "example-apps.android.zip" \ - "capture-timber-$VERSION.android.zip" + "capture-timber-$VERSION.android.zip" \ + "capture-apollo3-$VERSION.android.zip" \ + "capture-plugin-$VERSION.android.zip" env: VERSION: ${{ inputs.version }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release_public.yaml b/.github/workflows/release_public.yaml index 00608d90..68404a9b 100644 --- a/.github/workflows/release_public.yaml +++ b/.github/workflows/release_public.yaml @@ -90,9 +90,10 @@ jobs: run: | gh release download "v$VERSION" -p 'Capture*.android.zip' gh release download "v$VERSION" -p 'capture-timber*.android.zip' + gh release download "v$VERSION" -p 'capture-plugin*.android.zip' env: VERSION: ${{ inputs.version }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload Android Artifacts to aws bucket - run: ./ci/capture_android_release.sh ${{ inputs.version }} "Capture-${{ inputs.version }}.android.zip" "capture-timber-${{ inputs.version }}.android.zip" + run: ./ci/capture_android_release.sh ${{ inputs.version }} "Capture-${{ inputs.version }}.android.zip" "capture-timber-${{ inputs.version }}.android.zip" "capture-apollo3-${{ inputs.version }}.android.zip" "capture-plugin-${{ inputs.version }}.android.zip" diff --git a/ci/capture_android_release.sh b/ci/capture_android_release.sh index 129460ed..685cc2c9 100755 --- a/ci/capture_android_release.sh +++ b/ci/capture_android_release.sh @@ -9,6 +9,8 @@ readonly remote_location_root_prefix="s3://bitdrift-public-dl/sdk/android-maven/ readonly version="$1" readonly capture_archive="$2" readonly capture_timber_archive="$3" +readonly capture_apollo3_archive="$4" +readonly capture_plugin_archive="$5" function upload_file() { local -r location="$1" @@ -78,36 +80,29 @@ function release_capture_sdk() { popd } -function release_capture_timber() { +function release_gradle_library() { + local -r library_name="$1" + local -r archive="$2" + echo "+++ dl.bitdrift.io Android Capture Timber artifacts upload" - # We get a zip containing the artifacts named per Maven conventions. + local -r remote_location_prefix="$remote_location_root_prefix/$library_name" pushd "$(mktemp -d)" - unzip -o "$sdk_repo/$capture_timber_archive" - - echo "+++ Uploading artifacts to s3 bucket" + unzip -o "$archive" + + # Make sure we update the top-level maven-metadata.xml file with the new release version + aws s3 cp maven-metadata.xml* "$remote_location_prefix/" --region us-east-1 - local -r remote_location_prefix="$remote_location_root_prefix/capture-timber" - local -r name="capture-timber-$version" + # Update the per-version files + aws s3 cp "$sdk_repo/ci/LICENSE.txt" "$remote_location_prefix/$version/LICENSE.txt" --region us-east-1 + aws s3 cp "$sdk_repo/ci/NOTICE.txt" "$remote_location_prefix/$version/NOTICE.txt" --region us-east-1 - files=(\ - "$sdk_repo/ci/LICENSE.txt" \ - "$sdk_repo/ci/NOTICE.txt" \ - "$name.pom" \ - "$name-javadoc.jar" \ - "$name-sources.jar" \ - "$name.module" \ - "$name.aar" \ - ) - - for file in "${files[@]}"; do - upload_file "$remote_location_prefix/$version" "$file" - done - - generate_maven_file "$remote_location_prefix" + aws s3 cp "$version" "$remote_location_prefix/$version/" --recursive --region us-east-1 popd } release_capture_sdk -release_capture_timber +release_gradle_library "capture-timber" "$capture_timber_archive" +release_gradle_library "capture-apollo3" "$capture_apollo3_archive" +release_gradle_library "capture-plugin" "$capture_plugin_archive" diff --git a/ci/gh_prepare_android_artifacts.sh b/ci/gh_prepare_android_artifacts.sh index 2cc4fe5e..42f08b09 100755 --- a/ci/gh_prepare_android_artifacts.sh +++ b/ci/gh_prepare_android_artifacts.sh @@ -43,33 +43,21 @@ function prepare_capture_sdk() { function prepare_capture_timber() { echo "+++ Preparing Android Capture Timber library artifacts for '$version' version" - pushd "$(mktemp -d)" - local -r out_artifacts_dir="capture-timber-out" - - unzip "$sdk_repo/capture-timber.zip" - - mkdir "$out_artifacts_dir" + cp "$sdk_repo/capture-timber.zip" "$sdk_repo/capture-timber-$version.android.zip" +} - local -r name="capture-timber-$version" +function prepare_capture_apollo3() { + echo "+++ Preparing Android Capture Apollo3 library artifacts for '$version' version" - files=(\ - "$name.aar" \ - "$name.module" \ - "$name.pom" \ - "$name-javadoc.jar" \ - "$name-sources.jar" \ - "$sdk_repo/ci/LICENSE.txt" \ - "$sdk_repo/ci/NOTICE.txt" \ - ) + cp "$sdk_repo/capture-apollo3.zip" "$sdk_repo/capture-apollo4-$version.android.zip" +} - for file in "${files[@]}"; do - filename=$(basename "$file") - mv "$file" "$out_artifacts_dir/$filename" - done +function prepare_capture_plugin() { + echo "+++ Preparing Android Capture Android Plugin artifacts for '$version' version" - (cd "$out_artifacts_dir" && zip -r "$sdk_repo/capture-timber-$version.android.zip" ./*) - popd + cp "$sdk_repo/capture-plugin.zip" "$sdk_repo/capture-plugin-$version.android.zip" } prepare_capture_sdk prepare_capture_timber +prepare_capture_plugin diff --git a/platform/jvm/capture-apollo3/build.gradle.kts b/platform/jvm/capture-apollo3/build.gradle.kts index d724ac83..f947f2fd 100644 --- a/platform/jvm/capture-apollo3/build.gradle.kts +++ b/platform/jvm/capture-apollo3/build.gradle.kts @@ -3,6 +3,11 @@ plugins { alias(libs.plugins.kotlin.android) alias(libs.plugins.detekt) + // Publish + alias(libs.plugins.dokka) // Must be applied here for publish plugin. + alias(libs.plugins.maven.publish) + signing + id("dependency-license-config") } @@ -55,9 +60,50 @@ tasks.preBuild { dependencies { implementation(project(":capture")) - implementation("com.apollographql.apollo3:apollo-runtime:3.8.3") + implementation(libs.apollo.runtime) + + testImplementation(libs.truth) + testImplementation(libs.junit) + testImplementation(libs.kotlin.mockito.kotlin) +} - testImplementation("com.google.truth:truth:1.4.4") - testImplementation("junit:junit:4.13.2") - testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0") // last version with Java 8 support +mavenPublishing { + pom { + name.set("CaptureApollo") + description.set("Official Capture integration for Apollo v3 (GraphQL).") + url.set("https://bitdrift.io") + licenses { + license { + name.set("BITDRIFT SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT") + url.set("https://dl.bitdrift.io/sdk/android-maven/io/bitdrift/capture-timber/${findProperty("VERSION_NAME")}/LICENSE.txt") + distribution.set("repo") + } + license { + name.set("NOTICE") + url.set("https://dl.bitdrift.io/sdk/android-maven/io/bitdrift/capture-timber/${findProperty("VERSION_NAME")}/NOTICE.txt") + distribution.set("repo") + } + } + developers { + developer { + id.set("bitdriftlabs") + name.set("Bitdrift, Inc.") + url.set("https://github.com/bitdriftlabs") + email.set("info@bitdrift.io") + } + scm { + connection.set("scm:git:git://github.com/bitdriftlabs/capture-sdk.git") + developerConnection.set("scm:git:ssh://git@github.com:bitdriftlabs/capture-sdk.git") + url.set("https://github.com/bitdriftlabs/capture-sdk") + } + } + } +} + +publishing { + repositories { + maven { + url = uri(layout.buildDirectory.dir("repos/releases")) + } + } } diff --git a/platform/jvm/capture-plugin/build.gradle.kts b/platform/jvm/capture-plugin/build.gradle.kts index fe05bf20..312f147c 100644 --- a/platform/jvm/capture-plugin/build.gradle.kts +++ b/platform/jvm/capture-plugin/build.gradle.kts @@ -5,6 +5,8 @@ id("java-gradle-plugin") } +group = "io.bitdrift" + dependencies { compileOnly("com.android.tools.build:gradle:7.4.0") compileOnly("org.ow2.asm:asm-commons:9.4") @@ -22,17 +24,51 @@ dependencies { gradlePlugin { plugins { create("capturePlugin") { - id = "io.bitdrift.capture.capture-plugin" + id = "io.bitdrift.capture-plugin" implementationClass = "io.bitdrift.capture.CapturePlugin" } } } + mavenPublishing { + configureBasedOnAppliedPlugins() + + pom { + name.set("CapturePlugin") + description.set("Official Capture Gradle plugin.") + url.set("https://bitdrift.io") + licenses { + license { + name.set("BITDRIFT SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT") + url.set("https://dl.bitdrift.io/sdk/android-maven/io/bitdrift/capture-plugin/${findProperty("VERSION_NAME")}/LICENSE.txt") + distribution.set("repo") + } + license { + name.set("NOTICE") + url.set("https://dl.bitdrift.io/sdk/android-maven/io/bitdrift/capture-plugin/${findProperty("VERSION_NAME")}/NOTICE.txt") + distribution.set("repo") + } + } + developers { + developer { + id.set("bitdriftlabs") + name.set("Bitdrift, Inc.") + url.set("https://github.com/bitdriftlabs") + email.set("info@bitdrift.io") + } + scm { + connection.set("scm:git:git://github.com/bitdriftlabs/capture-sdk.git") + developerConnection.set("scm:git:ssh://git@github.com:bitdriftlabs/capture-sdk.git") + url.set("https://github.com/bitdriftlabs/capture-sdk") + } + } + } + } + publishing { repositories { - mavenLocal() + maven { + url = uri(layout.buildDirectory.dir("repos/releases")) + } } } - -group = "io.bitdrift.capture.capture-plugin" -version = "0.1.0" \ No newline at end of file diff --git a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/AndroidComponentsConfig.kt b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/AndroidComponentsConfig.kt index e41e67a0..315684cb 100644 --- a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/AndroidComponentsConfig.kt +++ b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/AndroidComponentsConfig.kt @@ -61,7 +61,8 @@ fun AndroidComponentsExtension<*, *, *>.configure( FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS, ) { params -> params.tmpDir.set(tmpDir) - params.debug.set(false) + params.debug.set(extension.instrumentation.debug) + params.proxyOkHttpEventListener.set(extension.instrumentation.proxyOkHttpEventListener) } } } diff --git a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/extension/InstrumentationExtension.kt b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/extension/InstrumentationExtension.kt index 3e4a848f..e9b33db0 100644 --- a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/extension/InstrumentationExtension.kt +++ b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/extension/InstrumentationExtension.kt @@ -19,4 +19,6 @@ open class InstrumentationExtension @Inject constructor(objects: ObjectFactory) val debug: Property = objects.property(Boolean::class.java).convention( false ) + + val proxyOkHttpEventListener: Property = objects.property(Boolean::class.java).convention(false) } \ No newline at end of file diff --git a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/SpanAddingClassVisitorFactory.kt b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/SpanAddingClassVisitorFactory.kt index c6ff448b..ebffcbc3 100644 --- a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/SpanAddingClassVisitorFactory.kt +++ b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/SpanAddingClassVisitorFactory.kt @@ -54,6 +54,9 @@ abstract class SpanAddingClassVisitorFactory : AsmClassVisitorFactory + @get:Input + val proxyOkHttpEventListener: Property + @get:Internal val tmpDir: Property diff --git a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/OkHttpEventListener.kt b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/OkHttpEventListener.kt index 64ca3410..7d78d229 100644 --- a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/OkHttpEventListener.kt +++ b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/OkHttpEventListener.kt @@ -48,19 +48,19 @@ class OkHttpEventListener( override val fqName: String get() = "okhttp3.OkHttpClient" override fun getVisitor( - instrumentableContext: ClassContext, - apiVersion: Int, - originalVisitor: ClassVisitor, - parameters: SpanAddingClassVisitorFactory.SpanAddingParameters + instrumentableContext: ClassContext, + apiVersion: Int, + originalVisitor: ClassVisitor, + parameters: SpanAddingClassVisitorFactory.SpanAddingParameters ): ClassVisitor = CommonClassVisitor( - apiVersion = apiVersion, - classVisitor = originalVisitor, - className = fqName.substringAfterLast('.'), - methodInstrumentables = listOf( - OkHttpEventListenerMethodInstrumentable( - ) - ), - parameters = parameters + apiVersion = apiVersion, + classVisitor = originalVisitor, + className = fqName.substringAfterLast('.'), + methodInstrumentables = listOf( + OkHttpEventListenerMethodInstrumentable( + ) + ), + parameters = parameters ) } @@ -69,14 +69,15 @@ class OkHttpEventListenerMethodInstrumentable( override val fqName: String get() = "" override fun getVisitor( - instrumentableContext: MethodContext, - apiVersion: Int, - originalVisitor: MethodVisitor, - parameters: SpanAddingClassVisitorFactory.SpanAddingParameters + instrumentableContext: MethodContext, + apiVersion: Int, + originalVisitor: MethodVisitor, + parameters: SpanAddingClassVisitorFactory.SpanAddingParameters ): MethodVisitor = OkHttpEventListenerMethodVisitor( - apiVersion = apiVersion, - originalVisitor = originalVisitor, - instrumentableContext = instrumentableContext, + apiVersion = apiVersion, + originalVisitor = originalVisitor, + instrumentableContext = instrumentableContext, + proxyEventListener = parameters.proxyOkHttpEventListener.get() ) override fun isInstrumentable(data: MethodContext): Boolean { diff --git a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/visitor/OkHttpEventListenerMethodVisitor.kt b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/visitor/OkHttpEventListenerMethodVisitor.kt index bec36f6b..bb98bce4 100644 --- a/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/visitor/OkHttpEventListenerMethodVisitor.kt +++ b/platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/visitor/OkHttpEventListenerMethodVisitor.kt @@ -39,25 +39,68 @@ import org.objectweb.asm.Opcodes import org.objectweb.asm.commons.AdviceAdapter class OkHttpEventListenerMethodVisitor( - apiVersion: Int, - originalVisitor: MethodVisitor, - instrumentableContext: MethodContext, + apiVersion: Int, + originalVisitor: MethodVisitor, + instrumentableContext: MethodContext, + val proxyEventListener: Boolean ) : AdviceAdapter( - apiVersion, - originalVisitor, - instrumentableContext.access, - instrumentableContext.name, - instrumentableContext.descriptor + apiVersion, + originalVisitor, + instrumentableContext.access, + instrumentableContext.name, + instrumentableContext.descriptor ) { private val captureOkHttpEventListenerFactory = - "io/bitdrift/capture/network/okhttp/CaptureOkHttpEventListenerFactory" + "io/bitdrift/capture/network/okhttp/CaptureOkHttpEventListenerFactory" override fun onMethodEnter() { super.onMethodEnter() + if (proxyEventListener) { + addProxyingEventListener() + } else { + addOverwritingEventListener() + } + } + + private fun addOverwritingEventListener() { + // Add the following call at the beginning of the constructor with the Builder parameter: + // builder.eventListenerFactory(new CaptureOkHttpEventListenerFactory()); + + // OkHttpClient.Builder is the parameter, retrieved here + visitVarInsn(Opcodes.ALOAD, 1) + + // Let's declare the CaptureOkHttpEventListenerFactory variable + visitTypeInsn(Opcodes.NEW, captureOkHttpEventListenerFactory) + + // The CaptureOkHttpEventListenerFactory constructor, which is called later, will consume the + // element without pushing anything back to the stack ( returns void). + // Dup will give a reference to the CaptureOkHttpEventListenerFactory after the constructor call + visitInsn(Opcodes.DUP) + + // Call CaptureOkHttpEventListenerFactory constructor passing "eventListenerFactory" as parameter + visitMethodInsn( + Opcodes.INVOKESPECIAL, + captureOkHttpEventListenerFactory, + "", + "()V", + false + ) + + // Call "eventListener" function of OkHttpClient.Builder passing CaptureOkHttpEventListenerFactory + visitMethodInsn( + Opcodes.INVOKEVIRTUAL, + "okhttp3/OkHttpClient\$Builder", + "eventListenerFactory", + "(Lokhttp3/EventListener\$Factory;)Lokhttp3/OkHttpClient\$Builder;", + false + ) + } + + private fun addProxyingEventListener() { // Add the following call at the beginning of the constructor with the Builder parameter: - // builder.eventListener(new CaptureOkHttpEventListener(builder.eventListenerFactory)); + // builder.eventListenerFactory(new CaptureOkHttpEventListenerFactory(builder.eventListenerFactory)); // OkHttpClient.Builder is the parameter, retrieved here visitVarInsn(Opcodes.ALOAD, 1) diff --git a/platform/jvm/capture-timber/build.gradle.kts b/platform/jvm/capture-timber/build.gradle.kts index 32edc2c1..f69cf9fa 100644 --- a/platform/jvm/capture-timber/build.gradle.kts +++ b/platform/jvm/capture-timber/build.gradle.kts @@ -64,7 +64,7 @@ dependencies { testImplementation(libs.truth) testImplementation(libs.junit) - testImplementation(libs.kotlin.mockito.kotlin) // last version with Java 8 support + testImplementation(libs.kotlin.mockito.kotlin) } mavenPublishing { diff --git a/platform/jvm/gradle/libs.versions.toml b/platform/jvm/gradle/libs.versions.toml index aab5e344..ceb418ed 100644 --- a/platform/jvm/gradle/libs.versions.toml +++ b/platform/jvm/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] androidBenchkmarkPlugin = "1.2.4" androidGradlePlugin = "8.2.2" # have to pin to this version due to 8.3.x breaking our lint https://issuetracker.google.com/issues/332755363 -apolloGraphqlPlugin = "3.8.3" +apollo = "3.8.3" appcompat = "1.5.1" assertjCore = "3.22.0" androidxCore = "1.9.0" @@ -37,6 +37,7 @@ androidx-core = { group = "androidx.core", name = "core", version.ref = "android androidx-startup-runtime = { module = "androidx.startup:startup-runtime", version.ref = "startupRuntime" } androidx-test-core = { module = "androidx.test:core", version.ref = "androidxTestCore" } androidx-ui = { module = "androidx.compose.ui:ui", version.ref = "ui" } +apollo-runtime = { module = "com.apollographql.apollo3:apollo-runtime", version.ref = "apollo" } assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertjCore" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" } jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "jsr305" } @@ -56,7 +57,7 @@ truth = { module = "com.google.truth:truth", version.ref = "truth" } android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } android-benchmark = { id = "androidx.benchmark", version.ref = "androidBenchkmarkPlugin" } android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" } -apollo-graphql = { id = "com.apollographql.apollo3", version.ref = "apolloGraphqlPlugin" } +apollo-graphql = { id = "com.apollographql.apollo3", version.ref = "apollo" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektPlugin" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaPlugin" } maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublishPlugin" }