Class: Kettle::Family::Workflow

Inherits:
Object
  • Object
show all
Defined in:
lib/kettle/family/workflow.rb

Defined Under Namespace

Classes: PreflightProgressMember

Constant Summary collapse

DEFAULT_COMMANDS =
{
  # kettle-jem owns the member bundle bootstrap, so it must not be
  # launched through that bundle. The standalone executable prepares the
  # templating dependencies before the member bundle can include them.
  "template" => "kettle-jem install",
  "test" => "bundle exec kettle-test",
  "lint" => "bundle exec rake rubocop_gradual",
  "docs" => "bundle exec rake yard",
  "gha-sha-pins" => "bundle exec kettle-gha-pins",
  "sync" => [
    "sh",
    "-lc",
    "      set -e\n      current_branch=$(git branch --show-current)\n      if [ -z \"$current_branch\" ]; then\n        echo \"kettle-family sync requires a named branch checkout\" >&2\n        exit 1\n      fi\n      default_ref=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true)\n      default_branch=${default_ref#origin/}\n      if [ -z \"$default_branch\" ] || [ \"$default_branch\" = \"$default_ref\" ]; then\n        default_branch=$(git remote show origin | awk '/HEAD branch:/ { print $NF; exit }')\n      fi\n      if [ -z \"$default_branch\" ]; then\n        echo \"could not determine origin default branch\" >&2\n        exit 1\n      fi\n      git fetch origin \"$default_branch\"\n      if [ \"$current_branch\" != \"$default_branch\" ]; then\n        git switch \"$default_branch\"\n      fi\n      git rebase \"origin/$default_branch\"\n      if [ \"$current_branch\" != \"$default_branch\" ]; then\n        git switch \"$current_branch\"\n        git rebase \"$default_branch\"\n      fi\n    SH\n  ],\n  \"bupb\" => %w[bundle update --bundler]\n}.freeze\n"
TEMPLATE_AUTOSTASH_ALLOWED_DIRECTORIES =
%w[lib spec test].freeze
TEMPLATE_MANAGED_DIRTY_PATH_PATTERN =
%r{(?:\A|/)(?:Gemfile\.lock|Appraisal\.root\.gemfile\.lock|\.structuredmerge/kettle-jem\.lock|gemfiles/modular/[^/]+_local\.gemfile)\z}
PRE_TEMPLATE_BOOTSTRAP_GEMS =
%w[nomono kettle-dev].freeze
GIT_SYNC_COMMANDS =
{
  "push" => [["push", %w[git push]]],
  "pull" => [["pull", %w[git pull --rebase]]],
  "up" => [["pull", %w[git pull --rebase]], ["push", %w[git push]]]
}.freeze
TEMPLATE_QUIET_ENV =
{
  "KETTLE_JEM_QUIET" => "true",
  "KETTLE_JEM_DEBUG" => "false",
  "KETTLE_DEV_DEBUG" => "false",
  "STRUCTUREDMERGE_DEBUG" => "false",
  "DEBUG" => nil,
  "BUNDLE_QUIET" => "true",
  "BUNDLE_DEBUG" => "false",
  "BUNDLER_DEBUG" => "false",
  "BUNDLE_VERBOSE" => "false",
  "DEBUG_RESOLVER" => nil,
  "DEBUG_RESOLVER_TREE" => nil,
  "BUNDLER_DEBUG_RESOLVER" => nil,
  "BUNDLER_DEBUG_RESOLVER_TREE" => nil,
  "DEBUG_COMPACT_INDEX" => nil,
  "MOLINILLO_DEBUG" => nil,
  "BUNDLE_SILENCE_DEPRECATIONS" => "true",
  "BUNDLE_SILENCE_ROOT_WARNING" => "true",
  "BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES" => "true"
}.freeze
RESET_LOCKFILE_HELPER =
"require \"bundler/inline\"\n\nsource_url = ENV.fetch(\"KETTLE_FAMILY_RESET_GEM_SOURCE\", \"https://gem.coop\")\nkettle_dev_version = ENV[\"KETTLE_FAMILY_RESET_KETTLE_DEV_VERSION\"].to_s\n\ngemfile(true) do\n  source source_url\n  if kettle_dev_version.empty?\n    gem \"kettle-dev\"\n  else\n    gem \"kettle-dev\", kettle_dev_version\n  end\nend\n\nload Gem.bin_path(\"kettle-dev\", \"kettle-reset\")\n"
REGISTRY_WAIT_ATTEMPTS =
15
REGISTRY_WAIT_INTERVAL_SECONDS =
15

Instance Method Summary collapse

Constructor Details

#initialize(command:, config:, members:, family_members: nil, execute: false, accept: true, commit: true, allow_dirty: false, autostash: true, template_cleanup: true, publish: false, push: false, tag: false, start_step: nil, skip_steps: nil, fast_recovery: nil, fast_recovery_members: nil, skip_ci: false, skip_changelog: false, skip_appraisals: false, local_ci: false, continue_ci_failures: false, ci_workflows: nil, skip_bundle_audit: false, skip_remotes: nil, required_remotes: nil, auto_dependency_floors: nil, validate_ci_bundles: nil, gha_sha_pins_upgrade: "patch", gha_sha_pins_check: false, gha_sha_pins_ttl_days: nil, env_overrides: {}, debug: false, verbose: false, gem_signing_password: nil, secrets_provider: nil, jobs: nil, progress_io: nil, reset_target: nil, bup_args: [], bex_args: [], start_member: nil, start_branch: nil, release_state_results: nil, **options) ⇒ Workflow

Returns a new instance of Workflow.

Raises:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/kettle/family/workflow.rb', line 112

def initialize(command:, config:, members:, family_members: nil, execute: false, accept: true, commit: true, allow_dirty: false, autostash: true, template_cleanup: true, publish: false, push: false, tag: false, start_step: nil, skip_steps: nil, fast_recovery: nil, fast_recovery_members: nil, skip_ci: false, skip_changelog: false, skip_appraisals: false, local_ci: false, continue_ci_failures: false, ci_workflows: nil, skip_bundle_audit: false, skip_remotes: nil, required_remotes: nil, auto_dependency_floors: nil, validate_ci_bundles: nil, gha_sha_pins_upgrade: "patch", gha_sha_pins_check: false, gha_sha_pins_ttl_days: nil, env_overrides: {}, debug: false, verbose: false, gem_signing_password: nil, secrets_provider: nil, jobs: nil, progress_io: nil, reset_target: nil, bup_args: [], bex_args: [], start_member: nil, start_branch: nil, release_state_results: nil, **options)
  @command = command
  @config = config
  @members = members
  @family_members = family_members || members
  @execute = execute
  @accept = accept
  @commit = commit
  @allow_dirty = allow_dirty
  @autostash = autostash
  @template_cleanup = template_cleanup
  @publish = publish
  @push = push
  @tag = tag
  @start_step = start_step
  @skip_steps = skip_steps
  @fast_recovery = normalize_fast_recovery(fast_recovery, publish: publish)
  if (@fast_recovery || skip_ci) && !kettle_release_command?(raw_release_command)
    raise Error, "named CI recovery requires a kettle-release publish command"
  end
  raise Error, "--skip-ci requires --publish" if skip_ci && !publish
  if @fast_recovery && (start_step || (skip_steps && !skip_steps.to_s.empty?) || skip_ci)
    raise Error, "--fast-recovery cannot be combined with --start-step, --skip-steps, or --skip-ci"
  end
  if fast_recovery_members_given?(fast_recovery_members) && !@fast_recovery
    raise Error, "--fast-recovery-members requires --fast-recovery"
  end
  @fast_recovery_members = normalize_fast_recovery_members(fast_recovery_members)
  @skip_ci = !!skip_ci
  @skip_changelog = !!skip_changelog
  @skip_appraisals = !!skip_appraisals
  @local_ci = local_ci
  @continue_ci_failures = continue_ci_failures
  @ci_workflows = validate_ci_workflows(ci_workflows)
  @skip_bundle_audit = skip_bundle_audit
  @skip_remotes = validate_remote_list(skip_remotes, "--skip-remotes")
  @required_remotes = validate_remote_list(required_remotes.nil? ? config.release_required_remotes : required_remotes, "--required-remotes")
  @auto_dependency_floors = auto_dependency_floors.nil? ? config.release_auto_dependency_floors? : auto_dependency_floors
  @validate_ci_bundles = validate_ci_bundles.nil? ? config.release_validate_ci_bundles? : validate_ci_bundles
  @gha_sha_pins_upgrade = gha_sha_pins_upgrade
  @gha_sha_pins_check = gha_sha_pins_check
  @gha_sha_pins_ttl_days = gha_sha_pins_ttl_days.nil? ? 1.0 : gha_sha_pins_ttl_days.to_f
  @env_overrides = env_overrides
  @debug = debug
  @verbose = verbose
  @gem_signing_password = gem_signing_password
  @secrets_provider = secrets_provider || Secrets::Provider.new
  @jobs = jobs
  @progress_io = progress_io
  @reset_target = reset_target
  @bup_args = bup_args
  @bex_args = bex_args
  @start_member = start_member
  @start_branch = start_branch
  @release_state_results = Array(release_state_results)
  @template_commit_mutex = Mutex.new
end

Instance Method Details

#resultsObject



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/kettle/family/workflow.rb', line 170

def results
  if command == "release" && execute
    return with_release_secrets_broker { release_results }
  end

  return template_with_worktree_sync_results if command == "template" && execute

  preflight = branch_checkout_dirty_preflight_results
  return preflight if preflight.any? { |result| !result.ok? }

  prompt_for_gem_signing_password if command == "release" && execute && release_signing_prompt_required?
  return preflight + branch_target_results unless config.release_target_branches.empty?
  return preflight + member_local_branch_target_results if member_local_branch_targets?

  preflight + current_branch_results(members)
end