Skip to content

Commit 20b395c

Browse files
committed
Migrate website from PHP to plain HTML with Java-Script and markdown
Create json files with all variables and define custom html tags that a java-script replaces on the client TODO: - Complete the testsResults.html page - The buildLogs.html page is not implemented, but mostly just listing log files - The testLogs.html page is not implemented, but mostly just listing log files - Generate TOC for non markdown files. Decide if we want to use the plain/simple or 'high-constrast' style - Fully discard markdown files - Complete generation of data files in the build - Implement Equinox page too - Clean-up of unused elements - Delete testresults folder to not keep them forever - Delete old website files - Replace images with high-res/svg icons (for later) Fixes #2656
1 parent bfc4fe8 commit 20b395c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2476
-115
lines changed

.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<type>30</type>
1616
<matcher>
1717
<id>org.eclipse.ui.ide.multiFilter</id>
18-
<arguments>1.0-projectRelativePath-matches-true-true-(eclipse.platform.releng.prereqs.sdk|eclipse.platform.releng.tychoeclipsebuilder|oomph|products|sites)/.*</arguments>
18+
<arguments>1.0-projectRelativePath-matches-true-true-(eclipse.platform.releng.prereqs.sdk|eclipse.platform.releng.tychoeclipsebuilder|oomph|products|scripts|sites)/.*</arguments>
1919
</matcher>
2020
</filter>
2121
</filteredResources>

JenkinsJobs/AutomatedTests/integrationTests.jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pipeline {
109109
scp -r ${localResultsDirectory}/* [email protected]:${remoteResultsDirectory}
110110
# Download the result summary directly to the storage server
111111
112-
curl --fail --location --output "${remoteResultsDirectory}/${JOB_BASE_NAME}.xml" "${BUILD_URL}/testReport/api/xml?tree=failCount,passCount,skipCount,duration"
112+
curl --fail --location --output "${remoteResultsDirectory}/${JOB_BASE_NAME}.xml" "${BUILD_URL}/testReport/api/json?tree=failCount,passCount,skipCount,duration"
113113
fi
114114
'''
115115
}

JenkinsJobs/Builds/build.jenkinsfile

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -168,31 +168,38 @@ pipeline {
168168
}
169169
// Git log creation
170170
sh '''#!/bin/bash -xe
171-
reportTimestamp=$(TZ="America/New_York" date +%Y%m%d-%H%M)
171+
reportTimestamp=$(TZ='UTC' date +%Y%m%d-%H%M)
172172
export lastTag=$(cat "${WORKSPACE}/lastTag")
173173
if [[ -n "$lastTag" ]]; then
174-
export gitLogFile="${DROP_DIR}/$BUILD_ID/gitLog.html"
174+
export gitLogFile="${DROP_DIR}/$BUILD_ID/gitLog.json"
175175
mkdir -p $(dirname "${gitLogFile}")
176176

177-
echo -e "<h2>Git log from $lastTag (previous) to $BUILD_ID (current)</h2>" > $gitLogFile
178-
echo -e "<h2>The tagging, and this report, were done at about $reportTimestamp</h2>" >> $gitLogFile
177+
echo '{' > $gitLogFile
178+
echo "\\"label\\": \\"${BUILD_ID}\\"," >> $gitLogFile
179+
echo "\\"logFrom\\": \\"${lastTag}\\"," >> $gitLogFile
180+
echo "\\"logTo\\": \\"${BUILD_ID}\\"," >> $gitLogFile
181+
echo "\\"timestamp\\": \\"${reportTimestamp}\\"," >> $gitLogFile
182+
echo "\\"repositories\\": [" >> $gitLogFile >> $gitLogFile
179183

180184
function createGitLog() {
181185
gitURL=$(git config remote.origin.url | sed --expression 's,[email protected]:,https://github.com/,' | sed 's/\\.git$//')
182186
gitName="${gitURL##*/}"
183-
gitLog=$(git log $lastTag..$BUILD_ID --date=short --format=format:"<tr><td class=\"datecell\">%cd</td><td class=\"commitcell\"><a href=\"${gitURL}/commit/%H\">%s</a></td><td class=\"authorcell\">%aN</td></tr>")
187+
#TODO: handle potential double-quotes in commit message?
188+
gitLog=$(git log $lastTag..$BUILD_ID --date=short --format=format:"{ \\"date\\": \\"%cd\\", \\"message\\": \\"%s\\", \\"author\\": \\"%aN\\", \\"url\\": \\"${gitURL}/commit/%H\\"},")
184189
if [ -n "$gitLog" ]; then
185190
echo "Record changes in ${gitName}"
186-
echo "<table><tbody> <tr><th class=\"cell\" colspan=\"3\">Repository: ${gitName}</th></tr>" >> $gitLogFile
187-
echo "<tr> <th class=\"datecell\">Date</th> <th class=\"commitcell\">Commit message</th> <th class=\"authorcell\">Author</th> </tr>" >> $gitLogFile
188-
echo "${gitLog}" >> $gitLogFile
189-
echo "</tbody></table><br><br>" >> $gitLogFile
190-
echo '' >> $gitLogFile
191+
echo "{" >> $gitLogFile
192+
echo "\\"name\\": \\"${gitName}\\"," >> $gitLogFile
193+
echo "\\"commits\\": [" >> $gitLogFile
194+
echo "${gitLog%,}" >> $gitLogFile
195+
echo "]}," >> $gitLogFile
191196
fi
192197
}
193198
export -f createGitLog
194199
createGitLog
195200
git submodule foreach 'createGitLog'
201+
202+
echo "{}]}" >> $gitLogFile # Append empty object to keep JSON valid
196203
else
197204
echo -e "\n\tGit log not generated because a reasonable previous tag could not be found." > $gitLogFile
198205
fi
@@ -297,6 +304,9 @@ pipeline {
297304
stage('Eclipse') {
298305
stages {
299306
stage('Gather Eclipse parts') {
307+
tools {
308+
jdk 'temurin-jdk25-latest'
309+
}
300310
environment {
301311
KEYRING = credentials('secret-subkeys-releng.asc')
302312
KEYRING_PASSPHRASE = credentials('secret-subkeys-releng.asc-passphrase')
@@ -450,27 +460,46 @@ pipeline {
450460
cat $f
451461
done
452462

453-
# Publish Eclipse
454-
pushd $CJE_ROOT
455-
$BASE_BUILDER_ECLIPSE_EXE \
463+
pushd ${DROP_DIR}/${BUILD_ID}
464+
export client=eclipse
465+
bash ${ECLIPSE_BUILDER_DIR}/eclipse/extras/produceChecksum.sh
466+
popd
467+
468+
#TODO: call this like in tests directly and make eclipse.platform.releng.tychoeclipsebuilder/eclipse/helper.xml obsolete
469+
#triggering ant runner
470+
pushd ${EBuilderDir}/eclipse/publishingFiles
471+
$BASE_BUILDER_ECLIPSE_EXE -debug \
456472
-application org.eclipse.ant.core.antRunner \
457-
-buildfile $ECLIPSE_BUILDER_DIR/eclipse/helper.xml \
473+
-buildfile "${CJE_ROOT}/scripts/publish.xml" \
458474
-data $CJE_ROOT/$TMP_DIR/workspace-publish \
459-
-DAGGR_DIR=${AGG_DIR} \
460-
-DcjeDir=$CJE_ROOT \
461-
-DEBuilderDir=$ECLIPSE_BUILDER_DIR \
462475
-DbuildDirectory=${DROP_DIR}/${BUILD_ID} \
463-
-DbuildLabel=$BUILD_ID \
464-
-DbuildDir=$BUILD_ID \
465-
-DbuildRepo=$PLATFORM_REPO_DIR \
466-
-DbuildType=$BUILD_TYPE \
467-
-DpublishingContent=$ECLIPSE_BUILDER_DIR/eclipse/publishingFiles \
468-
-DindexFileName=index.php \
469-
-Djava.io.tmpdir=$CJE_ROOT/$TMP_DIR \
470-
-v \
471-
publish
472-
popd
476+
-DbuildType=${BUILD_TYPE} \
477+
"-DdropTemplateFileName=${ECLIPSE_BUILDER_DIR}/eclipse/publishingFiles/templateFiles/index.template.php" \
478+
"-DcompileLogsDirectoryName=${DROP_DIR}/${BUILD_ID}/compilelogs/plugins" \
479+
"-DindexFileName=index.php" \
480+
"-DmanifestFile=${WORKSPACE}/git-repo/eclipse.platform.releng.tychoeclipsebuilder/eclipse/publishingFiles/testManifest.xml" \
481+
"-DtestsConfigExpected=${TEST_CONFIGURATIONS_EXPECTED}" \
482+
generateIndex
483+
484+
# Prepare build drop website
485+
cp -r sites/eclipse/build-page/. ${DROP_DIR}/${BUILD_ID}
486+
java \
487+
-Ddirectory=${DROP_DIR}/${BUILD_ID} \
488+
scripts/releng/GenerateDropData.java mainEclipse
473489
'''
490+
script {
491+
//TODO: Necessary?
492+
def buildProperties = readBuildProperties("${CJE_ROOT}/buildproperties.properties")
493+
def utilities = load "JenkinsJobs/shared/utilities.groovy"
494+
dir("$CJE_ROOT/$DROP_DIR/$BUILD_IID") {
495+
//TODO: Remove this and call the Java script instead
496+
// def fileList = sh(script: "ssh [email protected] 'cd ${EP_ECLIPSE_DROPS}/I20251202-0300 && stat --format \"%n %s\" *'", returnStdout: true)
497+
def fileList = sh(script: 'stat --format "%n %s" *', returnStdout: true)
498+
def buildSiteProperties = generateSiteData(buildProperties, fileList)
499+
utilities.writeJSON("buildproperties.json", buildSiteProperties)
500+
}
501+
}
502+
474503
}
475504
}
476505
stage('Promote Eclipse') {
@@ -492,6 +521,9 @@ pipeline {
492521
stage('Equinox') {
493522
stages {
494523
stage('Gather Equinox parts') {
524+
tools {
525+
jdk 'temurin-jdk25-latest'
526+
}
495527
environment {
496528
KEYRING = credentials('secret-subkeys-releng.asc')
497529
KEYRING_PASSPHRASE = credentials('secret-subkeys-releng.asc-passphrase')
@@ -705,3 +737,23 @@ def exportPropertiesAsEnvironmentVariables(String propertiesFile, Collection<Str
705737
assignEnvVariable(envVar, value.startsWith('"') && value.endsWith('"') ? value.substring(1, value.length() - 1) : value)
706738
}
707739
}
740+
741+
@NonCPS
742+
def generateSiteData(Map<String, String> buildProperties, String fileList) {
743+
def files = fileList.split('\\R').collectEntries{ e -> e.split(' ') } //TODO: check for more than one space?
744+
def testConfigurations = buildProperties.TEST_CONFIGURATIONS_EXPECTED.split(',').collect{ c ->
745+
def config = c.split('-')
746+
return "${config[2]}-${config[3]}-${config[4].substring(0, config[4].indexOf('_'))}".toString()
747+
}
748+
return [ identifier: buildProperties.BUILD_ID, label: buildProperties.BUILD_ID,
749+
kind: buildProperties.BUILD_TYPE_NAME,
750+
release: buildProperties.STREAM, releaseShort: buildProperties.RELEASE_VER,
751+
expectedTests: testConfigurations,
752+
p2Repository: [ name: '', size: '' ],
753+
'eclipse-sdk-products': [ name: '', size: '' ],
754+
'eclipse-platform-products': [ name: '', size: '' ],
755+
'eclipse-tests': [ name: '', size: '' ],
756+
'jdt-compiler': [ name: '', size: '' ],
757+
'swt-binaries': [ name: '', size: '' ],
758+
]
759+
}

JenkinsJobs/Releng/promoteBuild.jenkinsfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ pipeline {
215215
-DnewPrevious-release.baseline="${RELEASE_P2_REPOSITORY}"
216216
'''
217217
utilities.replaceAllInFile('cje-production/buildproperties.txt', [
218-
'API_PREV_REF_LABEL=".*?"' : "API_PREV_REF_LABEL=\"${BUILD_MAJOR}.${BUILD_MINOR}\"",
219218
'PREVIOUS_RELEASE_VER=".*?"' : "PREVIOUS_RELEASE_VER=\"${BUILD_MAJOR}.${BUILD_MINOR}\"",
220219
'PREVIOUS_RELEASE_REPO_ID=".*?"' : "PREVIOUS_RELEASE_REPO_ID=\"${BUILD_MAJOR}.${BUILD_MINOR}\"",
221220
'BASEBUILD_ID=".*?"' : "BASEBUILD_ID=\"${DL_DROP_ID}\"",
@@ -371,11 +370,10 @@ EOF
371370
BUILD_ID: "${newBuildLabel}",
372371
BUILD_TYPE: "${DL_TYPE}",
373372
BUILD_TYPE_NAME: "${newTypeName}",
374-
BUILD_DIR_SEG: "${newDropID}",
375-
EQ_BUILD_DIR_SEG: "${newDropID}",
376373
]
377374
def buildPropertiesPHP = sh(returnStdout: true, script: "ssh [email protected] cat ${sourcePath}/buildproperties.php")
378375
for (entry in newProperties) {
376+
//TODO: update this to modify the buildproperties.json with the new names/labels and updated filenames/size(?)
379377
buildPropertiesPHP = buildPropertiesPHP.replaceFirst('\\$' + entry.key + ' = "[^"]+"', '\\$' + entry.key + ' = "' + entry.value + '"')
380378
}
381379
writeFile(file: 'buildproperties.php', text: buildPropertiesPHP)

JenkinsJobs/Releng/updateIndex.jenkinsfile

Lines changed: 165 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
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} [email protected]:/home/data/httpd/download.eclipse.org/eclipse/downloads/${HTML_PAGE}
71+
sh '''
72+
#TODO: adjust paths to real target
73+
rsync -avzh site/. [email protected]:${EP_ROOT}/eclipse/try-outs/eclipse/downloads/
2674
'''
75+
// FIXME: remove the following
76+
script {
77+
def fileList = sh(script: "ssh [email protected] 'cd ${EP_ECLIPSE_DROPS}/I20251201-1800 && stat --format \"%n %s\" *'", returnStdout: true)
78+
echo "fileList: ${fileList}"
79+
def buildProperties = readBuildProperties(sh(script: "ssh [email protected] '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
}

JenkinsJobs/Releng/updateTestResultIndex.jenkinsfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pipeline {
3131
}
3232
}
3333
}
34+
//TODO: can this job and all called (ANT) scripts become obsoelte?
3435
stage('Update test results'){
3536
environment {
3637
// Download Server locations (seldomly change)

0 commit comments

Comments
 (0)