1+ pipeline {
2+ options {
3+ disableConcurrentBuilds() // prevent concurrent updates of the same repository
4+ timestamps()
5+ skipDefaultCheckout()
6+ timeout(time: 15, unit: 'MINUTES')
7+ buildDiscarder(logRotator(numToKeepStr:'5'))
8+ }
9+ //TODO: move parameters to job definition
10+ parameters {
11+ string(name: 'repositoryPath', defaultValue: 'eclipse/updates/4.37-I-builds', description: "Relative repository path from https://download.eclipse.org/. E.g. 'eclipse/updates/4.37-I-builds'")
12+ string(name: 'add', defaultValue: 'I20250616-1800', description: 'Comma separated list of children to add. May be empty')
13+ string(name: 'remove', description: 'Comma separated list of children to remove. May be empty')
14+ string(name: 'sizeLimit', defaultValue: '3', description: 'The maximum number of childrem of the modified composite. If the')
15+ }
16+ agent {
17+ label 'ubuntu-2404'
18+ }
19+ tools {
20+ jdk 'temurin-jdk21-latest'
21+ //TODO: try to use a Tycho eclipse-run task! and just use the releng-aggr parent as file and only run the eclipserun goal.
22+ // This would also solve the question how to get the eclipse platform product
23+ }
24+ environment {
25+ //TODO: use latest release automatically? How to determine the version?
26+ ECLIPSE_EXE = installLatestReleasedEclipsePlatformProduct()
27+ }
28+ stages {
29+ stage('Check Composites Validity') {
30+ steps {
31+ sh '''
32+ repository="https://download.eclipse.org/${repositoryPath}"
33+ echo "Validate consistency of content at: ${repository}"
34+ ${ECLIPSE_EXE} -nosplash -consolelog --launcher.suppressErrors -application org.eclipse.equinox.p2.director -repository "${repository}" -list
35+ '''
36+ }
37+ }
38+ stage('Update composite repository') {
39+ environment {
40+ ANT_TASK_NAME = 'modifyComposite'
41+ OUTPUT_PATH = './output-repository'
42+ }
43+ steps {
44+ script {
45+ //TODO: test this with the empty template repository
46+ //TODO: copy this via SSH to avoid caching issues.
47+ sh "curl -o compositeArtifacts.jar https://download.eclipse.org/${repositoryPath}/compositeArtifacts.jar"
48+ def childenXPathSet = sh(script: '''#!/bin/sh +xe
49+ unzip -p compositeArtifacts.jar compositeArtifacts.xml |\
50+ xmllint - --xpath '/repository/children/child/@location'
51+ exit 0
52+ ''', returnStdout: true).trim()
53+ def compositeChildren = 'XPath set is empty' == childenXPathSet ? []
54+ : parseList(childenXPathSet, '\\s+')
55+ .collect{c -> c.startsWith('location="') && c.endsWith('"') ? c.substring(10, c.length() - 1) : null}
56+ .findAll{c -> c != null}
57+
58+ echo "Current children: ${compositeChildren}"
59+ def toAdd = parseList(params.add, ',').unique()
60+ def toRemove = parseList(params.remove, ',').unique()
61+ toRemove = toRemove.findAll{e -> compositeChildren.contains(e)}
62+
63+ if (params.sizeLimit) {
64+ def sizeRestrictionRemovals = compositeChildren.size() + toAdd.size() - toRemove.size() - Integer.parseInt(params.sizeLimit)
65+ if (sizeRestrictionRemovals > 0) {
66+ toRemove += compositeChildren.subList(0, sizeRestrictionRemovals)
67+ }
68+ }
69+ echo "Children added: ${toAdd}"
70+ echo "Children removed: ${toRemove}"
71+ if (compositeChildren.size() + toAdd.size() - toRemove.size() == 0) {
72+ error('All children are removed and composite repository becomes empty.')
73+ }
74+ def modifyComposite_xml = """\
75+ <?xml version="1.0" encoding="UTF-8"?>
76+ <project default="${ANT_TASK_NAME}" basedir=".">
77+ <target name="${ANT_TASK_NAME}">
78+ <p2.composite.repository>
79+ <source location="https://download.eclipse.org/${repositoryPath}" />
80+ <repository location="${OUTPUT_PATH}" />
81+ """.stripIndent() //FIXME: check if the local path works as desired
82+ for (child in toAdd) {
83+ modifyComposite_xml += """ <add><repository location="${child}"/></add>\n"""
84+ }
85+ for (child in toRemove) {
86+ modifyComposite_xml += """ <remove><repository location="${child}"/></remove>\n"""
87+ }
88+ modifyComposite_xml+= '''\
89+ </p2.composite.repository>
90+ </target>
91+ </project>
92+ '''.stripIndent()
93+ writeFile(file: "${ANT_TASK_NAME}.xml", text: modifyComposite_xml)
94+
95+ sh '''
96+ ${ECLIPSE_EXE} -nosplash -consolelog --launcher.suppressErrors -debug -data ./eclipse-ws \
97+ -application org.eclipse.ant.core.antRunner -file "${ANT_TASK_NAME}.xml" "${ANT_TASK_NAME}"
98+ '''
99+ sshagent(['projects-storage.eclipse.org-bot-ssh']) {
100+ sh '''
101+ epDownloadsDir='/home/data/httpd/download.eclipse.org'
102+ echo -r "${OUTPUT_PATH}" "
[email protected] :${epDownloadsDir}/${repositoryPath}"
103+ #TODO: activate copying
104+ #scp -r "${OUTPUT_PATH}" "
[email protected] :${epDownloadsDir}/${repositoryPath}"
105+ '''
106+ }
107+ }
108+ }
109+ }
110+ }
111+ post {
112+ always {
113+ archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: 'tools/**/*'
114+ }
115+ }
116+ }
117+
118+ @NonCPS
119+ def parseList(String str, String delimiterPattern) {
120+ return str !=null && !str.trim().isEmpty() ? str.trim().split(delimiterPattern).collect{c -> c.trim()} : []
121+ }
122+
123+ def installLatestReleasedEclipsePlatformProduct() {
124+ sh 'curl -o buildproperties.txt https://download.eclipse.org/eclipse/relengScripts/cje-production/buildproperties.txt'
125+ def eclipseURL = sh(script: '''#!/bin/sh +xe
126+ source ./buildproperties.txt
127+ #TODO: Remove this after the next release!
128+ PREVIOUS_RELEASE_ID='I20250630-1800'
129+ PREVIOUS_RELEASE_VER='I20250630-1800'
130+ echo "https://download.eclipse.org/eclipse/downloads/drops4/${PREVIOUS_RELEASE_ID}/eclipse-platform-${PREVIOUS_RELEASE_VER}-linux-gtk-x86_64.tar.gz"
131+ ''', returnStdout: true).trim()
132+ return install('eclipse-platform', eclipseURL) + '/eclipse'
133+ }
134+
135+ def install(String toolType, String url) {
136+ dir("${WORKSPACE}/tools/${toolType}") {
137+ sh "curl -L ${url} | tar -xzf -"
138+ return "${pwd()}/" + sh(script: 'ls', returnStdout: true).trim()
139+ }
140+ }
0 commit comments