diff --git a/.github/workflows/cross-platform-tests.yml b/.github/workflows/cross-platform-tests.yml index 0f57f8b9e..ba7fdb936 100644 --- a/.github/workflows/cross-platform-tests.yml +++ b/.github/workflows/cross-platform-tests.yml @@ -10,12 +10,12 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout Cross Platform Tests Repo" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: repository: mParticle/crossplatform-sdk-tests - name: "Checkout Android SDK Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: repository: ${{github.event.pull_request.head.repo.full_name}} ref: ${{github.head_ref}} diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 1a390b2fc..6d5ba595c 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -45,7 +45,7 @@ jobs: GIT_COMMITTER_EMAIL: developers@mparticle.com steps: - name: "Clone branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: token: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} repository: mparticle/mparticle-android-sdk @@ -69,7 +69,7 @@ jobs: # needs: create-regression-branch # steps: # - name: "Checkout future release branch" - # uses: actions/checkout@v6.0.2 + # uses: actions/checkout@v6 # with: # repository: mparticle/mparticle-android-sdk # ref: regression/${{ github.run_number }} @@ -102,7 +102,7 @@ jobs: # needs: create-regression-branch # steps: # - name: "Checkout Branch" - # uses: actions/checkout@v6.0.2 + # uses: actions/checkout@v6 # with: # repository: mparticle/mparticle-android-sdk # ref: regression/${{ github.run_number }} @@ -192,7 +192,7 @@ jobs: needs: create-regression-branch steps: - name: "Checkout future release branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: repository: mparticle/mparticle-android-sdk ref: regression/${{ github.run_number }} @@ -221,7 +221,7 @@ jobs: needs: create-regression-branch steps: - name: "Checkout Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: ref: regression/${{ github.run_number }} - name: "Install JDK 17" @@ -233,10 +233,10 @@ jobs: - name: "Run Android Core SDK Lint" run: ./gradlew lint - name: "Setup Android Kit Lint" - run: ./gradlew publishReleaseLocal + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=$(head -n 1 VERSION) - name: "Run Android Kit Lint" - run: ./gradlew publishReleaseLocal -c settings-kits.gradle lint - - name: "Run Isolated Kit Lint (urbanairship)" + run: ./gradlew lint -c settings-kits.gradle + - name: "Run Isolated Kit Lint (urbanairship-kit)" working-directory: kits/urbanairship/urbanairship-20 run: ./gradlew lint - name: "Archive Test Results" @@ -259,7 +259,7 @@ jobs: needs: create-regression-branch steps: - name: "Checkout Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: ref: regression/${{ github.run_number }} - name: "Install JDK 17" @@ -271,10 +271,10 @@ jobs: - name: "Run Android Core SDK Kotlin Lint" run: ./gradlew ktlintCheck - name: "Setup Android Kit Kotlin Lint" - run: ./gradlew publishReleaseLocal + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=$(head -n 1 VERSION) - name: "Run Android Kit Kotlin Lint" - run: ./gradlew publishReleaseLocal -c settings-kits.gradle ktlintCheck - - name: "Run Isolated Kit Kotlin Lint (urbanairship)" + run: ./gradlew ktlintCheck -c settings-kits.gradle + - name: "Run Isolated Kit Kotlin Lint (urbanairship-kit)" working-directory: kits/urbanairship/urbanairship-20 run: ./gradlew ktlintCheck - name: "Archive Test Results" @@ -301,7 +301,7 @@ jobs: GIT_COMMITTER_EMAIL: developers@mparticle.com steps: - name: "Checkout future release branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: repository: mparticle/mparticle-android-sdk ref: regression/${{ github.run_number }} @@ -312,12 +312,12 @@ jobs: java-version: "17" cache: "gradle" - name: "Build Android Core" - run: ./gradlew -PisRelease=true clean publishReleaseLocal + run: ./gradlew clean publishMavenPublicationToMavenLocal -PVERSION=$(head -n 1 VERSION) - name: "Test Kits" - run: ./gradlew -PisRelease=true clean testRelease publishReleaseLocal -c settings-kits.gradle - - name: "Test Isolated Kits (urbanairship)" + run: ./gradlew clean testRelease -c settings-kits.gradle + - name: "Test Isolated Kits (urbanairship-kit)" working-directory: kits/urbanairship/urbanairship-20 - run: ./gradlew -PisRelease=true clean testRelease publishReleaseLocal + run: ./gradlew clean testRelease semantic-release-dryrun: name: "Test Semantic Release - Dry Run" @@ -331,7 +331,7 @@ jobs: GIT_COMMITTER_EMAIL: developers@mparticle.com steps: - name: "Checkout public main branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: fetch-depth: 0 ref: main @@ -362,7 +362,7 @@ jobs: GIT_COMMITTER_EMAIL: developers@mparticle.com steps: - name: "Checkout repo" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 with: token: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} fetch-depth: 0 diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 8cfe0ecda..3f41bf20c 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -75,7 +75,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 - name: "Install JDK 17" uses: actions/setup-java@v5 with: @@ -95,11 +95,11 @@ jobs: lint-checks: name: "Lint Checks" - timeout-minutes: 15 + timeout-minutes: 20 runs-on: macos-latest steps: - name: "Checkout Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 - name: "Install JDK 17" uses: actions/setup-java@v5 with: @@ -108,7 +108,7 @@ jobs: - name: "Run Android Core SDK Lint" run: ./gradlew lint - name: "Setup Android Kit Lint" - run: ./gradlew publishReleaseLocal + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=$(head -n 1 VERSION) - name: "Run Android Kit Lint" run: ./gradlew -c settings-kits.gradle lint - name: "Archive Lint Test Results" @@ -124,7 +124,7 @@ jobs: runs-on: macos-latest steps: - name: "Checkout Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 - name: "Install JDK 17" uses: actions/setup-java@v5 with: @@ -133,7 +133,7 @@ jobs: - name: "Run Android Core SDK Kotlin Lint" run: ./gradlew ktlintCheck - name: "Setup Android Kit Kotlin Lint" - run: ./gradlew publishReleaseLocal + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=$(head -n 1 VERSION) - name: "Run Android Kit Kotlin Lint" run: ./gradlew -c settings-kits.gradle ktlintCheck - name: "Archive Kotlin Lint Test Results" @@ -155,18 +155,18 @@ jobs: if: github.event_name == 'pull_request' steps: - name: "Checkout Branch" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@v6 - name: "Install JDK 17" uses: actions/setup-java@v5 with: distribution: "zulu" java-version: "17" - name: "Generate Core Release Build" - run: ./gradlew -PisRelease=true publishLocal + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=$(head -n 1 VERSION) - name: "Run Kit-Base Release Tests and Build" - run: ./gradlew -PisRelease=true :android-kit-base:testRelease + run: ./gradlew :android-kit-base:testRelease -PVERSION=$(head -n 1 VERSION) - name: "Run Kit Release Tests and Build" - run: ./gradlew -PisRelease=true -p kits testRelease -c ../settings-kits.gradle + run: ./gradlew -p kits testRelease -c ../settings-kits.gradle -PVERSION=$(head -n 1 VERSION) - name: "Run Isolated Kit Compatibility Tests (urbanairship)" working-directory: kits/urbanairship/urbanairship-20 run: ./gradlew -PisRelease=true testRelease diff --git a/.github/workflows/release-draft.yml b/.github/workflows/release-draft.yml new file mode 100644 index 000000000..40dcaf84a --- /dev/null +++ b/.github/workflows/release-draft.yml @@ -0,0 +1,76 @@ +name: Release – Draft + +on: + workflow_dispatch: # checkov:skip=CKV_GHA_7 + inputs: + bump-type: + description: "Specify if the version should be bumped as patch, minor, or major" + required: true + type: choice + options: + - patch + - minor + - major + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + pull-requests: write + +jobs: + publish-draft-release: + runs-on: ubuntu-latest + env: + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.MAVEN_CENTRAL_SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.MAVEN_CENTRAL_SIGNING_KEY_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Install JDK 17 + uses: actions/setup-java@v5 + with: + distribution: "zulu" + java-version: "17" + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2 + + - name: Get current version + id: version-file + run: | + version_from_file=$(head -n 1 VERSION) + echo "release-version=$version_from_file" >> $GITHUB_OUTPUT + + - name: Bump version + id: bump-version + uses: actions-ecosystem/action-bump-semver@34e334551143a5301f38c830e44a22273c6ff5c5 # v1.0.0 + with: + current_version: ${{ steps.version-file.outputs.release-version }} + level: ${{ github.event.inputs.bump-type || 'patch' }} + + - name: Save bumped version to file + run: | + echo "${{ steps.bump-version.outputs.new_version }}" > VERSION + + - name: Publish to Maven local (smoke test) + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=${{ steps.bump-version.outputs.new_version }} + + - name: Create Pull Request + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 + with: + token: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} + commit-message: "chore: prepare release ${{ steps.bump-version.outputs.new_version }}" + branch: release/${{ steps.bump-version.outputs.new_version }} + title: "Prepare release ${{ steps.bump-version.outputs.new_version }}" + base: main + body: | + Preparing for release ${{ steps.bump-version.outputs.new_version }} + - Bumped version to ${{ steps.bump-version.outputs.new_version }} diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml new file mode 100644 index 000000000..19d6d67f0 --- /dev/null +++ b/.github/workflows/release-publish.yml @@ -0,0 +1,64 @@ +name: Release – Publish + +on: + push: + branches: + - main + paths: + - VERSION + +permissions: + contents: write + +jobs: + setup-and-version: + runs-on: ubuntu-latest + outputs: + final_version: ${{ steps.version-file.outputs.release-version }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Get current version + id: version-file + run: | + version_from_file=$(head -n 1 VERSION) + echo "release-version=$version_from_file" >> $GITHUB_OUTPUT + + build-and-release: + needs: setup-and-version + runs-on: ubuntu-latest + env: + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.MAVEN_CENTRAL_SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.MAVEN_CENTRAL_SIGNING_KEY_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Install JDK 17 + uses: actions/setup-java@v5 + with: + distribution: "zulu" + java-version: "17" + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2 + + - name: Publish core to Maven local (required before kits can compile) + run: ./gradlew publishMavenPublicationToMavenLocal -PVERSION=${{ needs.setup-and-version.outputs.final_version }} + + - name: Publish core to Maven Central + run: ./gradlew publishMavenPublicationToMavenCentralRepository -PVERSION=${{ needs.setup-and-version.outputs.final_version }} + + - name: Publish kits to Maven Central + run: ./gradlew publishMavenPublicationToMavenCentralRepository -PVERSION=${{ needs.setup-and-version.outputs.final_version }} -c settings-kits.gradle + + - name: Create GitHub release + uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0 + with: + makeLatest: true + tag: ${{ needs.setup-and-version.outputs.final_version }} + body: | + Release ${{ needs.setup-and-version.outputs.final_version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index b185ad906..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,190 +0,0 @@ -name: "Release SDK" - -# checkov:skip=CKV_GHA_7: This workflow requires dryRun parameter for release control -on: - workflow_dispatch: - inputs: - dryRun: - description: "Do a dry run to preview instead of a real release [true/false]" - required: true - default: "true" - -permissions: - contents: write - pull-requests: read - checks: write - -jobs: - # SDK release is done from public main branch. - confirm-public-repo-main-branch: - name: "Confirm release is run from public/main branch" - uses: mParticle/mparticle-workflows/.github/workflows/sdk-release-repo-branch-check.yml@main - - create-release-branch: - name: "Create Release Branch" - runs-on: ubuntu-latest - needs: confirm-public-repo-main-branch - env: - GITHUB_TOKEN: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} - GIT_AUTHOR_NAME: mparticle-automation - GIT_AUTHOR_EMAIL: developers@mparticle.com - GIT_COMMITTER_NAME: mparticle-automation - GIT_COMMITTER_EMAIL: developers@mparticle.com - steps: - - name: Checkout main branch - uses: actions/checkout@v6.0.2 - with: - token: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} - repository: mparticle/mparticle-android-sdk - ref: main - - name: "Import GPG Key" - uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec #v6.0 - with: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.GPG_PASSPHRASE }} - git_user_signingkey: true - git_commit_gpgsign: true - - name: "Create and push release branch" - run: | - git checkout -b release/${{ github.run_number }} - git push origin release/${{ github.run_number }} - - regression-check: - needs: create-release-branch - name: "Run regression" - uses: mParticle/mparticle-android-sdk/.github/workflows/daily.yml@main - with: - dryRun: ${{ github.event.inputs.dryRun }} - branch_name: release/${{ github.run_number }} - secrets: inherit - - semantic-release: - name: "Semantic Release" - needs: regression-check - runs-on: macos-latest - env: - GITHUB_TOKEN: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} - GIT_AUTHOR_NAME: mparticle-automation - GIT_AUTHOR_EMAIL: developers@mparticle.com - GIT_COMMITTER_NAME: mparticle-automation - GIT_COMMITTER_EMAIL: developers@mparticle.com - steps: - - name: "Checkout public main branch" - uses: actions/checkout@v6.0.2 - with: - token: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} - fetch-depth: 0 - ref: main - - name: "Import GPG Key" - uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec #v6.0 - with: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.GPG_PASSPHRASE }} - git_user_signingkey: true - git_commit_gpgsign: true - - name: "Merge release branch into main branch" - run: | - git pull origin release/${{ github.run_number }} - - name: "Semantic Release --dry-run" - if: ${{ github.event.inputs.dryRun == 'true' }} - run: | - npx \ - -p lodash \ - -p semantic-release@17 \ - -p @semantic-release/changelog@5 \ - -p @semantic-release/git@9 \ - -p @semantic-release/exec@5 \ - -p conventional-changelog-conventionalcommits@7 \ - semantic-release --dry-run - - name: "Semantic Release" - if: ${{ github.event.inputs.dryRun == 'false' }} - run: | - npx \ - -p lodash \ - -p semantic-release@17 \ - -p @semantic-release/changelog@5 \ - -p @semantic-release/git@9 \ - -p @semantic-release/exec@5 \ - -p conventional-changelog-conventionalcommits@7 \ - semantic-release - - name: "Push automated release commits to release branch" - if: ${{ github.event.inputs.dryRun == 'false' }} - run: | - git push origin HEAD:release/${{ github.run_number }} - - sonatype-release: - name: "Sonatype Release" - needs: semantic-release - runs-on: ubuntu-latest - env: - sonatypeUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }} - sonatypePassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} - mavenSigningKeyId: ${{ secrets.MAVEN_CENTRAL_SIGNING_KEY }} - mavenSigningKeyPassword: ${{ secrets.MAVEN_CENTRAL_SIGNING_KEY_PASSWORD }} - steps: - - name: "Checkout release branch" - uses: actions/checkout@v6.0.2 - with: - repository: mparticle/mparticle-android-sdk - ref: release/${{ github.run_number }} - - name: "Install JDK 17" - uses: actions/setup-java@v5 - with: - distribution: "zulu" - java-version: "17" - - name: "Publish Core, KitManager, KitPlugin" - if: ${{ github.event.inputs.dryRun == 'false'}} - run: | - ./gradlew -PisRelease=true publishReleasePublicationToMavenRepository --stacktrace - - name: "Publish Kits" - if: ${{ github.event.inputs.dryRun == 'false'}} - # build kit-plugin locally so kits will compile, then release to sonatype - run: | - ./gradlew -PisRelease=true publishReleasePublicationToMavenLocal - ./gradlew -PisRelease=true publishReleasePublicationToMavenRepository -c settings-kits.gradle --stacktrace - - name: "Get SDK version for isolated kits" - if: ${{ github.event.inputs.dryRun == 'false'}} - id: sdk-version - run: echo "version=$(./gradlew -PisRelease=true -q properties | grep '^version:' | awk '{print $2}')" >> $GITHUB_OUTPUT - - name: "Publish Isolated Kits (urbanairship)" - if: ${{ github.event.inputs.dryRun == 'false'}} - working-directory: kits/urbanairship/urbanairship-20 - run: ./gradlew -PisRelease=true -Pversion=${{ steps.sdk-version.outputs.version }} publishReleasePublicationToMavenRepository --stacktrace - - # Temporary workaround: https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#ensuring-deployment-visibility-in-the-central-publisher-portal - - name: Ensuring Deployment Visibility In The Central Publisher Portal - if: ${{ github.event.inputs.dryRun == 'false'}} - env: - USER: ${{ secrets.SONATYPE_NEXUS_USERNAME }} - PASS: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} - run: | - curl -f -u "$USER:$PASS" -X POST \ - "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/com.mparticle?publishing_type=user_managed" \ - -H "Content-Type: application/json" -d '{}' \ - && echo "Success" - - sync-repository: - name: "Sync Repository" - needs: sonatype-release - runs-on: ubuntu-latest - steps: - - name: "Checkout main branch" - uses: actions/checkout@v6.0.2 - with: - fetch-depth: 0 - repository: ${{ github.repository }} - token: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} - ref: main - - name: "Merge release branch into main branch" - if: ${{ github.event.inputs.dryRun == 'false' }} - run: | - git pull origin release/${{ github.run_number }} - - name: "Push release commits to main branch" - if: ${{ github.event.inputs.dryRun == 'false'}} - run: | - git push origin HEAD:main - git push -f origin HEAD:chore/dependabot - - name: "Delete release branch" - if: ${{ github.event.inputs.dryRun == 'false' }} - run: | - git push --delete origin release/${{ github.run_number }} diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..cd1d147a7 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +5.78.2 diff --git a/android-core/build.gradle b/android-core/build.gradle index f3230652f..518641f00 100644 --- a/android-core/build.gradle +++ b/android-core/build.gradle @@ -1,11 +1,12 @@ -ext { - kitDescription = 'Core mParticle SDK supporting only server-side integrations.' -} - apply plugin: 'com.android.library' -apply from: '../scripts/maven.gradle' +apply plugin: 'mparticle.android.library.publish' apply plugin: 'kotlin-android' +mparticleMavenPublish { + artifactId.set('android-core') + description.set('Core mParticle SDK supporting only server-side integrations.') +} + android { namespace 'com.mparticle' compileSdk 33 @@ -45,7 +46,7 @@ android { defaultConfig { minSdk 14 targetSdk 33 - versionName project.version.toString().replace('-SNAPSHOT', '') + versionName (project.findProperty("VERSION") ?: "0.0.0").toString() versionCode Integer.parseInt(new Date().format('yyyyMMdd')) buildConfigField 'String', 'GIT_SHA', "\"$gitHash\"" @@ -106,36 +107,6 @@ android { } } -task coreSdkJavadocs(type: Javadoc) { - android.libraryVariants.all { variant -> - if (variant.name == 'release') { - source = android.sourceSets.main.java.srcDirs - source += 'build/generated/source/buildConfig/release/' - owner.classpath += variant.javaCompileProvider.get().classpath - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - classpath += project.files('src/main/java') - } - title = 'mParticle Android SDK API Reference' - failOnError true - getOptions().setNoTimestamp(true) - exclude { - String filePath = it.toString() - filePath.contains('/com/mparticle/internal/') || - filePath.contains('/com/mparticle/kits/') - } - } -} - -task generateJavadocsJar(type: Jar, dependsOn: coreSdkJavadocs) { - archiveClassifier.set('javadoc') - from coreSdkJavadocs.destinationDir -} - -task generateSourcesJar(type: Jar) { - archiveClassifier.set('sources') - from android.sourceSets.main.java.srcDirs -} - dependencies { //noinspection GradleCompatible compileOnly 'com.google.firebase:firebase-messaging:[10.2.1, )' @@ -159,8 +130,8 @@ dependencies { testImplementation project(':testutils') testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_version" - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" androidTestImplementation project(':testutils') if (useOrchestrator()) { @@ -169,7 +140,7 @@ dependencies { } androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" androidTestImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" - androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_version" + androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" } diff --git a/android-kit-base/build.gradle b/android-kit-base/build.gradle index 2a1cdcc97..846da389c 100644 --- a/android-kit-base/build.gradle +++ b/android-kit-base/build.gradle @@ -1,11 +1,12 @@ -ext { - kitDescription = 'mParticle Kit library for extending the Core mParticle SDK.' -} - apply plugin: 'com.android.library' -apply from: '../scripts/maven.gradle' +apply plugin: 'mparticle.android.library.publish' apply plugin: 'kotlin-android' +mparticleMavenPublish { + artifactId.set('android-kit-base') + description.set('mParticle Kit library for extending the Core mParticle SDK.') +} + android { namespace 'com.mparticle.kits' @@ -49,36 +50,12 @@ tasks.withType(Test).configureEach { jvmArgs('--add-opens=java.base/java.util.concurrent=ALL-UNNAMED') } -task kitSdkJavadocs(type: Javadoc) { - include { - String filePath = it.toString() - filePath.contains('KitIntegration.java') || - filePath.contains('KitUtils') - } - source = android.sourceSets.main.java.srcDirs - source += 'build/generated/source/buildConfig/release/' - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - title = 'mParticle Android Kit API Reference' - failOnError true - getOptions().setNoTimestamp(true) -} - -task generateJavadocsJar(type: Jar, dependsOn: kitSdkJavadocs) { - archiveClassifier.set('javadoc') - from kitSdkJavadocs.destinationDir -} - -task generateSourcesJar(type: Jar) { - archiveClassifier.set('sources') - from android.sourceSets.main.java.srcDirs -} - dependencies { api project(':android-core') api 'androidx.annotation:annotation:[1.0.0,)' - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_version" - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" testImplementation 'junit:junit:4.13.2' testImplementation files('libs/java-json.jar') diff --git a/build.gradle b/build.gradle index ae38d7a0d..d69815c34 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ buildscript { - ext.kotlin_version = '1.9.0' - ext.gradle_version = '8.1.4' + ext.kotlin_version = '2.0.20' + ext.coroutines_version = '1.9.0' + ext.gradle_version = '8.3.2' repositories { mavenCentral() @@ -63,10 +64,6 @@ subprojects { allprojects { group = 'com.mparticle' - version = '5.78.2-SNAPSHOT' - if (project.hasProperty('isRelease') && project.isRelease) { - version = version.toString().replace("-SNAPSHOT", "") - } repositories { mavenLocal() diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..cdee35637 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,36 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "2.0.20" + `kotlin-dsl` +} + +repositories { + google() + mavenCentral() + gradlePluginPortal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +tasks.withType().configureEach { + kotlinOptions { jvmTarget = JavaVersion.VERSION_17.toString() } +} + +dependencies { + implementation("com.android.tools.build:gradle:8.3.2") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20") + implementation("com.vanniktech:gradle-maven-publish-plugin:0.31.0") +} + +gradlePlugin { + plugins { + register("androidLibraryPublish") { + id = "mparticle.android.library.publish" + implementationClass = "AndroidLibraryMavenCentralPublishPlugin" + } + } +} diff --git a/buildSrc/src/main/kotlin/AndroidLibraryMavenCentralPublishPlugin.kt b/buildSrc/src/main/kotlin/AndroidLibraryMavenCentralPublishPlugin.kt new file mode 100644 index 000000000..4f32b46b6 --- /dev/null +++ b/buildSrc/src/main/kotlin/AndroidLibraryMavenCentralPublishPlugin.kt @@ -0,0 +1,14 @@ +import com.mparticle.configureMavenPublishing +import com.mparticle.publish.MParticleMavenPublishExtension +import org.gradle.api.Plugin +import org.gradle.api.Project + +class AndroidLibraryMavenCentralPublishPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.vanniktech.maven.publish") + val publishExtension = extensions.create("mparticleMavenPublish", MParticleMavenPublishExtension::class.java) + configureMavenPublishing(publishExtension) + } + } +} diff --git a/buildSrc/src/main/kotlin/com/mparticle/MavenCentralPublish.kt b/buildSrc/src/main/kotlin/com/mparticle/MavenCentralPublish.kt new file mode 100644 index 000000000..e593c6466 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/mparticle/MavenCentralPublish.kt @@ -0,0 +1,96 @@ +package com.mparticle + +import com.mparticle.publish.MParticleMavenPublishExtension +import com.vanniktech.maven.publish.AndroidSingleVariantLibrary +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.SonatypeHost +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.tasks.PublishToMavenLocal +import org.gradle.jvm.tasks.Jar + +fun Project.configureMavenPublishing(mparticleMavenPublish: MParticleMavenPublishExtension) { + val versionFromProperty = project.findProperty("VERSION")?.toString() + .takeIf { !it.isNullOrBlank() } ?: "0.0.0" + val shouldSign = !project.findProperty("signingInMemoryKey")?.toString().isNullOrBlank() + // Capture before entering configure block where `this` changes to MavenPublishBaseExtension + val isAndroidLibrary = pluginManager.hasPlugin("com.android.library") + + extensions.configure("mavenPublishing") { + // Dokka (bundled with AGP 8.3.2) uses ASM8, which cannot handle PermittedSubclasses + // attributes present in sealed classes compiled with JVM 17 (e.g. RoktEvent in + // android-core). Prevent AGP's withJavadocJar() from registering the failing + // javaDocReleaseGeneration task; we attach a stub empty javadoc jar in afterEvaluate. + if (isAndroidLibrary) { + configure(AndroidSingleVariantLibrary(sourcesJar = true, publishJavadocJar = false)) + } + + val publicationName = "maven" + + afterEvaluate { + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + coordinates( + groupId = mparticleMavenPublish.groupId.getOrElse("com.mparticle"), + artifactId = mparticleMavenPublish.artifactId.getOrElse(project.name), + version = versionFromProperty, + ) + if (shouldSign) { + signAllPublications() + } else { + logger.lifecycle("Skipping signAllPublications for ${project.name} (no signingInMemoryKey)") + } + pom { + name.set(mparticleMavenPublish.description.getOrElse(project.name)) + description.set(mparticleMavenPublish.description.getOrElse(project.name)) + url.set("https://github.com/mparticle/mparticle-android-sdk") + licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("mParticle") + name.set("mParticle Inc.") + email.set("developers@mparticle.com") + } + } + scm { + url.set("https://github.com/mparticle/mparticle-android-sdk") + connection.set("scm:git:https://github.com/mparticle/mparticle-android-sdk") + developerConnection.set("scm:git:git@github.com:mparticle/mparticle-android-sdk.git") + } + } + + // Attach a stub empty javadoc jar to satisfy Maven Central requirements. + // The javaDocReleaseGeneration Dokka task was intentionally bypassed above. + if (isAndroidLibrary) { + val emptyJavadocJar = tasks.register("emptyJavadocJar", Jar::class.java) + emptyJavadocJar.configure { archiveClassifier.set("javadoc") } + project.extensions.getByType(PublishingExtension::class.java) + .publications + .withType(MavenPublication::class.java) + .matching { it.name == publicationName } + .configureEach { artifact(emptyJavadocJar) } + } + } + + val validateTaskName = + "validatePomFor${publicationName.replaceFirstChar { it.uppercaseChar() }}Publication" + + tasks.register(validateTaskName, ValidatePomTask::class.java) { + description = "Validates the generated POM file for the '$publicationName' publication." + group = "verification" + pomFile.set(project.layout.buildDirectory.file("publications/$publicationName/pom-default.xml")) + dependsOn("generatePomFileFor${publicationName.replaceFirstChar { it.uppercaseChar() }}Publication") + } + + tasks.withType(PublishToMavenLocal::class.java).configureEach { + if (name.contains(publicationName, ignoreCase = true)) { + dependsOn(validateTaskName) + } + } + } +} diff --git a/buildSrc/src/main/kotlin/com/mparticle/ValidatePomTask.kt b/buildSrc/src/main/kotlin/com/mparticle/ValidatePomTask.kt new file mode 100644 index 000000000..8bf6e0ac7 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/mparticle/ValidatePomTask.kt @@ -0,0 +1,128 @@ +package com.mparticle + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.* +import org.w3c.dom.Document +import org.w3c.dom.Element +import org.w3c.dom.NodeList +import javax.xml.parsers.DocumentBuilderFactory + +abstract class ValidatePomTask : DefaultTask() { + + @get:InputFile + @get:PathSensitive(PathSensitivity.NONE) + abstract val pomFile: RegularFileProperty + + @TaskAction + fun execute() { + val pom = pomFile.get().asFile + if (!pom.exists()) { + throw GradleException("POM file not found: ${pom.absolutePath}") + } + + val factory = DocumentBuilderFactory.newInstance() + val builder = factory.newDocumentBuilder() + val doc: Document = builder.parse(pom) + doc.documentElement.normalize() + + val errors = mutableListOf() + val projectElement = doc.documentElement // Root element + + // Helper function to get text content of the first element by tag name + fun getFirstElementText(parent: Element, tagName: String): String? { + val nodeList = parent.getElementsByTagName(tagName) + return if (nodeList.length > 0) nodeList.item(0).textContent?.trim() else null + } + + // Helper function to check if text content is null or empty + fun checkNotEmpty(parent: Element, tagName: String, errorMessage: String) { + if (getFirstElementText(parent, tagName).isNullOrEmpty()) { + errors.add(errorMessage) + } + } + + // --- Basic Structure Checks --- + checkNotEmpty(projectElement, "groupId", "Missing or empty ") + checkNotEmpty(projectElement, "artifactId", "Missing or empty ") + checkNotEmpty(projectElement, "version", "Missing or empty ") + checkNotEmpty(projectElement, "name", "Missing or empty ") + checkNotEmpty(projectElement, "description", "Missing or empty ") + checkNotEmpty(projectElement, "url", "Missing or empty ") + + // --- License Check --- + val licensesNode = projectElement.getElementsByTagName("licenses").item(0) as? Element + val licenseNodes = licensesNode?.getElementsByTagName("license") + if (licenseNodes == null || licenseNodes.length == 0) { + errors.add("Missing section or entry") + } else { + for (i in 0 until licenseNodes.length) { + val lic = licenseNodes.item(i) as Element + checkNotEmpty(lic, "name", "Missing in license") + checkNotEmpty(lic, "url", "Missing in license") + } + } + + // --- Developer Check --- + val developersNode = projectElement.getElementsByTagName("developers").item(0) as? Element + val developerNodes = developersNode?.getElementsByTagName("developer") + if (developerNodes == null || developerNodes.length == 0) { + errors.add("Missing section or entry") + } else { + for (i in 0 until developerNodes.length) { + val dev = developerNodes.item(i) as Element + val devId = getFirstElementText(dev, "id") + val devName = getFirstElementText(dev, "name") + val devEmail = getFirstElementText(dev, "email") + if (devId.isNullOrEmpty() && devName.isNullOrEmpty() && devEmail.isNullOrEmpty()) { + errors.add("Developer entry needs at least , , or ") + } + } + } + + // --- SCM Check --- + val scmNode = projectElement.getElementsByTagName("scm").item(0) as? Element + if (scmNode == null) { + errors.add("Missing section") + } else { + checkNotEmpty(scmNode, "connection", "Missing ") + checkNotEmpty(scmNode, "developerConnection", "Missing ") + checkNotEmpty(scmNode, "url", "Missing ") + } + + // --- Dependency Version Check --- + val dependenciesNode = projectElement.getElementsByTagName("dependencies").item(0) as? Element + val dependencyNodes: NodeList? = dependenciesNode?.getElementsByTagName("dependency") + if (dependencyNodes != null) { + for (i in 0 until dependencyNodes.length) { + val dep = dependencyNodes.item(i) as Element + val groupId = getFirstElementText(dep, "groupId") + val artifactId = getFirstElementText(dep, "artifactId") + val version = getFirstElementText(dep, "version") + val scope = getFirstElementText(dep, "scope") + val depId = "${groupId ?: "MISSING_GROUP"}:${artifactId ?: "MISSING_ARTIFACT"}" + + if (groupId.isNullOrEmpty()) { + errors.add("Dependency entry is missing .") + } + if (artifactId.isNullOrEmpty()) { + errors.add("Dependency entry is missing .") + } + + // Check specifically for missing tag within a + // Ignore dependencies with import (BOMs) + if (version.isNullOrEmpty() && scope != "import") { + errors.add("Dependency $depId is missing required tag.") + } + } + } + + // --- Report Errors --- + if (errors.isNotEmpty()) { + throw GradleException("POM validation failed for ${pom.name}:\n - ${errors.joinToString("\n - ")}") + } else { + logger.lifecycle("POM validation successful for ${pom.name}") + } + } +} diff --git a/buildSrc/src/main/kotlin/com/mparticle/publish/MParticleMavenPublishExtension.kt b/buildSrc/src/main/kotlin/com/mparticle/publish/MParticleMavenPublishExtension.kt new file mode 100644 index 000000000..6dba29989 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/mparticle/publish/MParticleMavenPublishExtension.kt @@ -0,0 +1,9 @@ +package com.mparticle.publish + +import org.gradle.api.provider.Property + +interface MParticleMavenPublishExtension { + val groupId: Property + val artifactId: Property + val description: Property +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1..3499ded5c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kit-plugin/build.gradle b/kit-plugin/build.gradle index 1dd5660b1..9891f1eff 100644 --- a/kit-plugin/build.gradle +++ b/kit-plugin/build.gradle @@ -1,11 +1,11 @@ apply plugin: 'groovy' +apply plugin: 'mparticle.android.library.publish' -ext { - kitDescription = 'mParticle Gradle Plugin for creating mParticle kits' +mparticleMavenPublish { + artifactId.set('android-kit-plugin') + description.set('mParticle Gradle Plugin for creating mParticle kits') } -apply from: '../scripts/maven.gradle' - dependencies { implementation gradleApi() implementation localGroovy() @@ -26,12 +26,4 @@ tasks.withType(Test) { jvmArgs('--add-opens=java.base/java.lang=ALL-UNNAMED') } -task generateJavadocsJar(type: Jar, dependsOn: groovydoc) { - archiveClassifier.set("javadoc") - from groovydoc.destinationDir -} -task generateSourcesJar(type: Jar) { - archiveClassifier.set("sources") - from sourceSets.main.java.srcDirs -} diff --git a/kit-plugin/src/main/groovy/com/mparticle/kits/KitPlugin.groovy b/kit-plugin/src/main/groovy/com/mparticle/kits/KitPlugin.groovy index ac016fb20..039eb81b6 100644 --- a/kit-plugin/src/main/groovy/com/mparticle/kits/KitPlugin.groovy +++ b/kit-plugin/src/main/groovy/com/mparticle/kits/KitPlugin.groovy @@ -3,9 +3,6 @@ package com.mparticle.kits import com.android.build.gradle.LibraryExtension import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.plugins.signing.SigningExtension class KitPlugin implements Plugin { void apply(Project target) { @@ -20,7 +17,8 @@ class KitPlugin implements Plugin { target.repositories.add(target.repositories.google()) target.repositories.add(target.repositories.mavenCentral()) target.configurations.create('deployerJars') - target.dependencies.add('api', 'com.mparticle:android-kit-base:' + target.version) + def kitBaseVersion = target.findProperty('VERSION') ?: '+' + target.dependencies.add('api', 'com.mparticle:android-kit-base:' + kitBaseVersion) target.dependencies.add('testImplementation', 'junit:junit:4.13.2') target.dependencies.add('testImplementation', 'org.mockito:mockito-core:1.10.19') target.dependencies.add('testImplementation', 'androidx.annotation:annotation:[1.0.0,)') @@ -44,121 +42,20 @@ class KitPlugin implements Plugin { jvmArgs += ['--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED'] } - //formerly in maven.gradle - target.apply(plugin: 'maven-publish') - target.apply(plugin: 'signing') - - target.afterEvaluate { - PublishingExtension publishing = target.extensions.findByName('publishing') - publishing.publications.create("release", MavenPublication.class) { - groupId = "com.mparticle" - artifactId = target.name - version = target.version - if (target.plugins.findPlugin("com.android.library")) { - from target.components.release - } else { - from target.components.java - } - - pom { - artifactId = target.name - packaging = 'aar' - name = target.name - if (target.mparticle.kitDescription == null) { - description = target.name + ' for the mParticle SDK' - } else { - description = target.mparticle.kitDescription - } - url = 'https://github.com/mparticle/mparticle-sdk-android' - licenses { - license { - name = 'The Apache Software License, Version 2.0' - url = 'https://www.apache.org/license/LICENSE-2.0.txt' - } - } - developers { - developer { - id = 'mParticle' - name = 'mParticle Inc.' - email = 'developers@mparticle.com' - } - } - scm { - url = 'https://github.com/mparticle/mparticle-android-sdk' - connection = 'scm:git:https://github.com/mparticle/mparticle-android-sdk' - developerConnection = 'scm:git:git@github.com:mparticle/mparticle-android-sdk.git' - } - } - } - publishing.publications.register("debug", MavenPublication.class) { - groupId = "com.mparticle" - artifactId = target.name - version = target.version - if (target.plugins.findPlugin("com.android.library")) { - from target.components.debug - } else { - from target.components.java - } - - pom { - artifactId = target.name - packaging = 'aar' - name = target.name - if (target.mparticle.kitDescription == null) { - description = target.name + ' for the mParticle SDK' - } else { - description = target.mparticle.kitDescription - } - url = 'https://github.com/mparticle/mparticle-sdk-android' - licenses { - license { - name = 'The Apache Software License, Version 2.0' - url = 'https://www.apache.org/license/LICENSE-2.0.txt' - } - } - developers { - developer { - id = 'mParticle' - name = 'mParticle Inc.' - email = 'developers@mparticle.com' - } - } - scm { - url = 'https://github.com/mparticle/mparticle-android-sdk' - connection = 'scm:git:https://github.com/mparticle/mparticle-android-sdk' - developerConnection = 'scm:git:git@github.com:mparticle/mparticle-android-sdk.git' - } - } - } - - publishing.repositories.maven { - credentials { - username System.getenv('sonatypeUsername') ?: "" - password System.getenv('sonatypePassword') ?: "" - } - url = 'https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/' - } - - target.extensions.configure(SigningExtension) { signing -> - signing.required { - target.gradle.taskGraph.hasTask("publishReleasePublicationToMavenRepository") - } - - def signingKey = target.findProperty('signingKey') ?: System.getenv('mavenSigningKeyId') - def signingPassword = target.findProperty('signingPassword') ?: System.getenv('mavenSigningKeyPassword') - - if (signingKey && signingPassword) { - signing.useInMemoryPgpKeys(signingKey, signingPassword) - signing.sign(target.extensions.getByType(PublishingExtension) - .publications - .findByName("release")) - } - } + // mparticle.android.library.publish is only available when building inside the + // monorepo (buildSrc on classpath). Standalone kit builds and test fixtures skip + // Maven publishing configuration — kits will be migrated to the monorepo. + try { + target.apply(plugin: 'mparticle.android.library.publish') + def publishExt = target.extensions.getByName('mparticleMavenPublish') + publishExt.artifactId.convention(target.providers.provider { target.name }) + publishExt.description.convention(target.providers.provider { + String desc = target.extensions.findByName('mparticle')?.kitDescription + desc ?: (target.name + ' for the mParticle SDK') + }) + } catch (org.gradle.api.plugins.UnknownPluginException ignored) { + // no-op: publish plugin unavailable outside monorepo } - - //Publishing task aliases for simpler local development - target.task("publishLocal") { dependsOn "publishDebugPublicationToMavenLocal" } - target.task("publishReleaseLocal") { dependsOn "publishReleasePublicationToMavenLocal" } } } diff --git a/release.config.js b/release.config.js deleted file mode 100644 index de2aa3278..000000000 --- a/release.config.js +++ /dev/null @@ -1,100 +0,0 @@ -module.exports = { - branches: ["main"], - tagFormat: "v${version}", - plugins: [ - [ - "@semantic-release/commit-analyzer", - { - preset: "angular", - releaseRules: [ - { type: "feat", release: "minor" }, - { type: "ci", release: "patch" }, - { type: "fix", release: "patch" }, - { type: "docs", release: "patch" }, - { type: "test", release: "patch" }, - { type: "refactor", release: "patch" }, - { type: "style", release: "patch" }, - { type: "build", release: "patch" }, - { type: "chore", release: "patch" }, - { type: "revert", release: "patch" }, - ], - }, - ], - [ - "@semantic-release/release-notes-generator", - { - preset: "conventionalcommits", - presetConfig: { - types: [ - { - type: "feat", - section: "Features", - hidden: false, - }, - { - type: "fix", - section: "Bug Fixes", - hidden: false, - }, - { - type: "docs", - section: "Documentation", - hidden: false, - }, - { - type: "style", - section: "Updates & Maintenance", - hidden: false, - }, - { - type: "refactor", - section: "Updates & Maintenance", - hidden: false, - }, - { - type: "perf", - section: "Updates & Maintenance", - hidden: false, - }, - { - type: "test", - section: "Updates & Maintenance", - hidden: false, - }, - { - type: "ci", - section: "Updates & Maintenance", - hidden: false, - }, - { - type: "chore", - section: "Updates & Maintenance", - hidden: false, - }, - ], - }, - }, - ], - [ - "@semantic-release/changelog", - { - changelogFile: "CHANGELOG.md", - }, - ], - [ - "@semantic-release/exec", - { - prepareCmd: "sh ./scripts/release.sh ${nextRelease.version}", - }, - ], - ["@semantic-release/github"], - [ - "@semantic-release/git", - { - assets: ["CHANGELOG.md", "build.gradle", "README.md"], - message: - "chore: ${nextRelease.version} (release) \n\n${nextRelease.notes}", - }, - ], - ], -}; diff --git a/scripts/maven.gradle b/scripts/maven.gradle deleted file mode 100644 index 66063bcbb..000000000 --- a/scripts/maven.gradle +++ /dev/null @@ -1,128 +0,0 @@ -apply plugin: 'maven-publish' -apply plugin: 'signing' - -allprojects { - ext."signing.keyId" = System.getenv("mavenSigningKeyId") - ext."signing.secretKeyRingFile" = System.getenv("mavenSigningKeyRingFile") - ext."signing.password" = System.getenv("mavenSigningKeyPassword") -} -// For AGP 8.x compatibility, configure Android library projects -if (project.plugins.findPlugin("com.android.library")) { - android { - publishing { - // Configure publishing for both variants - singleVariant("release") - singleVariant("debug") - } - } -} -afterEvaluate { - publishing { - publications { - release(MavenPublication) { - groupId = "com.mparticle" - artifactId = project.name - version = project.version - if (project.plugins.findPlugin("com.android.library")) { - from components.release - } else { - from components.java - } - - if (project.tasks.findByName('generateJavadocsJar')) { - artifact project.tasks.getByName('generateJavadocsJar') - } - if (project.tasks.findByName('generateSourcesJar')) { - artifact project.tasks.getByName('generateSourcesJar') - } - - pom { - name = project.ext.kitDescription - description = project.ext.kitDescription - url = 'https://github.com/mparticle/mparticle-sdk-android' - licenses { - license { - name = 'The Apache Software License, Version 2.0' - url = 'https://www.apache.org/license/LICENSE-2.0.txt' - } - } - developers { - developer { - id = 'mParticle' - name = 'mParticle Inc.' - email = 'developers@mparticle.com' - } - } - scm { - url = 'https://github.com/mparticle/mparticle-android-sdk' - connection = 'scm:git:https://github.com/mparticle/mparticle-android-sdk' - developerConnection = 'scm:git:git@github.com:mparticle/mparticle-android-sdk.git' - } - } - } - debug(MavenPublication) { - groupId = "com.mparticle" - artifactId = project.name - version = project.version - if (project.plugins.findPlugin("com.android.library")) { - from components.debug - } else { - from components.java - } - - if (project.tasks.findByName('generateJavadocsJar')) { - artifact project.tasks.getByName('generateJavadocsJar') - } - - if (project.tasks.findByName('generateSourcesJar')) { - artifact project.tasks.getByName('generateSourcesJar') - } - - pom { - name = project.ext.kitDescription - description = project.ext.kitDescription - url = 'https://github.com/mparticle/mparticle-sdk-android' - licenses { - license { - name = 'The Apache Software License, Version 2.0' - url = 'https://www.apache.org/license/LICENSE-2.0.txt' - } - } - developers { - developer { - id = 'mParticle' - name = 'mParticle Inc.' - email = 'developers@mparticle.com' - } - } - scm { - url = 'https://github.com/mparticle/mparticle-android-sdk' - connection = 'scm:git:https://github.com/mparticle/mparticle-android-sdk' - developerConnection = 'scm:git:git@github.com:mparticle/mparticle-android-sdk.git' - } - } - } - } - repositories { - maven { - credentials { - username System.getenv('sonatypeUsername') - password System.getenv('sonatypePassword') - } - url = 'https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/' - } - } - } - - def signingKey = System.getenv("mavenSigningKeyId") - def signingPassword = System.getenv("mavenSigningKeyPassword") - signing { - required { gradle.taskGraph.hasTask("publishReleasePublicationToMavenRepository") } - useInMemoryPgpKeys(signingKey, signingPassword) - sign publishing.publications.release - } -} - -//Publishing task aliases for simpler local development -task publishLocal { dependsOn "publishDebugPublicationToMavenLocal" } -task publishReleaseLocal { dependsOn "publishReleasePublicationToMavenLocal" } diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 92d3f3b08..000000000 --- a/scripts/release.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -: "${1?"Version missing - usage: $0 x.y.z"}" # nosemgrep - -#update build.gradle -sed -i '.bak' "s/version = '.*-SNAPSHOT/version = '$1-SNAPSHOT/g" build.gradle - -#update README.md -sed -i '.bak' "s/'com.mparticle:android-core:.*'/'com.mparticle:android-core:$1'/g" README.md -sed -i '.bak' "s/'com.mparticle:android-example-kit:.*'/'com.mparticle:android-example-kit:$1'/g" README.md -sed -i '.bak' "s/'com.mparticle:android-another-kit:.*'/'com.mparticle:android-another-kit:$1'/g" README.md - -#commit the version bump, tag, and push to private and public -git add build.gradle -git add README.md diff --git a/testutils/build.gradle b/testutils/build.gradle index d71690104..41e0938f9 100644 --- a/testutils/build.gradle +++ b/testutils/build.gradle @@ -88,8 +88,8 @@ dependencies { androidTestUtil 'androidx.test:orchestrator:1.4.2' - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_version" - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" } boolean legacyTest() { diff --git a/tooling/android-plugin/build.gradle b/tooling/android-plugin/build.gradle index 1e5dce121..ae244614c 100644 --- a/tooling/android-plugin/build.gradle +++ b/tooling/android-plugin/build.gradle @@ -1,16 +1,15 @@ apply plugin: 'groovy' apply plugin: 'kotlin' +apply plugin: 'mparticle.android.library.publish' sourceCompatibility = JavaVersion.toVersion(JAVA_VERSION) targetCompatibility = JavaVersion.toVersion(JAVA_VERSION) - -ext { - kitDescription = 'mParticle Gradle Plugin for managing Dataplanning functionality' +mparticleMavenPublish { + artifactId.set('android-plugin') + description.set('mParticle Gradle Plugin for managing Dataplanning functionality') } -apply from: '../../scripts/maven.gradle' - buildscript { repositories { mavenCentral() @@ -40,12 +39,3 @@ jar { } } -task generateJavadocsJar(type: Jar, dependsOn: groovydoc) { - archiveClassifier.set("javadoc") - from groovydoc.destinationDir -} - -task generateSourcesJar(type: Jar) { - archiveClassifier.set("sources") - from sourceSets.main.allJava -} \ No newline at end of file diff --git a/tooling/custom-lint-rules/build.gradle b/tooling/custom-lint-rules/build.gradle index 991a16e38..68fb920c2 100755 --- a/tooling/custom-lint-rules/build.gradle +++ b/tooling/custom-lint-rules/build.gradle @@ -73,8 +73,11 @@ rootProject.project('android-core').android.buildTypes.all { } task zipSources(type: Jar) { - def fileName = "$project.rootDir/android-core/build/intermediates/javac/${targetBuildType}/classes" - from(fileTree(dir: fileName)) + from { + def compileTask = rootProject.project('android-core') + .tasks.named("compile${targetBuildType.capitalize()}JavaWithJavac").get() + fileTree(dir: compileTask.destinationDirectory.get().asFile) + } destinationDirectory.set(new File("$project.projectDir/libs")) archiveFileName.set("mparticle.jar") outputs.upToDateWhen { false } diff --git a/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/DataplanDetector.kt b/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/DataplanDetector.kt index 3b8bee4c3..ce4fc08b5 100644 --- a/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/DataplanDetector.kt +++ b/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/DataplanDetector.kt @@ -274,7 +274,7 @@ class DataplanDetector : CallScanner() { ; companion object { - fun get(value: String?): ViolationSchemaKeywordType = values().firstOrNull { it.toString().toLowerCase() == value?.toLowerCase() } + fun get(value: String?): ViolationSchemaKeywordType = values().firstOrNull { it.toString().lowercase() == value?.lowercase() } ?: Unknown } } diff --git a/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/MpApiDetectorKt.kt b/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/MpApiDetectorKt.kt index d483f39e5..1dfe35e14 100644 --- a/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/MpApiDetectorKt.kt +++ b/tooling/custom-lint-rules/src/main/java/com/mparticle/lints/detectors/MpApiDetectorKt.kt @@ -299,7 +299,7 @@ class MpApiDetectorKt : var isApplicationSubclass = evaluator.extendsClass(it, "android.app.Application", false) var isApplicationClass = - method.containingClass?.qualifiedName.equals("android.app.Application") + method.getContainingUClass()?.qualifiedName == "android.app.Application" isApplicationSubclass && !isApplicationClass } ?: false }