2008-08-26 4 views
61

でGitのサブディレクトリを展開する私のmasterブランチのレイアウトはすべて、このようなものです:はカピストラーノ

/ < - トップレベル

/クライアント < - デスクトップクライアントのソースファイル

/サーバー < - レールアプリ

私は何をしたいですか? doは私のdeploy.rbの/ serverディレクトリをプルダウンするだけですが、私はそれを行う方法を見つけることができないようです。/clientディレクトリは巨大なので、コピー/サーバーへのフックの設定は非常にうまくいかないので、Railsアプリケーションをプルダウンするだけで済みます。

答えて

75

どんなダーティーなフォークアクションもなく、より汚れた!私のconfig/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

ああ、私はあなたにcoooldビールのパイントを送ることができたらいいなあ。ありがとうございました!! – Nazar

+3

パーフェクト。ちょうど私が必要なもの。ありがとう! – Matt

+0

NB。誰かが読んでいる、これはあなたがすでに:remote_cacheをあなたの:deploy_viaメカニズム(サーバ側のSCMアクセスに依存している)で使用している場合に動作します。 – jrg

2

残念ながら、gitはこれを行う方法を提供していません。代わりに、 'git way'はクライアントとサーバーの2つのリポジトリを持ち、必要なものを複製することです。

+0

は何か誰も助けにはなりません。 –

4

2つのgitリポジトリ(クライアントとサーバー)を持ち、それらを「スーパープロジェクト」(app)に追加できます。この "スーパープロジェクト"では、2つのリポジトリをサブモジュールとして追加できます(チェックthis tutorial)。

もう1つの解決策(もう少し汚い)は、クライアントとサーバーのために別々のブランチを用意し、 'サーバー'ブランチから引き出すことです。

2

解決策があります。グラムからcrdloのpatch for capistranocapistrano sourceをつかみなさい。既存のcapistrano gemを削除し、パッチsetup.rbをインストールしてください。そして、彼の非常に簡単な設定行set :project, "mysubdirectory"を使って、サブディレクトリを設定することができます。

唯一の問題は、githubが少なくともアーカイブコマンドをサポートしていないことです...少なくとも彼がそれを書いたときです。私はsvn上で私自身のプライベートgitリポジトリを使用しています、それはうまく動作し、私はgithubでそれを試していないが、十分な人々が彼らはその機能を追加すると不平を言う場合は想像しています。

capistranoの作成者がキャップat the relevant bugにこの機能を追加できるかどうかを確認してください。私は混乱:-)はたぶん、実際にいくつかのカピストラーノタスクをオーバーライドすることによってこれを行うことの少ないハック方法がありますクリーンカピストラーノタスクを作ることになったので、それはまた... codebasehq.comで作業していないよう

+0

灯台リンクが壊れています。その間にカピストラーノがこれを実装したのだろうかと思います。 –

1

が見える

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)に変数を宣言することがあります。

それがどれほど頑丈かを見てみましょう。 「前」を使うのはかなり弱いです。

10

また、完全なリポジトリをクローンダウンし、未使用のファイルとフォルダを削除し、目的のフォルダを階層の上に移動することで、これをCapistranoで行います。

一緒にgitのと同じように、長いプロジェクトは、これが私たちのためにかなり良い作品大きくなりすぎていますが、できれば、各コンポーネントの独自のリポジトリを作成しないよう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 

やグループ、それらをサブモジュール。カピストラーノ3.0の場合

+1

ニース!少し非効率ですが、少なくとも醜いハックではありません。 –

+0

そして、カピストラノが自動的にそれを自動的に行わないので、ログディレクトリを手動でシンボリックリンクすることを忘れないでください。 –

+2

より効率的なアプローチ。配備戦略 "copy_subdir"を追加する人が作成した宝石があります。レポ内のサブディレクトリのみがアーカイブされ、リモートサーバーにコピーされます。 https://github.com/yyuu/capistrano-copy-subdir – Kevin

40

は、私は、次の使用:私の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適切なレベルでアーカイブを解凍するには、tarに送信してください。カピストラーノ3.3.3のよう

UPDATE

、あなたは今、この答えは時代遅れになり: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を参照してください。

+0

「set:git_strategy」を使ってカスタム戦略を設定できませんでした。これはDefaultStrategyを使用して保存しました – leojh

+7

オリジナルから「fetch_revision」メソッドをコピー&ペーストする必要がありました(https://github.com/capistrano/capistrano/blob/ master/lib/capistrano/git.rb) –

+1

@TsuneoYoshiokaはい、 "fetch_revision"メソッドがCapistrano 3.1に追加されました。しかし、3.1では 'repo_tree'設定変数も追加されています。これは(喜んで)この回答を廃止しました。詳細はhttps://github.com/capistrano/capistrano#configurationをご覧ください。 –

1

私はカピストラーノの前のanwersに基づいて、3.xと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の骨子として利用可能です。 @Thomas Fankhauserの回答に基づいてカピストラーノ3については、

+0

誤ってスクロールしてこれを見つけました。私のために働く、+1。 –

+0

それは私のためにもうまく動作します...ありがとう+1 私は今、APIバージョンv1、v2を展開することができます... – erwin

2

: 'Gitの道' を言及

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" 
関連する問題