wip: ci: Keep workspace between builds
Some checks failed
dustin/kitchenos/pipeline/head There was a failure building this commit

When building Buildroot projects, especially ones with packages that
take a very long time to compile like WebkitGTK in this one, we usually
want to keep the workspace around between builds to avoid rebuilding
everything every time the job runs.  Historically, I've done this by
allocating a persistent volume for the workspace, however, this is
problematic for a few reasons.  First, the configuration is external to
the CI pipeline.  More importantly, jobs that run on cloud workers do
not have access to the iSCSI target.  As such, an alternative solution
is to use a local path, but store the contents in the artifact
repository at the end of the run.  The next run can then download the
archive from the artifact repository and extract it into the workspace
before beginning the build.  This mostly achieves the same effect, but
is completely self-contained within the CI pipeline definition, and does
not rely on persistent storage at all.
This commit is contained in:
2025-11-12 18:34:53 -06:00
parent 361477dd09
commit 9f143fd5b7
5 changed files with 88 additions and 33 deletions

47
ci/Jenkinsfile vendored
View File

@@ -1,6 +1,24 @@
def workspaceExists() {
def packageName = "${env.JOB_NAME.split('/')[-2]}-workspace"
def res = httpRequest(
url: "${GITEA_URL}/api/v1/packages/jenkins/generic/${packageName}/-/latest",
acceptType: 'APPLICATION_JSON',
authentication: 'jenkins-gitea',
validResponseCodes: '200,404',
)
if (res.status == 200) {
def data = readJSON(text: res.content)
env.SAVED_WORKSPACE_URL = "${GITEA_URL}/api/packages/jenkins/generic/${packageName}/${data.version}/workspace.tar.gz"
return true
} else {
return false
}
}
pipeline {
parameters {
booleanParam 'CLEAN_BUILD'
booleanParam name: 'KEEP_WORKSPACE', defaultValue: true
}
options {
@@ -16,25 +34,38 @@ pipeline {
}
stages {
stage('Clean') {
stage('Download Workspace') {
when {
expression {
params.CLEAN_BUILD == 'true'
return !params.CLEAN_BUILD && workspaceExists()
}
}
steps {
sh 'git clean -fdx'
sh 'rm -rf buildroot'
sh '. ci/download-workspace.sh'
}
}
stage('Prepare') {
steps {
sh '. ci/prepare.sh'
}
}
stage('Build') {
steps {
sh '. ci/build.sh'
}
post {
success {
dir('_build/images') {
archiveArtifacts 'sdcard.img'
}
}
post {
always {
script {
if (params.KEEP_WORKSPACE) {
withCredentials([usernameColonPassword(
credentialsId: 'jenkins-gitea',
variable: 'GITEA_AUTH',
)]) {
sh '. ci/upload-workspace.sh'
}
}
}

View File

@@ -1,27 +1,4 @@
#!/bin/sh
BUILDROOT_REPO=https://gitlab.com/buildroot.org/buildroot.git
BUILDROOT_BRANCH=2025.05.x
DEFCONFIG=kitchenos_defconfig
if [ ! -d buildroot ]; then
git clone "${BUILDROOT_REPO}" --depth=1 -b "${BUILDROOT_BRANCH}"
else
git -C buildroot fetch --depth=1 origin "${BUILDROOT_BRANCH}"
git -C buildroot checkout -f "${BUILDROOT_BRANCH}"
git -C buildroot merge FETCH_HEAD --ff-only
fi
sed -i \
-e /BR2_LINUX_KERNEL_CUSTOM_TARBALL/a"$(
grep BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION= buildroot/configs/raspberrypi3_defconfig
)" \
-e /BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION/d \
configs/"${DEFCONFIG}"
if [ ! -f _build/.config ]; then
make -C buildroot O="${PWD}"/_build BR2_EXTERNAL="${PWD}" "${DEFCONFIG}"
fi
make -C _build BR2_JLEVEL=4
make -C _build toolchain
#make -C _build BR2_JLEVEL=$(($(nproc) / 2))

5
ci/download-workspace.sh Normal file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
rm -rf _build
mkdir _build
curl -fL "${SAVED_WORKSPACE_URL}" | tar -C _build -xz

27
ci/prepare.sh Normal file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
BUILDROOT_REPO=https://gitlab.com/buildroot.org/buildroot.git
BUILDROOT_BRANCH=2025.05.x
DEFCONFIG=kitchenos_defconfig
if [ ! -d buildroot ]; then
git clone "${BUILDROOT_REPO}" --depth=1 -b "${BUILDROOT_BRANCH}"
else
git -C buildroot fetch --depth=1 origin "${BUILDROOT_BRANCH}"
git -C buildroot checkout -f "${BUILDROOT_BRANCH}"
git -C buildroot merge FETCH_HEAD --ff-only
fi
sed -i \
-e /BR2_LINUX_KERNEL_CUSTOM_TARBALL/a"$(
grep BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION= buildroot/configs/raspberrypi3_defconfig
)" \
-e /BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION/d \
configs/"${DEFCONFIG}"
if [ ! -f _build/.config ]; then
make -C buildroot O="${PWD}"/_build BR2_EXTERNAL="${PWD}" "${DEFCONFIG}"
else
make -C _build "${DEFCONFIG}"
fi

15
ci/upload-workspace.sh Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
package_name=${JOB_NAME#*/}
package_name=${package_name%%/*}-workspace
tar -czf workspace.tar.gz -C _build \
build \
host \
staging \
target \
Makefile
curl -u "${GITEA_AUTH}" \
"https://git.pyrocufflink.net/api/packages/jenkins/generic/${package_name}/${BUILD_NUMBER}/workspace.tar.gz"
--upload-file workspace.tar.gz