Skip to content

Instantly share code, notes, and snippets.

@bhaberer
Forked from stevenscg/submodule_strategy.rb
Last active January 29, 2019 20:13
Show Gist options
  • Save bhaberer/8835805 to your computer and use it in GitHub Desktop.
Save bhaberer/8835805 to your computer and use it in GitHub Desktop.
Capistrano 3.1.x Strategy to deploy git projects with submodules.
# Usage:
# 1. Drop this file into lib/capistrano/submodule_strategy.rb
# 2. Add the following to your Capfile:
# require 'capistrano/git'
# require './lib/capistrano/submodule_strategy'
# 3. Add the following to your config/deploy.rb
# set :git_strategy, SubmoduleStrategy
module SubmoduleStrategy
# do all the things a normal capistrano git session would do
include Capistrano::Git::DefaultStrategy
# check for a .git directory
def test
test! " [ -d #{repo_path}/.git ] "
end
# same as in Capistrano::Git::DefaultStrategy
def check
test! :git, :'ls-remote', repo_url
end
def clone
git :clone, '-b', fetch(:branch), '--recursive', repo_url, repo_path
end
# same as in Capistrano::Git::DefaultStrategy
def update
git :remote, :update
end
# put the working tree in a release-branch,
# make sure the submodules are up-to-date
# and copy everything to the release path
def release
release_branch = fetch(:release_branch, File.basename(release_path))
git :checkout, '-B', release_branch,
fetch(:remote_branch, "origin/#{fetch(:branch)}")
git :submodule, :update, '--init'
context.execute "rsync -ar --exclude=.git\* #{repo_path}/ #{release_path}"
end
end
@dtuite
Copy link

dtuite commented May 17, 2014

You have to escape the rsync command to make this work on ZSH

context.execute %|rsync -ar --exclude=".git\*" #{repo_path}/ #{release_path}|

@kjprince
Copy link

Can't seem to find a way to make this work.

Tasks: TOP => git:create_release => git:update => git:clone

** Invoke deploy:failed (first_time) ** Execute deploy:failed

@tomconroy
Copy link

Deploying any other branch breaks with this message:

fatal: Needed a single revision

We can fix by adding this method:

def fetch_revision
  context.capture(:git, "rev-parse --short HEAD")
end

The default strategy does context.capture(:git, "rev-parse --short fetch(:branch)") but this breaks since we're making a new branch with the release timestamp.

@Simes
Copy link

Simes commented May 22, 2014

Requiring 'capistrano/git' in your Capfile means that the git.rake is loaded twice, which leads to every Rake task in git.rake being defined twice, which leads to all of the git commands being run twice. Using the -B flag to force the second checkout to overwrite the first is a nasty hack to avoid the errors this throws. It would be better if this could be used without the extra require.

I realise that this is probably Capistrano's issue.

@henscu
Copy link

henscu commented Aug 12, 2014

I'm going to try this solution unless there are any others recently..?

https://gist.github.com/seenmyfate/11206162

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment