capistrano-scm-jenkins 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e986ebc776893d443585515bdb498107f71a9e44
4
- data.tar.gz: 61b5bd0f5a5ea6e1d4187b66d2aafbcaa45734c6
3
+ metadata.gz: d9d496f715b9d4a38d5c1fe98dcf8dbc966084be
4
+ data.tar.gz: edcba1aeb92ad730ac7cabbb7ae284841ff0fe5e
5
5
  SHA512:
6
- metadata.gz: d8e59b049253b7894b4422a5b3442e2c65b361947511ad5d4c3a149d74577356bc35face55198de4e1aecee03a790575145410bbb466b5cec60f9b7ee6fbeba9
7
- data.tar.gz: afb2843672fe6978aafb1a9dc1f50e3ccf2c13d92c2a77bc954d985845b995a74735b1995b1eba34ff36b8c12a6fd90d9edb3dc8b7cc37e5ce2e32c2b4b40e95
6
+ metadata.gz: 91dbf110bb7d2ff0ab8357e0d0f3a5f29693f57630d4b5d9181d49d4f3e37dd30ed95b5422f38c65c7a6a4f9235f01726d482b78b4bec1ba8f99b39b27d5617f
7
+ data.tar.gz: f1a9e7ba9c056e2d74a2d4bef57e3ec16238df92b54ee908d23b5f65275e2dcab1794f58e32b724c6d901a729b2e99ab568512f382527fad21743810d826dd1b
data/.gitignore CHANGED
@@ -1,5 +1,19 @@
1
1
  *.gem
2
+ *.rbc
2
3
  .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
3
17
  pkg/*
4
18
  *.swp
5
19
  test
@@ -3,13 +3,10 @@ branches:
3
3
  only:
4
4
  - master
5
5
  rvm:
6
- - 1.8.7
7
6
  - 1.9.2
8
7
  - 1.9.3
9
8
  - 2.0.0
10
9
  - 2.1.0
11
- - jruby-18mode
12
10
  - jruby-19mode
13
- - rbx-18mode
14
- - rbx-19mode
11
+ - rbx
15
12
  - ree
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in capistrano-scm-jenkins.gemspec
4
4
  gemspec
@@ -1,48 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capistrano-scm-jenkins (0.0.9)
5
- capistrano (~> 2.0)
6
- net-netrc
7
- rubyzip (~> 0.0)
4
+ capistrano-scm-jenkins (0.1.0)
5
+ capistrano (~> 3.1)
8
6
 
9
7
  GEM
10
8
  remote: https://rubygems.org/
11
9
  specs:
12
- Platform (0.4.0)
13
- capistrano (2.15.5)
14
- highline
15
- net-scp (>= 1.0.0)
16
- net-sftp (>= 2.0.0)
17
- net-ssh (>= 2.0.14)
18
- net-ssh-gateway (>= 1.1.0)
10
+ capistrano (3.1.0)
11
+ i18n
12
+ rake (>= 10.0.0)
13
+ sshkit (~> 1.3)
19
14
  diff-lcs (1.2.5)
20
- highline (1.6.21)
21
- net-netrc (0.2.2)
22
- Platform (>= 0.3.0)
23
- net-scp (1.2.1)
24
- net-ssh (>= 2.6.5)
25
- net-sftp (2.1.2)
26
- net-ssh (>= 2.6.5)
27
- net-ssh (2.9.1)
28
- net-ssh-gateway (1.2.0)
15
+ i18n (0.6.9)
16
+ metaclass (0.0.2)
17
+ mocha (1.0.0)
18
+ metaclass (~> 0.0.1)
19
+ net-scp (1.1.2)
29
20
  net-ssh (>= 2.6.5)
21
+ net-ssh (2.8.0)
30
22
  rake (10.1.1)
31
23
  rspec (2.14.1)
32
24
  rspec-core (~> 2.14.0)
33
25
  rspec-expectations (~> 2.14.0)
34
26
  rspec-mocks (~> 2.14.0)
35
27
  rspec-core (2.14.7)
36
- rspec-expectations (2.14.4)
28
+ rspec-expectations (2.14.5)
37
29
  diff-lcs (>= 1.1.3, < 2.0)
38
- rspec-mocks (2.14.4)
39
- rubyzip (0.9.9)
30
+ rspec-mocks (2.14.5)
31
+ sshkit (1.3.0)
32
+ net-scp (>= 1.1.2)
33
+ net-ssh
34
+ term-ansicolor
35
+ term-ansicolor (1.3.0)
36
+ tins (~> 1.0)
37
+ tins (1.0.0)
40
38
 
41
39
  PLATFORMS
42
40
  ruby
43
41
  x86-mingw32
44
42
 
45
43
  DEPENDENCIES
44
+ bundler (~> 1.5)
46
45
  capistrano-scm-jenkins!
46
+ mocha
47
47
  rake
48
48
  rspec
data/NEWS.md CHANGED
@@ -1,6 +1,9 @@
1
- ## 0.0.9 (2014-07-02)
1
+ ## 0.1.0 (2014-02-11)
2
2
 
3
- * #20 Fix `mktemp` issue in OS X (thanks to @mcspring)
3
+ * Initial version for Capistrano 3
4
+ * Removes certain features:
5
+ * `:jenkins_use_unstable`
6
+ * `:jenkins_scm_log_prefix`
4
7
 
5
8
  ## 0.0.8 (2013-12-29)
6
9
 
data/README.md CHANGED
@@ -1,69 +1,70 @@
1
- # capistrano-scm-jenkins
1
+ # Capistrano::Jenkins
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/lidaobing/capistrano-scm-jenkins.png?branch=master)](http://travis-ci.org/lidaobing/capistrano-scm-jenkins) [![Gem Version](https://badge.fury.io/rb/capistrano-scm-jenkins.png)](http://badge.fury.io/rb/capistrano-scm-jenkins)
4
4
 
5
- With this plugin, you can use jenkins build artifact as a repository, and
6
- deploy your build artifact with capistrano.
5
+ Allows Capistrano to treat Jenkins as an SCM, deploying artifacts from a specified job.
7
6
 
8
- ## INSTALL
7
+ ## Installation
9
8
 
10
- gem install capistrano-scm-jenkins
9
+ Add this line to your application's Gemfile:
11
10
 
12
- ## USAGE
11
+ ```ruby
12
+ gem 'capistrano-scm-jenkins'
13
+ ```
13
14
 
14
- a sample config/deploy.rb
15
+ And then execute:
15
16
 
16
- ```ruby
17
- require 'capistrano-scm-jenkins'
17
+ ```bash
18
+ $ bundle
19
+ ```
18
20
 
19
- set :application, "example"
20
- set :repository, "http://jenkins.example.com/job/example/"
21
+ Or install it yourself as:
21
22
 
22
- set :scm, :jenkins
23
+ ```bash
24
+ $ gem install capistrano-scm-jenkins
25
+ ```
23
26
 
24
- # uncomment following line if you want deploy unstable version
25
- # set :jenkins_use_unstable, true
27
+ ## Usage
26
28
 
27
- # jenkins username and password
28
- # set :scm_username, ENV['JENKINS_USERNAME']
29
- # set :scm_password, ENV['JENKINS_PASSWORD']
30
- # or use the netrc support for curl
31
- # set :jenkins_use_netrc, true
32
- #
33
- # if you use netrc, add the following line in your $HOME/.netrc
34
- # machine jenkins.example.com login USERNAME password secret
35
- #
36
- # bypass ssl verification
37
- # set :jenkins_insecure, true
38
- #
39
- # deploy from artifact subfolder. (ex: mv zipout/#{:jenkins_artifact_path} #{destination})
40
- # set :jenkins_artifact_path, 'archive'
41
- #
42
- # deploy a single file.
43
- # set :jenkins_artifact_file, 'webapp.war'
44
- #
45
- # filter the scm log with prefix when deploy:pending
46
- # set :jenkins_scm_log_prefix, 'project_name/'
29
+ In your `Capfile`, you’ll need to `require 'capistrano-scm-jenkins`.
47
30
 
48
- set :user, 'username'
49
- set :use_sudo, false
50
- set :deploy_to, "/home/#{user}/apps/#{application}"
31
+ A sample `config/deploy.rb`:
51
32
 
52
- role :web, "test.example.com" # Your HTTP server, Apache/etc
53
- role :app, "test.example.com" # This may be the same as your `Web` server
54
- role :db, "test.example.com", :primary => true # This is where Rails migrations will run
55
- ```
33
+ ```ruby
34
+ set :application, 'my-sweet-app'
35
+ set :repo_url, 'http://my.jenkins.install/job/my-sweet-app'
36
+ set :deploy_to, "/home/#{fetch(:user)}/#{fetch(:application)}"
56
37
 
57
- for more information about capistrano, check https://github.com/capistrano/capistrano
38
+ # Jenkins username & password
39
+ set :jenkins_user, 'user'
40
+ set :jenkins_pass, 'pass'
41
+
42
+ # Deploy from artifact subfolder. (ex: mv zipout/#{:jenkins_artifact_path} #{destination})
43
+ # set :jenkins_artifact_path, 'archive'
44
+ #
45
+ # Deploy a single file.
46
+ # set :jenkins_artifact_file, 'my-api/target/webapp.war'
47
+ #
48
+ # Bypass SSL verification
49
+ # set :jenkins_insecure, true
50
+ ```
58
51
 
59
52
  ### maven module
60
53
 
61
- for the maven module, you should include the module name in your repository url. for example:
54
+ For a Maven module, you should include the module name in the `:repo_url`:
62
55
 
63
56
  ```ruby
64
- set :repository, "http://jenkins.example.com/job/example/com.example.helloworld$helloworld/"
57
+ set :repo_url, "http://jenkins.example.com/job/example/com.example.helloworld$helloworld/"
65
58
  ```
66
59
 
60
+ ## Contributing
61
+
62
+ 1. Fork it ( http://github.com/evertrue/capistrano-scm-jenkins/fork )
63
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
64
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
65
+ 4. Push to the branch (`git push origin my-new-feature`)
66
+ 5. Create new Pull Request
67
+
67
68
  ## LICENSE
68
69
 
69
70
  Permission is hereby granted, free of charge, to any person obtaining
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new :spec
@@ -1,30 +1,29 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "capistrano-scm-jenkins/version"
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano-scm-jenkins/version'
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = "capistrano-scm-jenkins"
7
- s.version = Capistrano::Scm::Jenkins::VERSION
8
- s.authors = ["LI Daobing"]
9
- s.email = ["lidaobing@gmail.com"]
10
- s.homepage = "https://github.com/lidaobing/capistrano-scm-jenkins"
11
- s.summary = %q{use jenkins as a capistrano scm}
12
- s.description = %q{
13
- With this plugin, you can use jenkins build artifact as a repository, and
14
- deploy your build artifact with capistrano.
15
- }
7
+ s.name = 'capistrano-scm-jenkins'
8
+ s.version = CapistranoScmJenkins::VERSION
9
+ s.authors = ['LI Daobing', 'Jeff Byrnes']
10
+ s.email = ['lidaobing@gmail.com', 'jeff@evertrue.com']
11
+ s.summary = %q{Use Jenkins as a Capistrano 3.x SCM.}
12
+ s.description = %q{Capistrano 3.x plugin to deploy Jenkins artifacts.}
13
+ s.homepage = "https://github.com/lidaobing/#{s.name}"
14
+ s.license = 'MIT'
16
15
 
17
- s.rubyforge_project = "capistrano-scm-jenkins"
16
+ s.rubyforge_project = 'capistrano-scm-jenkins'
18
17
 
19
- s.files = `git ls-files`.split("\n")
20
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
- s.require_paths = ["lib"]
18
+ s.files = `git ls-files -z`.split("\x0")
19
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
21
+ s.require_paths = ['lib']
23
22
 
24
- # specify any dependencies here; for example:
25
- s.add_runtime_dependency "capistrano", "~> 2.0"
26
- s.add_runtime_dependency "net-netrc"
27
- s.add_runtime_dependency "rubyzip", "~> 0.0"
28
- s.add_development_dependency "rspec"
29
- s.add_development_dependency "rake"
23
+ s.add_dependency 'capistrano', '~> 3.1'
24
+
25
+ s.add_development_dependency 'bundler', '~> 1.5'
26
+ s.add_development_dependency 'rake'
27
+ s.add_development_dependency 'rspec'
28
+ s.add_development_dependency 'mocha'
30
29
  end
@@ -1,2 +0,0 @@
1
- require "capistrano-scm-jenkins/version"
2
- require "capistrano/recipes/deploy/scm/jenkins"
@@ -1,7 +1,3 @@
1
- module Capistrano
2
- module Scm
3
- module Jenkins
4
- VERSION = "0.0.9"
5
- end
6
- end
1
+ module CapistranoScmJenkins
2
+ VERSION = '0.1.0'
7
3
  end
@@ -0,0 +1,125 @@
1
+ load File.expand_path('../tasks/jenkins.rake', __FILE__)
2
+
3
+ require 'capistrano/scm'
4
+ require 'open-uri'
5
+ require 'json'
6
+
7
+ # Jenkins as SCM for Capistrano
8
+ #
9
+ # @author Jeff Byrnes <jeff@evertrue.com>
10
+ #
11
+ class Capistrano::Jenkins < Capistrano::SCM
12
+ def jenkins_user
13
+ @jenkins_user ||= begin
14
+ if fetch(:jenkins_user)
15
+ fetch(:jenkins_user)
16
+ else
17
+ nil
18
+ end
19
+ end
20
+ end
21
+
22
+ def jenkins_pass
23
+ @jenkins_pass ||= begin
24
+ if fetch(:jenkins_pass)
25
+ fetch(:jenkins_pass)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+ end
31
+
32
+ def ssl_opts
33
+ if fetch(:jenkins_insecure)
34
+ { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }
35
+ else
36
+ { ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER }
37
+ end
38
+ end
39
+
40
+ def auth_opts
41
+ if jenkins_user && jenkins_pass
42
+ { http_basic_authentication: [jenkins_user, jenkins_pass] }
43
+ else
44
+ {}
45
+ end
46
+ end
47
+
48
+ def curl_auth
49
+ if jenkins_user && jenkins_pass
50
+ "--user '#{jenkins_user}:#{jenkins_pass}'"
51
+ else
52
+ ''
53
+ end
54
+ end
55
+
56
+ def artifact_filename
57
+ @artifact_filename = File.basename(fetch(:jenkins_artifact_file))
58
+ end
59
+
60
+ def artifact_ext
61
+ @artifact_ext = File.extname(artifact_filename)
62
+ end
63
+
64
+ def artifact_url
65
+ artifact = fetch(:jenkins_artifact_file)
66
+ artifact_url_prefix = "#{repo_url}/lastBuild/artifact"
67
+
68
+ if artifact
69
+ "#{artifact_url_prefix}/#{artifact}"
70
+ else
71
+ "#{artifact_url_prefix}/*zip*/archive.zip"
72
+ end
73
+ end
74
+
75
+ def last_build_number
76
+ @last_build_number = jenkins_api_res['number']
77
+ end
78
+
79
+ def jenkins_api_res
80
+ jenkins_job_api_url = "#{repo_url}/lastBuild/api/json"
81
+
82
+ res ||= open(jenkins_job_api_url, auth_opts.merge(ssl_opts)).read
83
+
84
+ @jenkins_api_res = JSON.parse(res)
85
+ rescue => e
86
+ abort "Request to '#{jenkins_job_api_url}'} failed: #{e}"
87
+ end
88
+
89
+ # The Capistrano default strategy for git. You should want to use this.
90
+ module DefaultStrategy
91
+ def test
92
+ test! " [ -d #{repo_path} ] "
93
+ end
94
+
95
+ def check
96
+ res = jenkins_api_res
97
+ build_status = res['result'].downcase
98
+
99
+ set :current_revision, "build #{last_build_number}"
100
+
101
+ if build_status == 'success'
102
+ true
103
+ else
104
+ abort 'Latest build status isn’t green!'
105
+ end
106
+ end
107
+
108
+ def clone
109
+ # Left unimplemented, as Jenkins has no analog to `git clone`
110
+ context.execute :mkdir, '-p', repo_path
111
+
112
+ true
113
+ end
114
+
115
+ def update
116
+ # grab the newest artifact
117
+ context.execute :curl, "--silent --fail --show-error #{curl_auth} " +
118
+ "#{artifact_url} -o #{fetch(:application)}#{artifact_ext}"
119
+ end
120
+
121
+ def release
122
+ context.execute :cp, "#{fetch(:application)}#{artifact_ext}", release_path
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,48 @@
1
+ namespace :jenkins do
2
+
3
+ def strategy
4
+ @strategy ||= Capistrano::Jenkins.new(
5
+ self,
6
+ fetch(:jenkins_strategy, Capistrano::Jenkins::DefaultStrategy))
7
+ end
8
+
9
+ desc 'Check that Jenkins is reachable & the last build is green'
10
+ task :check do
11
+ on release_roles :all do
12
+ strategy.check
13
+ end
14
+ end
15
+
16
+ desc 'Clone the repo to the cache'
17
+ task clone: :'jenkins:check' do
18
+ on release_roles :all do
19
+ if strategy.test
20
+ info t(:mirror_exists, at: repo_path)
21
+ else
22
+ within deploy_path do
23
+ debug "We’re not cloning anything, just creating #{repo_path}"
24
+ strategy.clone
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ desc 'Update the repo mirror to reflect the origin state'
31
+ task update: :'jenkins:clone' do
32
+ on release_roles :all do
33
+ within repo_path do
34
+ strategy.update
35
+ end
36
+ end
37
+ end
38
+
39
+ desc 'Copy repo to releases'
40
+ task create_release: :'jenkins:update' do
41
+ on release_roles :all do
42
+ within repo_path do
43
+ execute :mkdir, '-p', release_path
44
+ strategy.release
45
+ end
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-scm-jenkins
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LI Daobing
8
+ - Jeff Byrnes
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-07-02 00:00:00.000000000 Z
12
+ date: 2014-02-13 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: capistrano
@@ -16,42 +17,42 @@ dependencies:
16
17
  requirements:
17
18
  - - "~>"
18
19
  - !ruby/object:Gem::Version
19
- version: '2.0'
20
+ version: '3.1'
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - "~>"
25
26
  - !ruby/object:Gem::Version
26
- version: '2.0'
27
+ version: '3.1'
27
28
  - !ruby/object:Gem::Dependency
28
- name: net-netrc
29
+ name: bundler
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ">="
32
+ - - "~>"
32
33
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
34
+ version: '1.5'
35
+ type: :development
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
- - - ">="
39
+ - - "~>"
39
40
  - !ruby/object:Gem::Version
40
- version: '0'
41
+ version: '1.5'
41
42
  - !ruby/object:Gem::Dependency
42
- name: rubyzip
43
+ name: rake
43
44
  requirement: !ruby/object:Gem::Requirement
44
45
  requirements:
45
- - - "~>"
46
+ - - ">="
46
47
  - !ruby/object:Gem::Version
47
- version: '0.0'
48
- type: :runtime
48
+ version: '0'
49
+ type: :development
49
50
  prerelease: false
50
51
  version_requirements: !ruby/object:Gem::Requirement
51
52
  requirements:
52
- - - "~>"
53
+ - - ">="
53
54
  - !ruby/object:Gem::Version
54
- version: '0.0'
55
+ version: '0'
55
56
  - !ruby/object:Gem::Dependency
56
57
  name: rspec
57
58
  requirement: !ruby/object:Gem::Requirement
@@ -67,7 +68,7 @@ dependencies:
67
68
  - !ruby/object:Gem::Version
68
69
  version: '0'
69
70
  - !ruby/object:Gem::Dependency
70
- name: rake
71
+ name: mocha
71
72
  requirement: !ruby/object:Gem::Requirement
72
73
  requirements:
73
74
  - - ">="
@@ -80,10 +81,10 @@ dependencies:
80
81
  - - ">="
81
82
  - !ruby/object:Gem::Version
82
83
  version: '0'
83
- description: "\nWith this plugin, you can use jenkins build artifact as a repository,
84
- and\ndeploy your build artifact with capistrano.\n "
84
+ description: Capistrano 3.x plugin to deploy Jenkins artifacts.
85
85
  email:
86
86
  - lidaobing@gmail.com
87
+ - jeff@evertrue.com
87
88
  executables: []
88
89
  extensions: []
89
90
  extra_rdoc_files: []
@@ -99,11 +100,12 @@ files:
99
100
  - capistrano-scm-jenkins.gemspec
100
101
  - lib/capistrano-scm-jenkins.rb
101
102
  - lib/capistrano-scm-jenkins/version.rb
102
- - lib/capistrano/recipes/deploy/scm/jenkins.rb
103
- - spec/capistrano/recipes/deploy/scm/jenkins_spec.rb
103
+ - lib/capistrano/jenkins.rb
104
+ - lib/capistrano/tasks/jenkins.rake
104
105
  - spec/spec_helper.rb
105
106
  homepage: https://github.com/lidaobing/capistrano-scm-jenkins
106
- licenses: []
107
+ licenses:
108
+ - MIT
107
109
  metadata: {}
108
110
  post_install_message:
109
111
  rdoc_options: []
@@ -121,10 +123,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
123
  version: '0'
122
124
  requirements: []
123
125
  rubyforge_project: capistrano-scm-jenkins
124
- rubygems_version: 2.3.0
126
+ rubygems_version: 2.2.0.rc.1
125
127
  signing_key:
126
128
  specification_version: 4
127
- summary: use jenkins as a capistrano scm
129
+ summary: Use Jenkins as a Capistrano 3.x SCM.
128
130
  test_files:
129
- - spec/capistrano/recipes/deploy/scm/jenkins_spec.rb
130
131
  - spec/spec_helper.rb
@@ -1,252 +0,0 @@
1
- require 'open-uri'
2
- require 'tmpdir'
3
- require 'rexml/document'
4
-
5
- require 'capistrano/logger'
6
- require 'capistrano/recipes/deploy/scm/base'
7
- require 'net/netrc'
8
- require 'fileutils'
9
- require 'open-uri'
10
- require 'zip/zip'
11
-
12
- module Capistrano
13
- module Deploy
14
- module SCM
15
- class Jenkins < Base
16
- def head
17
- last_deploy_build
18
- end
19
-
20
- def query_revision(revision)
21
- return revision if revision.to_s =~ /^\d+$/
22
- raise "invalid revision: #{revision}"
23
- end
24
-
25
- def checkout(revision, destination)
26
- execute = []
27
-
28
- unless destination.end_with?('/')
29
- destination = destination.to_s + '/'
30
- end
31
-
32
- execute << 'TMPDIR=`mktemp -d 2>/dev/null || mktemp -d -t .deploy_tempdir`'
33
- execute << 'cd $TMPDIR'
34
- execute << "curl #{curl_interface} #{insecure} #{authentication} -sO '#{artifact_url(revision)}'"
35
- if artifact = variable(:jenkins_artifact_file)
36
- execute << "mkdir '#{destination}'"
37
- execute << "mv #{File.basename(artifact)} '#{destination}'"
38
- elsif variable(:jenkins_artifact_path)
39
- execute << 'unzip archive.zip -d \'out/\''
40
- execute << "mv out/#{variable(:jenkins_artifact_path)} #{destination}"
41
- else
42
- execute << "unzip archive.zip -d \"#{destination}\""
43
-
44
- end
45
- execute << 'rm -rf "$TMPDIR"'
46
-
47
- execute.compact.join(' && ').gsub(/\s+/, ' ')
48
- rescue ArgumentError => e
49
- logger.log(Logger::IMPORTANT, e.message)
50
- exit
51
- end
52
-
53
- alias_method :export, :checkout
54
-
55
- def log(from, to=nil)
56
- log_build_message(from, to)
57
- log_scm_message(from, to)
58
- 'true'
59
- end
60
-
61
- def diff(from, to=nil)
62
- logger.info 'jenkins does not support diff'
63
- 'true'
64
- end
65
-
66
- private
67
-
68
- def authentication
69
- if variable(:jenkins_use_netrc)
70
- "--netrc"
71
- elsif variable(:scm_username) and variable(:scm_password)
72
- "--user '#{variable(:scm_username)}:#{variable(:scm_password)}'"
73
- else
74
- ""
75
- end
76
- end
77
-
78
- def insecure
79
- if variable(:jenkins_insecure)
80
- '--insecure'
81
- else
82
- ''
83
- end
84
- end
85
-
86
- def curl_interface
87
- if variable(:jenkins_curl_interface)
88
- "--interface '#{variable(:jenkins_curl_interface)}'"
89
- else
90
- ''
91
- end
92
- end
93
-
94
- def use_unstable?
95
- !!variable(:jenkins_use_unstable)
96
- end
97
-
98
- def log_build_message(from, to=nil, message=nil)
99
- message = rss_all if message.nil?
100
- doc = REXML::Document.new(message).root
101
- logger.info ''
102
- logger.info "BUILD LOG"
103
- logger.info '========='
104
- REXML::XPath.each(doc, "./entry") do |entry|
105
- title = REXML::XPath.first(entry, "./title").text
106
- time = REXML::XPath.first(entry, "./updated").text
107
- build_number = get_build_number_from_rss_all_title(title).to_i
108
- if build_number > from.to_i and (to.nil? or build_number <= to.to_i)
109
- logger.info "#{time}\t#{title}"
110
- end
111
- end
112
- end
113
-
114
- def log_scm_message(from, to=nil, message=nil)
115
- message = rss_changelog if message.nil?
116
- doc = REXML::Document.new(message).root
117
- logger.info "SCM LOG"
118
- logger.info '======='
119
- REXML::XPath.each(doc, "./entry") do |entry|
120
- title = REXML::XPath.first(entry, "./title").text
121
- time = REXML::XPath.first(entry, "./updated").text
122
- content = REXML::XPath.first(entry, "./content").text
123
- build_number = get_build_number_from_rss_changelog_title(title).to_i
124
- if build_number > from.to_i \
125
- and (to.nil? or build_number <= to.to_i) \
126
- and scm_message_useful?(content, variable(:jenkins_scm_log_prefix))
127
- logger.info "#{time}\t#{title}"
128
- logger.info "#{content}"
129
- end
130
- end
131
- end
132
-
133
- def scm_message_useful?(content, prefix)
134
- return true if prefix.nil?
135
- content.each_line do |line|
136
- return true if line.start_with? prefix
137
- end
138
- false
139
- end
140
-
141
- def last_deploy_build(message = nil, opts={})
142
- message = rss_all if message.nil?
143
- use_unstable = opts[:use_unstable]
144
- use_unstable = use_unstable? if use_unstable.nil?
145
- doc = REXML::Document.new(message).root
146
- valid_end_strings = ['(back to normal)', '(stable)']
147
- if use_unstable
148
- valid_end_strings << '(unstable)'
149
- end
150
- REXML::XPath.each(doc, "./entry/title") do |title|
151
- title = title.text
152
- for x in valid_end_strings
153
- return get_build_number_from_rss_all_title(title) if title.end_with? x
154
- end
155
- end
156
- raise 'can not find a build suitable for deploy'
157
- end
158
-
159
- def get_build_number_from_rss_all_title(title)
160
- /#(\d+) /.match(strip_right_parentheses(title))[1]
161
- end
162
-
163
- def get_build_number_from_rss_changelog_title(title)
164
- /^#(\d+) /.match(title)[1]
165
- end
166
-
167
- def strip_right_parentheses(title)
168
- return title if title.slice(title.size-1, 1) != ')'
169
- count = 1
170
- (title.size-2).downto(0).each do |idx|
171
- count += 1 if title.slice(idx, 1) == ')'
172
- count -= 1 if title.slice(idx, 1) == '('
173
- return title.slice(0, idx) if count == 0
174
- end
175
- return ""
176
- end
177
-
178
- def rss_all
179
- begin
180
- @rss_all ||= open(repository + '/rssAll', accept_language.merge(auth_opts).merge(ssl_opts)).read()
181
- rescue => e
182
- raise Capistrano::Error, "open url #{repository + '/rssAll'} failed: #{e}"
183
- end
184
- end
185
-
186
- def rss_changelog
187
- @rss_changelog ||= open(repository + '/rssChangelog', accept_language.merge(auth_opts).merge(ssl_opts)).read()
188
- end
189
-
190
- def accept_language
191
- {"Accept-Language" => "en-US"}
192
- end
193
-
194
- def auth_opts
195
- if jenkins_username and jenkins_password
196
- {:http_basic_authentication => [jenkins_username, jenkins_password]}
197
- else
198
- {}
199
- end
200
- end
201
-
202
- def ssl_opts
203
- if variable(:jenkins_insecure)
204
- {:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}
205
- else
206
- {}
207
- end
208
- end
209
-
210
- def artifact_url(revision)
211
- if artifact = variable(:jenkins_artifact_file)
212
- "#{repository}/#{revision}/artifact/#{artifact}"
213
- else
214
- "#{repository}/#{revision}/artifact/*zip*/archive.zip"
215
- end
216
- end
217
-
218
- def jenkins_username
219
- @jenkins_username ||= begin
220
- if variable(:jenkins_use_netrc)
221
- rc = Net::Netrc.locate(jenkins_hostname)
222
- raise ".netrc missing or no entry found" if rc.nil?
223
- rc.login
224
- elsif variable(:scm_username)
225
- variable(:scm_username)
226
- else
227
- nil
228
- end
229
- end
230
- end
231
-
232
- def jenkins_password
233
- @jenkins_password ||= begin
234
- if variable(:jenkins_use_netrc)
235
- rc = Net::Netrc.locate(jenkins_hostname)
236
- raise ".netrc missing or no entry found" if rc.nil?
237
- rc.password
238
- elsif variable(:scm_password)
239
- variable(:scm_password)
240
- else
241
- nil
242
- end
243
- end
244
- end
245
-
246
- def jenkins_hostname
247
- @jenkins_hostname ||= URI.parse(repository).host
248
- end
249
- end
250
- end
251
- end
252
- end
@@ -1,66 +0,0 @@
1
- require 'spec_helper'
2
- require 'capistrano/recipes/deploy/scm/jenkins'
3
-
4
- module Capistrano::Deploy::SCM
5
- describe Jenkins do
6
- before :each do
7
- @jenkins = Jenkins.new
8
- end
9
-
10
- context "last_deploy_build" do
11
- it "should support back to normal" do
12
- msg = %Q{<?xml version="1.0" encoding="UTF-8"?>
13
- <feed xmlns="http://www.w3.org/2005/Atom"><title>estore-nginx all builds</title><link type="text/html" href="http://ci.eb.in.sdo.com/view/eStore/job/estore-nginx/" rel="alternate"/><updated>2011-11-24T07:11:06Z</updated><author><name>Jenkins Server</name></author><id>urn:uuid:903deee0-7bfa-11db-9fe1-0800200c9a66</id><entry><title>estore-nginx #2 (back to normal)</title><link type="text/html" href="http://ci.eb.in.sdo.com/view/eStore/job/estore-nginx/2/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:estore-nginx:2011-11-24_15-11-06</id><published>2011-11-24T07:11:06Z</published><updated>2011-11-24T07:11:06Z</updated></entry><entry><title>estore-nginx #1 (broken for a long time)</title><link type="text/html" href="http://ci.eb.in.sdo.com/view/eStore/job/estore-nginx/1/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:estore-nginx:2011-11-24_15-09-18</id><published>2011-11-24T07:09:18Z</published><updated>2011-11-24T07:09:18Z</updated></entry></feed>}
14
- @jenkins.send(:last_deploy_build, msg).should == '2'
15
- end
16
-
17
- it "should support stable" do
18
- msg = %Q{<?xml version="1.0" encoding="UTF-8"?>
19
- <feed xmlns="http://www.w3.org/2005/Atom"><title>cerl all builds</title><link type="text/html" href="http://ci.eb.in.sdo.com/view/eStore/job/cerl/" rel="alternate"/><updated>2011-11-17T05:17:58Z</updated><author><name>Jenkins Server</name></author><id>urn:uuid:903deee0-7bfa-11db-9fe1-0800200c9a66</id><entry><title>cerl #98 (stable)</title><link type="text/html" href="http://ci.eb.in.sdo.com/view/eStore/job/cerl/98/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:cerl:2011-11-17_13-17-58</id><published>2011-11-17T05:17:58Z</published><updated>2011-11-17T05:17:58Z</updated></entry><entry><title>cerl #97 (stable)</title><link type="text/html" href="http://ci.eb.in.sdo.com/view/eStore/job/cerl/97/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:cerl:2011-11-12_18-27-58</id><published>2011-11-12T10:27:58Z</published><updated>2011-11-12T10:27:58Z</updated></entry></feed>}
20
- @jenkins.send(:last_deploy_build, msg).should == '98'
21
- end
22
-
23
- it "should honor unstable" do
24
- msg = %Q{<?xml version="1.0" encoding="UTF-8"?>
25
- <feed xmlns="http://www.w3.org/2005/Atom"><title>IndexCoordinator all builds</title><link type="text/html" href="http://ci.eb.in.sdo.com/job/IndexCoordinator/" rel="alternate"/><updated>2011-11-24T09:22:32Z</updated><author><name>Jenkins Server</name></author><id>urn:uuid:903deee0-7bfa-11db-9fe1-0800200c9a66</id><entry><title>IndexCoordinator #1450 (unstable)</title><link type="text/html" href="http://ci.eb.in.sdo.com/job/IndexCoordinator/1450/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:IndexCoordinator:2011-11-22_19-44-23</id><published>2011-11-22T11:44:23Z</published><updated>2011-11-22T11:44:23Z</updated></entry><entry><title>IndexCoordinator #1449 (back to normal)</title><link type="text/html" href="http://ci.eb.in.sdo.com/job/IndexCoordinator/1449/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:IndexCoordinator:2011-11-22_19-23-22</id><published>2011-11-22T11:23:22Z</published><updated>2011-11-22T11:23:22Z</updated></entry><entry><title>IndexCoordinator #1448 (broken since this build)</title><link type="text/html" href="http://ci.eb.in.sdo.com/job/IndexCoordinator/1448/" rel="alternate"/><id>tag:hudson.dev.java.net,2011:IndexCoordinator:2011-11-22_19-10-50</id><published>2011-11-22T11:10:50Z</published><updated>2011-11-22T11:10:50Z</updated></entry></feed>
26
- }
27
- @jenkins.send(:last_deploy_build, msg).should == '1449'
28
- @jenkins.send(:last_deploy_build, msg, :use_unstable => true).should == '1450'
29
- end
30
- end
31
-
32
- context 'get_build_number_from_rss_all_title' do
33
- {
34
- "account #22 (1 more test is failing (total 19))" => 22,
35
- "account #37 (stable)" => 37
36
- }.each do |text, build_number|
37
- it "should convert `#{text}` to `#{build_number}`" do
38
- @jenkins.send(:get_build_number_from_rss_all_title, text).should == "#{build_number}"
39
- end
40
- end
41
- end
42
-
43
- context 'strip_right_parentheses' do
44
- {
45
- "account #22 (1 more test is failing (total 19))" => "account #22 ",
46
- "account #37 (stable)" => "account #37 "
47
- }.each do |from, to|
48
- it "should convert `#{from}` to `#{to}`" do
49
- @jenkins.send(:strip_right_parentheses, from).should == to
50
- end
51
- end
52
- end
53
-
54
- context 'scm_message_useful?' do
55
- {
56
- "a" => true,
57
- "b" => false,
58
- "b\na\n" => true
59
- }.each do |from, to|
60
- it "should treat `#{from}` as #{to ? "useful" : "not useful"}" do
61
- @jenkins.send(:scm_message_useful?, from, "a").should == to
62
- end
63
- end
64
- end
65
- end
66
- end