From 9e6f7fb9e2ed8488fc009a3b519416c0c0d02d24 Mon Sep 17 00:00:00 2001 From: swaps19 Date: Tue, 14 Apr 2020 22:54:26 +0530 Subject: [PATCH 1/4] updated all Job#list* methods to include folder_path --- lib/jenkins_api_client/job.rb | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/jenkins_api_client/job.rb b/lib/jenkins_api_client/job.rb index 30d7dc9c..1d130890 100644 --- a/lib/jenkins_api_client/job.rb +++ b/lib/jenkins_api_client/job.rb @@ -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] 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 @@ -640,10 +645,10 @@ def exists?(job_name) # # @return [Array] filtered jobs # - def list_by_status(status, jobs = []) + def list_by_status(status, jobs = [], folder_path = '') jobs = list_all 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 && @@ -661,9 +666,9 @@ def list_by_status(status, jobs = []) # # @return [Array] 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 @@ -679,9 +684,9 @@ def list(filter, ignorecase = true) # # @return [Array] 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 @@ -691,9 +696,9 @@ def list_all_with_details # # @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 From bd9e9c3d8377a972cdfcbd483ef6d79b97253bf7 Mon Sep 17 00:00:00 2001 From: swaps19 Date: Sat, 18 Apr 2020 21:22:10 +0530 Subject: [PATCH 2/4] added unit TCs for Job class changes --- .gitignore | 6 +++++ lib/jenkins_api_client/job.rb | 8 +++---- spec/unit_tests/job_spec.rb | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index a9e7b943..1c10ea92 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,9 @@ jenkins_api_client.log # Vagrant .vagrant + +# VS Code history folder +.history + +# local gem file +*.gem diff --git a/lib/jenkins_api_client/job.rb b/lib/jenkins_api_client/job.rb index 1d130890..1d5626b2 100644 --- a/lib/jenkins_api_client/job.rb +++ b/lib/jenkins_api_client/job.rb @@ -621,7 +621,7 @@ def get_console_output(job_name, build_num = 0, start = 0, mode = 'text') # @return [Array] the names of all jobs in jenkins # def list_all(folder_path = '') - response_json = @client.api_get_request(path_encode folder_path, "tree=jobs[name]")["jobs"] + response_json = @client.api_get_request(path_encode(folder_path), "tree=jobs[name]")["jobs"] response_json.map { |job| job["name"] }.sort end @@ -646,9 +646,9 @@ def exists?(job_name) # @return [Array] filtered jobs # def list_by_status(status, jobs = [], folder_path = '') - jobs = list_all if jobs.empty? + jobs = list_all(folder_path) if jobs.empty? @logger.info "Obtaining jobs matching status '#{status}'" - json_response = @client.api_get_request(path_encode folder_path, "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 && @@ -666,7 +666,7 @@ def list_by_status(status, jobs = [], folder_path = '') # # @return [Array] jobs matching the given pattern # - def list(filter, ignorecase = true, folder_path) + def list(filter, ignorecase = true, folder_path = '') @logger.info "Obtaining jobs matching filter '#{filter}'" response_json = @client.api_get_request(path_encode folder_path) jobs = [] diff --git a/spec/unit_tests/job_spec.rb b/spec/unit_tests/job_spec.rb index 3863cd5e..a4aff90d 100644 --- a/spec/unit_tests/job_spec.rb +++ b/spec/unit_tests/job_spec.rb @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 From 8c1d664e7976ccbcb322eb4e73487de7acee0811 Mon Sep 17 00:00:00 2001 From: swaps19 Date: Sun, 19 Apr 2020 02:24:17 +0530 Subject: [PATCH 3/4] added pending functional TCs for Job class --- spec/func_tests/job_spec.rb | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/spec/func_tests/job_spec.rb b/spec/func_tests/job_spec.rb index bb678b0a..84d0deae 100644 --- a/spec/func_tests/job_spec.rb +++ b/spec/func_tests/job_spec.rb @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 From 7e9c116cf4505df536a1092eef78cfd8da0cb4b8 Mon Sep 17 00:00:00 2001 From: swaps19 Date: Sun, 19 Apr 2020 02:53:31 +0530 Subject: [PATCH 4/4] updated Readme file & added documentation to the changed methods --- README.md | 9 +++++++++ lib/jenkins_api_client/job.rb | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/README.md b/README.md index b4157053..f87fa440 100644 --- a/README.md +++ b/README.md @@ -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 @@ -171,6 +174,12 @@ want to build failed and unstable jobs, just pass ["failure", "unstable"]. 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 threshold 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 success will move to the next job only if the diff --git a/lib/jenkins_api_client/job.rb b/lib/jenkins_api_client/job.rb index 1d5626b2..05c0a6cd 100644 --- a/lib/jenkins_api_client/job.rb +++ b/lib/jenkins_api_client/job.rb @@ -642,6 +642,11 @@ def exists?(job_name) # @param jobs [Array] 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] filtered jobs # @@ -663,6 +668,11 @@ def list_by_status(status, jobs = [], folder_path = '') # # @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] jobs matching the given pattern # @@ -682,6 +692,11 @@ def list(filter, ignorecase = true, folder_path = '') # 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] the details of all jobs in jenkins # def list_all_with_details(folder_path = '') @@ -693,6 +708,11 @@ def list_all_with_details(folder_path = '') # 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 #