Skip to content

Commit

Permalink
Release generator improvements (#5077)
Browse files Browse the repository at this point in the history
* add json release config, add PR link parsing, remove intentionally skipped commits from all searched

* ktfmt

* remove trailing space

* fix gson

* swap to built in serialization over gson

* updated comments for better rendering

* ktfmt

---------

Co-authored-by: David Motsonashvili <davidmotson@google.com>
  • Loading branch information
davidmotson and David Motsonashvili authored Jun 22, 2023
1 parent dd710a7 commit d028b21
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/create_releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
with:
base: 'releases/${{ inputs.name }}'
branch: 'releases/${{ inputs.name }}.release'
add-paths: release.json,release_report.md
add-paths: release.json,release_report.md,release_report.json
title: '${{ inputs.name}} release'
body: 'Auto-generated PR for release ${{ inputs.name}}'
commit-message: 'Create release config for ${{ inputs.name }}'
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,10 @@ abstract class PublishingPlugin : Plugin<Project> {
printReleaseConfig.convention(project.provideProperty("printOutput"))

releaseConfigFile.convention(project.layout.projectDirectory.file(RELEASE_CONFIG_FILE))
releaseReportFile.convention(project.layout.projectDirectory.file(RELEASE_REPORT_FILE))
releaseReportMdFile.convention(project.layout.projectDirectory.file(RELEASE_REPORT_MD_FILE))
releaseReportJsonFile.convention(
project.layout.projectDirectory.file(RELEASE_REPORT_JSON_FILE)
)
}

/**
Expand Down Expand Up @@ -441,7 +444,8 @@ abstract class PublishingPlugin : Plugin<Project> {

companion object {
const val RELEASE_CONFIG_FILE = "release.json"
const val RELEASE_REPORT_FILE = "release_report.md"
const val RELEASE_REPORT_MD_FILE = "release_report.md"
const val RELEASE_REPORT_JSON_FILE = "release_report.json"

const val GENERATE_BOM_TASK = "generateBom"
const val VALIDATE_PROJECTS_TO_PUBLISH_TASK = "validateProjectsToPublish"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ package com.google.firebase.gradle.plugins

import com.google.common.collect.ImmutableList
import java.io.File
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.api.ListBranchCommand
import org.eclipse.jgit.api.errors.GitAPIException
Expand All @@ -31,25 +34,85 @@ import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.findByType

/**
* Contains output data from the Release Generator, published as release_report.json
*
* @property changesByLibraryName contains libs which have opted into the release, and their changes
* @property changedLibrariesWithNoChangelog contains libs not opted into the release, despite
* having changes
*/
@Serializable
data class ReleaseReport(
val changesByLibraryName: Map<String, List<CommitDiff>>,
val changedLibrariesWithNoChangelog: Set<String>
) {
companion object {
val formatter = Json { prettyPrint = true }
}

fun toFile(file: File) = file.also { it.writeText(formatter.encodeToString(this)) }

override fun toString() =
"""
|# Release Report
|${
changesByLibraryName.entries.joinToString("\n") {
"""
|## ${it.key}
|${it.value.joinToString("\n") { it.toString() }}
""".trimMargin()
}
}
|
|## SDKs with changes, but no changelogs
|${changedLibrariesWithNoChangelog.joinToString(" \n")}
"""
.trimMargin()
}

@Serializable
data class CommitDiff(
val commitId: String,
val prId: String,
val author: String,
val message: String,
val commitLink: String,
val prLink: String,
) {
constructor(
revCommit: RevCommit
) : this(revCommit.id.name, revCommit.authorIdent.name, revCommit.fullMessage) {}
companion object {
// This is a meant to capture the PR number from PR Titles
// ex: "Fix a problem (#1234)" -> "1234"
private val PR_ID_EXTRACTOR = Regex(".*\\(#(\\d+)\\).*")

public fun fromRevCommit(commit: RevCommit): CommitDiff {
val commitId = commit.id.name
val prId =
PR_ID_EXTRACTOR.find(commit.fullMessage.split("\n").first())?.groupValues?.get(1) ?: ""
return CommitDiff(
commitId,
prId,
commit.authorIdent.name,
commit.fullMessage,
"https://github.com/firebase/firebase-android-sdk/commit/$commitId",
"https://github.com/firebase/firebase-android-sdk/pull/$prId"
)
}
}

override fun toString(): String =
"""
|* ${message.split("\n").first()}
| https://github.com/firebase/firebase-android-sdk/commit/${commitId} [${author}]
| [pr]($prLink) [commit]($commitLink) [$author]
"""
.trimMargin()
}

abstract class ReleaseGenerator : DefaultTask() {
companion object {
private val RELEASE_CHANGE_FILTER = "NO_RELEASE_CHANGE"
}

@get:Input abstract val currentRelease: Property<String>

Expand All @@ -59,7 +122,9 @@ abstract class ReleaseGenerator : DefaultTask() {

@get:OutputFile abstract val releaseConfigFile: RegularFileProperty

@get:OutputFile abstract val releaseReportFile: RegularFileProperty
@get:OutputFile abstract val releaseReportMdFile: RegularFileProperty

@get:OutputFile abstract val releaseReportJsonFile: RegularFileProperty

@TaskAction
@Throws(Exception::class)
Expand All @@ -81,34 +146,14 @@ abstract class ReleaseGenerator : DefaultTask() {
val releaseConfig = ReleaseConfig(currentRelease.get(), libsToRelease.map { it.path })
releaseConfig.toFile(releaseConfigFile.get().asFile)

val releaseReport = generateReleaseReport(changes, changedLibsWithNoChangelog)
val releaseReport = ReleaseReport(changes, changedLibsWithNoChangelog)
if (printReleaseConfig.orNull.toBoolean()) {
project.logger.info(releaseReport)
project.logger.info(releaseReport.toString())
}
writeReleaseReport(releaseReportFile.get().asFile, releaseReport)
releaseReportMdFile.get().asFile.writeText(releaseReport.toString())
releaseReportJsonFile.get().asFile.let { releaseReport.toFile(it) }
}

private fun generateReleaseReport(
changes: Map<String, List<CommitDiff>>,
changedLibrariesWithNoChangelog: Set<String>
) =
"""
|# Release Report
|${
changes.entries.joinToString("\n") {
"""
|## ${it.key}
|${it.value.joinToString("\n") { it.toString() }}
""".trimMargin()
}
}
|
|## SDKs with changes, but no changelogs
|${changedLibrariesWithNoChangelog.joinToString(" \n")}
"""
.trimMargin()

private fun getChangesForLibraries(
repo: Git,
branchRef: ObjectId,
Expand Down Expand Up @@ -179,7 +224,7 @@ abstract class ReleaseGenerator : DefaultTask() {
.addRange(previousReleaseRef, currentReleaseRef)
.setMaxCount(10)
.call()
.filter { !it.fullMessage.contains("NO_RELEASE_CHANGE") }
.filter { !it.fullMessage.contains(RELEASE_CHANGE_FILTER) }
.isNotEmpty()

private fun getDirChanges(
Expand All @@ -188,11 +233,13 @@ abstract class ReleaseGenerator : DefaultTask() {
currentReleaseRef: ObjectId,
directory: String
) =
repo.log().addPath(directory).addRange(previousReleaseRef, currentReleaseRef).call().map {
CommitDiff(it)
}

private fun writeReleaseReport(file: File, report: String) = file.writeText(report)
repo
.log()
.addPath(directory)
.addRange(previousReleaseRef, currentReleaseRef)
.call()
.filter { !it.fullMessage.contains(RELEASE_CHANGE_FILTER) }
.map { CommitDiff.fromRevCommit(it) }

private fun getRelativeDir(project: Project) = project.path.substring(1).replace(':', '/')
}

0 comments on commit d028b21

Please sign in to comment.