Skip to content

Commit 0ef320f

Browse files
committed
Experimental artifact promotion task
As part of my efforts to consolidate SharedActions, I've created this new experimental task to handle artifact promotion. It requies the same environment variables as before, but it is not automated. To use this, simply use `gradleutils.pom.promote()` inside of your maven publication. ```gradle publications.register('pluginMaven', MavenPublication) { gradleutils.pom.promote it changelog.publish it // ... ```
1 parent 21404ca commit 0ef320f

File tree

4 files changed

+141
-2
lines changed

4 files changed

+141
-2
lines changed

src/main/groovy/net/minecraftforge/gradleutils/GradleUtils.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class GradleUtils {
4040
project.afterEvaluate(action)
4141
}
4242

43+
static Provider<String> getEnvVar(String name, ProviderFactory providers) {
44+
providers.of(GradleUtilsSources.EnvVar) { it.parameters.variableName.set name }
45+
}
46+
4347
static Provider<Boolean> hasEnvVar(String name, ProviderFactory providers) {
4448
providers.of(GradleUtilsSources.HasEnvVar) { it.parameters.variableName.set name }
4549
}

src/main/groovy/net/minecraftforge/gradleutils/GradleUtilsSources.groovy

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,28 @@ import org.gradle.api.Describable
66
import org.gradle.api.provider.Property
77
import org.gradle.api.provider.ValueSource
88
import org.gradle.api.provider.ValueSourceParameters
9+
import org.jetbrains.annotations.Nullable
910

1011
@CompileStatic
1112
@PackageScope
1213
final class GradleUtilsSources {
14+
@CompileStatic
15+
static abstract class EnvVar implements ValueSource<@Nullable String, Parameters>, Describable {
16+
interface Parameters extends ValueSourceParameters {
17+
Property<String> getVariableName();
18+
}
19+
20+
@Override
21+
@Nullable String obtain() {
22+
System.getenv(this.parameters.variableName.get())
23+
}
24+
25+
@Override
26+
String getDisplayName() {
27+
"Environment Variable value: ${this.parameters.variableName.get()}"
28+
}
29+
}
30+
1331
@CompileStatic
1432
static abstract class HasEnvVar implements ValueSource<Boolean, Parameters>, Describable {
1533
interface Parameters extends ValueSourceParameters {

src/main/groovy/net/minecraftforge/gradleutils/PomUtils.groovy

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,27 @@ import groovy.transform.CompileStatic
88
import groovy.transform.PackageScope
99
import net.minecraftforge.gradleutils.gitversion.GitVersionExtension
1010
import org.gradle.api.Action
11+
import org.gradle.api.Project
1112
import org.gradle.api.logging.Logger
1213
import org.gradle.api.provider.ProviderFactory
1314
import org.gradle.api.publish.maven.MavenPom
1415
import org.gradle.api.publish.maven.MavenPomDeveloper
1516
import org.gradle.api.publish.maven.MavenPomLicense
17+
import org.gradle.api.publish.maven.MavenPublication
1618

1719
/** Utilities for making configuring a {@link MavenPom} more ergonomic. */
1820
@CompileStatic
1921
@SuppressWarnings('unused')
2022
final class PomUtils {
23+
private final Project project
2124
private final Logger logger
2225
private final ProviderFactory providers
2326

2427
private final GitVersionExtension gitversion
2528

26-
@PackageScope PomUtils(Logger logger, ProviderFactory providers, GitVersionExtension gitversion) {
27-
this.logger = logger
29+
@PackageScope PomUtils(Project project, ProviderFactory providers, GitVersionExtension gitversion) {
30+
this.project = project
31+
this.logger = project.logger
2832
this.providers = providers
2933
this.gitversion = gitversion
3034
}
@@ -83,6 +87,10 @@ final class PomUtils {
8387
}
8488
}
8589

90+
void promote(MavenPublication publication) {
91+
PromoteArtifact.register(this.project, publication)
92+
}
93+
8694
/**
8795
* Reduces boilerplate when setting up GitHub details in a {@link MavenPom}.
8896
*
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package net.minecraftforge.gradleutils
2+
3+
import groovy.json.JsonBuilder
4+
import groovy.transform.CompileStatic
5+
import org.gradle.api.DefaultTask
6+
import org.gradle.api.Project
7+
import org.gradle.api.provider.Property
8+
import org.gradle.api.provider.ProviderFactory
9+
import org.gradle.api.publish.maven.MavenPublication
10+
import org.gradle.api.tasks.Input
11+
import org.gradle.api.tasks.Optional
12+
import org.gradle.api.tasks.TaskAction
13+
import org.gradle.api.tasks.TaskProvider
14+
import org.jetbrains.annotations.ApiStatus
15+
16+
import javax.inject.Inject
17+
import javax.net.ssl.SSLContext
18+
import java.net.http.HttpClient
19+
import java.net.http.HttpRequest
20+
import java.net.http.HttpResponse
21+
import java.time.Duration
22+
23+
@CompileStatic
24+
@ApiStatus.Experimental
25+
abstract class PromoteArtifact extends DefaultTask {
26+
static TaskProvider<PromoteArtifact> register(Project project, MavenPublication publication) {
27+
project.tasks.register('promoteArtifact', PromoteArtifact) { task ->
28+
final webhookURL = GradleUtils.getEnvVar('PROMOTE_ARTIFACT_WEBHOOK', project.providers)
29+
final username = GradleUtils.getEnvVar('PROMOTE_ARTIFACT_WEBHOOK', project.providers)
30+
final password = GradleUtils.getEnvVar('PROMOTE_ARTIFACT_WEBHOOK', project.providers)
31+
task.onlyIf { webhookURL.present && username.present && password.present }
32+
33+
task.artifactGroup.set publication.groupId
34+
task.artifactName.set publication.artifactId
35+
task.artifactVersion.set publication.version
36+
task.webhookURL.set webhookURL
37+
task.username.set username
38+
task.password.set password
39+
}
40+
}
41+
42+
@Inject
43+
abstract ProviderFactory getProviders()
44+
45+
PromoteArtifact() {
46+
this.artifactGroup.convention 'net.minecraftforge'
47+
this.artifactName.convention this.providers.provider { this.project.name }
48+
this.artifactVersion.convention this.providers.provider { String.valueOf this.project.version }
49+
this.promotionType.convention Type.LATEST
50+
}
51+
52+
@Input
53+
abstract Property<String> getArtifactGroup()
54+
55+
@Input
56+
abstract Property<String> getArtifactName()
57+
58+
@Input
59+
abstract Property<String> getArtifactVersion()
60+
61+
@Input
62+
@Optional
63+
abstract Property<Type> getPromotionType()
64+
65+
@Input
66+
abstract Property<String> getWebhookURL()
67+
68+
@Input
69+
abstract Property<String> getUsername()
70+
71+
@Input
72+
abstract Property<String> getPassword()
73+
74+
static enum Type {
75+
LATEST, RECOMMENDED;
76+
77+
@Override
78+
String toString() {
79+
return super.toString().toLowerCase()
80+
}
81+
}
82+
83+
@TaskAction
84+
void exec() {
85+
var client = HttpClient
86+
.newBuilder()
87+
.sslParameters(SSLContext.default.defaultSSLParameters.tap { protocols = ["TLSv1.3"] })
88+
.build()
89+
90+
var request = HttpRequest
91+
.newBuilder()
92+
.uri(URI.create(this.webhookURL.get()))
93+
.setHeader("Content-Type", 'application/json')
94+
.setHeader("Authorization", "Basic ${Base64.getEncoder().encodeToString("${this.username.get()}:${this.password.get()}".getBytes())}")
95+
.timeout(Duration.ofSeconds(10))
96+
.POST(HttpRequest.BodyPublishers.ofString(new JsonBuilder(
97+
group: this.artifactGroup.get(),
98+
artifact: this.artifactName.get(),
99+
version: this.artifactVersion.get(),
100+
type: this.promotionType.getOrElse(Type.LATEST).toString()
101+
).toPrettyString()))
102+
.build()
103+
104+
var response = client.send(request, HttpResponse.BodyHandlers.ofString())
105+
if (response.statusCode() != 200) {
106+
throw new RuntimeException("Failed to promote artifact: ${response.statusCode()} ${response.body()}")
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)