git-deploy-ng 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/AGENTS.md +46 -0
- data/CHANGELOG.md +37 -0
- data/CONTRIBUTING.md +41 -3
- data/README.md +335 -0
- data/ROADMAP.md +15 -3
- data/bin/update-changelog +47 -0
- data/lib/git_deploy/changelog.rb +125 -0
- data/lib/git_deploy/configuration.rb +20 -5
- data/lib/git_deploy/generator.rb +39 -2
- data/lib/git_deploy/remote_path.rb +28 -0
- data/lib/git_deploy/ssh_methods.rb +15 -0
- data/lib/git_deploy/templates/generic/after_push.sh +15 -0
- data/lib/git_deploy/templates/generic/before_restart.sh +3 -0
- data/lib/git_deploy/templates/generic/restart.sh +2 -0
- data/lib/git_deploy/templates/php-composer/after_push.sh +15 -0
- data/lib/git_deploy/templates/php-composer/before_restart.sh +12 -0
- data/lib/git_deploy/templates/php-composer/restart.sh +13 -0
- data/lib/git_deploy/templates/rails-puma/after_push.sh +17 -0
- data/lib/git_deploy/templates/rails-puma/before_restart.rb +38 -0
- data/lib/git_deploy/templates/rails-puma/restart.sh +9 -0
- data/lib/git_deploy.rb +43 -5
- data/spec/changelog_spec.rb +110 -0
- data/spec/cli_spec.rb +9 -1
- data/spec/commands_spec.rb +22 -0
- data/spec/configuration_spec.rb +10 -0
- data/spec/documentation_spec.rb +15 -0
- data/spec/generator_spec.rb +75 -0
- data/spec/hooks_spec.rb +15 -0
- data/spec/remote_path_spec.rb +45 -0
- data/spec/setup_spec.rb +48 -1
- data/spec/workflows_spec.rb +57 -0
- metadata +25 -6
- data/README.markdown +0 -172
- /data/lib/git_deploy/templates/{after_push.sh → rails-passenger/after_push.sh} +0 -0
- /data/lib/git_deploy/templates/{before_restart.rb → rails-passenger/before_restart.rb} +0 -0
- /data/lib/git_deploy/templates/{restart.sh → rails-passenger/restart.sh} +0 -0
data/spec/commands_spec.rb
CHANGED
|
@@ -21,6 +21,28 @@ describe GitDeploy do
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
describe '#download' do
|
|
25
|
+
it 'copies remote files into the local app directory' do
|
|
26
|
+
instance = described_class.new([], remote: 'production', noop: true)
|
|
27
|
+
downloads = {}
|
|
28
|
+
|
|
29
|
+
allow(instance).to receive(:scp_download) { |files| downloads.merge!(files) }
|
|
30
|
+
instance.send(:git_config)['remote -v'] = "production\tgit@example.com:/apps/demo (fetch)"
|
|
31
|
+
|
|
32
|
+
instance.download('log/deploy.log')
|
|
33
|
+
|
|
34
|
+
expect(downloads['/apps/demo/log/deploy.log']).to eq('log/deploy.log')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'requires a remote' do
|
|
38
|
+
instance = described_class.new([], noop: true)
|
|
39
|
+
|
|
40
|
+
expect {
|
|
41
|
+
instance.download('index.html')
|
|
42
|
+
}.to output(/Specify a remote with -r/).to_stderr.and raise_error(SystemExit)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
24
46
|
describe '#restart' do
|
|
25
47
|
it 'runs the deploy restart script on the server' do
|
|
26
48
|
instance = described_class.new([], remote: 'production', noop: true)
|
data/spec/configuration_spec.rb
CHANGED
|
@@ -84,6 +84,16 @@ describe GitDeploy::Configuration do
|
|
|
84
84
|
it { expect(subject.deploy_to).to eq('~/path/to/app') }
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
+
context "scp-style relative path" do
|
|
88
|
+
it 'resolves against the remote home directory' do
|
|
89
|
+
instance = GitDeploy.new([], remote: 'production', noop: true)
|
|
90
|
+
instance.send(:git_config)['remote -v'] = "production\tgit@example.com:apps/myapp (fetch)"
|
|
91
|
+
allow(instance).to receive(:run).with('echo $HOME').and_return("/home/git\n")
|
|
92
|
+
|
|
93
|
+
expect(instance.send(:deploy_to)).to eq('/home/git/apps/myapp')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
87
97
|
context "pushurl only" do
|
|
88
98
|
before {
|
|
89
99
|
remote = options.fetch(:remote)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Documentation' do
|
|
4
|
+
it 'ships README.md and AGENTS.md instead of README.markdown' do
|
|
5
|
+
expect(File).to exist('README.md')
|
|
6
|
+
expect(File).to exist('AGENTS.md')
|
|
7
|
+
expect(File).not_to exist('README.markdown')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'documents required remote in README' do
|
|
11
|
+
readme = File.read('README.md')
|
|
12
|
+
expect(readme).to include('-r')
|
|
13
|
+
expect(readme).to include('AGENTS.md')
|
|
14
|
+
end
|
|
15
|
+
end
|
data/spec/generator_spec.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'tmpdir'
|
|
3
|
+
require 'fileutils'
|
|
3
4
|
require 'git_deploy/generator'
|
|
4
5
|
|
|
5
6
|
describe GitDeploy::Generator do
|
|
@@ -11,6 +12,80 @@ describe GitDeploy::Generator do
|
|
|
11
12
|
expect(File.executable?('deploy/after_push')).to be true
|
|
12
13
|
expect(File.executable?('deploy/restart')).to be true
|
|
13
14
|
expect(File.executable?('deploy/before_restart')).to be true
|
|
15
|
+
expect(File.read('deploy/restart')).to include('Passenger')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'generates PHP/composer scripts with the php-composer template' do
|
|
21
|
+
Dir.mktmpdir do |dir|
|
|
22
|
+
Dir.chdir(dir) do
|
|
23
|
+
described_class.start(['--template', 'php-composer'])
|
|
24
|
+
|
|
25
|
+
expect(File.read('deploy/before_restart')).to include('composer install')
|
|
26
|
+
expect(File.read('deploy/restart')).to include('PHP')
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'rejects unknown templates' do
|
|
32
|
+
Dir.mktmpdir do |dir|
|
|
33
|
+
Dir.chdir(dir) do
|
|
34
|
+
expect {
|
|
35
|
+
described_class.start(['--template', 'django'])
|
|
36
|
+
}.to output(/Unknown template/).to_stderr.and raise_error(SystemExit)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'rejects path traversal in template names' do
|
|
42
|
+
Dir.mktmpdir do |dir|
|
|
43
|
+
Dir.chdir(dir) do
|
|
44
|
+
expect {
|
|
45
|
+
described_class.start(['--template', '../rails-passenger'])
|
|
46
|
+
}.to output(/Unknown template/).to_stderr.and raise_error(SystemExit)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'refuses to run when deploy exists as a file' do
|
|
52
|
+
Dir.mktmpdir do |dir|
|
|
53
|
+
Dir.chdir(dir) do
|
|
54
|
+
File.write('deploy', '#!/bin/sh')
|
|
55
|
+
|
|
56
|
+
expect {
|
|
57
|
+
described_class.start([])
|
|
58
|
+
}.to output(/deploy.*is a file/).to_stderr.and raise_error(SystemExit)
|
|
59
|
+
|
|
60
|
+
expect(File.directory?('deploy')).to be false
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'warns and preserves existing files when deploy is not empty' do
|
|
66
|
+
Dir.mktmpdir do |dir|
|
|
67
|
+
Dir.chdir(dir) do
|
|
68
|
+
FileUtils.mkdir_p('deploy')
|
|
69
|
+
File.write('deploy/custom', 'keep me')
|
|
70
|
+
|
|
71
|
+
expect {
|
|
72
|
+
described_class.start([])
|
|
73
|
+
}.to output(/already exists/).to_stdout
|
|
74
|
+
|
|
75
|
+
expect(File.read('deploy/custom')).to eq('keep me')
|
|
76
|
+
expect(File.executable?('deploy/after_push')).to be true
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'generates a PHP restart script that fails when reload fails' do
|
|
82
|
+
Dir.mktmpdir do |dir|
|
|
83
|
+
Dir.chdir(dir) do
|
|
84
|
+
described_class.start(['--template', 'php-composer'])
|
|
85
|
+
|
|
86
|
+
restart = File.read('deploy/restart')
|
|
87
|
+
expect(restart).not_to include('|| true')
|
|
88
|
+
expect(restart).to include('exit 1')
|
|
14
89
|
end
|
|
15
90
|
end
|
|
16
91
|
end
|
data/spec/hooks_spec.rb
CHANGED
|
@@ -8,11 +8,26 @@ describe GitDeploy do
|
|
|
8
8
|
|
|
9
9
|
allow(instance).to receive(:scp_upload) { |files| uploads.merge!(files) }
|
|
10
10
|
allow(instance).to receive(:run)
|
|
11
|
+
allow(instance).to receive(:run_test).and_return(false)
|
|
11
12
|
instance.send(:git_config)['remote -v'] = "production\tgit@example.com:/apps/demo (fetch)"
|
|
12
13
|
|
|
13
14
|
instance.hooks
|
|
14
15
|
|
|
15
16
|
expect(uploads.values).to include('/apps/demo/.git/hooks/post-receive')
|
|
16
17
|
end
|
|
18
|
+
|
|
19
|
+
it 'requires a remote name' do
|
|
20
|
+
instance = described_class.new([], noop: true)
|
|
21
|
+
|
|
22
|
+
expect { instance.hooks }.to output(/Specify a remote with -r/).to_stderr.and raise_error(SystemExit)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'refuses to overwrite an existing post-receive hook without --force' do
|
|
26
|
+
instance = described_class.new([], remote: 'production', noop: true)
|
|
27
|
+
instance.send(:git_config)['remote -v'] = "production\tgit@example.com:/apps/demo (fetch)"
|
|
28
|
+
allow(instance).to receive(:run_test).with("[ -f /apps/demo/.git/hooks/post-receive ]").and_return(true)
|
|
29
|
+
|
|
30
|
+
expect { instance.hooks }.to output(/already has a post-receive hook/).to_stderr.and raise_error(SystemExit)
|
|
31
|
+
end
|
|
17
32
|
end
|
|
18
33
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'git_deploy/remote_path'
|
|
3
|
+
|
|
4
|
+
describe GitDeploy::RemotePath do
|
|
5
|
+
describe '.raw_path' do
|
|
6
|
+
it 'returns a relative path from scp-style remotes' do
|
|
7
|
+
expect(described_class.raw_path('git@example.com:apps/myapp')).to eq('apps/myapp')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'returns an absolute path from scp-style remotes' do
|
|
11
|
+
expect(described_class.raw_path('git@example.com:/apps/myapp')).to eq('/apps/myapp')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'returns a home-relative path from scp-style remotes' do
|
|
15
|
+
expect(described_class.raw_path('git@example.com:~/apps/myapp')).to eq('~/apps/myapp')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'returns the path from ssh URLs' do
|
|
19
|
+
expect(described_class.raw_path('ssh://git@example.com:88/apps/myapp')).to eq('/apps/myapp')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'aborts when the url is missing' do
|
|
23
|
+
expect {
|
|
24
|
+
described_class.raw_path(nil)
|
|
25
|
+
}.to output(/No deploy remote URL configured/).to_stderr.and raise_error(SystemExit)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '.deploy_path' do
|
|
30
|
+
it 'joins relative paths with the remote home directory' do
|
|
31
|
+
expect(described_class.deploy_path('git@example.com:apps/myapp') { '/home/git' }).
|
|
32
|
+
to eq('/home/git/apps/myapp')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'leaves absolute paths unchanged' do
|
|
36
|
+
expect(described_class.deploy_path('git@example.com:/var/www/app', home: '/home/git')).
|
|
37
|
+
to eq('/var/www/app')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'leaves home-relative paths unchanged' do
|
|
41
|
+
expect(described_class.deploy_path('git@example.com:~/apps/myapp', home: '/home/git')).
|
|
42
|
+
to eq('~/apps/myapp')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/spec/setup_spec.rb
CHANGED
|
@@ -4,9 +4,13 @@ describe GitDeploy do
|
|
|
4
4
|
describe '#setup' do
|
|
5
5
|
let(:instance) { described_class.new([], remote: 'production', noop: true, shared: false, sudo: false) }
|
|
6
6
|
let(:commands) { [] }
|
|
7
|
+
let(:run_tests) { {} }
|
|
7
8
|
|
|
8
9
|
before do
|
|
9
|
-
allow(instance).to receive(:run_test)
|
|
10
|
+
allow(instance).to receive(:run_test) do |cmd|
|
|
11
|
+
run_tests[cmd] = false if run_tests[cmd].nil?
|
|
12
|
+
run_tests[cmd]
|
|
13
|
+
end
|
|
10
14
|
allow(instance).to receive(:run) do |cmd = nil, **_opts, &block|
|
|
11
15
|
cmd = block.call([]) if block
|
|
12
16
|
commands << cmd
|
|
@@ -15,6 +19,49 @@ describe GitDeploy do
|
|
|
15
19
|
instance.send(:git_config)['remote -v'] = "production\tgit@example.com:/apps/demo (fetch)"
|
|
16
20
|
end
|
|
17
21
|
|
|
22
|
+
it 'requires a remote name' do
|
|
23
|
+
instance = described_class.new([], noop: true)
|
|
24
|
+
|
|
25
|
+
expect { instance.setup }.to output(/Specify a remote with -r/).to_stderr.and raise_error(SystemExit)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'refuses to overwrite an existing post-receive hook without --force' do
|
|
29
|
+
run_tests["[ -f /apps/demo/.git/hooks/post-receive ]"] = true
|
|
30
|
+
|
|
31
|
+
expect { instance.setup }.to output(/already has a post-receive hook/).to_stderr.and raise_error(SystemExit)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'proceeds when post-receive exists and --force is given' do
|
|
35
|
+
forced = described_class.new([], remote: 'production', noop: true, shared: false, sudo: false, force: true)
|
|
36
|
+
allow(forced).to receive(:run_test) do |cmd|
|
|
37
|
+
run_tests[cmd] = false if run_tests[cmd].nil?
|
|
38
|
+
run_tests[cmd]
|
|
39
|
+
end
|
|
40
|
+
allow(forced).to receive(:run) do |cmd = nil, **_opts, &block|
|
|
41
|
+
cmd = block.call([]) if block
|
|
42
|
+
commands << cmd
|
|
43
|
+
end
|
|
44
|
+
allow(forced).to receive(:invoke)
|
|
45
|
+
forced.send(:git_config)['remote -v'] = "production\tgit@example.com:/apps/demo (fetch)"
|
|
46
|
+
run_tests["[ -f /apps/demo/.git/hooks/post-receive ]"] = true
|
|
47
|
+
run_tests["test -x /apps/demo"] = true
|
|
48
|
+
run_tests["[ -d /apps/demo/.git ]"] = true
|
|
49
|
+
|
|
50
|
+
forced.setup
|
|
51
|
+
|
|
52
|
+
expect(commands).not_to be_empty
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'skips git init when the remote repo already exists' do
|
|
56
|
+
run_tests["[ -d /apps/demo/.git ]"] = true
|
|
57
|
+
|
|
58
|
+
instance.setup
|
|
59
|
+
|
|
60
|
+
init_cmd = commands.flatten.join(' && ')
|
|
61
|
+
expect(init_cmd).not_to include('git init')
|
|
62
|
+
expect(init_cmd).to include('git config receive.denyCurrentBranch ignore')
|
|
63
|
+
end
|
|
64
|
+
|
|
18
65
|
it 'initializes the remote repo with the current branch as HEAD' do
|
|
19
66
|
instance.send(:git_config)['symbolic-ref -q HEAD'] = 'refs/heads/main'
|
|
20
67
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
def load_workflow(path)
|
|
5
|
+
# Psych treats bare `on:` as boolean true; GitHub Actions uses it as the trigger key.
|
|
6
|
+
YAML.load(File.read(path).gsub(/^on:/, 'trigger:'))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe 'GitHub workflows' do
|
|
10
|
+
let(:ci) { load_workflow('.github/workflows/ci.yml') }
|
|
11
|
+
let(:release) { load_workflow('.github/workflows/release.yml') }
|
|
12
|
+
|
|
13
|
+
it 'verifies the gem builds on every CI run' do
|
|
14
|
+
expect(ci['jobs']).to have_key('build-gem')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'publishes to RubyGems when a version tag is pushed' do
|
|
18
|
+
expect(release['trigger']['push']['tags']).to include('v*')
|
|
19
|
+
expect(release['jobs']).to have_key('release')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'runs the test suite before publishing' do
|
|
23
|
+
steps = release.dig('jobs', 'release', 'steps').map { |s| s['run'] }.compact
|
|
24
|
+
expect(steps).to include('bundle exec rspec')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'publishes to RubyGems with the API key secret' do
|
|
28
|
+
steps = release.dig('jobs', 'release', 'steps')
|
|
29
|
+
publish = steps.find { |s| s['name'] == 'Build and publish to RubyGems' }
|
|
30
|
+
expect(publish).not_to be_nil
|
|
31
|
+
expect(publish['run']).to include('gem push')
|
|
32
|
+
expect(publish['env']).to include('GEM_HOST_API_KEY')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'builds the gem on the latest supported Ruby' do
|
|
36
|
+
ruby = ci.dig('jobs', 'build-gem', 'steps').
|
|
37
|
+
find { |s| s['uses'] == 'ruby/setup-ruby@v1' }['with']['ruby-version']
|
|
38
|
+
expect(ruby).to eq('4.0')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'verifies the release tag matches the gemspec version' do
|
|
42
|
+
steps = release.dig('jobs', 'release', 'steps').map { |s| s['name'] }
|
|
43
|
+
expect(steps).to include('Verify tag matches gemspec version')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'verifies the changelog documents the release' do
|
|
47
|
+
steps = release.dig('jobs', 'release', 'steps').map { |s| s['name'] }
|
|
48
|
+
expect(steps).to include('Verify CHANGELOG documents this release')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'creates a GitHub release from the changelog section' do
|
|
52
|
+
steps = release.dig('jobs', 'release', 'steps')
|
|
53
|
+
gh_release = steps.find { |s| s['uses']&.start_with?('softprops/action-gh-release') }
|
|
54
|
+
expect(gh_release).not_to be_nil
|
|
55
|
+
expect(gh_release['with']['body_path']).to eq('release-notes.md')
|
|
56
|
+
end
|
|
57
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git-deploy-ng
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Edwards
|
|
@@ -71,31 +71,50 @@ description: A community continuation of mislav/git-deploy. Push-based, Heroku-l
|
|
|
71
71
|
email: npfedwards@gmail.com
|
|
72
72
|
executables:
|
|
73
73
|
- git-deploy
|
|
74
|
+
- update-changelog
|
|
74
75
|
extensions: []
|
|
75
76
|
extra_rdoc_files: []
|
|
76
77
|
files:
|
|
78
|
+
- AGENTS.md
|
|
79
|
+
- CHANGELOG.md
|
|
77
80
|
- CONTRIBUTING.md
|
|
78
81
|
- LICENSE
|
|
79
82
|
- MAINTAINERS.md
|
|
80
|
-
- README.
|
|
83
|
+
- README.md
|
|
81
84
|
- ROADMAP.md
|
|
82
85
|
- bin/git-deploy
|
|
86
|
+
- bin/update-changelog
|
|
83
87
|
- lib/git_deploy.rb
|
|
88
|
+
- lib/git_deploy/changelog.rb
|
|
84
89
|
- lib/git_deploy/configuration.rb
|
|
85
90
|
- lib/git_deploy/generator.rb
|
|
91
|
+
- lib/git_deploy/remote_path.rb
|
|
86
92
|
- lib/git_deploy/ssh_methods.rb
|
|
87
|
-
- lib/git_deploy/templates/after_push.sh
|
|
88
|
-
- lib/git_deploy/templates/before_restart.
|
|
89
|
-
- lib/git_deploy/templates/restart.sh
|
|
93
|
+
- lib/git_deploy/templates/generic/after_push.sh
|
|
94
|
+
- lib/git_deploy/templates/generic/before_restart.sh
|
|
95
|
+
- lib/git_deploy/templates/generic/restart.sh
|
|
96
|
+
- lib/git_deploy/templates/php-composer/after_push.sh
|
|
97
|
+
- lib/git_deploy/templates/php-composer/before_restart.sh
|
|
98
|
+
- lib/git_deploy/templates/php-composer/restart.sh
|
|
99
|
+
- lib/git_deploy/templates/rails-passenger/after_push.sh
|
|
100
|
+
- lib/git_deploy/templates/rails-passenger/before_restart.rb
|
|
101
|
+
- lib/git_deploy/templates/rails-passenger/restart.sh
|
|
102
|
+
- lib/git_deploy/templates/rails-puma/after_push.sh
|
|
103
|
+
- lib/git_deploy/templates/rails-puma/before_restart.rb
|
|
104
|
+
- lib/git_deploy/templates/rails-puma/restart.sh
|
|
90
105
|
- lib/hooks/post-receive.sh
|
|
106
|
+
- spec/changelog_spec.rb
|
|
91
107
|
- spec/cli_spec.rb
|
|
92
108
|
- spec/commands_spec.rb
|
|
93
109
|
- spec/configuration_spec.rb
|
|
110
|
+
- spec/documentation_spec.rb
|
|
94
111
|
- spec/generator_spec.rb
|
|
95
112
|
- spec/hooks_spec.rb
|
|
113
|
+
- spec/remote_path_spec.rb
|
|
96
114
|
- spec/setup_spec.rb
|
|
97
115
|
- spec/spec_helper.rb
|
|
98
116
|
- spec/ssh_connection_spec.rb
|
|
117
|
+
- spec/workflows_spec.rb
|
|
99
118
|
homepage: https://github.com/npfedwards/git-deploy#readme
|
|
100
119
|
licenses:
|
|
101
120
|
- MIT
|
|
@@ -114,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
114
133
|
- !ruby/object:Gem::Version
|
|
115
134
|
version: '0'
|
|
116
135
|
requirements: []
|
|
117
|
-
rubygems_version: 4.0.
|
|
136
|
+
rubygems_version: 4.0.10
|
|
118
137
|
specification_version: 4
|
|
119
138
|
summary: Simple git push-based application deployment
|
|
120
139
|
test_files: []
|
data/README.markdown
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
Easy git deployment
|
|
2
|
-
===================
|
|
3
|
-
|
|
4
|
-
Community continuation of [mislav/git-deploy](https://github.com/mislav/git-deploy), published as **git-deploy-ng**. The CLI is unchanged: `git deploy <command>`.
|
|
5
|
-
|
|
6
|
-
Straightforward, [Heroku][]-style, push-based deployment. Your deploys can become as simple as this:
|
|
7
|
-
|
|
8
|
-
$ git push production main
|
|
9
|
-
|
|
10
|
-
To get started, install the gem on the machine that runs setup (once per project):
|
|
11
|
-
|
|
12
|
-
gem install git-deploy-ng
|
|
13
|
-
|
|
14
|
-
Only the person who is setting up deployment for the first time needs to install
|
|
15
|
-
the gem. You don't have to add it to your project's Gemfile. Production servers
|
|
16
|
-
do not need Ruby — only bash and git.
|
|
17
|
-
|
|
18
|
-
See [ROADMAP.md](ROADMAP.md) for ideas under consideration and [CONTRIBUTING.md](CONTRIBUTING.md) to contribute.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Migrating from mislav/git-deploy
|
|
22
|
-
--------------------------------
|
|
23
|
-
|
|
24
|
-
Requires **Ruby 2.7+** on the setup machine (including Ruby 4.x; system Ruby 2.6 on macOS is not supported).
|
|
25
|
-
|
|
26
|
-
1. `gem uninstall git-deploy` (optional)
|
|
27
|
-
2. `gem install git-deploy-ng`
|
|
28
|
-
3. `git deploy hooks -r production` (optional, per host — refreshes remote hooks)
|
|
29
|
-
|
|
30
|
-
Existing `deploy/` callback scripts in your apps do not need to change.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Which app languages/frameworks are supported?
|
|
34
|
-
---------------------------------------------
|
|
35
|
-
|
|
36
|
-
Regardless of the fact that this tool is mostly written in Ruby, git-deploy can be useful for any kind of code that needs deploying on a remote server. The default scripts are suited for Ruby web apps, but can be edited to accommodate other frameworks.
|
|
37
|
-
|
|
38
|
-
Your deployment is customized with per-project callback scripts which can be written in any language.
|
|
39
|
-
|
|
40
|
-
The assumption is that you're deploying to a single host to which you connect over SSH using public/private key authentication.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Initial setup
|
|
44
|
-
-------------
|
|
45
|
-
|
|
46
|
-
1. Create a git remote for where you'll push the code on your server. The name of this remote in the examples is "production", but it can be whatever you wish ("online", "website", or other).
|
|
47
|
-
|
|
48
|
-
```sh
|
|
49
|
-
git remote add production "user@example.com:/apps/mynewapp"
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
`/apps/mynewapp` is the directory where you want your code to reside on the
|
|
53
|
-
remote server. If the directory doesn't exist, the next step creates it.
|
|
54
|
-
|
|
55
|
-
2. Run the setup task:
|
|
56
|
-
|
|
57
|
-
```sh
|
|
58
|
-
git deploy setup -r "production"
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
This will initialize the remote git repository in the deploy directory
|
|
62
|
-
(`/apps/mynewapp` in the above example) and install the remote git hook.
|
|
63
|
-
|
|
64
|
-
3. Run the init task:
|
|
65
|
-
|
|
66
|
-
```sh
|
|
67
|
-
git deploy init
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
This generates default deploy callback scripts in the `deploy/` directory.
|
|
71
|
-
You should check them in git because they are going to be executed on the
|
|
72
|
-
server during each deploy.
|
|
73
|
-
|
|
74
|
-
4. Push the code.
|
|
75
|
-
|
|
76
|
-
```sh
|
|
77
|
-
git push production main
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Use whichever branch is checked out locally; `git deploy setup` configures the remote repo to match your current branch (`main` or `master`).
|
|
81
|
-
|
|
82
|
-
5. Login to your server and manually perform necessary one-time administrative operations. This might include:
|
|
83
|
-
* set up the Apache/nginx virtual host for this application;
|
|
84
|
-
* check your `config/database.yml` and create the production database.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Everyday deployments
|
|
88
|
-
--------------------
|
|
89
|
-
|
|
90
|
-
If you've set your app correctly, visiting <http://example.com> in your browser
|
|
91
|
-
should show it up and running.
|
|
92
|
-
|
|
93
|
-
Now, subsequent deployments are done simply **by pushing to the branch that is
|
|
94
|
-
currently checked out on the remote**:
|
|
95
|
-
|
|
96
|
-
git push production main
|
|
97
|
-
|
|
98
|
-
Because the deployments are performed with git, nobody else on the team needs to
|
|
99
|
-
install the git-deploy gem.
|
|
100
|
-
|
|
101
|
-
On every deploy, the default `deploy/after_push` script performs the following:
|
|
102
|
-
|
|
103
|
-
1. updates git submodules (if there are any);
|
|
104
|
-
2. runs `bundle install --deployment` if there is a Gemfile;
|
|
105
|
-
3. runs `rake db:migrate` if new migrations have been added;
|
|
106
|
-
4. clears cached CSS/JS assets in "public/stylesheets" and "public/javascripts";
|
|
107
|
-
5. restarts the web application.
|
|
108
|
-
|
|
109
|
-
You can customize all this by editing generated scripts in the `deploy/`
|
|
110
|
-
directory of your app.
|
|
111
|
-
|
|
112
|
-
Deployments are logged to `log/deploy.log` in your application's directory.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
How it works
|
|
116
|
-
------------
|
|
117
|
-
|
|
118
|
-
The `git deploy setup` command installed a `post-receive` git hook in the remote
|
|
119
|
-
repository. This is how your code on the server is kept up to date. This script
|
|
120
|
-
checks out the latest version of your project from the current branch and
|
|
121
|
-
runs the following callback scripts:
|
|
122
|
-
|
|
123
|
-
* `deploy/setup` - on first push.
|
|
124
|
-
* `deploy/after_push` - on subsequent pushes. It in turn executes:
|
|
125
|
-
* `deploy/before_restart`
|
|
126
|
-
* `deploy/restart`
|
|
127
|
-
* `deploy/after_restart`
|
|
128
|
-
* `deploy/rollback` - executed for `git deploy rollback`.
|
|
129
|
-
|
|
130
|
-
All of the callbacks are optional. These scripts are ordinary Unix executables.
|
|
131
|
-
The ones which get generated for you by `git deploy init` are written in shell
|
|
132
|
-
script and Ruby.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
Extra commands
|
|
136
|
-
--------------
|
|
137
|
-
|
|
138
|
-
* `git deploy hooks` - Updates git hooks on the remote repository
|
|
139
|
-
|
|
140
|
-
* `git deploy log [N=20]` - Shows last 20 lines of deploy log on the server
|
|
141
|
-
|
|
142
|
-
* `git deploy rerun` - Re-runs the `deploy/after_push` callback as if a git push happened
|
|
143
|
-
|
|
144
|
-
* `git deploy restart` - Runs the `deploy/restart` callback
|
|
145
|
-
|
|
146
|
-
* `git deploy rollback` - Undo a deploy by checking out the previous revision,
|
|
147
|
-
runs `deploy/rollback` if exists instead of `deploy/after_push`
|
|
148
|
-
|
|
149
|
-
* `git deploy upload <files>` - Copy local files to the remote app
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
Troubleshooting
|
|
153
|
-
---------------
|
|
154
|
-
|
|
155
|
-
### `unsupported key type ssh-ed25519`
|
|
156
|
-
|
|
157
|
-
Modern OpenSSH keys (ed25519) require optional gems that net-ssh does not bundle:
|
|
158
|
-
|
|
159
|
-
```sh
|
|
160
|
-
gem install ed25519 bcrypt_pbkdf
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
git-deploy-ng will print this command if the gems are missing when connecting.
|
|
164
|
-
|
|
165
|
-
### Still running upstream `git-deploy` 0.7.0?
|
|
166
|
-
|
|
167
|
-
The original gem targets older Ruby and net-ssh versions. Migrate to `git-deploy-ng`
|
|
168
|
-
on Ruby 2.7+ — see [Migrating from mislav/git-deploy](#migrating-from-mislavgit-deploy).
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
[heroku]: http://heroku.com/
|
|
File without changes
|
|
File without changes
|
|
File without changes
|