Pergunta

Meu branch master esquema é assim:

/ <-- nível superior

/cliente <-- cliente da área de trabalho arquivos de origem

/server <-- Trilhos app

O que eu gostaria de fazer é só puxar para baixo o diretório /server na minha deploy.rb, mas eu não consigo encontrar nenhuma maneira de fazer isso.O cliente /diretório é enorme, então a configuração de um gancho para cópia /servidor / não irá funcionar muito bem, ele precisa só puxar para baixo o app Rails.

Foi útil?

Solução

Sem qualquer suja bifurcar-se de ação, mas ainda mais sujo !

Na minha config/deploy.rb :

set :deploy_subdir, "project/subdir"

Então eu adicionei essa nova estratégia, a meu 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)

Outras dicas

Para Capistrano 3.0, eu uso o seguinte:

No meu 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

E no meu 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'

Todo o código é importante na estratégia release o método, que usa git archive para arquivar apenas um subdiretório do acordo de recompra, em seguida, usa o --strip argumento tar para extrair o arquivo no nível certo.

ATUALIZAÇÃO

Como de Capistrano 3.3.3, agora você pode usar o :repo_tree variável de configuração, o que torna esta resposta obsoletos.Por exemplo:

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

Ver http://capistranorb.com/documentation/getting-started/configuration.

Também estamos fazendo isso com Capistrano através da clonagem para baixo o repositório completo, apagando os arquivos e pastas não utilizados e mover a pasta desejada para cima na hierarquia.

implantar.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

Enquanto o projeto não é muito grande, isso funciona muito bem para nós, mas se você pode criar um repositório próprio para cada componente e agrupá-los em conjunto com o git submódulos.

Você pode ter dois repositórios git (cliente e servidor) e adicioná-los a um "super-projeto" (app).Nesta "super-projecto" você pode adicionar os dois repositórios como submódulos (seleção este tutorial).

Outra solução possível (um pouco mais suja) é separado ramos para o cliente e servidor e, em seguida, você pode usar o 'servidor' ramo.

Não é uma solução.Pegue crdlo do patch para capistrano e o capistrano de origem a partir do github.Remova o existente em seu capistrano gem, aplicar o patch, o programa de configuração.rb instalar e, em seguida, você pode usar a sua configuração muito simples de linha de set :project, "mysubdirectory" para definir um subdiretório.

A única pegadinha é que, aparentemente, o github não "suporta o comando de arquivo" ...pelo menos quando ele a escreveu.Eu estou usando o meu próprio privado repositório git sobre o svn e ele funciona muito bem, eu ainda não tentei com o github, mas eu imagino que se um número suficiente de pessoas se queixam de que vai adicionar essa funcionalidade.

Também veja se você pode obter capistrano de autores para adicionar esse recurso no pac no respectivo erro.

Para Capistrano 3, com base no @Thomas Fankhauser resposta:

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"

Infelizmente, o git não fornece nenhuma maneira de fazer isso.Em vez disso, o 'git forma' é ter dois repositórios -- o cliente e o servidor, e o clone(s) que você precisa.

Eu criei um corte que funciona com Capistrano 3.x baseado no anterior anwers e outras informações encontradas no 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

Ele também está disponível como uma Essência em Github.

Parece que ele também não trabalho com codebasehq.com então eu acabei fazendo capistrano tarefas que limpa a bagunça :-) Talvez na verdade, há uma menor hacky maneira de fazer isso substituindo alguns capistrano tarefas...

Esta tem sido a trabalhar para mim por algumas horas.

# 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'

Você pode declarar uma variável para o diretório (aqui rails_app).

Vamos ver o quão robusta é.Usando o "antes" é muito fraco.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top