lib/chef/knife/github_deploy.rb in knife-github-0.0.6 vs lib/chef/knife/github_deploy.rb in knife-github-0.0.7

- old
+ new

@@ -1,69 +1,59 @@ -# -# Author:: Sander Botman (<sbotman@schubergphilis.com>) -# Copyright:: Copyright (c) 2013 Sander Botman. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ---------------------------------------------------------------------------- # -# Abstract -# ---------------------------------------------------------------------------- # -# This code is specific to our company workflow -# When a cookbook is released it is tagged to a specific version -# This version should match the cookbook version (from the metadata) -# This version is then pinned against specific environments -# -# This class expects you to have pushed all your changes to github -# It will then do the rest -# -# All modes presume you have used github download to download a cookbook or -# are creating a new cookbook -# -# There are two modes of operation -# Development (default) -# -# This will take a cookbook name -# Do some basic version checks (if the current cookbook is frozen) and -# upload it -# -# If the cookbook is frozen it will force you to choose a new version -# and update the metadata accordingly -# -# Final (-f) -# -# You will be forced to select a new version. -# You can choose via the options whether to increment the Major/minor or patch -# revision numbers -# The version will be tagged -# Uploaded to the Chef server and frozen -# -# Version numbers -# -# You can choose a specific version number by specifying it on the command -# line. -# -# If you do not specify a version, the version will be the version in your -# cookbook's metadata -# -# A warning is issued if the version is lower than the version in github -# ---------------------------------------------------------------------------- # require 'chef/knife' class Chef class Knife - + # Implements the knife github deploy function + # @author:: Ian Southam (<isoutham@schubergphilis.com>) + # Copyright:: Copyright (c) 2013 Ian Southam. + # This code is specific to our company workflow + # + # == Overview + # All modes presume you have used github download to download a cookbook or + # are creating a new cookbook + # + # === Examples + # Deploy a development version of cookbook to your chef server + # knife github deploy cookbook_name + # + # Deploy a release version of cookbook to your chef server + # knife github deploy cookbook_name -f + # + # === Options + # -f Operate in final release mode + # -p Update the patch component of the version + # -m Update the minor component of the version + # -M Update the minor component of the version + # + # == Operation Modes + # Development (default) + # + # This will take a cookbook name + # Do some basic version checks (if the current cookbook is frozen) and + # upload it + # + # If the cookbook is frozen it will force you to choose a new version + # and update the metadata accordingly + # + # Release (-f) + # + # You will be forced to select a new version. + # You can choose via the options whether to increment the Major/minor or patch + # revision numbers + # The version will be tagged + # Uploaded to the Chef server and frozen + # + # == Version numbers + # + # You can choose a specific version number by specifying it on the command + # line. + # + # If you do not specify a version, the version will be the version in your + # cookbook's metadata + # + # A warning is issued if the version is lower than the version in github + # class GithubDeploy < Knife deps do require 'chef/knife/github_base' include Chef::Knife::GithubBase require 'chef/cookbook_loader' @@ -100,15 +90,14 @@ :description => "In final mode, increase the minor version ie. x.x.X (Default)", :boolean => true, :default => true def run + # Main run entry point for the class - # validate base options from base module. validate_base_options - # Display information if debug mode is on. display_debug_info # Gather all repo information from github. get_all_repos = get_all_repos(@github_organizations.reverse) @@ -133,11 +122,11 @@ end # is the cookbook in the cookbook_path? if cookbook_path_valid?(@cookbook_name, false).nil? Chef::Log.error("Cookbook is not in cookbook path") - ui.info("HINT: knife github download #{@cookbook_name}") + ui.info("HINT: knife github clone #{@cookbook_name}") exit 1 end # ----------------------------- # # The version can come @@ -159,10 +148,13 @@ inChef = true isFrozen = false if (config[:major] || config[:minor]) config[:patch] = false end + if (config[:major] && config[:minor]) + config[:minor] = false + end begin isFrozen = rest.get_rest("cookbooks/#{@cookbook_name}/#{cookbook_version}").frozen_version? rescue ui.warn "#{@cookbook_name} is not yet in chef" @@ -188,10 +180,11 @@ ui.info("Cookbook #{cookbook_version} has no tag in Git") ui.confirm("Shall I add a tag for you?") set_cookbook_version(cookbook_version) add_tag(cookbook_version) else + ui.confirm("Tag #{cookbook_version} exists - did you make this for this release?") checkout_tag(cookbook_version) set_cookbook_version(cookbook_version) end do_commit(cookbook_version, true) @@ -208,28 +201,42 @@ # If we have gotten this far we can just upload the cookbook cookbook_upload() end + # Ask user to increment current/desired version number + # Method will exit if the user chooses not to increment the version + # + # @param version [String] Version + # @return [String] New version number + # def up_version(version) while true do ui.info("Trying to deploy version #{version}") if @versions.include?(version) ui.info("Version #{version} is already in chef") - ui.confirm("Shall I bump the version (No to Cancel)") + vt = choose_version(version) + ui.confirm("Shall I bump the version to #{vt} (No to Cancel)") version = choose_version(version) else break end end version end + # Increment the current version according to the config + # options config[major] config[minor] config[patch] + # Method will exit if the user chooses not to increment the version + # + # @param version [String] Version + # @return [String] New version number + # def choose_version(version) if version =~ /(\d+)\.(\d+)\.(\d+)/ major = $1 - minor = $1 + minor = $2 patch = $3 major = major.to_i + 1 if config[:major] minor = minor.to_i + 1 if config[:minor] patch = patch.to_i + 1 if config[:patch] version = "#{major}.#{minor}.#{patch}" @@ -239,10 +246,12 @@ exit 1 end version end + # Upload the cookbook to chef server + # If mode is final, freeze the cookbook def cookbook_upload() # Git meuk should not be uploaded use chefignore file instead # FileUtils.remove_entry("#{@github_tmp}/git/#{@cookbook_name}/.git") args = ['cookbook', 'upload', @cookbook_name ] if config[:final] @@ -252,10 +261,14 @@ #upload.config[:cookbook_path] = "#{@github_tmp}/git" # plugin will throw its own errors upload.run end + # If a tag is available in github check it out + # Potentially quite dangerous as it could cause code to + # get rolled back + # @param version [String] Version def checkout_tag(version) ui.info "Checking out tag #{version}" cpath = get_cookbook_path(@cookbook_name) Dir.chdir(cpath); `git checkout -b #{version}` @@ -263,20 +276,20 @@ ui.error("Failed to checkout branch #{version} of #{@cookbook_name}") exit 1 end end + # Get a sorted array of version for the cookbook def get_cookbook_chef_versions () cookbooks = rest.get_rest("/cookbooks/#{@cookbook_name}?num_version=all") cookbooks[@cookbook_name]['versions'].each do |v| @versions.push v['version'] end end - # ---------------------------------------------------------------------- # # Get the version number in the git version of the cookbook - # ---------------------------------------------------------------------- # + # @param version [String] Version def get_cookbook_version() version = nil cpath = get_cookbook_path(@cookbook_name) File.foreach("#{cpath}/metadata.rb") do |line| if line =~ /version.*"(.*)"/i @@ -289,14 +302,21 @@ exit 1 end version end + # Determine if the current cookbook path is valid and that there + # is a cookbook of the correct name in there + # @param cookbook [String] cookbook name + # @return [String] Path to cookbook def get_cookbook_path(cookbook) return cookbook_path_valid?(cookbook, false) end + # Commit changes in git + # @param version [String] cookbook version + # @param push [Bool] true is the cookbook should also be pushed def do_commit(version, push) cpath = get_cookbook_path(@cookbook_name) Dir.chdir("#{cpath}") puts cpath output = `git commit -a -m "Deploy #{version}" 2>&1` @@ -316,9 +336,11 @@ output = `git push 2>&1` end end + # Set the version in metadata.rb + # @param version [String] cookbook version def set_cookbook_version(version) return unless get_cookbook_version() != version contents = '' cpath = get_cookbook_path(@cookbook_name) File.foreach("#{cpath}/metadata.rb") do |line|