Diffstat (limited to 'Jenkinsfile')
| -rw-r--r-- | Jenkinsfile | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..74f942c --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,186 @@ +// Builds are driven by the tag name. The pipeline does nothing at all unless +// the checkout is a tag of the form +// +// fedora-<fedora_ver>-kernel-<upstream_ver>-patchset-<patchset_ver> +// +// e.g. fedora-45-kernel-7.2.3-patchset-1. +// +// The Fedora version picks the build container and the bucket prefix. The +// kernel and patchset versions are asserted against the spec rather than fed +// into it, so the spec stays the one place they are defined and a mistyped tag +// fails the build instead of publishing something that disagrees with its name. +TAG_PATTERN = /^fedora-(\d+)-kernel-(.+)-patchset-(\d+)$/ + +// The container image is the one field that has to be known before the agent +// exists, so it cannot be read out of the shell below. Everything between +// `fedora-` and `-kernel-` is the Fedora version, and it never contains a dash. +def fedoraVersionFromTag() { + def tag = env.TAG_NAME ?: '' + tag ==~ TAG_PATTERN ? tag.split('-')[1] : null +} + +pipeline { + agent none + + options { + timestamps() + } + + environment { + B2_ENDPOINT = 'https://s3.eu-central-003.backblazeb2.com' + AWS_DEFAULT_REGION = 'eu-central-003' + RPM_BUCKET = 'dist-sayagit-fedora-rpm' + + // awscli2 sends CRC32 checksums by default, which B2 rejects. Ask for + // them only where the S3 API requires them. + AWS_REQUEST_CHECKSUM_CALCULATION = 'when_required' + AWS_RESPONSE_CHECKSUM_VALIDATION = 'when_required' + } + + stages { + stage('Build and publish kernel-surface RPM (ARM64)') { + when { + beforeAgent true + allOf { + buildingTag() + expression { env.TAG_NAME ==~ TAG_PATTERN } + } + } + + agent { + kubernetes { + defaultContainer 'rpmbuild' + yaml """ +apiVersion: v1 +kind: Pod +metadata: + namespace: jenkins +spec: + nodeSelector: + kubernetes.io/arch: arm64 + containers: + - name: rpmbuild + image: fedora:${fedoraVersionFromTag()} + imagePullPolicy: Always + command: [ 'sleep' ] + args: [ 'infinity' ] + tty: true + resources: + requests: + cpu: "4" + memory: 5Gi + ephemeral-storage: 40Gi + limits: + memory: 7Gi + ephemeral-storage: 100Gi +""" + } + } + steps { + checkout scm + container('rpmbuild') { + withCredentials([usernamePassword( + credentialsId: 'backblaze-b2-dist-rpm', + usernameVariable: 'AWS_ACCESS_KEY_ID', + passwordVariable: 'AWS_SECRET_ACCESS_KEY')]) { + sh ''' + set -eux + + dnf --assumeyes install \\ + git rpm-build rpmdevtools dnf5-plugins awscli2 curl tar \\ + createrepo_c + + git config --global --add safe.directory '*' + git submodule update --init overlay + + rest=${TAG_NAME#fedora-*-kernel-} + tag_fedora=${TAG_NAME#fedora-} + tag_fedora=${tag_fedora%%-kernel-*} + tag_kernel=${rest%-patchset-*} + tag_patchset=${rest##*-patchset-} + fedora_version=${tag_fedora} + + # The tag drives the build: these override the + # spec's own %global defaults, and make-sources.sh + # reads them out of the environment so the patch + # tarball it assembles is the one Source1 names. + export UPSTREAM_VER=${tag_kernel} + export PATCHSET_VER=${tag_patchset} + + # A numbered tag has to agree with the container it + # selected, which is what stamps %{?dist} onto the + # release. + container_fedora=$(rpm --eval '%{fedora}') + if [ "${tag_fedora}" != "${container_fedora}" ]; then + echo "tag names Fedora ${tag_fedora}, container is ${container_fedora}" >&2 + exit 1 + fi + + rpmdev-setuptree + + # The published file name is whatever the spec + # resolves to under the tag's versions, so the two + # cannot drift. A kernel build is expensive; if this + # exact NEVRA is already in the bucket, skip + # straight to the metadata. + rpm_file=$(rpmspec -q \\ + --define "upstream_ver ${UPSTREAM_VER}" \\ + --define "patchset_ver ${PATCHSET_VER}" \\ + --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\\n' \\ + kernel-surface.spec | head -n1) + dest="s3://${RPM_BUCKET}/fedora/${fedora_version}/aarch64/${rpm_file}" + + skip_build=false + if aws s3 ls --endpoint-url "${B2_ENDPOINT}" "${dest}"; then + echo "${rpm_file} already published, skipping build" + skip_build=true + fi + + if [ "${skip_build}" = false ]; then + ./make-sources.sh + dnf --assumeyes builddep kernel-surface.spec + + rpmbuild -bb \\ + --define "upstream_ver ${UPSTREAM_VER}" \\ + --define "patchset_ver ${PATCHSET_VER}" \\ + --define '_smp_mflags -j4' \\ + kernel-surface.spec + + built="${HOME}/rpmbuild/RPMS/aarch64/${rpm_file}" + test -f "${built}" + + aws s3 cp --endpoint-url "${B2_ENDPOINT}" \\ + "${built}" "${dest}" + fi + + repo_url="s3://${RPM_BUCKET}/fedora/${fedora_version}/aarch64" + repo="${WORKSPACE}/repo" + + mkdir -p "${repo}" + aws s3 sync --endpoint-url "${B2_ENDPOINT}" \\ + --exclude '*' --include '*.rpm' \\ + "${repo_url}/" "${repo}/" + + createrepo_c --update "${repo}" + + aws s3 sync --endpoint-url "${B2_ENDPOINT}" \\ + --exclude 'repomd.xml*' \\ + "${repo}/repodata/" "${repo_url}/repodata/" + aws s3 cp --endpoint-url "${B2_ENDPOINT}" \\ + "${repo}/repodata/repomd.xml" \\ + "${repo_url}/repodata/repomd.xml" + + # Served next to the repository so that consumers + # can `dnf config-manager --add-repo` the URL. + sed "s|[$]releasever|${fedora_version}|g" \\ + kernel-sp12in.repo > "${WORKSPACE}/published.repo" + aws s3 cp --endpoint-url "${B2_ENDPOINT}" \\ + "${WORKSPACE}/published.repo" \\ + "s3://${RPM_BUCKET}/fedora/${fedora_version}/kernel-sp12in.repo" + ''' + } + } + } + } + } +} |