diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile new file mode 100644 index 0000000..1b1313f --- /dev/null +++ b/ci/Jenkinsfile @@ -0,0 +1,110 @@ +def getFedoraVersions() { + def response = httpRequest( + url: 'https://pdc.fedoraproject.org/rest_api/v1/product-versions?short=fedora&active=true', + acceptType: 'APPLICATION_JSON', + ) + def content = readJSON(text: response.content) + return content.results. + findAll { it.version != "rawhide" }. + collect { it.version } +} + +def matrixBuild(architectures, fedoraVersions, block) { + echo "Building for Fedora ${fedoraVersions}, architectures ${architectures}" + parallel architectures.collectMany { arch -> + fedoraVersions.collect { version -> + [arch, version] + } + }.collectEntries { + def arch = it[0] + def version = it[1] + block.delegate = [ + arch: arch, + fedoraVersion: version, + ] + ["f${version}/${arch}", { block() }] + } +} + +def podTemplateYaml = readTrusted('ci/podTemplate.yaml') + +def architectures = ["amd64"] +def fedoraVersions = getFedoraVersions() + +stage('Fetch Sources') { + podTemplate( + yaml: podTemplateYaml, + yamlMergeStrategy: merge(), + ) { + node(POD_LABEL) { + checkout scm + def version + container('build') { + version = sh( + script: '''rpmspec -q --srpm --qf '%{VERSION}' wal-g.spec''', + returnStdout: true, + ) + } + container('fetch') { + sh "sh sources.sh ${version}" + } + stash name: 'sources', includes: 'wal-g-*.tar.gz' + } + } +} +matrixBuild(architectures, fedoraVersions) { + def tmpl = readYaml(text: podTemplateYaml) + tmpl.spec.containers.each { container -> + if (container.name == 'build') { + container.image = "registry.fedoraproject.org/fedora:${fedoraVersion}" + } + } + podTemplate( + yaml: writeYaml(data: tmpl, returnText: true), + yamlMergeStrategy: merge(), + nodeSelector: "kubernetes.io/arch=${arch}", + ) { + node(POD_LABEL) { + checkout scm + stage("Prepare f${fedoraVersion}/${arch}") { + container('build') { + sh '. ci/prepare.sh' + } + } + stage("Build f${fedoraVersion}/${arch}") { + unstash 'sources' + container('build') { + sh '. ci/build.sh' + } + } + stage("Sign f${fedoraVersion}/${arch}") { + when(env.BRANCH_NAME == 'master') { + container('build') { + 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' + } + } + } + } + archiveArtifacts '*.rpm' + stage("Publish f${fedoraVersion}/${arch}") { + when(env.BRANCH_NAME == 'master') { + container('build') { + sshagent(['jenkins-repohost']) { + sh '. ci/publish.sh' + } + } + } + } + } + } +} diff --git a/ci/build.sh b/ci/build.sh new file mode 100644 index 0000000..9458ef9 --- /dev/null +++ b/ci/build.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +rpmbuild -ba \ + -D "_topdir ${PWD}" \ + -D '_rpmdir %_topdir' \ + -D '_sourcedir %_topdir' \ + -D '_specdir %_topdir' \ + -D '_srcrpmdir %_topdir' \ + wal-g.spec + +mv $(uname -m)/*.rpm . diff --git a/ci/podTemplate.yaml b/ci/podTemplate.yaml new file mode 100644 index 0000000..aa5c915 --- /dev/null +++ b/ci/podTemplate.yaml @@ -0,0 +1,26 @@ +spec: + containers: + - name: fetch + image: docker.io/library/golang:1.21 + command: + - cat + stdin: true + tty: true + - name: build + image: git.pyrocufflink.blue/containerimages/build/rpm + command: + - cat + stdin: true + tty: true + resources: + requests: + cpu: 1500m + 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..ccb303d --- /dev/null +++ b/ci/prepare.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +dnf install -y \ + --setopt install_weak_deps=0 \ + rpm-build \ + rpm-sign \ + rsync \ + -- + +rpmspec -q --srpm --requires wal-g.spec \ + | xargs dnf install -y --setopt install_weak_deps=0 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..a3ffe38 --- /dev/null +++ b/ci/sign-rpms.sh @@ -0,0 +1,11 @@ +#!/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}"