Skip to content

Commit

Permalink
Init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
romanrod committed Feb 26, 2021
0 parents commit 8e64ccc
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM ruby

COPY Gemfile /Gemfile
COPY Gemfile.lock /Gemfile.lock
COPY jenkins /jenkins

COPY jenkins_job.rb /jenkins_job.rb

RUN bundle install

ENTRYPOINT [ "ruby", "/jenkins_job.rb" ]
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'rest-client'
29 changes: 29 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
GEM
remote: https://rubygems.org/
specs:
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
http-accept (1.7.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0225)
netrc (0.11.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)

PLATFORMS
x86_64-darwin-18

DEPENDENCIES
rest-client

BUNDLED WITH
2.2.2
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# jenkins-job-trigger-action

Triggers Jenkins Jobs from GitHub actions

This action allows to trigger a job on Jenkins and get the build result.

```
name: Your GHA
on:
pull_request:
types: [opened, synchronize]
jobs:
your_job_name:
name: Trigger Jenkins Job
runs-on: ubuntu-latest
steps:
- name: Trigger your-awesome-job-name job
uses: toptal/jenkins-job-trigger-action@master
with:
jenkins_url: "https://your.jenkins.url/"
jenkins_user: ${{ secrets.JENKINS_USER }}
jenkins_token: ${{ secrets.JENKINS_TOKEN }}
job_name: "the-name-of-your-jenkins-job"
job_params: '{"param_1":"value_1", "param_2":"value_2"}'
job_timeout: "3600" # Default 30 sec. (optional)
```
12 changes: 12 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

task default: :git_release

task :git_release do
version = `cat VERSION`
`git add VERSION`
`git commit -m "Version bump to #{version}"`
`git push origin master`
`git tag -a -m "Tagging version #{version}" #{version}`
`git push origin #{version}`
end
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1
26 changes: 26 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 'Run Jenkins Job and get build result'
description: 'Triggers Jenkins Job and get build result'
author: 'Toptal'
inputs:
jenkins_url:
description: 'Jenkins domain URL'
jenkins_user:
description: 'Jenkins username'
jenkins_token:
description: 'Jenkins token generated by user'
job_name:
description: 'Jenkins job to triggered and follow up'
job_params:
description: 'Jenkins build job parameters'
required: false
job_timeout:
description: 'Jenkins job timeout period. Default 30 seconds'
required: false
default: '30'
runs:
using: 'docker'
image: 'Dockerfile'

branding:
icon: 'check-circle'
color: 'green'
126 changes: 126 additions & 0 deletions jenkins/job_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
require 'rest-client'
require 'json'
module Jenkins
class JobClient

attr_reader :jenkins_url, :jenkins_user, :jenkins_token, :job_name, :job_params, :job_timeout

DEFAULT_TIMEOUT = 30
INTERVAL_SECONDS = 10

def initialize(args)
@jenkins_url = args['INPUT_JENKINS_URL']
@jenkins_user = args['INPUT_JENKINS_USER']
@jenkins_token = args['INPUT_JENKINS_TOKEN']
@job_name = args['INPUT_JOB_NAME']
@job_params = JSON.parse(args['INPUT_JOB_PARAMS'])
@job_timeout = args['INPUT_JOB_TIMEOUT'] || DEFAULT_TIMEOUT
end

def call
crumb = get_crumb
queue_item_location = queue_job(crumb, job_name, job_params)
job_run_url = get_job_run_url(queue_item_location, job_timeout)
puts "Job run URL: #{job_run_url}"
job_progress(job_run_url, job_timeout)
exit(0)
end

def perform_request(url, method = :get, **args)
response = RestClient::Request.execute method: method, url: url, user: jenkins_user, password: jenkins_token, args: args
response_code = response.code
raise "Error on #{method} to #{url} [#{response_code}]" unless (200..299).include? response_code
response
end


def get_crumb
response = perform_request("#{jenkins_url}/crumbIssuer/api/json", headers: {'content-type': 'application/json'})
JSON.parse(response)['crumb']
end


def queue_job(crumb, job_name, job_params)
query_string = ''
job_params&.each_pair { |k, v| query_string +="#{k}=#{v}&" }
job_queue_url = "#{jenkins_url}job/#{job_name}/buildWithParameters?#{query_string}".chop
queue_response = perform_request(job_queue_url, :post, params: { 'token': jenkins_token }, headers: {'Jenkins-Crumb': crumb})
queue_item_location = queue_response.headers[:location]
queue_item_location
end


def get_job_run_url(queue_item_location, job_timeout = DEFAULT_TIMEOUT)
job_run_url = nil
job_timeout = job_timeout.to_i if job_timeout.is_a? String
timeout_countdown = job_timeout

while job_run_url.nil? && timeout_countdown.positive?
begin
job_run_response = perform_request("#{queue_item_location}api/json", :get)
job_run_response_executable = nil
job_run_response_executable = JSON.parse(job_run_response)['executable']
if job_run_response_executable
job_run_url = job_run_response_executable['url']
end
rescue
# NOOP
end
if job_run_url.nil?
timeout_countdown -= sleep(INTERVAL_SECONDS)
end
end

if job_run_url
return job_run_url
elsif timeout_countdown.zero?
fail!("JOB TRIGGER TIMED OUT (After #{job_timeout} seconds)")
else
fail!("JOB TRIGGER FAILED.")
end
job_run_url
end

def job_progress(job_run_url, job_timeout = DEFAULT_TIMEOUT)
job_timeout = job_timeout.to_i if job_timeout.is_a? String
job_progress_url = "#{job_run_url}api/json"
job_log_url = "#{job_run_url}logText/progressiveText"
build_response = nil
build_result = nil
timeout_countdown = job_timeout
while build_result.nil? and timeout_countdown > 0
begin
build_response = perform_request(job_progress_url, :get)
result = JSON.parse(build_response)['result']
build_result = result || build_result
rescue
# "NOOP"
end
if build_result.nil?
timeout_countdown = timeout_countdown - sleep(INTERVAL_SECONDS)
elsif build_result == 'ABORTED'
fail!('JOB ABORTED')
end
end
if build_result == 'SUCCESS'
puts 'DDL validation with SUCCESS status!'
elsif timeout_countdown == 0
fail!("JOB FOLLOW TIMED OUT (After #{job_timeout} seconds)")
else
puts "DDL validation with #{build_result} status."
begin
log_response = perform_request(job_log_url, :get)
puts log_response.body.force_encoding('utf-8')
rescue
puts 'Couldn\'t retrieve log messages.'
end
exit(1)
end
end

def fail!(message = nil)
puts message if message
exit(1)
end
end
end
4 changes: 4 additions & 0 deletions jenkins_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

require_relative 'jenkins/job_client'
Jenkins::JobClient.new(ENV).call

0 comments on commit 8e64ccc

Please sign in to comment.