Skip to content

Commit 4595aa2

Browse files
committed
Output artifact list during local publishing.
This effort replaces #494.
1 parent 63232fc commit 4595aa2

File tree

4 files changed

+87
-9
lines changed

4 files changed

+87
-9
lines changed

buildSrc/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ dependencies {
3737
implementation 'org.jsoup:jsoup:1.11.2'
3838
implementation 'digital.wup:android-maven-publish:3.6.2'
3939
implementation 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20'
40+
implementation 'org.json:json:20180813'
4041

4142
implementation 'io.opencensus:opencensus-api:0.18.0'
4243
implementation 'io.opencensus:opencensus-exporter-stats-stackdriver:0.18.0'
4344
runtime 'io.opencensus:opencensus-impl:0.18.0'
4445

4546
implementation 'com.android.tools.build:gradle:3.2.1'
4647
testImplementation 'junit:junit:4.12'
47-
testImplementation 'org.json:json:20180813'
4848
testImplementation('org.spockframework:spock-core:1.1-groovy-2.4') {
4949
exclude group: 'org.codehaus.groovy'
5050
}

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/ci/AffectedProjectFinder.groovy

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class AffectedProjectFinder {
2525
Set<String> changedPaths;
2626

2727
@Builder
28+
AffectedProjectFinder(Project project, List<Pattern> ignorePaths) {
29+
this(project, changedPaths(project.rootDir), ignorePaths)
30+
}
31+
2832
AffectedProjectFinder(Project project,
2933
Set<String> changedPaths,
3034
List<Pattern> ignorePaths) {
@@ -49,6 +53,13 @@ class AffectedProjectFinder {
4953
return project.subprojects
5054
}
5155

56+
private static Set<String> changedPaths(File workDir) {
57+
return 'git diff --name-only --submodule=diff HEAD@{0} HEAD@{1}'
58+
.execute([], workDir)
59+
.text
60+
.readLines()
61+
}
62+
5263
/**
5364
* Performs a post-order project tree traversal and returns a set of projects that own the
5465
* 'changedPaths'.

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/ci/ContinuousIntegrationPlugin.groovy

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ class ContinuousIntegrationPlugin implements Plugin<Project> {
9797

9898
def affectedProjects = AffectedProjectFinder.builder()
9999
.project(project)
100-
.changedPaths(changedPaths(project.rootDir))
101100
.ignorePaths(extension.ignorePaths)
102101
.build()
103102
.find()
@@ -143,13 +142,6 @@ class ContinuousIntegrationPlugin implements Plugin<Project> {
143142
}
144143
}
145144

146-
private static Set<String> changedPaths(File workDir) {
147-
return 'git diff --name-only --submodule=diff HEAD@{0} HEAD@{1}'
148-
.execute([], workDir)
149-
.text
150-
.readLines()
151-
}
152-
153145
private static final ANDROID_PLUGINS = ["com.android.application", "com.android.library",
154146
"com.android.test"]
155147

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/publish/PublishingPlugin.groovy

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414

1515
package com.google.firebase.gradle.plugins.publish
1616

17+
import com.google.firebase.gradle.plugins.ci.AffectedProjectFinder
1718
import com.google.firebase.gradle.plugins.FirebaseLibraryExtension
1819
import digital.wup.android_maven_publish.AndroidMavenPublishPlugin
1920
import org.gradle.api.Plugin
2021
import org.gradle.api.Project
22+
import org.gradle.api.artifacts.ProjectDependency
2123
import org.gradle.api.publish.maven.MavenPublication
2224
import org.gradle.api.tasks.bundling.Jar
2325
import org.gradle.api.tasks.bundling.Zip
26+
import org.json.JSONArray
27+
import org.json.JSONObject
2428

2529
/**
2630
* Enables releasing of the SDKs.
@@ -64,6 +68,16 @@ import org.gradle.api.tasks.bundling.Zip
6468
* -PpublishMode=(RELEASE|SNAPSHOT) \
6569
* publishProjectsToMavenLocal
6670
* </pre>
71+
*
72+
* <p><strong>Build recently changed snapshots</strong>
73+
*
74+
* <pre>
75+
* ./gradlew publishChangedToBuildDir # publishes changed projects to build/m2repository
76+
* </pre>
77+
*
78+
* This option builds projects that have been changed by the latest git commit and all of their
79+
* dependencies. They are published to the build directory. This workflow is intended for
80+
* compatibility testing, where the changed projects need to be layered over a previous release.
6781
*/
6882
class PublishingPlugin implements Plugin<Project> {
6983
@Override
@@ -83,9 +97,16 @@ class PublishingPlugin implements Plugin<Project> {
8397

8498
def publishAllToLocal = project.task('publishAllToLocal')
8599
def publishAllToBuildDir = project.task('publishAllToBuildDir')
100+
def publishChangedToBuildDir = project.task('publishChangedToBuildDir')
86101
def firebasePublish = project.task('firebasePublish')
87102

88103
project.getGradle().projectsEvaluated {
104+
// These three variables are used for generating the JSON file that lists the artifacts
105+
// affected by the latest commit. This is generally useful only on CI builds.
106+
def changedProjects = getChangedProjects(project)
107+
def changedArtifacts = new HashSet<String>()
108+
def allArtifacts = new HashSet<String>()
109+
89110
project.subprojects { Project sub ->
90111
if (!sub.plugins.hasPlugin('firebase-library')) {
91112
return
@@ -121,11 +142,40 @@ class PublishingPlugin implements Plugin<Project> {
121142
publisher.decorate(sub, it)
122143
}
123144
}
145+
124146
publishAllToLocal.dependsOn "$sub.path:publishMavenAarPublicationToMavenLocal"
125147
publishAllToBuildDir.dependsOn "$sub.path:publishMavenAarPublicationToBuildDirRepository"
126148

149+
// Update the changed and all sets each time an artifact is published. This is
150+
// used to build the JSON file of affected targets.
151+
sub.tasks.getByName("publishMavenAarPublicationToBuildDirRepository").doLast {
152+
def artifact = "$sub.group:$sub.name:$sub.version-SNAPSHOT"
153+
allArtifacts.add(artifact)
154+
155+
if (changedProjects.contains(sub)) {
156+
changedArtifacts.add(artifact)
157+
}
158+
}
127159
}
160+
128161
}
162+
163+
// Build the JSON file of affected targets after all artifacts have been published.
164+
publishAllToBuildDir.doLast {
165+
def changed = new JSONArray()
166+
changedArtifacts.each { changed.put(it) }
167+
168+
def all = new JSONArray()
169+
allArtifacts.each { all.put(it) }
170+
171+
def json = new JSONObject()
172+
json.put("all", all)
173+
json.put("changed", changed)
174+
175+
def path = project.buildDir.toPath()
176+
path.resolve("m2repository/changed-artifacts.json").write(json.toString())
177+
}
178+
129179
project.task('publishProjectsToMavenLocal') {
130180
projectsToPublish.each { projectToPublish ->
131181
dependsOn getPublishTask(projectToPublish, 'MavenLocal')
@@ -155,6 +205,31 @@ class PublishingPlugin implements Plugin<Project> {
155205
}
156206
}
157207

208+
private static Set<Project> getChangedProjects(Project p) {
209+
Set<Project> roots = new AffectedProjectFinder(p, []).find()
210+
HashSet<Project> changed = new HashSet<>()
211+
212+
getChangedProjectsLoop(roots, changed)
213+
return changed
214+
}
215+
216+
private static void getChangedProjectsLoop(Collection<Project> projects, Set<Project> changed) {
217+
for (Project p : projects) {
218+
// Skip processing and recursion if this project has already been added to the set.
219+
if (!changed.add(p)) {
220+
continue;
221+
}
222+
223+
// Find all (head) dependencies to other projects in this respository.
224+
def all = p.configurations.releaseRuntimeClasspath.allDependencies
225+
def affected =
226+
all.findAll { it instanceof ProjectDependency }.collect { it.getDependencyProject() }
227+
228+
// Recurse with the new dependencies.
229+
getChangedProjectsLoop(affected, changed)
230+
}
231+
}
232+
158233
private static String getPublishTask(Project p, String repoName) {
159234
return "${p.path}:publishMavenAarPublicationTo$repoName"
160235
}

0 commit comments

Comments
 (0)