diff --git a/.github/workflows/make-bom.yml b/.github/workflows/make-bom.yml
index 0ad2ecf4add..0e7d63f5c96 100644
--- a/.github/workflows/make-bom.yml
+++ b/.github/workflows/make-bom.yml
@@ -11,7 +11,9 @@ jobs:
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
with:
python-version: '3.10'
+
- uses: actions/checkout@v4.1.1
+
- name: Set up JDK 17
uses: actions/setup-java@v4.1.0
with:
@@ -21,19 +23,25 @@ jobs:
- name: Build
run: |
- ./ci/run.sh \
- --artifact-target-dir=./logs/artifacts \
- --artifact-patterns=bom.zip \
- --artifact-patterns=bomReleaseNotes.md \
- --artifact-patterns=recipeVersionUpdate.txt \
- gradle \
- -- \
- --build-cache \
- buildBomZip
-
- - name: Upload generated artifacts
+ ./gradlew buildBomBundleZip
+
+ - name: Upload bom
+ uses: actions/upload-artifact@v4.3.3
+ with:
+ name: bom
+ path: build/bom/
+ retention-days: 15
+
+ - name: Upload release notes
+ uses: actions/upload-artifact@v4.3.3
+ with:
+ name: bom_release_notes
+ path: build/bomReleaseNotes.md
+ retention-days: 15
+
+ - name: Upload recipe version update
uses: actions/upload-artifact@v4.3.3
with:
- name: artifacts
- path: ./logs/artifacts/
- retention-days: 5
+ name: recipe_version
+ path: build/recipeVersionUpdate.txt
+ retention-days: 15
diff --git a/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomReleaseNotesTask.kt b/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomReleaseNotesTask.kt
index 72fe51a8017..75bb991dd60 100644
--- a/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomReleaseNotesTask.kt
+++ b/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomReleaseNotesTask.kt
@@ -51,7 +51,7 @@ abstract class GenerateBomReleaseNotesTask : DefaultTask() {
val previousDeps = previousBom.get().dependencyManagement?.dependencies.orEmpty()
previousBomVersions.set(previousDeps.associate { it.fullArtifactName to it.version })
- val sortedDependencies = currentDeps.sortedBy { it.version }
+ val sortedDependencies = currentDeps.sortedBy { it.toString() }
val headingId = "{: #bom_v${bom.version.replace(".", "-")}}"
@@ -71,8 +71,9 @@ abstract class GenerateBomReleaseNotesTask : DefaultTask() {
| Firebase Android SDKs mapped to this {{bom}} version
|
|
- | Libraries that were versioned with this release are in highlighted rows.
- | Refer to a library's release notes (on this page) for details about its changes.
+ | Libraries that were versioned with this release are in highlighted rows.
+ |
Refer to a library's release notes (on this page) for details about its
+ | changes.
|
|
|
diff --git a/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomTask.kt b/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomTask.kt
index 8e5599a530a..9fb7fe35130 100644
--- a/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomTask.kt
+++ b/plugins/src/main/java/com/google/firebase/gradle/bomgenerator/GenerateBomTask.kt
@@ -25,8 +25,8 @@ import com.google.firebase.gradle.plugins.datamodels.LicenseElement
import com.google.firebase.gradle.plugins.datamodels.PomElement
import com.google.firebase.gradle.plugins.datamodels.fullArtifactName
import com.google.firebase.gradle.plugins.datamodels.moduleVersion
-import com.google.firebase.gradle.plugins.diff
import com.google.firebase.gradle.plugins.orEmpty
+import com.google.firebase.gradle.plugins.pairBy
import com.google.firebase.gradle.plugins.partitionNotNull
import com.google.firebase.gradle.plugins.services.GMavenService
import org.gradle.api.DefaultTask
@@ -144,7 +144,7 @@ abstract class GenerateBomTask : DefaultTask() {
val oldBomVersion = ModuleVersion.fromString(oldBom.artifactId, oldBom.version)
val oldBomDependencies = oldBom.dependencyManagement?.dependencies.orEmpty()
- val changedDependencies = oldBomDependencies.diff(releasingDependencies)
+ val changedDependencies = oldBomDependencies.pairBy(releasingDependencies) { it.artifactId }
val versionBumps =
changedDependencies.mapNotNull { (old, new) ->
diff --git a/plugins/src/main/java/com/google/firebase/gradle/plugins/KotlinExtensions.kt b/plugins/src/main/java/com/google/firebase/gradle/plugins/KotlinExtensions.kt
index 8b7634f4500..8f058603e3b 100644
--- a/plugins/src/main/java/com/google/firebase/gradle/plugins/KotlinExtensions.kt
+++ b/plugins/src/main/java/com/google/firebase/gradle/plugins/KotlinExtensions.kt
@@ -296,6 +296,43 @@ infix fun List.diff(other: List): List> {
return firstList.zip(secondList).filter { it.first != it.second }
}
+/**
+ * Creates a list of pairs between two lists, matching according to the provided [mapper].
+ *
+ * ```kotlin
+ * data class Person(name: String, age: Int)
+ *
+ * val firstList = listOf(
+ * Person("Mike", 5),
+ * Person("Rachel", 6)
+ * )
+ *
+ * val secondList = listOf(
+ * Person("Michael", 4),
+ * Person("Mike", 1)
+ * )
+ *
+ * val diffList = firstList.pairBy(secondList) {
+ * it.name
+ * }
+ *
+ * diffList shouldBeEqualTo listOf(
+ * Person("Mike", 5) to Person("Mike", 1)
+ * Person("Rachel", 6) to null
+ * null to Person("Mike", 1)
+ * )
+ * ```
+ */
+inline fun List.pairBy(other: List, mapper: (T) -> R): List> {
+ val firstMap = associateBy { mapper(it) }
+ val secondMap = other.associateBy { mapper(it) }
+
+ val changedOrRemoved = firstMap.map { it.value to secondMap[it.key] }
+ val added = secondMap.filterKeys { it !in firstMap }.map { null to it.value }
+
+ return changedOrRemoved + added
+}
+
/**
* Creates a list that is forced to certain size.
*
diff --git a/plugins/src/main/java/com/google/firebase/gradle/plugins/ModuleVersion.kt b/plugins/src/main/java/com/google/firebase/gradle/plugins/ModuleVersion.kt
index c07b382aac6..3479c536699 100644
--- a/plugins/src/main/java/com/google/firebase/gradle/plugins/ModuleVersion.kt
+++ b/plugins/src/main/java/com/google/firebase/gradle/plugins/ModuleVersion.kt
@@ -269,9 +269,10 @@ data class ModuleVersion(
.let { it ?: if (pre != null) VersionType.PRE else VersionType.PATCH }
.let {
when (it) {
- VersionType.MAJOR -> copy(major = major + 1)
- VersionType.MINOR -> copy(minor = minor + 1)
- VersionType.PATCH -> copy(patch = patch + 1)
+ VersionType.MAJOR ->
+ copy(major = major + 1, minor = 0, patch = 0, pre = pre?.copy(build = 1))
+ VersionType.MINOR -> copy(minor = minor + 1, patch = 0, pre = pre?.copy(build = 1))
+ VersionType.PATCH -> copy(patch = patch + 1, pre = pre?.copy(build = 1))
VersionType.PRE -> copy(pre = pre?.bump())
}
}
diff --git a/plugins/src/main/java/com/google/firebase/gradle/plugins/PublishingPlugin.kt b/plugins/src/main/java/com/google/firebase/gradle/plugins/PublishingPlugin.kt
index b698dc08ad8..82a2aaae858 100644
--- a/plugins/src/main/java/com/google/firebase/gradle/plugins/PublishingPlugin.kt
+++ b/plugins/src/main/java/com/google/firebase/gradle/plugins/PublishingPlugin.kt
@@ -61,6 +61,8 @@ import org.gradle.kotlin.dsl.register
* outside of the standard [FIREBASE_PUBLISH_TASK] workflow (possibly at a later time in the release
* cycle):
* - [BUILD_BOM_ZIP_TASK] -> Creates a zip file of the contents of [GENERATE_BOM_TASK]
+ * [registerGenerateBomTask]
+ * - [BUILD_BOM_BUNDLE_ZIP_TASK] -> Creates a zip file of the contents of [BUILD_BOM_ZIP_TASK]
* [registerGenerateBomTask],
* [GENERATE_BOM_RELEASE_NOTES_TASK][registerGenerateBomReleaseNotesTask] and
* [GENERATE_TUTORIAL_BUNDLE_TASK][registerGenerateTutorialBundleTask]
@@ -140,9 +142,16 @@ abstract class PublishingPlugin : Plugin {
destinationDirectory.set(project.layout.buildDirectory)
}
- project.tasks.register(BUILD_BOM_ZIP_TASK) {
- from(generateBom, generateBomReleaseNotes, generateTutorialBundle)
- archiveFileName.set("bom.zip")
+ val buildBomZip =
+ project.tasks.register(BUILD_BOM_ZIP_TASK) {
+ from(generateBom)
+ archiveFileName.set("bom.zip")
+ destinationDirectory.set(project.layout.buildDirectory)
+ }
+
+ project.tasks.register(BUILD_BOM_BUNDLE_ZIP_TASK) {
+ from(buildBomZip, generateBomReleaseNotes, generateTutorialBundle)
+ archiveFileName.set("bomBundle.zip")
destinationDirectory.set(project.layout.projectDirectory)
}
@@ -757,6 +766,7 @@ abstract class PublishingPlugin : Plugin {
const val BUILD_KOTLINDOC_ZIP_TASK = "buildKotlindocZip"
const val BUILD_RELEASE_NOTES_ZIP_TASK = "buildReleaseNotesZip"
const val BUILD_BOM_ZIP_TASK = "buildBomZip"
+ const val BUILD_BOM_BUNDLE_ZIP_TASK = "buildBomBundleZip"
const val FIREBASE_PUBLISH_TASK = "firebasePublish"
const val PUBLISH_ALL_TO_BUILD_TASK = "publishAllToBuildDir"
diff --git a/plugins/src/main/java/com/google/firebase/gradle/plugins/datamodels/PomElement.kt b/plugins/src/main/java/com/google/firebase/gradle/plugins/datamodels/PomElement.kt
index e3fccfb66e9..dda8db2896d 100644
--- a/plugins/src/main/java/com/google/firebase/gradle/plugins/datamodels/PomElement.kt
+++ b/plugins/src/main/java/com/google/firebase/gradle/plugins/datamodels/PomElement.kt
@@ -158,7 +158,7 @@ data class PomElement(
@XmlElement val artifactId: String,
@XmlElement val version: String,
@XmlElement val packaging: String? = null,
- @XmlChildrenName("licenses") val licenses: List? = null,
+ @XmlChildrenName("license") val licenses: List? = null,
@XmlElement val scm: SourceControlManagement? = null,
@XmlElement val dependencyManagement: DependencyManagementElement? = null,
@XmlChildrenName("dependency") val dependencies: List? = null,
@@ -171,15 +171,25 @@ data class PomElement(
* @see fromFile
*/
fun toFile(file: File): File {
- val xmlWriter = XML {
- indent = 2
- xmlDeclMode = XmlDeclMode.None
- }
- file.writeText(xmlWriter.encodeToString(this))
+ file.writeText(toString())
return file
}
+ /**
+ * Serializes this pom element into a valid XML element.
+ *
+ * @see toFile
+ */
+ override fun toString(): String {
+ return xml.encodeToString(this)
+ }
+
companion object {
+ private val xml = XML {
+ indent = 2
+ xmlDeclMode = XmlDeclMode.None
+ }
+
/**
* Deserializes a [PomElement] from a `pom.xml` file.
*
@@ -201,6 +211,6 @@ data class PomElement(
* @see fromFile
*/
fun fromElement(element: Element): PomElement =
- XML.decodeFromReader(xmlStreaming.newReader(element))
+ xml.decodeFromReader(xmlStreaming.newReader(element))
}
}
diff --git a/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomReleaseNotesTests.kt b/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomReleaseNotesTests.kt
index 3d914df29d8..182d7d0ffb2 100644
--- a/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomReleaseNotesTests.kt
+++ b/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomReleaseNotesTests.kt
@@ -65,8 +65,68 @@ class GenerateBomReleaseNotesTests : FunSpec() {
Firebase Android SDKs mapped to this {{bom}} version
- Libraries that were versioned with this release are in highlighted rows.
- Refer to a library's release notes (on this page) for details about its changes.
+ Libraries that were versioned with this release are in highlighted rows.
+
Refer to a library's release notes (on this page) for details about its
+ changes.
+
+
+
+ Artifact name |
+ Version mapped to previous {{bom}} v1.0.0 |
+ Version mapped to this {{bom}} v1.0.0 |
+
+
+
+ com.google.firebase:firebase-auth |
+ 10.0.0 |
+ 10.0.0 |
+
+
+ com.google.firebase:firebase-firestore |
+ 10.0.0 |
+ 10.0.0 |
+
+
+
+
+ """
+ .trimIndent()
+ }
+
+ @Test
+ fun `sorts the entries alphabetically`() {
+ val dependencies =
+ listOf(
+ ArtifactDependency(
+ groupId = "com.google.firebase",
+ artifactId = "firebase-firestore",
+ version = "10.0.0",
+ ),
+ ArtifactDependency(
+ groupId = "com.google.firebase",
+ artifactId = "firebase-auth",
+ version = "10.0.0",
+ ),
+ )
+ val bom = makeBom("1.0.0", dependencies)
+ val file = makeReleaseNotes(bom, bom)
+
+ file.readText().trim() shouldBeText
+ """
+ ### {{firebase_bom_long}} ({{bill_of_materials}}) version 1.0.0 {: #bom_v1-0-0}
+ {% comment %}
+ These library versions must be flat-typed, do not use variables.
+ The release note for this BoM version is a library-version snapshot.
+ {% endcomment %}
+
+
+
+ Firebase Android SDKs mapped to this {{bom}} version
+
+
+ Libraries that were versioned with this release are in highlighted rows.
+
Refer to a library's release notes (on this page) for details about its
+ changes.
@@ -147,8 +207,9 @@ class GenerateBomReleaseNotesTests : FunSpec() {
Firebase Android SDKs mapped to this {{bom}} version
- Libraries that were versioned with this release are in highlighted rows.
- Refer to a library's release notes (on this page) for details about its changes.
+ Libraries that were versioned with this release are in highlighted rows.
+
Refer to a library's release notes (on this page) for details about its
+ changes.
diff --git a/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomTests.kt b/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomTests.kt
index 0298a4584f3..a1bd5fffbf1 100644
--- a/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomTests.kt
+++ b/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/GenerateBomTests.kt
@@ -243,11 +243,11 @@ class GenerateBomTests : FunSpec() {
1.0.1
pom
-
+
The Apache Software License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
repo
-
+
diff --git a/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/ModuleVersionTests.kt b/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/ModuleVersionTests.kt
index d5027399a0f..c6eb626825d 100644
--- a/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/ModuleVersionTests.kt
+++ b/plugins/src/test/kotlin/com/google/firebase/gradle/plugins/ModuleVersionTests.kt
@@ -95,6 +95,16 @@ class ModuleVersionTests : FunSpec() {
ModuleVersion(1, 1, 1).apply { bump(PRE) shouldBe this }
}
+ @Test
+ fun `Bump resets the smaller version types`() {
+ val version = ModuleVersion(1, 1, 1, PreReleaseVersion(ALPHA, 2))
+
+ version.bump(PRE) shouldBe ModuleVersion(1, 1, 1, PreReleaseVersion(ALPHA, 3))
+ version.bump(PATCH) shouldBe ModuleVersion(1, 1, 2, PreReleaseVersion(ALPHA, 1))
+ version.bump(MINOR) shouldBe ModuleVersion(1, 2, 0, PreReleaseVersion(ALPHA, 1))
+ version.bump(MAJOR) shouldBe ModuleVersion(2, 0, 0, PreReleaseVersion(ALPHA, 1))
+ }
+
@Test
fun `Bump correctly chooses the smallest by default`() {
ModuleVersion(1, 1, 1).bump().patch shouldBe 2