Использование capistrano для развертывания из разных веток git

Я использую capistrano для развертывания приложения RoR. Кодовая база находится в репозитории git, и при разработке широко используется ветвление. Capistrano использует deploy.rb файл для своих настроек, один из которых является веткой для развертывания.

Моя проблема заключается в следующем: допустим, я создаю новую ветку A от master. Файл развертывания будет ссылаться на ветвь master. Я редактирую его, поэтому A можно развернуть в тестовой среде. Я заканчиваю работу над функцией и объединяю ветку A в master. Поскольку файл deploy.rb из A более свежий, он объединяется, и теперь deploy.rb в master ссылается на ветвь A. Время снова редактировать.

Это много, казалось бы, ненужного ручного редактирования - параметр всегда должен соответствовать имени текущей ветки. Вдобавок ко всему, легко забыть редактировать настройки каждый раз.

Как лучше всего автоматизировать этот процесс?

Изменить: Оказывается кто-то уже сделал именно то, что мне нужно:

Этим утром у меня была возможность развернуть ветку репозитория git на промежуточном сервере, но я не имел ни малейшего представления, как это сделать. Быстрый поиск в исходном коде capistrano показал, что я могу использовать set :branch "branch_name" в моем сценарии развертывания. Я попробовал, и это сработало. Затем я подумал, что мне нужно будет внести аналогичные изменения во все мои ветки. Конечно, я ленивый дурачок и задавался вопросом, нет ли лучшего способа.

Если вы не знакомы с git, вывод команды git branch представляет собой список веток со звездочкой, отмеченной той, которая в настоящее время проверена на вашем локальном компьютере. Например:

> git branch
* drupal_authentication
fragment_caching
master

Итак, я подумал, что, если бы я просто проанализировал вывод и поискал ветку, помеченную как текущую:

set :branch, $1 if `git branch` =~ /\* (\S+)\s/m

Теперь я могу развернуть любую ветку, текущую на моем локальном компьютере, с помощью единого общего сценария развертывания.


person Toms Mikoss    schedule 06.10.2009    source источник


Ответы (13)


Это работает с Capistrano> = 3.1:

добавьте эту строку в config/deploy.rb:

set :branch, ENV['BRANCH'] if ENV['BRANCH']

а затем вызовите capistrano с помощью:

cap production deploy BRANCH=master

Это решение работает с Capistrano ‹3.1:

# call with cap -s env="<env>" branch="<branchname>" deploy

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")
person wintersolutions    schedule 30.01.2012
comment
При использовании расширения mustistage нет необходимости устанавливать env, но это сработало для меня, просто используя ветку - person Tom Harrison; 24.08.2012
comment
как указано в @lulalala, мне нужно использовать -s в нижнем регистре, чтобы получить указанную ветку. - person Jahan; 07.12.2013
comment
@Jani: Спасибо, кажется, они изменили это в новых релизах capistrano, я соответствующим образом отредактировал свой ответ. - person wintersolutions; 07.12.2013
comment
У меня была прямо противоположная проблема, чем у @Jani: мне пришлось использовать -S в верхнем регистре, иначе аргумент не передавался в cap при использовании fetch (: var_name, 'default') для его получения. - person Frederik Struck-Schøning; 23.01.2014
comment
опция '-s' (--set) означает 'Установить переменную после загрузки рецептов'. а опция «S» (--set-before) означает «Установить переменную перед загрузкой рецептов». - person Ramon Caldeira; 30.07.2014

Используя Capistrano 3.1.0+, ни один из них больше не работал у меня. Вместо этого, согласно их прокомментированным инструкциям:

   ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

Но вы не хотите использовать ask, иначе он вам подскажет. Вместо этого вы должны использовать set. HEAD - это самая верхняя ветвь; «край», как это называется. Если вам нужна другая ветка, замените HEAD именем своей ветки, например: master, staging и т. Д.

В заключение с примерами в /config/deploy/production.rb вы можете включить эту строку:

   set :branch, proc { `git rev-parse --abbrev-ref master`.chomp }

...or

   set :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

Кстати, HEAD - это настройка по умолчанию, поэтому нет необходимости указывать это в файле. Может быть лучше использовать в /config/deploy/edge.rb.

В /config/deploy/staging.rb вы можете включить эту строку:

   set :branch, proc { `git rev-parse --abbrev-ref staging`.chomp }

...or

   set :branch, proc { `git rev-parse --abbrev-ref test`.chomp }

Вы поняли!

Надеюсь, эти примеры помогут будущим пользователям capistrano (^_^)

person Eric Wanchic    schedule 31.01.2014
comment
git rev-parse --abbrev-ref HEAD используется, чтобы узнать, в какой ветви находится HEAD. при запуске git rev-parse --abbrev-ref staging (почти) всегда выводится staging. Вы можете просто использовать set :branch, 'staging'. - person MiniGod; 05.12.2014

Я могу подтвердить, что нижеприведенное все еще работает в Cap 3.11.0 13/10/18, а также в Cap 2:

В deploy.rb / stage.rb:

set :branch, ENV['BRANCH'] || 'develop'

В командной строке:

cap deploy BRANCH=featurex

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

person Paul Odeon    schedule 18.03.2013

С многоступенчатостью это на самом деле сейчас:

cap production deploy -s branch=my-branch

Синтаксис предыдущего сообщения не работает в моей среде

person David Hersey    schedule 15.10.2012
comment
-s branch=foo устанавливает ветвь переменной capistrano на foo после загрузки рецептов. - person alvin; 23.04.2013

В качестве альтернативы вы можете структурировать его из командной строки, где у вас есть ветка и среда по умолчанию, а также вы можете передавать параметры в вызов cap, которые могут включать среду и используемую ветвь. Это может быть явно переданная ветвь, или у вас может быть параметр, который будет указывать текущую ветвь, как описано в указанной вами ссылке.

#call with cap -S env="<env>" branch="<branchname>" deploy
...

# Prevents error if not parameter passed, assumes that default 'cap deploy' command
# and should deploy the master branch to the production server
set(:env, ‘production’) unless exists?(:env)
set(:branch, ‘master’) unless exists?(:branch)

if !env.nil? && env == "production"
   role :web, "production_ip_address"
else   # add more as needed 
   role :web, "development_ip_address"
end

if !branch.nil? && branch == "current"
   set :branch, $1 if `git branch` =~ /\* (\S+)\s/m
elsif !branch.nil?
   set :branch, branch
else   # add more as needed 
   set :branch, "master"
end
...

Пример кода, сильно заимствованный отсюда

person naven87    schedule 17.11.2009
comment
Мне нужно использовать строчные буквы -s, чтобы получить указанную ветку - person lulalala; 11.06.2012
comment
У меня была прямо противоположная проблема, чем у @lulula: мне пришлось использовать -S в верхнем регистре, иначе аргумент не перешел бы в cap при использовании fetch (: var_name, 'default') для его получения. - person Frederik Struck-Schøning; 23.01.2014

Если вы используете capistrano-multistage, вам нужно только запустить

cap -s branch=$MY_BRANCH deploy

or

cap -s branch=$MY_BRANCH production deploy

без дальнейшего редактирования вашего deploy.rb.

person asymmetric    schedule 09.07.2012
comment
Это должно быть branch=, а не branch-. - person Jimothy; 02.05.2013
comment
OptionParser :: AmbiguousOption: неоднозначный параметр: -s - person giorgio; 14.01.2015

Эта команда больше не будет работать:

cap deploy -s branch=your_branch

Поддержка -sS флагов была удалена в capistrano v3 +.
Здесь вы можете узнать больше об этом: ссылка
Это было упомянуто в пару ответов, но на данный момент не верный.

Что у меня работает:
в deploy.rb файл добавить

set :branch, ENV['BRANCH'] || :master

затем запустите:

BRANCH=your_branch cap deploy

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

person SakyHank    schedule 14.05.2016

Это решение должно работать со всеми версиями Capistrano.

def branch_name(default_branch)
  branch = ENV.fetch('BRANCH', default_branch)

  if branch == '.'
    # current branch
    `git rev-parse --abbrev-ref HEAD`.chomp
  else
    branch
  end
end

set :branch, branch_name('master')

Использование:

BRANCH=. cap [staging] deploy
# => deploy current branch

BRANCH=master cap [staging] deploy
# => deploy master branch

cap [staging] deploy
# => deploy default branch
person Pablo Cantero    schedule 25.06.2014

Я использую версию 3.3.5, и у меня это работает:

set :branch, 'develop'
person David Rosa    schedule 22.01.2015

Общий ответ:

Если у вас есть файл настроек, содержимое которого изменяется от среды к среде, вы должны сделать эту строку «шаблоном» (со строкой, представляющей имя переменной, например @BRANCH_NAME@ или @ENV_NAME@).

Тогда у вас будет (версионный) скрипт, способный читать ваш файл конфигурации и заменять переменную «@BRANCH_NAME@» на соответствующее значение, необходимое для вашего процесса развертывания.

person VonC    schedule 06.10.2009

Для пользователей capistrano 3:

desc "prompt for branch or tag"
task :git_branch_or_tag do
  on roles(:all) do |host|
    run_locally do
      execute :git, 'tag'
      tag_prompt = "Enter a branch or tag name to deploy"
      ask(:branch_or_tag, tag_prompt)
      tag_branch_target = fetch(:branch_or_tag, 'master')
      set(:branch, tag_branch_target)
    end
  end
end

before 'deploy:updated',  :git_branch_or_tag
person lfender6445    schedule 03.11.2014

Метод 1. Установите конкретную ветвь этапа (например, тестовую, производственную) для развертывания

Поместите branch конфигурацию в файлы сцены вместо deploy.rb и задайте целевую ветвь для этой стадии, из которой будет выполняться развертывание.

Для двухэтапного приложения с ассоциированным именем ветки test и production конфигурация будет выглядеть следующим образом:

# app_root/config/deploy/test.rb
...
set :branch, "test"
...

# app_root/config/deploy/production.rb
...
set :branch, "production"
...

Этот метод позволяет выполнять развертывание из отдельных веток этапа. Таким образом, потребуется лишь дополнительный шаг - объединить или переустановить последний код из базовой ветки.

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

Другой подход - развертывание с использованием тега. Для развертывания с использованием тега установите branch config. в deploy.rb следующим образом,

set :branch, `git describe --tags $(git rev-list --tags --max-count=1)`.chomp

И настройте CI для условного развертывания на разных этапах, если соответствующий шаблон тега совпадает (например, /.*-test$/).

Теперь развертывание можно производить из любой ветки,

  • Сначала создайте тег из любой ветки,

    git tag -a v0.1.0-test -m "Версия 0.1.0-test"

  • И нажмите

    git push origin v0.1.0-тест

Примечание. Вышеуказанные методы основаны на Capistrano 3.

person Shakil    schedule 09.09.2017

git rev-parse --abbrev-ref HEAD

вернет текущую ветку, в которой вы находитесь.

Я всегда устанавливаю gpsh вместо git push -u origin branch_name

$ which gpsh
gpsh: aliased to git push -u origin `git rev-parse --abbrev-ref HEAD`
person TorvaldsDB    schedule 18.11.2019