Skip to content

Commit 188f623

Browse files
committed
Merge branch 'master' into firebase-sessions
2 parents 48aed7f + 5f273c7 commit 188f623

File tree

23 files changed

+1334
-27
lines changed

23 files changed

+1334
-27
lines changed

.github/workflows/fireperf-e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ jobs:
9393
title: 'FirePerf E2E Test Failures',
9494
body: text,
9595
labels: ['fireperf-e2e-tests'],
96-
assignees: ['jeremyjiang-dev', 'leotianlizhan', 'raymondlam', 'visumickey']
96+
assignees: ['raymondlam', 'visumickey']
9797
});
9898
}
9999
- name: Upload test artifacts

buildSrc/src/main/java/com/google/firebase/gradle/plugins/CheckHeadDependencies.kt

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,39 @@ abstract class CheckHeadDependencies : DefaultTask() {
2929
@TaskAction
3030
fun run() {
3131
val projectsReleasing: Set<String> = projectsToPublish.get().map { it.artifactId.get() }.toSet()
32-
val projectsToRelease =
32+
val errors =
3333
projectsToPublish
3434
.get()
35-
.flatMap {
36-
it.project.configurations
37-
.getByName(it.runtimeClasspath)
38-
.allDependencies
39-
.filter { it is ProjectDependency }
40-
.map { it.name }
41-
.toSet()
35+
.associate {
36+
it.artifactId.get() to
37+
it
38+
.projectDependenciesByName()
39+
.intersect(allFirebaseProjects.get())
40+
.subtract(projectsReleasing)
41+
.subtract(DEPENDENCIES_TO_IGNORE)
4242
}
43-
.intersect(allFirebaseProjects.get())
44-
.subtract(projectsReleasing)
43+
.filterValues { it.isNotEmpty() }
44+
.map { "${it.key} requires: ${it.value.joinToString(", ") }" }
4545

46-
if (projectsToRelease.isNotEmpty()) {
46+
if (errors.isNotEmpty()) {
4747
throw GradleException(
48-
"Following Sdks have to release as well. Please update the release config.\n${projectsToRelease.joinToString("\n")}"
48+
"Project-level dependency errors found. Please update the release config.\n${
49+
errors.joinToString(
50+
"\n"
51+
)
52+
}"
4953
)
5054
}
5155
}
56+
57+
fun FirebaseLibraryExtension.projectDependenciesByName(): List<String> =
58+
project.configurations
59+
.getByName(runtimeClasspath)
60+
.allDependencies
61+
.filter { it is ProjectDependency }
62+
.map { it.name }
63+
64+
companion object {
65+
val DEPENDENCIES_TO_IGNORE: List<String> = listOf("protolite-well-known-types")
66+
}
5267
}

buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseJavaLibraryPlugin.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import com.github.sherter.googlejavaformatgradleplugin.GoogleJavaFormatExtension
1818
import com.github.sherter.googlejavaformatgradleplugin.GoogleJavaFormatPlugin
1919
import com.google.common.collect.ImmutableList
2020
import com.google.firebase.gradle.plugins.LibraryType.JAVA
21+
import com.google.firebase.gradle.plugins.semver.ApiDiffer
22+
import com.google.firebase.gradle.plugins.semver.GmavenCopier
2123
import org.gradle.api.Project
2224
import org.gradle.api.attributes.Attribute
2325
import org.gradle.api.plugins.JavaLibraryPlugin
@@ -48,9 +50,38 @@ class FirebaseJavaLibraryPlugin : BaseFirebaseLibraryPlugin() {
4850
setupStaticAnalysis(project, firebaseLibrary)
4951
setupApiInformationAnalysis(project)
5052
getIsPomValidTask(project, firebaseLibrary)
53+
getSemverTaskJar(project, firebaseLibrary)
5154
configurePublishing(project, firebaseLibrary)
5255
}
5356

57+
private fun getSemverTaskJar(project: Project, firebaseLibrary: FirebaseLibraryExtension) {
58+
project.mkdir("semver")
59+
project.tasks.register<GmavenCopier>("copyPreviousArtifacts") {
60+
dependsOn("jar")
61+
project.file("semver/previous.jar").delete()
62+
groupId.value(firebaseLibrary.groupId.get())
63+
artifactId.value(firebaseLibrary.artifactId.get())
64+
aarAndroidFile.value(false)
65+
filePath.value(project.file("semver/previous.jar").absolutePath)
66+
}
67+
val currentJarFile =
68+
project
69+
.file("build/libs/${firebaseLibrary.artifactId.get()}-${firebaseLibrary.version}.jar")
70+
.absolutePath
71+
val previousJarFile = project.file("semver/previous.jar").absolutePath
72+
project.tasks.register<ApiDiffer>("semverCheck") {
73+
currentJar.value(currentJarFile)
74+
previousJar.value(previousJarFile)
75+
version.value(firebaseLibrary.version)
76+
previousVersionString.value(
77+
GmavenHelper(firebaseLibrary.groupId.get(), firebaseLibrary.artifactId.get())
78+
.getLatestReleasedVersion()
79+
)
80+
81+
dependsOn("copyPreviousArtifacts")
82+
}
83+
}
84+
5485
private fun setupApiInformationAnalysis(project: Project) {
5586
val srcDirs =
5687
project.convention.getPlugin<JavaPluginConvention>().sourceSets.getByName("main").java.srcDirs

buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.kt

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ import com.github.sherter.googlejavaformatgradleplugin.GoogleJavaFormatPlugin
2121
import com.google.firebase.gradle.plugins.LibraryType.ANDROID
2222
import com.google.firebase.gradle.plugins.ci.device.FirebaseTestServer
2323
import com.google.firebase.gradle.plugins.license.LicenseResolverPlugin
24+
import com.google.firebase.gradle.plugins.semver.ApiDiffer
25+
import com.google.firebase.gradle.plugins.semver.GmavenCopier
2426
import java.io.File
2527
import org.gradle.api.JavaVersion
2628
import org.gradle.api.Project
2729
import org.gradle.api.attributes.Attribute
2830
import org.gradle.api.publish.tasks.GenerateModuleMetadata
29-
import org.gradle.kotlin.dsl.apply
30-
import org.gradle.kotlin.dsl.create
31-
import org.gradle.kotlin.dsl.getByType
32-
import org.gradle.kotlin.dsl.withType
31+
import org.gradle.api.tasks.Copy
32+
import org.gradle.kotlin.dsl.*
3333
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
3434

3535
class FirebaseLibraryPlugin : BaseFirebaseLibraryPlugin() {
@@ -81,9 +81,51 @@ class FirebaseLibraryPlugin : BaseFirebaseLibraryPlugin() {
8181
android.testServer(FirebaseTestServer(project, firebaseLibrary.testLab, android))
8282
setupStaticAnalysis(project, firebaseLibrary)
8383
getIsPomValidTask(project, firebaseLibrary)
84+
getSemverTaskAar(project, firebaseLibrary)
8485
configurePublishing(project, firebaseLibrary, android)
8586
}
8687

88+
private fun getSemverTaskAar(project: Project, firebaseLibrary: FirebaseLibraryExtension) {
89+
project.mkdir("semver")
90+
project.tasks.register<GmavenCopier>("copyPreviousArtifacts") {
91+
dependsOn("bundleReleaseAar")
92+
project.file("semver/previous.aar").delete()
93+
94+
groupId.value(firebaseLibrary.groupId.get())
95+
artifactId.value(firebaseLibrary.artifactId.get())
96+
aarAndroidFile.value(true)
97+
filePath.value(project.file("semver/previous.aar").absolutePath)
98+
}
99+
100+
project.tasks.register<Copy>("extractCurrentClasses") {
101+
dependsOn("bundleReleaseAar")
102+
103+
from(project.zipTree("build/outputs/aar/${firebaseLibrary.artifactId.get()}-release.aar"))
104+
into(project.file("semver/current-version"))
105+
}
106+
project.tasks.register<Copy>("extractPreviousClasses") {
107+
dependsOn("copyPreviousArtifacts")
108+
109+
from(project.zipTree("semver/previous.aar"))
110+
into(project.file("semver/previous-version"))
111+
}
112+
113+
val currentJarFile = project.file("semver/current-version/classes.jar").absolutePath
114+
115+
val previousJarFile = project.file("semver/previous-version/classes.jar").absolutePath
116+
project.tasks.register<ApiDiffer>("semverCheck") {
117+
currentJar.value(currentJarFile)
118+
previousJar.value(previousJarFile)
119+
version.value(firebaseLibrary.version)
120+
previousVersionString.value(
121+
GmavenHelper(firebaseLibrary.groupId.get(), firebaseLibrary.artifactId.get())
122+
.getLatestReleasedVersion()
123+
)
124+
dependsOn("extractCurrentClasses")
125+
dependsOn("extractPreviousClasses")
126+
}
127+
}
128+
87129
private fun setupApiInformationAnalysis(project: Project, android: LibraryExtension) {
88130
val srcDirs = android.sourceSets.getByName("main").java.srcDirs
89131

buildSrc/src/main/java/com/google/firebase/gradle/plugins/GmavenHelper.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ class GmavenHelper(val groupId: String, val artifactId: String) {
2929
return "${GMAVEN_ROOT}/${groupIdAsPath}/${artifactId}/${version}/${pomFileName}"
3030
}
3131

32+
fun getArtifactForVersion(version: String, isJar: Boolean): String {
33+
val fileName =
34+
if (isJar == true) "${artifactId}-${version}.jar" else "${artifactId}-${version}.aar"
35+
val groupIdAsPath = groupId.replace(".", "/")
36+
return "${GMAVEN_ROOT}/${groupIdAsPath}/${artifactId}/${version}/${fileName}"
37+
}
38+
3239
fun getLatestReleasedVersion(): String {
3340
try {
3441
val groupIdAsPath = groupId.replace(".", "/")

buildSrc/src/main/java/com/google/firebase/gradle/plugins/ModuleVersion.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ enum class PreReleaseVersionType {
6161
* "12.13.1-beta" // 12.13.1-beta01
6262
* ```
6363
*
64-
* @see fromStringsOrNull
6564
* @property type an enum of [PreReleaseVersionType] that identifies the pre-release identifier
6665
* @property build an [Int] that specifies the build number; defaults to one
66+
* @see fromStringsOrNull
6767
*/
6868
data class PreReleaseVersion(val type: PreReleaseVersionType, val build: Int = 1) :
6969
Comparable<PreReleaseVersion> {
@@ -124,11 +124,11 @@ data class PreReleaseVersion(val type: PreReleaseVersionType, val build: Int = 1
124124
*
125125
* To see rules about pre-release (`PRE`) formatting, see [PreReleaseVersion].
126126
*
127-
* @see fromStringOrNull
128127
* @property major An update that represents breaking changes
129128
* @property minor An update that represents new functionality
130129
* @property patch An update that represents bug fixes
131130
* @property pre An update that represents unstable changes not ready for a full release
131+
* @see fromStringOrNull
132132
*/
133133
data class ModuleVersion(
134134
val major: Int,
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.gradle.plugins.semver
16+
17+
import org.objectweb.asm.Opcodes
18+
19+
/**
20+
* Convenience class that helps avoid confusing (if more performant) bitwise checks against {@link
21+
* Opcodes}
22+
*/
23+
class AccessDescriptor(private val access: Int) {
24+
fun isProtected(): Boolean = accessIs(Opcodes.ACC_PROTECTED)
25+
26+
fun isPublic(): Boolean = accessIs(Opcodes.ACC_PUBLIC)
27+
28+
fun isStatic(): Boolean = accessIs(Opcodes.ACC_STATIC)
29+
30+
fun isSynthetic(): Boolean = accessIs(Opcodes.ACC_SYNTHETIC)
31+
32+
fun isBridge(): Boolean = accessIs(Opcodes.ACC_BRIDGE)
33+
34+
fun isAbstract(): Boolean = accessIs(Opcodes.ACC_ABSTRACT)
35+
36+
fun isFinal(): Boolean = accessIs(Opcodes.ACC_FINAL)
37+
38+
fun isPrivate(): Boolean = !this.isProtected() && !this.isPublic()
39+
40+
fun getVerboseDescription(): String {
41+
val outputStringList = mutableListOf<String>()
42+
if (this.isPublic()) {
43+
outputStringList.add("public")
44+
}
45+
if (this.isPrivate()) {
46+
outputStringList.add("private")
47+
}
48+
if (this.isProtected()) {
49+
outputStringList.add("protected")
50+
}
51+
if (this.isStatic()) {
52+
outputStringList.add("static")
53+
}
54+
if (this.isFinal()) {
55+
outputStringList.add("final")
56+
}
57+
if (this.isAbstract()) {
58+
outputStringList.add("abstract")
59+
}
60+
return outputStringList.joinToString(" ")
61+
}
62+
/** Returns true if the given access modifier matches the given opcode. */
63+
fun accessIs(opcode: Int): Boolean = (access and opcode) != 0
64+
}

0 commit comments

Comments
 (0)