capsulecd 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +95 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +9 -0
  7. data/Dockerfile +16 -0
  8. data/Dockerfile.chef +26 -0
  9. data/Dockerfile.javascript +7 -0
  10. data/Dockerfile.node +7 -0
  11. data/Dockerfile.python +7 -0
  12. data/Dockerfile.ruby +4 -0
  13. data/FEATURES.md +12 -0
  14. data/Gemfile +26 -0
  15. data/LICENSE.md +22 -0
  16. data/README.md +227 -0
  17. data/Rakefile +43 -0
  18. data/bin/capsulecd +4 -0
  19. data/capsulecd.gemspec +27 -0
  20. data/circle.yml +24 -0
  21. data/lib/capsulecd/base/common/git_utils.rb +90 -0
  22. data/lib/capsulecd/base/common/validation_utils.rb +22 -0
  23. data/lib/capsulecd/base/configuration.rb +151 -0
  24. data/lib/capsulecd/base/engine.rb +163 -0
  25. data/lib/capsulecd/base/runner/circleci.rb +37 -0
  26. data/lib/capsulecd/base/runner/default.rb +38 -0
  27. data/lib/capsulecd/base/source/github.rb +183 -0
  28. data/lib/capsulecd/base/transform_engine.rb +62 -0
  29. data/lib/capsulecd/chef/chef_engine.rb +172 -0
  30. data/lib/capsulecd/chef/chef_helper.rb +29 -0
  31. data/lib/capsulecd/cli.rb +64 -0
  32. data/lib/capsulecd/error.rb +51 -0
  33. data/lib/capsulecd/javascript/javascript_engine.rb +213 -0
  34. data/lib/capsulecd/node/node_engine.rb +141 -0
  35. data/lib/capsulecd/python/python_engine.rb +157 -0
  36. data/lib/capsulecd/ruby/ruby_engine.rb +191 -0
  37. data/lib/capsulecd/ruby/ruby_helper.rb +60 -0
  38. data/lib/capsulecd/version.rb +3 -0
  39. data/lib/capsulecd.rb +16 -0
  40. data/logo.svg +1 -0
  41. data/spec/fixtures/chef/cookbook_analogj_test/CHANGELOG.md +3 -0
  42. data/spec/fixtures/chef/cookbook_analogj_test/Gemfile +18 -0
  43. data/spec/fixtures/chef/cookbook_analogj_test/LICENSE +21 -0
  44. data/spec/fixtures/chef/cookbook_analogj_test/README.md +13 -0
  45. data/spec/fixtures/chef/cookbook_analogj_test/Rakefile +1 -0
  46. data/spec/fixtures/chef/cookbook_analogj_test/Thorfile +12 -0
  47. data/spec/fixtures/chef/cookbook_analogj_test/chefignore +94 -0
  48. data/spec/fixtures/chef/cookbook_analogj_test/metadata.rb +5 -0
  49. data/spec/fixtures/chef/cookbook_analogj_test/recipes/default.rb +6 -0
  50. data/spec/fixtures/incorrect_configuration.yml +4 -0
  51. data/spec/fixtures/javascript/javascript_analogj_test/LICENSE +21 -0
  52. data/spec/fixtures/javascript/javascript_analogj_test/README.md +2 -0
  53. data/spec/fixtures/javascript/javascript_analogj_test/package.json +19 -0
  54. data/spec/fixtures/node/npm_analogj_test/LICENSE +21 -0
  55. data/spec/fixtures/node/npm_analogj_test/README.md +2 -0
  56. data/spec/fixtures/node/npm_analogj_test/package.json +19 -0
  57. data/spec/fixtures/python/pip_analogj_test/LICENSE +21 -0
  58. data/spec/fixtures/python/pip_analogj_test/MANIFEST.in +1 -0
  59. data/spec/fixtures/python/pip_analogj_test/README.md +1 -0
  60. data/spec/fixtures/python/pip_analogj_test/VERSION +1 -0
  61. data/spec/fixtures/python/pip_analogj_test/setup.cfg +5 -0
  62. data/spec/fixtures/python/pip_analogj_test/setup.py +80 -0
  63. data/spec/fixtures/python/pip_analogj_test/tox.ini +14 -0
  64. data/spec/fixtures/ruby/gem_analogj_test/Gemfile +4 -0
  65. data/spec/fixtures/ruby/gem_analogj_test/LICENSE.txt +21 -0
  66. data/spec/fixtures/ruby/gem_analogj_test/README.md +41 -0
  67. data/spec/fixtures/ruby/gem_analogj_test/Rakefile +6 -0
  68. data/spec/fixtures/ruby/gem_analogj_test/bin/console +14 -0
  69. data/spec/fixtures/ruby/gem_analogj_test/bin/setup +8 -0
  70. data/spec/fixtures/ruby/gem_analogj_test/gem_analogj_test.gemspec +25 -0
  71. data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test/version.rb +3 -0
  72. data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test.rb +5 -0
  73. data/spec/fixtures/ruby/gem_analogj_test/spec/gem_analogj_test_spec.rb +7 -0
  74. data/spec/fixtures/ruby/gem_analogj_test/spec/spec_helper.rb +2 -0
  75. data/spec/fixtures/ruby/gem_analogj_test-0.1.4.gem +0 -0
  76. data/spec/fixtures/sample_chef_configuration.yml +8 -0
  77. data/spec/fixtures/sample_configuration.yml +7 -0
  78. data/spec/fixtures/sample_global_configuration.yml +23 -0
  79. data/spec/fixtures/sample_node_configuration.yml +7 -0
  80. data/spec/fixtures/sample_python_configuration.yml +8 -0
  81. data/spec/fixtures/sample_repo_configuration.yml +22 -0
  82. data/spec/fixtures/sample_ruby_configuration.yml +5 -0
  83. data/spec/fixtures/vcr_cassettes/chef_build_step.yml +636 -0
  84. data/spec/fixtures/vcr_cassettes/gem_build_step.yml +653 -0
  85. data/spec/fixtures/vcr_cassettes/gem_build_step_without_version_rb.yml +653 -0
  86. data/spec/fixtures/vcr_cassettes/integration_chef.yml +1399 -0
  87. data/spec/fixtures/vcr_cassettes/integration_node.yml +1388 -0
  88. data/spec/fixtures/vcr_cassettes/integration_python.yml +1388 -0
  89. data/spec/fixtures/vcr_cassettes/integration_ruby.yml +1377 -0
  90. data/spec/fixtures/vcr_cassettes/node_build_step.yml +647 -0
  91. data/spec/fixtures/vcr_cassettes/pip_build_step.yml +653 -0
  92. data/spec/lib/capsulecd/base/configuration_spec.rb +75 -0
  93. data/spec/lib/capsulecd/base/engine_spec.rb +51 -0
  94. data/spec/lib/capsulecd/base/source/github_spec.rb +253 -0
  95. data/spec/lib/capsulecd/base/transform_engine_spec.rb +55 -0
  96. data/spec/lib/capsulecd/chef/chef_engine_spec.rb +114 -0
  97. data/spec/lib/capsulecd/cli_spec.rb +57 -0
  98. data/spec/lib/capsulecd/node/node_engine_spec.rb +113 -0
  99. data/spec/lib/capsulecd/python/python_engine_spec.rb +118 -0
  100. data/spec/lib/capsulecd/ruby/ruby_engine_spec.rb +128 -0
  101. data/spec/spec_helper.rb +105 -0
  102. data/spec/support/file_system.rb +21 -0
  103. data/spec/support/package_types.rb +11 -0
  104. metadata +281 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ff6c3f188e2a0119a08be46b207bcabcc00626e
4
+ data.tar.gz: 5a34e3b9147833e003349f61ec06d1aa74b1ba95
5
+ SHA512:
6
+ metadata.gz: f4dff53e8f98e6b79460650c37885892bf24030ab89f496c99bf443d66e6995915a9b1b24e9b9394fbd25f2ffa76073b788ed50809bd3b5f5e1d7267c8090aa9
7
+ data.tar.gz: e741369a67de85819e55ee990fc4b4cf71327c3369138d81ba168dd750218081fe6fd54f35fe298897e9fe8f958e7588a225bbbbf75b239be8245485e67252ed
data/.coveralls.yml ADDED
@@ -0,0 +1,2 @@
1
+ service_name: circleci
2
+ repo_token: lVl0zmYLiHlvhM6YIqr0XThDaD2EFHJHM
data/.dockerignore ADDED
@@ -0,0 +1,5 @@
1
+ # Created by .ignore support plugin (hsz.mobi)
2
+ .bundle
3
+ FEATURES.md
4
+ README.md
5
+ logo.svg
data/.gitignore ADDED
@@ -0,0 +1,95 @@
1
+ # Created by .ignore support plugin (hsz.mobi)
2
+ ### Ruby template
3
+ *.gem
4
+ *.rbc
5
+ /.config
6
+ /coverage/
7
+ /InstalledFiles
8
+ /pkg/
9
+ /spec/reports/
10
+ /spec/examples.txt
11
+ /test/tmp/
12
+ /test/version_tmp/
13
+ /tmp/
14
+
15
+ ## Specific to RubyMotion:
16
+ .dat*
17
+ .repl_history
18
+ build/
19
+
20
+ ## Documentation cache and generated files:
21
+ /.yardoc/
22
+ /_yardoc/
23
+ /doc/
24
+ /rdoc/
25
+
26
+ ## Environment normalisation:
27
+ /.bundle/
28
+ /vendor/bundle
29
+ /lib/bundler/man/
30
+
31
+ # for a library or gem, you might want to ignore these files since the code is
32
+ # intended to run in multiple environments; otherwise, check them in:
33
+ # Gemfile.lock
34
+ # .ruby-version
35
+ # .ruby-gemset
36
+
37
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
38
+ .rvmrc
39
+ ### JetBrains template
40
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
41
+
42
+ *.iml
43
+
44
+ ## Directory-based project format:
45
+ .idea/
46
+ # if you remove the above rule, at least ignore the following:
47
+
48
+ # User-specific stuff:
49
+ # .idea/workspace.xml
50
+ # .idea/tasks.xml
51
+ # .idea/dictionaries
52
+
53
+ # Sensitive or high-churn files:
54
+ # .idea/dataSources.ids
55
+ # .idea/dataSources.xml
56
+ # .idea/sqlDataSources.xml
57
+ # .idea/dynamic.xml
58
+ # .idea/uiDesigner.xml
59
+
60
+ # Gradle:
61
+ # .idea/gradle.xml
62
+ # .idea/libraries
63
+
64
+ # Mongo Explorer plugin:
65
+ # .idea/mongoSettings.xml
66
+
67
+ ## File-based project format:
68
+ *.ipr
69
+ *.iws
70
+
71
+ ## Plugin-specific files:
72
+
73
+ # IntelliJ
74
+ /out/
75
+
76
+ # mpeltonen/sbt-idea plugin
77
+ .idea_modules/
78
+
79
+ # JIRA plugin
80
+ atlassian-ide-plugin.xml
81
+
82
+ # Crashlytics plugin (for Android Studio and IntelliJ)
83
+ com_crashlytics_export_strings.xml
84
+ crashlytics.properties
85
+ crashlytics-build.properties
86
+
87
+ ## Custom ignores
88
+ container_settings.*
89
+ payload.json
90
+ test.rb
91
+ vendor
92
+ Gemfile.lock
93
+ spec/vcr.log
94
+
95
+ spec/fixtures/live_*_configuration.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --exclude-pattern "**/spec/fixtures/**/*.rb"
data/.simplecov ADDED
@@ -0,0 +1,9 @@
1
+ #fix for merging multiple test suites https://github.com/colszowka/simplecov/issues/350
2
+ #require 'coveralls'
3
+
4
+ #using ARGV.join to generate a new identifier for each coverage run (cant use PID because it'll always be 1 in the container)
5
+ SimpleCov.start do
6
+ add_filter '/spec/'
7
+ command_name "capsulecd_#{ARGV.join}"
8
+ merge_timeout 360 # 1 hour
9
+ end
data/Dockerfile ADDED
@@ -0,0 +1,16 @@
1
+ FROM ruby:2.1.8-alpine
2
+ MAINTAINER Jason Kulatunga <jason@thesparktree.com>
3
+
4
+ RUN mkdir -p /srv/capsulecd
5
+ COPY . /srv/capsulecd
6
+ workdir /srv/capsulecd
7
+
8
+ RUN apk --update --no-cache add \
9
+ build-base ruby-dev libc-dev linux-headers \
10
+ openssl-dev libxml2-dev libxslt-dev openssh git && \
11
+ mkdir ~/.ssh && \
12
+ ssh-keyscan github.com >> ~/.ssh/known_hosts && \
13
+ bundle install --without test chef
14
+
15
+ CMD ["sh"]
16
+ #CMD ["capsulecd", "start", "--runner", "circleci", "--source", "github", "--package_type", "ruby"]
data/Dockerfile.chef ADDED
@@ -0,0 +1,26 @@
1
+ from ubuntu
2
+ maintainer Jason Kulatunga <jk17@ualberta.ca>
3
+
4
+ run apt-get update
5
+ run apt-get install curl wget git make build-essential -y
6
+
7
+ run wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chefdk_0.6.2-1_amd64.deb
8
+ run dpkg -i chefdk_0.6.2-1_amd64.deb
9
+ run locale-gen en_US.UTF-8
10
+
11
+ # Make Chef DK the primary Ruby/Chef development environment.
12
+ env PATH /opt/chefdk/bin:/root/.chefdk/gem/ruby/2.1.0/bin:/opt/chefdk/embedded/bin:$PATH
13
+ env GEM_ROOT /opt/chefdk/embedded/lib/ruby/gems/2.1.0
14
+ env GEM_HOME /root/.chefdk/gem/ruby/2.1.0
15
+ env GEM_PATH /root/.chefdk/gem/ruby/2.1.0:/opt/chefdk/embedded/lib/ruby/gems/2.1.0
16
+
17
+ run which ruby
18
+ run gem install bundler
19
+
20
+ # copy the application files to the image
21
+ workdir /srv/capsulecd
22
+ run git clone https://github.com/AnalogJ/capsulecd.git .
23
+
24
+ run bundle install --with test --without node ruby python javascript
25
+ run bundle exec rake spec:chef
26
+ CMD ["bundle", "exec", "capsulecd", "start", "--runner", "circleci", "--source", "github", "--package_type", "chef"]
@@ -0,0 +1,7 @@
1
+ FROM analogj/capsulecd:latest
2
+ MAINTAINER Jason Kulatunga <jason@thesparktree.com>
3
+
4
+ RUN apk --update --no-cache add nodejs && \
5
+ npm install -g bower
6
+
7
+ CMD ["capsulecd", "start", "--source", "github", "--package_type", "javascript"]
data/Dockerfile.node ADDED
@@ -0,0 +1,7 @@
1
+ FROM analogj/capsulecd:latest
2
+ MAINTAINER Jason Kulatunga <jason@thesparktree.com>
3
+
4
+ RUN apk --update --no-cache add nodejs && \
5
+ npm install -g bower
6
+
7
+ CMD ["capsulecd", "start", "--source", "github", "--package_type", "node"]
data/Dockerfile.python ADDED
@@ -0,0 +1,7 @@
1
+ FROM analogj/capsulecd:latest
2
+ MAINTAINER Jason Kulatunga <jason@thesparktree.com>
3
+
4
+ RUN apk --update --no-cache add python python-dev py-pip && \
5
+ pip install tox
6
+
7
+ CMD ["capsulecd", "start", "--source", "github", "--package_type", "python"]
data/Dockerfile.ruby ADDED
@@ -0,0 +1,4 @@
1
+ FROM analogj/capsulecd:latest
2
+ MAINTAINER Jason Kulatunga <jason@thesparktree.com>
3
+
4
+ CMD ["capsulecd", "start", "--source", "github", "--package_type", "ruby"]
data/FEATURES.md ADDED
@@ -0,0 +1,12 @@
1
+ # Features
2
+ For this project to be viable over a standard CI platform it needs to have the following base features built in.
3
+
4
+ - [] Swappable sources (github, gitlab, bitbucket, filesystem). V1 will probably only have Github, but it should be possible to swap out the underlying source.
5
+ #Note, no matter what, the source must be a git repository of some sort.
6
+ - [] Everything should be event/hook based, and users should be able to run code before and after built in functions.
7
+ - [] All built in functions should be wrapped in conditionals, which can be turned off via the config file or environmental variables
8
+ - [] There should be a Dry Run mode of some sort, allowing the user to run the CI, without actually doing the final merging/
9
+ - [] Must support atleast chef and node packages to start, inheriting from a empty general spec
10
+ - [] Must automatically bump the package version by a minor value.
11
+ - [] Must validate the package version does not conflict with an existing package.
12
+ - [] Allow the commands being run in the base
data/Gemfile ADDED
@@ -0,0 +1,26 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ # These gems are required for testing
5
+ group :test do
6
+ gem 'rake'
7
+ gem 'rspec'
8
+ gem 'vcr'
9
+ gem 'coveralls'
10
+ gem 'webmock'
11
+ end
12
+
13
+ # These gems are required for the various sources
14
+ group :github do
15
+ gem 'octokit'
16
+ end
17
+
18
+ # These gems are required for the various language packages
19
+ group :chef do
20
+ gem 'ridley'
21
+ gem 'berkshelf'
22
+ gem 'solve'
23
+ gem 'chef'
24
+ gem 'stove'
25
+ end
26
+
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Jason Kulatunga
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,227 @@
1
+ # CapsuleCD
2
+
3
+ [![Circle CI](https://circleci.com/gh/AnalogJ/capsulecd.svg?style=shield)](https://circleci.com/gh/AnalogJ/capsulecd)
4
+ [![Coverage Status](https://coveralls.io/repos/github/AnalogJ/capsulecd/badge.svg)](https://coveralls.io/github/AnalogJ/capsulecd)
5
+ [![GitHub license](https://img.shields.io/github/license/AnalogJ/capsulecd.svg)](https://github.com/AnalogJ/capsulecd/blob/master/LICENSE)
6
+ [![Gratipay User](https://img.shields.io/gratipay/user/analogj.svg)](https://gratipay.com/~AnalogJ/)
7
+
8
+ <!--
9
+ [![Gem](https://img.shields.io/gem/dt/capsulecd.svg)]()
10
+ [![Gem](https://img.shields.io/gem/v/capsulecd.svg)]()
11
+ [![Gemnasium](https://img.shields.io/gemnasium/analogj/capsulecd.svg)]()
12
+ [![Docker Pulls](https://img.shields.io/docker/pulls/analogj/capsulecd.svg)]()
13
+ -->
14
+
15
+ CapsuleCD is a generic Continuous Delivery pipeline for versioned artifacts and libraries written in any language.
16
+ It's goal is to bring automation to the packaging and deployment stage of your library release cycle.
17
+ CapsuleCD is incredibly flexible, and works best when implemented side-by-side with a CI pipeline.
18
+
19
+ A short list of the features...
20
+
21
+ * Supports libraries written in any language. Has built-in support for
22
+ * Chef Cookbooks
23
+ * Python Pip
24
+ * NodeJS Npm Packages
25
+ * Ruby Gems
26
+ * Vanilla Javascript Bower/Npm Packages
27
+ * Highly configurable
28
+ * Follows language/library best practices. Including things like:
29
+ * automatically bumping the semvar version number
30
+ * regenerating any `*.lock` files/ shrinkwrap files with new version
31
+ * creating any recommended files (eg. `.gitignore`)
32
+ * validates all dependencies exist (by vendoring locally)
33
+ * running unit tests
34
+ * source minification
35
+ * linting library syntax
36
+ * generating code coverage reports
37
+ * updating changelog
38
+ * uploading versioned artifact to community hosting service (rubygems/supermarket/pypi/etc)
39
+ * creating a new git tag
40
+ * pushing changes back to source control (github)
41
+ * creating a new release in source control (github) and attaching any common artifacts
42
+
43
+ ## Links
44
+
45
+ * Source: <http://github.com/AnalogJ/capsulecd>
46
+ * Bugs: <http://github.com/AnalogJ/capsulecd/issues>
47
+
48
+ # Introduction
49
+
50
+ ## What is CapsuleCD
51
+
52
+ CapsuleCD is a generic Continuous Delivery pipeline for versioned artifacts and libraries written in any language.
53
+ It's goal is to bring automation to the packaging and deployment stage of your library release cycle.
54
+ It automates away all the common steps required when creating a new version of your library.
55
+
56
+ ## Why use CapsuleCD
57
+ At first glance, it seems simple to publish a new library version. Just bump the version number and publish, right?
58
+ Well, not always:
59
+
60
+ - If you're library includes a Gemfile.lock, Berksfile.lock or other most common lock files, you'll need to regenerate them.
61
+ - Everyone runs their library unit tests before creating a new release, but hat about validating that your library dependencies exist (maybe in your Company's private repo)?
62
+ - How about linting your source, to ensure that it follows common/team conventions?
63
+ - Who owns the gem? Is there one developer who has the credentials to push to RubyGems.org? Are they still on your team?
64
+ - Did you remember to tag your source when the new version was created (making it easy to determine what's changed between versions?)
65
+ - Did you update your changelog?
66
+
67
+ CapsuleCD handles all of that (and more!) for you. It pretty much guarantees that your library will have proper and consistent releases every time.
68
+ CapsuleCD is well structured and fully tested, unlike the release scripts you've manually cobbled together for each library. It can be customized as needed without rewriting from scratch.
69
+ The best part is that CapsuleCD uses CapsuleCD to automate its releases. We dogfood it so we're the first ones to find any issues with a new release.
70
+
71
+ ## How do I start?
72
+ You can use CapsuleCD to automate creating a new release from a pull request __or__ from the latest code on your default branch.
73
+
74
+ ### Automated pull request processing:
75
+
76
+ Here's how to use __docker__ to merge a pull request to your Ruby library
77
+
78
+ CAPSULE_SOURCE_GITHUB_ACCESS_TOKEN=123456789ABCDEF \
79
+ CAPSULE_RUNNER_REPO_FULL_NAME=AnalogJ/gem_analogj_test \
80
+ CAPSULE_RUNNER_PULL_REQUEST=4 \
81
+ CAPSULE_RUBYGEMS_API_KEY=ASDF12345F \
82
+ docker run AnalogJ/capsulecd:ruby capsulecd start --source github --package_type ruby
83
+
84
+ Or you could install and call CapsuleCD directly to merge a pull request to your Python library:
85
+
86
+ gem install capsulecd
87
+ CAPSULE_SOURCE_GITHUB_ACCESS_TOKEN=123456789ABCDEF \
88
+ CAPSULE_RUNNER_REPO_FULL_NAME=AnalogJ/pip_analogj_test \
89
+ CAPSULE_RUNNER_PULL_REQUEST=2 \
90
+ CAPSULE_PYPI_USERNAME=AnalogJ \
91
+ CAPSULE_PYPI_PASSWORD=mysupersecurepassword \
92
+ capsulecd start --source github --package_type python
93
+
94
+ ### Creating a branch release
95
+
96
+ TODO: add documentation on how to create a release from the master branch without a pull request. Specify the env variables required.
97
+
98
+ # Engine
99
+ Every package type is mapped to an engine class which inherits from a `BaseEngine` clas, ie `PythonEngine`, `NodeEngine`, `RubyEngine` etc.
100
+ Every source type is mapped to a source module, ie `GithubSource`. When CapsuleCD starts, it initializes the specified Engine, and loads the correct Source module.
101
+ Then it begins processing your source code step by step.
102
+
103
+ Step | Description
104
+ ------------ | ------------
105
+ source_configure | This will initialize the source client, ensuring that we can authenticate with the git server
106
+ runner_retrieve_payload | If a Pull Request # is specified, the payload is retrieved from Source api, otherwise the repo default branch HEAD info is retrived.
107
+ source_process_pull_request_payload __or__ source_process_push_payload | Depending on the retrieve_payload step, the merged pull request is cloned, or the default branch is cloned locally
108
+ build_step | Code is built, which includes adding any missing files/default structure, compilation, version bumping, etc.
109
+ test_step | Download package dependencies, run the package test runner(s) (eg. npm test, rake test, kitchen test, tox)
110
+ package_step | Commit any local changes and create a git tag. Nothing should be pushed to remote repository
111
+ release_step | Push the release to the package repository (ie. npm, chef supermarket, rubygems)
112
+ source_release | Push the merged, tested and version updated code up to the source code repository. Also do any source specific releases (github release, asset uploading, etc)
113
+
114
+ # Configuration
115
+ Specifying your `GITHUB_ACCESS_TOKEN` and `PYPI_PASSWORD` via an environmental variable might make sense, but do you
116
+ really want to specify the `PYPI_USERNAME`, `REPO_FULL_NAME` each time? Probably not.
117
+
118
+ CapsuleCD has you covered. We support a global YAML configuration file (that can be specified using the `--config-file` flag), and a repo specific YAML configuration file stored as `capsule.yml` inside the repo itself.
119
+
120
+ ## Setting Inheritance/Overrides
121
+ CapsuleCD settings are determined by loading configuration in the following order (where the last value specified is used)
122
+
123
+ - system YAML config file (`--config-file`)
124
+ - repo YAML config file (`capsule.yml`)
125
+ - environmental variables (setting in capital letters and prefixed with `CAPSULE_`)
126
+
127
+ ## Configuration Settings
128
+
129
+ Setting | System Config | Repo Config | Notes
130
+ ------------ | ------------- | ------------- | -------------
131
+ package_type | No | No | Must be set by `--package-type` flag
132
+ source | No | No | Must be set by `--source` flag
133
+ runner | No | No | Must be set by `--runner` flag
134
+ dry_run | Yes | No | Can be `YES` or `NO`
135
+ source_git_parent_path | Yes | No | Specifies the location where the git repo will be cloned, defaults to tmp directory
136
+ source_github_api_endpoint | Yes | No | Specifies the Github api endpoint to use (for use with Enterprise Github)
137
+ source_github_web_endpoint | Yes | No | Specifies the Github web endpoint to use (for use with Enterprise Github)
138
+ source_github_access_token | Yes | No | Specifies the access token to use when cloning from and committing to Github
139
+ runner_pull_request | Yes | No | Specifies the repo pull request number to clone from Github
140
+ runner_repo_full_name | Yes | No | Specifies the repo name to clone from Github
141
+ chef_supermarket_username | Yes | Yes | Specifies the Chef Supermarket username to use when creating public release for Chef cookbook
142
+ chef_supermarket_key | Yes | Yes | Specifies the Base64 encoded Chef Supermarket private key to use when creating public release for Chef cookbook
143
+ chef_supermarket_type | Yes | Yes | Specifies the Chef Supermarket cookbook type to use when creating public release for Chef cookbook
144
+ npm_auth_token | Yes | Yes | Specifies the NPM auth to use when creating public release for NPM package
145
+ pypi_username | Yes | Yes | Specifies the PYPI username to use when creating public release for Pypi package
146
+ pypi_password | Yes | Yes | Specifies the PYPI password to use when creating public release for Pypi package
147
+ engine_disable_test | Yes | Yes | Disables test_step before releasing package
148
+ engine_disable_minification | Yes | Yes | Disables source minification (if applicable) before releasing package
149
+ engine_disable_lint | Yes | Yes | Disables source linting before releasing package
150
+ engine_cmd_test | Yes | Yes | Specifies the test command to before releasing package
151
+ engine_cmd_minification | Yes | Yes | Specifies the minification command to before releasing package
152
+ engine_cmd_lint | Yes | Yes | Specifies the lint command to before releasing package
153
+ engine_version_bump_type | Yes | Yes | Specifies the Semvar segment (`major`, `minor`, `patch`) to bump before releasing package
154
+
155
+ TODO: specify the missing `BRANCH` release style settings.
156
+
157
+ As mentioned above, all settings can be specified via Environmental variable. All you need to do is convert the setting to uppercase
158
+ and then prefix it with `CAPSULE_`. So `pypi_password` can be set with `CAPSULE_PYPI_PASSWORD` and `engine_cmd_test` with `CAPSULE_ENGINE_CMD_TEST`
159
+
160
+ ### Example System Configuration File
161
+
162
+ Here's what an example system configuration file might look like:
163
+
164
+ ```
165
+ source_git_parent_path: /srv/myclonefolder
166
+ source_github_api_endpoint: https://git.mycorpsubnet.example.com/v2
167
+ source_github_web_endpoint: https://git.mycorpsubnet.example.com/v2
168
+ ```
169
+
170
+ ## Stage pre/post hooks and overrides
171
+
172
+ TODO: add example and documetnation on how to override stages.
173
+
174
+ # Testing
175
+
176
+ ## Test suite and continuous integration
177
+
178
+ CapsuleCD provides an extensive test-suite based on rspec and a full integration suite which uses VCR.
179
+ You can run the unit tests with `rake test`. The integration tests can be run by `rake 'spec:<package_type>'`.
180
+ So to run the Python integration tests you would call `rake 'spec:python'`.
181
+
182
+ CircleCI is used for continuous integration testing: <https://circleci.com/gh/AnalogJ/capsulecd>
183
+
184
+ # Contributing
185
+
186
+ If you'd like to help improve CapsuleCD, clone the project with Git by running:
187
+
188
+ $ git clone git://github.com/AnalogJ/capsulecd
189
+
190
+ Work your magic and then submit a pull request. We love pull requests!
191
+
192
+ If you find the documentation lacking, help us out and update this README.md. If you don't have the time to work on CapsuleCD, but found something we should know about, please submit an issue.
193
+
194
+ ## To-do List
195
+
196
+ We're actively looking for pull requests in the following areas:
197
+
198
+ - CapsuleCD Engines for other languages
199
+ - C#
200
+ - Objective C
201
+ - Dash
202
+ - Go
203
+ - Java
204
+ - Lua
205
+ - Rust
206
+ - Scala
207
+ - Swift
208
+ - Any others you can think of
209
+ - CapsuleCD Sources
210
+ - GitLab
211
+ - Bitbucket
212
+ - Beanstalk
213
+ - Kiln
214
+ - Any others you can think of
215
+
216
+
217
+ # Versioning
218
+
219
+ We use SemVer for versioning. For the versions available, see the tags on this repository.
220
+
221
+ # Authors
222
+
223
+ Jason Kulatunga - Initial Development - [@AnalogJ](https://github.com/AnalogJ)
224
+
225
+ #License
226
+
227
+ CapsuleCD is licensed under the MIT License - see the [LICENSE.md](https://github.com/AnalogJ/capsulecd/blob/master/LICENSE.md) file for details
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ begin
2
+ require 'rspec/core/rake_task'
3
+ require 'coveralls/rake/task'
4
+ Coveralls::RakeTask.new
5
+
6
+ PACKAGE_TYPES = Dir.entries('lib/capsulecd').select {|entry|
7
+ File.directory? File.join('lib/capsulecd',entry) and !(entry =='.' || entry == '..' || entry == 'base')
8
+ }
9
+
10
+ namespace :spec do
11
+
12
+ namespace :suite do
13
+ #spec:suite tests are language specific. only the 'python', 'javascript', 'chef', etc tests are run.
14
+ #generates 'spec:suite:python', 'spec:suite:javascript', etc.
15
+ PACKAGE_TYPES.each{|type|
16
+ RSpec::Core::RakeTask.new(type.to_sym) do |t|
17
+ t.rspec_opts = '--tag '+type
18
+ end
19
+ }
20
+ end
21
+
22
+ #unit test task, no
23
+ #generate 'spec:unit'
24
+ RSpec::Core::RakeTask.new(:unit) do |t|
25
+ options = ''
26
+ PACKAGE_TYPES.each{|type|
27
+ options +=' --tag ~'+type
28
+ }
29
+ t.rspec_opts = options
30
+ end
31
+
32
+ #spec tests run the language specific tests as well as the unit tests
33
+ #generates 'spec:python', 'spec:javascript', etc
34
+ PACKAGE_TYPES.each{|type|
35
+ task type.to_sym => ['spec:unit', 'spec:suite:'+type]
36
+ }
37
+ end
38
+
39
+ task :test => 'spec:unit'
40
+ task :default => 'spec:unit'
41
+
42
+ rescue LoadError
43
+ end
data/bin/capsulecd ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
3
+ require 'capsulecd/cli'
4
+ CapsuleCD::Cli.start(ARGV.dup)
data/capsulecd.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capsulecd/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'capsulecd'
8
+ spec.version = CapsuleCD::VERSION
9
+ spec.summary = 'CapsuleCD is a library for automating package releases (npm, cookbooks, gems, pip, jars, etc)'
10
+ spec.description = 'CapsuleCD is a library for automating package releases (npm, cookbooks, gems, pip, jars, etc)'
11
+ spec.authors = ['Jason Kulatunga (AnalogJ)']
12
+ spec.homepage = 'http://www.github.com/AnalogJ/capsulecd'
13
+ spec.license = 'MIT'
14
+
15
+ spec.required_ruby_version = '~> 2.0'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'thor'
23
+ spec.add_dependency 'json'
24
+ spec.add_dependency 'git'
25
+ spec.add_dependency 'semverly'
26
+ spec.add_dependency 'mkgitignore'
27
+ end
data/circle.yml ADDED
@@ -0,0 +1,24 @@
1
+ machine:
2
+ services:
3
+ - docker
4
+
5
+ dependencies:
6
+ override:
7
+ - docker info
8
+ - docker pull analogj/capsulecd
9
+ - docker pull analogj/capsulecd:chef
10
+ - docker pull analogj/capsulecd:javascript
11
+ - docker pull analogj/capsulecd:node
12
+ - docker pull analogj/capsulecd:python
13
+ - docker pull analogj/capsulecd:ruby
14
+
15
+ test:
16
+ override:
17
+ - docker run -e "CI=true" -v $PWD:/srv/capsulecd analogj/capsulecd:chef sh -c "bundle install --with test && rake 'spec:chef'"
18
+ - docker run -e "CI=true" -v $PWD:/srv/capsulecd analogj/capsulecd:javascript sh -c "bundle install --with test && rake 'spec:javascript'"
19
+ - docker run -e "CI=true" -v $PWD:/srv/capsulecd analogj/capsulecd:node sh -c "bundle install --with test && rake 'spec:node'"
20
+ - docker run -e "CI=true" -v $PWD:/srv/capsulecd analogj/capsulecd:python sh -c "bundle install --with test && rake 'spec:python'"
21
+ - docker run -e "CI=true" -v $PWD:/srv/capsulecd analogj/capsulecd:ruby sh -c "bundle install --with test && rake 'spec:ruby'"
22
+
23
+ - docker run -e "CI=true" -v $PWD:/srv/capsulecd analogj/capsulecd sh -c "bundle install --with test && rake 'coveralls:push'"
24
+