我的主分支布局是这样的:

/ <-- 顶层

/客户 <-- 桌面客户端源文件

/服务器 <-- Rails 应用程序

我想做的只是拉下我的 /server 目录 deploy.rb, ,但我似乎找不到任何方法来做到这一点。/client 目录很大,因此设置一个钩子来将 /server 复制到 / 效果不太好,它只需要拉取 Rails 应用程序即可。

有帮助吗?

解决方案

没有任何肮脏的分叉动作,但更肮脏!

在我的 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)

其他提示

对于 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 论证 tar 以正确的级别提取存档。

更新

从 Capistrano 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.

我们还通过 Capistrano 克隆完整的存储库、删除未使用的文件和文件夹并将所需的文件夹向上移动到层次结构中来实现此目的。

部署.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 子模块分组在一起。

您可以拥有两个 git 存储库(客户端和服务器)并将它们添加到“超级项目”(应用程序)。在这个“超级项目”中,您可以将两个存储库添加为子模块(检查 本教程).

另一种可能的解决方案(有点脏)是为客户端和服务器设置单独的分支,然后您可以从“服务器”分支中拉取。

有一个解决方案。抓住crdlo的 卡皮斯特拉诺补丁卡皮斯特拉诺来源 来自github。删除现有的 capistrano gem,应用补丁,setup.rb 安装,然后你就可以使用他非常简单的配置行 set :project, "mysubdirectory" 设置子目录。

唯一的问题是 github 显然不“支持存档命令”......至少在他写的时候是这样。我在 svn 上使用我自己的私有 git 存储库,它工作得很好,我还没有在 github 上尝试过,但我想如果有足够多的人抱怨他们会添加这个功能。

另请参阅是否可以让 capistrano 作者将此功能添加到 cap 中 在相关的错误处.

对于 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"

不幸的是,git 没有提供这样做的方法。相反,“git 方式”是拥有两个存储库——客户端和服务器,然后克隆您需要的存储库。

我根据之前的答案和 github 中找到的其他信息创建了一个与 Capistrano 3.x 一起使用的片段:

# 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

它也可以作为 Gist 提供 吉图布.

看起来它也不能与 codebasehq.com 一起使用,所以我最终制作了 capistrano 任务来清理混乱:-) 也许实际上有一种不那么黑客的方法可以通过覆盖一些 capistrano 任务来做到这一点......

这已经为我工作了几个小时。

# 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)。

让我们看看它有多坚固。使用“之前”是相当弱的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top