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
  • Star 19 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • 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
@cloudifysolutions
Copy link

Thanks mate worked like a charm

@t-anjan
Copy link

t-anjan commented Mar 9, 2014

I followed your instructions, but the include Capistrano::Git::DefaultStrategy line is causing an error.

/lib/capistrano/submodule_strategy.rb:11:in <module:SubmoduleStrategy>: uninitialized constant Capistrano::Git (NameError)

Any idea why?

@nodefourtytwo
Copy link

I have the same error as t-anjan.

@nodefourtytwo
Copy link

It requires capistrano 3.1.0 to work.

@rjksn
Copy link

rjksn commented Mar 11, 2014

For line 37 I get Unknown switch -B

DEBUG [77d89e1b] Command: cd ~/PATH/repo && ( GIT_ASKPASS=/bin/echo GIT_SSH=/FULLPATH/git-ssh.sh /usr/bin/env git checkout -B 20140311200837 origin/master )

This code is run twice, which when I switch the flag to a -b it freaks out that the branch exists.

@sld
Copy link

sld commented Apr 9, 2014

I've got

lib/capistrano/submodule_strategy.rb:24:in `clone'
DEBUG [d000b805]    fatal: destination path '/var/www/application/repo' already exists and is not an empty directory.

@cickes
Copy link

cickes commented Apr 10, 2014

@sld
from your server command line
sudo rm -rf /var/www/application/repo
Then from your workstation, deploy again via Capistrano

Your error occurs when using this gist on top of an existing project. This gist uses a different git strategy than ootb Capistrano 3.

@cickes
Copy link

cickes commented Apr 10, 2014

Great work. I forked your fork to easily exclude files from deployment (such as lib, config, etc.).

Check it out here: https://gist.github.com/cickes/10388315

@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