]> git.ipfire.org Git - location/libloc.git/commitdiff
jenkins: Initial import
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 6 Mar 2025 11:42:50 +0000 (11:42 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 6 Mar 2025 11:42:50 +0000 (11:42 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Jenkinsfile [new file with mode: 0644]

diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644 (file)
index 0000000..6614a69
--- /dev/null
@@ -0,0 +1,662 @@
+pipeline {
+       agent none
+
+       stages {
+               /*
+                       Run the build and test suite on various distributions...
+               */
+               stage("Run Tests on Multiple Distributions") {
+                       matrix {
+                               axes {
+                                       axis {
+                                               name "DISTRO"
+                                               values \
+                                                       "archlinux:base-devel", \
+                                                       "debian:trixie", \
+                                                       "debian:bookworm", \
+                                                       "fedora:41", \
+                                                       "fedora:42", \
+                                                       "ubuntu:24.10", \
+                                                       "ubuntu:25.04"
+                                       }
+
+                                       axis {
+                                               name "COMPILER"
+                                               values "gcc", "clang"
+                                       }
+                               }
+
+                               agent {
+                                       docker {
+                                               image "${DISTRO}"
+
+                                               // Run as root inside the containers to install dependencies
+                                               args "-u root"
+
+                                               customWorkspace "${JOB_NAME}/${BUILD_ID}/${env.DISTRO.replace(":", "-")}/${env.COMPILER}"
+                                       }
+                               }
+
+                               stages {
+                                       stage("Install Dependencies") {
+                                               steps {
+                                                       script {
+                                                               // Arch Linux
+                                                               if (env.DISTRO.contains("archlinux")) {
+                                                                       installBuildDepsArchLinux(env.DISTRO, env.COMPILER)
+
+                                                               // Fedora, etc.
+                                                               } else if (env.DISTRO.contains("fedora")) {
+                                                                       installBuildDepsRedHat(env.DISTRO, env.COMPILER)
+
+                                                               // Debian & Ubuntu
+                                                               } else if (env.DISTRO.contains("debian") || env.DISTRO.contains("ubuntu")) {
+                                                                       installBuildDepsDebian(env.DISTRO, env.COMPILER, "amd64")
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       stage("Configure") {
+                                               steps {
+                                                       // Run autogen
+                                                       sh "./autogen.sh"
+
+                                                       // Run ./configure...
+                                                       sh "CC=${env.COMPILER} ./configure --prefix=/usr --enable-debug --enable-perl"
+                                               }
+
+                                               post {
+                                                       failure {
+                                                               archiveArtifacts artifacts: "config.log",
+                                                                       allowEmptyArchive: true
+
+                                                               echo "config.log has been archived"
+                                                       }
+                                               }
+                                       }
+
+                                       stage("Build") {
+                                               steps {
+                                                       sh "make"
+                                               }
+                                       }
+
+                                       stage("Check") {
+                                               steps {
+                                                       script {
+                                                               try {
+                                                                       sh "make check"
+                                                               } catch (Exception e) {
+                                                                       unstable("Failed on ${env.DISTRO} with ${env.COMPILER}...")
+                                                               }
+                                                       }
+                                               }
+
+                                               post {
+                                                       always {
+                                                               // Copy test logs into a special directory
+                                                               sh """
+                                                                       mkdir -pv tests/${DISTRO}/${COMPILER}
+                                                                       find tests -name "*.log" | xargs --no-run-if-empty \
+                                                                               cp --verbose --parents --target-directory=tests/${DISTRO}/${COMPILER}/
+                                                               """
+
+                                                               // Archive the logs only if the stage fails
+                                                               archiveArtifacts artifacts: "tests/${DISTRO}/${COMPILER}/**/*"
+
+                                                               echo "The test logs have been archived"
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Cleanup the workspace afterwards
+                               post {
+                                       always {
+                                               cleanWs()
+                                       }
+                               }
+                       }
+               }
+
+               stage("Coverage Tests") {
+                       parallel {
+                               stage("Address Sanitizer") {
+                                       agent {
+                                               docker {
+                                                       image "debian:trixie"
+
+                                                       // Run as root inside the containers to install dependencies
+                                                       args "-u root"
+
+                                                       customWorkspace "${JOB_NAME}/${BUILD_ID}/asan"
+                                               }
+                                       }
+
+                                       stages {
+                                               stage("Install Dependencies") {
+                                                       steps {
+                                                               script {
+                                                                       installBuildDepsDebian("trixie", "gcc", "amd64")
+                                                               }
+                                                       }
+                                               }
+
+                                               stage("Configure") {
+                                                       steps {
+                                                               sh "./autogen.sh"
+                                                               sh """
+                                                                       ./configure \
+                                                                               --prefix=/usr \
+                                                                               --enable-asan \
+                                                                               --enable-debug
+                                                               """
+                                                       }
+                                               }
+
+                                               stage("Build") {
+                                                       steps {
+                                                               sh "make -j\$(nproc)"
+                                                       }
+                                               }
+
+                                               stage("Check") {
+                                                       steps {
+                                                               script {
+                                                                       try {
+                                                                               sh "make check"
+                                                                       } catch (Exception e) {
+                                                                               unstable("Address Sanitizer checks failed")
+                                                                       }
+                                                               }
+                                                       }
+
+                                                       post {
+                                                               unstable {
+                                                                       // Copy test logs into a special directory
+                                                                       sh """
+                                                                               mkdir -pv asan
+                                                                               find tests -name "*.log" | xargs --no-run-if-empty \
+                                                                                       cp --verbose --parents --target-directory=asan/
+                                                                       """
+
+                                                                       // Archive the logs only if the stage fails
+                                                                       archiveArtifacts artifacts: "asan/**/*"
+
+                                                                       echo "The test logs have been archived"
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       // Cleanup the workspace afterwards
+                                       post {
+                                               always {
+                                                       cleanWs()
+                                               }
+                                       }
+                               }
+
+                               /*
+                                       Run Pakfire through Clang's Static Analyzer...
+                               */
+                               stage("Clang Static Analyzer") {
+                                       agent {
+                                               docker {
+                                                       image "debian:trixie"
+
+                                                       // Run as root inside the containers to install dependencies
+                                                       args "-u root"
+
+                                                       customWorkspace "${JOB_NAME}/${BUILD_ID}/clang-static-analyzer"
+                                               }
+                                       }
+
+                                       stages {
+                                               stage("Install Dependencies") {
+                                                       steps {
+                                                               script {
+                                                                       installBuildDepsDebian("trixie", "clang", "amd64")
+
+                                                                       // Install Clang Tools
+                                                                       sh "apt-get install -y clang-tools"
+                                                               }
+                                                       }
+                                               }
+
+                                               stage("Configure") {
+                                                       steps {
+                                                               sh "./autogen.sh"
+                                                               sh "scan-build ./configure --prefix=/usr --enable-debug"
+                                                       }
+                                               }
+
+                                               stage("Build") {
+                                                       steps {
+                                                               sh "scan-build -o scan-build-output make -j\$(nproc)"
+                                                       }
+                                               }
+
+                                               stage("Publish Report") {
+                                                       steps {
+                                                               archiveArtifacts artifacts: "scan-build-output/**/*"
+                                                       }
+                                               }
+                                       }
+
+                                       // Cleanup the workspace afterwards
+                                       post {
+                                               always {
+                                                       cleanWs()
+                                               }
+                                       }
+                               }
+
+                               stage("LCOV") {
+                                       agent {
+                                               docker {
+                                                       image "debian:bookworm"
+
+                                                       // Run as root inside the containers to install dependencies
+                                                       args "-u root"
+
+                                                       customWorkspace "${JOB_NAME}/${BUILD_ID}/lcov"
+                                               }
+                                       }
+
+                                       stages {
+                                               stage("Install Dependencies") {
+                                                       steps {
+                                                               script {
+                                                                       installBuildDepsDebian("bookworm", "gcc", "amd64")
+
+                                                                       // Install lcov
+                                                                       sh "apt-get install -y lcov"
+                                                               }
+                                                       }
+                                               }
+
+                                               stage("Configure") {
+                                                       steps {
+                                                               sh "./autogen.sh"
+                                                               sh """
+                                                                       ./configure \
+                                                                               --prefix=/usr \
+                                                                               --enable-coverage \
+                                                                               --enable-debug
+                                                               """
+                                                       }
+                                               }
+
+                                               stage("Build") {
+                                                       steps {
+                                                               sh "make -j\$(nproc)"
+                                                       }
+                                               }
+
+                                               stage("Check") {
+                                                       steps {
+                                                               sh "make check || true"
+                                                       }
+                                               }
+
+                                               stage("Publish Report") {
+                                                       steps {
+                                                               // Capture coverage data
+                                                               sh """
+                                                                       lcov \
+                                                                               --capture \
+                                                                               --directory . \
+                                                                               --output-file coverage.info
+                                                               """
+
+                                                               // Generate HTML report
+                                                               sh """
+                                                                       genhtml \
+                                                                               coverage.info \
+                                                                               --output-directory lcov
+                                                               """
+
+                                                               // Upload the report
+                                                               archiveArtifacts artifacts: "lcov/**/*"
+                                                       }
+                                               }
+                                       }
+
+                                       // Cleanup the workspace afterwards
+                                       post {
+                                               always {
+                                                       cleanWs()
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               stage("Debian Packages") {
+                       // Only build packages when we are in the master branch
+                       // when {
+                       //      expression {
+                       //              env.GIT_BRANCH == "origin/master"
+                       //      }
+                       // }
+
+                       stages {
+                               stage("Build Debian Packages") {
+                                       matrix {
+                                               axes {
+                                                       axis {
+                                                               name "IMAGE"
+                                                               values "debian:trixie", "debian:bookworm"
+                                                       }
+
+                                                       axis {
+                                                               name "ARCH"
+                                                               values "amd64", "arm64"
+                                                       }
+                                               }
+
+                                               agent {
+                                                       docker {
+                                                               image "${IMAGE}"
+
+                                                               // Run as root inside the containers to install dependencies
+                                                               args "-u root"
+
+                                                               customWorkspace "${JOB_NAME}/${BUILD_ID}/${IMAGE.replace(":", "-")}/${ARCH}"
+                                                       }
+                                               }
+
+                                               stages {
+                                                       stage("Setup Build Environment") {
+                                                               steps {
+                                                                       // Add the architecture
+                                                                       sh "dpkg --add-architecture ${env.ARCH}"
+                                                                       sh "apt-get update"
+
+                                                                       // Install required packages
+                                                                       sh """
+                                                                               apt-get install -y \
+                                                                                       apt-utils \
+                                                                                       build-essential \
+                                                                                       crossbuild-essential-${env.ARCH} \
+                                                                                       devscripts \
+                                                                                       qemu-user-static
+                                                                       """
+                                                               }
+                                                       }
+
+                                                       stage("Install Build Dependencies") {
+                                                               steps {
+                                                                       // Install all build dependencies
+                                                                       sh "apt-get build-dep -y -a${env.ARCH} ."
+                                                               }
+                                                       }
+
+                                                       stage("Tag") {
+                                                               steps {
+                                                                       sh "dch -m \"Jenkins Build ${BUILD_ID}\" -l .build-${BUILD_ID}."
+                                                               }
+                                                       }
+
+                                                       stage("Build") {
+                                                               environment {
+                                                                       VERSION = ""
+                                                               }
+
+                                                               steps {
+                                                                       // Create the source tarball from the checked out source
+                                                                       sh """
+                                                                               version="\$(dpkg-parsechangelog --show-field Version | sed "s/-[^-]*\$//")";
+                                                                               tar \
+                                                                                       --create \
+                                                                                       --verbose \
+                                                                                       --xz \
+                                                                                       --file="../libloc_\$version.orig.tar.xz" \
+                                                                                       --transform="s|^|libloc-\$version/|" \
+                                                                                       *
+                                                                       """
+
+                                                                       // Build the packages
+                                                                       sh """
+                                                                               dpkg-buildpackage \
+                                                                                       --host-arch ${env.ARCH} \
+                                                                                       --build=full
+                                                                       """
+                                                               }
+                                                       }
+
+                                                       stage("Create Repository") {
+                                                               environment {
+                                                                       DISTRO = "${IMAGE.replace("debian:", "")}"
+                                                               }
+
+                                                               steps {
+                                                                       // Create a repository and generate Packages
+                                                                       sh "mkdir -pv \
+                                                                               packages/debian/dists/${DISTRO}/main/binary-${ARCH} \
+                                                                               packages/debian/dists/${DISTRO}/main/source \
+                                                                               packages/debian/pool/${DISTRO}/main/${ARCH}"
+
+                                                                       // Copy all packages
+                                                                       sh "cp -v ../*.deb packages/debian/pool/${DISTRO}/main/${ARCH}"
+
+                                                                       // Generate Packages
+                                                                       sh "cd packages/debian && apt-ftparchive packages pool/${DISTRO}/main/${ARCH} \
+                                                                               > dists/${DISTRO}/main/binary-${ARCH}/Packages"
+
+                                                                       // Compress Packages
+                                                                       sh "xz -v9 < packages/debian/dists/${DISTRO}/main/binary-${ARCH}/Packages \
+                                                                               > packages/debian/dists/${DISTRO}/main/binary-${ARCH}/Packages.xz"
+
+                                                                       // Generate Sources
+                                                                       sh "cd packages/debian && apt-ftparchive sources pool/${DISTRO}/main/${ARCH} \
+                                                                               > dists/${DISTRO}/main/source/Sources"
+
+                                                                       // Compress Sources
+                                                                       sh "xz -v9 < packages/debian/dists/${DISTRO}/main/source/Sources \
+                                                                               > packages/debian/dists/${DISTRO}/main/source/Sources.xz"
+
+                                                                       // Generate Contents
+                                                                       sh "cd packages/debian && apt-ftparchive contents pool/${DISTRO}/main/${ARCH} \
+                                                                               > dists/${DISTRO}/main/Contents-${ARCH}"
+
+                                                                       // Compress Contents
+                                                                       sh "xz -v9 < packages/debian/dists/${DISTRO}/main/Contents-${ARCH} \
+                                                                               > packages/debian/dists/${DISTRO}/main/Contents-${ARCH}.xz"
+
+                                                                       // Stash the packages
+                                                                       stash includes: "packages/debian/**/*", name: "${DISTRO}-${ARCH}"
+                                                               }
+                                                       }
+                                               }
+
+                                               // Cleanup the workspace afterwards
+                                               post {
+                                                       always {
+                                                               cleanWs()
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               stage("Master Debian Repository") {
+                                       agent any
+
+                                       // We don't need to check out the source for this stage
+                                       options {
+                                               skipDefaultCheckout()
+                                       }
+
+                                       environment {
+                                               GNUPGHOME  = "${WORKSPACE}/.gnupg"
+                                               KRB5CCNAME = "${WORKSPACE}/.krb5cc"
+
+                                               // Our signing key
+                                               GPG_KEY_ID = "E4D20FA6FAA108D54ABDFC6541836ADF9D5E2AD9"
+                                       }
+
+                                       steps {
+                                               // Cleanup the workspace
+                                               cleanWs()
+
+                                               // Create the GPG stash directory
+                                               sh """
+                                                       mkdir -p $GNUPGHOME
+                                                       chmod 700 $GNUPGHOME
+                                               """
+
+                                               // Import the GPG key
+                                               withCredentials([file(credentialsId: "${env.GPG_KEY_ID}", variable: "GPG_KEY_FILE")]) {
+                                                       // Jenkins prefers to have single quotes here so that $GPG_KEY_FILE won't be expanded
+                                                       sh 'gpg --import --batch < $GPG_KEY_FILE'
+                                               }
+
+                                               // Unstash all stashed packages from the matrix build
+                                               script {
+                                                       for (distro in ["trixie", "bookworm"]) {
+                                                               for (arch in ["amd64", "arm64"]) {
+                                                                       unstash "${distro}-${arch}"
+                                                               }
+
+                                                               // Create the Release file
+                                                               sh """
+                                                                       (
+                                                                               echo "Origin: Pakfire Repository"
+                                                                               echo "Label: Pakfire Repository"
+                                                                               echo "Suite: stable"
+                                                                               echo "Codename: $distro"
+                                                                               echo "Version: 1.0"
+                                                                               echo "Architectures: amd64 arm64"
+                                                                               echo "Components: main"
+                                                                               echo "Description: Pakfire Jenkins Repository"
+
+                                                                               # Do the rest automatically
+                                                                               cd packages/debian && apt-ftparchive release dists/$distro
+                                                                       ) >> packages/debian/dists/$distro/Release
+                                                               """
+
+                                                               // Create InRelease
+                                                               sh """
+                                                                       gpg --batch \
+                                                                               --clearsign \
+                                                                               --local-user ${env.GPG_KEY_ID} \
+                                                                               --output packages/debian/dists/$distro/InRelease \
+                                                                               packages/debian/dists/$distro/Release
+                                                               """
+
+                                                               // Create Release.gpg
+                                                               sh """
+                                                                       gpg --batch \
+                                                                               --armor \
+                                                                               --detach-sign \
+                                                                               --local-user ${env.GPG_KEY_ID} \
+                                                                               --output packages/debian/dists/$distro/Release.gpg \
+                                                                               packages/debian/dists/$distro/Release
+                                                               """
+                                                       }
+                                               }
+
+                                               // Export the public key
+                                               sh "gpg --batch --export --armor ${env.GPG_KEY_ID} \
+                                                       > packages/debian/${env.GPG_KEY_ID}.asc"
+
+                                               // Remove the GPG key material as soon as possible
+                                               sh "rm -rf $GNUPGHOME"
+
+                                               // Upload everything again
+                                               archiveArtifacts artifacts: "packages/debian/**/*"
+
+                                               // Fetch a Kerberos ticket
+                                               withCredentials([file(credentialsId: "jenkins.keytab", variable: "KEYTAB")]) {
+                                                       sh 'kinit -kV -t $KEYTAB jenkins@IPFIRE.ORG'
+                                               }
+
+                                               // Publish files
+                                               sh """
+                                                       rsync \
+                                                               --verbose \
+                                                               --recursive \
+                                                               --delete \
+                                                               --delete-excluded \
+                                                               --delay-updates \
+                                                               packages/debian/ \
+                                                               pakfire@fs01.haj.ipfire.org:/pub/mirror/packages/debian/libloc
+                                               """
+
+                                               // Destroy the Kerberos credentials
+                                               sh "kdestroy"
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+// Installs everything we need on RHEL/Fedora/etc.
+def installBuildDepsRedHat(distro, compier) {
+       // Install basic development tools
+       sh "dnf group install -y development-tools"
+
+       // Install our own build and runtime dependencies
+       sh """
+               dnf install -y \
+                       asciidoc \
+                       autoconf \
+                       automake \
+                       intltool \
+                       libtool \
+                       pkg-config \
+                       ${compiler} \
+                       \
+                       openssl-devel \
+                       perl-devel \
+                       python3-devel \
+                       systemd-devel
+       """
+}
+
+// Installs everything we need on Arch Linux
+def installBuildDepsArchLinux(distro, compiler) {
+       sh "pacman -Syu --noconfirm"
+       sh """
+               pacman -Sy \
+                       --needed \
+                       --noconfirm \
+                       asciidoc \
+                       autoconf \
+                       automake \
+                       intltool \
+                       libtool \
+                       pkg-config \
+                       ${compiler} \
+                       \
+                       openssl \
+                       perl \
+                       python3 \
+                       systemd
+       """
+}
+
+// Installs everything we need on Debian
+def installBuildDepsDebian(distro, compiler, arch) {
+       sh "apt-get update"
+       sh """
+               apt-get install -y \
+                       --no-install-recommends \
+                       asciidoc \
+                       autoconf \
+                       automake \
+                       build-essential \
+                       intltool \
+                       libtool \
+                       pkg-config \
+                       ${compiler} \
+                       \
+                       libperl-dev \
+                       libpython3-dev \
+                       libssl-dev \
+                       libsystemd-dev
+       """
+}