JENKINS-49815# Bump up plugin versions (#1681)

* JENKINS-49815# Bump up plugin versions

* Updated runtime dependencies

* Add pause to make sure we do not click too quickly

* Java MBP test

* Removed pause

* Re-write  folder.js tests in Java.

* core and other plugins upgrades

* bump up jenins-test-harness version to fix java.lang.ClassNotFoundException: hudson.slaves.CommandLauncher

hudson.slaves.CommandLauncher has been removed from core starting 2.86

* More of folder.js test ported to java
This commit is contained in:
Vivek Pandey 2018-04-24 14:48:37 -07:00 committed by GitHub
parent 10f646f796
commit 4736315e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 371 additions and 509 deletions

View File

@ -6,7 +6,7 @@
# Should be kept in sync with jenkins.properties of pom.xml
# Patch version is not to be considered, we prefer to base the image off the latest LTS of the line
# and keep the dependency on the baseline in pom.xml
FROM jenkins:2.73.3
FROM jenkins:2.107.2
USER root

8
Jenkinsfile vendored
View File

@ -47,8 +47,8 @@ node() {
archive '*/target/jest-coverage/**/*'
}
stage('ATH - Jenkins 2.73.3') {
sh "cd acceptance-tests && ./run.sh -v=2.73.3 --no-selenium --settings='-s ${env.WORKSPACE}/settings.xml'"
stage('ATH - Jenkins 2.107.2') {
sh "cd acceptance-tests && ./run.sh -v=2.107.2 --no-selenium --settings='-s ${env.WORKSPACE}/settings.xml'"
junit 'acceptance-tests/target/surefire-reports/*.xml'
archive 'acceptance-tests/target/screenshots/**/*'
}
@ -62,6 +62,10 @@ node() {
sh "cd acceptance-tests && ./run.sh -v=2.73.3 --no-selenium --settings='-s ${env.WORKSPACE}/settings.xml'"
junit 'acceptance-tests/target/surefire-reports/*.xml'
}
stage('ATH - Jenkins 2.107.2') {
sh "cd acceptance-tests && ./run.sh -v=2.107.2 --no-selenium --settings='-s ${env.WORKSPACE}/settings.xml'"
junit 'acceptance-tests/target/surefire-reports/*.xml'
}
}

View File

@ -9,7 +9,6 @@
<version>2.35</version>
<relativePath/>
</parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>fake-realm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>

View File

@ -7,7 +7,7 @@
<version>2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Blue Ocean Parent</name>
<name>Blue Ocean ATH Parent</name>
<modules>
<module>fake-security-realm-plugin</module>

View File

@ -56,7 +56,7 @@
</pluginRepository>
</pluginRepositories>
<properties>
<jenkins.version>2.73.3</jenkins.version>
<jenkins.version>2.107.2</jenkins.version>
<jenkins-test-harness.version>2.30</jenkins-test-harness.version>
<java.level>8</java.level>
</properties>
@ -68,25 +68,10 @@
</dependency>
<!-- following are required to run on newer jenkins versions (after 2.7) as it changed how classloading works a bit for plugins -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plain-credentials</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
<version>2.1.14</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.10</version>
<version>1.14</version>
</dependency>
<dependency>

View File

@ -1,4 +1,4 @@
JENKINS_VERSION=2.73.3
JENKINS_VERSION=2.107.2
SELENIUM_VERSION=2.53
MAVEN_SETTINGS=""

View File

@ -15,17 +15,17 @@ import io.blueocean.ath.BaseUrl;
import io.blueocean.ath.GitRepositoryRule;
import io.blueocean.ath.JenkinsUser;
import io.blueocean.ath.model.Folder;
import org.apache.http.client.HttpResponseException;
import org.apache.log4j.Logger;
import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.support.ui.FluentWait;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.HttpResponseException;
import org.apache.log4j.Logger;
import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.support.ui.FluentWait;
@Singleton
public class ClassicJobApi {
@ -64,6 +64,19 @@ public class ClassicJobApi {
}
}
public void deleteFolder(String folder) throws IOException {
try {
jenkins.deleteJob(folder);
logger.info("Deleted folder " + folder);
} catch(HttpResponseException e) {
if(e.getStatusCode() != 404) {
throw e;
}
}
}
public void createFreeStyleJob(FolderJob folder, String jobName, String command) throws IOException {
deletePipeline(folder, jobName);
URL url = Resources.getResource(this.getClass(), "freestyle.xml");
@ -92,6 +105,22 @@ public class ClassicJobApi {
jenkins.getJob(folder, pipelineName).build();
}
public FolderJob createJobFolder(String name, String jobUrl) throws IOException, UnirestException {
if(StringUtils.isBlank(jobUrl) || jobUrl.equals("/")){
jobUrl = base+"/";
}
URL url = Resources.getResource(this.getClass(), "folder.xml");
Unirest.post(jobUrl+"createItem?name="+name).header("Content-Type", "text/xml")
.basicAuth(admin.username, admin.password)
.body(Resources.toByteArray(url)).asString();
logger.info("Created folder: "+ name);
return new FolderJob(name, jobUrl+"job/"+name+"/");
}
public FolderJob createSubFolder(Folder parentFolder, String name) throws IOException, UnirestException {
return createJobFolder(name, parentFolder.getClassJobPath());
}
private void createFolderImpl(Job folder, String folderName) throws IOException {
String path = base + "/";
if (folder != null) {
@ -135,17 +164,17 @@ public class ClassicJobApi {
createMultiBranchPipeline(folder, pipelineName, repository.gitDirectory.getAbsolutePath());
}
public void createFolders(Folder folder, boolean deleteRoot) throws IOException {
public FolderJob createFolders(Folder folder, boolean deleteRoot) throws IOException, UnirestException {
if(deleteRoot) {
jenkins.deleteJob(folder.get(0));
deleteFolder(folder.get(0));
}
jenkins.createFolder(folder.get(0));
FolderJob lastFolder = jenkins.getFolderJob(jenkins.getJob(folder.get(0))).get();
FolderJob lastFolder = createJobFolder(folder.get(0), "/");
for (int i = 1; i < folder.getFolders().size(); i++) {
lastFolder.createFolder(folder.get(0));
lastFolder = jenkins.getFolderJob(lastFolder.getJob(folder.get(0))).get();
String subFolderName = folder.get(i);
lastFolder = createJobFolder(subFolderName, lastFolder.getUrl());
};
return lastFolder;
}
public <T> T until(Function<JenkinsServer, T> function, long timeoutInMS) {

View File

@ -2,9 +2,6 @@ package io.blueocean.ath.model;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -29,6 +26,10 @@ public class Folder {
return Joiner.on("/").join(folders);
}
public String getClassJobPath(){
return Joiner.on("/job/").join(folders);
}
public String get(int i) {
return folders.get(i);
}

View File

@ -4,13 +4,13 @@ import com.google.common.base.Predicate;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import com.offbytwo.jenkins.model.FolderJob;
import io.blueocean.ath.GitRepositoryRule;
import io.blueocean.ath.api.classic.ClassicJobApi;
import io.blueocean.ath.sse.SSEEvents;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import org.json.JSONObject;
public class MultiBranchPipeline extends AbstractPipeline {
@ -31,6 +31,12 @@ public class MultiBranchPipeline extends AbstractPipeline {
return this;
}
public MultiBranchPipeline createPipeline(FolderJob folderJob, GitRepositoryRule git) throws IOException {
jobApi.createMultiBranchPipeline(folderJob, getName(), git);
return this;
}
public Predicate<List<JSONObject>> buildsFinished = list -> SSEEvents.activityComplete(getFolder().getPath(getName())).apply(list);
public MultiBranchPipeline buildBranch(String branch) throws IOException {

View File

@ -119,11 +119,18 @@ public class ActivityPage {
}
public void testNumberRunsComplete(int atLeast) {
testNumberRunsComplete(atLeast, "success");
By selector = By.cssSelector("div[data-pipeline='" + pipeline.getName() + "'].JTable-row circle.success");
wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(selector, atLeast - 1));
logger.info("At least " + atLeast + " runs are complete");
}
public void testNumberRunsComplete(int atLeast, String status) {
By selector = By.cssSelector("div[data-pipeline='" + pipeline.getName() + "'].JTable-row circle."+status);
wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(selector, atLeast - 1));
logger.info("At least " + atLeast + " runs are complete");
}
public void checkBasicDomElements() {
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("article.activity")));
}

View File

@ -5,15 +5,15 @@ import com.google.inject.assistedinject.Assisted;
import io.blueocean.ath.BaseUrl;
import io.blueocean.ath.WaitUtil;
import io.blueocean.ath.model.AbstractPipeline;
import java.net.URLEncoder;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import javax.inject.Inject;
import java.net.URLEncoder;
public class RunDetailsArtifactsPage {
private Logger logger = Logger.getLogger(RunDetailsArtifactsPage.class);
@ -69,4 +69,11 @@ public class RunDetailsArtifactsPage {
public RunDetailsArtifactsPage open(int runNumber) {
return open(null, runNumber);
}
public RunDetailsArtifactsPage checkNumberOfArtifacts(int expected) {
wait.until(ExpectedConditions.numberOfElementsToBe(By.cssSelector(".artifacts-table .JTable-row"),
expected+1)); //1 for heading
return this;
}
}

View File

@ -10,6 +10,7 @@ import org.apache.log4j.Logger;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
@ -84,4 +85,9 @@ public class RunDetailsPipelinePage implements WebDriverMixin {
return this;
}
public boolean checkTitle(String title){
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".ResultPageHeader-main")));
WebElement element = driver.findElement(By.cssSelector(".ResultPageHeader-main"));
return element.getText().contains(title);
}
}

View File

@ -0,0 +1,28 @@
<?xml version='1.0' encoding='UTF-8'?>
<com.cloudbees.hudson.plugins.folder.Folder plugin="cloudbees-folder@6.3">
<description></description>
<properties>
<org.jenkinsci.plugins.pipeline.modeldefinition.config.FolderConfig plugin="pipeline-model-definition@1.2.7">
<dockerLabel></dockerLabel>
<registry plugin="docker-commons@1.5"/>
</org.jenkinsci.plugins.pipeline.modeldefinition.config.FolderConfig>
</properties>
<folderViews class="com.cloudbees.hudson.plugins.folder.views.DefaultFolderViewHolder">
<views>
<hudson.model.AllView>
<owner class="com.cloudbees.hudson.plugins.folder.Folder" reference="../../../.."/>
<name>All</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
</hudson.model.AllView>
</views>
<tabBar class="hudson.views.DefaultViewsTabBar"/>
</folderViews>
<healthMetrics>
<com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric>
<nonRecursive>false</nonRecursive>
</com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric>
</healthMetrics>
<icon class="com.cloudbees.hudson.plugins.folder.icons.StockFolderIcon"/>
</com.cloudbees.hudson.plugins.folder.Folder>

View File

@ -1,26 +1,43 @@
package io.blueocean.ath.offline.edgeCases;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.offbytwo.jenkins.model.FolderJob;
import io.blueocean.ath.ATHJUnitRunner;
import io.blueocean.ath.BaseUrl;
import io.blueocean.ath.BlueOceanAcceptanceTest;
import io.blueocean.ath.GitRepositoryRule;
import io.blueocean.ath.WaitUtil;
import io.blueocean.ath.api.classic.ClassicJobApi;
import io.blueocean.ath.factory.MultiBranchPipelineFactory;
import io.blueocean.ath.model.Folder;
import io.blueocean.ath.model.MultiBranchPipeline;
import io.blueocean.ath.pages.blue.ActivityPage;
import io.blueocean.ath.pages.blue.BranchPage;
import io.blueocean.ath.pages.blue.DashboardPage;
import io.blueocean.ath.pages.blue.RunDetailsArtifactsPage;
import io.blueocean.ath.pages.blue.RunDetailsPipelinePage;
import io.blueocean.ath.pages.blue.RunDetailsTestsPage;
import io.blueocean.ath.sse.SSEClientRule;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import java.io.IOException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(ATHJUnitRunner.class)
public class FolderTest extends BlueOceanAcceptanceTest {
private Logger logger = Logger.getLogger(FolderTest.class);
private Folder folder = Folder.folders("a folder", "bfolder", "cfolder");
private static final Folder folder = Folder.folders("a folder", "bfolder", "cfolder");
@Rule
@Inject
@ -32,6 +49,21 @@ public class FolderTest extends BlueOceanAcceptanceTest {
@Inject @Rule
public SSEClientRule client;
@Inject
ClassicJobApi jobApi;
@Inject
WebDriver driver;
@Inject @BaseUrl
String base;
@Inject
WaitUtil wait;
@Inject
DashboardPage dashboardPage;
/**
* Tests that the activity page works when there are multiple layers of folders, and with funky characters.
*
@ -47,6 +79,133 @@ public class FolderTest extends BlueOceanAcceptanceTest {
MultiBranchPipeline p = mbpFactory.pipeline(folder, pipelineName).createPipeline(git);
client.untilEvents(p.buildsFinished);
p.getActivityPage().open();
ActivityPage activityPage = p.getActivityPage();
activityPage.open();
activityPage.checkBasicDomElements();
}
@Test
public void foldersTest() throws IOException, GitAPIException, UnirestException, InterruptedException {
String pipelineName = "Sohn";
Folder folder = Folder.folders("firstFolder","三百", "ñba","");
FolderJob folderJob = jobApi.createFolders(folder, true);
jobApi.createFreeStyleJob(folderJob, pipelineName, "echo 'hello world!'");
driver.get(folderJob.getUrl()+"/job/"+pipelineName+"/");
driver.findElement(By.xpath("//a[contains(@class, 'task-link') and text()='Open Blue Ocean']")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".PlaceholderContent.NoRuns")));
String activityPage = driver.getCurrentUrl();
assertTrue(activityPage.endsWith(getNestedPipelinePath("firstFolder") +
"Sohn/activity"));
wait.until(By.cssSelector("nav a.activity"));
wait.until(By.cssSelector("nav a.branches"));
wait.until(By.cssSelector("nav a.pr"));
wait.until(By.cssSelector("a.main_exit_to_app"));
driver.findElement(By.cssSelector("a.main_exit_to_app")).click();
wait.until(By.xpath("//a[contains(@class, 'task-link') and text()='Open Blue Ocean']"));
assertEquals(base+"/job/firstFolder/job/"+
URLEncoder.encode("三百", "UTF-8")
+"/job/"+URLEncoder.encode("ñba", "UTF-8")
+"/job/"+URLEncoder.encode("", "UTF-8")
+"/job/Sohn/", driver.getCurrentUrl());
}
@Test
public void anotherFoldersTest() throws IOException, GitAPIException, UnirestException {
Folder anotherFolder = Folder.folders("anotherFolder", "三百", "ñba", "");
FolderJob folderJob = jobApi.createFolders(anotherFolder, true);
git.writeJenkinsFile(loadJenkinsFile());
git.writeFile("TEST-failure.TestThisWillFailAbunch.xml", loadResource("/TEST-failure.TestThisWillFailAbunch.xml"));
git.writeFile("TEST-failure.TestThisWontFail.xml", loadResource("/TEST-failure.TestThisWontFail.xml"));
git.addAll();
git.commit("First");
git.createBranch("feature/1");
String pipelineName = "NestedFolderTest_multiBranchFolderTest";
MultiBranchPipeline p = mbpFactory.pipeline(anotherFolder, pipelineName)
.createPipeline(folderJob, git);
client.untilEvents(p.buildsFinished);
//check dashboard
driver.get(base+"/blue/pipelines/");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".Header-topNav nav a[href=\"/blue/pipelines\"]")));
driver.findElement(By.cssSelector(".pipelines-table"));
driver.findElement(By.cssSelector(".Site-footer"));
//validate MBP activity page
//check dashboard has 1 run
ActivityPage activityPage = p.getActivityPage().open();
activityPage.testNumberRunsComplete(1, "unstable");
//validate run details
//JENKINS-36616 - Unable to load multibranch projects in a folder
RunDetailsPipelinePage runDetails = p.getRunDetailsPipelinePage();
runDetails.open("feature%2F1", 1);
assertTrue(runDetails.checkTitle("feature/1"));
assertEquals(0, runDetails.getDriver().findElements(By.className("a.authors")).size());
runDetails.click(".ResultPageHeader-close");
wait.tinySleep(1000);
assertTrue(driver.findElements(By.cssSelector(".RunDetails-content")).size() == 0);
//after closing we should be back to activity page
assertEquals(base+getNestedPipelinePath("anotherFolder") +
pipelineName+"/activity", driver.getCurrentUrl());
//validate artifacts page
RunDetailsArtifactsPage runDetailsArtifactsPage = p.getRunDetailsArtifactsPage();
runDetailsArtifactsPage.open("feature/1", 1);
runDetailsArtifactsPage.checkNumberOfArtifacts(3);
//Check whether the test tab shows failing tests
//@see {@link https://issues.jenkins-ci.org/browse/JENKINS-36674|JENKINS-36674} Tests are not being reported
RunDetailsTestsPage testPage = p.getRunDetailsTestsPage();
testPage.open("feature%2F1", 1);
testPage.checkResults("failure", 3);
//Jobs can be started from branch tab. - RUN
//@see {@link https://issues.jenkins-ci.org/browse/JENKINS-36615|JENKINS-36615} the multibranch project has the branch 'feature/1'
activityPage = p.getActivityPage().open();
BranchPage branchPage = activityPage.clickBranchTab();
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("a.run-button")));
driver.findElement(By.cssSelector("a.run-button")).click();
runDetails.open("feature%2F1", 2);
client.untilEvents(p.buildsFinished);
activityPage.open();
activityPage.testNumberRunsComplete(2, "unstable");
// test open blueocean from classic - run details
// make sure the open blue ocean button works. In this case,
// it should bring the browser to the run details page for the first run
driver.get(base+"/job/anotherFolder/job/三百/job/ñba/job/七/job/"+pipelineName+"/job/feature%252F1/1/");
wait.until(By.xpath("//a[contains(@class, 'task-link') and text()='Open Blue Ocean']")).click();
assertEquals(driver.getCurrentUrl(), base+getNestedPipelinePath("anotherFolder") +
pipelineName+"/detail/feature%2F1/1/");
wait.until(ExpectedConditions.or(
ExpectedConditions.presenceOfElementLocated(By.cssSelector(".RunDetails-content .log-wrapper")),
ExpectedConditions.presenceOfElementLocated(By.cssSelector(".RunDetails-content .Steps .logConsole"))
));
// make sure the open blue ocean button works. In this case,
// it should bring the browser to the main top-level pipelines page.
// See https://issues.jenkins-ci.org/browse/JENKINS-39842
driver.get(base+"/job/anotherFolder/job/三百/job/ñba");
wait.until(By.xpath("//a[contains(@class, 'task-link') and text()='Open Blue Ocean']")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".Header-topNav nav a[href=\"/blue/pipelines\"]")));
driver.findElement(By.cssSelector(".pipelines-table"));
driver.findElement(By.cssSelector(".Site-footer"));
assertTrue(driver.getCurrentUrl().endsWith("/pipelines"));
}
private String getNestedPipelinePath(String rootFolder) throws UnsupportedEncodingException {
return "/blue/organizations/jenkins/"+rootFolder+"%2F"
+ URLEncoder.encode("三百", "UTF-8")+ "%2F"
+ URLEncoder.encode("ñba", "UTF-8")+ "%2F"
+ URLEncoder.encode("", "UTF-8")+ "%2F";
}
}

View File

@ -1,234 +0,0 @@
/** @module folder
* @memberof edgeCases
* @description
*
* Tests: Condensed state of commit author in detail header
*
* REGRESSION covered:
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36618|JENKINS-36618} - create same job but in another folder
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36616|JENKINS-36616} - Unable to load multibranch projects in a folder
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36773|JENKINS-36773} / {@link https://issues.jenkins-ci.org/browse/JENKINS-37605|JENKINS-37605} verify encoding and spacing of details
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36613|JENKINS-36613} Unable to load steps for multibranch pipelines with / in them
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36674|JENKINS-36674} Tests are not being reported
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36615|JENKINS-36615} the multibranch project has the branch 'feature/1'
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-39842|JENKINS-39842} - Open Blue Ocean button should not try to load /activity for a folder
*
*/
const git = require("../../../main/js/api/git");
const path = require("path");
const pageHelper = require("../../../main/js/util/pageHelper");
const sanityCheck = pageHelper.sanityCheck;
// base configuration for the path of the folders
const folders = ['firstFolder', '三百', 'ñba', '七'];
const anotherFolders = ['anotherFolder', '三百', 'ñba', '七'];
// our job should be named the same way in both folders
const jobName = 'Sohn';
// git repo details
const pathToRepo = path.resolve('./target/test-project-folder');
const sourceRep = './src/test/resources/multibranch_1';
// helper to return the project name including a separator or '/'
function getProjectName(nameArray, separator) {
if (!separator) {
separator = '/';
}
return nameArray.join(separator) + separator + jobName;
}
// here we need to escape the real projectName to a urlEncoded string
const projectName = getProjectName(anotherFolders, '%2F');
module.exports = {
/** creating a git repo */
before: function (browser, done) {
browser.waitForJobDeleted('firstFolder', function () {
browser.waitForJobDeleted('anotherFolder', function () {
// we creating a git repo in target based on the src repo (see above)
git.createRepo(sourceRep, pathToRepo)
.then(function () {
git.createBranch('feature/1', pathToRepo)
.then(done);
});
});
});
},
/** Create folder - "firstFolder"*/
'step 01': function (browser) {
// Initial folder create page
const folderCreate = browser.page.folderCreate().navigate();
// create nested folder for the project
folderCreate.createFolders(folders);
},
/** Create freestyle job - "Sohn"*/
'step 02': function (browser) {
// create the freestyle job in the folder
browser.page.jobUtils().newItem();
const freestyleCreate = browser.page.freestyleCreate();
freestyleCreate.createFreestyle(jobName, 'freestyle.sh');
// make sure the open blue ocean button works. In this case,
// it should bring the browser to an empty pipeline activity
// page.
var bluePipelineActivity = browser.page.bluePipelineActivity();
browser.page.openBlueOcean().open();
bluePipelineActivity.assertEmptyLayoutOkay(jobName);
browser.assert.urlEndsWith('/blue/organizations/jenkins/firstFolder%2F三百%2Fñba%2F七%2FSohn/activity');
},
/** Create folder - "anotherFolder"
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36618|JENKINS-36618} part 1 - create same job but in another folder
*/
'step 03': function (browser) {
// Initial folder create page
const folderCreate = browser.page.folderCreate().navigate();
// create nested folder for the project
folderCreate.createFolders(anotherFolders);
},
/** Create multibranch job - "Sohn"
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36618|JENKINS-36618} part 1 - create same job but in another folder
*/
'step 04': function (browser) {
// go to the newItem page
browser.page.jobUtils().newItem();
// and then use the multibranchCreate page object to create
// a multibranch project
browser.page.multibranchCreate().createBranch(jobName, pathToRepo);
},
/** Jobs can have the same name in different folders, they should show up in the gui
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36618|JENKINS-36618} part 2 - verify
*/
'step 05': function (browser) {
const bluePipelinesPage = browser.page.bluePipelines().navigate();
// simply validate that the pipeline listing is showing the basic things
bluePipelinesPage.assertBasicLayoutOkay();
// by now we should have 2 different jobs from prior steps
bluePipelinesPage.countJobToBeEqual(browser, jobName, 2);
},
/** Build freestyle job */
'step 06': function (browser) {
const freestyleJob = browser.page.jobUtils()
.forJob(getProjectName(folders));
// start a build on the nested freestyle project
freestyleJob.buildStarted(function () {
// Reload the job page and check that there was a build done.
freestyleJob
.forRun(1)
.waitForElementVisible('@executer');
});
// See whether we have changed the url
browser.url(function (response) {
sanityCheck(browser, response);
// if we have changed the url then we should have now firstFolder in the path
browser.assert.equal(response.value.indexOf('firstFolder') > -1, true);
})
},
/** Validate correct encoding, pipeline graph and steps */
'step 07': function (browser) {
// /JENKINS-36616 - Unable to load multibranch projects in a folder
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'feature%2F1', 1);
// {@link https://issues.jenkins-ci.org/browse/JENKINS-36773|JENKINS-36773} / JENKINS-37605 verify encoding and spacing of details
blueRunDetailPage.assertTitle('feature/1');
// JENKINS-36613 Unable to load steps for multibranch pipelines with / in them
// FIXME should show the graph but it is failing because underlying 500 -> is under investigation currently
// blueRunDetailPage.validateGraph(); // test whether we have a pipeline graph
// blueRunDetailPage.validateSteps(); // validate that steps are displayed
// There should be no authors
blueRunDetailPage.authorsIsNotSet();
// FIXME JENKINS-36619 -> somehow the close in AT is not working
blueRunDetailPage.closeModal();
},
/** Check whether the artifacts tab shows artifacts*/
'step 08': function (browser) {
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'feature%2F1', 1);
// make sure we are finished before doing the next validations
blueRunDetailPage.waitForJobRunEnded(getProjectName(anotherFolders) + '/feature%2F1');
// go to the artifact page by clicking the tab
blueRunDetailPage.clickTab('artifacts', function (result) {
sanityCheck(result);
// we have added 2 files as artifact
blueRunDetailPage.validateNotEmptyArtifacts(2); // -> ATH is failing but local is not
});
},
/** Check whether the test tab shows failing tests
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36674|JENKINS-36674} Tests are not being reported
*/
'step 09': function (browser) {
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'feature%2F1', 1);
// Go to the test page by clicking the tab
blueRunDetailPage.clickTab('tests', function (result) {
sanityCheck(result);
// There should be failing tests
blueRunDetailPage.validateFailingTests(); // -> ATH is failing but local is not
});
},
/** Jobs can be started from branch tab. - RUN
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-36615|JENKINS-36615} the multibranch project has the branch 'feature/1'
*/
'step 10': function (browser) {
// first get the activity screen for the project
const blueActivityPage = browser.page.bluePipelineActivity().forJob(projectName, 'jenkins');
// validate that we have 3 activities from the previous tests
blueActivityPage.assertActivitiesToBeEqual(2); // -> FIXME previous test had been deactivated
// change to the branch page, clicking on the tab
blueActivityPage.clickTab('branches');
// click on the first matching run button (small one)
browser.page.bluePipelineBranch().clickRunButton();
// go to the detail page
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'feature%2F1', 2);
// Wait for the job to end
blueRunDetailPage.waitForJobRunEnded(getProjectName(anotherFolders) + '/feature%2F1');
},
/**
* test open blueocean from classic - run details
* @param browser
*/
'step 11': function(browser) {
var classicRunPage = browser.page.classicRun();
classicRunPage.navigateToRun('anotherFolder/job/三百/job/ñba/job/七/job/Sohn/job/feature%252F1');
// make sure the open blue ocean button works. In this case,
// it should bring the browser to the run details page for the first run.
browser.page.openBlueOcean().open();
browser.url(function (response) {
sanityCheck(browser, response);
response.value.endsWith('/blue/organizations/jenkins/anotherFolder%2F三百%2Fñba%2F七%2FSohn/detail/feature%2F1/1/pipeline');
// Make sure the page has all the bits and bobs
// See JENKINS-40137
const blueRunDetailPage = browser.page.bluePipelineRunDetail();
blueRunDetailPage.assertBasicLayoutOkay();
});
},
/**
* test open blueocean from classic - a normal folder page in classic jenkins.
* <p>
* It should send the user to the top level blue ocean page (pipelines).
* @param browser
*/
'step 12': function(browser) {
var classicGeneral = browser.page.classicGeneral();
// Go to a folder along the path to the MBP, but one
// of the parent folders i.e. not the MBP project folder.
classicGeneral.navigateToRun('job/anotherFolder/job/三百/job/ñba');
// make sure the open blue ocean button works. In this case,
// it should bring the browser to the main top-level pipelines page.
// See https://issues.jenkins-ci.org/browse/JENKINS-39842
browser.page.openBlueOcean().open();
browser.url(function (response) {
sanityCheck(browser, response);
response.value.endsWith('/blue/pipelines');
// Make sure the page has all the bits and bobs
// See JENKINS-40137
const bluePipelines = browser.page.bluePipelines();
bluePipelines.assertBasicLayoutOkay();
});
},
};

View File

@ -1,120 +0,0 @@
/** @module folder
* @memberof multibranch
* @description
*
* Tests: Tests specific to MBP in folders
*
* REGRESSION covered:
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-39842|JENKINS-39842} - Open Blue Ocean button should not try to load /activity for a folder
*
*/
const git = require("../../../main/js/api/git");
const path = require("path");
const pageHelper = require("../../../main/js/util/pageHelper");
const sanityCheck = pageHelper.sanityCheck;
// base configuration for the path of the folders
const projectFolderPath = ['aFolder', 'bFolder', 'cFolder'];
// our job should be named the same way in both folders
const jobName = 'MBPInFolderTree';
// git repo details
const pathToRepo = path.resolve('./target/test-project-folder');
const sourceRep = './src/test/resources/multibranch_1';
module.exports = {
/**
* creating a git repo
*/
before: function (browser, done) {
browser.waitForJobDeleted('aFolder', function () {
// we creating a git repo in target based on the src repo (see above)
git.createRepo(sourceRep, pathToRepo)
.then(function () {
git.createBranch('feature/1', pathToRepo)
.then(done);
});
});
},
/**
* Create folder structure - "aFolder/bFolder/cFolder"
*/
'step 01 - create folder': function (browser) {
// Initial folder create page
const folderCreate = browser.page.folderCreate().navigate();
// create nested folder for the project
folderCreate.createFolders(projectFolderPath);
},
/**
* Create multibranch job - "MBPInFolderTree"
*/
'step 02 - create multibranch job': function (browser) {
// go to the newItem page
browser.page.jobUtils().newItem();
// and then use the multibranchCreate page object to create
// a multibranch project
browser.page.multibranchCreate().createBranch(jobName, pathToRepo);
},
/**
* test open blueocean from classic - run details
* @param browser
*/
'step 03 - Open Blue Ocean (from a run details)': function(browser) {
var classicRunPage = browser.page.classicRun();
var runDetailsPage = browser.page.bluePipelineRunDetail();
classicRunPage.navigateToRun('aFolder/job/bFolder/job/cFolder/job/MBPInFolderTree/job/master');
// make sure the open blue ocean button works. In this case,
// it should bring the browser to the run details page for the first run.
browser.page.openBlueOcean().open();
runDetailsPage.waitForLocationContains('/blue/organizations/jenkins/aFolder%2FbFolder%2FcFolder%2FMBPInFolderTree/detail/master/1/pipeline');
browser.url(function (response) {
sanityCheck(browser, response);
response.value.endsWith('/blue/organizations/jenkins/aFolder%2FbFolder%2FcFolder%2FMBPInFolderTree/branches/');
// Make sure the page has all the bits and bobs
// See JENKINS-40137
const blueRunDetailPage = browser.page.bluePipelineRunDetail();
blueRunDetailPage.assertBasicLayoutOkay();
});
},
/**
* test escape to classic Jenkins from blueocean pipeline page.
* @param browser
*/
'step 04 - escape to classic Jenkins from pipeline page': function(browser) {
const blueMultiBranchPipeline = browser.page.blueMultiBranchPipeline();
blueMultiBranchPipeline.forPipeline('aFolder/bFolder/cFolder/MBPInFolderTree');
browser.assert.urlEndsWith('/blue/organizations/jenkins/aFolder%2FbFolder%2FcFolder%2FMBPInFolderTree/activity');
browser.url(function (response) {
response.value.endsWith('/blue/organizations/jenkins/aFolder%2FbFolder%2FcFolder%2FMBPInFolderTree/activity');
blueMultiBranchPipeline.assertBasicLayoutOkay();
blueMultiBranchPipeline.click('@exitToClassicWidget');
browser.page.openBlueOcean().visible();
browser.url(function (response) {
response.value.endsWith('/aFolder/job/bFolder/job/cFolder/job/MBPInFolderTree/');
});
});
},
/**
* test escape to classic Jenkins from blueocean pipeline run page.
* @param browser
*/
'step 05 - escape to classic Jenkins from pipeline run page': function(browser) {
const bluePipelineRunDetail = browser.page.bluePipelineRunDetail();
bluePipelineRunDetail.navigate(bluePipelineRunDetail.api.launchUrl + '/blue/organizations/jenkins/aFolder%2FbFolder%2FcFolder%2FMBPInFolderTree/detail/feature%2F1/1');
browser.url(function (response) {
response.value.endsWith('/blue/organizations/jenkins/aFolder%2FbFolder%2FcFolder%2FMBPInFolderTree/detail/feature%2F1/1/pipeline');
bluePipelineRunDetail.assertBasicLayoutOkay();
bluePipelineRunDetail.click('@exitToClassicWidget');
browser.page.openBlueOcean().visible();
browser.url(function (response) {
response.value.endsWith('/job/aFolder/job/bFolder/job/cFolder/job/MBPInFolderTree/job/feature%2F1/1/');
});
});
},
};

View File

@ -16,9 +16,8 @@
<url>https://wiki.jenkins-ci.org/display/JENKINS/Blue+Ocean+Plugin</url>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
</dependency>
</dependencies>

View File

@ -31,12 +31,8 @@
<artifactId>jira</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>

View File

@ -104,7 +104,6 @@
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-test-harness-tools</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>

183
pom.xml
View File

@ -25,8 +25,7 @@
<properties>
<java.level>8</java.level>
<jackson.version>2.8.9</jackson.version>
<jenkins.version>2.73.3</jenkins.version> <!-- Should be kept in sync with Dockerfile FROM statement-->
<jenkins.version>2.107.2</jenkins.version> <!-- Should be kept in sync with Dockerfile FROM statement-->
<javadoc.exec.goal>javadoc-no-fork</javadoc.exec.goal> <!-- stop initialize phase plugins executing twice -->
<frontend-version>1.6</frontend-version>
<node.version>6.4.0</node.version>
@ -40,8 +39,8 @@
<jacoco.line.coverage>0.70</jacoco.line.coverage>
<jacoco.missedclass.coverage>0.00</jacoco.missedclass.coverage>
<hpi.dependencyResolution>runtime</hpi.dependencyResolution>
<jenkins-test-harness.version>2.30</jenkins-test-harness.version>
<scm-api.version>2.2.2</scm-api.version>
<jenkins-test-harness.version>2.38</jenkins-test-harness.version>
<scm-api.version>2.2.6</scm-api.version>
<git.version>3.8.0</git.version>
</properties>
@ -259,12 +258,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.jenkins.blueocean.rest.annotation</groupId>
<artifactId>capability-annotation</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>blueocean-pipeline-scm-api</artifactId>
@ -295,12 +288,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>blueocean-autofavorite</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>blueocean-jira</artifactId>
@ -329,16 +316,11 @@
<version>${project.version}</version>
</dependency>
<!-- Pipeline -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>branch-api</artifactId>
<version>2.0.11</version>
</dependency>
<!-- Pipeline plugins -->
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-definition</artifactId>
<version>1.2.7</version>
<version>1.2.9</version>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci.plugins</groupId>
@ -346,40 +328,30 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plain-credentials</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.42</version>
<version>2.46</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-api</artifactId>
<version>2.22</version>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.14.1</version>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>pipeline-graph-analysis</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>github-branch-source</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-multibranch</artifactId>
<version>2.16</version>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@ -389,17 +361,17 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<version>2.13</version>
<version>2.18</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>2.14</version>
<version>2.18</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>2.14</version>
<version>2.18</version>
<classifier>tests</classifier>
</dependency>
<dependency>
@ -415,7 +387,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>pipeline-stage-step</artifactId>
<version>2.2</version>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
@ -435,7 +407,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
<version>1.39</version>
<version>1.44</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
@ -445,16 +417,9 @@
<dependency>
<groupId>com.coravy.hudson.plugins.github</groupId>
<artifactId>github</artifactId>
<version>1.28.0</version>
<version>1.29.0</version>
<exclusions>
<!-- Upper bound fix.
TODO: Remove it once github plugin commit
https://github.com/jenkinsci/github-plugin/commit/a9308f124eeb5e599b2564d6355c5dd5cdafee34
is released -->
<exclusion>
<groupId>org.jenkins-ci</groupId>
<artifactId>symbol-annotation</artifactId>
</exclusion>
<!-- Upper bound fix: Remove it once token-micro plugin is fixed to remove dependency on asm-tree
PR: https://github.com/jenkinsci/token-macro-plugin/pull/31
-->
@ -469,18 +434,24 @@
</exclusions>
</dependency>
<!-- Bitbucket dependencies -->
<!-- scm plugins -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>cloudbees-bitbucket-branch-source</artifactId>
<version>2.2.9</version>
<artifactId>scm-api</artifactId>
<version>${scm-api.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.5.0</version>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>branch-api</artifactId>
<version>2.0.18</version>
<exclusions>
<!-- Upper dependency fix: annotation-indexer comes from core, exclude from git -->
<exclusion>
<groupId>org.jenkins-ci</groupId>
<artifactId>annotation-indexer</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>apache-httpcomponents-client-4-api</artifactId>
@ -490,13 +461,18 @@
<!-- Other -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>blueocean-display-url</artifactId>
<version>2.2.0</version>
<artifactId>github-branch-source</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>scm-api</artifactId>
<version>${scm-api.version}</version>
<artifactId>cloudbees-bitbucket-branch-source</artifactId>
<version>2.2.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
@ -510,6 +486,29 @@
</exclusion>
</exclusions>
</dependency>
<!-- Upper bound dependency fix as git plugin brings new version of it than others -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git-client</artifactId>
<version>2.7.0</version>
</dependency>
<!-- Other -->
<dependency>
<groupId>io.jenkins.blueocean.rest.annotation</groupId>
<artifactId>capability-annotation</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>blueocean-autofavorite</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>blueocean-display-url</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jira</artifactId>
@ -519,10 +518,14 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<!-- Upper bound dependency fix
TODO: Remove it after https://github.com/jenkinsci/jira-plugin/pull/130 is merged and released.
-->
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.atlassian.httpclient</groupId>
<artifactId>atlassian-httpclient-plugin</artifactId>
@ -552,7 +555,12 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
<version>2.1.14</version>
<version>2.1.16</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plain-credentials</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
@ -562,12 +570,12 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>cloudbees-folder</artifactId>
<version>6.1.2</version>
<version>6.3</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>matrix-project</artifactId>
<version>1.11</version>
<version>1.12</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
@ -584,7 +592,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.10</version>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
@ -607,39 +615,15 @@
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>github-api</artifactId>
<version>1.86</version>
<exclusions>
<!-- Upper bound fix
TODO: Remove when PR https://github.com/jenkinsci/github-api-plugin/pull/15 is merged and released
-->
<exclusion>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
</exclusion>
</exclusions>
<version>1.90</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
<version>2.7.3</version>
<version>2.8.10.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@ -698,6 +682,13 @@
<groupId>io.keen</groupId>
<artifactId>keen-client-api-java</artifactId>
<version>5.2.0</version>
<exclusions>
<!-- upper bound fix, git plugin pulls in later versions -->
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Included in core -->