How to patch Travis CI's deployment tool for your needs
Travis CI is a pretty good software-as-a-service Continuous Integration server. It can deploy to many targets, including AWS BeanStalk, S3, and CodeDeploy.
However it might happen that the deploy tool (dpl) has a missing feature or doesn't do exactly what you need. Fortunately it is easy to fix and run a modified version of the tool, and I will show you how to do that.
My particular problem is that dpl allows me to upload an archive to S3 and to create a CodeDeploy deployment, but it lacks the intermediary and required step of registering a new revision based on the uploaded archive. (See #732)
To fix this:
Here is an example of fixing the code_deploy.rb to fetch S3 version and etag and register a revision before proceeding with creating the deployment:
As shown in the code, you can run it from the command line. To run it from your Travis CI build:
Enjoy!
PS: Or you can fork dpl and use your forked one, as described in Testing dpl in the context of Travis CI builds. This builds the whole dpl gem on the build VM.
However it might happen that the deploy tool (dpl) has a missing feature or doesn't do exactly what you need. Fortunately it is easy to fix and run a modified version of the tool, and I will show you how to do that.
My particular problem is that dpl allows me to upload an archive to S3 and to create a CodeDeploy deployment, but it lacks the intermediary and required step of registering a new revision based on the uploaded archive. (See #732)
To fix this:
- Subclass and fix the deployer
- Send a pull request to Travis CI :-)
- Run it as a Ruby script
Here is an example of fixing the code_deploy.rb to fetch S3 version and etag and register a revision before proceeding with creating the deployment:
# Modified Travis-CI deployment tool (dpl) provider for AWS CodeDeploy | |
# that does also correctly register the revision | |
require 'dpl/cli' | |
require 'dpl/provider' | |
require 'dpl/provider/code_deploy' | |
require 'time' | |
module DPL | |
class Provider | |
class CodeDeployWithRegister < DPL::Provider::CodeDeploy | |
experimental 'AWS Code Deploy With Register' | |
def revision_version_info | |
s3api = ::Aws::S3::Client.new(code_deploy_options) # region, credentials same for all services | |
s3obj = s3api.get_object({ | |
bucket: option(:bucket), | |
key: s3_key, | |
range: "bytes=0-1" | |
}) | |
end | |
def s3_revision | |
s3info = revision_version_info | |
{ | |
revision_type: 'S3', | |
s3_location: { | |
bucket: option(:bucket), | |
bundle_type: bundle_type, | |
key: s3_key, | |
version: s3info[:version_id], | |
e_tag: s3info[:etag] | |
} | |
} | |
end | |
def push_app | |
rev = revision() | |
if rev[:s3_location] | |
revInfo = rev[:s3_location] | |
log "Registering app revision with version=#{revInfo[:version]}, etag=#{revInfo[:e_tag]}" | |
end | |
code_deploy.register_application_revision({ | |
revision: rev, | |
application_name: options[:application] || option(:application_name), | |
description: options[:description] || default_description | |
}) | |
super | |
end | |
end | |
end | |
end | |
# EXPECTED ARGUMENTS: | |
# --bucket=.., | |
# key, application, deployment_group, | |
# optionally --region etc | |
args = [ | |
"--provider=codedeploywithregister"].concat(ARGV) | |
DPL::CLI.run(args) | |
# To test this from the command line: | |
# ruby --bucket=my-bucket --key=myapp.zip --application=my-cd-app --deployment_group=my-cd-group-staging \ | |
# --region=eu-west-1 --skip_cleanup |
As shown in the code, you can run it from the command line. To run it from your Travis CI build:
# excerpt from .travis.yml deploy: - provider: s3 local_dir: dpl_cd_upload skip_cleanup: true bucket: my-bucket region: eu-west-1 - provider: script script: ruby ./deploy_codedeploy.rb --bucket=my-bucket --key=myapp.zip --application=my-cd-app --deployment_group=my-cd-group-staging --region=eu-west-1
Enjoy!
PS: Or you can fork dpl and use your forked one, as described in Testing dpl in the context of Travis CI builds. This builds the whole dpl gem on the build VM.