diff --git a/build/jenkins/dockerfiles/lint.Dockerfile b/build/jenkins/dockerfiles/lint.Dockerfile
new file mode 100644
index 0000000000..663faa3b65
--- /dev/null
+++ b/build/jenkins/dockerfiles/lint.Dockerfile
@@ -0,0 +1,23 @@
+FROM debian:bookworm-slim
+ARG DEBIAN_FRONTEND=noninteractive
+ARG DEBCONF_NOWARNINGS="yes"
+RUN useradd -ms /bin/bash --uid 1006 builder
+RUN apt-get -qq update && apt-get install -qqy --no-install-recommends \
+ python3-dev \
+ cppcheck \
+ git \
+ subversion \
+ libphutil \
+ php-cli \
+ php-curl \
+ curl \
+&& apt-get clean
+ENV SHELL /bin/bash
+WORKDIR "/home/builder"
+RUN curl -fsSLk https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh
+RUN chmod +x nodesource_setup.sh && ./nodesource_setup.sh && rm nodesource_setup.sh
+RUN apt install nodejs -qqy
+RUN npm install -g eslint@8.57.0 eslint-plugin-brace-rules
+USER builder
+RUN git clone https://github.com/phacility/arcanist.git ~/arcanist
+ENV PATH="${PATH}:~/arcanist/bin/"
diff --git a/build/jenkins/pipelines/docker-differential.Jenkinsfile b/build/jenkins/pipelines/docker-differential.Jenkinsfile
index a73e82d79a..6a7ac9f89e 100644
--- a/build/jenkins/pipelines/docker-differential.Jenkinsfile
+++ b/build/jenkins/pipelines/docker-differential.Jenkinsfile
@@ -1,27 +1,28 @@
-/* Copyright (C) 2022 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D. If not, see .
- */
+/* Copyright (C) 2024 Wildfire Games.
+* This file is part of 0 A.D.
+*
+* 0 A.D. is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* (at your option) any later version.
+*
+* 0 A.D. is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with 0 A.D. If not, see .
+*/
// This pipeline is used to build patches on various compilers.
-def compilers = ["gcc7", "clang7"]
+def compilers = ["gcc7", "clang8"]
def patchesMap = compilers.collectEntries {
["${it}": patch(it)]
}
+
def patch(compiler) {
return {
stage("Patch: ${compiler}") {
@@ -30,16 +31,31 @@ def patch(compiler) {
sh "arc patch --diff ${params.DIFF_ID} --force"
}
} catch(e) {
- sh "sudo zfs rollback zpool0/${compiler}@latest"
+ reset("${compiler}").call()
throw e
}
}
}
}
+def resetMap = compilers.collectEntries {
+ ["${it}": reset(it)]
+}
+
+def reset(compiler)
+{
+ return {
+ stage("Reset: ${compiler}") {
+ sleep 30
+ sh "sudo zfs rollback zpool0/${compiler}@latest"
+ }
+ }
+}
+
def buildsMap = compilers.collectEntries {
["${it}": build(it)]
}
+
def build(compiler) {
return {
stage("Build: ${compiler}") {
@@ -101,7 +117,7 @@ def build(compiler) {
} catch (e) {
throw e
} finally {
- sh "sudo zfs rollback zpool0/${compiler}@latest"
+ reset("${compiler}").call()
}
}
}
@@ -123,13 +139,31 @@ pipeline {
stage("Patch") {
when { expression { return !!params.DIFF_ID } }
steps {
- sh "arc patch --diff ${params.DIFF_ID} --force"
- script { parallel patchesMap }
+ script {
+ try {
+ sh "arc patch --diff ${params.DIFF_ID} --force"
+ script { parallel patchesMap }
+ } catch(e) {
+ // In case of failure, reset both, since they were patched together.
+ parallel resetMap
+ throw e
+ }
+ }
}
}
stage("Build") {
steps {
- script { parallel buildsMap }
+ script {
+ try {
+ buildsMap.each { key, value ->
+ value.call()
+ }
+ } catch(e) {
+ // In case of failure, reset both, since they were patched together.
+ parallel resetMap
+ throw e
+ }
+ }
}
post {
always {
@@ -144,10 +178,10 @@ pipeline {
catchError {
sh '''
for file in builderr-*.txt ; do
- if [ -s "$file" ]; then
- echo "$file" >> build-errors.txt
- cat "$file" >> build-errors.txt
- fi
+ if [ -s "$file" ]; then
+ echo "$file" >> build-errors.txt
+ cat "$file" >> build-errors.txt
+ fi
done
'''
}
@@ -159,21 +193,38 @@ pipeline {
steps {
script {
try {
- // arc lint outputs an empty file on success - unless there is nothing to lint.
- // On failure, it'll output the file and a failure error code.
- // Explicitly checking for the file presence is thus best to detect the linter did run
- sh 'arc lint --never-apply-patches --output jenkins --outfile .phabricator-lint && touch .phabricator-lint'
- } catch (e) {
- if (!fileExists(".phabricator-lint")) {
- sh '''echo '{"General":[{"line": 0, "char": 0, "code": "Jenkins", "severity": "error", "name": "ci-error", "description": "Error running lint", "original": null, "replacement": null, "granularity": 1, "locations": [], "bypassChangedLineFiltering": true, "context": null}]}' > .phabricator-lint '''
- }
+ docker.image("0ad-lint:latest").inside {
+ try {
+ // arc lint outputs an empty file on success - unless there is nothing to lint.
+ // On failure, it'll output the file and a failure error code.
+ // Explicitly checking for the file presence is thus best to detect the linter did run
+ sh '~/arcanist/bin/arc lint --never-apply-patches --output jenkins --outfile .phabricator-lint && touch .phabricator-lint'
+ }
+ catch (e) {
+ if (!fileExists(".phabricator-lint")) {
+ sh '''echo '{"General":[{"line": 0, "char": 0, "code": "Jenkins", "severity": "error", "name": "ci-error", "description": "Error running lint", "original": null, "replacement": null, "granularity": 1, "locations": [], "bypassChangedLineFiltering": true, "context": null}]}' > .phabricator-lint '''
+ }
+ else {
+ sh 'echo "error(s) were found running lint"'
+ }
+ }
+ finally {
+ stash includes: ".phabricator-lint", name: "Lint File"
+ }
+ }
+ }
+ finally {
+ unstash("Lint File")
+ if (fileExists(".phabricator-lint")) {
+ sh '''cat .phabricator-lint '''
+ }
}
}
}
}
stage("Data checks") {
steps {
- warnError('CheckRefs.pl script failed!') {
+ warnError('CheckRefs.py script failed!') {
sh "cd source/tools/entity/ && python3 checkrefs.py -tax 2> data-errors.txt"
}
}
@@ -187,8 +238,8 @@ pipeline {
sh "if [ -s build-errors.txt ]; then cat build-errors.txt >> .phabricator-comment ; fi"
sh '''
if [ -s data-errors.txt ]; then
- echo "Data checks errors:" >> .phabricator-comment
- cat data-errors.txt >> .phabricator-comment
+ echo "Data checks errors:" >> .phabricator-comment
+ cat data-errors.txt >> .phabricator-comment
fi
'''
}
diff --git a/build/jenkins/pipelines/docker-reset.Jenkinsfile b/build/jenkins/pipelines/docker-reset.Jenkinsfile
index ae691e71f1..35e1cd4034 100644
--- a/build/jenkins/pipelines/docker-reset.Jenkinsfile
+++ b/build/jenkins/pipelines/docker-reset.Jenkinsfile
@@ -1,4 +1,4 @@
-/* Copyright (C) 2021 Wildfire Games.
+/* Copyright (C) 2024 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -42,16 +42,34 @@ pipeline {
steps {
sh 'docker build --no-cache -t build-base ~/dockerfiles/build-base'
sh 'docker build --no-cache -t 0ad-gcc7 ~/dockerfiles/gcc7'
- sh 'docker build --no-cache -t 0ad-coala ~/dockerfiles/coala'
+ sh 'docker build --no-cache -t 0ad-gcc7-docs ~/dockerfiles/gcc7-docs'
+ sh 'docker build --no-cache -t 0ad-clang8 ~/dockerfiles/clang8'
sh 'docker build --no-cache -t 0ad-translations ~/dockerfiles/translations'
+ sh 'docker build --no-cache -t 0ad-lint ~/dockerfiles/lint'
}
}
stage("Build") {
+ when {
+ environment name: 'no-cache', value: 'true'
+ }
steps {
sh 'docker build -t build-base ~/dockerfiles/build-base'
sh 'docker build -t 0ad-gcc7 ~/dockerfiles/gcc7'
- sh 'docker build -t 0ad-coala ~/dockerfiles/coala'
+ sh 'docker build -t 0ad-gcc7-docs ~/dockerfiles/gcc7-docs'
+ sh 'docker build -t 0ad-clang8 ~/dockerfiles/clang8'
sh 'docker build -t 0ad-translations ~/dockerfiles/translations'
+ sh 'docker build -t 0ad-lint ~/dockerfiles/lint'
+ sh """
+ docker rmi debian:buster
+ DANGLING_IMAGES="\$(docker images --filter \"\"\"dangling=true\"\"\" -q --no-trunc)"
+ if [ -n "\$DANGLING_IMAGES" ]; then
+ echo "Removing dangling images: \$DANGLING_IMAGES"
+ docker rmi \$(docker images --filter \"\"\"dangling=true\"\"\" -q --no-trunc)
+ echo "Done."
+ else
+ echo "No dangling images found."
+ fi
+ """
}
}
stage("Update") {
@@ -72,8 +90,10 @@ pipeline {
sh "sudo zfs snapshot zpool0/trunk@base"
sh "sudo zfs clone zpool0/trunk@base zpool0/gcc7"
-
+ sh "sudo zfs clone zpool0/trunk@base zpool0/clang8"
sh "sudo zfs snapshot zpool0/trunk@latest"
+ sh "sudo zfs snapshot zpool0/clang8@latest"
+ sh "sudo zfs snapshot zpool0/gcc7@latest"
}
}
}