capistrano-nextjs 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 06e138f48096ae45c17c5bb40ec3b3331128dc4c1d2b7b69bed5a52d8fdb7332
4
+ data.tar.gz: 3e03654dac9515fc45d142ddcd94557e4a162d508801c9cd5a78422c37b678b5
5
+ SHA512:
6
+ metadata.gz: f65195942ae440a5a079564e11218d646318ab7eeb8eb2d1388fdca972be96b12f0fe615e004b3301b062cde31c821048036d76e4a985ad3d414be51ca57da6d
7
+ data.tar.gz: 011cd3efcec06a345b1e9f570b0c625550a896549c0026528381944f7e5e1cee38a576cb2bb2d47782951720a68705241c2ac6d7131f09a545ced547a1c394f3
data/CHANGELOG.md ADDED
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2025-07-07
9
+
10
+ ### Added
11
+
12
+ - Initial release of capistrano-nextjs
13
+ - Next.js application deployment support with Capistrano
14
+ - Systemd service integration for Next.js applications
15
+ - Support for pnpm package manager
16
+ - Automatic build and deployment hooks with proper sequencing
17
+ - Graceful shutdown support
18
+ - Environment variable management
19
+ - Service management tasks (start, stop, restart, status)
20
+ - Installation and uninstallation of systemd services
21
+ - Database migration support before build process
22
+ - RuboCop integration for code quality and style enforcement
23
+
24
+ ### Features
25
+
26
+ - Automatic detection of pnpm executable
27
+ - NODE_ENV environment variable management
28
+ - Customizable service templates
29
+ - User and system service support
30
+ - Logging configuration
31
+ - Background process management
32
+ - Optimized deployment flow: migrate → build → deploy
33
+ - Code linting and formatting with RuboCop
34
+
35
+ ### Changed
36
+
37
+ - Reordered deployment hooks to run migrations before build process
38
+ - Improved deployment sequence for better reliability
39
+ - Added RuboCop configuration and fixed all linting issues
40
+ - Moved development dependencies from gemspec to Gemfile
41
+ - Added MFA requirement for gem publishing
data/LICENSE.txt ADDED
@@ -0,0 +1,68 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+ This version of the GNU Lesser General Public License incorporates
9
+ the terms and conditions of version 3 of the GNU General Public
10
+ License, supplemented by the additional permissions listed below.
11
+
12
+ 0. Additional Definitions.
13
+
14
+ As used herein, "this License" refers to version 3 of the GNU Lesser
15
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
16
+ General Public License.
17
+
18
+ "The Library" refers to a covered work governed by this License,
19
+ other than an Application or a Combined Work as defined below.
20
+
21
+ An "Application" is any work that makes use of an interface provided
22
+ by the Library, but which is not otherwise based on the Library.
23
+ Defining a subclass of a class defined by the Library is deemed a mode
24
+ of using an interface provided by the Library.
25
+
26
+ A "Combined Work" is a work produced by combining or linking an
27
+ Application with the Library. The particular version of the Library
28
+ with which the Combined Work was made is also called the "Linked
29
+ Version".
30
+
31
+ The "Minimal Corresponding Source" for a Combined Work means the
32
+ Corresponding Source for the Combined Work, excluding any source code
33
+ for portions of the Combined Work that, considered in isolation, are
34
+ based on the Application, and not on the Linked Version.
35
+
36
+ The "Corresponding Application Code" for a Combined Work means the
37
+ object code and/or source code for the Application, including any data
38
+ and utility programs needed for reproducing the Combined Work from the
39
+ Application, but excluding the System Libraries of the Combined Work.
40
+
41
+ 1. Exception to Section 3 of the GNU GPL.
42
+
43
+ You may convey a covered work under sections 3 and 4 of this License
44
+ without being bound by section 3 of the GNU GPL.
45
+
46
+ 2. Conveying this Library.
47
+
48
+ You may convey a copy of the Library under this License. However, if you
49
+ modify the Library, you may not distribute your modifications without
50
+ accompanying the distribution with complete Corresponding Source code.
51
+
52
+ Permission is hereby granted, free of charge, to any person obtaining a copy
53
+ of this software and associated documentation files (the "Software"), to deal
54
+ in the Software without restriction, including without limitation the rights
55
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
56
+ copies of the Software, and to permit persons to whom the Software is
57
+ furnished to do so, subject to the following conditions:
58
+
59
+ The above copyright notice and this permission notice shall be included in all
60
+ copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
68
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # Capistrano::Nextjs
2
+
3
+ Next.js integration for Capistrano with systemd support.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'capistrano-nextjs'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ Add the following to your `Capfile`:
22
+
23
+ ```ruby
24
+ require 'capistrano/pnpm'
25
+ require 'capistrano/nextjs'
26
+ install_plugin Capistrano::NextjsPlugin
27
+ install_plugin Capistrano::NextjsSystemd
28
+ ```
29
+
30
+ Add the following to your `config/deploy.rb`:
31
+
32
+ ```ruby
33
+ # Next.js configuration
34
+ set :nextjs_roles, :app
35
+ set :nextjs_env, fetch(:stage)
36
+ ```
37
+
38
+ ## Available Tasks
39
+
40
+ - `cap nextjs:start` - Start Next.js application
41
+ - `cap nextjs:stop` - Stop Next.js application
42
+ - `cap nextjs:restart` - Restart Next.js application
43
+ - `cap nextjs:status` - Check Next.js application status
44
+ - `cap nextjs:install` - Install systemd service
45
+ - `cap nextjs:uninstall` - Uninstall systemd service
46
+ - `cap nextjs:build` - Build Next.js application
47
+ - `cap nextjs:check` - Check Next.js application (lint)
48
+
49
+ ## Configuration
50
+
51
+ The gem automatically integrates with your deployment process:
52
+
53
+ - Stops the service before deployment
54
+ - Starts the service after successful deployment
55
+ - Restarts the service if deployment fails
56
+
57
+ ## Requirements
58
+
59
+ - Node.js
60
+ - pnpm
61
+ - systemd (for service management)
62
+
63
+ ## License
64
+
65
+ The gem is available as open source under the terms of the [LGPL-3.0 License](https://opensource.org/licenses/LGPL-3.0).
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module Nextjs
5
+ class Systemd < Capistrano::Plugin
6
+ include NextjsCommon
7
+ def define_tasks
8
+ eval_rakefile File.expand_path('../tasks/systemd.rake', __dir__)
9
+ end
10
+
11
+ def set_defaults
12
+ set_if_empty :systemctl_bin, '/bin/systemctl'
13
+ set_if_empty :service_unit_user, :user
14
+ set_if_empty :systemctl_user, fetch(:service_unit_user, :user) == :user
15
+
16
+ set_if_empty :nextjs_service_unit_name, -> { "#{fetch(:application)}_nextjs_#{fetch(:stage)}" }
17
+ set_if_empty :nextjs_lingering_user, -> { fetch(:lingering_user, fetch(:user)) }
18
+
19
+ ## Next.js environment variables
20
+ set_if_empty :nextjs_service_unit_env_files, -> { fetch(:service_unit_env_files, []) }
21
+ set_if_empty :nextjs_service_unit_env_vars, lambda {
22
+ base_vars = fetch(:service_unit_env_vars, [])
23
+ base_vars + ["NODE_ENV=#{fetch(:nextjs_env, 'production')}"]
24
+ }
25
+
26
+ set_if_empty :nextjs_service_templates_path, fetch(:service_templates_path, 'config/deploy/templates')
27
+ end
28
+
29
+ def systemd_command(*args)
30
+ command = [fetch(:systemctl_bin)]
31
+
32
+ command << '--user' unless fetch(:service_unit_user) == :system
33
+
34
+ command + args
35
+ end
36
+
37
+ def sudo_if_needed(*command)
38
+ if fetch(:service_unit_user) == :system
39
+ backend.sudo command.map(&:to_s).join(' ')
40
+ else
41
+ backend.execute(*command)
42
+ end
43
+ end
44
+
45
+ def execute_systemd(*)
46
+ sudo_if_needed(*systemd_command(*))
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module Nextjs
5
+ VERSION = '1.0.0'
6
+ end
7
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'capistrano/pnpm'
5
+ rescue LoadError, RuntimeError
6
+ # Ignore missing pnpm dependency in test environment
7
+ end
8
+
9
+ require 'capistrano/plugin'
10
+
11
+ module Capistrano
12
+ module NextjsCommon
13
+ def compiled_template(config_file = 'nextjs.yml')
14
+ @config_file = config_file
15
+ local_template_directory = fetch(:nextjs_service_templates_path)
16
+ search_paths = [
17
+ File.join(local_template_directory, 'nextjs.service.capistrano.erb'),
18
+ File.expand_path(
19
+ File.join(*%w[.. templates nextjs.service.capistrano.erb]),
20
+ __FILE__
21
+ )
22
+ ]
23
+ template_path = search_paths.detect { |path| File.file?(path) }
24
+ template = File.read(template_path)
25
+ ERB.new(template, trim_mode: '-').result(binding)
26
+ end
27
+
28
+ def pnpm_path
29
+ # Try to find pnpm in various locations
30
+
31
+ backend.capture(:which, :pnpm).strip
32
+ rescue StandardError
33
+ # Try nvm path
34
+ begin
35
+ backend.capture(:bash, '-c', 'source ~/.nvm/nvm.sh && which pnpm').strip
36
+ rescue StandardError
37
+ # Fallback to common paths
38
+ [
39
+ '/usr/local/bin/pnpm',
40
+ '/usr/bin/pnpm',
41
+ 'pnpm'
42
+ ].each do |path|
43
+ return path if backend.test(:test, '-f', path) || path == 'pnpm'
44
+ rescue StandardError
45
+ next
46
+ end
47
+ 'pnpm' # Ultimate fallback
48
+ end
49
+ end
50
+
51
+ def nextjs_config
52
+ '' # Next.js doesn't use config files like Sidekiq
53
+ end
54
+
55
+ def switch_user(role, &)
56
+ su_user = nextjs_user(role)
57
+ if su_user == role.user
58
+ yield
59
+ else
60
+ as(su_user, &)
61
+ end
62
+ end
63
+
64
+ def nextjs_user(role = nil)
65
+ if role.nil?
66
+ fetch(:nextjs_user)
67
+ else
68
+ properties = role.properties
69
+ properties.fetch(:nextjs_user) || # local property for nextjs only
70
+ fetch(:nextjs_user) ||
71
+ properties.fetch(:run_as) || # global property across multiple capistrano gems
72
+ role.user
73
+ end
74
+ end
75
+ end
76
+
77
+ module Nextjs
78
+ class Plugin < Capistrano::Plugin
79
+ def define_tasks
80
+ eval_rakefile File.expand_path('tasks/nextjs.rake', __dir__)
81
+ end
82
+
83
+ def set_defaults
84
+ set_if_empty :nextjs_default_hooks, true
85
+
86
+ set_if_empty :nextjs_env, -> { fetch(:node_env, fetch(:stage)) }
87
+ set_if_empty :nextjs_roles, fetch(:nextjs_role, :app)
88
+ set_if_empty :nextjs_configs, %w[nextjs] # basic nextjs config
89
+
90
+ set_if_empty :nextjs_log, -> { File.join(shared_path, 'log', 'nextjs.log') }
91
+ set_if_empty :nextjs_error_log, -> { File.join(shared_path, 'log', 'nextjs.log') }
92
+
93
+ set_if_empty :nextjs_config_files, ['nextjs.yml']
94
+
95
+ # pnpm integration
96
+ append :pnpm_map_bins, 'next'
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ require_relative 'nextjs/systemd'
103
+
104
+ # Create top-level aliases for easier plugin installation
105
+ module Capistrano
106
+ NextjsPlugin = Nextjs::Plugin
107
+ NextjsSystemd = Nextjs::Systemd
108
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :deploy do
4
+ before :starting, :check_nextjs_hooks do
5
+ invoke 'nextjs:add_default_hooks' if fetch(:nextjs_default_hooks)
6
+ end
7
+ end
8
+
9
+ namespace :nextjs do
10
+ task :add_default_hooks do
11
+ after 'pnpm:install', 'nextjs:build'
12
+ # after 'deploy:starting', 'nextjs:quiet' if Rake::Task.task_defined?('nextjs:quiet')
13
+ after 'deploy:updated', 'nextjs:stop'
14
+ after 'deploy:published', 'nextjs:start'
15
+ after 'deploy:failed', 'nextjs:restart'
16
+ end
17
+
18
+ desc 'Build Next.js application'
19
+ task :build do
20
+ on roles fetch(:nextjs_roles) do
21
+ within release_path do
22
+ execute :pnpm, 'build'
23
+ end
24
+ end
25
+ end
26
+
27
+ desc 'Check Next.js application'
28
+ task :check do
29
+ on roles fetch(:nextjs_roles) do
30
+ within current_path do
31
+ execute :pnpm, 'lint'
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ git_plugin = self
4
+
5
+ namespace :nextjs do
6
+ standard_actions = {
7
+ start: 'Start Next.js',
8
+ stop: 'Stop Next.js (graceful shutdown)',
9
+ status: 'Get Next.js Status',
10
+ restart: 'Restart Next.js'
11
+
12
+ }
13
+ standard_actions.each do |command, description|
14
+ desc description
15
+ task command do
16
+ on roles fetch(:nextjs_roles) do |role|
17
+ git_plugin.switch_user(role) do
18
+ git_plugin.config_files(role).each do |config_file|
19
+ git_plugin.execute_systemd(command, git_plugin.nextjs_service_file_name(config_file))
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ desc 'Stop Next.js gracefully'
27
+ task :quiet do
28
+ on roles fetch(:nextjs_roles) do |role|
29
+ git_plugin.switch_user(role) do
30
+ git_plugin.stop_nextjs_gracefully(role)
31
+ end
32
+ end
33
+ end
34
+
35
+ desc 'Install Next.js systemd service'
36
+ task :install do
37
+ on roles fetch(:nextjs_roles) do |role|
38
+ git_plugin.switch_user(role) do
39
+ git_plugin.create_systemd_template(role)
40
+ end
41
+ end
42
+ invoke 'nextjs:enable'
43
+ end
44
+
45
+ desc 'Uninstall Next.js systemd service'
46
+ task :uninstall do
47
+ invoke 'nextjs:disable'
48
+ on roles fetch(:nextjs_roles) do |role|
49
+ git_plugin.switch_user(role) do
50
+ git_plugin.rm_systemd_service(role)
51
+ end
52
+ end
53
+ end
54
+
55
+ desc 'Enable Next.js systemd service'
56
+ task :enable do
57
+ on roles(fetch(:nextjs_roles)) do |role|
58
+ git_plugin.config_files(role).each do |config_file|
59
+ git_plugin.execute_systemd('enable', git_plugin.nextjs_service_file_name(config_file))
60
+ end
61
+
62
+ if fetch(:systemctl_user) && fetch(:nextjs_lingering_user)
63
+ execute :loginctl, 'enable-linger', fetch(:nextjs_lingering_user)
64
+ end
65
+ end
66
+ end
67
+
68
+ desc 'Disable Next.js systemd service'
69
+ task :disable do
70
+ on roles(fetch(:nextjs_roles)) do |role|
71
+ git_plugin.config_files(role).each do |config_file|
72
+ git_plugin.execute_systemd('disable', git_plugin.nextjs_service_file_name(config_file))
73
+ end
74
+ end
75
+ end
76
+
77
+ def fetch_systemd_unit_path
78
+ if fetch(:nextjs_systemctl_user) == :system
79
+ '/etc/systemd/system/'
80
+ else
81
+ home_dir = backend.capture :pwd
82
+ File.join(home_dir, '.config', 'systemd', 'user')
83
+ end
84
+ end
85
+
86
+ def create_systemd_template(role)
87
+ systemd_path = fetch(:service_unit_path, fetch_systemd_unit_path)
88
+ backend.execute :mkdir, '-p', systemd_path if fetch(:systemctl_user)
89
+
90
+ config_files(role).each do |config_file|
91
+ ctemplate = compiled_template(config_file)
92
+ temp_file_name = File.join('/tmp', "nextjs.#{config_file}.service")
93
+ systemd_file_name = File.join(systemd_path, nextjs_service_file_name(config_file))
94
+ backend.upload!(StringIO.new(ctemplate), temp_file_name)
95
+ if fetch(:systemctl_user)
96
+ warn "Moving #{temp_file_name} to #{systemd_file_name}"
97
+ backend.execute :mv, temp_file_name, systemd_file_name
98
+ else
99
+ warn "Installing #{systemd_file_name} as root"
100
+ backend.execute :sudo, :mv, temp_file_name, systemd_file_name
101
+ end
102
+ end
103
+ end
104
+
105
+ def rm_systemd_service(role)
106
+ systemd_path = fetch(:service_unit_path, fetch_systemd_unit_path)
107
+
108
+ config_files(role).each do |config_file|
109
+ systemd_file_name = File.join(systemd_path, nextjs_service_file_name(config_file))
110
+ if fetch(:systemctl_user)
111
+ warn "Deleting #{systemd_file_name}"
112
+ backend.execute :rm, '-f', systemd_file_name
113
+ else
114
+ warn "Deleting #{systemd_file_name} as root"
115
+ backend.execute :sudo, :rm, '-f', systemd_file_name
116
+ end
117
+ end
118
+ end
119
+
120
+ def stop_nextjs_gracefully(role)
121
+ config_files(role).each do |config_file|
122
+ nextjs_service = nextjs_service_unit_name(config_file)
123
+ warn "Stopping #{nextjs_service} gracefully"
124
+ execute_systemd('stop', nextjs_service)
125
+ end
126
+ end
127
+
128
+ def nextjs_service_unit_name(config_file)
129
+ if config_file == 'nextjs.yml'
130
+ fetch(:nextjs_service_unit_name)
131
+ else
132
+ "#{fetch(:nextjs_service_unit_name)}.#{config_file.split('.')[0..-2].join('.')}"
133
+ end
134
+ end
135
+
136
+ def nextjs_service_file_name(config_file)
137
+ ## Remove the extension
138
+ config_file = config_file.split('.').join('.')
139
+
140
+ "#{nextjs_service_unit_name(config_file)}.service"
141
+ end
142
+
143
+ def config_files(role)
144
+ role.properties.fetch(:nextjs_config_files) ||
145
+ fetch(:nextjs_config_files)
146
+ end
147
+ end
@@ -0,0 +1,23 @@
1
+
2
+ [Unit]
3
+ Description=Next.js for <%= "#{fetch(:application)} (#{fetch(:stage)})" %>
4
+ # start us only once the network and logging subsystems are available
5
+ After=syslog.target network.target
6
+
7
+ [Service]
8
+ Type=simple
9
+ <%="User=#{nextjs_user}" if fetch(:nextjs_systemctl_user) == :system %>
10
+ WorkingDirectory=<%= current_path %>
11
+ ExecStart=/bin/bash -l -c 'pnpm start'
12
+ ExecReload=/bin/kill -TSTP $MAINPID
13
+ ExecStop=/bin/kill -SIGTERM $MAINPID
14
+
15
+ Restart=always
16
+
17
+
18
+ StandardOutput=file:<%= shared_path %>/log/nextjs.log
19
+ StandardError=file:<%= shared_path %>/log/nextjs-error.log
20
+
21
+ SyslogIdentifier=<%= nextjs_service_unit_name(@config_file) %>
22
+ [Install]
23
+ WantedBy=default.target
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-nextjs
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Florian Crusius
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.9'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.9.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '3.9'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.9.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: capistrano-pnpm
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: dotenv
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.7'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.7'
61
+ description: Next.js integration for Capistrano with systemd support, enabling automated
62
+ deployment and service management for Next.js applications using pnpm
63
+ email:
64
+ - florian@zauberware.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - CHANGELOG.md
70
+ - LICENSE.txt
71
+ - README.md
72
+ - lib/capistrano/nextjs.rb
73
+ - lib/capistrano/nextjs/systemd.rb
74
+ - lib/capistrano/nextjs/version.rb
75
+ - lib/capistrano/tasks/nextjs.rake
76
+ - lib/capistrano/tasks/systemd.rake
77
+ - lib/capistrano/templates/nextjs.service.capistrano.erb
78
+ homepage: https://github.com/zauberware/capistrano-nextjs
79
+ licenses:
80
+ - LGPL-3.0
81
+ metadata:
82
+ rubygems_mfa_required: 'true'
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 3.2.7
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.4.19
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Next.js integration for Capistrano
102
+ test_files: []