def nativeBuildAgent(String platform, Closure body) {
def final nativeBuildStageName = 'Build SWT-native binaries'
if(platform == 'gtk.linux.x86_64') {
return podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: "swtbuild"
image: "eclipse/platformreleng-centos-swt-build:8"
imagePullPolicy: "Always"
resources:
limits:
memory: "4096Mi"
cpu: "2000m"
requests:
memory: "512Mi"
cpu: "1000m"
command:
- cat
tty: true
volumeMounts:
- name: tools
mountPath: /opt/tools
volumes:
- name: tools
persistentVolumeClaim:
claimName: tools-claim-jiro-releng
''') { node(POD_LABEL) { stage(nativeBuildStageName) { container('swtbuild') { body() } } } }
} else {
return node('swt.natives-' + platform) { stage(nativeBuildStageName) { body() } }
}
}
/** Returns the download URL of the JDK against whoose C headers (in the 'include/' folder) and native libaries the SWT natives are compiled.*/
def getNativeJdkUrl(String os, String arch){ // To update the used JDK version update the URL template below
return "https://download.eclipse.org/justj/jres/17/downloads/20230428_1804/org.eclipse.justj.openjdk.hotspot.jre.minimal.stripped-17.0.7-${os}-${arch}.tar.gz"
}
pipeline {
options {
skipDefaultCheckout() // Specialiced checkout is performed below
timestamps()
timeout(time: 180, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr:'5'))
disableConcurrentBuilds(abortPrevious: true)
}
agent {
label 'centos-latest'
}
environment {
MAVEN_OPTS = "-Xmx4G"
PR_VALIDATION_BUILD = "true"
}
parameters {
booleanParam(name: 'forceNativeBuilds', defaultValue: false, description: 'Forces to run the native builds of swt\'s binaries. Useful in debugging.')
booleanParam(name: 'skipCommit', defaultValue: false, description: 'Stops committing to swt and swt binaries repo at the end. Useful in debugging.')
}
stages {
stage('Checkout swt git repos') {
steps {
dir ('eclipse.platform.swt') {
checkout scm
script {
def authorMail = sh(script: 'git log -1 --pretty=format:"%ce" HEAD', returnStdout: true)
echo 'HEAD commit author: ' + authorMail
if ('eclipse-releng-bot@eclipse.org'.equals(authorMail)) {
// Prevent endless build-loops due to self triggering because of a previous automated build of SWT-natives and the associated updates.
currentBuild.result = 'ABORTED'
error('Abort build only triggered by automated SWT-natives update.')
}
}
sh '''
git fetch --all --tags --quiet
git remote set-url --push origin git@github.com:eclipse-platform/eclipse.platform.swt.git
'''
}
dir ('eclipse.platform.swt.binaries') {
checkout([$class: 'GitSCM', branches: [[name: 'refs/heads/master']],
extensions: [[$class: 'CloneOption', timeout: 120, noTags: false ]],
userRemoteConfigs: [[url: 'https://github.com/eclipse-platform/eclipse.platform.swt.binaries.git']]
])
sh 'git remote set-url --push origin git@github.com:eclipse-platform/eclipse.platform.swt.binaries.git'
}
}
}
stage('Check if SWT-binaries build is needed') {
steps {
withAnt(installation: 'apache-ant-latest', jdk: 'openjdk-jdk11-latest') { // nashorn javascript-engine required in ant-scripts
sh'''
java -version
git config --global user.email 'eclipse-releng-bot@eclipse.org'
git config --global user.name 'Eclipse Releng Bot'
ant -f eclipse.platform.swt/bundles/org.eclipse.swt/buildSWT.xml check_sources_and_update_sha1_file -DTAG=HEAD
ant -f eclipse.platform.swt/bundles/org.eclipse.swt/buildSWT.xml new_build_with_create_file -DTAG=HEAD
'''
}
}
}
stage('Build SWT-binaries, if needed') {
when {
anyOf {
expression { return params.forceNativeBuilds }
expression { return fileExists ('tmp/build_changed.txt') && fileExists ('tmp/natives_changed.txt') }
}
}
matrix {
axes {
axis {
name 'PLATFORM'
values 'cocoa.macosx.aarch64' , 'cocoa.macosx.x86_64', 'gtk.linux.aarch64', 'gtk.linux.ppc64le', 'gtk.linux.x86_64', 'win32.win32.x86_64'
}
}
stages {
stage("Collect SWT-native's sources") {
steps {
dir('eclipse.platform.swt.binaries/bundles'){
withAnt(installation: 'apache-ant-latest', jdk: 'openjdk-jdk11-latest') { // nashorn javascript-engine required in ant-scripts
sh '''
pfSpec=(${PLATFORM//"."/ })
ant -f binaries-parent/build.xml copy_library_src_and_create_zip -Dws=${pfSpec[0]} -Dos=${pfSpec[1]} -Darch=${pfSpec[2]}
'''
}
dir("org.eclipse.swt.${PLATFORM}/tmpdir") {
stash name:"swt.binaries.sources.${PLATFORM}", includes: "org.eclipse.swt.${PLATFORM}.master.zip"
}
}
}
}
stage('Build SWT-natives') {
options {
timeout(time: 120, unit: 'MINUTES') // Some build agents are rare and it might take awhile until they are available.
}
steps {
script {
def (ws, os, arch) = env.PLATFORM.split('\\.')
dir("jdk-download-${os}.${arch}") {
// Fetch the JDK, which provides the C header-files and shared native libaries, against which the natives are build.
sh "curl ${getNativeJdkUrl(os, arch)} | tar -xzf - include/ lib/"
stash name:"jdk.resources.${os}.${arch}", includes: "include/,lib/"
deleteDir()
}
nativeBuildAgent("${PLATFORM}") {
cleanWs() // Workspace is not cleaned up by default, so we do it explicitly
echo "OS: ${os}"
echo "ARCH: ${arch}"
unstash "swt.binaries.sources.${PLATFORM}"
dir('jdk.resources') {
unstash "jdk.resources.${os}.${arch}"
}
// TODO: don't zip the sources and just (un)stash them unzipped! That safes the unzipping and removal of the the zip
withEnv(['MODEL=' + arch, "OUTPUT_DIR=${WORKSPACE}/libs", "SWT_JAVA_HOME=${WORKSPACE}/jdk.resources"]) {
if(isUnix()){
sh '''
unzip -aa org.eclipse.swt.${PLATFORM}.master.zip
rm org.eclipse.swt.${PLATFORM}.master.zip
mkdir libs
sh build.sh install
ls -1R libs
'''
} else {
withEnv(['PATH=C:\\tools\\cygwin\\bin;' + env.PATH]) {
bat '''
unzip org.eclipse.swt.%PLATFORM%.master.zip
rm org.eclipse.swt.%PLATFORM%.master.zip
mkdir libs
cmd /c build.bat x86_64 all install
ls -1R libs
'''
}
}
}
dir('libs') {
stash "swt.binaries.${PLATFORM}"
}
}
}
}
}
stage('Collect and sign binaries') {
steps {
dir("libs/${PLATFORM}") {
unstash "swt.binaries.${PLATFORM}"
sh '''#!/bin/bash -x
fn-sign-files()
{
extension=$1
signingServiceAddress=$2
if [[ "${BRANCH_NAME}" == master ]] || [[ "${BRANCH_NAME}" =~ R[0-9]+_[0-9]+(_[0-9]+)?_maintenance ]]; then
for filename in $(ls *.${extension})
do
mv ${filename} unsigned-${filename}
curl -f -o ${filename} -F file=@unsigned-${filename} $signingServiceAddress
if [[ $? != 0 ]]; then
echo "Signing of ${filename} failed"
exit 1
else
rm unsigned-${filename}
fi
done
fi
}
binaryFragmentsRoot=${WORKSPACE}/eclipse.platform.swt.binaries/bundles
if [[ ${PLATFORM} == cocoa.macosx.* ]]; then
#TODO: Instead use (with adjusted URL): https://github.com/eclipse-cbi/org.eclipse.cbi/tree/main/maven-plugins/eclipse-winsigner-plugin
# The mac-signer mojo only works for Mac-applications and not for jnilib files, but the winsigner-plugin with adjusted URL seems to do what we want.
echo "Sign ${PLATFORM} libraries"
fn-sign-files jnilib https://cbi.eclipse.org/macos/codesign/sign
cp *.jnilib ${binaryFragmentsRoot}/org.eclipse.swt.${PLATFORM}/
elif [[ ${PLATFORM} == gtk.linux.* ]]; then
#TODO: can the webkit handling be removed?!
#echo "Removing existing webkitextensions"
#rm -r ${binaryFragmentsRoot}/org.eclipse.swt.${PLATFORM}/webkit*/
#cp -r webkitextensions* ${binaryFragmentsRoot}/org.eclipse.swt.${PLATFORM}/
cp *.so ${binaryFragmentsRoot}/org.eclipse.swt.${PLATFORM}/
elif [[ ${PLATFORM} == win32.win32.* ]]; then
#TODO: Instead use: https://github.com/eclipse-cbi/org.eclipse.cbi/tree/main/maven-plugins/eclipse-winsigner-plugin
echo "Sign ${PLATFORM} libraries"
fn-sign-files dll https://cbi.eclipse.org/authenticode/sign
cp *.dll ${binaryFragmentsRoot}/org.eclipse.swt.${PLATFORM}/
fi
'''
}
}
}
}
}
}
stage('Commit SWT-native binaries, if build') {
when {
expression { return params.forceNativeBuilds || fileExists ('tmp/build_changed.txt') }
}
steps {
withAnt(installation: 'apache-ant-latest', jdk: 'openjdk-jdk11-latest') { // nashorn javascript-engine required in ant-scripts
//The maven build reads the git-history so we should have to commit the native-binaries before building
sh '''
pushd eclipse.platform.swt.binaries
git add --all *
echo "git status after add"
git status
popd
ant -f eclipse.platform.swt/bundles/org.eclipse.swt/buildInternal.xml write_qualifier -Dlib.dir=${WORKSPACE} -Dbuild_changed=true
ant -f eclipse.platform.swt/bundles/org.eclipse.swt/buildSWT.xml commit_poms_and_binaries
ant -f eclipse.platform.swt/bundles/org.eclipse.swt/buildSWT.xml tag_projects
pushd eclipse.platform.swt
git status
git log -p -2
popd
pushd eclipse.platform.swt.binaries
git status
git log -p -1
popd
'''
}
}
}
stage('Build') {
tools {
// Define tools only in this stage to not interfere with default environemts of SWT-natives build-agents
jdk 'openjdk-jdk17-latest'
maven 'apache-maven-latest'
}
steps {
xvnc(useXauthority: true) {
dir ('eclipse.platform.swt.binaries') {
sh '''
mvn install \
--batch-mode -Pbuild-individual-bundles -DforceContextQualifier=zzz \
-Dcompare-version-with-baselines.skip=true -Dmaven.compiler.failOnWarning=true
'''
}
dir ('eclipse.platform.swt') {
sh '''
mvn clean verify \
--batch-mode -DforkCount=0 \
-Dcompare-version-with-baselines.skip=false -Dmaven.compiler.failOnWarning=true \
-Dmaven.test.failure.ignore=true -Dmaven.test.error.ignore=true
'''
}
}
}
post {
always {
junit 'eclipse.platform.swt/tests/*.test*/target/surefire-reports/*.xml'
archiveArtifacts artifacts: '**/*.log,**/*.html,**/target/*.jar,**/target/*.zip'
discoverGitReferenceBuild referenceJob: 'eclipse.platform.swt/master'
recordIssues publishAllIssues: true, tools: [java(), mavenConsole(), javaDoc()]
}
}
}
stage('Push SWT-native binaries, if build') {
when {
expression { return params.forceNativeBuilds || fileExists ('tmp/build_changed.txt') }
}
steps {
sshagent(['github-bot-ssh']) {
script {
def newSWTNativesTag = null;
dir ('eclipse.platform.swt.binaries') {
newSWTNativesTag = sh(script: 'git describe --abbrev=0 --tags --match v[0-9][0-9][0-9][0-9]*', returnStdout: true).strip()
}
echo "newSWTNativesTag: ${newSWTNativesTag}"
sh """
# Check for the master-branch as late as possible to have as much of the same behaviour as possible
if [[ '${BRANCH_NAME}' == master ]] || [[ '${BRANCH_NAME}' =~ R[0-9]+_[0-9]+(_[0-9]+)?_maintenance ]]; then
if [[ ${params.skipCommit} != true ]]; then
#Don't rebase and just fail in case another commit has been pushed to the master/maintanance branch in the meantime
pushd eclipse.platform.swt
git push origin HEAD:refs/heads/${BRANCH_NAME}
git push origin refs/tags/${newSWTNativesTag}
popd
pushd eclipse.platform.swt.binaries
git push origin HEAD:refs/heads/${BRANCH_NAME}
git push origin refs/tags/${newSWTNativesTag}
popd
exit 0
else
echo Committing is skipped
fi
else
echo Skip pushing changes of native-binaries for branch '${BRANCH_NAME}'
fi
# The commits are not pushed. At least list them, so one can check if the result is as expected.
pushd eclipse.platform.swt
git log -n 2
popd
pushd eclipse.platform.swt.binaries
git log -n 2
popd
"""
}
}
}
}
}
}