capistrano v3 deploy git repository and its submod

2019-02-11 03:01发布

With capistrano v2 submodules can be includes in the deploy by using option:

set :git_enable_submodules, 1

In v3 this does not seem to work. Is this option still supported or is there a new way to reach the same goal?

4条回答
唯我独甜
2楼-- · 2019-02-11 03:31

In capistrano 3.1.x and later you can implement your own SCM strategy. There is an available gem that helps with git submodule, please see: https://github.com/i-ekho/capistrano-git-submodule-strategy.

NOTE: you may have problem with the repo folder if you already tried with the default git strategy. Simply go to the deploy directory on server and remove it and then run cap deploy again to fix.

查看更多
闹够了就滚
3楼-- · 2019-02-11 03:42

The new Pull Request "828" is trying to implement that again: https://github.com/capistrano/capistrano/pull/828

As discussed by @coffeeaddict, this Commit is a scrap of the code you will need to deploy locally until it's bundled with the capistrano itself. Please note that you need Capistrano >= 3.1.0 to use the code.

There is also another Gist that suggest to fix some issues of the strategy above.

查看更多
神经病院院长
4楼-- · 2019-02-11 03:44

As you can see in the Capistrano source code https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake#L34 and https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake#L56 it uses git archive to check out the code into the release directory.

The code is reproduced here:

desc 'Clone the repo to the cache'
task clone: :'git:wrapper' do
  on roles :all do
    if test " [ -f #{repo_path}/HEAD ] "
      info t(:mirror_exists, at: repo_path)
    else
      within deploy_path do
        with git_environmental_variables do
          execute :git, :clone, '--mirror', repo_url, repo_path
        end
      end
    end
  end
end
desc 'Update the repo mirror to reflect the origin state'
task update: :'git:clone' do
  on roles :all do
    within repo_path do
      execute :git, :remote, :update
    end
  end
end
desc 'Copy repo to releases'
task create_release: :'git:update' do
  on roles :all do
    with git_environmental_variables do
    within repo_path do
      execute :mkdir, '-p', release_path
      execute :git, :archive, fetch(:branch), '| tar -x -C', release_path
    end
  end
 end

From that we can ascertain that submodules are not supported. As the commands to clone or initialize submodules are never issued, and git-archive ignores them.

The decision was made (source: Capistrano author here) not to include submodules "out of the box" as the hooks needed to build this in, if you need it are already there, and it's trivial to write an add-on task that does what you need to checkout/update submodules in a way that works for you. The Capistrano v2 submodule support often had unexpected consequences for people.

With that in mind. It might be worth to hooking into update, to initialize and update your submodules after the update is finished, and examining ways to augment git-archive do do what you need.

查看更多
别忘想泡老子
5楼-- · 2019-02-11 03:45

It turns out it's very difficult to hook into any of the git tasks of capistrano (because they don't exist until the stage is set). Besides, git archive does not in any way provide support for submodules, so that part has to be completely replaced.

Copy and paste is also not an option for obvious reasons.

So I wrote this simple gem that can replace the git scm. It uses a similiar approach to capistrano 2, by cloning the repo with its submodules. It is very simple and enough for our goals. I suspect there are not many different usages of submodules out there (if people try to avoid complications).

https://github.com/juanibiapina/capistrano-scm-gitsubmodules

Let me know if it helps you too.

UPDATE:

This module has been deprecated with capistrano 3.1.0. Try this instead: https://gist.github.com/stevenscg/8176735

查看更多
登录 后发表回答