From dd2a99d9e5afe86b20e7b16726e0eef718e1bb23 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Wed, 13 Aug 2025 21:34:02 -0500 Subject: [PATCH] wip: ci: Add Jenkins build pipeline --- ci/Jenkinsfile | 87 +++++++++++++++++++++++++++++++++++++++++++++ ci/build.sh | 14 ++++++++ ci/podTemplate.yaml | 25 +++++++++++++ ci/prepare.sh | 11 ++++++ ci/publish.sh | 25 +++++++++++++ ci/sign-rpms.sh | 12 +++++++ 6 files changed, 174 insertions(+) create mode 100644 ci/Jenkinsfile create mode 100644 ci/build.sh create mode 100644 ci/podTemplate.yaml create mode 100644 ci/prepare.sh create mode 100644 ci/publish.sh create mode 100644 ci/sign-rpms.sh diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile new file mode 100644 index 0000000..0467955 --- /dev/null +++ b/ci/Jenkinsfile @@ -0,0 +1,87 @@ +pipeline { + agent none + + stages { + stage('RPM') { + matrix { + axes { + axis { + name 'ARCH' + values 'amd64', 'arm64' + } + axis { + name 'FEDORA' + values '41', '42' + } + } + + agent { + kubernetes { + yamlFile 'ci/podTemplate.yaml' + yamlMergeStrategy merge() + defaultContainer 'build' + nodeSelector "kubernetes.io/arch=${ARCH}" + } + } + + environment { + GNUPGHOME = "${env.WORKSPACE_TMP}/gnupg" + } + + stages { + stage('Prepare') { + steps { + sh '. ci/prepare.sh' + } + post { + success { + archiveArtifacts '*.tar.gz' + } + } + } + + stage('Build') { + steps { + sh '. ci/build.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 { + archiveArtifacts '*.rpm,*.log' + } + } + } + + stage('Publish') { + when { + branch 'master' + } + steps { + container('publish') { + sshagent(['jenkins-repohost']) { + sh '. ci/publish.sh' + } + } + } + } + } + } + } + + } +} diff --git a/ci/build.sh b/ci/build.sh new file mode 100644 index 0000000..de34046 --- /dev/null +++ b/ci/build.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +rm -rf BUILD BUILDROOT RPMS SOURCES SRPMS + +rpmbuild \ + -D "_topdir ${PWD}" \ + -D '_specdir %_topdir' \ + -D '_sourcedir %_topdir' \ + -bs dch-autoprovision.spec + +target=fedora-${FEDORA}-$(uname -m) + +mock -r ${target} SRPMS/dch-autoprovision-*.src.rpm +cp /var/lib/mock/result/* . diff --git a/ci/podTemplate.yaml b/ci/podTemplate.yaml new file mode 100644 index 0000000..0c26e8b --- /dev/null +++ b/ci/podTemplate.yaml @@ -0,0 +1,25 @@ +spec: + containers: + - name: build + image: git.pyrocufflink.net/containerimages/build/rpm + command: &sleep + - /bin/sh + - -c + - | + trap 'kill $!' TERM + sleep infinity & + wait + securityContext: + privileged: true + - name: publish + image: git.pyrocufflink.net/containerimages/rsync + command: *sleep + volumeMounts: + - mountPath: /etc/ssh/ssh_known_hosts + name: ssh-known-hosts + subPath: ssh_known_hosts + hostUsers: false + volumes: + - name: ssh-known-hosts + configMap: + name: ssh-known-hosts diff --git a/ci/prepare.sh b/ci/prepare.sh new file mode 100644 index 0000000..99638a7 --- /dev/null +++ b/ci/prepare.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +NAME=dch-autoprovision +VERSION=$(rpmspec -q --qf '%{VERSION}' *.spec) + +id +ls -ld . +git config --global --add safe.directory "${PWD}" + +git archive --format=tar.gz --prefix ${NAME}-${VERSION}/ HEAD \ + > "${NAME}-${VERSION}.tar.gz" diff --git a/ci/publish.sh b/ci/publish.sh new file mode 100644 index 0000000..42bb7f6 --- /dev/null +++ b/ci/publish.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +ARCH="$(uname -m)" +REPO_HOST=jenkins@files.pyrocufflink.blue +REPO_PATH=/srv/www/repohost/repos/dch/fedora/$(rpm --eval %fedora) + +ssh-add -l +ssh-add -L + +case "${ARCH}" in +x86_64) + # only include the SRPM once + include='*.rpm' + ;; +*) + include="*.${ARCH}.rpm" + ;; +esac + +rsync -rtiO \ + --chmod=ugo=rwX \ + --include "${include}" \ + --exclude '*' \ + ./ \ + "${REPO_HOST}:${REPO_PATH}/" diff --git a/ci/sign-rpms.sh b/ci/sign-rpms.sh new file mode 100644 index 0000000..cd228df --- /dev/null +++ b/ci/sign-rpms.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +gpg2 --pinentry-mode loopback --passphrase-fd 0 \ + --import "${RPM_GPG_PRIVATE_KEY}" \ + < "${RPM_GPG_KEY_PASSPHRASE}" + +rpmsign --addsign \ + -D '_gpg_name jenkins@pyrocufflink.net' \ + -D '_gpg_sign_cmd_extra_args --pinentry-mode loopback --passphrase-fd 3' \ + *.rpm \ + 3< "${RPM_GPG_KEY_PASSPHRASE}" +