Skip to content

Commit

Permalink
Complete redesign of this gem (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouball committed Jan 29, 2023
1 parent d75e1e9 commit c7bd12d
Show file tree
Hide file tree
Showing 78 changed files with 3,254 additions and 1,593 deletions.
7 changes: 0 additions & 7 deletions .vscode/settings.json

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2022 James Couball
Copyright (c) 2023 James Couball

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
57 changes: 36 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,40 @@

Create a GitHub release for a new gem version.

To create a new GitHub release for a gem, run the following from the top level
project directory with the default branch selected:

```shell
create-github-release [major|minor|patch]
The `create-github-release` script does the following:

* Bumps the project's version
* Updates the project's changelog
* Creates a release branch
* Commits the version change and changelog update
* Creates a version tag
* Pushes the release branch to GitHub
* Creates a GitHub release and GitHub pull request for the release

You should merge the pull request once it is reviewed and approved.

Pull the changes from the default branch and publish your gem with the `rake release` command.

Here is the command line --help output:

```text
Usage:
create-github-release --help | RELEASE_TYPE [options]
RELEASE_TYPE must be 'major', 'minor', or 'patch'
Options:
--default-branch=BRANCH_NAME Override the default branch
--release-branch=BRANCH_NAME Override the release branch to create
--remote=REMOTE_NAME Use this remote name instead of 'origin'
--last-release-version=VERSION
Use this version instead `bump current`
--next-release-version=VERSION
Use this version instead `bump RELEASE_TYPE`
--changelog-path=PATH Use this file instead of CHANGELOG.md
-q, --[no-]quiet Do not show output
-v, --[no-]verbose Show extra output
-h, --help Show this message
```

The following conditions must be met in order to create a release:
Expand All @@ -21,21 +50,11 @@ The following conditions must be met in order to create a release:
* The default branch must be checked out
* There are no uncommitted changes
* The local and remote must be on the same commit
* The last release tag must exist
* The new release tag must not already exist either locally or remotely
* The new release branch must not already exist either locally or remotely
* Docker must be running
* The changelog docker container must already exist or be able to be built
* The gh command must be installed

The result of running this command is:
* A new release branch is created
* CHANGELOG.md is updated with a list of PRs since the last release
* The Gem version is updated via Bump
* The CHANGELOG.md and version changes are committed and tagged on the new release branch
* The new release branch is pushed to the remote
* A release is created on GitHub
* A release PR is created on GitHub

## Installation

Add `create_github_release` as a development dependency in your project's gemspec:
Expand All @@ -52,11 +71,7 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
`rake spec` to run the tests. You can also run `bin/console` for an interactive
prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To
release a new version, update the version number in `version.rb`, and then run
`bundle exec rake release`, which will create a git tag for the version, push git
commits and the created tag, and push the `.gem` file to
[rubygems.org](https://rubygems.org).
To install this gem onto your local machine, run `bundle exec rake install`.

## Contributing

Expand Down
1 change: 1 addition & 0 deletions create_github_release.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'simplecov', '~> 0.21'
spec.add_development_dependency 'simplecov-lcov', '~> 0.8'
spec.add_development_dependency 'solargraph', '~> 0.47'
spec.add_development_dependency 'timecop', '~> 0.9'
spec.add_development_dependency 'yard', '~> 0.9'
spec.add_development_dependency 'yardstick', '~> 0.9'

Expand Down
20 changes: 12 additions & 8 deletions exe/create-github-release
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@

require 'create_github_release'

options = CreateGithubRelease::CommandLineParser.new.parse(ARGV)
CreateGithubRelease::ReleaseAssertions.new(options).make_assertions
options = CreateGithubRelease::CommandLineParser.new.parse(*ARGV)
pp options if options.verbose

project = CreateGithubRelease::Project.new(options)

CreateGithubRelease::ReleaseAssertions.new(project).make_assertions
puts unless options.quiet
CreateGithubRelease::ReleaseTasks.new(options).run
CreateGithubRelease::ReleaseTasks.new(project).run

puts <<~MESSAGE unless options.quiet
Release '#{options.tag}' created successfully
See the release notes at #{options.release_url}
puts <<~MESSAGE unless project.quiet
Release '#{project.next_release_tag}' created successfully
See the release notes at #{project.release_url}
Next steps:
* Get someone to review and approve the release pull request
* Merge the pull request manually from the command line with the following commands:
git checkout #{options.default_branch}
git merge --ff-only #{options.branch}
git checkout #{project.default_branch}
git merge --ff-only #{project.release_branch}
git push
MESSAGE
6 changes: 4 additions & 2 deletions lib/create_github_release.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# frozen_string_literal: true

require 'create_github_release/backtick_debug'
require 'create_github_release/command_line_options'
require 'create_github_release/command_line_parser'
require 'create_github_release/project'

require 'create_github_release/change'
require 'create_github_release/changelog'
require 'create_github_release/options'
require 'create_github_release/release'

require 'create_github_release/assertion_base'
require 'create_github_release/assertions'
Expand Down
36 changes: 25 additions & 11 deletions lib/create_github_release/assertion_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ module CreateGithubRelease
# @api private
#
class AssertionBase
# Create a new assertion object and save the given `options`
# @param options [CreateGithubRelease::Options] the options
# Create a new assertion object and save the given `project`
# @param project [CreateGithubRelease::Project] the project to create a release for
# @api private
def initialize(options)
@options = options
def initialize(project)
raise ArgumentError, 'project must be a CreateGithubRelease::Project' unless
project.is_a?(CreateGithubRelease::Project)

@project = project
end

# This method must be overriden by a subclass
Expand All @@ -29,25 +32,25 @@ def assert

# @!attribute [r] options
#
# The options passed to the assertion object
# @return [CreateGithubRelease::Options] the options
# The project passed to the assertion object
# @return [CreateGithubRelease::Project] the project to create a release for
# @api private
attr_reader :options
attr_reader :project

# Calls `Kernel.print` if the `quiet` flag is not set in the `options`
# Calls `Kernel.print` if the `quiet` flag is not set in the `project`
# @param args [Array] the arguments to pass to `Kernel.print`
# @return [void]
# @api private
def print(*args)
super unless options.quiet
super unless project.quiet?
end

# Calls `Kernel.puts` if the `quiet` flag is not set in the `options`
# Calls `Kernel.puts` if the `quiet` flag is not set in the `project`
# @param args [Array] the arguments to pass to `Kernel.puts`
# @return [void]
# @api private
def puts(*args)
super unless options.quiet
super unless project.quiet?
end

# Writes a message to stderr and exits with exitcode 1
Expand All @@ -58,5 +61,16 @@ def error(message)
warn "ERROR: #{message}"
exit 1
end

# `true` if the `project.verbose?` flag is `true`
# @return [Boolean]
# @api private
def backtick_debug?
project.verbose?
end

# This overrides the backtick operator for this class to output debug
# information if `verbose?` is true
include CreateGithubRelease::BacktickDebug
end
end
3 changes: 1 addition & 2 deletions lib/create_github_release/assertions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ module Assertions; end
end

require_relative 'assertions/bundle_is_up_to_date'
require_relative 'assertions/changelog_docker_container_exists'
require_relative 'assertions/docker_is_running'
require_relative 'assertions/gh_command_exists'
require_relative 'assertions/git_command_exists'
require_relative 'assertions/in_git_repo'
require_relative 'assertions/in_repo_root_directory'
require_relative 'assertions/last_release_tag_exists'
require_relative 'assertions/local_and_remote_on_same_commit'
require_relative 'assertions/local_release_branch_does_not_exist'
require_relative 'assertions/local_release_tag_does_not_exist'
Expand Down
7 changes: 4 additions & 3 deletions lib/create_github_release/assertions/bundle_is_up_to_date.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

module CreateGithubRelease
module Assertions
# Assert that options.branch does not exist
# Assert that project.release+branch does not exist
#
# Checks both the local repository and the remote repository.
#
Expand All @@ -17,8 +17,9 @@ class BundleIsUpToDate < AssertionBase
# @example
# require 'create_github_release'
#
# options = CreateGithubRelease::Options.new { |o| o.release_type = 'major' }
# assertion = CreateGithubRelease::Assertions::BundleIsUpToDate.new(options)
# options = CreateGithubRelease::CommandLineOptions.new { |o| o.release_type = 'major' }
# project = CreateGithubRelease::Project.new(options)
# assertion = CreateGithubRelease::Assertions::BundleIsUpToDate.new(project)
# begin
# assertion.assert
# puts 'Assertion passed'
Expand Down

This file was deleted.

5 changes: 3 additions & 2 deletions lib/create_github_release/assertions/gh_command_exists.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ class GhCommandExists < AssertionBase
# @example
# require 'create_github_release'
#
# options = CreateGithubRelease::Options.new { |o| o.release_type = 'major' }
# assertion = CreateGithubRelease::Assertions::GhCommandExists.new(options)
# options = CreateGithubRelease::CommandLineOptions.new { |o| o.release_type = 'major' }
# project = CreateGithubRelease::Project.new(options)
# assertion = CreateGithubRelease::Assertions::GhCommandExists.new(project)
# begin
# assertion.assert
# puts 'Assertion passed'
Expand Down
5 changes: 3 additions & 2 deletions lib/create_github_release/assertions/git_command_exists.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ class GitCommandExists < AssertionBase
# @example
# require 'create_github_release'
#
# options = CreateGithubRelease::Options.new { |o| o.release_type = 'major' }
# assertion = CreateGithubRelease::Assertions::GitCommandExists.new(options)
# options = CreateGithubRelease::CommandLineOptions.new { |o| o.release_type = 'major' }
# project = CreateGithubRelease::Project.new(options)
# assertion = CreateGithubRelease::Assertions::GitCommandExists.new(project)
# begin
# assertion.assert
# puts 'Assertion passed'
Expand Down
5 changes: 3 additions & 2 deletions lib/create_github_release/assertions/in_git_repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ class InGitRepo < AssertionBase
# @example
# require 'create_github_release'
#
# options = CreateGithubRelease::Options.new { |o| o.release_type = 'major' }
# assertion = CreateGithubRelease::Assertions::InGitRepo.new(options)
# options = CreateGithubRelease::CommandLineOptions.new { |o| o.release_type = 'major' }
# project = CreateGithubRelease::Project.new(options)
# assertion = CreateGithubRelease::Assertions::InGitRepo.new(project)
# begin
# assertion.assert
# puts 'Assertion passed'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ class InRepoRootDirectory < AssertionBase
# @example
# require 'create_github_release'
#
# options = CreateGithubRelease::Options.new { |o| o.release_type = 'major' }
# assertion = CreateGithubRelease::Assertions::InRepoRootDirectory.new(options)
# options = CreateGithubRelease::CommandLineOptions.new { |o| o.release_type = 'major' }
# project = CreateGithubRelease::Project.new(options)
# assertion = CreateGithubRelease::Assertions::InRepoRootDirectory.new(project)
# begin
# assertion.assert
# puts 'Assertion passed'
Expand Down
Loading

0 comments on commit c7bd12d

Please sign in to comment.