Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GitHub Action to build and deploy #693

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions .github/workflows/build_and_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Build and Deploy
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
jobs:
build_and_deploy:
if: github.repository_owner == 'ManageIQ'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "2.7"
bundler-cache: true
- name: Docker login
run: echo ${{ secrets.DOCKER_REGISTRY_PASSWORD }} | docker login docker.io --password-stdin --username ${{ secrets.DOCKER_REGISTRY_USERNAME }}
- name: Build
run: bundle exec rake production:release:build[${{ github.ref_name }}]
- name: Set up kubectl
uses: azure/setup-kubectl@v4
- name: Set up ibmcloud CLI
uses: IBM/actions-ibmcloud-cli@v1
with:
api_key: ${{ secrets.IBMCLOUD_API_KEY }}
region: us-east
group: manageiq
plugins: container-service
- name: Deploy
run: bundle exec rake production:release:deploy[${{ github.ref_name }}]
122 changes: 75 additions & 47 deletions lib/tasks/production.rake
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ module IbmCloud
!`which ibmcloud`.chomp.empty?
end

def self.plugin_available?(plugin)
`ibmcloud plugin list --output json | jq -r .[].Name`.lines(chomp: true).include?(plugin)
end

def self.ks_plugin_available?
plugin_available?("container-service")
end

def self.api_key
ENV["IBMCLOUD_BOT_API_KEY"]
end
Expand Down Expand Up @@ -90,6 +98,7 @@ namespace :production do

raise "kubectl command not installed" unless Kubernetes.available?
raise "ibmcloud command not installed" unless IbmCloud.available?
raise "ibmcloud container-service plugin not installed" unless IbmCloud.ks_plugin_available?
raise "Unable to login with ibmcloud command" unless IbmCloud.logged_in? || (IbmCloud.login && IbmCloud.logged_in?)
raise "Unable to configure the kubernetes cluster for ibmcloud command" unless IbmCloud.ks_cluster_config(cluster_name)
raise "Kubernetes context does not exist" unless Kubernetes.context?(context)
Expand Down Expand Up @@ -131,56 +140,75 @@ namespace :production do
container = args[:container] || "queue-worker"
exit 1 unless Kubernetes.tail_log(container)
end
end

desc "Release a new version to production"
task :release, [:version, :remote] => "production:set_context" do |_t, args|
version = args[:version]
if version.nil?
$stderr.puts "ERROR: must specify the version number to deploy"
exit 1
end
version = "v#{version}" unless version.start_with?("v")

remote = args[:remote] || "upstream"

puts "Ensuring version number..."
unless File.readlines("templates/bot.yaml").grep(/image: .+miq_bot:v/).all? { |l| l.include?("miq_bot:#{version}") }
$stderr.puts "ERROR: images in templates/bot.yaml have not been updated to the expected version"
exit 1
end

puts "Deploying version #{version}..."

puts
puts "Tagging repository..."
if `git tag --list #{version}`.chomp.empty?
exit 1 unless system("git tag #{version}")
elsif `git tag --points-at HEAD`.chomp != version
$stderr.puts "ERROR: Already tagged '#{version}', but you are not on that commit"
exit 1
else
puts "Already tagged '#{version}'"
def release_version(version)
if version.nil?
$stderr.puts "ERROR: must specify the version number to deploy"
exit 1
end
version = "v#{version}" unless version.start_with?("v")
version
end

desc "Release a new version to production"
task :release, [:version, :remote] do |_t, args|
version = release_version(args[:version])
remote = args[:remote] || "upstream"

puts "Ensuring version number..."
unless File.readlines("templates/bot.yaml").grep(/image: .+miq_bot:v/).all? { |l| l.include?("miq_bot:#{version}") }
$stderr.puts "ERROR: images in templates/bot.yaml have not been updated to the expected version"
exit 1
end

puts "Deploying version #{version}..."

puts
puts "Tagging repository..."
if `git tag --list #{version}`.chomp.empty?
exit 1 unless system("git tag #{version}")
elsif `git tag --points-at HEAD`.chomp != version
$stderr.puts "ERROR: Already tagged '#{version}', but you are not on that commit"
exit 1
else
puts "Already tagged '#{version}'"
end
exit 1 unless system("git push #{remote} #{version}")
end

namespace :release do
desc "Build the specified version and push to docker.io"
task :build, [:version] do |_t, args|
version = release_version(args[:version])
image = "docker.io/manageiq/miq_bot:#{version}"

puts "Building docker image..."
exit 1 unless system("docker build . --no-cache --build-arg REF=#{version} -t #{image}")
puts
puts "Pushing docker image..."
exit 1 unless system("docker login docker.io") && system("docker push #{image}")
puts
end

desc "Deploy the specified version to Kubernetes"
task :deploy, [:version] => "production:set_context" do |_t, args|
version = release_version(args[:version])
image = "docker.io/manageiq/miq_bot:#{version}"

puts "Updating queue-worker deployment..."
exit 1 unless Kubernetes.update_deployment_image("queue-worker", image)
puts "Updating ui deployment..."
exit 1 unless Kubernetes.update_deployment_image("ui", image)

puts
puts "Deploying version #{version}...Complete"
end
end
exit 1 unless system("git push #{remote} #{version}")

image = "docker.io/manageiq/miq_bot:#{version}"

puts
puts "Building docker image..."
exit 1 unless system("docker build . --no-cache --build-arg REF=#{version} -t #{image}")
puts
puts "Pushing docker image..."
exit 1 unless system("docker login") && system("docker push #{image}")
puts

puts "Updating queue-worker deployment..."
exit 1 unless Kubernetes.update_deployment_image("queue-worker", image)
puts "Updating ui deployment..."
exit 1 unless Kubernetes.update_deployment_image("ui", image)
end

puts
puts "Deploying version #{version}...Complete"
desc "Release a new version to production (alias of production:release)"
task :release, [:version, :remote] do |_t, args|
Rake::Task["production:release"].invoke(*args)
end

# rubocop:enable Style/StderrPuts