Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: save artifact size metrics task #40

Merged
merged 4 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-plugins/build-support/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ dependencies {
gradlePlugin {
plugins {
create("artifact-size-metrics") {
id = "artifact-size-metrics"
id = "aws.sdk.kotlin.gradle.artifactsizemetrics"
implementationClass = "aws.sdk.kotlin.gradle.plugins.artifactsizemetrics.ArtifactSizeMetricsPlugin"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
package aws.sdk.kotlin.gradle.plugins.artifactsizemetrics

import org.gradle.api.GradleException
import aws.sdk.kotlin.gradle.util.verifyRootProject
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.TaskProvider
Expand All @@ -22,9 +22,7 @@ internal const val S3_ARTIFACT_SIZE_METRICS_BUCKET = "artifact-size-metrics" //
*/
class ArtifactSizeMetricsPlugin : Plugin<Project> {
override fun apply(target: Project) {
if (target != target.rootProject) {
throw GradleException("${this::class.java} can only be applied to the root project")
}
target.verifyRootProject { "${this::class.java} can only be applied to the root project" }

target.extensions.create("artifactSizeMetrics", ArtifactSizeMetricsPluginConfig::class.java)

Expand All @@ -36,6 +34,7 @@ class ArtifactSizeMetricsPlugin : Plugin<Project> {
target.tasks.register<CollectDelegatedArtifactSizeMetrics>("collectDelegatedArtifactSizeMetrics") { group = TASK_GROUP }
target.tasks.register<AnalyzeArtifactSizeMetrics>("analyzeArtifactSizeMetrics") { group = TASK_GROUP }
target.tasks.register<PutArtifactSizeMetricsInCloudWatch>("putArtifactSizeMetricsInCloudWatch") { group = TASK_GROUP }
target.tasks.register<SaveArtifactSizeMetrics>("saveArtifactSizeMetrics") { group = TASK_GROUP }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
package aws.sdk.kotlin.gradle.plugins.artifactsizemetrics

import aws.sdk.kotlin.gradle.util.AwsSdkGradleException
import aws.sdk.kotlin.gradle.util.stringPropertyNotNull
import aws.sdk.kotlin.services.cloudwatch.CloudWatchClient
import aws.sdk.kotlin.services.cloudwatch.model.Dimension
import aws.sdk.kotlin.services.cloudwatch.model.MetricDatum
Expand Down Expand Up @@ -36,9 +36,7 @@ internal abstract class PutArtifactSizeMetricsInCloudWatch : DefaultTask() {
fun put() {
val currentTime = Instant.now()
val pluginConfig = project.rootProject.extensions.getByType(ArtifactSizeMetricsPluginConfig::class.java)
val releaseTag = project.findProperty("release")?.toString()?.also {
check(it.isNotEmpty()) { "The release property is set to empty \"-Prelease=\" (no value set). Please specify a value." }
} ?: throw AwsSdkGradleException("The release property is not set. Please set a value: \"-Prelease=YOUR_RELEASE_VALUE\"")
val releaseTag = project.stringPropertyNotNull("release")

val metrics = metricsFile
.get()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package aws.sdk.kotlin.gradle.plugins.artifactsizemetrics

import aws.sdk.kotlin.gradle.util.stringPropertyNotNull
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.putObject
import aws.smithy.kotlin.runtime.content.ByteStream
import kotlinx.coroutines.runBlocking
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.TaskAction

/**
* Puts artifact size metrics in S3 to save them.
* We put them in CloudWatch also (as metrics) but CloudWatch only keeps metrics temporarily.
*/
internal abstract class SaveArtifactSizeMetrics : DefaultTask() {
/**
* File containing the project's artifact size metrics.
*/
@get:InputFile
abstract val metricsFile: RegularFileProperty

init {
metricsFile.convention(project.layout.buildDirectory.file(OUTPUT_PATH + "artifact-size-metrics.csv"))
}

private val pluginConfig = project.rootProject.extensions.getByType(ArtifactSizeMetricsPluginConfig::class.java)

@TaskAction
fun save() {
val releaseTag = project.stringPropertyNotNull("release")
val artifactSizeMetrics = ByteStream.fromString(metricsFile.get().asFile.readText())

runBlocking {
S3Client.fromEnvironment().use { s3 ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized we don't specify the client region anywhere, I hope that will be consistently set by the environment (i.e env var)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s3.putObject {
bucket = S3_ARTIFACT_SIZE_METRICS_BUCKET
key = "${pluginConfig.projectRepositoryName}-latest-release.csv"
body = artifactSizeMetrics
}

s3.putObject {
bucket = S3_ARTIFACT_SIZE_METRICS_BUCKET
key = "${pluginConfig.projectRepositoryName}-$releaseTag-release.csv"
body = artifactSizeMetrics
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,14 @@ public inline fun Project.verifyRootProject(lazyMessage: () -> Any) {
}
}

/**
* Will access a project property as a String, only if it is not null or not empty.
* @throws AwsSdkGradleException If the property is empty or null
* @return The property as a String
*/
fun Project.stringPropertyNotNull(property: String): String =
findProperty(property)?.toString()?.also {
check(it.isNotEmpty()) { "The $property property is set to empty \"-P$property=\" (no value set). Please specify a value." }
} ?: throw AwsSdkGradleException("The $property property is not set. Please set a value: \"-P$property=YOUR_VALUE\"")

class AwsSdkGradleException(message: String) : GradleException(message)
Loading