Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
zipofar committed Oct 9, 2023
2 parents 8995b43 + 0c1ba25 commit d700a46
Show file tree
Hide file tree
Showing 18 changed files with 541 additions and 44 deletions.
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,30 @@ git pull --rebase qa
git merge --no-ff BRANCH_NAME
git push origin qa
```

## Release

1. Merge the branch to develop.
2. Checkout to the develop branch.
3. Run one of the following command depending on the new release version:

```
make release_patch
make release_minor
make release_major
```

These commands will merge and push the develop branch into main and create a new tag.
Once the tag is pushed, the GHA workflows will release a gem and create new binaries for Linux and MacOs that can be found in the github release artefacts.

## Homebrew tap

Uffizzi supports a [Homebrew tap package] (https://github.com/UffizziCloud/homebrew-tap) and it needs to be updated after each release.
1. Go to the [latest release] (https://github.com/UffizziCloud/uffizzi_cli/releases/latest).
2. Copy the link to the source code archive (tar.gz).
3. Run `brew create [link copied in the previous step]` - this will create a new Formula file with the sha and the source code url.
4. Copy over the contents of the existing [Formula](https://github.com/UffizziCloud/homebrew-tap/blob/main/Formula/uffizzi.rb) from the master, replacing the sha and the url for the ones from the newly created Formula.
5. Update the `resource "uffizzi-cli"` to the latest gem and add new dependencies if needed.
6. Run `HOMEBREW_NO_INSTALL_FROM_API=1 brew install --build-from-source --verbose --debug uffizzi` and manually test the new uffizzi version (make sure that all other homebrew uffizzi versions are uninstalled).
7. Run `brew audit --strict --online` to check if the Formula adheres to the Homebrew style.
8. If tests and audit pass, create a PR into master in the UffizziCloud/homebrew-tap [repository] (https://github.com/UffizziCloud/homebrew-tap) with the new Formula.
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:
uffizzi-cli (2.1.0)
uffizzi-cli (2.1.1)
activesupport
awesome_print
faker
Expand Down
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ NEXT_PATCH=$(shell docker-compose run --rm gem bash -c "bundle exec bump show-ne
NEXT_MINOR=$(shell docker-compose run --rm gem bash -c "bundle exec bump show-next minor")
NEXT_MAJOR=$(shell docker-compose run --rm gem bash -c "bundle exec bump show-next major")
TAG_FULL_VERSION=v${VERSION}
CURRENT_LOCAL_GEM_NAME := $(shell ls | sort -r | grep 'uffizzi-cli-.*\.gem' | head -1)

release_gem:
mkdir -p ${HOME}/.gem
Expand Down Expand Up @@ -53,4 +54,17 @@ lint:
run_single_test:
docker-compose run --rm gem bash -c 'bundle exec rake test TEST=$(TEST_PATH) TESTOPTS="--name=${TEST_NAME}"'

gem_build:
gem build uffizzi.gemspec

gem_install:
gem install $(CURRENT_LOCAL_GEM_NAME)

gem_build_install:
make gem_build
make gem_install

gem_uninstall:
gem uninstall uffizzi-cli

.PHONY: test
4 changes: 4 additions & 0 deletions lib/uffizzi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,9 @@ def prompt
def root
@root ||= Pathname.new(File.expand_path('..', __dir__))
end

def process
@process ||= Process
end
end
end
4 changes: 1 addition & 3 deletions lib/uffizzi/cli/cluster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
require 'uffizzi/services/kubeconfig_service'
require 'uffizzi/services/cluster/disconnect_service'

MANUAL = 'manual'

module Uffizzi
class Cli::Cluster < Thor
class Error < StandardError; end
Expand Down Expand Up @@ -115,7 +113,7 @@ def handle_create_command(project_slug, command_args)
end

cluster_name = command_args[:name] || options[:name] || ClusterService.generate_name
creation_source = options[:"creation-source"] || MANUAL
creation_source = options[:"creation-source"] || ClusterService::MANUAL_CREATION_SOURCE

unless ClusterService.valid_name?(cluster_name)
Uffizzi.ui.say_error_and_exit("Cluster name: #{cluster_name} is not valid.")
Expand Down
59 changes: 40 additions & 19 deletions lib/uffizzi/cli/dev.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,51 @@

require 'uffizzi/services/command_service'
require 'uffizzi/services/cluster_service'
require 'uffizzi/services/dev_service'
require 'uffizzi/services/kubeconfig_service'

module Uffizzi
class Cli::Dev < Thor
include ApiClient

desc 'start [CONFIG]', 'Start dev environment'
method_option :quiet, type: :boolean, aliases: :q
method_option :'default-repo', type: :string
method_option :kubeconfig, type: :string
def start(config_path = 'skaffold.yaml')
check_skaffold_existence
DevService.check_skaffold_existence
DevService.check_running_daemon if options[:quiet]
DevService.check_skaffold_config_existence(config_path)
check_login
cluster_id, cluster_name = start_create_cluster
kubeconfig = wait_cluster_creation(cluster_name)
launch_scaffold(config_path)

if options[:quiet]
launch_demonise_skaffold(config_path)
else
DevService.start_basic_skaffold(config_path, options)
end
ensure
if defined?(cluster_name).present? && defined?(cluster_id).present?
kubeconfig = defined?(kubeconfig).present? ? kubeconfig : nil
handle_delete_cluster(cluster_id, cluster_name, kubeconfig)
end
end

desc 'stop', 'Stop dev environment'
def stop
return Uffizzi.ui.say('Uffizzi dev is not running') unless File.exist?(DevService.pid_path)

pid = File.read(DevService.pid_path).to_i
File.delete(DevService.pid_path)

Uffizzi.process.kill('QUIT', pid)
Uffizzi.ui.say('Uffizzi dev was stopped')
rescue Errno::ESRCH
Uffizzi.ui.say('Uffizzi dev is not running')
File.delete(DevService.pid_path)
end

private

def check_login
Expand All @@ -31,7 +56,7 @@ def check_login

def start_create_cluster
cluster_name = ClusterService.generate_name
creation_source = MANUAL
creation_source = ClusterService::MANUAL_CREATION_SOURCE
params = cluster_creation_params(cluster_name, creation_source)
Uffizzi.ui.say('Start creating a cluster')
response = create_cluster(ConfigFile.read_option(:server), project_slug, params)
Expand All @@ -56,7 +81,7 @@ def wait_cluster_creation(cluster_name)
end

def handle_succeed_cluster_creation(cluster_data)
kubeconfig_path = KubeconfigService.default_path
kubeconfig_path = options[:kubeconfig] || KubeconfigService.default_path
parsed_kubeconfig = parse_kubeconfig(cluster_data[:kubeconfig])

Uffizzi.ui.say("Cluster with name: #{cluster_data[:name]} was created.")
Expand Down Expand Up @@ -99,6 +124,8 @@ def cluster_creation_params(name, creation_source)
end

def handle_delete_cluster(cluster_id, cluster_name, kubeconfig)
return if cluster_id.nil? || cluster_name.nil?

exclude_kubeconfig(cluster_id, kubeconfig) if kubeconfig.present?

params = {
Expand Down Expand Up @@ -149,25 +176,19 @@ def parse_kubeconfig(kubeconfig)
Psych.safe_load(Base64.decode64(kubeconfig))
end

def launch_scaffold(config_path)
Uffizzi.ui.say('Start skaffold')
cmd = "skaffold dev --filename='#{config_path}'"
def launch_demonise_skaffold(config_path)
Uffizzi.process.daemon(true)

Uffizzi.ui.popen2e(cmd) do |_stdin, stdout_and_stderr, wait_thr|
stdout_and_stderr.each { |l| puts l }
wait_thr.value
at_exit do
File.delete(DevService.pid_path) if File.exist?(DevService.pid_path)
end
end

def check_skaffold_existence
cmd = 'skaffold version'
stdout_str, stderr_str = Uffizzi.ui.capture3(cmd)

return if stdout_str.present? && stderr_str.blank?

Uffizzi.ui.say_error_and_exit(stderr_str)
File.delete(DevService.logs_path) if File.exist?(DevService.logs_path)
File.write(DevService.pid_path, Uffizzi.process.pid)
DevService.start_check_pid_file_existence
DevService.start_demonised_skaffold(config_path, options)
rescue StandardError => e
Uffizzi.ui.say_error_and_exit(e.message)
File.open(DevService.logs_path, 'a') { |f| f.puts(e.message) }
end

def project_slug
Expand Down
1 change: 1 addition & 0 deletions lib/uffizzi/config_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

module Uffizzi
class ConfigFile
CONFIG_DIR = "#{Dir.home}/.config/uffizzi"
CONFIG_PATH = "#{Dir.home}/.config/uffizzi/config_default.json"

class << self
Expand Down
1 change: 1 addition & 0 deletions lib/uffizzi/services/cluster_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class ClusterService
CLUSTER_STATE_FAILED_DEPLOY_NAMESPACE = 'failed_deploy_namespace'
CLUSTER_STATE_FAILED = 'failed'
CLUSTER_NAME_MAX_LENGTH = 15
MANUAL_CREATION_SOURCE = 'manual'

class << self
include ApiClient
Expand Down
108 changes: 108 additions & 0 deletions lib/uffizzi/services/dev_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# frozen_string_literal: true

require 'uffizzi/clients/api/api_client'

class DevService
class << self
include ApiClient

DEFAULT_REGISTRY_REPO = 'registry.uffizzi.com'

def check_running_daemon
return unless File.exist?(pid_path)

pid = File.read(pid_path)
File.delete(pid_path) if pid.blank?
Uffizzi.process.kill(0, pid.to_i)

Uffizzi.ui.say_error_and_exit("You have already started uffizzi dev as daemon. To stop the process do 'uffizzi dev stop'")
rescue Errno::ESRCH
File.delete(pid_path)
end

def start_check_pid_file_existence
Thread.new do
loop do
Uffizzi.process.kill('QUIT', Uffizzi.process.pid) unless File.exist?(pid_path)
sleep(1)
end
end
end

def start_basic_skaffold(config_path, options)
Uffizzi.ui.say('Start skaffold')
cmd = build_skaffold_dev_command(config_path, options)

Uffizzi.ui.popen2e(cmd) do |_stdin, stdout_and_stderr, wait_thr|
stdout_and_stderr.each { |l| Uffizzi.ui.say(l) }
wait_thr.value
end
end

def start_demonised_skaffold(config_path, options)
File.write(logs_path, "Start skaffold\n")
cmd = build_skaffold_dev_command(config_path, options)

Uffizzi.ui.popen2e(cmd) do |_stdin, stdout_and_stderr, wait_thr|
File.open(logs_path, 'a') do |f|
stdout_and_stderr.each do |line|
f.puts(line)
f.flush
end
end

wait_thr.value
end
end

def check_skaffold_existence
cmd = 'skaffold version'
stdout_str, stderr_str = Uffizzi.ui.capture3(cmd)

return if stdout_str.present? && stderr_str.blank?

Uffizzi.ui.say_error_and_exit(stderr_str)
rescue StandardError => e
Uffizzi.ui.say_error_and_exit(e.message)
end

def check_skaffold_config_existence(config_path)
msg = 'A valid dev environment configuration is required. Please provide a valid config,'\
"\r\n"\
'or run `skaffold init` to generate a skaffold.yaml configuration.'\
"\r\n"\
'See the `uffizzi dev start --help` page for supported configs and usage details.'

Uffizzi.ui.say_error_and_exit(msg) unless File.exist?(config_path)
end

def pid_path
File.join(Uffizzi::ConfigFile::CONFIG_DIR, 'uffizzi_dev.pid')
end

def logs_path
File.join(Uffizzi::ConfigFile::CONFIG_DIR, 'uffizzi_dev.log')
end

def build_skaffold_dev_command(config_path, options)
cmd = [
'skaffold dev',
"--filename='#{config_path}'",
"--default-repo='#{default_registry_repo(options[:'default-repo'])}'",
"--kubeconfig='#{default_kubeconfig_path(options[:kubeconfig])}'",
]

cmd.join(' ')
end

def default_registry_repo(repo)
repo || DEFAULT_REGISTRY_REPO
end

def default_kubeconfig_path(kubeconfig_path)
path = kubeconfig_path || KubeconfigService.default_path

File.expand_path(path)
end
end
end
4 changes: 3 additions & 1 deletion lib/uffizzi/services/kubeconfig_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ def save_to_filepath(filepath, kubeconfig = nil)
end

def default_path
kubeconfig_env_path || Uffizzi.configuration.default_kubeconfig_path
path = kubeconfig_env_path || Uffizzi.configuration.default_kubeconfig_path

File.expand_path(path)
end

def read_kubeconfig(filepath)
Expand Down
2 changes: 1 addition & 1 deletion lib/uffizzi/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Uffizzi
VERSION = '2.1.0'
VERSION = '2.1.1'
end
Loading

0 comments on commit d700a46

Please sign in to comment.