kettle-gha-pins 0.3.9 → 0.3.10
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/CHANGELOG.md +18 -1
- data/README.md +20 -1
- data/lib/kettle/gha/pins/cli.rb +127 -4
- data/lib/kettle/gha/pins/github_client.rb +27 -27
- data/lib/kettle/gha/pins/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +1 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e39d2df910b12d4b40d0978f63481a73d87a5efcdf6ea58c4966b397d3319470
|
|
4
|
+
data.tar.gz: 584ac1b59952635a279806c03aba51460a757e9edd2dbcafc5b7f158b8a302dd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 43c208e30cd0c6501479f4cf52a48a3e4df4b9192ada22b05017681a4761ffe01ca4abdb0398cf8c523828a32814ef9fcd51cf57f2be46f7ff55b81c89e05237
|
|
7
|
+
data.tar.gz: a47e19be556a73215a786b4e9fe23b50ac1890e5087ed0b5eea1a14e8e7f9dd1ce8da62d8e95a329949a6e339aacda9c1b8e12cabd0debe167e301ed12ca96f9
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,21 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [0.3.10] - 2026-08-09
|
|
34
|
+
|
|
35
|
+
- TAG: [v0.3.10][0.3.10t]
|
|
36
|
+
- COVERAGE: 98.08% -- 1022/1042 lines in 8 files
|
|
37
|
+
- BRANCH COVERAGE: 88.03% -- 412/468 branches in 8 files
|
|
38
|
+
- 26.17% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Add JSON action inventory and cache review modes, strict offline pin resolution, and configurable action metadata TTL handling.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Keep JSON action inventory and review parsing compatible with Ruby 2.5.
|
|
47
|
+
|
|
33
48
|
## [0.3.9] - 2026-08-05
|
|
34
49
|
|
|
35
50
|
- TAG: [v0.3.9][0.3.9t]
|
|
@@ -282,7 +297,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
282
297
|
- kettle-jem-template-20260720-005 - Generated README Support & Community rows
|
|
283
298
|
now include a RubyForum help badge.
|
|
284
299
|
|
|
285
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.
|
|
300
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.10...HEAD
|
|
301
|
+
[0.3.10]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.9...v0.3.10
|
|
302
|
+
[0.3.10t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.10
|
|
286
303
|
[0.3.9]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.8...v0.3.9
|
|
287
304
|
[0.3.9t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.9
|
|
288
305
|
[0.3.8]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.7...v0.3.8
|
data/README.md
CHANGED
|
@@ -155,6 +155,17 @@ cooldown window. The same default can be supplied with
|
|
|
155
155
|
`KETTLE_GHA_PINS_COOLDOWN_DAYS`. The default is `0`, so checks remain strict
|
|
156
156
|
unless a project opts into a warning window.
|
|
157
157
|
|
|
158
|
+
The action metadata cache uses a one-day TTL by default. Set `--ttl DAYS` to
|
|
159
|
+
change it; `--ttl 0` forces a refresh. `--offline` trusts the cache without
|
|
160
|
+
checking TTL or contacting GitHub and fails if required repository metadata is
|
|
161
|
+
missing.
|
|
162
|
+
|
|
163
|
+
For family orchestration, `kettle-gha-pins --list --json` emits the action
|
|
164
|
+
repositories used by a project without network access. A separate
|
|
165
|
+
`kettle-gha-pins --review --input PATH` refreshes the repositories listed in
|
|
166
|
+
that JSON and updates the shared cache. Review refreshes metadata independently
|
|
167
|
+
of the selected major/minor/patch upgrade policy.
|
|
168
|
+
|
|
158
169
|
`Kettle::Gha::Pins::PersistentActionCache.default_path` intentionally preserves
|
|
159
170
|
the historical `kettle-gha-sha-pins` cache location so command-line tools can
|
|
160
171
|
share action metadata without coupling to each other.
|
|
@@ -188,6 +199,14 @@ plan[:updates]
|
|
|
188
199
|
# => {sha: "...", version: "7.0.0", reason: "upgrade_to_allowed_release"}
|
|
189
200
|
```
|
|
190
201
|
|
|
202
|
+
The family-oriented cache workflow is:
|
|
203
|
+
|
|
204
|
+
```console
|
|
205
|
+
kettle-gha-pins --list --json
|
|
206
|
+
kettle-gha-pins --review --input pins.json
|
|
207
|
+
kettle-gha-pins --offline --write --upgrade major
|
|
208
|
+
```
|
|
209
|
+
|
|
191
210
|
When two version-equivalent tags point at the same SHA, the rubric keeps the
|
|
192
211
|
more explicit release spelling. For example, `v7` and `v7.0.0` pointing at the
|
|
193
212
|
same commit canonicalize to `v7.0.0`; if they point at different SHAs, both
|
|
@@ -563,7 +582,7 @@ Thanks for RTFM. ☺️
|
|
|
563
582
|
[📌gitmoji]: https://gitmoji.dev
|
|
564
583
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
565
584
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
566
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-
|
|
585
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-1.042-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
567
586
|
[🔐security]: https://github.com/kettle-dev/kettle-gha-pins/blob/main/SECURITY.md
|
|
568
587
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
569
588
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/lib/kettle/gha/pins/cli.rb
CHANGED
|
@@ -67,9 +67,13 @@ module Kettle
|
|
|
67
67
|
user_agent: "kettle-gha-pins",
|
|
68
68
|
upgrade: DEFAULT_UPGRADE_LEVEL,
|
|
69
69
|
cache_path: ENV["KETTLE_GHA_SHA_PINS_CACHE"] || PersistentActionCache.default_path,
|
|
70
|
+
ttl_days: DEFAULT_CACHE_TTL_SECONDS / 86_400.0,
|
|
70
71
|
cooldown_days: cooldown_days,
|
|
71
72
|
clock: clock,
|
|
72
73
|
refresh_cache: false,
|
|
74
|
+
offline: false,
|
|
75
|
+
mode: :project,
|
|
76
|
+
input: nil,
|
|
73
77
|
reject_patterns: Set.new,
|
|
74
78
|
progress: nil
|
|
75
79
|
}
|
|
@@ -78,20 +82,43 @@ module Kettle
|
|
|
78
82
|
def run!
|
|
79
83
|
parse!
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
return list_workflows! if @options[:mode] == :list
|
|
86
|
+
|
|
87
|
+
client, persistent_cache = build_client
|
|
88
|
+
return review_cache!(client: client, persistent_cache: persistent_cache) if @options[:mode] == :review
|
|
89
|
+
|
|
90
|
+
run_project!(client: client)
|
|
91
|
+
rescue Error, GitHubClient::CacheMissError, GitHubClient::RefreshError => error
|
|
92
|
+
@err.puts("kettle-gha-pins: #{error.message}")
|
|
93
|
+
2
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def build_client
|
|
99
|
+
@options[:token] ||= gh_auth_token if @options[:api_base] == API_BASE && !@options[:offline]
|
|
82
100
|
persistent_cache = if @options[:cache_path].to_s.empty?
|
|
83
101
|
nil
|
|
84
102
|
else
|
|
85
|
-
PersistentActionCache.new(
|
|
103
|
+
PersistentActionCache.new(
|
|
104
|
+
path: @options[:cache_path],
|
|
105
|
+
ttl_seconds: (@options[:ttl_days] * 86_400).to_i,
|
|
106
|
+
clock: @options[:clock]
|
|
107
|
+
)
|
|
86
108
|
end
|
|
87
109
|
client = GitHubClient.new(
|
|
88
110
|
token: @options[:token],
|
|
89
111
|
api_base: @options[:api_base],
|
|
90
112
|
user_agent: @options[:user_agent],
|
|
91
113
|
persistent_cache: persistent_cache,
|
|
92
|
-
refresh_cache: @options[:refresh_cache]
|
|
114
|
+
refresh_cache: @options[:refresh_cache],
|
|
115
|
+
offline: @options[:offline],
|
|
116
|
+
fail_on_refresh_error: @options[:mode] == :review
|
|
93
117
|
)
|
|
118
|
+
[client, persistent_cache]
|
|
119
|
+
end
|
|
94
120
|
|
|
121
|
+
def run_project!(client:)
|
|
95
122
|
state = {
|
|
96
123
|
files_scanned: 0,
|
|
97
124
|
files_with_changes: 0,
|
|
@@ -293,7 +320,79 @@ module Kettle
|
|
|
293
320
|
0
|
|
294
321
|
end
|
|
295
322
|
|
|
296
|
-
|
|
323
|
+
def list_workflows!
|
|
324
|
+
state = {files_scanned: 0, failures: 0, errors: []}
|
|
325
|
+
workflow_files = discover_workflow_files(@options[:root], @options[:reject_patterns])
|
|
326
|
+
workflows = load_workflows(workflow_files, state)
|
|
327
|
+
pins = workflows.flat_map do |workflow|
|
|
328
|
+
workflow.fetch(:uses_nodes).each_with_object([]) do |node, entries|
|
|
329
|
+
parsed = classify_action_ref(node[:value].to_s)
|
|
330
|
+
next unless parsed
|
|
331
|
+
|
|
332
|
+
action = parsed.fetch(:action)
|
|
333
|
+
entries << {
|
|
334
|
+
"repository" => "#{action[:owner]}/#{action[:repo]}",
|
|
335
|
+
"ref" => action[:ref],
|
|
336
|
+
"value" => parsed[:value],
|
|
337
|
+
"path" => workflow[:path],
|
|
338
|
+
"line" => node[:line].to_i + 1
|
|
339
|
+
}
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
repositories = pins.map { |pin| pin.fetch("repository") }.uniq.sort
|
|
343
|
+
puts JSON.pretty_generate(
|
|
344
|
+
"schema_version" => 1,
|
|
345
|
+
"root" => @options[:root],
|
|
346
|
+
"repositories" => repositories,
|
|
347
|
+
"pins" => pins
|
|
348
|
+
)
|
|
349
|
+
state[:failures].zero? ? 0 : 2
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def review_cache!(client:, persistent_cache:)
|
|
353
|
+
raise Error, "--review requires a writable cache; do not use --cache-path \"\"" unless persistent_cache
|
|
354
|
+
|
|
355
|
+
repositories = review_repositories
|
|
356
|
+
refreshed = repositories.map do |repository|
|
|
357
|
+
versions = client.versions_for_repo(repository)
|
|
358
|
+
{
|
|
359
|
+
"repository" => repository,
|
|
360
|
+
"versions" => versions.length,
|
|
361
|
+
"cache" => client.last_versions_cache_hit ? "hit" : "refreshed"
|
|
362
|
+
}
|
|
363
|
+
end
|
|
364
|
+
puts JSON.pretty_generate(
|
|
365
|
+
"schema_version" => 1,
|
|
366
|
+
"mode" => "review",
|
|
367
|
+
"ttl_days" => @options[:ttl_days],
|
|
368
|
+
"repositories" => refreshed
|
|
369
|
+
)
|
|
370
|
+
0
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
def review_repositories
|
|
374
|
+
source = @options[:input].to_s
|
|
375
|
+
source = if source.empty? || source == "-"
|
|
376
|
+
$stdin.read
|
|
377
|
+
else
|
|
378
|
+
File.read(source)
|
|
379
|
+
end
|
|
380
|
+
payload = JSON.parse(source)
|
|
381
|
+
entries = if payload.is_a?(Array)
|
|
382
|
+
payload
|
|
383
|
+
elsif payload.is_a?(Hash)
|
|
384
|
+
payload["repositories"] || payload["actions"] || payload["pins"] || []
|
|
385
|
+
else
|
|
386
|
+
[]
|
|
387
|
+
end
|
|
388
|
+
entries.each_with_object([]) do |entry, repositories|
|
|
389
|
+
value = entry.is_a?(Hash) ? (entry["repository"] || entry["action"] || entry["value"]) : entry
|
|
390
|
+
repository = value.to_s.split("@", 2).first
|
|
391
|
+
repositories << repository if repository.match?(%r{\A[^/\s]+/[^/\s]+\z})
|
|
392
|
+
end.uniq.sort
|
|
393
|
+
rescue JSON::ParserError => error
|
|
394
|
+
raise Error, "invalid review JSON: #{error.message}"
|
|
395
|
+
end
|
|
297
396
|
|
|
298
397
|
def parse!
|
|
299
398
|
parser = OptionParser.new do |opt|
|
|
@@ -328,6 +427,27 @@ module Kettle
|
|
|
328
427
|
opt.on("--refresh-cache", "Bypass cached action release data and refresh discovered actions") do
|
|
329
428
|
@options[:refresh_cache] = true
|
|
330
429
|
end
|
|
430
|
+
opt.on("--ttl DAYS", Float, "Cache TTL in days (default: #{@options[:ttl_days]})") do |days|
|
|
431
|
+
Kernel.abort("Invalid --ttl value #{days.inspect}; use a non-negative number") if days.negative?
|
|
432
|
+
|
|
433
|
+
@options[:ttl_days] = days
|
|
434
|
+
end
|
|
435
|
+
opt.on("--offline", "Use only the persistent cache; fail on a cache miss") do
|
|
436
|
+
@options[:offline] = true
|
|
437
|
+
end
|
|
438
|
+
opt.on("--list", "List project action pins as JSON without network access") do
|
|
439
|
+
raise OptionParser::InvalidOption, "--list cannot be combined with --review" if @options[:mode] == :review
|
|
440
|
+
|
|
441
|
+
@options[:mode] = :list
|
|
442
|
+
end
|
|
443
|
+
opt.on("--review", "Refresh action metadata from JSON input and update the cache") do
|
|
444
|
+
raise OptionParser::InvalidOption, "--review cannot be combined with --list" if @options[:mode] == :list
|
|
445
|
+
|
|
446
|
+
@options[:mode] = :review
|
|
447
|
+
end
|
|
448
|
+
opt.on("--input PATH", "Review JSON input path, or - for stdin") do |path|
|
|
449
|
+
@options[:input] = path
|
|
450
|
+
end
|
|
331
451
|
opt.on("--cache-path PATH", "Action release cache path (default: #{@options[:cache_path]})") do |path|
|
|
332
452
|
@options[:cache_path] = path
|
|
333
453
|
end
|
|
@@ -356,6 +476,9 @@ module Kettle
|
|
|
356
476
|
end
|
|
357
477
|
end
|
|
358
478
|
parser.parse!(@argv)
|
|
479
|
+
if @options[:mode] == :review && @options[:offline]
|
|
480
|
+
raise OptionParser::InvalidOption, "--review cannot be combined with --offline"
|
|
481
|
+
end
|
|
359
482
|
end
|
|
360
483
|
|
|
361
484
|
def display_path(path)
|
|
@@ -10,12 +10,17 @@ module Kettle
|
|
|
10
10
|
module Pins
|
|
11
11
|
# Lightweight GitHub API client for commit and release SHA resolution.
|
|
12
12
|
class GitHubClient
|
|
13
|
-
|
|
13
|
+
class CacheMissError < Error; end
|
|
14
|
+
class RefreshError < Error; end
|
|
15
|
+
|
|
16
|
+
def initialize(token:, api_base:, user_agent:, persistent_cache: nil, refresh_cache: false, offline: false, fail_on_refresh_error: false, open_timeout: DEFAULT_HTTP_OPEN_TIMEOUT_SECONDS, read_timeout: DEFAULT_HTTP_READ_TIMEOUT_SECONDS, refresh_timeout: DEFAULT_HTTP_REFRESH_TIMEOUT_SECONDS)
|
|
14
17
|
@token = token
|
|
15
18
|
@api_base = api_base
|
|
16
19
|
@user_agent = user_agent
|
|
17
20
|
@persistent_cache = persistent_cache
|
|
18
21
|
@refresh_cache = refresh_cache
|
|
22
|
+
@offline = offline
|
|
23
|
+
@fail_on_refresh_error = fail_on_refresh_error
|
|
19
24
|
@open_timeout = open_timeout
|
|
20
25
|
@read_timeout = read_timeout
|
|
21
26
|
@refresh_timeout = refresh_timeout
|
|
@@ -34,15 +39,22 @@ module Kettle
|
|
|
34
39
|
return @release_cache[repo_ref]
|
|
35
40
|
end
|
|
36
41
|
|
|
42
|
+
if @offline
|
|
43
|
+
cached = @persistent_cache&.versions_for_repo(repo_ref, fresh: false)
|
|
44
|
+
raise CacheMissError, "offline cache miss for #{repo_ref}" if cached.nil?
|
|
45
|
+
|
|
46
|
+
@last_versions_cache_hit = true
|
|
47
|
+
@release_cache[repo_ref] = cached
|
|
48
|
+
return cached
|
|
49
|
+
end
|
|
50
|
+
|
|
37
51
|
stale = nil
|
|
38
52
|
unless @refresh_cache
|
|
39
53
|
cached = @persistent_cache&.versions_for_repo(repo_ref, fresh: true)
|
|
40
54
|
if cached
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return cached
|
|
45
|
-
end
|
|
55
|
+
@last_versions_cache_hit = true
|
|
56
|
+
@release_cache[repo_ref] = cached
|
|
57
|
+
return cached
|
|
46
58
|
end
|
|
47
59
|
stale = @persistent_cache&.versions_for_repo(repo_ref, fresh: false)
|
|
48
60
|
end
|
|
@@ -50,10 +62,10 @@ module Kettle
|
|
|
50
62
|
releases = nil
|
|
51
63
|
Timeout.timeout(@refresh_timeout) do
|
|
52
64
|
data = request_json("/repos/#{repo_ref}/releases?per_page=100")
|
|
53
|
-
return
|
|
65
|
+
return refresh_failed!(repo_ref, stale, "invalid releases response") unless data.is_a?(Array)
|
|
54
66
|
|
|
55
67
|
tag_shas = tag_ref_shas(repo_ref)
|
|
56
|
-
return
|
|
68
|
+
return refresh_failed!(repo_ref, stale, "invalid tag response") unless tag_shas
|
|
57
69
|
|
|
58
70
|
releases = build_release_versions(data, tag_shas)
|
|
59
71
|
end
|
|
@@ -61,7 +73,7 @@ module Kettle
|
|
|
61
73
|
@release_cache[repo_ref] = releases
|
|
62
74
|
releases
|
|
63
75
|
rescue Timeout::Error
|
|
64
|
-
|
|
76
|
+
refresh_failed!(repo_ref, stale, "GitHub refresh timed out")
|
|
65
77
|
end
|
|
66
78
|
|
|
67
79
|
def commit_sha(repo_ref, ref, refresh: false)
|
|
@@ -71,13 +83,15 @@ module Kettle
|
|
|
71
83
|
return @commit_cache[cache_key] if @commit_cache.key?(cache_key) && !refresh
|
|
72
84
|
|
|
73
85
|
unless @refresh_cache || refresh
|
|
74
|
-
cached = @persistent_cache&.ref_sha(repo_ref, ref, fresh:
|
|
86
|
+
cached = @persistent_cache&.ref_sha(repo_ref, ref, fresh: !@offline)
|
|
75
87
|
if cached
|
|
76
88
|
@commit_cache[cache_key] = cached
|
|
77
89
|
return cached
|
|
78
90
|
end
|
|
79
91
|
end
|
|
80
92
|
|
|
93
|
+
raise CacheMissError, "offline cache miss for #{repo_ref}@#{ref}" if @offline
|
|
94
|
+
|
|
81
95
|
data = request_json("/repos/#{repo_ref}/commits/#{uri_encode(ref)}")
|
|
82
96
|
sha = if data.is_a?(Hash)
|
|
83
97
|
data.fetch("sha", "")[0, 40]
|
|
@@ -106,24 +120,10 @@ module Kettle
|
|
|
106
120
|
versions
|
|
107
121
|
end
|
|
108
122
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
# only when that probe identifies a tag or target the cache lacks.
|
|
112
|
-
def cache_requires_refresh?(repo_ref, cached)
|
|
113
|
-
latest = request_json("/repos/#{repo_ref}/releases/latest")
|
|
114
|
-
return false unless latest.is_a?(Hash)
|
|
115
|
-
|
|
116
|
-
tag = latest["tag_name"].to_s
|
|
117
|
-
return false unless VersionRubric.parse(tag)
|
|
118
|
-
|
|
119
|
-
cached_entry = cached.find { |entry| entry[:tag].to_s == tag }
|
|
120
|
-
return true unless cached_entry
|
|
121
|
-
|
|
122
|
-
latest_sha = commit_sha(repo_ref, tag, refresh: true)
|
|
123
|
-
cached_sha = cached_entry[:sha].to_s
|
|
124
|
-
return !latest_sha.to_s.empty? if cached_sha.empty?
|
|
123
|
+
def refresh_failed!(repo_ref, stale, message)
|
|
124
|
+
return cached_versions(repo_ref, stale) unless @fail_on_refresh_error
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
raise RefreshError, "#{message} for #{repo_ref}"
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
def build_release_versions(data, tag_shas)
|
|
@@ -6,7 +6,7 @@ module Kettle
|
|
|
6
6
|
# Version namespace for this gem.
|
|
7
7
|
module Version
|
|
8
8
|
# Current gem version.
|
|
9
|
-
VERSION = "0.3.
|
|
9
|
+
VERSION = "0.3.10"
|
|
10
10
|
end
|
|
11
11
|
# Current gem version exposed at the traditional constant location.
|
|
12
12
|
VERSION = Version::VERSION # Traditional Constant Location
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-gha-pins
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -301,10 +301,10 @@ licenses:
|
|
|
301
301
|
- MIT
|
|
302
302
|
metadata:
|
|
303
303
|
homepage_uri: https://github.com/kettle-dev/kettle-gha-pins
|
|
304
|
-
source_code_uri: https://github.com/kettle-dev/kettle-gha-pins/tree/v0.3.
|
|
305
|
-
changelog_uri: https://github.com/kettle-dev/kettle-gha-pins/blob/v0.3.
|
|
304
|
+
source_code_uri: https://github.com/kettle-dev/kettle-gha-pins/tree/v0.3.10
|
|
305
|
+
changelog_uri: https://github.com/kettle-dev/kettle-gha-pins/blob/v0.3.10/CHANGELOG.md
|
|
306
306
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-gha-pins/issues
|
|
307
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-gha-pins/0.3.
|
|
307
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-gha-pins/0.3.10
|
|
308
308
|
funding_uri: https://github.com/sponsors/pboling
|
|
309
309
|
wiki_uri: https://github.com/kettle-dev/kettle-gha-pins/wiki
|
|
310
310
|
news_uri: https://www.railsbling.com/tags/kettle-gha-pins
|
metadata.gz.sig
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
@[5A
|
|
1
|
+
���8����)Dz-P��k�0��W��[Xq�{j�)9܉��m��Ԥ=oh��[���+��A�)�G�oQ[�̆��v�vw�&�n���CM�^�q��0����pc�_�rO������G6mċF�@z]m�@CJ�&�L��v���
|