Implementación de un subdirectorio de Git en Capistrano


El diseño de mi rama maestra es así:

/

/client

/servidor

Lo que me gustaría hacer es solo bajar el directorio /server en mi deploy.rb, pero parece que no puedo encontrar ninguna manera de hacerlo. El directorio / client es enorme, por lo que configurar un gancho para copiar /server a / no funcionará muy bien, solo necesita tirar hacia abajo la aplicación Rails.

Author: Charles Menguy, 2008-08-27

10 answers

Sin ninguna acción de bifurcación sucia, pero aún más sucia !

En mi config/deploy.rb:

set :deploy_subdir, "project/subdir"

Luego agregué esta nueva estrategia a mi 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)
 76
Author: thodg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-12 08:18:01

Para Capistrano 3.0, utilizo lo siguiente:

En mi 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

Y en mi 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 el código importante está en el método strategy release, que usa git archive para archivar solo un subdirectorio del repositorio, luego usa el argumento --strip para tar para extraer el archivo en el nivel correcto.

UPDATE

A partir de Capistrano 3.3.3, ahora puede usar la variable de configuración :repo_tree, lo que hace que esta respuesta sea obsoleta. Para ejemplo:

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

Véase http://capistranorb.com/documentation/getting-started/configuration .

 42
Author: Mr Friendly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-08 16:09:23

También estamos haciendo esto con Capistrano clonando el repositorio completo, eliminando los archivos y carpetas no utilizados y moviendo la carpeta deseada hacia arriba en la jerarquía.

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

Mientras el proyecto no sea demasiado grande, esto funciona bastante bien para nosotros, pero si puedes, crea un repositorio propio para cada componente y agrupalos con submódulos de git.

 10
Author: Thomas Fankhauser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-19 15:16:23

Puedes tener dos repositorios git (cliente y servidor) y agregarlos a un "super-proyecto" (app). En este "super-proyecto" puedes añadir los dos repositorios como submódulos (comprueba este tutorial).

Otra posible solución (un poco más sucia) es tener ramas separadas para el cliente y el servidor, y luego puede extraer desde la rama 'server'.

 4
Author: Federico Builes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-13 15:17:25

Desafortunadamente, git no proporciona ninguna manera de hacer esto. En su lugar, la' forma git ' es tener dos repositorios client cliente y servidor, y clonar el uno(s) que necesita.

 2
Author: Silas Snider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-27 06:38:13

Hay una solución. Coge el parche de crdlo para capistrano y la fuente de capistrano de github. Retire su gema capistrano existente, aplicar el parche, configuración.rb instalar, y luego puede utilizar su línea de configuración muy simple set :project, "mysubdirectory" para establecer un subdirectorio.

El único problema es que aparentemente github no "soporta el comando archive" ... al menos cuando lo escribió. Estoy usando mi propio repositorio git privado sobre svn y funciona bien, no lo he probado con github pero imagina que si suficientes personas se quejan agregarán esa característica.

También vea si puede conseguir que los autores de capistrano agreguen esta característica a cap en el error relevante.

 2
Author: Simon Woodside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-14 06:15:09

Para Capistrano 3, basado en @ Thomas Fankhauser respuesta:

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"
 2
Author: fsainz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-22 11:38:56

Parece que tampoco funciona con codebasehq.com así que terminé haciendo tareas de capistrano que limpia el desorden : -) Tal vez hay realmente una forma menos hacky de hacer esto anulando algunas tareas de capistrano...

 1
Author: StuFF mc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-16 19:27:50

He creado un snipped que funciona con Capistrano 3.x basado en anwers anteriores y otra información encontrada en 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

También está disponible como Gist en Github.

 1
Author: JAlberto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-06 15:04:20

Esto ha estado funcionando para mí durante unas 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'

Puede declarar una variable para el directorio (aquí rails_app).

Veamos qué tan robusto es. Usar "antes" es bastante débil.

 0
Author: Stephan Wehner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-06 22:50:37