Question

La disposition de ma branche principale ressemble à ceci :

/ <-- niveau supérieur

/client <-- fichiers sources du client de bureau

/serveur <-- Application Rails

Ce que j'aimerais faire, c'est uniquement dérouler le répertoire /server dans mon deploy.rb, mais je n'arrive pas à trouver un moyen de le faire.Le répertoire /client est énorme, donc configurer un hook pour copier /server vers / ne fonctionnera pas très bien, il suffit de dérouler l'application Rails.

Était-ce utile?

La solution

Sans aucune sale action de fourche mais encore plus sale !

Dans mon config/deploy.rb :

set :deploy_subdir, "project/subdir"

Ensuite j'ai ajouté cette nouvelle stratégie à mon 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)

Autres conseils

Pour Capistrano 3.0, j'utilise ce qui suit :

Dans mon 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

Et dans mon 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'

Tout le code important est dans la stratégie release méthode qui utilise git archive pour archiver uniquement un sous-répertoire du dépôt, puis utilise le --strip argument à tar pour extraire l'archive au bon niveau.

MISE À JOUR

Depuis Capistrano 3.3.3, vous pouvez désormais utiliser le :repo_tree variable de configuration, ce qui rend cette réponse obsolète.Par exemple:

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

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

Nous faisons également cela avec Capistrano en clonant le référentiel complet, en supprimant les fichiers et dossiers inutilisés et en déplaçant le dossier souhaité vers le haut de la hiérarchie.

déployer.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

Tant que le projet ne devient pas trop gros, cela fonctionne plutôt bien pour nous, mais si vous le pouvez, créez votre propre référentiel pour chaque composant et regroupez-les avec des sous-modules git.

Vous pouvez avoir deux référentiels git (client et serveur) et les ajouter à un "super-projet" (application).Dans ce "super-projet" vous pouvez ajouter les deux référentiels en tant que sous-modules (cochez ce tutoriel).

Une autre solution possible (un peu plus sale) consiste à avoir des branches distinctes pour le client et le serveur, puis à extraire de la branche « serveur ».

Il existe une solution.Prenez les crdlo patch pour Capistrano et le source capistrano de github.Supprimez votre gemme Capistrano existante, appliquez le correctif, installez setup.rb, puis vous pourrez utiliser sa ligne de configuration très simple. set :project, "mysubdirectory" pour définir un sous-répertoire.

Le seul problème est qu'apparemment, github ne "prend pas en charge la commande archive"...du moins quand il l'a écrit.J'utilise mon propre dépôt git privé sur svn et cela fonctionne bien, je ne l'ai pas essayé avec github mais j'imagine que si suffisamment de personnes se plaignent, elles ajouteront cette fonctionnalité.

Vérifiez également si vous pouvez demander aux auteurs de Capistrano d'ajouter cette fonctionnalité dans Cap. au bug concerné.

Pour Capistrano 3, basé sur la réponse de @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"

Malheureusement, git ne fournit aucun moyen de le faire.Au lieu de cela, la « méthode git » consiste à avoir deux référentiels – client et serveur, et à cloner celui(s) dont vous avez besoin.

J'ai créé un extrait qui fonctionne avec Capistrano 3.x basé sur les réponses précédentes et d'autres informations trouvées dans 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

Il est également disponible en résumé sur GitHub.

On dirait que cela ne fonctionne pas non plus avec codebasehq.com, j'ai donc fini par créer des tâches Capistrano qui nettoient les dégâts :-) Peut-être qu'il existe en fait une façon moins compliquée de procéder en remplaçant certaines tâches Capistrano...

Cela fonctionne pour moi depuis quelques heures.

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

Vous pouvez déclarer une variable pour le répertoire (ici rails_app).

Voyons à quel point il est robuste.Utiliser "avant" est assez faible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top