Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 92 additions & 18 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ name: CI
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
branches: [main]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand All @@ -19,46 +18,121 @@ jobs:
lint-and-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
uses: gradle/actions/wrapper-validation@0723195856401067f7a2779048b490ace7a47d7c # ratchet:gradle/actions/wrapper-validation@v5.0.2
- name: Lint GitHub Actions
uses: abcxyz/actions/.github/actions/lint-github-actions@e32ec3bd6af6d87d79fe7c441f435eb7ad11d527 # main
uses: abcxyz/actions/.github/actions/lint-github-actions@e32ec3bd6af6d87d79fe7c441f435eb7ad11d527 # ratchet:abcxyz/actions/.github/actions/lint-github-actions@main
- name: Ratchet Check
uses: sethvargo/ratchet@8b4ca256dbed184350608a3023620f267f0a5253 # main
uses: sethvargo/ratchet@8b4ca256dbed184350608a3023620f267f0a5253 # ratchet:sethvargo/ratchet@main
with:
files: .github/workflows/*.yml

# This workflow contains a single job called "build"
# Build the simple plugins (no special test infrastructure needed)
build:
needs: lint-and-check
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Runs this job in parallel for each sub-project
strategy:
matrix:
project-dir:
- strict-version-matcher-plugin
- google-services-plugin
- oss-licenses-plugin

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2

- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # ratchet:actions/setup-java@v5.2.0
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # ratchet:gradle/actions/setup-gradle@v5.0.2
with:
dependency-graph: generate-and-submit

# Runs a build which includes `check` and `test` tasks
- name: Perform a Gradle build
run: ./gradlew build
working-directory: ./${{ matrix.project-dir }}

# Build and test the oss-licenses plugin, then publish for downstream jobs.
oss-licenses-build:
needs: lint-and-check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2

- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # ratchet:actions/setup-java@v5.2.0
with:
java-version: '17'
distribution: 'temurin'

- name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # ratchet:actions/setup-java@v5.2.0
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # ratchet:gradle/actions/setup-gradle@v5.0.2
with:
dependency-graph: generate-and-submit

- name: Build and test
run: ./gradlew build
working-directory: ./oss-licenses-plugin

- name: Publish to local repo
run: ./gradlew publish
working-directory: ./oss-licenses-plugin

- name: Upload local repo artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # ratchet:actions/upload-artifact@v4.6.2
with:
name: oss-licenses-local-repo
path: oss-licenses-plugin/build/repo/

# Build the testapp and verify configuration cache store → clean → reuse.
# CC strictness flags are in testapp/gradle.properties (always on).
oss-licenses-testapp:
needs: oss-licenses-build
runs-on: ubuntu-latest
env:
ANDROID_USER_HOME: /home/runner/.android
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2

- name: Download local repo artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # ratchet:actions/download-artifact@v4.3.0
with:
name: oss-licenses-local-repo
path: oss-licenses-plugin/build/repo/

- name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # ratchet:actions/setup-java@v5.2.0
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # ratchet:gradle/actions/setup-gradle@v5.0.2

- name: Pre-create Android SDK cache directory
run: mkdir -p "$ANDROID_USER_HOME/cache"

- name: Build testapp (store configuration cache)
run: ./gradlew build -PusePublishedPluginFrom=../build/repo
working-directory: oss-licenses-plugin/testapp

- name: Clean testapp outputs
run: ./gradlew clean -PusePublishedPluginFrom=../build/repo
working-directory: oss-licenses-plugin/testapp

- name: Rebuild testapp (verify configuration cache reuse)
working-directory: oss-licenses-plugin/testapp
run: |
OUTPUT=$(./gradlew build -PusePublishedPluginFrom=../build/repo 2>&1)
echo "$OUTPUT"
echo "$OUTPUT" | grep -q "Configuration cache entry reused" || \
{ echo "::error::Configuration cache was NOT reused"; exit 1; }
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea/
repo/
.kotlin/
.DS_Store
12 changes: 12 additions & 0 deletions oss-licenses-plugin/gradle/gradle-daemon-jvm.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/4945f00643ec68e7c7a6b66f90124f89/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/4945f00643ec68e7c7a6b66f90124f89/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/46949723aaa20c7b64d7ecfed7207034/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/d6690dfd71c4c91e08577437b5b2beb0/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/4945f00643ec68e7c7a6b66f90124f89/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3cd7045fca9a72cd9bc7d14a385e594c/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/552c7bffe0370c66410a51c55985b511/redirect
toolchainVersion=21
4 changes: 4 additions & 0 deletions oss-licenses-plugin/settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}

rootProject.name = 'oss-licenses-plugin'
108 changes: 108 additions & 0 deletions oss-licenses-plugin/testapp/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import com.android.build.api.variant.HostTestBuilder
import org.gradle.api.tasks.testing.Test
import org.gradle.jvm.toolchain.JavaToolchainService

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.oss.licenses)
}

android {
namespace = "com.google.android.gms.oss.licenses.testapp"
compileSdk = libs.versions.compileSdk.get().toInt()
testBuildType = "release"

defaultConfig {
applicationId = "com.google.android.gms.oss.licenses.testapp"
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
debug { isMinifyEnabled = false }
release {
signingConfig = signingConfigs.getByName("debug")
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
testOptions { unitTests { isIncludeAndroidResources = true } }
lint {
abortOnError = true
checkDependencies = true
ignoreWarnings = false
}
}

tasks.withType<Test>().configureEach {
val javaToolchains = project.extensions.getByType<JavaToolchainService>()
javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(21)) })

// Enable parallel execution for faster Robolectric runs
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)

testLogging {
events("passed", "skipped", "failed", "standardOut", "standardError")
showStandardStreams = true
}
}

androidComponents {
beforeVariants { variantBuilder ->
// AGP 9.0 only enables unit tests for the "tested build type" by default.
// We explicitly enable them for all variants to ensure both Debug and Release coverage.
variantBuilder.hostTests[HostTestBuilder.UNIT_TEST_TYPE]?.enable = true
}
}

kotlin {
jvmToolchain(21)
compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21) }
}

dependencies {
implementation(libs.play.services.oss.licenses)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.activity)
implementation("androidx.activity:activity-compose:${libs.versions.androidx.activity.get()}")
implementation(platform(libs.androidx.compose.bom))
implementation("androidx.compose.material3:material3")


testImplementation(libs.junit)
testImplementation(libs.androidx.test.ext.junit)
testImplementation(libs.androidx.test.espresso.core)
testImplementation(libs.androidx.test.espresso.contrib)
testImplementation(libs.androidx.test.core)
testImplementation(libs.robolectric)

// Compose Test (required for testing the V2 activity)
testImplementation(platform(libs.androidx.compose.bom))
testImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.test.manifest)
}
17 changes: 17 additions & 0 deletions oss-licenses-plugin/testapp/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:label="OSS Licenses Test App"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light">
<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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.gms.oss.licenses.testapp

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity as V1Activity
import com.google.android.gms.oss.licenses.v2.OssLicensesMenuActivity as V2Activity

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Button(onClick = { startActivity(Intent(this@MainActivity, V1Activity::class.java)) }) {
Text("Launch V1 Licenses")
}
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { startActivity(Intent(this@MainActivity, V2Activity::class.java)) }) {
Text("Launch V2 Licenses")
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Global Robolectric Configuration
# Note: SDK 36 (Baklava) requires Java 21+ — Robolectric will fail to run it on older JVMs.
sdk=24, 33, 34, 35, 36
Loading
Loading