From 1f80b91d07cd4c15b7d74fe0b61bf2f8ceafe154 Mon Sep 17 00:00:00 2001
From: Davide Depau <davide@depau.eu>
Date: Thu, 30 Apr 2020 01:22:18 +0200
Subject: [PATCH] Separate hardcoded values and add signing

---
 helpers.star  | 86 +++++++++++++++++++++++++++++++++++++--------------
 settings.star | 27 ++++++++++++++++
 2 files changed, 90 insertions(+), 23 deletions(-)
 create mode 100644 settings.star

diff --git a/helpers.star b/helpers.star
index 2c95e4f..44a6f4a 100644
--- a/helpers.star
+++ b/helpers.star
@@ -1,3 +1,5 @@
+load('@lib//arch_pkg:settings.star', 'default_settings')
+
 PLATFORMS = {
     'aarch64':  {'os': 'linux', 'arch': 'arm64'},
     'x86_64':   {'os': 'linux', 'arch': 'amd64'},
@@ -6,7 +8,6 @@ PLATFORMS = {
     'i386':     {'os': 'linux', 'arch': '386'},
     'pentium4': {'os': 'linux', 'arch': '386'}
 }
-DOCKER_IMAGE = "depau/drone-makepkg:{arch}"
 
 # For debugging purposes since Drone CLI won't print anything unless you
 # give it a somewhat valid pipeline
@@ -18,10 +19,26 @@ def _debug_bogus(*a, **kw):
     } 
 
 def generate(config):
+    # "Unfreeze" config so we can add defaults and pass them around
+    _cfg = {}
+    _cfg.update(config)
+    config = _cfg
+
+    # Retrieve architectures with special configuration
     special_archs = {arch: cfg for arch, cfg in config.items() if arch in PLATFORMS.keys()}
+    # Retrieve architectures with common configuration
     others = config.get("all") or config.get("others") or None
 
+    # Apply pipeline-specific settings on top of defaults, if any
+    settings = {}
+    settings.update(default_settings)
+    settings.update(config.get('settings', {}))
+    config['settings'] = settings
+
+    # Expand common config architectures into one dict, together with the
+    # special architectures
     if others:
+        # Ensure architectues are specified when using a generic config
         if "arch_matrix" not in config:
             print("arch_matrix is required if all/others is defined")
             return None
@@ -42,6 +59,7 @@ def generate(config):
     
     pipelines = []
 
+    # Generate pipelines for every arch
     for arch, archconfig in archs.items():
         pipelines.append(generate_pipeline(config, arch, archconfig))
 
@@ -52,12 +70,14 @@ def generate(config):
 
 
 def generate_pipeline(config, arch, archconfig):
-    pipeline = {
-        'kind': 'pipeline',
-        'type': 'docker',
+    settings = config['settings']
+
+    pipeline = {}
+    pipeline.update(settings['pipeline'])
+    pipeline.update({
         'name': arch,
         'platform': PLATFORMS[arch]
-    }
+    })
 
     steps = []
 
@@ -73,7 +93,7 @@ def generate_pipeline(config, arch, archconfig):
     pull_set = False
     for pkgconfig in archconfig:
         stepcfg = step_git(pkgconfig) if is_git(pkgconfig) else step_aur(pkgconfig)
-        stepcfg['image'] = DOCKER_IMAGE.format(arch=arch)
+        stepcfg['image'] = settings['images']['build'].format(arch=arch)
 
         if not pull_set:
             # Ensure the image is pulled in the first step
@@ -82,10 +102,14 @@ def generate_pipeline(config, arch, archconfig):
 
         steps.append(stepcfg)
 
-    steps += upload_steps(arch)
+    # Add additional steps
+    for step in settings.get('additional_steps', []):
+        image = settings['images'][step].format(arch=arch)
+        step_fn = ADDITIONAL_STEPS[step]
+        steps.append(step_fn(image, arch, settings.get(step, {})))
 
+    # Allow builds only in the master branch by default
     if config.get('master_only', True):
-        # Allow builds only in the master branch by default
         for step in steps:
             step['when'] = {'branch': ['master']}
     
@@ -147,19 +171,35 @@ def step_git(pkgconfig):
         return None
 
 
-# TODO: probably it's better not to hardcode everything here
-def upload_steps(arch):
-    return [{
+def sign_step(image, arch, settings):
+    step = {
+        'name': 'sign',
+        'image': image,
+        'settings': {}
+    }
+    step['settings'].update(settings)
+    step['settings'].update({
+        'sign_dir': 'out'
+    })
+    return step
+
+
+def upload_step(image, arch, settings):
+    step = {
         'name': 'upload',
-        'image': 'plugins/s3',
-        'settings': {
-            'endpoint': 'https://objstor.depau.eu',
-            'bucket': 'archlinux-packages',
-            'access_key': {'from_secret': 'minio_user'},
-            'secret_key': {'from_secret': 'minio_passwd'},
-            'source': 'out/*',
-            'target': '/' + arch,
-            'strip_prefix': True,
-            'path_style': True
-        }
-    }]
+        'image': image,
+        'settings': {}
+    }
+    step['settings'].update(settings)
+    step['settings'].update({
+        'source': 'out/*',
+        'target': '/' + arch,
+        'strip_prefix': True
+    })
+    return step
+
+
+ADDITIONAL_STEPS = {
+    'sign': sign_step,
+    'upload': upload_step
+}
diff --git a/settings.star b/settings.star
new file mode 100644
index 0000000..2d7f84e
--- /dev/null
+++ b/settings.star
@@ -0,0 +1,27 @@
+default_settings = {
+  'images': {
+    'build':  "depau/drone-makepkg:{arch}",
+    'sign':   "depau/drone-detach-sign:{arch}",
+    'upload': "plugins/s3"
+  },
+
+  'pipeline': {
+    'kind': 'pipeline',
+    'type': 'docker'
+  }
+ 
+  'additional_steps': ['sign', 'upload'],
+ 
+  'sign': {
+    'gpg_secret_key': {'from_secret': 'gpg_secret_key'},
+    'gpg_passphrase': {'from_secret': 'gpg_passphrase'}
+  },
+  
+  'upload': {
+    'endpoint': 'https://objstor.depau.eu',
+    'bucket': 'archlinux-packages',
+    'access_key': {'from_secret': 'minio_user'},
+    'secret_key': {'from_secret': 'minio_passwd'},
+    'path_style': True
+  }
+}