From 2243e9e41d92cf51c1581d7a7940ad7a4c0a7a49 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Wed, 8 Nov 2023 19:15:01 -0600 Subject: [PATCH] ci: Add Jenkins pipeline The CI pipeline builds both the SSHCA server and client CLI. The server is published as an OCI image, while the latter uses RPMs. Since multiple RPMs with the same version cannot exist in the same repository, and since RPM versions cannot be arbitrarily set after they have been built, the RPMs are only published when building the *master* branch. Server container images are published from every branch, as each image is tagged with the branch name and build number. --- ci/Jenkinsfile | 109 ++++++++++++++++++++++++++++++++++++++ ci/build-client.sh | 4 ++ ci/build-server.sh | 5 ++ ci/clientPodTemplate.yaml | 9 ++++ ci/common.sh | 13 +++++ ci/prepare-client.sh | 21 ++++++++ ci/publish-client.sh | 14 +++++ ci/publish-server.sh | 11 ++++ ci/serverPodTemplate.yaml | 19 +++++++ ci/sign-rpms.sh | 12 +++++ 10 files changed, 217 insertions(+) create mode 100644 ci/Jenkinsfile create mode 100644 ci/build-client.sh create mode 100644 ci/build-server.sh create mode 100644 ci/clientPodTemplate.yaml create mode 100644 ci/common.sh create mode 100644 ci/prepare-client.sh create mode 100644 ci/publish-client.sh create mode 100644 ci/publish-server.sh create mode 100644 ci/serverPodTemplate.yaml create mode 100644 ci/sign-rpms.sh diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile new file mode 100644 index 0000000..7948b3e --- /dev/null +++ b/ci/Jenkinsfile @@ -0,0 +1,109 @@ +pipeline { + agent none + + stages { + stage('SSHCA') { + parallel { + stage('Server') { + agent { + kubernetes { + yamlFile 'ci/serverPodTemplate.yaml' + yamlMergeStrategy merge() + defaultContainer 'buildah' + } + } + stages { + stage('Build - Server') { + steps { + sh '. ci/build-server.sh' + } + } + + stage('Publish - Server') { + steps { + withEnv([ + "REGISTRY_AUTH_FILE=${env.WORKSPACE_TMP}/auth.json" + ]) { + withCredentials([usernamePassword( + credentialsId: 'jenkins-packages', + usernameVariable: 'BUILDAH_USERNAME', + passwordVariable: 'BUILDAH_PASSWORD', + )]) { + sh """ + buildah login \ + --username \${BUILDAH_USERNAME} \ + --password \${BUILDAH_PASSWORD} \ + git.pyrocufflink.net + """ + } + sh '. ci/publish-server.sh' + } + } + } + } + } + + stage('CLI') { + agent { + kubernetes { + yamlFile 'ci/clientPodTemplate.yaml' + yamlMergeStrategy merge() + defaultContainer 'fedora' + } + } + environment { + GNUPGHOME = "${env.WORKSPACE_TMP}/gnupg" + } + stages { + stage('Prepare - CLI') { + steps { + sh '. ci/prepare-client.sh' + } + } + + stage('Build - CLI') { + steps { + sh '. ci/build-client.sh' + script { + if (env.BRANCH_NAME == 'master') { + withCredentials([ + file( + credentialsId: 'rpm-gpg-key', + variable: 'RPM_GPG_PRIVATE_KEY', + ), + file( + credentialsId: 'rpm-gpg-key-passphrase', + variable: 'RPM_GPG_KEY_PASSPHRASE', + ), + ]) { + sh '. ci/sign-rpms.sh' + } + } + } + } + post { + success { + dir('cli') { + archiveArtifacts '*.rpm' + } + } + } + } + + stage('Publish - CLI') { + when { + branch 'master' + } + steps { + sshagent(['jenkins-repohost']) { + sh '. ci/publish-client.sh' + } + } + } + } + + } + } + } + } +} diff --git a/ci/build-client.sh b/ci/build-client.sh new file mode 100644 index 0000000..ce7a005 --- /dev/null +++ b/ci/build-client.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cd cli +make rpm diff --git a/ci/build-server.sh b/ci/build-server.sh new file mode 100644 index 0000000..1788b5a --- /dev/null +++ b/ci/build-server.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +. ci/common.sh + +buildah build -t "${IMAGE_NAME}:${TAG}" server diff --git a/ci/clientPodTemplate.yaml b/ci/clientPodTemplate.yaml new file mode 100644 index 0000000..d591414 --- /dev/null +++ b/ci/clientPodTemplate.yaml @@ -0,0 +1,9 @@ +spec: + containers: + - name: fedora + image: registry.fedoraproject.org/fedora:38 + command: + - cat + stdin: true + tty: true + hostUsers: false diff --git a/ci/common.sh b/ci/common.sh new file mode 100644 index 0000000..060e8cb --- /dev/null +++ b/ci/common.sh @@ -0,0 +1,13 @@ +escape_name() { + echo "$1" \ + | tr A-Z a-z \ + | sed -e 's/[^a-zA-Z0-9._-]/-/g' -e 's/^[.-]/_/' +} + +REGISTRY_URL=git.pyrocufflink.net +NAMESPACE=containerimages +NAME="${JOB_NAME#*/}" +NAME=$(escape_name "${NAME%/*}") +TAG=$(escape_name "${BRANCH_NAME}") + +IMAGE_NAME="${REGISTRY_URL}/${NAMESPACE}/${NAME}" diff --git a/ci/prepare-client.sh b/ci/prepare-client.sh new file mode 100644 index 0000000..ca80d7e --- /dev/null +++ b/ci/prepare-client.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +dnf install -y \ + --setopt install_weak_deps=0 \ + cargo \ + cargo-rpm-macros \ + make \ + openssh-clients \ + openssl-devel \ + rpm-build \ + rpm-sign \ + rsync \ + rust \ + systemd-rpm-macros \ + tar \ + -- + +install -m u=rwx,go= -d "${GNUPGHOME}" +cat > "${GNUPGHOME}"/gpg-agent.conf <