Я пытаюсь создать конвейер Дженкинса, который берет последнюю версию проекта и использует его артефакты (например, docker изображения) для сквозных тестов.
Трубопровод может выглядеть сложным, но это довольно просто. Класс ProjectVersion
предназначен для сортировки версий . Наиболее сложная часть находится в методе CompareTo, который предназначен для использования при выборе самых больших версий (в дальнейшем будут более сложные логи c с сопоставлением с регулярным выражением)
Там закомментирована часть с сортировкой потому что он терпит неудачу с ним, когда используется.
Конвейер:
class ProjectVersion implements Comparable<ProjectVersion>, Serializable {
private String version;
public final String get() {
return this.version;
}
public ProjectVersion(String version) {
this.version = version;
}
public int compareTo(ProjectVersion that) {
if(that == null)
return 1;
String[] thisParts = this.get().split("\\.");
String[] thatParts = that.get().split("\\.");
int length = Math.max(thisParts.length, thatParts.length);
for(int i = 0; i < length; i++) {
int thisPart = i < thisParts.length ?
tryToParse(thisParts[i]) : 0;
int thatPart = i < thatParts.length ?
tryToParse(thatParts[i]) : 0;
if(thisPart < thatPart)
return -1;
if(thisPart > thatPart)
return 1;
}
return 0;
}
private int tryToParse(String part) {
try {
return Integer.parseInt(part)
} catch (NumberFormatException e) {
return 0;
}
}
boolean equals(Object that) {
if(this == that)
return true;
if(that == null)
return false;
if(this.getClass() != that.getClass())
return false;
return this.compareTo((ProjectVersion) that) == 0;
}
@Override
public String toString() {
return "ProjectVersion{" +
"version='" + version + '\'' +
'}';
}
}
def getJSON(url) {
sh(returnStdout: true, script: "curl -s ${url} 2>&1 | tee result.json")
readFile('result.json').trim()
}
def getVersions(String url) {
def json = readJSON text: getJSON(url)
def allVersions = json.children.findAll { child -> child.folder }
.collect { it.uri.substring(1).trim() }
return sort(allVersions)
}
@NonCPS
def sort(allVersions) {
return allVersions
.collect { it-> new ProjectVersion(it) }
// .sort{it1, it2 -> it1.compareTo(it2)}
// .reverse()
}
def getVersions() {
def versions = getVersions(MVN_ARTIFACTORY)
println(versions.toString())
def lastVersion = versions.iterator().next()
println(lastVersion.toString())
versions
}
pipeline {
agent {
label JENKINS_NODES
}
stages {
stage('Get the right version') {
steps {
getVersions()
}
}
}
Результат:
// not important stuff here
+ curl -s ************************ // not important
+ tee result.json
[Pipeline] readFile
[Pipeline] readJSON
[Pipeline] echo
ProjectVersion{version='1.5.10'}
[Pipeline] echo
ProjectVersion{version='1.5.10'}
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Первый эхо-сигнал должен напечатать все версии в collection - пока что переменная, очевидно, является экземпляром ProjectVersion
класса , а не списка . Как это вообще возможно?
Я пытался поиграться с аннотацией @NonCPS
, но безуспешно.
Я совершенно уверен, что кодовая часть groovy работает. Когда я пытаюсь запустить его с консоли groovy (и заменить синтаксический анализ json на new groovy.json.JsonSlurper().parseText(new URL(url).getText())
), это работает. Ожидаемый результат (без сортировки):
[ProjectVersion{version='1.5.10'}, ProjectVersion{version='1.5.11'}, ProjectVersion{version='1.6.0.31'}, ProjectVersion{version='1.6.0.32'}, ProjectVersion{version='1.6.0.33'}, ProjectVersion{version='1.6.0.34'}, ProjectVersion{version='1.6.0.35'}, ProjectVersion{version='1.6.0.36'}, ProjectVersion{version='2.0.0'}, ProjectVersion{version='2.0.10'}]
Спасибо за помощь.
Фрэнк