From 1b2ea31de4f517840705711d3484763a2410d1e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaspar=20L=C3=B6chte?= <jaspar.loechte@greenbone.net>
Date: Mon, 28 Jun 2021 16:49:21 +0200
Subject: [PATCH 1/4] Add the possiblity to use pontos-release sign headless
 with the passphrase

---
 pontos/release/release.py | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/pontos/release/release.py b/pontos/release/release.py
index 3bfa95741..065b3b0bb 100644
--- a/pontos/release/release.py
+++ b/pontos/release/release.py
@@ -162,6 +162,15 @@ def initialize_default_parser() -> argparse.ArgumentParser:
         default='greenbone',
         help='user/team name in github',
     )
+
+    sign_parser.add_argument(
+        '--passphrase',
+        default='greenbone',
+        help=(
+            'Use gpg in a headless mode e.g. for '
+            'the CI and use this passphrase for signing.'
+        ),
+    )
     return parser
 
 
@@ -448,10 +457,17 @@ def sign(
     for file_path in file_paths:
         info(f"Signing {file_path}")
 
-        shell_cmd_runner(
-            f"gpg --default-key {signing_key} --yes --detach-sign --armor "
-            f"{file_path}"
-        )
+        if args.passphrase:
+            shell_cmd_runner(
+                f"gpg --pinentry-mode loopback --default-key {signing_key}"
+                f" --yes --detach-sign --passphrase {args.passphrase}"
+                f" --armor {file_path}"
+            )
+        else:
+            shell_cmd_runner(
+                f"gpg --default-key {signing_key} --yes --detach-sign --armor "
+                f"{file_path}"
+            )
 
     return upload_assets(
         username,
@@ -499,7 +515,8 @@ def main(
             ):
                 return sys.exit(1) if leave else False
         except subprocess.CalledProcessError as e:
-            error(f'Could not run command "{e.cmd}". Error was:\n\n{e.stderr}')
+            error(f'Could not run command "{e.cmd}".')
+            out(f'Error was: {e.stderr}')
             sys.exit(1)
 
     return sys.exit(0) if leave else True

From 97c6e18dac14577894d7a3fee6c693bc9fed5237 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaspar=20L=C3=B6chte?= <jaspar.loechte@greenbone.net>
Date: Mon, 28 Jun 2021 16:50:22 +0200
Subject: [PATCH 2/4] Adjust naming and behavior of this flushing terminal
 print

---
 pontos/release/helper.py    |  9 ++++-----
 pontos/terminal/__init__.py |  4 ++--
 pontos/terminal/terminal.py | 17 +++++++++++------
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/pontos/release/helper.py b/pontos/release/helper.py
index 8446d4f44..0ae51940e 100644
--- a/pontos/release/helper.py
+++ b/pontos/release/helper.py
@@ -30,7 +30,7 @@
 import requests
 
 from pontos import version
-from pontos.terminal import error, warning, info, ok, out, out_flush
+from pontos.terminal import error, warning, info, ok, out, overwrite
 from pontos.terminal.terminal import Signs
 from pontos.version.helper import VersionError
 from pontos.version import (
@@ -191,7 +191,7 @@ def download(
                 dl += len(content)
                 download_file.write(content)
                 done = int(50 * dl / total_length)
-                out_flush(f"[{'=' * done}{' ' * (50-done)}]")
+                overwrite(f"[{'=' * done}{' ' * (50-done)}]")
     else:
         with file_path.open(mode='wb') as download_file:
             spinner = ['-', '\\', '|', '/']
@@ -201,9 +201,8 @@ def download(
                 if i == 4:
                     i = 0
                 download_file.write(content)
-                out_flush(f"[{spinner[i]}]")
-    out_flush(f"[{Signs.OK}]{' ' * 50}")
-    out('')
+                overwrite(f"[{spinner[i]}]")
+    overwrite(f"[{Signs.OK}]{' ' * 50}", new_line=True)
 
     return file_path
 
diff --git a/pontos/terminal/__init__.py b/pontos/terminal/__init__.py
index 0933b399b..f90559c93 100644
--- a/pontos/terminal/__init__.py
+++ b/pontos/terminal/__init__.py
@@ -58,8 +58,8 @@ def out(message: str):
     __term.print(message)
 
 
-def out_flush(message: str):
-    __term.print_without_newline(message)
+def overwrite(message: str, new_line: bool = False):
+    __term.print_overwrite(message, new_line=new_line)
 
 
 def _set_terminal(term: Terminal):
diff --git a/pontos/terminal/terminal.py b/pontos/terminal/terminal.py
index 1e2756647..0acef666f 100644
--- a/pontos/terminal/terminal.py
+++ b/pontos/terminal/terminal.py
@@ -61,10 +61,10 @@ def _print_status(
         style: Callable,
         *,
         new_line: bool = True,
-        flush: bool = False,
+        overwrite: bool = False,
     ) -> None:
         first_line = ''
-        if not new_line:
+        if overwrite:
             first_line = '\r'
         output = ''
         width = self.get_width()
@@ -84,7 +84,7 @@ def _print_status(
         if new_line:
             print(style(output))
         else:
-            print(style(output), end='', flush=flush)
+            print(style(output), end='', flush=True)
 
     @contextmanager
     def indent(self, indentation: int = 4) -> Generator:
@@ -105,12 +105,17 @@ def print(self, *messages: str, style: Callable = cf.reset) -> None:
         message = ''.join(messages)
         self._print_status(message, Signs.NONE, cf.white, style)
 
-    def print_without_newline(
-        self, *messages: str, style: Callable = cf.reset
+    def print_overwrite(
+        self, *messages: str, style: Callable = cf.reset, new_line: bool = False
     ) -> None:
         message = ''.join(messages)
         self._print_status(
-            message, Signs.NONE, cf.white, style, new_line=False, flush=True
+            message,
+            Signs.NONE,
+            cf.white,
+            style,
+            new_line=new_line,
+            overwrite=True,
         )
 
     def ok(self, message: str, style: Callable = cf.reset) -> None:

From fb961809fcaf85729a6c0eb255fa514753a07c88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaspar=20L=C3=B6chte?= <jaspar.loechte@greenbone.net>
Date: Mon, 28 Jun 2021 16:53:26 +0200
Subject: [PATCH 3/4] Add Changelog entry

---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86a5c48d5..1c0100c65 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@ and this project adheres to [Calendar Versioning](https://calver.org).
 
 ## [Unreleased]
 ### Added
+* `pontos-release`: You can use `sign` now headless (without passphrase prompt) by passing it per arugment. [#148](https://github.com/greenbone/pontos/pull/148)
+
 ### Changed
 ### Deprecated
 ### Removed

From 07bbdf5139b5bf81a0c770b76f0c711c48fabf32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaspar=20L=C3=B6chte?= <jaspar.loechte@greenbone.net>
Date: Mon, 28 Jun 2021 21:02:14 +0200
Subject: [PATCH 4/4] Update the release workflow (add signing :) )

---
 .github/workflows/release-pontos.yml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/.github/workflows/release-pontos.yml b/.github/workflows/release-pontos.yml
index 8812e18fd..3a37c4e85 100644
--- a/.github/workflows/release-pontos.yml
+++ b/.github/workflows/release-pontos.yml
@@ -10,6 +10,9 @@ jobs:
       GITHUB_USER: ${{ secrets.GREENBONE_BOT }}
       GITHUB_MAIL: ${{ secrets.GREENBONE_BOT_MAIL }}
       GITHUB_TOKEN: ${{ secrets.GREENBONE_BOT_TOKEN }}
+      GPG_KEY: ${{ secrets.GPG_KEY }}
+      GPG_FINGERPRINT: ${{ secrets.FINGERPRINT }}
+      GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
     name: Build and release with pontos
     # If the label 'make release' is set. If PR is closed because of an merge
     if: contains( github.event.pull_request.labels.*.name, 'make release') && github.event.pull_request.merged == true
@@ -32,6 +35,16 @@ jobs:
     - name: Prepare release with pontos
       run: |
         poetry run pontos-release prepare --calendar
+        echo "VERSION=$(poetry run pontos-version show)" >> $GITHUB_ENV
     - name: Release with pontos
       run: |
         poetry run pontos-release release
+    - name: Sign assets with pontos
+      run: |
+        echo "Signing assets for ${{env.VERSION}}"
+        echo -e "${{ env.GPG_PASSPHRASE }}" >> tmp.file
+        gpg --import tmp.file && rm tmp.file
+        poetry run pontos-release sign \
+          --signing-key ${{ env.GPG_FINGERPRINT }} \
+          --passphrase ${{ env.GPG_PASSPHRASE }} \
+          --release-version ${{ env.VERSION }}