diff --git a/README.md b/README.md index fa97348..002c242 100644 --- a/README.md +++ b/README.md @@ -117,11 +117,12 @@ Basically if the upload or progression triggers a release in octopus deploy, the Configuration is done on the tasks themself: -Property | Description | default value +Property | Description | default value ---|---|--- -waitForReleaseDeployments | If the task should wait | false -waitTimeoutSeconds | max time to poll the Ocotopus API | 600 -delayBetweenChecksSeconds | how long to delay between polls | 5 +waitForReleaseDeployments | If the task should wait | false +waitTimeoutSeconds | max time to poll the Ocotopus API | 600 +delayBetweenChecksSeconds | how long to delay between polls | 5 +initialWaitSeconds | initial delay before waitForReleaseDeployments logic starts | - Example: ``` diff --git a/src/integrationTest/kotlin/com/liftric/octopusdeploy/task/UploadPackageTaskWithInitialWaitIntegrationTest.kt b/src/integrationTest/kotlin/com/liftric/octopusdeploy/task/UploadPackageTaskWithInitialWaitIntegrationTest.kt new file mode 100644 index 0000000..f3d501e --- /dev/null +++ b/src/integrationTest/kotlin/com/liftric/octopusdeploy/task/UploadPackageTaskWithInitialWaitIntegrationTest.kt @@ -0,0 +1,101 @@ +package com.liftric.octopusdeploy.task + +import com.liftric.octopusdeploy.apiKey +import com.liftric.octopusdeploy.getPackageResponse +import com.liftric.octopusdeploy.serverUrl +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertNotNull +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder +import org.slf4j.LoggerFactory +import kotlin.random.Random + +class UploadPackageTaskWithInitialWaitIntegrationTest { + private val log = LoggerFactory.getLogger(UploadPackageTaskWithInitialWaitIntegrationTest::class.java) + @get:Rule + val testProjectDir = TemporaryFolder() + + @Test + fun testExecute() { + val major = Random.Default.nextInt(0, 100) + val minor = Random.Default.nextInt(0, 100) + val micro = Random.Default.nextInt(0, 100) + log.info(testProjectDir.root.absolutePath) + setupBuild(major, minor, micro) + + val result = GradleRunner.create() + .forwardOutput() + .withProjectDir(testProjectDir.root) + .withArguments("build", "uploadPackage") + .withPluginClasspath() + .build() + log.info(result.output) + assertEquals(TaskOutcome.SUCCESS, result.task(":uploadPackage")?.outcome) + + val packageItem = getPackageResponse() + .items + ?.firstOrNull { + it.version == "$major.$minor.$micro" + } + assertNotNull(packageItem) + assertEquals(".jar", packageItem?.fileExtension) + + val secondResult = GradleRunner.create() + .forwardOutput() + .withProjectDir(testProjectDir.root) + .withArguments("build", "uploadPackage") + .withPluginClasspath() + .buildAndFail() + log.info(secondResult.output) + // override is not set + assertEquals(TaskOutcome.FAILED, secondResult.task(":uploadPackage")?.outcome) + } + + fun setupBuild(major: Int, minor: Int, micro: Int) { + testProjectDir.newFile("build.gradle.kts").apply { + writeText( + """ +import com.liftric.octopusdeploy.task.UploadPackageTask +plugins { + java + id("com.liftric.octopus-deploy-plugin") +} +group = "com.liftric.test" +version = "$major.$minor.$micro" + +tasks { + withType { + archiveFileName.set( + "${'$'}{archiveBaseName.get() + .removeSuffix("-")}.${'$'}{archiveVersion.get()}.${'$'}{archiveExtension.get()}" + ) + } + withType{ + initialWaitSeconds.set(2L) + waitForReleaseDeployments.set(true) + waitTimeoutSeconds.set(1L) + delayBetweenChecksSeconds.set(2L) + httpLogLevel.set(okhttp3.logging.HttpLoggingInterceptor.Level.HEADERS) + } +} +octopus { + serverUrl.set("$serverUrl") + apiKey.set("$apiKey") + + generateChangelogSinceLastTag = true + + val jar by tasks.existing(Jar::class) + packageName.set(jar.get().archiveBaseName.get().removeSuffix("-")) + version.set(jar.get().archiveVersion.get()) + pushPackage.set(jar.get().archiveFile) + +} +""" + ) + } + testProjectDir.root.setupGitRepoCopy() + } +} diff --git a/src/main/kotlin/com/liftric/octopusdeploy/OctopusDeployPlugin.kt b/src/main/kotlin/com/liftric/octopusdeploy/OctopusDeployPlugin.kt index a8178f8..f35d2b0 100644 --- a/src/main/kotlin/com/liftric/octopusdeploy/OctopusDeployPlugin.kt +++ b/src/main/kotlin/com/liftric/octopusdeploy/OctopusDeployPlugin.kt @@ -89,8 +89,8 @@ class OctopusDeployPlugin : Plugin { } project.tasks.withType(PromoteReleaseTask::class.java) { project.afterEvaluate { - apiKey.set(extension.apiKey ?: error("$extensionName: didn't specify apiKey!")) - octopusUrl.set(extension.serverUrl ?: error("$extensionName: didn't specify serverUrl!")) + apiKey.set(extension.apiKey) + octopusUrl.set(extension.serverUrl) httpLogLevel.set(extension.httpLogLevel) } } diff --git a/src/main/kotlin/com/liftric/octopusdeploy/task/PromoteReleaseTask.kt b/src/main/kotlin/com/liftric/octopusdeploy/task/PromoteReleaseTask.kt index 3fb66ae..34a4cc6 100644 --- a/src/main/kotlin/com/liftric/octopusdeploy/task/PromoteReleaseTask.kt +++ b/src/main/kotlin/com/liftric/octopusdeploy/task/PromoteReleaseTask.kt @@ -48,6 +48,14 @@ open class PromoteReleaseTask : DefaultTask() { @Optional val waitTimeoutSeconds: Property = project.objects.property() + /** + * Octopus server might need longer for the deployment to trigger, so we can define an + * additional, initial, minimum wait before the actual release check logic even happens + */ + @Input + @Optional + val initialWaitSeconds: Property = project.objects.property() + @Input @Optional val delayBetweenChecksSeconds: Property = project.objects.property() @@ -98,7 +106,8 @@ open class PromoteReleaseTask : DefaultTask() { fromEnv = fromValue, toEnv = toValue ) - } + }, + initialWaitSeconds = initialWaitSeconds.orNull ) } } diff --git a/src/main/kotlin/com/liftric/octopusdeploy/task/UploadPackageTask.kt b/src/main/kotlin/com/liftric/octopusdeploy/task/UploadPackageTask.kt index eca28cc..986333b 100644 --- a/src/main/kotlin/com/liftric/octopusdeploy/task/UploadPackageTask.kt +++ b/src/main/kotlin/com/liftric/octopusdeploy/task/UploadPackageTask.kt @@ -48,6 +48,14 @@ open class UploadPackageTask : DefaultTask() { @Optional val waitTimeoutSeconds: Property = project.objects.property() + /** + * Octopus server might need longer for the deployment to trigger, so we can define an + * additional, initial, minimum wait before the actual release check logic even happens + */ + @Input + @Optional + val initialWaitSeconds: Property = project.objects.property() + @Input @Optional val delayBetweenChecksSeconds: Property = project.objects.property() @@ -92,7 +100,8 @@ open class UploadPackageTask : DefaultTask() { apiLogLevel = httpLogLevel.getOrElse(HttpLoggingInterceptor.Level.NONE), checkLogic = { determinAnyOngoingTask(packageNameValue = packageNameValue, versionValue = versionValue) - } + }, + initialWaitSeconds = initialWaitSeconds.orNull ) } } diff --git a/src/main/kotlin/com/liftric/octopusdeploy/task/shared.kt b/src/main/kotlin/com/liftric/octopusdeploy/task/shared.kt index 23b00aa..a31f0d9 100644 --- a/src/main/kotlin/com/liftric/octopusdeploy/task/shared.kt +++ b/src/main/kotlin/com/liftric/octopusdeploy/task/shared.kt @@ -5,12 +5,15 @@ import com.liftric.octopusdeploy.rest.* import kotlinx.coroutines.* import okhttp3.logging.HttpLoggingInterceptor import java.time.Duration +import kotlin.time.seconds /** * repeatedly poll the octopus api for all releases for the given [packageNameValue] [versionValue] combination. * * @param checkLogic Remoting used to determin if any task is ongoing. * Difference between upload and progress makes this necessary. + * @param initialWaitSeconds Octopus server might need longer for the deployment to trigger, so we can define an + * additional, initial, minimum wait before the actual release check logic even happens */ internal fun awaitReleaseLogic( octopusUrlValue: String, @@ -18,7 +21,8 @@ internal fun awaitReleaseLogic( waitTimeoutSeconds: Long, delayBetweenChecksSeconds: Long, apiLogLevel: HttpLoggingInterceptor.Level, - checkLogic: OctoApiClient.() -> Boolean + checkLogic: OctoApiClient.() -> Boolean, + initialWaitSeconds: Long? ) { println("checking is upload triggered any release with auto deployment (${waitTimeoutSeconds}s max)") @@ -33,6 +37,11 @@ internal fun awaitReleaseLogic( octoApiClient.shutdown() } runBlocking(handler) { + initialWaitSeconds?.let { + println("initial check delay: ${it}s") + delay(it * 1000) + println("initial check delay done") + } withTimeout(Duration.ofSeconds(waitTimeoutSeconds).toMillis()) { var anyOngoingTask = octoApiClient.checkLogic() while (anyOngoingTask) {