bake-gem-github 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/bake/gem/github/setup.rb +6 -0
- data/context/getting-started.md +15 -2
- data/context/index.yaml +1 -1
- data/lib/bake/gem/github/publisher.rb +4 -1
- data/lib/bake/gem/github/setup.rb +37 -14
- data/lib/bake/gem/github/version.rb +1 -1
- data/releases.md +5 -0
- data/templates/release-prepare.yaml.erb +4 -2
- data/templates/release-publish.yaml.erb +10 -7
- data/templates/release-validate.yaml.erb +2 -2
- data/templates/releasing.md +2 -0
- data.tar.gz.sig +0 -0
- metadata +15 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec4e3e7088789843fbadf6a3b8a679593e5b24e328fce5301e63fe79a10dfdf7
|
|
4
|
+
data.tar.gz: 77857229f0d478caba8181e9bdd1f5d81b2198d377cf37c9826c461531eab37d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 046244ece39b8e166674a1368781012123175f4bd2902ea4777da518f86b148f8a85bcd0c4eda889291bc7a6e00617992dd8f35c1fef8e156e883af1458abb37
|
|
7
|
+
data.tar.gz: 0cea0e0fcbd5c3b2d8c04c432698b520a1ab9883781a5969649cb8e122cafe7657385501cc501028f3fd509de0f84d096216409af32ceecd1fef497110796a97
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/bake/gem/github/setup.rb
CHANGED
|
@@ -13,3 +13,9 @@ def apply
|
|
|
13
13
|
require_relative "../../../lib/bake/gem/github/project"
|
|
14
14
|
Bake::Gem::GitHub::Project.new(context.root).apply
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
# Update generated files in the working tree using config/release.yaml and the installed templates.
|
|
18
|
+
def update
|
|
19
|
+
require_relative "../../../lib/bake/gem/github/setup"
|
|
20
|
+
Bake::Gem::GitHub::Setup.new(context.root).update
|
|
21
|
+
end
|
data/context/getting-started.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GitHub Releases
|
|
2
2
|
|
|
3
|
-
This guide
|
|
3
|
+
This guide explains how to set up reviewed Ruby gem releases with `bake-gem-github`, native GitHub rules, RubyGems Trusted Publishing, and retained release artifacts.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,7 +18,18 @@ bundle exec bake agent:context:install
|
|
|
18
18
|
bundle exec bake gem:github:setup:plan
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Setup adds three
|
|
21
|
+
Setup adds three release workflows, `config/release.yaml`, native ruleset payloads, and `.github/releasing.md`. Identical reruns do nothing; conflicting existing files stop before any file is written. Setup does not replace other publishers: remove conflicting release workflows during migration.
|
|
22
|
+
|
|
23
|
+
To adopt template fixes after upgrading the gem, start from a clean working tree, edit `config/release.yaml` as needed, and regenerate:
|
|
24
|
+
|
|
25
|
+
``` bash
|
|
26
|
+
bundle exec bake gem:github:setup:update
|
|
27
|
+
git diff
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The task updates the managed workflows, policy payloads, configuration formatting, and maintainer instructions directly in the working tree and returns the changed paths. It does not stage, commit, or change remote settings. An agent or maintainer can review the diff and selectively keep changes, restoring repository-specific customizations from Git where needed. Commit or stash existing edits first: generated files are replaced by the current templates. Repeating an update produces no further changes; intentionally retained customizations will appear in later update diffs. Apply remote rulesets after the corresponding workflows are running.
|
|
31
|
+
|
|
32
|
+
Release workflows follow `bake modernize` action versions and use moving major tags where upstream provides them. These tags receive upstream updates automatically; full commit hashes select fixed revisions. The RubyGems credentials action uses its [documented `@main` reference](https://github.com/rubygems/configure-rubygems-credentials#trusted-publisher-recommended), since upstream does not provide a moving major tag. Repositories that require fixed revisions can customize these references.
|
|
22
33
|
|
|
23
34
|
The default is two approvals with explicit administrator bypass, dismissed stale reviews, approval of the last push, strict up-to-date CI, and immutable default-branch history/release tags. These branch rules affect **all PRs** into the default branch. Ordinary administrator reviews count as one review. A human who dispatches a bot-authored PR is not its author under GitHub's native rules.
|
|
24
35
|
|
|
@@ -64,6 +75,8 @@ After merge/squash, the publishing workflow verifies GitHub's merged PR record a
|
|
|
64
75
|
|
|
65
76
|
The workflow retains the gem, receipt and attestations before obtaining RubyGems publishing credentials. It verifies both attestations, checks the uploaded bytes and registry bundle, then pushes the specific version tag and creates the GitHub release. Existing tags/assets are checked and never overwritten. The old `after_gem_release` GitHub hook is not called by this pipeline, so there is one owner for release creation.
|
|
66
77
|
|
|
78
|
+
The draft release description includes the exact version's notes from `releases.md` in the merged release checkout, followed by the PR URL, source commit, and gem digest. Notes are extracted using `bake-releases`; a missing or empty section leaves the metadata as the description. Retries preserve the existing release description.
|
|
79
|
+
|
|
67
80
|
``` bash
|
|
68
81
|
set -e
|
|
69
82
|
for file in example-1.2.3.gem release.json; do
|
data/context/index.yaml
CHANGED
|
@@ -6,5 +6,5 @@ metadata: {}
|
|
|
6
6
|
files:
|
|
7
7
|
- path: getting-started.md
|
|
8
8
|
title: GitHub Releases
|
|
9
|
-
description: This guide
|
|
9
|
+
description: This guide explains how to set up reviewed Ruby gem releases with `bake-gem-github`,
|
|
10
10
|
native GitHub rules, RubyGems Trusted Publishing, and retained release artifacts.
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Copyright, 2026, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "project"
|
|
7
|
+
require "bake/releases"
|
|
7
8
|
require "digest"
|
|
8
9
|
require "net/http"
|
|
9
10
|
require "openssl"
|
|
@@ -146,10 +147,12 @@ module Bake
|
|
|
146
147
|
tag = "v#{receipt.fetch(:version)}"
|
|
147
148
|
release = github_release(tag)
|
|
148
149
|
unless release
|
|
150
|
+
notes = Bake::Releases.notes(tag, path: File.join(@root, "releases.md"))
|
|
151
|
+
metadata = "#{receipt.fetch(:pull_request_url)}\n\nSource: #{receipt.fetch(:commit)}\nSHA256: #{receipt.fetch(:sha256)}\n"
|
|
149
152
|
Tempfile.create("release") do |file|
|
|
150
153
|
file.write(JSON.generate(
|
|
151
154
|
tag_name: tag, draft: true, target_commitish: receipt.fetch(:commit), name: "#{receipt.fetch(:name)} #{tag}",
|
|
152
|
-
body:
|
|
155
|
+
body: [notes, metadata].compact.join("\n")
|
|
153
156
|
))
|
|
154
157
|
file.flush
|
|
155
158
|
# The release list can remain stale after a successful creation:
|
|
@@ -25,25 +25,20 @@ module Bake
|
|
|
25
25
|
raise "Select the required CI check names." if checks.empty?
|
|
26
26
|
raise "Review count must be between 1 and 6." unless (1..6).include?(approvals)
|
|
27
27
|
config = {"schema" => 1, "repository" => repository, "branch" => branch, "checks" => (checks + ["Release validation"]).uniq, "approvals" => approvals, "signing" => signing, "ruby" => ruby, "environment" => "rubygems"}
|
|
28
|
-
|
|
29
|
-
files = {"config/release.yaml" => YAML.dump(config)}
|
|
30
|
-
Dir.glob("*.erb", base: templates).each do |name|
|
|
31
|
-
files[".github/workflows/#{name.delete_suffix('.erb')}"] = ERB.new(File.read(File.join(templates, name)), trim_mode: "-").result(binding)
|
|
32
|
-
end
|
|
33
|
-
self.class.rules(config).each do |name, rule|
|
|
34
|
-
files[".github/release-rules/#{name}.json"] = JSON.pretty_generate(rule) + "\n"
|
|
35
|
-
end
|
|
36
|
-
files[".github/releasing.md"] = File.read(File.join(templates, "releasing.md"))
|
|
28
|
+
files = render(config)
|
|
37
29
|
conflicts = files.keys.select{|name| File.exist?(File.join(@root, name)) && File.read(File.join(@root, name)) != files[name]}
|
|
38
30
|
raise "Existing files differ; review them before regenerating: #{conflicts.join(', ')}" unless conflicts.empty?
|
|
39
|
-
files
|
|
40
|
-
path = File.join(@root, name)
|
|
41
|
-
FileUtils.mkdir_p(File.dirname(path))
|
|
42
|
-
File.write(path, content) unless File.exist?(path)
|
|
43
|
-
end
|
|
31
|
+
write(files)
|
|
44
32
|
files.keys
|
|
45
33
|
end
|
|
46
34
|
|
|
35
|
+
# Update generated files in the working tree using the existing configuration; return changed paths.
|
|
36
|
+
def update
|
|
37
|
+
config = YAML.safe_load_file(File.join(@root, "config/release.yaml"))
|
|
38
|
+
raise "Unsupported release configuration." unless config.fetch("schema") == 1
|
|
39
|
+
write(render(config))
|
|
40
|
+
end
|
|
41
|
+
|
|
47
42
|
# Native review/check rules allow PR-only administrator bypass; history rules have no bypass.
|
|
48
43
|
def self.rules(config)
|
|
49
44
|
conditions = {ref_name: {include: ["refs/heads/#{config.fetch('branch')}"], exclude: []}}
|
|
@@ -56,6 +51,34 @@ module Bake
|
|
|
56
51
|
"tags" => {name: "Gem release tags", target: "tag", enforcement: "active", bypass_actors: [], conditions: {ref_name: {include: ["refs/tags/v*"], exclude: []}}, rules: [{type: "deletion"}, {type: "non_fast_forward"}]}
|
|
57
52
|
}
|
|
58
53
|
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def write(files)
|
|
58
|
+
files.filter_map do |name, content|
|
|
59
|
+
path = File.join(@root, name)
|
|
60
|
+
next if File.exist?(path) && File.read(path) == content
|
|
61
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
62
|
+
File.write(path, content)
|
|
63
|
+
name
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def render(config)
|
|
68
|
+
branch = config.fetch("branch")
|
|
69
|
+
ruby = config.fetch("ruby")
|
|
70
|
+
signing = config.fetch("signing")
|
|
71
|
+
templates = File.expand_path("../../../../templates", __dir__)
|
|
72
|
+
files = {"config/release.yaml" => YAML.dump(config)}
|
|
73
|
+
Dir.glob("*.erb", base: templates).each do |name|
|
|
74
|
+
files[".github/workflows/#{name.delete_suffix('.erb')}"] = ERB.new(File.read(File.join(templates, name)), trim_mode: "-").result(binding)
|
|
75
|
+
end
|
|
76
|
+
self.class.rules(config).each do |name, rule|
|
|
77
|
+
files[".github/release-rules/#{name}.json"] = JSON.pretty_generate(rule) + "\n"
|
|
78
|
+
end
|
|
79
|
+
files[".github/releasing.md"] = File.read(File.join(templates, "releasing.md"))
|
|
80
|
+
files
|
|
81
|
+
end
|
|
59
82
|
end
|
|
60
83
|
end
|
|
61
84
|
end
|
data/releases.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.1.0
|
|
4
|
+
|
|
5
|
+
- Include the version's release notes in GitHub releases using `bake-releases`.
|
|
6
|
+
- Update generated release files in the working tree with `gem:github:setup:update`.
|
|
7
|
+
|
|
3
8
|
## v0.0.5
|
|
4
9
|
|
|
5
10
|
- Preserve and recover release files even when GitHub's release list is stale.
|
|
@@ -25,12 +25,12 @@ jobs:
|
|
|
25
25
|
if: github.ref == 'refs/heads/<%= branch %>'
|
|
26
26
|
runs-on: ubuntu-latest
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@v7
|
|
29
29
|
with:
|
|
30
30
|
ref: <%= branch %>
|
|
31
31
|
fetch-depth: 0
|
|
32
32
|
persist-credentials: false
|
|
33
|
-
- uses: ruby/setup-ruby@
|
|
33
|
+
- uses: ruby/setup-ruby@v1
|
|
34
34
|
with:
|
|
35
35
|
ruby-version: <%= ruby.to_json %>
|
|
36
36
|
bundler-cache: true
|
|
@@ -39,6 +39,8 @@ jobs:
|
|
|
39
39
|
GH_TOKEN: ${{ github.token }}
|
|
40
40
|
BUMP: ${{ inputs.bump }}
|
|
41
41
|
run: |
|
|
42
|
+
# GitHub.com's shared Actions bot ID; this identity is not for GitHub Enterprise Server.
|
|
43
|
+
# https://github.com/actions/checkout#push-a-commit-using-the-built-in-token
|
|
42
44
|
git config user.name 'github-actions[bot]'
|
|
43
45
|
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
44
46
|
case "$BUMP" in patch|minor|major) ;; *) exit 1 ;; esac
|
|
@@ -27,11 +27,11 @@ jobs:
|
|
|
27
27
|
release: ${{ steps.inspect.outputs.release }}
|
|
28
28
|
commit: ${{ steps.inspect.outputs.commit }}
|
|
29
29
|
steps:
|
|
30
|
-
- uses: actions/checkout@
|
|
30
|
+
- uses: actions/checkout@v7
|
|
31
31
|
with:
|
|
32
32
|
fetch-depth: 0
|
|
33
33
|
persist-credentials: false
|
|
34
|
-
- uses: ruby/setup-ruby@
|
|
34
|
+
- uses: ruby/setup-ruby@v1
|
|
35
35
|
with:
|
|
36
36
|
ruby-version: <%= ruby.to_json %>
|
|
37
37
|
bundler-cache: true
|
|
@@ -52,12 +52,15 @@ jobs:
|
|
|
52
52
|
id-token: write
|
|
53
53
|
attestations: write
|
|
54
54
|
steps:
|
|
55
|
-
- uses: actions/checkout@
|
|
55
|
+
- uses: actions/checkout@v7
|
|
56
56
|
with:
|
|
57
|
+
# Inspection verified this merged commit belongs to the default branch.
|
|
58
|
+
# Checkout v7 also blocks merged fork PRs without this explicit opt-in.
|
|
59
|
+
allow-unsafe-pr-checkout: true
|
|
57
60
|
ref: ${{ needs.inspect.outputs.commit }}
|
|
58
61
|
fetch-depth: 0
|
|
59
62
|
persist-credentials: false
|
|
60
|
-
- uses: ruby/setup-ruby@
|
|
63
|
+
- uses: ruby/setup-ruby@v1
|
|
61
64
|
with:
|
|
62
65
|
ruby-version: <%= ruby.to_json %>
|
|
63
66
|
rubygems: '4.0.21'
|
|
@@ -78,7 +81,7 @@ jobs:
|
|
|
78
81
|
- name: Attest gem and release receipt
|
|
79
82
|
if: steps.build.outputs.restored != 'true'
|
|
80
83
|
id: attest
|
|
81
|
-
uses: actions/attest@
|
|
84
|
+
uses: actions/attest@v4
|
|
82
85
|
with:
|
|
83
86
|
subject-path: |
|
|
84
87
|
${{ steps.build.outputs.package }}
|
|
@@ -90,13 +93,13 @@ jobs:
|
|
|
90
93
|
run: cp "$ATTESTATION_BUNDLE" pkg/provenance.sigstore.json
|
|
91
94
|
- name: Preserve release before upload
|
|
92
95
|
if: steps.build.outputs.restored != 'true'
|
|
93
|
-
uses: actions/upload-artifact@
|
|
96
|
+
uses: actions/upload-artifact@v7
|
|
94
97
|
with:
|
|
95
98
|
name: ${{ steps.build.outputs.artifact }}
|
|
96
99
|
path: pkg/
|
|
97
100
|
if-no-files-found: error
|
|
98
101
|
retention-days: 90
|
|
99
|
-
- uses: rubygems/configure-rubygems-credentials@
|
|
102
|
+
- uses: rubygems/configure-rubygems-credentials@main
|
|
100
103
|
- name: Verify, publish, and finalize
|
|
101
104
|
env:
|
|
102
105
|
GH_TOKEN: ${{ github.token }}
|
|
@@ -15,12 +15,12 @@ jobs:
|
|
|
15
15
|
name: Release validation
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
19
|
with:
|
|
20
20
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
21
21
|
fetch-depth: 0
|
|
22
22
|
persist-credentials: false
|
|
23
|
-
- uses: ruby/setup-ruby@
|
|
23
|
+
- uses: ruby/setup-ruby@v1
|
|
24
24
|
with:
|
|
25
25
|
ruby-version: <%= ruby.to_json %>
|
|
26
26
|
bundler-cache: true
|
data/templates/releasing.md
CHANGED
|
@@ -13,3 +13,5 @@ If a publishing job fails, use **Re-run all jobs** on that same workflow run, or
|
|
|
13
13
|
Verify both the downloaded gem and `release.json` with `gh attestation verify`, enforcing the publishing workflow's certificate identity and default branch ref. Then check the signed receipt's source commit and gem digest; follow the companion gem's setup guide for the complete commands. `--source-digest` checks the workflow revision, which can differ from the release commit. Release assets include the gem, RubyGems Sigstore bundle, GitHub provenance bundle, and signed source/digest receipt.
|
|
14
14
|
|
|
15
15
|
The initial implementation supports public repositories, a single gemspec, stable patch/minor/major versions, and merge/squash commits. Keep rebase merges and merge queues disabled. Generation hooks must be repeatable from the same source and version. Run setup and account recovery checks before enabling publishing; see the companion gem's setup guide.
|
|
16
|
+
|
|
17
|
+
After upgrading `bake-gem-github`, start from a clean working tree and run `bundle exec bake gem:github:setup:update`. It updates generated files without staging or committing them. Review `git diff`, selectively keep changes and restore customizations as needed, then open a PR.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bake-gem-github
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -48,6 +48,20 @@ dependencies:
|
|
|
48
48
|
- - ">="
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
50
|
version: 0.15.0
|
|
51
|
+
- !ruby/object:Gem::Dependency
|
|
52
|
+
name: bake-releases
|
|
53
|
+
requirement: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - "~>"
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0.6'
|
|
58
|
+
type: :runtime
|
|
59
|
+
prerelease: false
|
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - "~>"
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: '0.6'
|
|
51
65
|
- !ruby/object:Gem::Dependency
|
|
52
66
|
name: net-http
|
|
53
67
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
|
Binary file
|