Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature 210/support for jenkins folders #298

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,9 @@ jenkins_api_client.log

# Vagrant
.vagrant

# VS Code history folder
.history

# local gem file
*.gem
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ jobs_to_filter = "^test_job.*"
# Get a filtered list of jobs from the server
jobs = @client.job.list(jobs_to_filter)

# Get job list from a specific folder
folder_job_list = @client.job.list('/job/folder_path')

# Chain all the jobs with 'success' as the threshold
# The chain method will return the jobs that is in the head of the sequence
# This method will also remove any existing chaining
Expand Down Expand Up @@ -171,6 +174,12 @@ want to build failed and unstable jobs, just pass
<tt>["failure", "unstable"]</tt>. Also if you pass in an empty array, it will
assume that you want to consider all jobs and no filtering will be performed.

Another API is where you cnaa get list of all jobs using the `list_all` method.
By default if no parameter is specified then it'll give a list of all jobs from
root as an Array. If you want to get list of jobs from specific folder, then as
mentioned in the example you can provide a complete `folder_path` as viewed in
a browser address bar (URL).

There is another parameter called <tt>threshold</tt> you can specify for the
chaining and this is used to decide whether to move forward with the next job
in the chain or not. A <tt>success</tt> will move to the next job only if the
Expand Down
47 changes: 36 additions & 11 deletions lib/jenkins_api_client/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -613,10 +613,15 @@ def get_console_output(job_name, build_num = 0, start = 0, mode = 'text')

# List all jobs on the Jenkins CI server
#
# @param [String] folder_path Path of the folder as displayed in Jenkins URL.
# For ex.
# Root level folder - "/job/folder1"
# Nested folder - "/job/folder1/job/folder2/..."
#
# @return [Array<String>] the names of all jobs in jenkins
#
def list_all
response_json = @client.api_get_request("", "tree=jobs[name]")["jobs"]
def list_all(folder_path = '')
response_json = @client.api_get_request(path_encode(folder_path), "tree=jobs[name]")["jobs"]
response_json.map { |job| job["name"] }.sort
end

Expand All @@ -637,13 +642,18 @@ def exists?(job_name)
# @param jobs [Array<String>] if specified this array will be used for
# filtering by the status otherwise the filtering will be done using
# all jobs available in jenkins
# @param [String] folder_path Path of the folder as displayed in Jenkins URL.
# For ex.
# Root level folder - "/job/folder1"
# Nested folder - "/job/folder1/job/folder2/..."
#
#
# @return [Array<String>] filtered jobs
#
def list_by_status(status, jobs = [])
jobs = list_all if jobs.empty?
def list_by_status(status, jobs = [], folder_path = '')
jobs = list_all(folder_path) if jobs.empty?
@logger.info "Obtaining jobs matching status '#{status}'"
json_response = @client.api_get_request("", "tree=jobs[name,color]")
json_response = @client.api_get_request(path_encode(folder_path), "tree=jobs[name,color]")
filtered_jobs = []
json_response["jobs"].each do |job|
if color_to_status(job["color"]) == status &&
Expand All @@ -658,12 +668,17 @@ def list_by_status(status, jobs = [])
#
# @param filter [String] a regular expression or a string to filter jobs
# @param ignorecase [Boolean] whether to ignore case or not
# @param [String] folder_path Path of the folder as displayed in Jenkins URL.
# For ex.
# Root level folder - "/job/folder1"
# Nested folder - "/job/folder1/job/folder2/..."
#
#
# @return [Array<String>] jobs matching the given pattern
#
def list(filter, ignorecase = true)
def list(filter, ignorecase = true, folder_path = '')
@logger.info "Obtaining jobs matching filter '#{filter}'"
response_json = @client.api_get_request("")
response_json = @client.api_get_request(path_encode folder_path)
jobs = []
response_json["jobs"].each do |job|
if ignorecase
Expand All @@ -677,23 +692,33 @@ def list(filter, ignorecase = true)

# List all jobs on the Jenkins CI server along with their details
#
# @param [String] folder_path Path of the folder as displayed in Jenkins URL.
# For ex.
# Root level folder - "/job/folder1"
# Nested folder - "/job/folder1/job/folder2/..."
#
# @return [Array<Hash>] the details of all jobs in jenkins
#
def list_all_with_details
def list_all_with_details(folder_path = '')
@logger.info "Obtaining the details of all jobs"
response_json = @client.api_get_request("")
response_json = @client.api_get_request(path_encode folder_path)
response_json["jobs"]
end

# List details of a specific job
#
# @param job_name [String] the name of the job to obtain the details from
# @param [String] folder_path Path of the folder as displayed in Jenkins URL.
# For ex.
# Root level folder - "/job/folder1"
# Nested folder - "/job/folder1/job/folder2/..."
#
#
# @return [Hash] the details of the specified job
#
def list_details(job_name)
def list_details(job_name, folder_path = '')
@logger.info "Obtaining the details of '#{job_name}'"
@client.api_get_request("/job/#{path_encode job_name}")
@client.api_get_request("#{path_encode folder_path}/job/#{path_encode job_name}")
end

# List upstream projects of a specific job
Expand Down
56 changes: 56 additions & 0 deletions spec/func_tests/job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@
end
end

## This block is an expection how job creation under folders could work
## This can change as per the implementation
# before(:all) do
# @folder_path = '/job/folder1'
# @client.job.create(@folder_path, @helper.create_folder_xml)

# # Creating 10 jobs to run the spec tests on
# begin
# 10.times do |num|
# xml = @helper.create_job_xml
# job = "#{@job_name_prefix}_#{num}"
# @job_name = job if num == 0
# @client.job.create(job, xml, @folder_path).to_i.should == 200
# end
# rescue => e
# puts "WARNING: Can't create jobs for preparing to spec tests"
# end
# end

describe "InstanceMethods" do

describe "#initialize" do
Expand Down Expand Up @@ -409,6 +428,11 @@ def test_and_validate(name, params, config_line = nil)
it "Should list all jobs" do
@client.job.list_all.class.should == Array
end

# This testcase is pending as currently there is no way to create a job within the folder
it 'Should list all jobs within the folder' # do
# @client.job.list_all(@folder_path).class.should == Array
# end
end

describe "#list" do
Expand All @@ -419,6 +443,15 @@ def test_and_validate(name, params, config_line = nil)
name.should match /#{@filter}/i
}
end

# This testcase is pending as currently there is no way to create a job within the folder
it 'Should return job names from a given folder based on the filter' # do
# names = @client.job.list(@filter, true, @folder_path)
# names.class.should == Array
# names.each do |name|
# name.should match /#{@filter}/i
# end
# end
end

describe "#list_by_status" do
Expand All @@ -430,12 +463,28 @@ def test_and_validate(name, params, config_line = nil)
status.should == 'success'
end
end

# This testcase is pending as currently there is no way to create a job within the folder
it 'Should be able to jobs list from a folder by status' # do
# names = @client.job.list_by_status('success', [], @folder_path)
# names.class.should == Array
# names.each do |name|
# # The folder_path should also be implemented for Job#get_current_build_status method
# status = @client.job.get_current_build_status(name, @folder_path)
# status.should == 'success'
# end
# end
end

describe "#list_all_with_details" do
it "Should return all job names with details" do
@client.job.list_all_with_details.class.should == Array
end

# This testcase is pending as currently there is no way to create a job within the folder
it 'Should return all job names with details' # do
# @client.job.list_all_with_details(@folder_path).class.should == Array
# end
end

describe "#list_details" do
Expand All @@ -444,6 +493,13 @@ def test_and_validate(name, params, config_line = nil)
job_name.class.should == String
@client.job.list_details(job_name).class.should == Hash
end

# This testcase is pending as currently there is no way to create a job within the folder
it 'Should list details of a particular job from a given folder' # do
# job_name = @client.job.list(@filter, true, @folder_path)[0]
# job_name.class.should == String
# @client.job.list_details(job_name, @folder_path).class.should == Hash
# end
end

describe "#get_upstream_projects" do
Expand Down
42 changes: 42 additions & 0 deletions spec/unit_tests/job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@
response.class.should == Array
response.size.should == @sample_json_response["jobs"].size
end

it 'accepts folder_path parameter to list all jobs from inside a folder' do
@client.should_receive(:api_get_request).and_return(
@sample_json_response)
response = @job.list_all('/job/folder')
response.class.should == Array
response.size.should eq @sample_json_response['jobs'].size
end
end

describe "#exists?" do
Expand All @@ -297,11 +305,24 @@
@sample_json_response)
@job.list_by_status("success").class.should == Array
end

it "accepts the status and returns the jobs in specified status" do
@client.should_receive(:api_get_request).and_return(
@sample_json_response)
@job.list_by_status("success", ["test_job"]).class.should == Array
end

it 'accepts the status, folder_path and returns jobs in specified status' do
@client.should_receive(:api_get_request).twice.and_return(
@sample_json_response)
@job.list_by_status('success', [], '/job/folder').class.should == Array
end

it 'accepts the status, folder_path and returns the jobs in specified status' do
@client.should_receive(:api_get_request).and_return(
@sample_json_response)
@job.list_by_status('success', ['test_job'], '/job/folder').class.should == Array
end
end

describe "#list" do
Expand All @@ -310,6 +331,12 @@
"jobs" => ["test_job"])
@job.list("filter").class.should == Array
end

it 'accepts a filter and returns all jobs matching the filter' do
@client.should_receive(:api_get_request).and_return(
'jobs' => ['test_job'])
@job.list('filter', true, '/job/folder').class.should == Array
end
end

describe "#list_all_with_details" do
Expand All @@ -320,6 +347,14 @@
response.class.should == Array
response.size.should == @sample_json_response["jobs"].size
end

it 'accepts folder_path and returns all jobs with details' do
@client.should_receive(:api_get_request).and_return(
@sample_json_response)
response = @job.list_all_with_details('/job/folder')
response.class.should == Array
response.size.should == @sample_json_response['jobs'].size
end
end

describe "#list_details" do
Expand All @@ -329,6 +364,13 @@
response = @job.list_details("test_job")
response.class.should == Hash
end

it 'accepts the job name with folder path and returns its details' do
@client.should_receive(:api_get_request).and_return(
@sample_json_response)
response = @job.list_details('test_job', '/job/folder')
response.class.should == Hash
end
end

describe "#get_upstream_projects" do
Expand Down