67

私のマスターブランチのレイアウトは次のようになります。

/ <-トップレベル

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

/ server <-Railsアプリ

私がやりたいのは、私の/ serverディレクトリをプルダウンすることだけdeploy.rbですが、それを行う方法が見つからないようです。/ clientディレクトリは巨大であるため、/ serverを/にコピーするためのフックを設定してもうまく機能せず、Railsアプリをプルダウンするだけで済みます。

4

11 に答える 11

78

汚れた分岐アクションはありませんが、さらに汚れています。

私の 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)
于 2010-01-12T08:18:01.160 に答える
44

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--striptar

アップデート

:repo_treeCapistrano 3.3.3 の時点で、構成変数を使用できるようになったため、この回答は廃止されました。例えば:

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を参照してください。

于 2014-01-25T00:26:39.283 に答える
10

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

deploy.rb

set :repository,  "git@github.com: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

プロジェクトが大きくなりすぎない限り、これでうまくいきますが、可能であれば、コンポーネントごとに独自のリポジトリを作成し、それらを git サブモジュールでグループ化してください。

于 2012-01-19T15:16:23.897 に答える
3

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

もう 1 つの考えられる解決策 (もう少し汚い) は、クライアントとサーバーに別々のブランチを用意し、「サーバー」ブランチからプルできるようにすることです。

于 2008-08-29T16:16:23.573 に答える
2

解決策があります。githubからcapistranoとcapistranoソースのcrdloのパッチを入手してください。既存のcapistranogemを削除し、パッチをappy、setup.rb installすると、彼の非常に単純な構成行を使用してサブディレクトリを設定できます。set :project, "mysubdirectory"

唯一の落とし穴は、明らかにgithubが「アーカイブコマンドをサポートしていない」ということです...少なくとも彼が書いたときは。私はsvnで自分のプライベートgitリポジトリを使用していますが、正常に動作します。githubで試したことはありませんが、十分な数の人がその機能を追加すると不満を言っていると思います。

また、capistranoの作成者に、関連するバグでこの機能をcapに追加してもらうことができるかどうかも確認してください。

于 2009-05-14T06:15:09.077 に答える
2

Capistrano 3 の場合、@Thomas Fankhauser の回答に基づいています。

set :repository,  "git@github.com: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"
于 2014-08-22T11:38:56.757 に答える
1

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

于 2008-08-27T06:38:13.617 に答える
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)。

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

于 2011-08-06T22:50:37.950 に答える
0

codebasehq.com でも動作していないように見えるので、混乱を解消するカピストラーノ タスクを作成することになりました :-) 実際には、いくつかのカピストラーノ タスクをオーバーライドすることで、これを行うハックの少ない方法があるかもしれません...

于 2009-09-16T19:27:50.360 に答える