From 735b0833f54fd74a1584070ff22611a6e1a7611f Mon Sep 17 00:00:00 2001 From: James Couball Date: Mon, 3 Jan 2022 13:14:27 -0800 Subject: [PATCH 1/4] Release v1.10.1 (#553) Signed-off-by: James Couball --- CHANGELOG.md | 4 ++++ lib/git/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e53dd79e..5c8ad209 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ # Change Log +## 1.10.1 + +See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.1 + ## 1.10.0 See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.0 diff --git a/lib/git/version.rb b/lib/git/version.rb index ea10ef11..89ef1017 100644 --- a/lib/git/version.rb +++ b/lib/git/version.rb @@ -1,5 +1,5 @@ module Git # The current gem version # @return [String] the current gem version. - VERSION='1.10.0' + VERSION='1.10.1' end From 12e3d0300c6aead9c416e5d8445bacb84d8a5b37 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Wed, 5 Jan 2022 20:31:53 -0600 Subject: [PATCH 2/4] Store tempfile objects to prevent deletion during tests (#555) --- tests/units/test_archive.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/units/test_archive.rb b/tests/units/test_archive.rb index 3386a27f..93ec66f2 100644 --- a/tests/units/test_archive.rb +++ b/tests/units/test_archive.rb @@ -7,10 +7,16 @@ class TestArchive < Test::Unit::TestCase def setup set_file_paths @git = Git.open(@wdir) + @tempfiles = [] + end + + def teardown + @tempfiles.clear end def tempfile tempfile_object = Tempfile.new('archive-test') + @tempfiles << tempfile_object # prevent deletion until teardown tempfile_object.close # close to avoid locking from git processes tempfile_object.path end From c987a74776f186e97f958662beea719fa83000f7 Mon Sep 17 00:00:00 2001 From: James Couball Date: Thu, 6 Jan 2022 14:45:55 -0800 Subject: [PATCH 3/4] Add create-release, setup, and console dev scripts (#560) Signed-off-by: James Couball --- bin/console | 15 ++ bin/create-release | 506 +++++++++++++++++++++++++++++++++++++++++++++ bin/setup | 8 + git.gemspec | 3 +- 4 files changed, 531 insertions(+), 1 deletion(-) create mode 100755 bin/console create mode 100755 bin/create-release create mode 100755 bin/setup diff --git a/bin/console b/bin/console new file mode 100755 index 00000000..0199a6fc --- /dev/null +++ b/bin/console @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'bundler/setup' +require 'git' + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require 'irb' +IRB.start(__FILE__) diff --git a/bin/create-release b/bin/create-release new file mode 100755 index 00000000..fdc8aa83 --- /dev/null +++ b/bin/create-release @@ -0,0 +1,506 @@ +#!/usr/bin/env ruby + +# Run this script while in the root directory of the project with the default +# branch checked out. + +require 'bump' +require 'English' +require 'fileutils' +require 'optparse' +require 'tempfile' + +# TODO: Right now the default branch and the remote name are hard coded + +class Options + attr_accessor :current_version, :next_version, :tag, :current_tag, :next_tag, :branch, :quiet + + def initialize + yield self if block_given? + end + + def release_type + raise "release_type not set" if @release_type.nil? + @release_type + end + + VALID_RELEASE_TYPES = %w(major minor patch) + + def release_type=(release_type) + raise 'release_type must be one of: ' + VALID_RELEASE_TYPES.join(', ') unless VALID_RELEASE_TYPES.include?(release_type) + @release_type = release_type + end + + def quiet + @quiet = false unless instance_variable_defined?(:@quiet) + @quiet + end + + def current_version + @current_version ||= Bump::Bump.current + end + + def next_version + current_version # Save the current version before bumping + @next_version ||= Bump::Bump.next_version(release_type) + end + + def tag + @tag ||= "v#{next_version}" + end + + def current_tag + @current_tag ||= "v#{current_version}" + end + + def next_tag + tag + end + + def branch + @branch ||= "release-#{tag}" + end + + def default_branch + @default_branch ||= `git remote show '#{remote}'`.match(/HEAD branch: (.*?)$/)[1] + end + + def remote + @remote ||= 'origin' + end + + def to_s + <<~OUTPUT + release_type='#{release_type}' + current_version='#{current_version}' + next_version='#{next_version}' + tag='#{tag}' + branch='#{branch}' + quiet=#{quiet} + OUTPUT + end +end + +class CommandLineParser + attr_reader :options + + def initialize + @option_parser = OptionParser.new + define_options + @options = Options.new + end + + def parse(args) + option_parser.parse!(remaining_args = args.dup) + parse_remaining_args(remaining_args) + # puts options unless options.quiet + options + end + + private + + attr_reader :option_parser + + def parse_remaining_args(remaining_args) + error_with_usage('No release type specified') if remaining_args.empty? + @options.release_type = remaining_args.shift || nil + error_with_usage('Too many args') unless remaining_args.empty? + end + + def error_with_usage(message) + warn <<~MESSAGE + ERROR: #{message} + #{option_parser} + MESSAGE + exit 1 + end + + def define_options + option_parser.banner = 'Usage: create_release --help | release-type' + option_parser.separator '' + option_parser.separator 'Options:' + + define_quiet_option + define_help_option + end + + def define_quiet_option + option_parser.on('-q', '--[no-]quiet', 'Do not show output') do |quiet| + options.quiet = quiet + end + end + + def define_help_option + option_parser.on_tail('-h', '--help', 'Show this message') do + puts option_parser + exit 0 + end + end +end + +class ReleaseAssertions + attr_reader :options + + def initialize(options) + @options = options + end + + def make_assertions + bundle_is_up_to_date + in_git_repo + in_repo_toplevel_directory + on_default_branch + no_uncommitted_changes + local_and_remote_on_same_commit + tag_does_not_exist + branch_does_not_exist + docker_is_running + changelog_docker_container_exists + gh_command_exists + end + + private + + def gh_command_exists + print "Checking that the gh command exists..." + `which gh > /dev/null 2>&1` + if $CHILD_STATUS.success? + puts "OK" + else + error "The gh command was not found" + end + end + + def docker_is_running + print "Checking that docker is installed and running..." + `docker info > /dev/null 2>&1` + if $CHILD_STATUS.success? + puts "OK" + else + error "Docker is not installed or not running" + end + end + + + def changelog_docker_container_exists + print "Checking that the changelog docker container exists (might take time to build)..." + `docker build --file Dockerfile.changelog-rs --tag changelog-rs . 1>/dev/null` + if $CHILD_STATUS.success? + puts "OK" + else + error "Failed to build the changelog-rs docker container" + end + end + + def bundle_is_up_to_date + print "Checking that the bundle is up to date..." + if File.exist?('Gemfile.lock') + print "Running bundle update..." + `bundle update --quiet` + if $CHILD_STATUS.success? + puts "OK" + else + error "bundle update failed" + end + else + print "Running bundle install..." + `bundle install --quiet` + if $CHILD_STATUS.success? + puts "OK" + else + error "bundle install failed" + end + end + end + + def in_git_repo + print "Checking that you are in a git repo..." + `git rev-parse --is-inside-work-tree --quiet > /dev/null 2>&1` + if $CHILD_STATUS.success? + puts "OK" + else + error "You are not in a git repo" + end + end + + def in_repo_toplevel_directory + print "Checking that you are in the repo's toplevel directory..." + toplevel_directory = `git rev-parse --show-toplevel`.chomp + if toplevel_directory == FileUtils.pwd + puts "OK" + else + error "You are not in the repo's toplevel directory" + end + end + + def on_default_branch + print "Checking that you are on the default branch..." + current_branch = `git branch --show-current`.chomp + if current_branch == options.default_branch + puts "OK" + else + error "You are not on the default branch '#{default_branch}'" + end + end + + def no_uncommitted_changes + print "Checking that there are no uncommitted changes..." + if `git status --porcelain | wc -l`.to_i == 0 + puts "OK" + else + error "There are uncommitted changes" + end + end + + def no_staged_changes + print "Checking that there are no staged changes..." + if `git diff --staged --name-only | wc -l`.to_i == 0 + puts "OK" + else + error "There are staged changes" + end + end + + def local_and_remote_on_same_commit + print "Checking that local and remote are on the same commit..." + local_commit = `git rev-parse HEAD`.chomp + remote_commit = `git ls-remote '#{options.remote}' '#{options.default_branch}' | cut -f 1`.chomp + if local_commit == remote_commit + puts "OK" + else + error "Local and remote are not on the same commit" + end + end + + def local_tag_does_not_exist + print "Checking that local tag '#{options.tag}' does not exist..." + + tags = `git tag --list "#{options.tag}"`.chomp + error 'Could not list tags' unless $CHILD_STATUS.success? + + if tags.split.empty? + puts 'OK' + else + error "'#{options.tag}' already exists" + end + end + + def remote_tag_does_not_exist + print "Checking that the remote tag '#{options.tag}' does not exist..." + `git ls-remote --tags --exit-code '#{options.remote}' #{options.tag} >/dev/null 2>&1` + unless $CHILD_STATUS.success? + puts "OK" + else + error "'#{options.tag}' already exists" + end + end + + def tag_does_not_exist + local_tag_does_not_exist + remote_tag_does_not_exist + end + + def local_branch_does_not_exist + print "Checking that local branch '#{options.branch}' does not exist..." + + if `git branch --list "#{options.branch}" | wc -l`.to_i.zero? + puts "OK" + else + error "'#{options.branch}' already exists." + end + end + + def remote_branch_does_not_exist + print "Checking that the remote branch '#{options.branch}' does not exist..." + `git ls-remote --heads --exit-code '#{options.remote}' '#{options.branch}' >/dev/null 2>&1` + unless $CHILD_STATUS.success? + puts "OK" + else + error "'#{options.branch}' already exists" + end + end + + def branch_does_not_exist + local_branch_does_not_exist + remote_branch_does_not_exist + end + + private + + def print(*args) + super unless options.quiet + end + + def puts(*args) + super unless options.quiet + end + + def error(message) + warn "ERROR: #{message}" + exit 1 + end +end + +class ReleaseCreator + attr_reader :options + + def initialize(options) + @options = options + end + + def create_release + create_branch + update_changelog + update_version + make_release_commit + create_tag + push_release_commit_and_tag + create_github_release + create_release_pull_request + end + + private + + def create_branch + print "Creating branch '#{options.branch}'..." + `git checkout -b "#{options.branch}" > /dev/null 2>&1` + if $CHILD_STATUS.success? + puts "OK" + else + error "Could not create branch '#{options.branch}'" unless $CHILD_STATUS.success? + end + end + + def update_changelog + print 'Updating CHANGELOG.md...' + changelog_lines = File.readlines('CHANGELOG.md') + first_entry = changelog_lines.index { |e| e =~ /^## / } + error "Could not find changelog insertion point" unless first_entry + FileUtils.rm('CHANGELOG.md') + File.write('CHANGELOG.md', <<~CHANGELOG.chomp) + #{changelog_lines[0..first_entry - 1].join}## #{options.tag} + + See https://github.com/ruby-git/ruby-git/releases/tag/#{options.tag} + + #{changelog_lines[first_entry..].join} + CHANGELOG + `git add CHANGELOG.md` + if $CHILD_STATUS.success? + puts 'OK' + else + error 'Could not stage changes to CHANGELOG.md' + end + end + + def update_version + print 'Updating version...' + message, status = Bump::Bump.run(options.release_type, commit: false) + error 'Could not bump version' unless status == 0 + `git add lib/git/version.rb` + if $CHILD_STATUS.success? + puts 'OK' + else + error 'Could not stage changes to lib/git/version.rb' + end + end + + def make_release_commit + print 'Making release commit...' + `git commit -s -m 'Release #{options.tag}'` + error 'Could not make release commit' unless $CHILD_STATUS.success? + end + + def create_tag + print "Creating tag '#{options.tag}'..." + `git tag '#{options.tag}'` + if $CHILD_STATUS.success? + puts 'OK' + else + error "Could not create tag '#{options.tag}'" + end + end + + def push_release_commit_and_tag + print "Pushing branch '#{options.branch}' to remote..." + `git push --tags --set-upstream '#{options.remote}' '#{options.branch}' > /dev/null 2>&1` + if $CHILD_STATUS.success? + puts 'OK' + else + error 'Could not push release commit' + end + end + + def changelog + @changelog ||= begin + print "Generating changelog..." + pwd = FileUtils.pwd + from = options.current_tag + to = options.next_tag + command = "docker run --rm --volume '#{pwd}:/worktree' changelog-rs '#{from}' '#{to}'" + changelog = `#{command}` + if $CHILD_STATUS.success? + puts 'OK' + changelog.rstrip.lines[1..].join + else + error 'Could not generate the changelog' + end + end + end + + def create_github_release + Tempfile.create do |f| + f.write changelog + f.close + + print "Creating GitHub release '#{options.tag}'..." + tag = options.tag + `gh release create #{tag} --title 'Release #{tag}' --notes-file '#{f.path}' --target #{options.default_branch}` + if $CHILD_STATUS.success? + puts 'OK' + else + error 'Could not create release' + end + end + end + + def create_release_pull_request + Tempfile.create do |f| + f.write <<~PR + ### Your checklist for this pull request + 🚨Please review the [guidelines for contributing](https://github.com/ruby-git/ruby-git/blob/#{options.default_branch}/CONTRIBUTING.md) to this repository. + + - [X] Ensure all commits include DCO sign-off. + - [X] Ensure that your contributions pass unit testing. + - [X] Ensure that your contributions contain documentation if applicable. + + ### Description + #{changelog} + PR + f.close + + print "Creating GitHub pull request..." + `gh pr create --title 'Release #{options.tag}' --body-file '#{f.path}' --base '#{options.default_branch}'` + if $CHILD_STATUS.success? + puts 'OK' + else + error 'Could not create release pull request' + end + end + end + + def error(message) + warn "ERROR: #{message}" + exit 1 + end + + def print(*args) + super unless options.quiet + end + + def puts(*args) + super unless options.quiet + end +end + +options = CommandLineParser.new.parse(ARGV) +ReleaseAssertions.new(options).make_assertions +ReleaseCreator.new(options).create_release diff --git a/bin/setup b/bin/setup new file mode 100755 index 00000000..dce67d86 --- /dev/null +++ b/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/git.gemspec b/git.gemspec index 3fcee253..8d974e28 100644 --- a/git.gemspec +++ b/git.gemspec @@ -28,6 +28,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'rchardet', '~> 1.8' + s.add_development_dependency 'bump', '~> 0.10' s.add_development_dependency 'minitar', '~> 0.9' s.add_development_dependency 'rake', '~> 13.0' s.add_development_dependency 'test-unit', '~> 3.3' @@ -41,6 +42,6 @@ Gem::Specification.new do |s| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. s.files = Dir.chdir(File.expand_path(__dir__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(tests|spec|features)/}) } + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(tests|spec|features|bin)/}) } end end From 57f941ccd296fbb0cacd1d3392626fe90a233511 Mon Sep 17 00:00:00 2001 From: James Couball Date: Thu, 6 Jan 2022 15:20:38 -0800 Subject: [PATCH 4/4] Release v1.10.2 Signed-off-by: James Couball --- CHANGELOG.md | 4 ++++ lib/git/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c8ad209..2c1d27e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ # Change Log +## v1.10.2 + +See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.2 + ## 1.10.1 See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.1 diff --git a/lib/git/version.rb b/lib/git/version.rb index 89ef1017..54ebae36 100644 --- a/lib/git/version.rb +++ b/lib/git/version.rb @@ -1,5 +1,5 @@ module Git # The current gem version # @return [String] the current gem version. - VERSION='1.10.1' + VERSION='1.10.2' end pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy