Skip to content

Commit

Permalink
Implement centralized config for Release Note generation (#6099)
Browse files Browse the repository at this point in the history
Per [b/352342089](https://b.corp.google.com/issues/352342089),

This implements a new extension through `FirebaseLibrary` called
`ReleaseNotesConfigurationExtension`. This can be configured through the
`releaseNotes` helper method that takes an `Action` argument; similar to
what we do with `FirebaseTestLabExtension` and `FirebaseStaticAnalysis`.

The goal of this move is to not only allow teams to modify their release
notes metadata, but provide an obvious indicator of release note
configuration that must be changed to properly generate release notes.
This way, we avoid accidentally _not_ generating release notes for
libraries that should otherwise have them.

Furthermore, this opens the door for exposing more release note
configurations to product teams (such as `annotationsNotToDisplay`,
`suppressedFiles`, `includedHeadTagsPath`, `package-list` mappings,
etc.,).

NO_RELEASE_CHANGE
  • Loading branch information
daymxn authored Jul 15, 2024
1 parent f23f6f1 commit cad0339
Show file tree
Hide file tree
Showing 63 changed files with 288 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ firebaseLibrary {
libraryGroup "appcheck"
testLab.enabled = true
publishSources = true
releaseNotes {
name.set("{{app_check}} Debug Testing")
versionName.set("appcheck-debug-testing")
hasKTX.set(false)
}
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ plugins {
firebaseLibrary {
libraryGroup "appcheck"
publishSources = true
releaseNotes {
name.set("{{app_check}} Debug")
versionName.set("appcheck-debug")
hasKTX.set(false)
}
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ plugins {
firebaseLibrary {
publishSources = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ plugins {
firebaseLibrary {
libraryGroup "appcheck"
publishSources = true
releaseNotes {
name.set("{{app_check}} Play integrity")
versionName.set("appcheck-playintegrity")
hasKTX.set(false)
}
}

android {
Expand Down
4 changes: 4 additions & 0 deletions appcheck/firebase-appcheck/firebase-appcheck.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ plugins {
firebaseLibrary {
libraryGroup "appcheck"
publishSources = true
releaseNotes {
name.set("{{app_check}}")
versionName.set("appcheck")
}
}

android {
Expand Down
4 changes: 3 additions & 1 deletion appcheck/firebase-appcheck/ktx/ktx.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ firebaseLibrary {
libraryGroup "appcheck"
testLab.enabled = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
publishSources = true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ public class FirebaseLibraryExtension {
/** Indicates whether the library has public javadoc. */
public boolean publishJavadoc = true;

/** Indicates whether release notes are published for the library. */
public boolean publishReleaseNotes = true;

/** Indicates whether sources are published alongside the library. */
public boolean publishSources;

Expand All @@ -54,6 +51,9 @@ public class FirebaseLibraryExtension {
/** Firebase Test Lab configuration/ */
public final FirebaseTestLabExtension testLab;

/** Release notes configuration. */
public final ReleaseNotesConfigurationExtension releaseNotes;

public Property<String> groupId;
public Property<String> artifactId;

Expand Down Expand Up @@ -83,6 +83,10 @@ public FirebaseLibraryExtension(Project project, LibraryType type) {
this.testLab = new FirebaseTestLabExtension(project.getObjects());
this.artifactId = project.getObjects().property(String.class);
this.groupId = project.getObjects().property(String.class);
this.releaseNotes = project.getExtensions().create("releaseNotes", ReleaseNotesConfigurationExtension.class);
this.releaseNotes.getEnabled().convention(true);
this.releaseNotes.getHasKTX().convention(true);
this.releaseNotes.getArtifactName().convention(project.getName());

if ("ktx".equals(project.getName()) && project.getParent() != null) {
artifactId.set(new DefaultProvider<>(() -> project.getParent().getName() + "-ktx"));
Expand Down Expand Up @@ -127,6 +131,10 @@ public void customizePom(Action<MavenPom> action) {
customizePomAction = action;
}

public void releaseNotes(Action<ReleaseNotesConfigurationExtension> action) {
action.execute(releaseNotes);
}

public void applyPomCustomization(MavenPom pom) {
if (customizePomAction != null) {
customizePomAction.execute(pom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,17 @@ abstract class MakeReleaseNotesTask : DefaultTask() {
* updates.
* ```
*
* @see convertToMetadata
* @see ReleaseNotesConfigurationExtension
*/
@TaskAction
fun make() {
val changelog = Changelog.fromFile(changelogFile.asFile.get())
val metadata = convertToMetadata(project.name)
val config = project.firebaseLibrary.releaseNotes
val unreleased = changelog.releases.first()
val version = project.version.toString()
val skipMissing = skipMissingEntries.getOrElse(false)

if (!project.firebaseLibrary.publishReleaseNotes)
if (!config.enabled.get())
throw StopActionException("No release notes required for ${project.name}")

if (!unreleased.hasContent()) {
Expand All @@ -108,7 +108,7 @@ abstract class MakeReleaseNotesTask : DefaultTask() {

val baseReleaseNotes =
"""
|### ${metadata.name} version $version {: #${metadata.versionName}_v$versionClassifier}
|### ${config.name.get()} version $version {: #${config.versionName.get()}_v$versionClassifier}
|
|${unreleased.content.toReleaseNotes()}
"""
Expand All @@ -117,13 +117,13 @@ abstract class MakeReleaseNotesTask : DefaultTask() {

val ktxReleaseNotes =
"""
|#### ${metadata.name} Kotlin extensions version $version {: #${metadata.versionName}-ktx_v$versionClassifier}
|#### ${config.name.get()} Kotlin extensions version $version {: #${config.versionName.get()}-ktx_v$versionClassifier}
|
|${unreleased.ktx?.toReleaseNotes() ?: KTXTransitiveReleaseText(project.name)}
"""
.trimMargin()
.trim()
.takeIf { metadata.hasKTX }
.takeIf { config.hasKTX.get() }

val releaseNotes =
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,22 @@ abstract class MoveUnreleasedChangesTask : DefaultTask() {
* Ensures the entry is only created if the library has a KTX lib to begin with, and adds template
* subtext if it lacks any changes.
*
* @see convertToMetadata
* @see ReleaseNotesConfigurationExtension
* @see KTXTransitiveReleaseText
*/
private fun createEntryForKTX(release: ReleaseEntry): ReleaseContent? {
val metadata = convertToMetadata(project.name)
val releaseNotesConfig = project.firebaseLibrary.releaseNotes

val nonEmptyKTXContent = release.ktx?.takeIf { it.hasContent() }

val ktxContent =
nonEmptyKTXContent ?: ReleaseContent(KTXTransitiveReleaseText(project.name), emptyList())
nonEmptyKTXContent
?: ReleaseContent(
KTXTransitiveReleaseText(releaseNotesConfig.artifactName.get()),
emptyList()
)

return ktxContent.takeIf { metadata.hasKTX }
return ktxContent.takeIf { releaseNotesConfig.hasKTX.get() }
}

private fun configure() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2024 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
*
* http://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.firebase.gradle.plugins

import org.gradle.api.provider.Property

/**
* Configuration options for release note generation of libraries.
*
* Also facilitates the centralization of certain externally defined data (usually defined on G3).
* As we can't link G3 files on GitHub, if you're setting up a new SDK and are unsure what release
* note mappings your SDK has (or will have) ask Rachel or the ACore team for the relevant variable
* mappings.
*
* @property enabled Whether to generate release notes for this library. Defaults to true.
*
* @property name The variable name mapping for this library, defined on G3.
*
* @property versionName The version name mapping for this library, defined on G3.
*
* @property hasKTX The library has a sub module with the suffix '-ktx' that releases alongside this
* library, and should have the transitive text added to the release notes. Defaults to true. Will
* likely be removed when we officially drop KTX libraries.
*
* @property artifactName The name of the generation artifact. _Only_ required if your project's
* name is different than your generated artifact name. Defaults to the project name.
*
* @see MakeReleaseNotesTask
*/
abstract class ReleaseNotesConfigurationExtension {
abstract val enabled: Property<Boolean>
abstract val name: Property<String>
abstract val versionName: Property<String>
abstract val hasKTX: Property<Boolean>
abstract val artifactName: Property<String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import java.io.IOException
import java.util.Properties
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.tasks.StopActionException

val Project.sdkDir: File
get() {
Expand Down Expand Up @@ -58,85 +57,8 @@ val Project.androidJar: File?
fun KTXTransitiveReleaseText(projectName: String) =
"""
|The Kotlin extensions library transitively includes the updated
|`${ProjectNameToKTXPlaceholder(projectName)}` library. The Kotlin extensions library has no additional
|`$projectName` library. The Kotlin extensions library has no additional
|updates.
"""
.trimMargin()
.trim()

/**
* Maps a project's name to a KTX suitable placeholder.
*
* Some libraries produce artifacts with different coordinates than their project name. This method
* helps to map that gap for [KTXTransitiveReleaseText].
*/
fun ProjectNameToKTXPlaceholder(projectName: String) =
when (projectName) {
"firebase-perf" -> "firebase-performance"
"firebase-appcheck" -> "firebase-appcheck"
else -> projectName
}

/**
* Provides extra metadata needed to create release notes for a given project.
*
* This data is needed for g3 internal mappings, and does not really have any implications for
* public repo actions.
*
* @property name The variable name for a project in a release note
* @property vesionName The variable name given to the versions of a project
* @property hasKTX The module has a KTX submodule (not to be confused with having KTX files)
* @see MakeReleaseNotesTask
*/
data class ReleaseNotesMetadata(
val name: String,
val versionName: String,
val hasKTX: Boolean = true
)

/**
* Maps the name of a project to its potential [ReleaseNotesMetadata].
*
* @throws StopActionException If a mapping is not found
*/
// TODO() - Should we expose these as firebaselib configuration points; especially for new SDKS?
fun convertToMetadata(string: String) =
when (string) {
"firebase-abt" -> ReleaseNotesMetadata("{{ab_testing}}", "ab_testing", false)
"firebase-appdistribution" -> ReleaseNotesMetadata("{{appdistro}}", "app-distro", false)
"firebase-appdistribution-api" -> ReleaseNotesMetadata("{{appdistro}} API", "app-distro-api")
"firebase-config" -> ReleaseNotesMetadata("{{remote_config}}", "remote-config")
"firebase-crashlytics" -> ReleaseNotesMetadata("{{crashlytics}}", "crashlytics")
"firebase-crashlytics-ndk" ->
ReleaseNotesMetadata("{{crashlytics}} NDK", "crashlytics-ndk", false)
"firebase-database" -> ReleaseNotesMetadata("{{database}}", "realtime-database")
"firebase-dynamic-links" -> ReleaseNotesMetadata("{{ddls}}", "dynamic-links")
"firebase-firestore" -> ReleaseNotesMetadata("{{firestore}}", "firestore")
"firebase-functions" -> ReleaseNotesMetadata("{{functions_client}}", "functions-client")
"firebase-dynamic-module-support" ->
ReleaseNotesMetadata(
"Dynamic feature modules support",
"dynamic-feature-modules-support",
false
)
"firebase-inappmessaging" -> ReleaseNotesMetadata("{{inappmessaging}}", "inappmessaging")
"firebase-inappmessaging-display" ->
ReleaseNotesMetadata("{{inappmessaging}} Display", "inappmessaging-display")
"firebase-installations" -> ReleaseNotesMetadata("{{firebase_installations}}", "installations")
"firebase-messaging" -> ReleaseNotesMetadata("{{messaging_longer}}", "messaging")
"firebase-messaging-directboot" ->
ReleaseNotesMetadata("Cloud Messaging Direct Boot", "messaging-directboot", false)
"firebase-ml-modeldownloader" ->
ReleaseNotesMetadata("{{firebase_ml}}", "firebaseml-modeldownloader")
"firebase-perf" -> ReleaseNotesMetadata("{{perfmon}}", "performance")
"firebase-storage" -> ReleaseNotesMetadata("{{firebase_storage_full}}", "storage")
"firebase-appcheck" -> ReleaseNotesMetadata("{{app_check}}", "appcheck")
"firebase-appcheck-debug" ->
ReleaseNotesMetadata("{{app_check}} Debug", "appcheck-debug", false)
"firebase-appcheck-debug-testing" ->
ReleaseNotesMetadata("{{app_check}} Debug Testing", "appcheck-debug-testing", false)
"firebase-appcheck-playintegrity" ->
ReleaseNotesMetadata("{{app_check}} Play integrity", "appcheck-playintegrity", false)
"firebase-vertexai" -> ReleaseNotesMetadata("{{firebase_vertexai}}", "vertex-ai", false)
else -> throw StopActionException("No metadata mapping found for project: $string")
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ plugins {
id 'firebase-library'
}

firebaseLibrary {
releaseNotes {
name.set("{{firebase_storage_full}}")
versionName.set("storage")
}
}

android{
namespace 'com.example.firebase-storage'
compileSdkVersion 26
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ plugins {
firebaseLibrary {
publishSources = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ plugins {
firebaseLibrary {
publishSources = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ plugins {
firebaseLibrary {
publishSources = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
}

java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ plugins {
firebaseLibrary {
publishSources = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
}

android {
Expand Down
4 changes: 3 additions & 1 deletion encoders/firebase-encoders/firebase-encoders.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ plugins {
firebaseLibrary {
publishSources = true
publishJavadoc = false
publishReleaseNotes = false
releaseNotes {
enabled.set(false)
}
}

java {
Expand Down
Loading

0 comments on commit cad0339

Please sign in to comment.