From f7274899f5a86136a538be8032bbcfe9275ea228 Mon Sep 17 00:00:00 2001 From: Artem IG Date: Thu, 20 Oct 2022 07:38:43 +0300 Subject: [PATCH] refa --- .github/workflows/test-and-stage.yaml | 2 +- src/main/kotlin/Main.kt | 7 +-- src/main/kotlin/stages/sign/GpgTty.kt | 49 ++++++++++++++++++ src/main/kotlin/stages/sign/TempGpg.kt | 72 +++----------------------- src/test/kotlin/GpgTest.kt | 1 + 5 files changed, 58 insertions(+), 73 deletions(-) create mode 100644 src/main/kotlin/stages/sign/GpgTty.kt diff --git a/.github/workflows/test-and-stage.yaml b/.github/workflows/test-and-stage.yaml index c404948..9dc57f0 100644 --- a/.github/workflows/test-and-stage.yaml +++ b/.github/workflows/test-and-stage.yaml @@ -140,7 +140,7 @@ jobs: echo "result=$VERSION" >>$GITHUB_OUTPUT - name: Build run: | - export GPG_TTY=$(tty) + #export GPG_TTY=$(tty) ./gradlew uberJar mv ./build/libs/mavence.uber.jar ./build/libs/mavence.jar env: diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt index 1bacf20..3773b85 100644 --- a/src/main/kotlin/Main.kt +++ b/src/main/kotlin/Main.kt @@ -8,13 +8,8 @@ import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.options.* import kotlinx.coroutines.runBlocking import maven.* -import stages.sign.cmdSign +import stages.sign.* import stages.upload.* -import tools.* - -import java.nio.file.* - - class Cli : NoOpCliktCommand( diff --git a/src/main/kotlin/stages/sign/GpgTty.kt b/src/main/kotlin/stages/sign/GpgTty.kt new file mode 100644 index 0000000..03b0474 --- /dev/null +++ b/src/main/kotlin/stages/sign/GpgTty.kt @@ -0,0 +1,49 @@ +package stages.sign + +import com.github.pgreze.process.process + +private suspend fun canGetTty(): Boolean = + process("tty").resultCode == 0 + +private fun isGpgTtySet() = + (System.getenv("GPG_TTY") ?: "").trim().isNotEmpty() + +private fun weAreInWindows() = + System.getProperty("os.name").startsWith("Windows") + +@Deprecated("Not needed anymore?", ReplaceWith("")) // since 2022-10 +suspend fun requireGpgTtyIfNeeded() { + // Есть проблема, которая мешает GPG подписывать файлы в Github Actions: + // "gpg: signing failed: Inappropriate ioctl for device" + // + // у неё есть workaround: + // https://github.com/keybase/keybase-issues/issues/2798#issue-205008630 + // + // Это описано также в `man gpg-agent`: + // + // You should always add the following lines to your .bashrc or whatever + // initialization file is used for all shell invocations: + // ``` + // GPG_TTY=$(tty) + // export GPG_TTY + // ``` + // + // It is important that this environment variable always reflects the out- + // put of the tty command. For W32 systems this option is not required. + // + // Я пытался сделать это прямо из скрипта, но в Actions не мог выяснить tty: + // 1. subprocess.check_output("tty") + // 2. os.ttyname(sys.stdout.fileno()) + // В первом случае получал код ошибки, во втором + // "OSError: [Errno 25] Inappropriate ioctl for device" + // + // В общем, эта функция просто проверяла, чтобы переменная была определена + // до запуска программы. + // + // Однако, в коде Gradle https://bit.ly/3Sb4iml нашлось другое решение: аргумент "--no-tty". + // Похоже, он исправляет проблему и без проверок. + if (!isGpgTtySet() && !weAreInWindows() && !canGetTty()) + throw Exception( + """Please set GPG_TTY environment variable: + | `export GPG_TTY=${'$'}(tty)`""".trimIndent()) +} \ No newline at end of file diff --git a/src/main/kotlin/stages/sign/TempGpg.kt b/src/main/kotlin/stages/sign/TempGpg.kt index 8b04755..134717d 100644 --- a/src/main/kotlin/stages/sign/TempGpg.kt +++ b/src/main/kotlin/stages/sign/TempGpg.kt @@ -3,7 +3,7 @@ * SPDX-License-Identifier: ISC **/ -package tools +package stages.sign import com.github.pgreze.process.* import java.io.* @@ -20,22 +20,10 @@ value class GpgPassphrase(val string: String) @JvmInline value class GpgPrivateKey(val string: String) -@OptIn(GpgInternals::class) -suspend fun signFile( - file: Path, - key: GpgPrivateKey, - phrase: GpgPassphrase, - target: Path = file.parent.resolve(file.name + ".asc"), -) { - TempGpg().use { - it.importKey(key) - it.signFile(file, phrase, target) - } -} - -/// Runs GPG with a temporary "homedir", i.e. with a temporary keys database. -/// We can import keys into it without changing the system - +/** + * Runs GPG with a temporary "homedir", i.e. with a temporary keys database. + * We can import keys into it without changing the system + */ internal class TempGpg : Closeable { private val exe: String = "gpg" @@ -101,7 +89,6 @@ internal class TempGpg : Closeable { Regex("\\s+"), " ") } - /// Creates `file.ext.asc` next to `file.ext`. suspend fun signFile( file: Path, passphrase: GpgPassphrase, @@ -128,51 +115,4 @@ internal class TempGpg : Closeable { .unwrap() check(target.exists()) } -} - -private suspend fun canGetTty(): Boolean = - process("tty").resultCode == 0 - -private fun isGpgTtySet() = - (System.getenv("GPG_TTY") ?: "").trim().isNotEmpty() - -private fun weAreInWindows() = - System.getProperty("os.name").startsWith("Windows") - -suspend fun requireGpgTtyIfNeeded() { - // есть проблема, которая мешает GPG подписывать файлы в Github Actions: - // "gpg: signing failed: Inappropriate ioctl for device" - // - // у неё есть workaround: - // https://github.com/keybase/keybase-issues/issues/2798#issue-205008630 - // - // Это описано также в `man gpg-agent`: - // - // You should always add the following lines to your .bashrc or whatever - // initialization file is used for all shell invocations: - // ``` - // GPG_TTY=$(tty) - // export GPG_TTY - // ``` - // - // It is important that this environment variable always reflects the out- - // put of the tty command. For W32 systems this option is not required. - // - // Я пытался сделать это прямо из скрипта, но в Actions не мог выяснить tty: - // 1. subprocess.check_output("tty") - // 2. os.ttyname(sys.stdout.fileno()) - // В первом случае получал код ошибки, во втором - // "OSError: [Errno 25] Inappropriate ioctl for device" - // - // В общем, просто требуем, чтобы переменная была определена - // Поэтому пока я просто требую, чтобы такая переменная среды была задана - // до запуска скрипта. - // - // !!! впрочем, возможно задачу решит аргумент "--no-tty". Его использует Gradle - // https://bit.ly/3Sb4iml - - if (!canGetTty() && !weAreInWindows() && !canGetTty()) - throw Exception( - """Please set GPG_TTY environment variable: - | `export GPG_TTY=${'$'}(tty)`""".trimIndent()) -} +} \ No newline at end of file diff --git a/src/test/kotlin/GpgTest.kt b/src/test/kotlin/GpgTest.kt index 85717eb..ab35dc0 100644 --- a/src/test/kotlin/GpgTest.kt +++ b/src/test/kotlin/GpgTest.kt @@ -2,6 +2,7 @@ import io.kotest.matchers.booleans.* import io.kotest.matchers.shouldBe import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test +import stages.sign.* import tools.* import java.nio.file.* import java.util.zip.CRC32