@@ -11,21 +11,177 @@ pipeline {
1111 agent {
1212 label 'basic'
1313 }
14+ environment {
15+ GIT_REPO = "${WORKSPACE}/git-repo"
16+ BUILD_SEPARATOR = 'BUILD_SEPARATOR'
17+ // Download server paths
18+ EP_ROOT = '/home/data/httpd/download.eclipse.org'
19+ EP_ECLIPSE_DROPS = "${EP_ROOT}/eclipse/downloads/drops4"
20+ EP_EQUINOX_DROPS = "${EP_ROOT}/equinox/drops"
21+ EP_ECLIPSE_UPDATES = "${EP_ROOT}/eclipse/updates"
22+ }
1423 stages {
15- stage('Update index'){
24+ stage('Update index') {
1625 steps {
26+ dir("${GIT_REPO}") {
27+ checkout scmGit(userRemoteConfigs: [[url: "${scm.userRemoteConfigs[0].url}"]], branches: [[name: "${scm.branches[0].name}"]],
28+ extensions: [cloneOption(depth: 1, shallow: true, noTags: true), sparseCheckout([
29+ [path: 'JenkinsJobs/shared/utilities.groovy'],
30+ [path: 'sites/eclipse'],
31+ ])])
32+ }
33+ sh '''
34+ # Collect files of the overview site
35+ mkdir site
36+ pushd site
37+ cp -r ${GIT_REPO}/sites/eclipse/overview-page/. .
38+ # Copy in common shared files located in the folder of the indivdual build page
39+ cp ${GIT_REPO}/sites/eclipse/build-page/page.css .
40+ cp ${GIT_REPO}/sites/eclipse/build-page/page.js .
41+ sed --in-place --expression='s|<script src="../build-page/page.js">|<script src="page.js">|g' index.html
42+ popd
43+ '''
44+ script {
45+ def utilities = load "${GIT_REPO}/JenkinsJobs/shared/utilities.groovy"
46+ def buildDropsData;
47+ sshagent(['projects-storage.eclipse.org-bot-ssh']) {
48+ buildDropsData = sh(script: """
49+ ssh genie.releng@projects-storage.eclipse.org '
50+ cd ${EP_ECLIPSE_DROPS}
51+ for drop in \$(ls); do
52+ if [ -d \${drop} ] && [ ! -f \${drop}/buildHidden ]; then
53+ echo "\${drop}"
54+ grep --count "expectedTestConfigs\\[]=" \${drop}/testConfigs.php
55+ grep --count "foundTestConfigs\\[]=" \${drop}/testConfigsFound.php || echo 0
56+ if [ -f \${drop}/buildUnstable ]; then
57+ echo 'unstable'
58+ fi
59+ echo "${BUILD_SEPARATOR}"
60+ fi
61+ done
62+ '
63+ """.stripIndent(), returnStdout: true)
64+ }
65+ // TODO: Replace this by Java script and capture the ssh output in file passed to the script?
66+ // The script could then also collect all the files?
67+ def overviewData = parseBuildDrops(buildDropsData)
68+ utilities.writeJSON('site/data.json', overviewData)
69+ }
1770 sshagent(['projects-storage.eclipse.org-bot-ssh']) {
18- sh '''#!/bin/bash -xe
19- PHP_PAGE="createIndex4x.php"
20- HTML_PAGE="index.html"
21- TEMP_INDEX="tempIndex.html"
22-
23- wget --no-verbose -O ${TEMP_INDEX} https://download.eclipse.org/eclipse/downloads/${PHP_PAGE} 2>&1
24-
25- scp ${TEMP_INDEX} genie.releng@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/eclipse/downloads/${HTML_PAGE}
71+ sh '''
72+ #TODO: adjust paths to real target
73+ rsync -avzh site/. genie.releng@projects-storage.eclipse.org:${EP_ROOT}/eclipse/try-outs/eclipse/downloads/
2674 '''
75+ // FIXME: remove the following
76+ script {
77+ def fileList = sh(script: "ssh genie.releng@projects-storage.eclipse.org 'cd ${EP_ECLIPSE_DROPS}/I20251201-1800 && stat --format \"%n %s\" *'", returnStdout: true)
78+ echo "fileList: ${fileList}"
79+ def buildProperties = readBuildProperties(sh(script: "ssh genie.releng@projects-storage.eclipse.org 'cat ${EP_ECLIPSE_DROPS}/I20251201-1800/buildproperties.properties'", returnStdout: true))
80+ echo "buildProperties: ${buildProperties}"
81+ def buildSiteProperties = generateSiteData(buildProperties, fileList)
82+ echo "buildSiteProperties: ${buildSiteProperties}"
83+ }
2784 }
2885 }
2986 }
3087 }
88+ post {
89+ always {
90+ archiveArtifacts artifacts: 'site/**/*'
91+ }
92+ }
93+ }
94+
95+ @NonCPS
96+ def parseBuildDrops(String buildDrops) {
97+ def releases = []
98+ def stableBuilds = []
99+ def iBuilds = []
100+ def yBuilds = []
101+ for (dropData in buildDrops.trim().split("BUILD_SEPARATOR")) {
102+ if (dropData.isEmpty()) {
103+ continue;
104+ }
105+ def dropDataElements = dropData.trim().split('\\s+')
106+ def String dropID = dropDataElements[0]
107+ def int testsExpected = Integer.parseInt(dropDataElements[1])
108+ def int testsFinished = Integer.parseInt(dropDataElements[2])
109+ def boolean isUnstable = dropDataElements.length > 3 && dropDataElements[3] == 'unstable'
110+ def boolean isOldStyleDrop = true
111+ def drop = [ path: "drops4/${dropID}".toString(), status: isUnstable ? 'unstable' : 'success' ]
112+ if (dropID.startsWith('R-')) {
113+ drop.label = dropID.substring(2, dropID.lastIndexOf('-'))
114+ drop.date = toUTCdateTime(dropID.substring(dropID.lastIndexOf('-') + 1))
115+ releases += drop
116+ } else if (dropID.startsWith('S-')) {
117+ drop.label = dropID.substring(2, dropID.lastIndexOf('-'))
118+ drop.date = toUTCdateTime(dropID.substring(dropID.lastIndexOf('-') + 1))
119+ stableBuilds += drop
120+ } else if (dropID.startsWith('I20')) {
121+ drop.label = dropID
122+ drop.date = toUTCdateTime(dropID.substring(1).replace('-', ''))
123+ iBuilds += drop
124+ } else if (dropID.startsWith('Y20')) {
125+ drop.label = dropID
126+ drop.date = toUTCdateTime(dropID.substring(1).replace('-', ''))
127+ yBuilds += drop
128+ }
129+ drop.testsCompletion = "${testsFinished} of ${testsExpected}".toString()
130+ drop.testsPath = isOldStyleDrop ? 'testResults.php' : 'testresults'
131+ }
132+ def overviewData = [releases: releases, stableBuilds: stableBuilds, iBuilds: iBuilds, yBuilds: yBuilds]
133+ overviewData.values().each{ list -> list.sort({d1, d2 -> -d1.label.compareTo(d2.label)})}
134+ // Select latest element among all releases, stable builds respectivly I-builds
135+ return overviewData
136+ }
137+
138+ @NonCPS
139+ def toUTCdateTime(String dateTime) {
140+ if (dateTime.length() != 12) {
141+ throw new IllegalArgumentException('Not an expected date-time string: ' + dateTime)
142+ }
143+ def int year = Integer.parseInt(dateTime.substring(0, 4))
144+ def int month = Integer.parseInt(dateTime.substring(4, 6))
145+ def int day = Integer.parseInt(dateTime.substring(6, 8))
146+ def int hour = Integer.parseInt(dateTime.substring(8, 10))
147+ def int minute = Integer.parseInt(dateTime.substring(10, 12))
148+ return java.time.LocalDateTime.of(year, month, day, hour, minute)
149+ .atZone(java.time.ZoneId.of("America/New_York"))
150+ .withZoneSameInstant(java.time.ZoneOffset.UTC)
151+ .toLocalDateTime().toString() + 'Z';
152+ }
153+
154+ // FIXME: remove the following
155+
156+ def readBuildProperties(String buildPropertiesFile) {
157+ return readProperties(text: buildPropertiesFile, charset: 'UTF-8').collectEntries{n, v ->
158+ v = v.trim();
159+ return [n, (v.startsWith('"') && v.endsWith('"') ? v.substring(1, v.length() - 1) : v)]
160+ }
161+ }
162+
163+ @NonCPS
164+ def generateSiteData(Map<String, String> buildProperties, String fileList) {
165+ def testPrefix = "ep${buildProperties.RELEASE_VER.replace('.', '')}I-unit-"
166+ def testConfigs = buildProperties.TEST_CONFIGURATIONS_EXPECTED.split(',').collect{ c ->
167+ def config = c.split('-')
168+ return "${config[2]}-${config[3]}-${config[4].substring(0, config[4].indexOf('_'))}"
169+ }
170+ echo "testConfigs: ${testConfigs}"
171+ def res = [ identifier: buildProperties.BUILD_ID, label: buildProperties.BUILD_ID,
172+ kind: buildProperties.BUILD_TYPE_NAME,
173+ release: buildProperties.STREAM, releaseShort: buildProperties.RELEASE_VER,
174+ expectedTests: buildProperties.TEST_CONFIGURATIONS_EXPECTED.split(',').collect{ c ->
175+ def config = c.split('-')
176+ return "${config[2]}-${config[3]}-${config[4].substring(0, config[4].indexOf('_'))}"
177+ },
178+ p2Repository: [ name: '', size: '' ],
179+ 'eclipse-sdk-products': [ name: '', size: '' ],
180+ 'eclipse-platform-products': [ name: '', size: '' ],
181+ 'eclipse-tests': [ name: '', size: '' ],
182+ 'jdt-compiler': [ name: '', size: '' ],
183+ 'swt-binaries': [ name: '', size: '' ],
184+ ]
185+ echo "res: ${res}"
186+ return res
31187}
0 commit comments