dkdeploy-core 8.0.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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rubocop.yml +18 -0
  4. data/Berksfile +3 -0
  5. data/Berksfile.lock +46 -0
  6. data/CONTRIBUTORS.md +16 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +7 -0
  9. data/README.md +88 -0
  10. data/Rakefile +5 -0
  11. data/Vagrantfile +60 -0
  12. data/config/vm/cookbooks/dkdeploy-core/metadata.rb +10 -0
  13. data/config/vm/cookbooks/dkdeploy-core/recipes/default.rb +56 -0
  14. data/dkdeploy-core.gemspec +34 -0
  15. data/features/apache.feature +35 -0
  16. data/features/assets.feature +100 -0
  17. data/features/bower.feature +52 -0
  18. data/features/current_folder.feature +17 -0
  19. data/features/db.feature +93 -0
  20. data/features/deploy.feature +48 -0
  21. data/features/enhanced_symlinks.feature +17 -0
  22. data/features/error_handlers.feature +59 -0
  23. data/features/file_access.feature +120 -0
  24. data/features/maintenance.feature +25 -0
  25. data/features/project_version.feature +42 -0
  26. data/features/support/env.rb +22 -0
  27. data/features/utils.feature +81 -0
  28. data/lib/capistrano/copy.rb +2 -0
  29. data/lib/capistrano/dkdeploy/core.rb +88 -0
  30. data/lib/dkdeploy/constants.rb +156 -0
  31. data/lib/dkdeploy/copy.rb +121 -0
  32. data/lib/dkdeploy/core/version.rb +15 -0
  33. data/lib/dkdeploy/dsl.rb +23 -0
  34. data/lib/dkdeploy/helpers/assets.rb +50 -0
  35. data/lib/dkdeploy/helpers/common.rb +31 -0
  36. data/lib/dkdeploy/helpers/db.rb +49 -0
  37. data/lib/dkdeploy/helpers/file_system.rb +76 -0
  38. data/lib/dkdeploy/i18n.rb +143 -0
  39. data/lib/dkdeploy/interaction_handler/password.rb +27 -0
  40. data/lib/dkdeploy/rollback_manager.rb +18 -0
  41. data/lib/dkdeploy/tasks/apache.rake +29 -0
  42. data/lib/dkdeploy/tasks/assets.rake +96 -0
  43. data/lib/dkdeploy/tasks/bower.rake +54 -0
  44. data/lib/dkdeploy/tasks/copy.rake +26 -0
  45. data/lib/dkdeploy/tasks/current_folder.rake +16 -0
  46. data/lib/dkdeploy/tasks/db.rake +412 -0
  47. data/lib/dkdeploy/tasks/deploy.rake +77 -0
  48. data/lib/dkdeploy/tasks/enhanced_symlinks.rake +74 -0
  49. data/lib/dkdeploy/tasks/fail.rake +8 -0
  50. data/lib/dkdeploy/tasks/file_access.rake +89 -0
  51. data/lib/dkdeploy/tasks/maintenance.rake +73 -0
  52. data/lib/dkdeploy/tasks/project_version.rake +32 -0
  53. data/lib/dkdeploy/tasks/utils.rake +141 -0
  54. data/lib/dkdeploy.rb +1 -0
  55. data/spec/fixtures/application/Capfile +11 -0
  56. data/spec/fixtures/application/Gemfile +11 -0
  57. data/spec/fixtures/application/Version +1 -0
  58. data/spec/fixtures/application/config/assets_exclude_file.txt +1 -0
  59. data/spec/fixtures/application/config/deploy/dev.rb +35 -0
  60. data/spec/fixtures/application/config/deploy.rb +18 -0
  61. data/spec/fixtures/application/config/etc/apache2/conf/.htaccess.erb +12 -0
  62. data/spec/fixtures/application/config/etc/apache2/conf/dev.htaccess.erb +3 -0
  63. data/spec/fixtures/application/config/preseed/default_content.sql.gz +0 -0
  64. data/spec/fixtures/application/config/preseed/default_structure.sql.gz +0 -0
  65. data/spec/fixtures/application/config/preseed/fileadmin.tar.gz +0 -0
  66. data/spec/fixtures/application/config/preseed/uploads.tar.gz +0 -0
  67. data/spec/fixtures/application/htdocs/.hidden/.gitkeep +0 -0
  68. data/spec/fixtures/application/htdocs/Gemfile +0 -0
  69. data/spec/fixtures/application/htdocs/bower.json +15 -0
  70. data/spec/fixtures/application/htdocs/catalog/.hidden/.gitkeep +0 -0
  71. data/spec/fixtures/application/htdocs/catalog/index.html +1 -0
  72. data/spec/fixtures/application/htdocs/index.html +1 -0
  73. data/spec/fixtures/application/htdocs/stylesheets/test1/config.rb +3 -0
  74. data/spec/fixtures/application/htdocs/stylesheets/test1/css/.gitkeep +0 -0
  75. data/spec/fixtures/application/htdocs/stylesheets/test1/src/source.scss +5 -0
  76. data/spec/fixtures/application/htdocs/stylesheets/test2/config.rb +3 -0
  77. data/spec/fixtures/application/htdocs/stylesheets/test2/css/.gitkeep +0 -0
  78. data/spec/fixtures/application/htdocs/stylesheets/test2/src/source.scss +5 -0
  79. data/spec/fixtures/application/temp/dkdeploy_core.sql.gz +0 -0
  80. data/spec/fixtures/capistrano/configuration/add_output_after_create_symlink.rb +7 -0
  81. data/spec/fixtures/capistrano/configuration/custom_compass_sources.rb +4 -0
  82. data/spec/fixtures/capistrano/configuration/custom_file_access.rb +13 -0
  83. data/spec/fixtures/capistrano/configuration/default_deployment_behaviour.rb +9 -0
  84. metadata +346 -0
@@ -0,0 +1,22 @@
1
+ require 'dkdeploy/test_environment/application'
2
+
3
+ ssh_config = {}
4
+
5
+ ssh_key_files = Dir.glob(File.join(Dir.getwd, '.vagrant', 'machines', '**', 'virtualbox', 'private_key'))
6
+ unless ssh_key_files.empty?
7
+ # Define generated ssh key files
8
+ ssh_config = {
9
+ user: 'vagrant',
10
+ keys: ssh_key_files
11
+ }
12
+ end
13
+
14
+ TEST_APPLICATION = Dkdeploy::TestEnvironment::Application.new(File.expand_path('../../../', __FILE__), 'dkdeploy-core.dev', ssh_config)
15
+ TEST_APPLICATION.mysql_connection_settings = { host: 'dkdeploy-core.dev', username: 'root', password: 'ilikerandompasswords' }
16
+
17
+ # this configuration tricks Bundler into executing another Bundler project with clean enviroment
18
+ # The official way via Bundler.with_clean_env did not work properly here
19
+ Aruba.configure do |config|
20
+ config.command_runtime_environment = { 'BUNDLE_GEMFILE' => File.join(TEST_APPLICATION.test_app_path, 'Gemfile') }
21
+ config.exit_timeout = 10
22
+ end
@@ -0,0 +1,81 @@
1
+ Feature: Test tasks for namespace 'utils'
2
+
3
+ Background:
4
+ Given a test app with the default configuration
5
+ And the remote server is cleared
6
+
7
+ Scenario: Upload local file to server
8
+ Given an empty file named "htdocs/new_file.html"
9
+ Then I successfully run `cap dev utils:upload_file['htdocs/new_file.html']`
10
+ Then a remote file named "current_path/new_file.html" should exist
11
+
12
+ Scenario: Upload local file to server which does not exist locally
13
+ And I run `cap dev utils:upload_file['htdocs/new_file.html']`
14
+ Then the exit status should be 1
15
+
16
+ Scenario: Call task "utils:upload_file" without entering any file name
17
+ Given an empty file named "htdocs/new_file.html"
18
+ When I run `cap dev utils:upload_file` interactively
19
+ And I type ""
20
+ And I close the stdin stream
21
+ Then the exit status should be 1
22
+ And a remote file named "current_path/new_file.html" should not exist
23
+
24
+ Scenario: Download remote file
25
+ Given a remote directory named "current_path"
26
+ And a remote file named "current_path/download_file.txt" with:
27
+ """
28
+ Remote file content
29
+ """
30
+ When I successfully run `cap dev utils:download_file['download_file.txt']`
31
+ Then a file named "temp/download_file.dkdeploy-core.dev.txt" should exist
32
+
33
+ Scenario: Download a file from server which does exist locally
34
+ Given a file named "temp/download_file.dkdeploy-core.dev.txt" with:
35
+ """
36
+ Local file content
37
+ """
38
+ And a remote directory named "current_path"
39
+ And a remote file named "current_path/download_file.txt" with:
40
+ """
41
+ Remote file content
42
+ """
43
+ When I successfully run `cap dev utils:download_file['download_file.txt']`
44
+ Then the file "temp/download_file.dkdeploy-core.dev.txt" should contain exactly:
45
+ """
46
+ Remote file content
47
+
48
+ """
49
+
50
+ Scenario: Call task "utils:download_file" without entering any file name
51
+ When I run `cap dev utils:download_file` interactively
52
+ And I type ""
53
+ And I close the stdin stream
54
+ Then the exit status should be 1
55
+
56
+ Scenario: Rsync add new files to server
57
+ Given the project is deployed
58
+ And an empty file named "htdocs/new_file.txt"
59
+ And I successfully run `cap dev utils:rsync`
60
+ Then a remote file named "current_path/new_file.txt" should exist
61
+
62
+ Scenario: Rsync add new files at root to server
63
+ Given the project is deployed
64
+ And I extend the development capistrano configuration variable rsync_path with value '.'
65
+ And an empty file named "new_file.txt"
66
+ And I successfully run `cap dev utils:rsync`
67
+ Then a remote file named "current_path/new_file.txt" should exist
68
+
69
+ Scenario: Rsync exclude files
70
+ Given the project is deployed
71
+ And I extend the development capistrano configuration variable rsync_exclude with value ['file_to_exclude.txt']
72
+ And an empty file named "htdocs/file_to_exclude.txt"
73
+ And I successfully run `cap dev utils:rsync`
74
+ Then a remote file named "current_path/file_to_exclude.txt" should not exist
75
+
76
+ Scenario: Create custom directories within path shared
77
+ When I run `cap dev utils:create_custom_directories` interactively
78
+ And I type "mydirectory"
79
+ And I close the stdin stream
80
+ Then the exit status should be 0
81
+ And a remote directory named "shared_path/mydirectory" should exist
@@ -0,0 +1,2 @@
1
+ # if capistrano scm is set to copy, the current file will be loaded
2
+ load File.expand_path('../../dkdeploy/tasks/copy.rake', __FILE__)
@@ -0,0 +1,88 @@
1
+ include Capistrano::DSL
2
+
3
+ require 'dkdeploy/rollback_manager'
4
+
5
+ # Load dkdeploy tasks
6
+ load File.expand_path('../../../dkdeploy/tasks/deploy.rake', __FILE__)
7
+ load File.expand_path('../../../dkdeploy/tasks/fail.rake', __FILE__)
8
+ load File.expand_path('../../../dkdeploy/tasks/maintenance.rake', __FILE__)
9
+ load File.expand_path('../../../dkdeploy/tasks/utils.rake', __FILE__)
10
+ load File.expand_path('../../../dkdeploy/tasks/file_access.rake', __FILE__)
11
+ load File.expand_path('../../../dkdeploy/tasks/assets.rake', __FILE__)
12
+ load File.expand_path('../../../dkdeploy/tasks/apache.rake', __FILE__)
13
+ load File.expand_path('../../../dkdeploy/tasks/project_version.rake', __FILE__)
14
+ load File.expand_path('../../../dkdeploy/tasks/db.rake', __FILE__)
15
+ load File.expand_path('../../../dkdeploy/tasks/enhanced_symlinks.rake', __FILE__)
16
+ load File.expand_path('../../../dkdeploy/tasks/current_folder.rake', __FILE__)
17
+ load File.expand_path('../../../dkdeploy/tasks/bower.rake', __FILE__)
18
+
19
+ # Hook into symlink related tasks
20
+ after 'deploy:check:linked_dirs', 'deploy:enhanced_symlinks:check:linked_dirs'
21
+ after 'deploy:check:linked_files', 'deploy:enhanced_symlinks:check:linked_files'
22
+ after 'deploy:check:make_linked_dirs', 'deploy:enhanced_symlinks:check:make_linked_dirs'
23
+ after 'deploy:symlink:linked_dirs', 'deploy:enhanced_symlinks:symlink:linked_dirs'
24
+ after 'deploy:symlink:linked_files', 'deploy:enhanced_symlinks:symlink:linked_files'
25
+
26
+ namespace :load do
27
+ task :defaults do
28
+ # Set scm to new scm "copy"
29
+ set :scm, :copy
30
+
31
+ # Set default values for copy scm
32
+ set :copy_source, 'htdocs'
33
+ set :copy_exclude, Array[
34
+ 'vendor/bundle/**',
35
+ 'Gemfile*',
36
+ '**/.git',
37
+ '**/.svn',
38
+ '**/.DS_Store',
39
+ '.settings',
40
+ '.project',
41
+ '.buildpath',
42
+ 'Capfile',
43
+ 'Thumbs.db',
44
+ 'composer.lock'
45
+ ]
46
+
47
+ # Set default web root paths
48
+ set :local_web_root_path, -> { fetch(:copy_source) }
49
+ set :remote_web_root_path, '.'
50
+
51
+ # Set default version file path
52
+ set :version_file_path, ''
53
+
54
+ # default file owner
55
+ set :default_file_access_owner_of_shared_path, 'www-data'
56
+ set :default_file_access_owner_of_release_path, 'www-data'
57
+ # default file group
58
+ set :default_file_access_group_of_shared_path, 'www-data'
59
+ set :default_file_access_group_of_release_path, 'www-data'
60
+ # default file access mode
61
+ set :default_file_access_mode_of_shared_path, 'u+rwX,g+rX,g-w,o-rwx'
62
+ set :default_file_access_mode_of_release_path, 'u+rwX,g+rX,g-w,o-rwx'
63
+ # custom file access properties
64
+ set :custom_file_access, {}
65
+
66
+ # Set default compass sources
67
+ set :compass_sources, []
68
+ set :compass_compile_arguments, []
69
+
70
+ # Number of archives to keep around
71
+ set :keep_rollback_archives, 5
72
+
73
+ # List of bower.json files
74
+ set :bower_path, -> { fetch(:copy_source) }
75
+ set :bower_paths, -> { Array(fetch(:copy_source)) }
76
+
77
+ # List of filters for file_access:set_selected_custom_access
78
+ set :selected_custom_file_access, []
79
+
80
+ # Set assets configuration
81
+ set :asset_default_content, []
82
+ set :asset_exclude_file, ''
83
+ set :asset_folders, []
84
+
85
+ # Airbrush configuration
86
+ set :format_options, command_output: true, log_file: nil, truncate: false
87
+ end
88
+ end
@@ -0,0 +1,156 @@
1
+ module Dkdeploy
2
+ # Global static methods
3
+ #
4
+ module Constants
5
+ #####################################################
6
+ # General constants
7
+ #####################################################
8
+
9
+ # Copy source path
10
+ #
11
+ # @return [String]
12
+ def copy_source
13
+ fetch :copy_source, '.'
14
+ end
15
+
16
+ # Local Dump Path
17
+ #
18
+ # @return [String]
19
+ def local_dump_path
20
+ fetch :local_dump_path, 'temp'
21
+ end
22
+
23
+ # Copy exclude pattern
24
+ #
25
+ # @return [Array]
26
+ def copy_exclude
27
+ fetch :copy_exclude, []
28
+ end
29
+
30
+ # Application name
31
+ #
32
+ # @return [String]
33
+ def application
34
+ fetch(:application)
35
+ end
36
+
37
+ # Assets path
38
+ #
39
+ # @return [String]
40
+ def assets_path
41
+ File.join shared_path, 'assets'
42
+ end
43
+
44
+ # File path to remote database config file
45
+ #
46
+ # @return [String]
47
+ def remote_database_config_path
48
+ File.join shared_path, 'config', "db_settings.#{fetch(:stage)}.yaml"
49
+ end
50
+
51
+ # File path to local database config file
52
+ #
53
+ # @return [String]
54
+ def local_database_config_path
55
+ File.join 'temp', "db_settings.#{fetch(:stage)}.yaml"
56
+ end
57
+
58
+ # Default timestamp format for database dump files
59
+ #
60
+ # @return [String]
61
+ def datetime_format
62
+ '%Y-%m-%d_%H-%M'
63
+ end
64
+
65
+ # List of table names to be ignored by default when dumping from database
66
+ #
67
+ # @return [String]
68
+ def default_ignore_tables
69
+ %w(
70
+ cache_extensions cache_hash cache_imagesizes cache_md5params
71
+ cache_pages cache_pagesection cache_sys_dmail_stat cache_treelist cache_typo3temp_log
72
+ cachingframework_cache_hash cachingframework_cache_hash_tags cachingframework_cache_pages
73
+ cachingframework_cache_pages_tags cachingframework_cache_pagesection
74
+ cachingframework_cache_pagesection_tags sys_workspace_cache sys_workspace_cache_tags
75
+ tt_news_cache tt_news_cache_tags tx_extbase_cache_object tx_extbase_cache_object_tags
76
+ tx_extbase_cache_reflection tx_extbase_cache_reflection_tags tx_realurl_chashcache
77
+ tx_realurl_pathcache tx_realurl_urldecodecache tx_realurl_urlencodecache be_users be_sessions
78
+ sys_domain fe_users fe_sessions fe_session_data
79
+ cf_cache_hash cf_cache_hash_tags cf_cache_pages cf_cache_pages_tags cf_cache_pagesection
80
+ cf_cache_pagesection_tags cf_cache_rootline cf_cache_rootline_tags cf_extbase_datamapfactory_datamap
81
+ cf_extbase_datamapfactory_datamap_tags cf_extbase_object cf_extbase_object_tags
82
+ cf_extbase_reflection cf_extbase_reflection_tags cf_extbase_typo3dbbackend_queries
83
+ cf_extbase_typo3dbbackend_queries_tags cf_extbase_typo3dbbackend_tablecolumns
84
+ cf_extbase_typo3dbbackend_tablecolumns_tags
85
+ )
86
+ end
87
+
88
+ # List of table names to be ignored when dumping from database defined via Capistrano variable or environment variable
89
+ #
90
+ # @return [String]
91
+ def additional_ignore_tables
92
+ env_string_list = ENV.fetch('ADDITIONAL_IGNORE_TABLES', '').split ' '
93
+ cap_string_list = fetch(:additional_ignore_tables, '').split ' '
94
+ env_string_list | cap_string_list
95
+ end
96
+
97
+ # List of table names to be ignored when dumping from database
98
+ #
99
+ # @return [String]
100
+ def ignore_tables
101
+ default_ignore_tables | additional_ignore_tables
102
+ end
103
+
104
+ #####################################################
105
+ # Local temporary directory constants
106
+ #####################################################
107
+
108
+ # Archive filename as singleton
109
+ # Note: if the archive filename doesn't already exist it will be generated
110
+ #
111
+ # @return [String]
112
+ def archive_filename
113
+ @archive_filename ||= Dir::Tmpname.make_tmpname [application + '_', '.tar.gz'], nil
114
+ end
115
+
116
+ # Local temporary directory path as singleton
117
+ # Note: if the directory doesn't already exist it will be created
118
+ #
119
+ # @return [String]
120
+ def local_tmp_dir
121
+ @local_tmp_dir ||= Dir.mktmpdir
122
+ end
123
+
124
+ # Archive path in a local temporary directory
125
+ #
126
+ # @return [String]
127
+ def local_exclude_path
128
+ File.join local_tmp_dir, 'exclude.txt'
129
+ end
130
+
131
+ # Archive path in a local temporary directory
132
+ #
133
+ # @return [String]
134
+ def local_archive_path
135
+ File.join local_tmp_dir, archive_filename
136
+ end
137
+
138
+ #####################################################
139
+ # remote paths constants
140
+ #####################################################
141
+
142
+ # Remote temporary directory path
143
+ #
144
+ # @return [String]
145
+ def remote_tmp_dir
146
+ File.join fetch(:tmp_dir), application
147
+ end
148
+
149
+ # Archive path in a remote temporary directory
150
+ #
151
+ # @return [String]
152
+ def remote_archive_path
153
+ File.join remote_tmp_dir, archive_filename
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,121 @@
1
+ require 'tmpdir'
2
+ require 'capistrano/scm'
3
+ require 'capistrano/i18n'
4
+ require 'dkdeploy/i18n'
5
+ require 'dkdeploy/constants'
6
+
7
+ include Capistrano::DSL
8
+
9
+ module Dkdeploy
10
+ # Class for the capistrano copy
11
+ #
12
+ class Copy
13
+ include Dkdeploy::Constants
14
+
15
+ # Provide a wrapper for the SCM that loads a strategy for the user.
16
+ #
17
+ # @param [Rake] context The context in which the strategy should run
18
+ # @param [Module] strategy A module to include into the SCM instance. The
19
+ # module should provide the abstract methods of Capistrano::SCM
20
+ #
21
+ def initialize(context, strategy)
22
+ @context = context
23
+ singleton = class << self; self; end
24
+ singleton.send(:include, strategy)
25
+ end
26
+
27
+ # Default copy strategy
28
+ #
29
+ module DefaultStrategy
30
+ # Checks if the local source directory exists.
31
+ #
32
+ def check
33
+ # scope object for the processing in the block
34
+ me = self
35
+ run_locally do
36
+ unless Dir.exist? me.copy_source
37
+ fatal I18n.t('directory.not_exists', name: me.copy_source, scope: :dkdeploy)
38
+ exit 1
39
+ end
40
+ end
41
+ end
42
+
43
+ # Copies the source file structure to the server excluding the not wanted elements.
44
+ #
45
+ def release
46
+ build_source_archive
47
+ copy_archive_to_server
48
+ clean_up_temporary_sources
49
+ end
50
+
51
+ # Builds a tar archive in a temporary directory
52
+ # excluding files and folders matching the configured pattern.
53
+ #
54
+ def build_source_archive
55
+ # scope object for the processing in the block
56
+ me = self
57
+ run_locally do
58
+ info I18n.t('tasks.copy.archive.generate', scope: :dkdeploy)
59
+
60
+ # generate an exclude.txt file with the patterns to be excluded
61
+ File.open(me.local_exclude_path, 'w+') do |file|
62
+ me.copy_exclude.each do |pattern|
63
+ file.puts pattern
64
+ end
65
+ end
66
+
67
+ # build the tar archive excluding the patterns from exclude.txt
68
+ within me.copy_source do
69
+ execute :tar, '-X ' + me.local_exclude_path, '-cpzf', me.local_archive_path, '.'
70
+ end
71
+ end
72
+ end
73
+
74
+ # Copies the tar archive on the remote server
75
+ # extracting it to the configured directory.
76
+ #
77
+ def copy_archive_to_server # rubocop:disable Metrics/AbcSize
78
+ # scope object for the processing in the block
79
+ me = self
80
+ on release_roles :app do
81
+ info I18n.t('file.upload', file: 'archive', target: me.remote_tmp_dir, scope: :dkdeploy)
82
+ execute :mkdir, '-p', me.remote_tmp_dir
83
+
84
+ upload! me.local_archive_path, me.remote_tmp_dir
85
+
86
+ info I18n.t('directory.create', directory: release_path, scope: :dkdeploy)
87
+ execute :mkdir, '-p', release_path
88
+
89
+ within release_path do
90
+ info I18n.t('tasks.copy.archive.extract', target: release_path, scope: :dkdeploy)
91
+ execute :tar, '-xpzf', me.remote_archive_path
92
+ end
93
+ end
94
+ end
95
+
96
+ # Cleans up the local and remote temporary directories
97
+ #
98
+ def clean_up_temporary_sources
99
+ # scope object for the processing in the block
100
+ me = self
101
+
102
+ # remove the local temporary directory
103
+ run_locally do
104
+ info I18n.t('file.remove', path: me.local_tmp_dir, scope: :dkdeploy)
105
+ execute :rm, '-rf', me.local_tmp_dir
106
+ end
107
+
108
+ # removes the remote archive
109
+ on release_roles :app do
110
+ info I18n.t('file.remove', path: me.remote_archive_path, scope: :dkdeploy)
111
+ execute :rm, '-f', me.remote_archive_path
112
+ end
113
+ end
114
+
115
+ # Fetches the current revision message
116
+ def fetch_revision
117
+ I18n.t('log.revision_log_message', copy_source: fetch(:copy_source), time: Time.now, scope: :dkdeploy)
118
+ end
119
+ end
120
+ end
121
+ end