Skip to content
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
1 change: 1 addition & 0 deletions bake-gem-github.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Gem::Specification.new do |spec|
spec.license = "MIT"
spec.homepage = "https://github.com/socketry/bake-gem-github"
spec.metadata = {
"documentation_uri" => "https://socketry.github.io/bake-gem-github/",
"bug_tracker_uri" => "https://github.com/socketry/bake-gem-github/issues",
"changelog_uri" => "https://github.com/socketry/bake-gem-github/blob/main/releases.md",
"source_code_uri" => "https://github.com/socketry/bake-gem-github.git",
Expand Down
6 changes: 4 additions & 2 deletions bake.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
# Released under the MIT License.
# Copyright, 2026, by Samuel Williams.

# Regenerate documentation when preparing a release.
# Update the project documentation with the new version number.
#
# @parameter version [String] The new version number.
def after_gem_release_version_increment(version)
context["releases:update"].call(version)
context["utopia:project:agent:context:update"].call
context["utopia:project:update"].call
end
30 changes: 21 additions & 9 deletions bake/gem/github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,41 @@
# Released under the MIT License.
# Copyright, 2026, by Samuel Williams.

# Generate local release workflows, policy, and documentation for review.
# Generate local release workflows, policy payloads, and configuration for review.
# @parameter checks [Array(String)] Required CI check names, including matrix entries.
# @parameter repository [String] Canonical owner/repository.
# @parameter branch [String] Default branch name.
# @parameter repository [String] Canonical owner/repository; discovered through GitHub when omitted.
# @parameter branch [String] Default branch name; discovered through GitHub when omitted.
# @parameter approvals [Integer] Number of approving reviews.
# @parameter signing [Boolean] Require legacy certificate signing.
# @parameter signing [Boolean] Require certificate signing; when omitted, enable it if `release.cert` exists.
# @parameter ruby [String] Ruby version for release workflows.
# @returns [Array(String)] Generated paths relative to the repository root.
def setup(checks:, repository: nil, branch: nil, approvals: 2, signing: nil, ruby: "3.4")
require_relative "../../lib/bake/gem/github/setup"
require "bake/gem/github/setup"
require "bake/gem/shell"

helper = Object.new.extend(Bake::Gem::Shell)
remote = if repository && branch
{}
else
JSON.parse(helper.readlines("gh", "repo", "view", "--json", "nameWithOwner,defaultBranchRef", chdir: context.root).join)
end
options = {repository: repository || remote.fetch("nameWithOwner"), branch: branch || remote.fetch("defaultBranchRef").fetch("name"), checks: checks, approvals: approvals, ruby: ruby}

options = {
repository: repository || remote.fetch("nameWithOwner"),
branch: branch || remote.fetch("defaultBranchRef").fetch("name"),
checks: checks,
approvals: approvals,
ruby: ruby,
}
options[:signing] = signing unless signing.nil?
Bake::Gem::GitHub::Setup.new(context.root).generate(**options)

return Bake::Gem::GitHub::Setup.new(context.root).generate(**options)
end

# Show the desired rules, existing rules, environments, and RubyGems bootstrap values.
# @returns [Hash] Desired and observed settings; RubyGems values describe the expected configuration.
def doctor
require_relative "../../lib/bake/gem/github/project"
Bake::Gem::GitHub::Project.new(context.root).doctor
require "bake/gem/github/project"

return Bake::Gem::GitHub::Project.new(context.root).doctor
end
28 changes: 23 additions & 5 deletions bake/gem/github/release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,70 @@
# Released under the MIT License.
# Copyright, 2026, by Samuel Williams.

require_relative "../../../lib/bake/gem/github/publisher"
require "bake/gem/github/project"

# Prepare a patch release and open its PR.
# @parameter refresh [Boolean] Preserve and regenerate an existing release branch.
# @returns [String] The release PR URL.
def patch(refresh: false)
Bake::Gem::GitHub::Project.new(context.root).prepare(context, "patch", refresh: refresh)
end

# Prepare a minor release and open its PR.
# @parameter refresh [Boolean] Preserve and regenerate an existing release branch.
# @returns [String] The release PR URL.
def minor(refresh: false)
Bake::Gem::GitHub::Project.new(context.root).prepare(context, "minor", refresh: refresh)
end

# Prepare a major release and open its PR.
# @parameter refresh [Boolean] Preserve and regenerate an existing release branch.
# @returns [String] The release PR URL.
def major(refresh: false)
Bake::Gem::GitHub::Project.new(context.root).prepare(context, "major", refresh: refresh)
end

# Resolve and validate a merged PR, emitting a commit output for the publishing job.
# @parameter number [String] The merged PR number; defaults to `RELEASE_PR`.
# @returns [Hash | Nil] Release metadata, or nil for an ordinary PR.
def resolve(number: ENV.fetch("RELEASE_PR"))
result = Bake::Gem::GitHub::Project.new(context.root).inspect_release(number)

if path = ENV["GITHUB_OUTPUT"]
File.open(path, "a") do |file|
file.puts "release=#{!result.nil?}"
file.puts "commit=#{result.fetch(:commit)}" if result
end
end
result

return result
end

# Build or restore the exact artifact for a merged release PR.
# @parameter number [String] The merged release PR number; defaults to `RELEASE_PR`.
# @returns [Hash] The built or restored release receipt.
def build(number: ENV.fetch("RELEASE_PR"))
Bake::Gem::GitHub::Publisher.new(context.root).build(number)
require "bake/gem/github/publisher"

return Bake::Gem::GitHub::Publisher.new(context.root).build(number)
end

# Verify, upload and finalize a merged release using its retained artifact.
# @parameter number [String] The merged release PR number; defaults to `RELEASE_PR`.
# @returns [Hash] The published release receipt.
def publish(number: ENV.fetch("RELEASE_PR"))
Bake::Gem::GitHub::Publisher.new(context.root).publish(number)
require "bake/gem/github/publisher"

return Bake::Gem::GitHub::Publisher.new(context.root).publish(number)
end

# Rerun the original publishing workflow, preserving event identity and artifact bytes.
# @parameter run [String] The original release-publish workflow run ID.
# @returns [Boolean] True when GitHub accepts the rerun request.
def resume(run:)
project = Bake::Gem::GitHub::Project.new(context.root)
details = project.api("actions/runs/#{Integer(run)}")
raise "Expected a release-publish workflow run." unless details.fetch("path") == ".github/workflows/release-publish.yaml"
project.system("gh", "run", "rerun", run.to_s, "--repo", project.config.fetch("repository"), chdir: context.root)

return project.system("gh", "run", "rerun", run.to_s, "--repo", project.config.fetch("repository"), chdir: context.root)
end
13 changes: 9 additions & 4 deletions bake/gem/github/setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
# Copyright, 2026, by Samuel Williams.

# Inspect external settings before applying the generated policy.
# @returns [Hash] Desired and observed settings for review.
def plan
context.lookup("gem:github:doctor").call
end

# Apply the four managed rulesets using the current gh administrator credentials.
# @returns [Hash] The managed ruleset payloads after successful application.
def apply
require_relative "../../../lib/bake/gem/github/project"
Bake::Gem::GitHub::Project.new(context.root).apply
require "bake/gem/github/project"

return Bake::Gem::GitHub::Project.new(context.root).apply
end

# Update generated files in the working tree using config/release.yaml and the installed templates.
# @returns [Array(String)] Changed paths relative to the repository root.
def update
require_relative "../../../lib/bake/gem/github/setup"
Bake::Gem::GitHub::Setup.new(context.root).update
require "bake/gem/github/setup"

return Bake::Gem::GitHub::Setup.new(context.root).update
end
Loading
Loading