-
[Fixed Issue 289][issue-289]
Added a build.stop() method which takes in a crumbFlag
-
Decoupled JenkinsServer and JenkinsHttpClient by extracting JenkinsHttpClient methods into public interface so that different implementations can be plugged into JenkinsServer if required
-
Added Closeable support to JenkinsServer and JenkinsHttpClient so that underlying resources can be cleaned up when instances no longer required
-
[JENKINS-46472][jissue-46472]
Added ability to modify offline cause for offline computers.
ComputerWithDetails computer = ... if (!computer.getOffline()){ computer.toggleOffline(); computer.changeOfflineCause("Scheduled for termination"); }
-
[JENKINS-46445][jissue-46445]
Add support for both client TLS and basic authentication.
HttpClientBuilder builder = HttpClientBuilder.create(); builder.setSslcontext(sslContext); JenkinsHttpClient client = new JenkinsHttpClient(uri, builder, username, password); JenkinsServer jenkins = new JenkinsServer(client);
-
[Refactor Issue 291][issue-291]
Useful utility methods refactored into utility classes.
-
[Fixed Issue 282][issue-282]
NullPointerException
may be thrown ifupstreamUrl
isnull
when converting cause toBuildCause
object. -
NullPointerException is thrown unless isRunning() is called first.
-
Splitting fix made for jacoco reports from Jenkins #98. Thanks to Shah, Prince.
-
Added new api for streaming build logs
BuildWithDetails build = ... // Get log with initial offset int offset = 40; String output = build.getConsoleOutputText(offset); // Stream logs (when build is in progress) BuildConsoleStreamListener buildListener = ... build.streamConsoleOutput(listener, 3, 420);
Thanks to Wojciech Trocki.
-
Fixed WARNING during build.
-
getViews()
Do not useapi/json?depth=1
cause of timeout. -
README.md Code grammar typos; Thanks to [email protected].
-
Pull Request #229 Fix race condition in JenkinsTriggerHelper
Thanks for that to Veske.
-
Pull Request #239 Fixed Bug in build method to prevent building twice.
Thanks for the pull request #239 from ladventure/master
-
Pull Request #240 Fixed code duplication.
Thanks for the pull request #240 from Jonathan Bremer.
-
Pull Request #247 Add JavaDoc.
Thanks to aisuke-yoshimoto
-
Pull Request #262 Fix typo.
Thanks for Alberto Scotto.
- ?
- Changed Eclipse Formatting configuration.
- Correctly escaping
{
and}
for range syntax.
- Added a supplemental package with classifier
apachehttp
which includes the packagesorg.apache.httpcomponents:httpclient
andorg.apache.httpcomponents:httpcore
.
-
The JenkinsServer class will return
JenkinsVersion
instead of String if you callgetJenkinsVersion()
.
public class JenkinsVersion ... {
public boolean isGreaterThan(String version);
public boolean isGreaterOrEqual(String version);
public boolean isLessThan(String version);
public boolean isLessOrEqual(String version);
public boolean isEqualTo(String version);
}
The JenkinsVersion
class can be used to compare different versions with
each other.
JenkinsVersion jv = new JenkinsVersion("1.651.1");
assertThat(jv.isGreaterThan("1.651.1")).isFalse();
-
Based on the differences between getting a TestReport for a MavenJob type and a freestyle job etc. you would have hit by getting 0 from
getTotalCount()
like in the following code snippet:
JobWithDetails job = js.getJob("non-maven-test");
Build lastCompletedBuild = job.getLastCompletedBuild();
TestReport testReport = lastCompletedBuild.getTestReport();
This is caused by the difference in the API of Jenkins which results in the following for a MavenJob type:
{
"_class" : "hudson.maven.reporters.SurefireAggregatedReport",
"failCount" : 0,
"skipCount" : 0,
"totalCount" : 489,
"urlName" : "testReport",
"childReports" : [
{
"child" : {
"_class" : "hudson.maven.MavenBuild",
"number" : 2,
"url" : "http://localhost:27100/buildserver/job/maven-test/com.soebes.subversion.sapm$sapm/2/"
},
"result" : {
"_class" : "hudson.tasks.junit.TestResult",
"testActions" : [
],
"duration" : 0.009,
"empty" : false,
"failCount" : 0,
"passCount" : 489,
"skipCount" : 0,
"suites" : [
{
"cases" : [
But for a non Maven job like freestyle job you will get the following:
{
"_class" : "hudson.tasks.junit.TestResult",
"testActions" : [
],
"duration" : 0.01,
"empty" : false,
"failCount" : 0,
"passCount" : 489,
"skipCount" : 0,
"suites" : [
{
"cases" : [
{
"testActions" : [
],
"age" : 0,
"className" : "com.soebes.subversion.sapm.AccessRuleGroupTest",
"duration" : 0.003,
This is exactly the cause for this result.
The API has been enhanced to get the correct result. This can be achieved by calling the following in cases where you have a non Maven job type.
TestResult testResult = lastCompletedBuild.getTestResult();
This means you need to take care yourself if you are getting the test results from Maven job type or non Maven job. (Future releases of the lib hopefully handle that in a more convenient way).
-
Consider Returning null from the "getTestReport()" of Build.java class for builds that Never run.
The type
BUILD_HAS_NEVER_RUN
has been enhanced to returnTestReport.NO_TEST_REPORT
if you callgetTestReport()
and returnBuildWithDetails.BUILD_HAS_NEVER_RUN
if you calldetails()
on the type.Furthermore
JobWithDetails
class has been enhanced with the following methods:
public class JobWithDetails ... {
public boolean hasFirstBuildRun();
public boolean hasLastBuildRun();
public boolean hasLastCompletedBuildRun();
public boolean hasLastFailedBuildRun();
public boolean hasLastStableBuildRun();
public boolean hasLastSuccessfulBuildRun();
public boolean hasLastUnstableBuildRun();
public boolean hasLastUnsuccessfulBuildRun();
}
to make checking more convenient. The following code snippet shows how you need to go before this change:
JobWithDetails job = server.getJob(jobName);
if (Build.BUILD_HAS_NEVER_RUN.equals(job.getLastBuild()) {
...
} else {
// Now we can get the TestReport
job.getLastBuild().getTestReport();
}
This can now be simplified to the following:
JobWithDetails job = server.getJob(jobName);
if (job.hasLastBuildRun()) {
// Now we can get the TestReport
job.getLastBuild().getTestReport();
} else {
}
-
Added methods to update/clear the description of a job.
public class JobWithDetails .. {
public void updateDescription(String description);
public void updateDescription(String description, boolean crumbFlag);
public void clearDescription();
public void clearDescription(boolean crumbFlag);
-
Added methods to update the description and the display name of a build.
public class BuildWithDetails .. {
public void updateDisplayNameAndDescription(String displayName, String description, boolean crumbFlag);
public void updateDisplayNameAndDescription(String displayName, String description);
public void updateDisplayName(String displayName, boolean crumbFlag);
public void updateDisplayName(String displayName);
public void updateDescription(String description, boolean crumbFlag);
public void updateDescription(String description);
}
-
Pull Request #206 added runScript with
crumbFlag
.Thanks Rainer W.
public class JenkinsServer {
public String runScript(String script,boolean crumb);
}
-
Fixed issue 197 Provide method for waiting until job has finished.
Added a helper class to support this.
public class JenkinsTriggerHelper {
public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName);
public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, boolean crumbFlag);
public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, Map<String, String> params);
public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, Map<String, String> params,boolean crumbFlag);
}
- Fixed Issue 104 all build* methods now return consistently
QueueReference
to make it possible to query for a queued build and if a build from the queue has been cancelled or to see if a build is running.
public class Job extends BaseModel {
public QueueReference build();
public QueueReference build(boolean crumbFlag);
public QueueReference build(Map<String, String> params);
public QueueReference build(Map<String, String> params, boolean crumbFlag);
}
-
Fixed Issue 203 with pull request #204 of RainerW [email protected]
Added methods getJobXml and updateJob with folder parameter.
public class JenkinsServer {
String getJobXml(FolderJob folder, String jobName);
void updateJob(FolderJob folder, String jobName, String jobXml, boolean crumbFlag);
}
-
Added
public class QueueItem extends BaseModel {
List<QueueItemActions> getActions();
}
and the new QueueItemActions
will offer access to the
actions.
-
Added an deleteJob method with a crumbFlag.
public class JenkinsServer {
deleteJob(FolderJob folder, String jobName, boolean crumbFlag);
}
-
Added several methods for creating/updating views.
public class JenkinsServer {
void createView(String viewName, String viewXml);
void createView(String viewName, String viewXml, Boolean crumbFlag);
void createView(FolderJob folder, String viewName, String viewXml);
void createView(FolderJob folder, String viewName, String viewXml, Boolean crumbFlag);
void updateView(String viewName, String viewXml);
void updateView(String viewName, String viewXml, boolean crumbFlag);
}
Returning null instead of IOException if view is not found in JenkinsServer.getView
MavenJobsWithDetails
is now in line with JobWithDetails
and returns
MavenBuild.BUILD_HAS_NEVER_RUN
in cases where the run has not taken
place yet.
public class MavenJobWithDetails {
public MavenBuild getLastBuild();
public MavenBuild getLastCompletedBuild();
public MavenBuild getLastFailedBuild();
public MavenBuild getLastStableBuild();
public MavenBuild getLastSuccessfulBuild();
public MavenBuild getLastUnstableBuild();
public MavenBuild getLastUnsuccessfulBuild();
}
The getBuilds()
method will return an empty list instead of NULL
in cases no
builds exists.
Fixed grammar and changed Build.BUILD_HAS_NEVER_RAN
into Build.BUILD_HAS_NEVER_RUN
public class MavenJobWithDetails {
public MavenBuild getFirstBuild();
}
Enhanced the QueueItem
to add information about the task (QueueTask).
public class QueueItem {
public QueueTask getTask();
}
Added two methods to get all builds and a range of builds so we are more in line wiht JobWithDetails.
public class MavenJobWithDetails {
public List<MavenBuild> getAllBuilds();
public List<MavenBuild> getAllBuilds(Range range);
}
Fixed #182 remove duplicated code
- maven-release-plugin to 2.5.3
- maven-site-plugin to 3.5.1
- maven-shade-plugin to 2.4.3
- maven-jar-plugin to 3.0.2
- maven-source-plugin 3.0.1
- maven-surefire/failsafe-plugin to 2.19.1
- maven-resources-plugin to 3.0.1
- Add missing maven-javadoc-plugin 2.10.4
Upgraded Maven Plugins JENKINS-35108
- maven-clean-plugin to 3.0.0
- maven-resources-plugin to 3.0.0
- maven-jar-plugin to 3.0.0
Fixed issue 176 HttpResponseException: Not Found (createJob) Based on the wrong usage of the sub methods using crumbFlag=true instead of crumbFlag=false.
JenkinsJob.details() produced NPE which has been got via view.getJob().
The implementation BuildWithDetails.getCauses()
could cause an
NPE which now has been imroved to prevent it. Thanks for hint
which brought me to reconsider the implementation.
Serveral issues fixed related to using logging framework issue-161, issue-113 and JENKINS-35002
Added slf4j-api as foundation for logging. Using log4j2-slf4j-impl in jenkins-client-it-docker for logging. As a user you can now decide which logging framework you would like to use.
Changed the structure and integrated Docker IT
The attributes of the following classes have been made private. They are only accessible via getters/setters.
MavenArtifact
, ComputerWithDetails
, Executable
, FolderJob
,
JobWithDetails
, MavenJobWithDetails
, MavenModule
, MavenModuleRecord
,
PluginManager
The getTestReport
has been moved up from MavenBuild
into
Build
class. This makes the TestReport
accessible
from any kind of build and not only from a Maven build.
jenkins.getComputerSet().getComputer()
produced an error.
Changed getComputer()
into getComputers()
cause it returns
a list an not only a single computer.
Based on the above problem the Executor
needed to be changed to
represent the correct data which is being returned.
public class ComputerSet {
public List<ComputerWithDetails> getComputers();
}
public class Executor {
public Job getCurrentExecutable();
public Job getCurrentWorkUnit();
}
Fixed issue 169 Add crumbFlag to renameJob
Added supplemental renameJob
method which supports crumbFlag. Furthermore
added renameJob
which supports folder with and without crumbFlag
.
So we now have the following methods to rename jobs:
public class JenkinsServer {
public void renameJob(String oldJobName, String newJobName) throws IOException;
public void renameJob(String oldJobName, String newJobName, Boolean crumbFlag) throws IOException;
public void renameJob(FolderJob folder, String oldJobName, String newJobName) throws IOException;
public void renameJob(FolderJob folder, String oldJobName, String newJobName, Boolean crumbFlag) throws IOException;
}
Fixed issue 168 deletejobs in folder
Added new method to delete a job within a folder.
public class JenkinsServer {
public void deleteJob(FolderJob folder, String jobName) throws IOException;
}
Changing getLocalContext(), setLocalContext()
The protected method getLocalContext()
now returns
HttpContext
instead of BasicHttpContext
.
So the API has changed from the following:
public class JenkinsServer {
protected BasicHttpContext getLocalContext();
protected void setLocalContext(BasicHttpContext localContext);
.
}
into this:
public class JenkinsServer {
protected HttpContext getLocalContext();
protected void setLocalContext(HttpContext localContext);
.
}
Apart from that the visibility of the class PreemptiveAuth
has been changed
from package private to public.
Get Jenkins Version from http header
public class JenkinsServer {
public String getVersion();
.
}
public class JobWithDetails {
public String getDescription();
.
}
The following methods have been changed to return Collections.emtpyList()
if
no builds exists or have ran before.
getAllBuilds(Range range);
getAllBuilds(),
getBuilds()
The JobWithDetails class contains several methods which could
have returned null
. This has been changed to return non null values.
public List<Job> getDownstreamProjects();
public List<Job> getUpstreamProjects();
They will return Collections.emptyList()
.
The following methods will return Build.BUILD_HAS_NEVER_RAN
in
cases where no build has executed for the appropriate methods instead
of the previous null
value.
public Build getFirstBuild();
public Build getLastBuild();
public Build getLastCompletedBuild();
public Build getLastFailedBuild();
public Build getLastStableBuild();
public Build getLastSuccessfulBuild();
public Build getLastUnstableBuild();
public Build getLastUnsuccessfulBuild();
Added getAllBuilds(), getAllBuilds(Range range)
The JobWithDetails
has been enhanced with two methods
to get all builds which exists or a range can be used
to select.
Note: There seemed to be no option to extract simply the number of existing builds of a particular job via the REST API.
public class JobWithDetails {
public List<Build> getAllBuilds() throws IOException;
public List<Build> getAllBuilds(Range range) throws IOException;
}
public class JenkinsServer {
renameJob(String jobName, String newJobName) throws IOException;
.
}
Added toggleOffline Node
Added toggleOffline to ComputerWithDetails
class.
public class ComputerWithDetails {
public void toggleOffline(boolean crumbFlag) throws IOException;
public void toggleOffline() throws IOException;
}
-
Some HTTP calls to jenkins result in a 302, which currently throws an HttpResponseException
-
Fixed. by changing call to client.post(, crumbFlag = true) into client.post(, crumbFlag = false).
Added getPluginManager() to JenkinsServer
PluginManager getPluginManager() throws IOException;
Added method to get Plugin
.
public class PluginManager extends BaseModel {
public List<Plugin> getPlugins()
}
Plugin
class contains methods to get informations about
the plugins plus a PluginDependency
class.
Added getFileFromWorkspace() to Job
Added method getFileFromWorkspace()
to Job
class to get a file
from workspace in Jenkins.
String getFileFromWorkspace(String fileName)
TestCase class enhanced
Now the TestCase
contains the information
about the errorDetails and the errorStackTrace of
a failed test case.
String getErrorDetails();
String getErrorStackTrace()
Added disableJob, enabledJob The following methods have been added to support enabling and disabling jobs.
void disableJob(String jobName);
void disableJob(String jobName, boolean crumbFlag);
void enableJob(String jobName);
void enableJob(String jobName, boolean crumbFlag);
Fixed #128 Added OfflineCause as a real object in ComputerWithDetails
Added OfflineCause
class which can now being used
as a return type for the attribute offlineCause
instead
of Object
in ComputerWithDetails
.
public class ComputerWithDetails {
Object offlineCause;
..
}
into the following which also influenced the appropriate return types of the getters:
into
public class ComputerWithDetails {
OfflineCause offlineCause;
public OfflineCause getOfflineCause() throws IOException;
}
Fixed #135 Created documentation area Started a documentation area under src/site/ for either Markdown or asciidoctor.
Fixed #130 org.jvnet.hudson:xstream I needed to remove the toString method from View class which uses the XStream classes which does not make sense from my point of view.
Fixed #144 Problems with spaces in paths and job names
Fixed #133 How do we find out which system the built was build on?
Now BuildWithDetails
API has been enhanced with the following method get
the information on which node this build has ran.
String getBuiltOn();
Fixed #146 duration / estimatedDuration are long
The API in BuildWithDetails
has been changed to represent the change
in datatype.
int getDuration();
int getEstimatedDuration();
into:
long getDuration();
long getEstimatedDuration();
Fixed #111 A missing dependency to jaxen caused problems The problem was that the dependency has missed from the compile scope which caused problems for users to use. The dependency was there via transitive dependency of a test scoped artifact.
Do not propagate IOException when GET for /CrumbIssuer fails
Added Cloudbees Folder support
The following methods have been added to support FolderJob
type.
void createFolder(String jobName, Boolean crumbFlag);
Optional<FolderJob> getFolderJob(Job job);
Map<String, Job> getJobs(FolderJob folder);
Map<String, Job> getJobs(FolderJob folder, String view);
Map<String, View> getViews(FolderJob folder);
View getView(FolderJob folder, String name);
JobWithDetails getJob(FolderJob folder, String jobName);
MavenJobWithDetails getMavenJob(FolderJob folder, String jobName);
void createJob(FolderJob folder, String jobName, String jobXml);
void createJob(FolderJob folder, String jobName, String jobXml, Boolean crumbFlag);
JobWithDetails has been enhanced with information about the first build.
Build getFirstBuild()
The JenkinsServer
API has been enhanced to get information about the Queue
QueueItem getQueueItem(QueueReference ref) throws IOException
Build getBuild(QueueItem q) throws IOException
The JenkinsHttpClient
API has been changed from the following:
JenkinsHttpClient(URI uri, DefaultHttpClient defaultHttpClient);
into
JenkinsHttpClient(URI uri, CloseableHttpClient client);
Furthermore the JenkinsHttpClient
API has been enhanced with the following
method which allows to create an unauthenticated Jenkins HTTP client.
JenkinsHttpClient(URI uri, HttpClientBuilder builder);
The Build
class Stop
method needed to be changed internally based on an
inconsistencies in Jenkins versions. (This might be change in future). There
are versions 1.565 which supports the stop method as a post call, version
1.609.1 support it as a get call and 1.609.2 as a post call.
The Job
class has been enhanced to trigger parameterized builds.
QueueReference build(Map<String, String> params, boolean crumbFlag) throws IOException;
Until to Release 0.3.0 the getLoadStatistics()
method returned a simple Map
which
needed to be changed to represent the information which is returned.
So the old one looked like this:
Map getLoadStatistics();
The new one looks like this:
LoadStatistics getLoadStatistics() throws IOException
You can see how it works by using the JenkinsLoadStatisticsExample.java.
The API for getExecutors()
has been changed from a simple Map
into something
more meaningful.
The old one looked like this:
List<Map> getExecutors();
where as the new API looks like this:
List<Executor> getExecutors();
This will result in a list of Executor which contain supplemental informations about the appropriate executor.
This release contains new functionality like support to get the list of existing views. This can be accomplished by using the following:
Map<String, View> views = jenkins.getViews();
The change for getExecutors()
which is documented in API changes.
The information about the ChangeSet
and the culprit
has been improved.
JenkinsServer jenkins = new JenkinsServer(new URI("http://localhost:8080/jenkins"), "admin", "password");
MavenJobWithDetails mavenJob = js.getMavenJob("javaee");
BuildWithDetails details = mavenJob.getLastSuccessfulBuild().details();
So now you can extract the causes which is related to the trigger which triggered the build.
List<BuildCause> causes = details.getCauses();
With the help of getChangeSet()
you can extract the changeset information of your build:
BuildChangeSet changeSet = details.getChangeSet();
By using the changeSet.getKind()
you would expect to get the kind of version control
which has been used. If you use Git or Subversion this is true but unfortunately it
is not true for all version control systems (for example TFS).
The information about files which have been changed an other information can be extracted by using the following:
List<BuildChangeSetItem> items = changeSet.getItems();
If you like to get a better overview check the example file in the project.
Extract TestReport from Jenkins
JenkinsServer js = new JenkinsServer(URI.create("http://jenkins-server/"));
MavenJobWithDetails mavenJob = js.getMavenJob("MavenJob");
BuildWithDetails details = mavenJob.getLastSuccessfulBuild().details();
TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport();
You can extract the information about the tests which have run which contains information about the number of tests, failed tests and skipped tests etc. For a more detailed example take a look into the project.
[jissue-46445]: https://issues.jenkins-ci.org/browse/JENKINS-46445) [jissue-46472]: https://issues.jenkins-ci.org/browse/JENKINS-46472)