Deploying a Git subdirectory in Capistrano

前端 未结 11 1292
梦谈多话
梦谈多话 2020-12-07 09:03

My master branch layout is like this:

/ <-- top level

/client <-- desktop client source files

/server

相关标签:
11条回答
  • 2020-12-07 09:17

    For Capistrano 3, based on @Thomas Fankhauser answer:

    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"
    
    0 讨论(0)
  • 2020-12-07 09:18

    There is a solution. Grab crdlo's patch for capistrano and the capistrano source from github. Remove your existing capistrano gem, appy the patch, setup.rb install, and then you can use his very simple configuration line set :project, "mysubdirectory" to set a subdirectory.

    The only gotcha is that apparently github doesn't "support the archive command" ... at least when he wrote it. I'm using my own private git repo over svn and it works fine, I haven't tried it with github but I imagine if enough people complain they'll add that feature.

    Also see if you can get capistrano authors to add this feature into cap at the relevant bug.

    0 讨论(0)
  • 2020-12-07 09:20

    We're also doing this with Capistrano by cloning down the full repository, deleting the unused files and folders and move the desired folder up the hierarchy.

    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
    

    As long as the project doesn't get too big this works pretty good for us, but if you can, create an own repository for each component and group them together with git submodules.

    0 讨论(0)
  • 2020-12-07 09:21

    Unfortunately, git provides no way to do this. Instead, the 'git way' is to have two repositories -- client and server, and clone the one(s) you need.

    0 讨论(0)
  • 2020-12-07 09:23

    For Capistrano 3.0, I use the following:

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

    And in my 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'
    

    All the important code is in the strategy release method, which uses git archive to archive only a subdirectory of the repo, then uses the --strip argument to tar to extract the archive at the right level.

    UPDATE

    As of Capistrano 3.3.3, you can now use the :repo_tree configuration variable, which makes this answer obsolete. For example:

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

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

    0 讨论(0)
  • 2020-12-07 09:24

    I created a snipped that works with Capistrano 3.x based in previous anwers and other information found 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
    

    It's also available as a Gist on Github.

    0 讨论(0)
提交回复
热议问题