Развертывание подкаталога Git в Capistrano

Макет моей основной ветки выглядит следующим образом:

/

/ клиент

/ сервер

Что я хотел бы сделать, так это вытащить каталог / server в моем deploy.rb, но я не могу найти никакого способа сделать это. Каталог / client огромен, поэтому установка ловушки для копирования / server в / не будет работать очень хорошо, нужно только вытащить приложение Rails.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
67
0
14 697
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

К сожалению, git не позволяет этого сделать. Вместо этого «способ git» состоит в том, чтобы иметь два репозитория - клиентский и серверный и клонировать тот (и), который вам нужен.

упоминание git way никому и ничему не помогает.

Sjors Branderhorst 28.01.2016 14:50

Вы можете иметь два репозитория git (клиентский и серверный) и добавлять их в «суперпроект» (приложение). В этом «суперпроекте» вы можете добавить два репозитория как подмодули (отметьте этот учебник).

Другое возможное решение (немного более грязное) - иметь отдельные ветки для клиента и сервера, а затем вы можете использовать ветку «сервер».

Выход есть. Возьмите crdlo патч для капистрано и источник капистрано с github. Удалите существующий драгоценный камень capistrano, примените патч, установите setup.rb, а затем вы можете использовать его очень простую строку конфигурации set :project, "mysubdirectory", чтобы установить подкаталог.

Единственная проблема заключается в том, что, по-видимому, github «не поддерживает команду архивирования» ... по крайней мере, когда он ее писал. Я использую свой собственный репозиторий git поверх svn, и он отлично работает, я не пробовал его с github, но думаю, если достаточно людей будет жаловаться, они добавят эту функцию.

Также посмотрите, сможете ли вы заставить авторов capistrano добавить эту функцию в шапку при соответствующей ошибке.

Связь с маяком не работает. Интересно, реализовал ли Capistrano это тем временем.

Michiel de Mare 01.07.2012 02:08

Похоже, он также не работает с codebasehq.com, поэтому я закончил тем, что сделал задачи capistrano, которые убирают беспорядок :-) Может быть, на самом деле есть менее хакерский способ сделать это, переопределив некоторые задачи capistrano ...

Ответ принят как подходящий

Без грязного разветвления, но еще грязнее!

В моем config / deploy.rb:

set :deploy_subdir, "project/subdir"

Затем я добавил эту новую стратегию в свой файл 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)

О, как бы я хотел послать вам несколько пинт холодного пива. Спасибо!!

Nazar 11.07.2011 23:38

Идеально. Как раз то, что мне было нужно. Спасибо!

Matt 14.06.2012 08:01

NB. любой, кто читает, это работает, если вы уже используете remote_cache в качестве механизма: deploy_via (который полагается на доступ SCM на стороне сервера).

jrg 29.05.2013 20:34

Выглядит красиво! Кто-нибудь сделал из него драгоценный камень?

M. Scott Ford 30.07.2013 22:00

Похоже, у него есть потенциал ... github.com/mcollina/capistrano-remote-cache-with-project-roo‌ т

M. Scott Ford 30.07.2013 22:01

См. Комментарий мистера Френдли к Capistrano 3 ниже.

vcardillo 17.05.2014 04:51

Спасибо, что поделились этим отличным решением. Мне просто интересно, правильный ли это способ Capistrano расширить и соединить элементы внутри него. А как насчет метода install_plugin?

leandroico 03.01.2017 04:53

Я все время получаю сообщение об ошибке загрузки: файл require 'capistrano / recipes / deploy / strategy / remote_cache' не найден. Я использую Capistrano 3

i_use_the_internet 07.03.2018 10:16

У меня это работает уже несколько часов.

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

Вы можете объявить переменную для каталога (здесь rails_app).

Посмотрим, насколько он надежен. Использование «до» довольно слабое.

Мы также делаем это с Capistrano, клонируя весь репозиторий, удаляя неиспользуемые файлы и папки и перемещая нужную папку вверх по иерархии.

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

Пока проект не становится слишком большим, это работает для нас очень хорошо, но если вы можете, создайте собственный репозиторий для каждого компонента и сгруппируйте их вместе с помощью подмодулей git.

Отлично! Немного неэффективно, но, по крайней мере, не уродливо.

Michiel de Mare 01.07.2012 02:07

И не забудьте вручную создать символическую ссылку на каталог журналов, поскольку capistrano больше не делает этого автоматически.

Thomas Fankhauser 02.07.2012 15:36

Для более эффективного подхода. Кто-то создал гем, который добавляет стратегию развертывания copy_subdir. Только подкаталог в репо архивируется и копируется на удаленный сервер. github.com/yyuu/capistrano-copy-subdir

Kevin 17.05.2013 03:11

есть идеи, как мы делаем эту роль?

sarat 12.10.2014 19:51

Для Capistrano 3.0 я использую следующее:

В моем 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

А в моем 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'

Весь важный код находится в методе стратегии release, который использует git archive для архивации только подкаталога репо, а затем использует аргумент --strip для tar для извлечения архива на нужном уровне.

ОБНОВИТЬ

Начиная с Capistrano 3.3.3, теперь вы можете использовать переменную конфигурации :repo_tree, что делает этот ответ устаревшим. Например:

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

См. http://capistranorb.com/documentation/getting-started/configuration.

Я не мог установить собственную стратегию с помощью set: git_strategy, он продолжал использовать DefaultStrategy

leojh 18.02.2014 00:16

Мне также нужно было скопировать и вставить метод "fetch_revision" из оригинала. (github.com/capistrano/capistrano/blob/master/lib/c‌ apistrano /…)

Tsuneo Yoshioka 01.05.2014 14:19

@TsuneoYoshioka Да, метод "fetch_revision" был добавлен в Capistrano 3.1. Однако в 3.1 также добавлена ​​конфигурационная переменная repo_tree, которая (к счастью) делает этот ответ устаревшим. Подробнее см. github.com/capistrano/capistrano#configuration.

Mr Friendly 17.12.2014 22:34

: repo_tree был добавлен в 3.3.3, а не в 3.1. Для тех, кто это видит, а у них это не работает.

Altonymous 04.03.2015 01:19

Привет, я использую capistrano 3.4.0, но я все еще не могу использовать переменную: repo_tree, чтобы она работала. У меня есть репозиторий git под названием demo_app, в котором есть два подкаталога сервер и клиент. Я хочу использовать подкаталог сервер для развертывания. Как мне установить это с помощью: repo_tree? Ни один из них не работал: - set :repo_tree, 'demo_app/server' или set :repo_tree, 'server'

chetang 01.07.2015 18:44

Спасибо за подсказку относительно set: repo_tree, 'relative / path / from / your / repo' в Capistrano> 3.3.3 :)

Anna Völkl 24.10.2017 15:35

Я создал фрагмент, который работает с Capistrano 3.x на основе предыдущих ответов и другой информации, найденной в 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

Он также доступен в виде Gist на Github.

Случайно прокрутил до конца и нашел вот это. У меня работает, +1.

Jorge Orpinel 06.08.2015 01:10

у меня тоже отлично работает ... спасибо +1 Теперь я могу развернуть версии API v1, v2, ...

user762579 29.02.2016 17:47

Для Capistrano 3 на основе ответа @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"

не знаю, интересно ли это кому-нибудь еще. но просто позволяю вам, ребята, если кто-то ищет ответ. теперь мы можем использовать:: repo_tree

https://capistranorb.com/documentation/getting-started/configuration/

Другие вопросы по теме