Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
96c2502
changing Target API
klevo Oct 10, 2025
763cc76
pass
klevo Oct 10, 2025
a89e936
refactor
klevo Oct 10, 2025
1f090d2
test "all defaults exist, override account_url" do
klevo Oct 10, 2025
a1b808f
test "all defaults exist, override project_name" do
klevo Oct 10, 2025
57c8595
drop ignored_params
klevo Oct 10, 2025
3d42cf3
test "missing_params" do
klevo Oct 10, 2025
3c60aeb
cleanup
klevo Oct 10, 2025
8386626
test "default_project_name and default_environ_name and no other defa…
klevo Oct 10, 2025
e298a8d
exapnd
klevo Oct 10, 2025
a26ee5a
test "environ_name override" do
klevo Oct 10, 2025
6fee1b1
save_defaults
klevo Oct 10, 2025
515e0d3
refactor
klevo Oct 10, 2025
b691d11
path as environ name overrides default
klevo Oct 11, 2025
affb1ec
target name prefix in path set default project name, overriden by pro…
klevo Oct 11, 2025
a94bd3e
service name as path in the service context
klevo Oct 11, 2025
5adfc06
environ name and service name as path in the service context
klevo Oct 11, 2025
eda49f2
target name, environ name and service name as path in the service con…
klevo Oct 11, 2025
e5009c7
rename
klevo Oct 11, 2025
7cb4cd4
rename
klevo Oct 11, 2025
fb91682
refactor
klevo Oct 11, 2025
ad73e37
save custom name
klevo Oct 11, 2025
0850056
target configure
klevo Oct 11, 2025
05ebc74
refactor
klevo Oct 11, 2025
a7a82bc
refactor
klevo Oct 11, 2025
37878be
configure project_name
klevo Oct 11, 2025
324c094
configure region
klevo Oct 11, 2025
618ebc5
missing only
klevo Oct 11, 2025
5c746b5
Name
klevo Oct 11, 2025
9171028
name validation during configure
klevo Oct 11, 2025
f0582c4
target validation
klevo Oct 11, 2025
498c8da
name validation
klevo Oct 11, 2025
4149591
target errors
klevo Oct 11, 2025
1f13895
tweak
klevo Oct 11, 2025
483a322
use new Target in deploy
klevo Oct 11, 2025
972e92d
path / suffix
klevo Oct 11, 2025
8a9d535
tweaks
klevo Oct 11, 2025
cbecdcf
typo
klevo Oct 11, 2025
0c5e7d6
exec implements new target
klevo Oct 11, 2025
5bf344e
exec working
klevo Oct 11, 2025
ae3869f
use with rsync
klevo Oct 11, 2025
ed11d0a
remove Defaults
klevo Oct 11, 2025
5001ea3
unattented option
klevo Oct 11, 2025
29338e8
typo
klevo Oct 11, 2025
c637a7f
save target if --unattended
klevo Oct 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
envirobly (1.10.0)
envirobly (1.11.0)
activesupport (~> 8.0)
aws-sdk-s3 (~> 1.182)
concurrent-ruby (~> 1.3)
Expand Down
106 changes: 72 additions & 34 deletions lib/envirobly/cli/main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
class Envirobly::Cli::Main < Envirobly::Base
include Envirobly::Colorize

class_option :unattended, type: :boolean, default: false

desc "version", "Show Envirobly CLI version"
method_option :pure, type: :boolean, default: false
def version
if options.pure
puts Envirobly::VERSION
say Envirobly::VERSION
else
puts "envirobly CLI v#{Envirobly::VERSION}"
say "envirobly CLI v#{Envirobly::VERSION}"
end
end

Expand All @@ -26,14 +28,28 @@ def signout
say "You can sign in again with `envirobly signin`"
end

desc "set_default_account", "Choose default account to deploy the current project to"
def set_default_account
Envirobly::Defaults::Account.new(shell:).require_value
end
desc "target [NAME]", "Configure deployment (default) target"
method_option :missing_only, type: :boolean, default: false
def target(name = nil)
Envirobly::AccessToken.new(shell:).require!

target = Envirobly::Target.new(default_project_name: File.basename(Dir.pwd), shell:)
target.name = name if name.present?

errors = target.errors :name

if errors.any?
errors.each do |message|
shell.say_error message
end

exit 1
end

desc "set_default_region", "Set default region for the current project when deploying for the first time"
def set_default_region
Envirobly::Defaults::Region.new(shell:).require_value
target.configure!(missing_only: options.missing_only)

shell.say "#{green_check} "
shell.say "Target configured.", :green
end

desc "validate", "Validates config (for given environ)"
Expand Down Expand Up @@ -69,18 +85,17 @@ def instance_types(region = nil)
table_data, borders: true
end

desc "deploy [ENVIRON_NAME]", <<~TXT
desc "deploy [[TARGET/[ENVIRON_NAME]]", <<~TXT
Deploy to environ identified by name.
Name can contain letters, numbers, dashes or underscores.
If environ name is left blank, current git branch name is used.
TXT
method_option :account_id, type: :numeric
method_option :account_url, type: :string
method_option :region, type: :string
method_option :project_id, type: :numeric
method_option :project_name, type: :string
method_option :commit, type: :string, default: "HEAD"
method_option :dry_run, type: :boolean, default: false
def deploy(environ_name = nil)
def deploy(path = nil)
commit = Envirobly::Git::Commit.new options.commit

unless commit.exists?
Expand All @@ -106,15 +121,8 @@ def deploy(environ_name = nil)

Envirobly::AccessToken.new(shell:).require!

deployment = Envirobly::Deployment.new(
account_id: options.account_id,
region: options.region,
project_id: options.project_id,
project_name: options.project_name,
environ_name: environ_name.presence,
commit:,
shell:
)
target = create_target(path:, commit:)
deployment = Envirobly::Deployment.new(target:, commit:, shell:)
deployment.perform(dry_run: options.dry_run)
end

Expand All @@ -130,35 +138,65 @@ def pull(region, bucket, ref, path)
Keep in mind, your container might not have a shell installed. In such cases you won't be able
to start an interactive session.
TXT
method_option :account_id, type: :numeric
method_option :project_id, type: :numeric
method_option :account_url, type: :string
method_option :project_name, type: :string
method_option :environ_name, type: :string
method_option :instance_slot, type: :numeric, default: 0
method_option :shell, type: :string
method_option :user, type: :string
def exec(service_name, *command)
Envirobly::ContainerShell.new(service_name, options, shell:).exec(command)
method_option :dry_run, type: :boolean, default: false
def exec(path, *command)
target = create_target(path:, context: :service)

Envirobly::ContainerShell.
new(target:, instance_slot: options.instance_slot, shell:, exec_shell: options.shell, exec_user: options.user).
exec(command, dry_run: options.dry_run)
end

desc "rsync [SERVICE_NAME:]SOURCE_PATH [SERVICE_NAME:]DESTINATION_PATH", <<~TXT
Synchronize files between you and your service's data volume.
TXT
method_option :account_id, type: :numeric
method_option :project_id, type: :numeric
method_option :account_url, type: :string
method_option :project_name, type: :string
method_option :environ_name, type: :string
method_option :args, type: :string, default: "-avzP"
method_option :dry_run, type: :boolean, default: false
def rsync(source, destination)
service_name = nil

[ source, destination ].each do |path|
if path =~ /\A([a-z0-9\-_]+):/i
service_name = $1
path = nil
[ source, destination ].each do |arg|
if arg =~ /\A([a-z0-9\-_\/]+):/i
path = $1
break
end
end

Envirobly::ContainerShell.new(service_name, options, shell:).rsync(source, destination)
target = create_target(path:, context: :service)

Envirobly::ContainerShell.
new(target:, shell:, rsync_args: options.args).
rsync(source, destination, path:, dry_run: options.dry_run)
end

private
def create_target(path:, commit: Envirobly::Git::Commit.new("HEAD"), context: nil)
target = Envirobly::Target.new(
path,
account_url: options.account_url,
project_name: options.project_name,
region: options.region,
default_project_name: File.basename(Dir.pwd),
default_environ_name: commit.current_branch,
shell:,
context:
)
target.render_and_exit_on_errors!

if options.unattended
target.save
else
target.configure!(missing_only: true)
end

target
end
end
5 changes: 3 additions & 2 deletions lib/envirobly/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module Envirobly
class Config
DIR = ".envirobly"
BASE = "deploy.yml"
OVERRIDES_PATTERN = /deploy\.([a-z0-9\-_]+)\.yml/i
ENVIRON_OVERRIDE_REGEXP = /deploy\.([a-z0-9\-_]+)\.yml/i
TARGETS_PATH = Pathname.new(DIR).join(".targets")

attr_reader :errors

Expand Down Expand Up @@ -43,7 +44,7 @@ def merge(environ_name = nil)

private
def config_file?(file)
file == BASE || file.match?(OVERRIDES_PATTERN)
file == BASE || file.match?(ENVIRON_OVERRIDE_REGEXP)
end

def parse(content, path)
Expand Down
71 changes: 26 additions & 45 deletions lib/envirobly/container_shell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,67 +17,48 @@ class ContainerShell
]
USER_AND_HOST = "envirobly-service@%s"

attr_reader :options, :service_name

def initialize(service_name, options, shell:)
@service_name = service_name
@options = options

commit = Git::Commit.new "HEAD"
default_account = Defaults::Account.new(shell:)
default_project = Defaults::Project.new(shell:)

target = Target.new(
default_account_id: default_account.value,
default_project_id: default_project.value,
default_project_name: Defaults::Project.dirname,
default_environ_name: commit.current_branch,
account_id: options.account_id,
project_id: options.project_id,
project_name: options.project_name,
environ_name: options.environ_name
)

if target.missing_params.include?(:account_id)
target.account_id = default_account.require_value
end

target.ignored_params.each do |param|
shell.say "--#{param.to_s.parameterize} ignored, due to other arguments overriding it"
end

def initialize(target:, shell:, instance_slot: 0, rsync_args: nil, exec_shell: nil, exec_user: nil)
@shell = shell
@rsync_args = rsync_args
@exec_shell = exec_shell
@exec_user = exec_user
@params = {
account_id: target.account_id,
project_id: target.project_id,
project_name: target.project_name,
environ_name: target.environ_name,
service_name:,
instance_slot: options.instance_slot || 0
service_name: target.service_name,
instance_slot: instance_slot
}

if options.project_name.blank? && options.account_id.blank? && options.project_id.blank?
@params[:project_id] = Defaults::Project.new.value
end
end

def exec(command = nil)
def exec(command = nil, dry_run: false)
do_dry_run if dry_run

with_private_key do
system join(env_vars, ssh, user_and_host, command)
end
end

def rsync(source, destination)
def rsync(source, destination, path:, dry_run: false)
do_dry_run if dry_run

with_private_key do
system join(
env_vars,
%(rsync #{options.args} -e "#{ssh}"),
source.sub("#{service_name}:", "#{user_and_host}:"),
destination.sub("#{service_name}:", "#{user_and_host}:")
%(rsync #{@rsync_args} -e "#{ssh}"),
source.sub("#{path}:", "#{user_and_host}:"),
destination.sub("#{path}:", "#{user_and_host}:")
)
end
end

private
def do_dry_run
@shell.say "Dry run", :green
@shell.say @params.to_yaml
exit
end

def join(*parts)
parts.flatten.compact.join(" ")
end
Expand Down Expand Up @@ -110,12 +91,12 @@ def env_vars
credentials.fetch("session_token")
)

if options.shell.present?
result = join "ENVIROBLY_SERVICE_INTERACTIVE_SHELL='#{options.shell}'", result
if @exec_shell.present?
result = join "ENVIROBLY_SERVICE_INTERACTIVE_SHELL='#{@exec_shell}'", result
end

if options.user.present?
result = join "ENVIROBLY_SERVICE_SHELL_USER='#{options.user}'", result
if @exec_user.present?
result = join "ENVIROBLY_SERVICE_SHELL_USER='#{@exec_user}'", result
end

result
Expand Down
43 changes: 0 additions & 43 deletions lib/envirobly/defaults/account.rb

This file was deleted.

7 changes: 0 additions & 7 deletions lib/envirobly/defaults/project.rb

This file was deleted.

Loading