نشر دليل فرعي لـ Git في Capistrano
-
09-06-2019 - |
سؤال
تخطيط الفرع الرئيسي الخاص بي هو مثل هذا:
/ <--المستوى الأعلى
/عميل <-- الملفات المصدر لعميل سطح المكتب
/الخادم <-- تطبيق ريلز
ما أود القيام به هو فقط سحب الدليل /server الموجود في ملفي deploy.rb
, ، ولكن يبدو أنني لا أستطيع العثور على أي طريقة للقيام بذلك.يعد دليل /client ضخمًا، لذا فإن إعداد رابط لنسخ /server إلى / لن يعمل بشكل جيد، فهو يحتاج فقط إلى سحب تطبيق Rails للأسفل.
المحلول
دون أي عمل شوكة قذرة ولكن حتى أقذر!
في ملف 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)
نصائح أخرى
بالنسبة إلى 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.
نحن نقوم بذلك أيضًا مع Capistrano عن طريق استنساخ المستودع الكامل، وحذف الملفات والمجلدات غير المستخدمة ونقل المجلد المطلوب إلى أعلى التسلسل الهرمي.
نشر.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
طالما أن المشروع لم يصبح كبيرًا جدًا، فهذا جيد جدًا بالنسبة لنا، ولكن إذا أمكن، قم بإنشاء مستودع خاص لكل مكون وقم بتجميعها معًا باستخدام وحدات git الفرعية.
يمكن أن يكون لديك مستودعين git (العميل والخادم) وإضافتهما إلى "مشروع فائق" (تطبيق).في هذا "المشروع الفائق" يمكنك إضافة المستودعين كوحدات فرعية (راجع هذا البرنامج التعليمي).
الحل الآخر المحتمل (أكثر قذارة قليلاً) هو أن يكون لديك فروع منفصلة للعميل والخادم، وبعد ذلك يمكنك السحب من فرع "الخادم".
هل هناك حل.الاستيلاء على crdlo التصحيح لكابيسترانو و ال مصدر كابسترانو من جيثب.قم بإزالة جوهرة capistrano الموجودة لديك، ثم قم بتثبيت التصحيح، ثم قم بتثبيت setup.rb، وبعد ذلك يمكنك استخدام خط التكوين البسيط الخاص به set :project, "mysubdirectory"
لتعيين دليل فرعي.
المشكلة الوحيدة هي أن جيثب على ما يبدو لا "يدعم أمر الأرشيف" ...على الأقل عندما كتب ذلك.أنا أستخدم git repo الخاص بي عبر svn وهو يعمل بشكل جيد، ولم أجربه مع github ولكني أتخيل أنه إذا اشتكى عدد كافٍ من الأشخاص فسوف يضيفون هذه الميزة.
تحقق أيضًا مما إذا كان بإمكانك إقناع مؤلفي capistrano بإضافة هذه الميزة إلى الحد الأقصى في الخطأ ذات الصلة.
بالنسبة إلى Capistrano 3، استنادًا إلى إجابة @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"
لسوء الحظ، لا يوفر git أي طريقة للقيام بذلك.بدلاً من ذلك، تتمثل "طريقة git" في الحصول على مستودعين - العميل والخادم، واستنساخ المستودع (المستودعات) الذي تحتاجه.
لقد قمت بإنشاء مقتطف يعمل مع Capistrano 3.x بناءً على الإجابات السابقة والمعلومات الأخرى الموجودة في جيثب:
# 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 on جيثب.
يبدو أيضًا أنه لا يعمل مع codebasehq.com، لذلك انتهيت من تنفيذ مهام capistrano التي تنظف الفوضى :-) ربما توجد في الواقع طريقة أقل اختراقًا للقيام بذلك عن طريق تجاوز بعض مهام capistrano...
لقد كان هذا يعمل بالنسبة لي لبضع ساعات.
# 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).
دعونا نرى مدى قوتها.استخدام "قبل" ضعيف جدًا.