rails deploy ruby-on-rails git deployment capistrano

ruby-on-rails - deploy - capistrano rails



Despliegue de un subdirectorio Git en Capistrano (10)

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

/ <- nivel superior

/ client <- archivos de origen del cliente de escritorio

/ server <- Aplicación Rails

Lo que me gustaría hacer es solo desplegar 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 hook para copiar / server a / will not work very well, necesita solo desplegar la aplicación Rails.


Desafortunadamente, git no ofrece ninguna forma de hacer esto. En cambio, la ''manera Git'' es tener dos repositorios, cliente y servidor, y clonar uno (s) que necesita.


Hay una solucion. Coge el parche de crdlo para capistrano y la fuente capistrano de github. Quite su gema capistrano existente, aplique el parche, install.rb install, y luego puede usar su set :project, "mysubdirectory" líneas de configuración muy simple set :project, "mysubdirectory" para establecer un subdirectorio.

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

También vea si puede lograr que los autores de capistrano agreguen esta característica al límite en el error relevante .


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


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

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)


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.


Puede tener dos repositorios de git (cliente y servidor) y agregarlos a un "superproyecto" (aplicación). En este "superproyecto" puede agregar los dos repositorios como submódulos (consulte este tutorial ).

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


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

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

Siempre que el proyecto no sea demasiado grande, esto funciona bastante bien para nosotros, pero si puede, cree un repositorio propio para cada componente y agrúpelos junto con los submódulos de git.


Creé un recorte que funciona con Capistrano 3.x basado en torres 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 .


Para Capistrano 3, basado en la respuesta de @Thomas Fankhauser:

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"


Para Capistrano 3.0, uso 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 de release estrategia, 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.

ACTUALIZAR

A partir de Capistrano 3.3.3, ahora puede usar la variable de configuración :repo_tree , que hace que esta respuesta sea obsoleta. Por 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

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