2008-08-26 3 views
61

Мой макет мастер ветви, как это:Развертывание подкаталог Git в Capistrano

/ < - уровень верхнего

/клиент < - настольные исходные файлы клиента

/сервер < - Rails app

Что бы я хотел do только вытаскивает каталог/server в моем deploy.rb, но я не могу найти способ сделать это. Каталог/client является огромным, поэтому настройка крюка для копирования/сервера в/не будет работать очень хорошо, ему нужно только вытащить приложение Rails.

ответ

75

Без каких-либо грязных действий, но даже грязнее!

В моей конфигурации/deploy.rb:

set :deploy_subdir, "project/subdir" 

Затем я добавил эту новую стратегию моей Capfile:

require 'capistrano/recipes/deploy/strategy/remote_cache' 

class RemoteCacheSubdir < Capistrano::Deploy::Strategy::RemoteCache 

    private 

    def repository_cache_subdir 
    if configuration[:deploy_subdir] then 
     File.join(repository_cache, configuration[:deploy_subdir]) 
    else 
     repository_cache 
    end 
    end 

    def copy_repository_cache 
    logger.trace "copying the cached version to #{configuration[:release_path]}" 
    if copy_exclude.empty? 
     run "cp -RPp #{repository_cache_subdir} #{configuration[:release_path]} && #{mark}" 
    else 
     exclusions = copy_exclude.map { |e| "--exclude=\"#{e}\"" }.join(' ') 
     run "rsync -lrpt #{exclusions} #{repository_cache_subdir}/* #{configuration[:release_path]} && #{mark}" 
    end 
    end 

end 


set :strategy, RemoteCacheSubdir.new(self) 
+14

О, как бы я хотел, я мог бы послать вам несколько пинтов из кузнечного пива. Спасибо!! – Nazar 2011-07-11 19:38:43

+3

Perfect. Только то, что мне было нужно. Благодаря! – Matt 2012-06-14 04:01:48

+0

NB. кто-либо читает, это работает, если вы уже используете remote_cache в качестве своего механизма: deploy_via (который опирается на доступ SCM на сервере). – jrg 2013-05-29 16:34:00

2

К сожалению, git не имеет возможности сделать это. Вместо этого «git way» должен иметь два репозитория - клиент и сервер и клонировать то, которое вам нужно.

+0

упоминая 'GIT путь' ничего или никого не поможет. – 2016-01-28 11:50:21

4

У вас может быть два репозитория git (клиент и сервер) и добавить их в «суперпроект» (приложение). В этом «суперпроекте» вы можете добавить два репозитория в виде подмодулей (отметьте this tutorial).

Еще одно возможное решение (немного более грязное) - иметь отдельные ветви для клиента и сервера, а затем вы можете вытащить из ветки «сервер».

2

Существует решение. Захватите crdlo patch for capistrano и capistrano source от github. Удалите существующий capistrano gem, установите патч, setup.rb install, а затем вы можете использовать его очень простую конфигурационную строку set :project, "mysubdirectory", чтобы установить подкаталог.

Единственное, что, по-видимому, github не «поддерживает команду архива» ... по крайней мере, когда он это написал. Я использую свою собственную приватную git-репо над svn, и она отлично работает, я не пробовал ее с github, но я предполагаю, что, если достаточно людей жалуются, они добавят эту функцию.

Также посмотрите, можете ли вы получить авторов capistrano, чтобы добавить эту функцию в колпачок at the relevant bug.

+0

Ссылка Lighthouse не работает. Интересно, выполнило ли это действие капистрано? – 2012-06-30 22:08:59

1

Похоже, он также не работает с codebasehq.com, так что я в конечном итоге сделать Capistrano задачи, которые чистит беспорядок :-) Может быть, есть на самом деле менее Hacky способ сделать это, перекрывая некоторые задачи Капистрано ...

0

Это работает для меня в течение нескольких часов.

# Capistrano assumes that the repository root is Rails.root 
namespace :uploads do 
    # We have the Rails application in a subdirectory rails_app 
    # Capistrano doesn't provide an elegant way to deal with that 
    # for the git case. (For subversion it is straightforward.) 
    task :mv_rails_app_dir, :roles => :app do 
    run "mv #{release_path}/rails_app/* #{release_path}/ " 
    end 
end 

before 'deploy:finalize_update', 'uploads:mv_rails_app_dir' 

Вы можете объявить переменную для каталога (здесь rails_app).

Давайте посмотрим, насколько он прочен. Использование «before» довольно слабое.

10

Мы также делаем это с помощью Capistrano, клонируя полный репозиторий, удаляя неиспользуемые файлы и папки и перемещая нужную папку вверх по иерархии.

deploy.rb

set :repository, "[email protected]:name/project.git" 
set :branch, "master" 
set :subdir, "server" 

after "deploy:update_code", "deploy:checkout_subdir" 

namespace :deploy do 

    desc "Checkout subdirectory and delete all the other stuff" 
    task :checkout_subdir do 
     run "mv #{current_release}/#{subdir}/ /tmp && rm -rf #{current_release}/* && mv /tmp/#{subdir}/* #{current_release}" 
    end 

end 

Пока проект не слишком большой это работает очень хорошо для нас, но если вы можете, создать собственное хранилище для каждого компонента и сгруппировать их вместе с мерзавцем подмодули.

40

Для Capistrano 3.0, я использую следующее:

В моих Capfile:

# Define a new SCM strategy, so we can deploy only a subdirectory of our repo. 
module RemoteCacheWithProjectRootStrategy 
    def test 
    test! " [ -f #{repo_path}/HEAD ] " 
    end 

    def check 
    test! :git, :'ls-remote', repo_url 
    end 

    def clone 
    git :clone, '--mirror', repo_url, repo_path 
    end 

    def update 
    git :remote, :update 
    end 

    def release 
    git :archive, fetch(:branch), fetch(:project_root), '| tar -x -C', release_path, "--strip=#{fetch(:project_root).count('/')+1}" 
    end 
end 

И в моем deploy.rb:

# Set up a strategy to deploy only a project directory (not the whole repo) 
set :git_strategy, RemoteCacheWithProjectRootStrategy 
set :project_root, 'relative/path/from/your/repo' 

Все важный код в методе стратегии release , который использует git archive для архивации только подкаталога репо, затем использует --strip a rgument до tar, чтобы извлечь архив на нужном уровне.

UPDATE

Как Капистрано 3.3.3, теперь вы можете использовать переменную :repo_tree конфигурации, что делает этот ответ устаревшим. Например:

set :repo_url, 'https://example.com/your_repo.git' 
set :repo_tree, 'relative/path/from/your/repo' # relative path to project root in repo 

См. http://capistranorb.com/documentation/getting-started/configuration.

1

Я создал пропущен, который работает с Capistrano 3.x на основе предыдущего anwers и другой информации, найденный в GitHub:

# Usage: 
# 1. Drop this file into lib/capistrano/remote_cache_with_project_root_strategy.rb 
# 2. Add the following to your Capfile: 
# require 'capistrano/git' 
# require './lib/capistrano/remote_cache_with_project_root_strategy' 
# 3. Add the following to your config/deploy.rb 
# set :git_strategy, RemoteCacheWithProjectRootStrategy 
# set :project_root, 'subdir/path' 

# Define a new SCM strategy, so we can deploy only a subdirectory of our repo. 
module RemoteCacheWithProjectRootStrategy 
    include Capistrano::Git::DefaultStrategy 
    def test 
    test! " [ -f #{repo_path}/HEAD ] " 
    end 

    def check 
    test! :git, :'ls-remote -h', repo_url 
    end 

    def clone 
    git :clone, '--mirror', repo_url, repo_path 
    end 

    def update 
    git :remote, :update 
    end 

    def release 
    git :archive, fetch(:branch), fetch(:project_root), '| tar -x -C', release_path, "--strip=#{fetch(:project_root).count('/')+1}" 
    end 
end 

Он также доступен как Сущность на Github.

2

Для Capistrano 3, на основе @Thomas Фанкхаузер ответ:

set :repository, "[email protected]:name/project.git" 
set :branch, "master" 
set :subdir, "relative_path_to_my/subdir" 


namespace :deploy do 

    desc "Checkout subdirectory and delete all the other stuff" 
    task :checkout_subdir do 

    subdir = fetch(:subdir) 
    subdir_last_folder = File.basename(subdir) 
    release_subdir_path = File.join(release_path, subdir) 

    tmp_base_folder = File.join("/tmp", "capistrano_subdir_hack") 
    tmp_destination = File.join(tmp_base_folder, subdir_last_folder) 

    cmd = [] 
    # Settings for my-zsh 
    # cmd << "unsetopt nomatch && setopt rmstarsilent" 
    # create temporary folder 
    cmd << "mkdir -p #{tmp_base_folder}" 
    # delete previous temporary files     
    cmd << "rm -rf #{tmp_base_folder}/*" 
    # move subdir contents to tmp   
    cmd << "mv #{release_subdir_path}/ #{tmp_destination}" 
    # delete contents inside release  
    cmd << "rm -rf #{release_path}/*" 
    # move subdir contents to release    
    cmd << "mv #{tmp_destination}/* #{release_path}" 
    cmd = cmd.join(" && ") 

    on roles(:app) do 
     within release_path do 
     execute cmd 
     end 
    end 
    end 

end 

after "deploy:updating", "deploy:checkout_subdir" 
Смежные вопросы