Frage

Mein Master-Branch-Layout sieht so aus:

/ <-- oberste Ebene

/Klient <-- Desktop-Client-Quelldateien

/Server <-- Rails-App

Ich möchte nur das Verzeichnis /server in meinem Verzeichnis herunterziehen deploy.rb, aber ich kann anscheinend keine Möglichkeit finden, das zu tun.Das /client-Verzeichnis ist riesig, daher funktioniert das Einrichten eines Hooks zum Kopieren von /server nach / nicht sehr gut, es muss nur die Rails-App heruntergezogen werden.

War es hilfreich?

Lösung

Ohne schmutzige Gabelung, aber noch schmutziger!

In meiner config/deploy.rb:

set :deploy_subdir, "project/subdir"

Dann habe ich diese neue Strategie zu meinem Capfile hinzugefügt:

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)

Andere Tipps

Für Capistrano 3.0 verwende ich Folgendes:

In meinem 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

Und in meinem 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'

Der gesamte wichtige Code ist in der Strategie enthalten release Methode, die verwendet git archive um nur ein Unterverzeichnis des Repos zu archivieren, verwendet dann das --strip Argument zu tar um das Archiv auf der richtigen Ebene zu extrahieren.

AKTUALISIEREN

Ab Capistrano 3.3.3 können Sie jetzt das verwenden :repo_tree Konfigurationsvariable, was diese Antwort überflüssig macht.Zum Beispiel:

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

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

Wir tun dies auch mit Capistrano, indem wir das gesamte Repository klonen, die nicht verwendeten Dateien und Ordner löschen und den gewünschten Ordner in der Hierarchie nach oben verschieben.

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

Solange das Projekt nicht zu groß wird, funktioniert das für uns ziemlich gut, aber wenn Sie können, erstellen Sie ein eigenes Repository für jede Komponente und gruppieren Sie sie mit Git-Submodulen.

Sie können zwei Git-Repositorys (Client und Server) haben und diese zu einem „Superprojekt“ (App) hinzufügen.In diesem „Superprojekt“ können Sie die beiden Repositories als Submodule hinzufügen (siehe dieses Tutorial).

Eine andere mögliche Lösung (etwas schmutziger) besteht darin, separate Zweige für Client und Server zu haben und dann aus dem Zweig „Server“ zu ziehen.

Es gibt eine Lösung.Schnapp dir Crdlos Patch für Capistrano und das Capistrano-Quelle von Github.Entfernen Sie Ihr vorhandenes Capistrano-Gem, wenden Sie den Patch an, installieren Sie setup.rb, und dann können Sie seine sehr einfache Konfigurationszeile verwenden set :project, "mysubdirectory" um ein Unterverzeichnis festzulegen.

Das einzige Problem ist, dass Github anscheinend „den Archivierungsbefehl nicht unterstützt“ ...Zumindest als er es schrieb.Ich verwende mein eigenes privates Git-Repo über SVN und es funktioniert gut. Ich habe es nicht mit Github versucht, aber ich kann mir vorstellen, dass sie diese Funktion hinzufügen werden, wenn sich genügend Leute beschweren.

Sehen Sie auch nach, ob Sie Capistrano-Autoren dazu bringen können, diese Funktion in Cap hinzuzufügen am entsprechenden Fehler.

Für Capistrano 3, basierend auf der Antwort von @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"

Leider bietet Git keine Möglichkeit, dies zu tun.Stattdessen besteht der „Git-Weg“ darin, zwei Repositorys zu haben – Client und Server – und die benötigten zu klonen.

Ich habe einen Ausschnitt erstellt, der mit Capistrano 3.x funktioniert, basierend auf früheren Antworten und anderen Informationen in 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

Es ist auch als Gist on erhältlich Github.

Sieht so aus, als würde es auch nicht mit codebasehq.com funktionieren, also habe ich am Ende Capistrano-Aufgaben erstellt, die das Chaos beseitigen :-) Vielleicht gibt es tatsächlich eine weniger knifflige Möglichkeit, dies zu tun, indem ich einige Capistrano-Aufgaben überschreibe ...

Bei mir funktioniert das seit ein paar Stunden.

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

Sie können eine Variable für das Verzeichnis deklarieren (hier „rails_app“).

Mal sehen, wie robust es ist.Die Verwendung von „before“ ist ziemlich schwach.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top