discharger 0.3.4 → 0.3.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25a6ab71ff65d9ada8fe82ce0a706b08d335aaa533b10c1b57a652434149cd91
4
- data.tar.gz: 524b68d60300a017c7d83bc7162f1962819b44f1be1255ec1fd8651b47740374
3
+ metadata.gz: 97070aca58c88a6f43e34f7d45bec964122a6db867e9bd5333988a082bb41d47
4
+ data.tar.gz: 0f39ea2c1136914a33666593af2bdaeed6f358a34364f9ffcb9b1557976c3fae
5
5
  SHA512:
6
- metadata.gz: 7b67aaf1127f81ca25f3f4f78ce3fc5884920048baa022128b46dfa24e4ab01dee3b4574894d7e3305026cdfc7eb4659351b3cf649dc509e2d8c76982207bf01
7
- data.tar.gz: 894a03d8fd806db6d0c831a1c47191332aa5cae0ab02fdf7709a040cab2e50f9e8a2ee02030d6e5015bfe2ab03d8a5e7ae806d6e79e9f0fe3f020a8f2cdc8a75
6
+ metadata.gz: 617ed8ed6727d1e1817e7859ce8121553399bd1ec0c5c70b2002d93eb0273915e112d5b30d6ba2e045e18ff0b4fd1bf075cc78d0000f0b8abdc360102d14cb0c
7
+ data.tar.gz: d8470a667ff24259e5efc590ad63fb7be3884e31ce3e35a5e3b8d22fdb3a399fe4948b3e8e465d2b4aee34e24e2ef25fce86453a041083abb6947b6b3454d7f7
data/CHANGELOG.md CHANGED
@@ -5,14 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/).
7
7
 
8
- ## [0.3.4] - 2026-07-22
8
+ ## [0.3.5] - 2026-08-10
9
9
 
10
10
  ### Added
11
11
 
12
- - Runbook announcement on stage builds, previewing post-release steps before production (c77b552)
12
+ - github_packages setup step storing bundler credentials for a private GitHub Packages gem source via the gh CLI (2cff4b6)
13
13
 
14
- ## [0.3.3] - 2026-07-22
14
+ ## [0.3.4] - 2026-07-22
15
15
 
16
16
  ### Added
17
17
 
18
- - Post-release runbook announcement in the Slack release thread, from Reissue's runbook_file (0cf9620)
18
+ - Runbook announcement on stage builds, previewing post-release steps before production (c77b552)
data/README.md CHANGED
@@ -274,6 +274,7 @@ The `steps` array specifies which built-in setup commands to run. Available comm
274
274
  - `brew` - Install Homebrew dependencies
275
275
  - `asdf` - Setup version management with asdf
276
276
  - `git` - Configure git settings
277
+ - `github_packages` - Store bundler credentials for a private GitHub Packages gem source using the GitHub CLI (run before `bundler`; requires a `github_packages.source` config entry)
277
278
  - `bundler` - Install Ruby gems
278
279
  - `yarn` - Install JavaScript packages
279
280
  - `config` - Copy configuration files
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_command"
4
+
5
+ module Discharger
6
+ module SetupRunner
7
+ module Commands
8
+ # Stores bundler credentials for a private GitHub Packages gem source
9
+ # using the GitHub CLI, so Gemfiles don't need embedded tokens.
10
+ # Credentials are written to the app's .bundle/config — keep .bundle
11
+ # gitignored. Run this step before "bundler" in setup.yml.
12
+ class GithubPackagesCommand < BaseCommand
13
+ def execute
14
+ unless gh_installed?
15
+ log "GitHub CLI (gh) not found; skipping. Install gh and rerun setup or `bundle install` may fail for #{source}"
16
+ return
17
+ end
18
+
19
+ unless authenticated? || login
20
+ log "Not logged in to GitHub; skipping. Run `gh auth login` and rerun setup."
21
+ return
22
+ end
23
+
24
+ username = gh("api", "user", "--jq", ".login")
25
+ token = gh("auth", "token")
26
+ if username.to_s.empty? || token.to_s.empty?
27
+ log "Could not read GitHub credentials from gh; skipping."
28
+ return
29
+ end
30
+
31
+ store_bundler_credentials(username, token)
32
+ if credentials_valid?(username, token)
33
+ log "Configured bundler credentials for #{source}"
34
+ else
35
+ log "#{source} rejected the stored credentials. Your gh token may lack " \
36
+ "the read:packages scope — run `gh auth refresh -s read:packages` and rerun setup."
37
+ end
38
+ end
39
+
40
+ def can_execute?
41
+ !source.to_s.empty?
42
+ end
43
+
44
+ def description
45
+ "Configure GitHub Packages credentials"
46
+ end
47
+
48
+ protected
49
+
50
+ def source
51
+ config.github_packages&.source if config.respond_to?(:github_packages)
52
+ end
53
+
54
+ def gh_installed?
55
+ system_quiet("which gh")
56
+ end
57
+
58
+ def authenticated?
59
+ system_quiet("gh auth status")
60
+ end
61
+
62
+ def login
63
+ return false unless $stdin.tty?
64
+ log "Logging in to GitHub..."
65
+ system("gh", "auth", "login")
66
+ authenticated?
67
+ end
68
+
69
+ def gh(*args)
70
+ require "open3"
71
+ stdout, _stderr, status = Open3.capture3("gh", *args)
72
+ status.success? ? stdout.chomp : nil
73
+ end
74
+
75
+ # Runs bundle config directly instead of through system! so the
76
+ # token never reaches the spinner display or the debug log.
77
+ def store_bundler_credentials(username, token)
78
+ require "open3"
79
+ _stdout, stderr, status = Open3.capture3(
80
+ "bundle", "config", "set", "--local", source, "#{username}:#{token}"
81
+ )
82
+ raise "bundle config set --local #{source} failed: #{stderr}" unless status.success?
83
+ end
84
+
85
+ # Probes the source's compact index with the stored credentials.
86
+ # Only a definite 401/403 counts as invalid — network trouble must
87
+ # not fail setup over an unverifiable token.
88
+ def credentials_valid?(username, token)
89
+ require "net/http"
90
+ require "uri"
91
+ uri = URI.join("#{source.chomp("/")}/", "versions")
92
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https",
93
+ open_timeout: 5, read_timeout: 10) do |http|
94
+ request = Net::HTTP::Get.new(uri)
95
+ request.basic_auth(username, token)
96
+ http.request(request)
97
+ end
98
+ !%w[401 403].include?(response.code)
99
+ rescue => e
100
+ logger&.debug("Could not verify GitHub Packages credentials: #{e.message}")
101
+ true
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -5,12 +5,13 @@ require "yaml"
5
5
  module Discharger
6
6
  module SetupRunner
7
7
  class Configuration
8
- attr_accessor :app_name, :database, :redis, :services, :steps, :custom_steps, :pre_steps
8
+ attr_accessor :app_name, :database, :redis, :github_packages, :services, :steps, :custom_steps, :pre_steps
9
9
 
10
10
  def initialize
11
11
  @app_name = "Application"
12
12
  @database = DatabaseConfig.new
13
13
  @redis = nil
14
+ @github_packages = nil
14
15
  @services = []
15
16
  @steps = []
16
17
  @custom_steps = []
@@ -27,6 +28,7 @@ module Discharger
27
28
  config.app_name = yaml["app_name"] if yaml["app_name"]
28
29
  config.database.from_hash(yaml["database"]) if yaml["database"]
29
30
  config.redis = RedisConfig.new.tap { |r| r.from_hash(yaml["redis"]) } if yaml["redis"]
31
+ config.github_packages = GithubPackagesConfig.new.tap { |g| g.from_hash(yaml["github_packages"]) } if yaml["github_packages"]
30
32
  config.services = yaml["services"] || []
31
33
  config.steps = yaml["steps"] || []
32
34
  config.custom_steps = yaml["custom_steps"] || []
@@ -56,6 +58,18 @@ module Discharger
56
58
  end
57
59
  end
58
60
 
61
+ class GithubPackagesConfig
62
+ attr_accessor :source
63
+
64
+ def initialize
65
+ @source = nil
66
+ end
67
+
68
+ def from_hash(hash)
69
+ @source = hash["source"] if hash["source"]
70
+ end
71
+ end
72
+
59
73
  class RedisConfig
60
74
  attr_accessor :port, :name, :version
61
75
 
@@ -1,3 +1,3 @@
1
1
  module Discharger
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  end
@@ -18,6 +18,14 @@ redis:
18
18
  name: "redis-your-app"
19
19
  version: "latest"
20
20
 
21
+ # Private GitHub Packages gem source (optional)
22
+ # Stores bundler credentials from the GitHub CLI (gh) so the Gemfile
23
+ # doesn't need an embedded token. Add "github_packages" to steps, before
24
+ # "bundler". Credentials are written to .bundle/config — keep .bundle
25
+ # gitignored.
26
+ # github_packages:
27
+ # source: "https://rubygems.pkg.github.com/your-org"
28
+
21
29
  # Pre-Rails steps (run BEFORE Rails loads)
22
30
  # These are for system dependencies and environment setup that must happen
23
31
  # before bundler/Rails can initialize. Use sparingly.
@@ -36,7 +44,7 @@ pre_steps: []
36
44
  # - postgresql_tools # Optional: for apps that use structure.sql or pg_dump/psql directly
37
45
 
38
46
  # Built-in commands to run (empty array runs all available commands)
39
- # Available commands: brew, asdf, git, bundler, yarn, config, docker, pg_tools, env, database
47
+ # Available commands: brew, asdf, git, github_packages, bundler, yarn, config, docker, pg_tools, env, database
40
48
  steps:
41
49
  - brew
42
50
  - asdf
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discharger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
@@ -122,6 +122,7 @@ files:
122
122
  - lib/discharger/setup_runner/commands/docker_command.rb
123
123
  - lib/discharger/setup_runner/commands/env_command.rb
124
124
  - lib/discharger/setup_runner/commands/git_command.rb
125
+ - lib/discharger/setup_runner/commands/github_packages_command.rb
125
126
  - lib/discharger/setup_runner/commands/pg_tools_command.rb
126
127
  - lib/discharger/setup_runner/commands/yarn_command.rb
127
128
  - lib/discharger/setup_runner/condition_evaluator.rb