From daaf37db9a35ebf572160fff31c683ca389c9da4 Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Wed, 14 Sep 2022 12:40:52 +0300 Subject: [PATCH] Use @EnabledIfOidcExists instead of several Gradle test tasks -PskipOidc command-line option could be used to skip OIDC tests. skipOidc=true could be added to gradle.properties or $HOME/gradle.properties Signed-off-by: Vladimir Sitnikov --- .github/workflows/ci-oidc.yaml | 36 ------------- .../main/kotlin/build-logic.java.gradle.kts | 1 + .../main/kotlin/build-logic.kotlin.gradle.kts | 1 + .../kotlin/build-logic.testing.gradle.kts | 6 +++ .../dev/sigstore/gradle/SigstoreSignTest.kt | 4 +- .../gradle/SigstorePublishSignTest.kt | 5 +- sigstore-java/build.gradle.kts | 17 +------ .../test/java/dev/sigstore/KeylessTest.java | 11 ++-- .../client/GithubActionsOidcClientTest.java | 5 +- .../testkit/DisableIfCiWithoutOidc.kt | 43 ---------------- .../testkit/EnableIfOidcExistsCondition.kt | 50 +++++++++++++++++++ .../annotations/EnabledIfOidcExists.kt | 32 ++++++++++++ .../testkit/annotations/OidcProviderType.kt | 26 ++++------ 13 files changed, 115 insertions(+), 122 deletions(-) delete mode 100644 .github/workflows/ci-oidc.yaml create mode 100644 build-logic/jvm/src/main/kotlin/build-logic.testing.gradle.kts delete mode 100644 sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/DisableIfCiWithoutOidc.kt create mode 100644 sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/EnableIfOidcExistsCondition.kt create mode 100644 sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/EnabledIfOidcExists.kt rename sigstore-java/src/test/java/dev/sigstore/testing/annotations/RequiresGithubOidc.java => sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/OidcProviderType.kt (51%) diff --git a/.github/workflows/ci-oidc.yaml b/.github/workflows/ci-oidc.yaml deleted file mode 100644 index 58e2f8ad2..000000000 --- a/.github/workflows/ci-oidc.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow will build a Java project with Gradle and -# cache/restore any dependencies to improve the workflow execution time -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle - -name: Test OIDC - -on: - push: - branches: '*' - workflow_call: # allow this workflow to be called by other workflows - -jobs: - gha-oidc-tests: - strategy: - matrix: - java-version: [11, 17] - permissions: - id-token: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up JDK ${{ matrix.java-version }} - uses: actions/setup-java@v3 - with: - java-version: ${{ matrix.java-version }} - distribution: 'temurin' - - - name: Run Github Actions OIDC tests - uses: gradle/gradle-build-action@8d2472536ed5e12cd8403b043e871b649399a208 - with: - arguments: testGithubOidc diff --git a/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts index 0a88edbb9..d8c1a7c34 100644 --- a/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts +++ b/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts @@ -3,6 +3,7 @@ import buildlogic.filterEolSimple plugins { `java-base` id("com.github.vlsi.gradle-extensions") + id("build-logic.testing") } java { diff --git a/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts index 4a237457e..2b24e18ec 100644 --- a/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts +++ b/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts @@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java-library") id("build-logic.java") + id("build-logic.testing") id("com.github.vlsi.gradle-extensions") id("com.github.autostyle") kotlin("jvm") diff --git a/build-logic/jvm/src/main/kotlin/build-logic.testing.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.testing.gradle.kts new file mode 100644 index 000000000..c01129a1c --- /dev/null +++ b/build-logic/jvm/src/main/kotlin/build-logic.testing.gradle.kts @@ -0,0 +1,6 @@ +tasks.withType().configureEach { + if (project.hasProperty("skipOidc")) { + println("skipOidc: ${project.findProperty("skipOidc")}") + systemProperty("sigstore-java.test.skipOidc", project.findProperty("skipOidc")!!) + } +} diff --git a/sigstore-gradle/sigstore-gradle-sign-base-plugin/src/test/kotlin/dev/sigstore/gradle/SigstoreSignTest.kt b/sigstore-gradle/sigstore-gradle-sign-base-plugin/src/test/kotlin/dev/sigstore/gradle/SigstoreSignTest.kt index 17accd10d..942cad73e 100644 --- a/sigstore-gradle/sigstore-gradle-sign-base-plugin/src/test/kotlin/dev/sigstore/gradle/SigstoreSignTest.kt +++ b/sigstore-gradle/sigstore-gradle-sign-base-plugin/src/test/kotlin/dev/sigstore/gradle/SigstoreSignTest.kt @@ -17,12 +17,12 @@ package dev.sigstore.gradle import dev.sigstore.testkit.BaseGradleTest -import dev.sigstore.testkit.DisableIfCiWithoutOidc +import dev.sigstore.testkit.annotations.EnabledIfOidcExists import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -@DisableIfCiWithoutOidc +@EnabledIfOidcExists class SigstoreSignTest: BaseGradleTest() { @ParameterizedTest @MethodSource("gradleVersionAndSettings") diff --git a/sigstore-gradle/sigstore-gradle-sign-plugin/src/test/kotlin/dev/sigstore/gradle/SigstorePublishSignTest.kt b/sigstore-gradle/sigstore-gradle-sign-plugin/src/test/kotlin/dev/sigstore/gradle/SigstorePublishSignTest.kt index bf59b0884..2ce2a88f1 100644 --- a/sigstore-gradle/sigstore-gradle-sign-plugin/src/test/kotlin/dev/sigstore/gradle/SigstorePublishSignTest.kt +++ b/sigstore-gradle/sigstore-gradle-sign-plugin/src/test/kotlin/dev/sigstore/gradle/SigstorePublishSignTest.kt @@ -17,13 +17,12 @@ package dev.sigstore.gradle import dev.sigstore.testkit.BaseGradleTest -import dev.sigstore.testkit.DisableIfCiWithoutOidc -import org.assertj.core.api.AbstractCharSequenceAssert +import dev.sigstore.testkit.annotations.EnabledIfOidcExists import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -@DisableIfCiWithoutOidc +@EnabledIfOidcExists class SigstorePublishSignTest : BaseGradleTest() { @ParameterizedTest @MethodSource("gradleVersionAndSettings") diff --git a/sigstore-java/build.gradle.kts b/sigstore-java/build.gradle.kts index da9aaf5b2..cf4c92508 100644 --- a/sigstore-java/build.gradle.kts +++ b/sigstore-java/build.gradle.kts @@ -49,6 +49,8 @@ dependencies { testImplementation("net.sourceforge.htmlunit:htmlunit:2.64.0") testImplementation("org.eclipse.jetty:jetty-server:11.0.11") + testImplementation(project(":sigstore-testkit")) + implementation("javax.validation:validation-api:2.0.1.Final") } @@ -114,20 +116,5 @@ tasks.named("sourcesJar") { tasks.test { useJUnitPlatform { - includeTags("none()") - } -} - -// a special test grouping for tests that require a valid gha oidc token -val testGithubOidc by tasks.registering(Test::class) { - useJUnitPlatform { - includeTags("github_oidc") - } -} - -// manual test groups that are *not* run in CI, these should be run before -val testManual by tasks.registering(Test::class) { - useJUnitPlatform { - includeTags("manual") } } diff --git a/sigstore-java/src/test/java/dev/sigstore/KeylessTest.java b/sigstore-java/src/test/java/dev/sigstore/KeylessTest.java index 725215285..3c63395d9 100644 --- a/sigstore-java/src/test/java/dev/sigstore/KeylessTest.java +++ b/sigstore-java/src/test/java/dev/sigstore/KeylessTest.java @@ -20,6 +20,8 @@ import dev.sigstore.oidc.client.GithubActionsOidcClient; import dev.sigstore.rekor.client.RekorTypeException; import dev.sigstore.rekor.client.RekorTypes; +import dev.sigstore.testkit.annotations.EnabledIfOidcExists; +import dev.sigstore.testkit.annotations.OidcProviderType; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -29,7 +31,6 @@ import org.bouncycastle.util.encoders.Hex; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -51,7 +52,7 @@ public static void setupArtifact() throws IOException { } @Test - @Tag("manual") + @EnabledIfOidcExists(provider = OidcProviderType.MANUAL) public void sign_production() throws Exception { var signer = KeylessSigner.builder().sigstorePublicDefaults().build(); var result = signer.sign(testArtifact); @@ -66,7 +67,7 @@ public void sign_production() throws Exception { } @Test - @Tag("manual") + @EnabledIfOidcExists(provider = OidcProviderType.MANUAL) public void sign_staging() throws Exception { var signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); var result = signer.sign(testArtifact); @@ -80,7 +81,7 @@ public void sign_staging() throws Exception { } @Test - @Tag("github_oidc") + @EnabledIfOidcExists(provider = OidcProviderType.GITHUB) public void sign_productionWithGithubOidc() throws Exception { var signer = KeylessSigner.builder() @@ -98,7 +99,7 @@ public void sign_productionWithGithubOidc() throws Exception { } @Test - @Tag("github_oidc") + @EnabledIfOidcExists(provider = OidcProviderType.GITHUB) public void sign_stagingWithGithubOidc() throws Exception { var signer = KeylessSigner.builder() diff --git a/sigstore-java/src/test/java/dev/sigstore/oidc/client/GithubActionsOidcClientTest.java b/sigstore-java/src/test/java/dev/sigstore/oidc/client/GithubActionsOidcClientTest.java index 3a5514dc9..dfd9370b6 100644 --- a/sigstore-java/src/test/java/dev/sigstore/oidc/client/GithubActionsOidcClientTest.java +++ b/sigstore-java/src/test/java/dev/sigstore/oidc/client/GithubActionsOidcClientTest.java @@ -15,14 +15,15 @@ */ package dev.sigstore.oidc.client; -import dev.sigstore.testing.annotations.RequiresGithubOidc; +import dev.sigstore.testkit.annotations.EnabledIfOidcExists; +import dev.sigstore.testkit.annotations.OidcProviderType; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class GithubActionsOidcClientTest { @Test - @RequiresGithubOidc + @EnabledIfOidcExists(provider = OidcProviderType.GITHUB) public void getToken() throws OidcException { var client = GithubActionsOidcClient.builder().build(); var token = client.getIDToken(); diff --git a/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/DisableIfCiWithoutOidc.kt b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/DisableIfCiWithoutOidc.kt deleted file mode 100644 index 5a5a53039..000000000 --- a/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/DisableIfCiWithoutOidc.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022 The Sigstore Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package dev.sigstore.testkit - -import org.junit.jupiter.api.extension.ConditionEvaluationResult -import org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled -import org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled -import org.junit.jupiter.api.extension.ExecutionCondition -import org.junit.jupiter.api.extension.ExtendWith -import org.junit.jupiter.api.extension.ExtensionContext - -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -@ExtendWith(DisableIfCiWithoutOidcCondition::class) -annotation class DisableIfCiWithoutOidc - -class DisableIfCiWithoutOidcCondition : ExecutionCondition { - override fun evaluateExecutionCondition(context: ExtensionContext): ConditionEvaluationResult { - return when { - System.getenv("CI") != "true" -> - enabled("CI environment variable is not found") - - System.getenv("ACTIONS_ID_TOKEN_REQUEST_URL") == null -> - disabled("ACTIONS_ID_TOKEN_REQUEST_URL environment variable is not found, so OIDC is not available") - - else -> - enabled("CI=true and ACTIONS_ID_TOKEN_REQUEST_URL is present, so OIDC is available") - } - } -} diff --git a/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/EnableIfOidcExistsCondition.kt b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/EnableIfOidcExistsCondition.kt new file mode 100644 index 000000000..dfd7bd5d8 --- /dev/null +++ b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/EnableIfOidcExistsCondition.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Sigstore Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package dev.sigstore.testkit + +import dev.sigstore.testkit.annotations.EnabledIfOidcExists +import dev.sigstore.testkit.annotations.OidcProviderType +import org.junit.jupiter.api.extension.ConditionEvaluationResult +import org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled +import org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled +import org.junit.jupiter.api.extension.ExecutionCondition +import org.junit.jupiter.api.extension.ExtensionContext +import org.junit.platform.commons.util.AnnotationUtils + +class EnableIfOidcExistsCondition : ExecutionCondition { + override fun evaluateExecutionCondition(context: ExtensionContext): ConditionEvaluationResult { + val element = context.element.orElse(null) + val provider = AnnotationUtils.findAnnotation(element, EnabledIfOidcExists::class.java) + .map { it.provider }.orElse(OidcProviderType.ANY) + + return when { + provider == OidcProviderType.MANUAL -> + if (System.getenv("CI") == "true") { + disabled("CI environment is present, and the test has been configured to run with MANUAL OIDC only") + } else { + enabled("the test has been configured with MANUAL OIDC, and no CI environment variable is detected") + } + + provider in listOf(OidcProviderType.ANY, OidcProviderType.CI, OidcProviderType.GITHUB) && + System.getenv("ACTIONS_ID_TOKEN_REQUEST_URL") != null -> + enabled("ACTIONS_ID_TOKEN_REQUEST_URL is present, so OIDC matches the requested $provider") + + else -> + disabled("test requires $provider OIDC provider") + } + } +} diff --git a/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/EnabledIfOidcExists.kt b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/EnabledIfOidcExists.kt new file mode 100644 index 000000000..33227db83 --- /dev/null +++ b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/EnabledIfOidcExists.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2022 The Sigstore Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package dev.sigstore.testkit.annotations + +import dev.sigstore.testkit.EnableIfOidcExistsCondition +import org.junit.jupiter.api.condition.DisabledIfSystemProperty +import org.junit.jupiter.api.extension.ExtendWith + +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +@DisabledIfSystemProperty( + named = "sigstore-java.test.skipOidc", + matches = "^\\s*+(true|y|on|)\\s*+$", + disabledReason = "sigstore-java.test.skipOidc system property is present", +) +@ExtendWith(EnableIfOidcExistsCondition::class) +annotation class EnabledIfOidcExists( + val provider: OidcProviderType = OidcProviderType.ANY +) diff --git a/sigstore-java/src/test/java/dev/sigstore/testing/annotations/RequiresGithubOidc.java b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/OidcProviderType.kt similarity index 51% rename from sigstore-java/src/test/java/dev/sigstore/testing/annotations/RequiresGithubOidc.java rename to sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/OidcProviderType.kt index 001e232d7..f9d50d947 100644 --- a/sigstore-java/src/test/java/dev/sigstore/testing/annotations/RequiresGithubOidc.java +++ b/sigstore-testkit/src/main/kotlin/dev/sigstore/testkit/annotations/OidcProviderType.kt @@ -12,21 +12,15 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package dev.sigstore.testing.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +package dev.sigstore.testkit.annotations -@Target(ElementType.METHOD) -@Tag("github_oidc") -@Retention(RetentionPolicy.RUNTIME) -@EnabledIfEnvironmentVariable( - named = "GITHUB_ACTIONS", - matches = "true", - disabledReason = "test only runs on github actions") -public @interface RequiresGithubOidc {} +enum class OidcProviderType { + ANY, + MANUAL, + CI, + AWS, + AZURE, + GITHUB, +}