Skip to content

Commit 2c27445

Browse files
davidmotsonDavid Motsonashvili
and
David Motsonashvili
authored
Release Generator Rebuilt PR (#4484)
* Release Generator PR Rebuilt * ktfmt & new dep * added change to github workflow * add license Co-authored-by: David Motsonashvili <[email protected]>
1 parent 72b228d commit 2c27445

File tree

4 files changed

+134
-6
lines changed

4 files changed

+134
-6
lines changed

.github/workflows/create_releases.yml

+5-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
description: 'Release name'
88
required: true
99
type: string
10+
past-name:
11+
description: 'Past release name'
12+
required: true
13+
type: string
1014

1115
jobs:
1216
create-branches:
@@ -32,12 +36,7 @@ jobs:
3236
run: |
3337
git config user.name 'Create Release GA'
3438
git config user.email '[email protected]'
35-
echo "[release]" > release.cfg
36-
echo "name = ${{ inputs.name }}" >> release.cfg
37-
echo "mode = RELEASE" >> release.cfg
38-
echo "" >> release.cfg
39-
echo "[modules]" >> release.cfg
40-
echo "" >> release.cfg
39+
./gradlew generateReleaseConfig -PcurrentRelease=${{ inputs.name }} -PpastRelease=${{ inputs.past-name }} -PprintOutput=true
4140
git add release.cfg
4241
git commit -a -m 'Create release config'
4342

buildSrc/build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ dependencies {
5858
implementation("org.eclipse.aether:aether-transport-http:1.0.0.v20140518")
5959
implementation("org.eclipse.aether:aether-transport-wagon:1.0.0.v20140518")
6060
implementation("org.apache.maven:maven-aether-provider:3.1.0")
61+
62+
implementation("org.eclipse.jgit:org.eclipse.jgit:6.3.0.202209071007-r")
6163

6264
implementation("com.google.code.gson:gson:2.8.9")
6365
implementation("com.android.tools.build:gradle:7.2.2")

buildSrc/src/main/java/com/google/firebase/gradle/MultiProjectReleasePlugin.java

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public void apply(Project project) {
8080
task.getDestinationDirectory().set(project.getRootDir());
8181
});
8282

83+
project.getTasks().create("generateReleaseConfig", ReleaseGenerator.class);
84+
8385
project
8486
.getGradle()
8587
.projectsEvaluated(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright 2021 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+
package com.google.firebase.gradle
15+
16+
import java.io.File
17+
import org.eclipse.jgit.api.Git
18+
import org.eclipse.jgit.api.ListBranchCommand
19+
import org.eclipse.jgit.api.errors.GitAPIException
20+
import org.eclipse.jgit.lib.Constants
21+
import org.eclipse.jgit.lib.ObjectId
22+
import org.gradle.api.DefaultTask
23+
import org.gradle.api.tasks.TaskAction
24+
25+
data class FirebaseLibrary(val moduleNames: List<String>, val directories: List<String>)
26+
27+
open class ReleaseGenerator : DefaultTask() {
28+
@TaskAction
29+
@Throws(Exception::class)
30+
fun generateReleaseConfig() {
31+
val currentRelease = project.property("currentRelease").toString()
32+
val pastRelease = project.property("pastRelease").toString()
33+
val printReleaseConfig = project.property("printOutput").toString().toBoolean()
34+
val rootDir = project.rootDir
35+
val availableModules = parseSubProjects(rootDir)
36+
val firebaseLibraries = extractLibraries(availableModules, rootDir)
37+
38+
val repo = Git.open(rootDir)
39+
val headRef = repo.repository.resolve(Constants.HEAD)
40+
val branchRef = getObjectRefForBranchName(repo, pastRelease)
41+
42+
val changedLibraries = getChangedLibraries(repo, branchRef, headRef, firebaseLibraries)
43+
writeReleaseConfig(rootDir, changedLibraries, currentRelease)
44+
if (printReleaseConfig) {
45+
println(changedLibraries.joinToString(",", "LIBRARIES TO RELEASE: "))
46+
}
47+
}
48+
49+
private fun extractLibraries(
50+
availableModules: Set<String>,
51+
rootDir: File
52+
): List<FirebaseLibrary> {
53+
val nonKtxModules = availableModules.filter { !it.endsWith("ktx") }.toSet()
54+
return nonKtxModules
55+
.map { moduleName ->
56+
val ktxModuleName = "$moduleName:ktx"
57+
58+
val moduleNames = listOf(moduleName, ktxModuleName).filter { availableModules.contains(it) }
59+
val directories = moduleNames.map { it.replace(":", "/") }
60+
61+
FirebaseLibrary(moduleNames, directories)
62+
}
63+
.filter { firebaseLibrary ->
64+
firebaseLibrary.directories.first().let { File(rootDir, "$it/gradle.properties").exists() }
65+
}
66+
}
67+
68+
private fun parseSubProjects(rootDir: File) =
69+
File(rootDir, "subprojects.cfg")
70+
.readLines()
71+
.filterNot { it.startsWith("#") || it.isEmpty() }
72+
.toSet()
73+
74+
@Throws(GitAPIException::class)
75+
private fun getObjectRefForBranchName(repo: Git, branchName: String) =
76+
repo
77+
.branchList()
78+
.setListMode(ListBranchCommand.ListMode.REMOTE)
79+
.call()
80+
.firstOrNull { it.name == "refs/remotes/origin/$branchName" }
81+
?.objectId
82+
?: throw RuntimeException("Could not find branch named $branchName")
83+
84+
private fun getChangedLibraries(
85+
repo: Git,
86+
previousReleaseRef: ObjectId,
87+
currentReleaseRef: ObjectId,
88+
libraries: List<FirebaseLibrary>
89+
) =
90+
libraries
91+
.filter { library ->
92+
library.directories.any { checkDirChanges(repo, previousReleaseRef, currentReleaseRef, it) }
93+
}
94+
.flatMap { it.moduleNames }
95+
96+
private fun checkDirChanges(
97+
repo: Git,
98+
previousReleaseRef: ObjectId,
99+
currentReleaseRef: ObjectId,
100+
directory: String
101+
) =
102+
repo
103+
.log()
104+
.addPath("$directory/")
105+
.addRange(previousReleaseRef, currentReleaseRef)
106+
.setMaxCount(1)
107+
.call()
108+
.iterator()
109+
.hasNext()
110+
111+
private fun writeReleaseConfig(configPath: File, libraries: List<String>, releaseName: String) {
112+
File(configPath, "release.cfg")
113+
.writeText(
114+
"""
115+
[release]
116+
name = $releaseName
117+
mode = RELEASE
118+
119+
[modules]
120+
${libraries.joinToString("\n".padEnd(21, ' '))}
121+
"""
122+
.trimIndent()
123+
)
124+
}
125+
}

0 commit comments

Comments
 (0)