Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(CONT-1026) Deprecate release command set #1297

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions lib/pdk/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def self.puppet_dev_option(dsl)
require 'pdk/cli/env'
require 'pdk/cli/get'
require 'pdk/cli/new'
require 'pdk/cli/publish'
require 'pdk/cli/set'
require 'pdk/cli/test'
require 'pdk/cli/update'
Expand Down
4 changes: 3 additions & 1 deletion lib/pdk/cli/build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module CLI
'The target directory where you want PDK to write the package.',
argument: :required, default: File.join(Dir.pwd, 'pkg')

option nil, 'force', 'Skips the prompts and builds the module package.'
flag nil, :force, 'Skips the prompts and builds the module package.'
flag nil, :'skip-documentation', 'Skips the documentation update.'
flag nil, :'skip-validation', 'Skips the module validation check.'

run do |opts, _args, _cmd|
require 'pdk/module/build'
Expand Down
87 changes: 87 additions & 0 deletions lib/pdk/cli/publish.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
require 'pdk/cli/util'
require 'pdk/validate'
require 'pdk/util/bundler'
require 'pdk/cli/util/interview'
require 'pdk/module/build'

module PDK
module CLI
@publish_cmd = @base_cmd.define_command do
name 'publish'
usage 'publish [options] <tarball>'
summary 'Publishes the module to the Forge.'

flag nil, :force, 'Publish the module automatically, with no prompts.'

option nil, :'forge-upload-url', 'Set forge upload url path.',
argument: :required, default: 'https://forgeapi.puppetlabs.com/v3/releases'

option nil, :'forge-token', 'Set Forge API token (you may also set via environment variable PDK_FORGE_TOKEN)', argument: :required

run do |opts, _args, _cmd|
# Make sure build is being run in a valid module directory with a metadata.json
PDK::CLI::Util.ensure_in_module!(
message: '`pdk publish` can only be run from inside a valid module with a metadata.json.',
log_level: :info
)
opts[:force] = true unless PDK::CLI::Util.interactive?
opts[:'forge-token'] ||= PDK::Util::Env['PDK_FORGE_TOKEN']

if opts[:'forge-token'].nil? || opts[:'forge-token'].empty?
PDK.logger.error 'You must supply a Forge API token either via `--forge-token` option or PDK_FORGE_TOKEN environment variable.'
exit 1
end

# pdk publish doesn't need any additional tasks. Since we still want to preserve functionality for
# the deprecated `pdk release` command, we'll just set all the skip flags to true.
opts[:'skip-validation'] = true
opts[:'skip-changelog'] = true
opts[:'skip-dependency'] = true
opts[:'skip-documentation'] = true
opts[:'skip-build'] = true

Release.send_analytics('publish', opts)

release = PDK::Module::Release.new(nil, opts)
release.run
end

module Release # rubocop:disable Lint/ConstantDefinitionInBlock
# Checks whether the module is compatible with PDK release process
# @param release PDK::Module::Release Object representing the release
# @param opts Options Hash from Cri
def self.module_compatibility_checks!(release, opts)
unless release.module_metadata.forge_ready?
if opts[:force]
PDK.logger.warn "This module is missing the following fields in the metadata.json: #{release.module_metadata.missing_fields.join(', ')}. " \
'These missing fields may affect the visibility of the module on the Forge.'
else
release.module_metadata.interview_for_forge!
release.write_module_metadata!
end
end

unless release.pdk_compatible? # rubocop:disable Style/GuardClause Nope!
if opts[:force]
PDK.logger.warn 'This module is not compatible with PDK, so PDK can not validate or test this build.'
else
PDK.logger.info 'This module is not compatible with PDK, so PDK can not validate or test this build. ' \
'Unvalidated modules may have errors when uploading to the Forge. ' \
'To make this module PDK compatible and use validate features, cancel the build and run `pdk convert`.'
unless PDK::CLI::Util.prompt_for_yes('Continue build without converting?')
PDK.logger.info 'Build cancelled; exiting.'
PDK::Util.exit_process(1)
end
end
end
end

# Send_analytics for the given command and Cri options
def self.send_analytics(command, opts)
# Don't pass tokens to analytics
PDK::CLI::Util.analytics_screen_view(command, opts.reject { |k, _| k == :'forge-token' })
end
end
end
end
end
4 changes: 2 additions & 2 deletions lib/pdk/cli/release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module CLI
@release_cmd = @base_cmd.define_command do
name 'release'
usage 'release [options]'
summary '(Experimental) Release a module to the Puppet Forge.'
summary '(Deprecated) Release a module to the Puppet Forge.'

flag nil, :force, 'Release the module automatically, with no prompts.'
flag nil, :'skip-validation', 'Skips the module validation check.'
Expand All @@ -27,7 +27,7 @@ module CLI
argument: :optional

option nil, :version, 'Update the module to the specified version prior to release. When not specified, the new version will be computed from the Changelog where possible.',
argument: :required
argument: :optional

option nil, :file, 'Path to the built module to push to the Forge. This option can only be used when --skip-build is also used. Defaults to pkg/<module version>.tar.gz',
argument: :required
Expand Down
2 changes: 1 addition & 1 deletion lib/pdk/cli/release/prep.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module CLI
@release_prep_cmd = @release_cmd.define_command do
name 'prep'
usage 'prep [options]'
summary '(Experimental) Performs all the pre-release checks to ensure module is ready to be released'
summary '(Deprecated) Performs all the pre-release checks to ensure module is ready to be released'

flag nil, :force, 'Prepare the module automatically, with no prompts.'
flag nil, :'skip-validation', 'Skips the module validation check.'
Expand Down
4 changes: 1 addition & 3 deletions lib/pdk/cli/release/publish.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
require 'pdk/cli/release'

module PDK
module CLI
@release_publish_cmd = @release_cmd.define_command do
name 'publish'
usage 'publish [options] <tarball>'
summary '(Experimental) Publishes the module <tarball> to the Forge.'
summary '(Deprecated) Publishes the module <tarball> to the Forge.'

flag nil, :force, 'Publish the module automatically, with no prompts.'

Expand Down
6 changes: 6 additions & 0 deletions lib/pdk/module/build.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'pdk'
require_relative 'pre_build'

module PDK
module Module
Expand All @@ -10,6 +11,7 @@ def self.invoke(options = {})
attr_reader :module_dir, :target_dir

def initialize(options = {})
@options = options
@module_dir = PDK::Util::Filesystem.expand_path(options[:module_dir] || Dir.pwd)
@target_dir = PDK::Util::Filesystem.expand_path(options[:'target-dir'] || File.join(module_dir, 'pkg'))
end
Expand All @@ -33,6 +35,10 @@ def package_file
#
# @return [String] The path to the built package file.
def build
extend PreBuild
run_documentation unless @options[:'skip-documentation']
run_validations(@options) unless @options[:'skip-validation']

create_build_dir

stage_module_in_build_dir
Expand Down
46 changes: 46 additions & 0 deletions lib/pdk/module/pre_build.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require 'pdk'

module PDK
module Module
module PreBuild
module_function

def run_validations(opts)
PDK::CLI::Util.validate_puppet_version_opts(opts)

PDK::CLI::Util.module_version_check

puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts)
PDK::Util::PuppetVersion.fetch_puppet_dev if opts[:'puppet-dev']
PDK::Util::RubyVersion.use(puppet_env[:ruby_version])

PDK::Util::Bundler.ensure_bundle!(puppet_env[:gemset])

validator_exit_code, report = PDK::Validate.invoke_validators_by_name(PDK.context, PDK::Validate.validator_names, false, opts)
report_formats = if opts[:format]
PDK::CLI::Util::OptionNormalizer.report_formats(opts[:format])
else
[{
method: PDK::Report.default_format,
target: PDK::Report.default_target
}]
end

report_formats.each do |format|
report.send(format[:method], format[:target])
end

raise PDK::CLI::ExitWithError, 'An error occured during validation' unless validator_exit_code.zero?
end

def run_documentation
PDK.logger.info 'Updating documentation using puppet strings'
docs_command = PDK::CLI::Exec::InteractiveCommand.new(PDK::CLI::Exec.bundle_bin, 'exec', 'puppet', 'strings', 'generate', '--format', 'markdown', '--out', 'REFERENCE.md')
docs_command.context = :module
result = docs_command.execute!

raise PDK::CLI::ExitWithError, format('An error occured generating the module documentation: %{stdout}', stdout: result[:stdout]) unless result[:exit_code].zero?
end
end
end
end
49 changes: 12 additions & 37 deletions lib/pdk/module/release.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'pdk'
require 'uri'
require_relative 'pre_build'

module PDK
module Module
Expand Down Expand Up @@ -27,6 +28,8 @@ def initialize(module_path, options = {})
end

def run
extend PreBuild

# Pre-release checks
unless force?
raise PDK::CLI::ExitWithError, 'The module is not PDK compatible' if requires_pdk_compatibility? && !pdk_compatible?
Expand All @@ -47,7 +50,7 @@ def run
# Calculate the new module version
new_version = specified_version
new_version = PDK::Util::ChangelogGenerator.compute_next_version(module_metadata.data['version']) if new_version.nil? && !skip_changelog?
new_version = module_metadata.data['version'] if new_version.nil?
new_version = module_metadata.data['version'] if new_version.nil? || !new_version

if new_version != module_metadata.data['version']
PDK.logger.info format('Updating version to %{module_version}', module_version: new_version)
Expand Down Expand Up @@ -99,41 +102,6 @@ def default_package_filename
@default_tarball_filename = builder.package_file
end

def run_validations(opts)
# TODO: Surely I can use a pre-existing class for this?
PDK::CLI::Util.validate_puppet_version_opts(opts)

PDK::CLI::Util.module_version_check

puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts)
PDK::Util::PuppetVersion.fetch_puppet_dev if opts[:'puppet-dev']
PDK::Util::RubyVersion.use(puppet_env[:ruby_version])

PDK::Util::Bundler.ensure_bundle!(puppet_env[:gemset])

validator_exit_code, = PDK::Validate.invoke_validators_by_name(PDK.context, PDK::Validate.validator_names, false, options)
raise PDK::CLI::ExitWithError, 'An error occured during validation' unless validator_exit_code.zero?
end

def run_documentation(_opts)
PDK.logger.info 'Updating documentation using puppet strings'
docs_command = PDK::CLI::Exec::InteractiveCommand.new(PDK::CLI::Exec.bundle_bin, 'exec', 'puppet', 'strings', 'generate', '--format', 'markdown', '--out', 'REFERENCE.md')
docs_command.context = :module
result = docs_command.execute!
raise PDK::CLI::ExitWithError, format('An error occured generating the module documentation: %{stdout}', stdout: result[:stdout]) unless result[:exit_code].zero?
end

def run_dependency_checker(_opts)
# run dependency-checker and output dependent modules list
PDK.logger.info 'Running dependency checks'

dep_command = PDK::CLI::Exec::Command.new('dependency-checker', 'metadata.json')
dep_command.context = :module
result = dep_command.execute!

raise PDK::CLI::ExitWithError, format('An error occured checking the module dependencies: %{stdout}', stdout: result[:stdout]) unless result[:exit_code].zero?
end

# @return [String] Path to the built tarball
def run_build(opts)
PDK::Module::Build.invoke(opts.dup)
Expand All @@ -155,6 +123,7 @@ def run_publish(_opts, tarball_path)
request['Content-Type'] = 'application/json'
data = { file: file_data }

require 'json'
request.body = data.to_json

require 'openssl'
Expand All @@ -163,7 +132,13 @@ def run_publish(_opts, tarball_path)
http.request(request)
end

raise PDK::CLI::ExitWithError, format('Error uploading to Puppet Forge: %{result}', result: response.body) unless response.is_a?(Net::HTTPSuccess)
unless response.is_a?(Net::HTTPSuccess)
PDK.logger.debug "Puppet Forge response: #{response.body}"
raise PDK::CLI::ExitWithError, "Authentication failure when uploading to Puppet Forge: #{JSON.parse(response.body)['error']}" if response.is_a?(Net::HTTPUnauthorized)

raise PDK::CLI::ExitWithError "Error uploading to Puppet Forge: #{JSON.parse(response.body)['message']}"

end

PDK.logger.info 'Publish to Forge was successful'
end
Expand Down
42 changes: 41 additions & 1 deletion lib/pdk/report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Report

# @return [Array<String>] the list of supported report formats.
def self.formats
@report_formats ||= ['junit', 'text'].freeze
@report_formats ||= ['junit', 'text', 'json', 'yaml'].freeze
end

# @return [Symbol] the method name of the default report format.
Expand Down Expand Up @@ -117,5 +117,45 @@ def write_text(target = self.class.default_target)
target << report.join("\n") << "\n"
end
end

# Renders the report as JSON
#
# This report is designed to output all events, including passing events as JSON.
# @param target [#write] an IO object that the report will be written to.
def write_json(target = self.class.default_target)
require 'json'

report = {
'pdk-version' => PDK::VERSION,
'timestamp' => Time.now.utc.iso8601,
'events' => events.map { |_, tool_events| tool_events.map(&:to_hash) }.flatten
}

if target.is_a?(String)
PDK::Util::Filesystem.write_file(target, JSON.pretty_generate(report))
else
target << JSON.pretty_generate(report)
end
end

# Renders the report as YAML
#
# This report is designed to output all events, including passing events as YAML.
# @param target [#write] an IO object that the report will be written to.
def write_yaml(target = self.class.default_target)
require 'yaml'

report = {
'pdk-version' => PDK::VERSION,
'timestamp' => Time.now.utc.iso8601,
'events' => events.map { |_, tool_events| tool_events.map(&:to_hash) }.flatten
}

if target.is_a?(String)
PDK::Util::Filesystem.write_file(target, YAML.dump(report))
else
target << YAML.dump(report)
end
end
end
end
16 changes: 16 additions & 0 deletions lib/pdk/report/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ def to_junit
testcase
end

# Renders the event as a HASH.
# @return [Hash] The rendered event.
def to_hash
{
'file' => file,
'line' => line,
'column' => column,
'source' => source,
'message' => message,
'severity' => severity,
'test' => test,
'state' => state,
'trace' => trace
}
end

private

# Processes the data hash used to initialise the event, validating and
Expand Down
1 change: 1 addition & 0 deletions lib/pdk/validate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module ControlRepo
module Metadata
autoload :MetadataJSONLintValidator, 'pdk/validate/metadata/metadata_json_lint_validator'
autoload :MetadataSyntaxValidator, 'pdk/validate/metadata/metadata_syntax_validator'
autoload :MetadataDependencyValidator, 'pdk/validate/metadata/metadata_dependency_validator'
autoload :MetadataValidatorGroup, 'pdk/validate/metadata/metadata_validator_group'
end

Expand Down
Loading