From 32a8f389477a7379aa12f289807a0d824b89f4f1 Mon Sep 17 00:00:00 2001 From: Manfred Endres <2523575+Larusso@users.noreply.github.com> Date: Tue, 20 Oct 2020 14:59:40 +0200 Subject: [PATCH] Add conditional reset of the keychains before adding build keychain (#73) Description =========== This patch adds a new action `reset` to the `ListKeychainTask`. This action is conditional and bount to the environment variable `ATLAS_BUILD_UNITY_IOS_RESET_KEYCHAINS`. The variable is checked directly in the task implementation for now. The plugin configures a new task called `resetKeychains` and adds it as a dependency to the `addKeychain` task. This change should help with _ghost keychains_ on the CI system. Changes ======= * ![ADD] conditional reset of keychains --- .../ios/IOSBuildPluginIntegrationSpec.groovy | 44 ++++++++++++++++--- .../build/unity/ios/IOSBuildPlugin.groovy | 6 +++ .../unity/ios/tasks/ListKeychainTask.groovy | 41 ++++++++++++----- .../build/unity/ios/IOSBuildPluginSpec.groovy | 2 + 4 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/integrationTest/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginIntegrationSpec.groovy index ff760bb1..2262bf1b 100644 --- a/src/integrationTest/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginIntegrationSpec.groovy @@ -23,9 +23,7 @@ import spock.lang.Shared import spock.lang.Unroll import wooga.gradle.build.IntegrationSpec -import wooga.gradle.build.unity.ios.internal.utils.SecurityUtil - -@Requires({ os.macOs }) +@Requires({ os.macOs && env['ATLAS_BUILD_UNITY_IOS_EXECUTE_KEYCHAIN_SPEC'] == 'YES' }) class IOSBuildPluginIntegrationSpec extends IntegrationSpec { @Shared @@ -87,26 +85,33 @@ class IOSBuildPluginIntegrationSpec extends IntegrationSpec { createTestCertificate(new File(projectDir, "test_ca.p12"), certPassword) - keychainLookupList.clear() + keychainLookupList.reset() } def cleanup() { - keychainLookupList.clear() + keychainLookupList.reset() } + @Unroll("creates custom build keychain") def "creates custom build keychain"() { given: "default project" + environmentVariables.set("ATLAS_BUILD_UNITY_IOS_RESET_KEYCHAINS", resetKeychainsEnabled ? "YES" : "NO") when: def result = runTasksSuccessfully("addKeychain") then: !result.wasUpToDate("addKeychain") + result.wasExecuted("resetKeychains") + result.wasSkipped("resetKeychains") != resetKeychainsEnabled buildKeychain.exists() keychainLookupList.contains(buildKeychain) cleanup: keychainLookupList.remove(buildKeychain) + + where: + resetKeychainsEnabled << [true, false] } def "removes custom build keychain"() { @@ -155,4 +160,33 @@ class IOSBuildPluginIntegrationSpec extends IntegrationSpec { "fails" || false "succeeds" || true } + + @Unroll + def "task :#taskToRun resets keychains before build when #message"() { + given: "project which will succeed/fail the assemble task" + //skip these tasks to succeed the build + buildFile << """ + project.xcodeArchive.onlyIf({false}) + project.xcodeExport.onlyIf({false}) + project.importProvisioningProfiles.onlyIf({false}) + """.stripIndent() + + and: + environmentVariables.set("ATLAS_BUILD_UNITY_IOS_RESET_KEYCHAINS", resetEnabled ? "YES" : "NO") + + when: + def result = runTasks("assemble") + + then: + result.wasExecuted("resetKeychains") + result.wasSkipped("resetKeychains") != resetEnabled + + where: + taskToRun | resetEnabled + "assemble" | true + "assemble" | false + "addKeychain" | true + "addKeychain" | false + message = (resetEnabled) ? "reset is enabled" : "reset is disabled" + } } diff --git a/src/main/groovy/wooga/gradle/build/unity/ios/IOSBuildPlugin.groovy b/src/main/groovy/wooga/gradle/build/unity/ios/IOSBuildPlugin.groovy index 41a6e6d2..f6902daf 100644 --- a/src/main/groovy/wooga/gradle/build/unity/ios/IOSBuildPlugin.groovy +++ b/src/main/groovy/wooga/gradle/build/unity/ios/IOSBuildPlugin.groovy @@ -182,9 +182,15 @@ class IOSBuildPlugin implements Plugin { it.keychain = buildKeychain } + def resetKeychains = tasks.create(maybeBaseName(baseName, "resetKeychains"), ListKeychainTask) { + it.action = ListKeychainTask.Action.reset + it.keychain buildKeychain + } + def addKeychain = tasks.create(maybeBaseName(baseName, "addKeychain"), ListKeychainTask) { it.action = ListKeychainTask.Action.add it.keychain buildKeychain + dependsOn(resetKeychains) } def removeKeychain = tasks.create(maybeBaseName(baseName, "removeKeychain"), ListKeychainTask) { diff --git a/src/main/groovy/wooga/gradle/build/unity/ios/tasks/ListKeychainTask.groovy b/src/main/groovy/wooga/gradle/build/unity/ios/tasks/ListKeychainTask.groovy index adc018de..b55709e0 100644 --- a/src/main/groovy/wooga/gradle/build/unity/ios/tasks/ListKeychainTask.groovy +++ b/src/main/groovy/wooga/gradle/build/unity/ios/tasks/ListKeychainTask.groovy @@ -32,7 +32,8 @@ class ListKeychainTask extends DefaultTask { enum Action { add, - remove + remove, + reset } private Action action @@ -85,12 +86,26 @@ class ListKeychainTask extends DefaultTask { outputs.upToDateWhen(new Spec() { @Override boolean isSatisfiedBy(ListKeychainTask element) { - if(getAction() == Action.add) { - def filesToCheck = getKeychains().files.findAll {it.exists()} - return lookupList.containsAll(filesToCheck) + switch (getAction()) { + case Action.add: + def filesToCheck = getKeychains().files.findAll { it.exists() } + return lookupList.containsAll(filesToCheck) + case Action.remove: + return !getKeychains().any { lookupList.contains(it) } + default: + return false } - else if (getAction() == Action.remove) { - return !getKeychains().any {lookupList.contains(it)} + } + }) + + onlyIf(new Spec() { + @Override + boolean isSatisfiedBy(ListKeychainTask task) { + switch (getAction()) { + case Action.reset: + return System.getenv("ATLAS_BUILD_UNITY_IOS_RESET_KEYCHAINS") == "YES" + default: + return true } } }) @@ -99,11 +114,15 @@ class ListKeychainTask extends DefaultTask { @TaskAction protected list() { def keychains = getKeychains().files - - if (getAction() == Action.add) { - lookupList.addAll(keychains) - } else { - lookupList.removeAll(keychains) + switch (getAction()) { + case Action.add: + lookupList.addAll(keychains) + break + case Action.remove: + lookupList.removeAll(keychains) + break + case Action.reset: + lookupList.reset() } } } diff --git a/src/test/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginSpec.groovy b/src/test/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginSpec.groovy index 384cd79d..2059a3e2 100644 --- a/src/test/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginSpec.groovy +++ b/src/test/groovy/wooga/gradle/build/unity/ios/IOSBuildPluginSpec.groovy @@ -98,6 +98,7 @@ class IOSBuildPluginSpec extends ProjectSpec { "buildKeychain" | KeychainTask "unlockKeychain" | LockKeychainTask "lockKeychain" | LockKeychainTask + "resetKeychains" | ListKeychainTask "addKeychain" | ListKeychainTask "removeKeychain" | ListKeychainTask "importProvisioningProfiles" | ImportProvisioningProfile @@ -132,6 +133,7 @@ class IOSBuildPluginSpec extends ProjectSpec { "buildKeychain" | KeychainTask "unlockKeychain" | LockKeychainTask "lockKeychain" | LockKeychainTask + "resetKeychains" | ListKeychainTask "addKeychain" | ListKeychainTask "removeKeychain" | ListKeychainTask "importProvisioningProfiles" | ImportProvisioningProfile