// Builds are driven by the tag name. The pipeline does nothing at all unless // the checkout is a tag of the form // // fedora--kernel--patchset- // // 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: 5Gi 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" ''' } } } } } }