| #!/usr/bin/env groovy |
| |
| List<String> getSupportedBoards() { |
| return [ |
| 'enterprise', |
| 'excelsior' |
| ] |
| } |
| |
| String generateDateStamp() { |
| def date = new Date() |
| return date.format("yyyyMMdd-HHmmss") |
| } |
| |
| String getLatestSnapshot(repository_stem) { |
| def script = """ |
| aptly snapshot list --sort=time --raw \ |
| | grep -E '^${repository_stem}-[0-9]' \ |
| | tail -n1 |
| """ |
| |
| return sh(returnStdout: true, script: script).trim() |
| } |
| |
| String getSnapshotFromPublish(releaseName, repoName, component) { |
| def script = "aptly publish show ${releaseName} filesystem:public:${repoName} | grep -E '^ ${component}: .*' | grep 'snapshot' | awk '{ print \$2 }'" |
| |
| return sh(returnStdout: true, script: script).trim() |
| } |
| |
| def installGpgKeyring() { |
| sh """ |
| install -d -m 700 -o root -g root /var/lib/aptly/.gnupg |
| tar -C /var/lib/aptly/.gnupg -zxf /var/lib/aptly/keyring/release-keyring.tar.gz |
| chown -R root:root /var/lib/aptly/.gnupg |
| find /var/lib/aptly/.gnupg -type d -exec chmod 700 '{}' ';' |
| find /var/lib/aptly/.gnupg -type f -exec chmod 600 '{}' ';' |
| """ |
| } |
| |
| def initSourceTree(boardName, needsNative = false) { |
| sh """ |
| /opt/gcompute-tools/git-cookie-authdaemon |
| |
| git config --global url.https://aiyprojects.googlesource.com/.insteadOf sso://aiyprojects/ |
| git config --global url.https://excelsior.googlesource.com/.insteadOf sso://excelsior/ |
| |
| mkdir -p .repo/local_manifests |
| mkdir -p cache |
| chmod 777 cache .repo/local_manifests |
| """ |
| |
| |
| timeout(time: 20, unit: 'MINUTES') { |
| checkout([$class: 'RepoScm', |
| currentBranch: true, |
| jobs: 24, |
| manifestRepositoryUrl: manifestUrlFromBoardName(boardName), |
| manifestBranch: 'master', |
| manifestFile: "${boardName}.xml", |
| manifestGroup: "default,internal", |
| depth: 1, |
| quiet: true]) |
| } |
| |
| // Bring in the pbuilder tarballs. |
| // |
| // archiveArtifacts includes the relative path to the |
| // files we archive, so we don't have to specify cache/ |
| // here in the target. |
| copyArtifacts(projectName: 'global.pbuilder.arm64', filter: '**/*.tgz') |
| copyArtifacts(projectName: 'global.pbuilder.armhf', filter: '**/*.tgz') |
| copyArtifacts(projectName: 'global.pbuilder.cross', filter: '**/*.tgz') |
| } |
| |
| def buildTarget(targetName) { |
| def nprocs = sh(returnStdout: true, script: 'nproc').trim() |
| sh "bash -c 'source build/setup.sh; m -j${nprocs} ${targetName}; exit \$?'" |
| } |
| |
| def manifestUrlFromBoardName(boardName) { |
| switch (boardName) { |
| case "excelsior": |
| case "enterprise": |
| return "http://coral.googlesource.com/manifest" |
| default: |
| error "Unknown board ${boardName}" |
| } |
| } |
| |
| def nameFromRepoType(repoType, boardName) { |
| if (repoType == "core") { |
| return "core" |
| } else if (repoType == "bsp") { |
| return "bsp-${boardName}" |
| } else { |
| error 'Unknown repoType ${repoType}' |
| } |
| } |
| |
| def uploadAllGeneratedPackages(repoType, boardName, packageNames, includeSources = true) { |
| def outPath = repoType |
| def repoName = nameFromRepoType(repoType, boardName) |
| def packageFilenames = [] |
| |
| echo "Packages to upload are: ${packageNames}" |
| |
| for (packageName in packageNames) { |
| def packages = findFiles(glob: "out/**/${packageName}*.deb") |
| def sources = [] |
| |
| if (includeSources == true) { |
| sources = findFiles(glob: "out/**/${packageName}*.dsc") |
| } |
| |
| def filenames = (packages + sources).each{entry -> entry.path} |
| packageFilenames.addAll(filenames) |
| } |
| |
| |
| if (packageFilenames.size() == 0) { |
| error 'No packages were found! Assuming failed build.' |
| } |
| |
| def date = new Date() |
| String stamp = date.format("yyyyMMdd-HHmmss") |
| |
| sh """ |
| aptly task run repo add -force-replace unstable-${repoName} ${packageFilenames.join(' ')}, \ |
| snapshot create unstable-${repoName}-${stamp} from repo unstable-${repoName} |
| """ |
| } |
| |
| def buildPackagePipeline(boardName, repoType, targetName, packageNames, needsNative = false, includeSources = true) { |
| def workspacePath = "/home/jenkins/agent/workspace" |
| def buildLabel = "${targetName}-${UUID.randomUUID().toString()}" |
| def sourcePath = "${workspacePath}/src" |
| |
| // FIXME(jtgans): Get rid of privileged! This is a security risk! |
| def jnlpContainer = containerTemplate(name: 'jnlp', |
| image: 'jenkins/jnlp-slave:alpine') |
| def debianContainer = containerTemplate(name: 'debian', |
| image: 'gcr.io/mendel-linux-cloud-infra/mendel-builder:latest', |
| command: 'cat', |
| args: '', |
| ttyEnabled: true, |
| privileged: true) |
| def aptlyVolume = persistentVolumeClaim(claimName: 'aptly-state', mountPath: '/var/lib/aptly') |
| |
| podTemplate(label: buildLabel, containers: [jnlpContainer, debianContainer], volumes: [aptlyVolume], envVars: []) { |
| node(buildLabel) { |
| dir(sourcePath) { |
| container('debian') { |
| stage('Init') { |
| initSourceTree(boardName, needsNative) |
| sh "bash -c 'source build/setup.sh; m prereqs; exit \$?'" |
| } |
| |
| stage('Build') { |
| buildTarget(targetName) |
| } |
| |
| stage('Deploy') { |
| sh 'ls ' |
| uploadAllGeneratedPackages(repoType, boardName, packageNames, includeSources) |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| String coreIsPublished(String releaseName) { |
| def script = "aptly publish list --raw |grep -E '^filesystem:public:${releaseName} ${releaseName}' || true" |
| String publishName = sh(returnStdout: true, script: script).trim() |
| return (publishName != "") |
| } |
| |
| String bspIsPublished(String releaseName, String boardName) { |
| def script = "aptly publish list --raw |grep -E '^filesystem:public:${releaseName}-bsp-${boardName} ${releaseName}' || true" |
| String publishName = sh(returnStdout: true, script: script).trim() |
| return (publishName != "") |
| } |