gitlab-org--gitlab-foss/scripts/lint_templates_bash.rb

82 lines
2.1 KiB
Ruby
Executable file

#!/usr/bin/env ruby
# frozen_string_literal: true
require_relative '../config/environment'
require 'open3'
module LintTemplatesBash
module_function
EXCLUDED_RULES = [
"SC2046", "SC2086", # will be fixed later: https://gitlab.com/gitlab-org/gitlab/-/issues/352973
"SC1090", "SC1091", # we do not have access to sourced files for analysis.
"SC2154", # Referencing undefined variables is common and adding per-line exceptions for them is unintuitive for end-users
"SC2164" # CI/CD automatically fails if attempting to change to a directory which does not exist.
].join(",").freeze
EXCLUDED_TEMPLATES = [
"dotNET.gitlab-ci.yml" # Powershell
].freeze
def run
failed_templates = Gitlab::Template::GitlabCiYmlTemplate.all.filter_map do |template|
next if EXCLUDED_TEMPLATES.include?(template.full_name)
success = check_template(template)
template.full_name unless success
end
if failed_templates.any?
puts "The following templates have shellcheck violations:"
puts failed_templates.join("\n")
exit 1
end
end
def process_content(content)
Gitlab::Ci::YamlProcessor.new(content).execute
end
def job_script(job)
parts = [:before_script, :script, :after_script].map do |key|
job[key]&.join("\n")
end.compact
parts.prepend("#!/bin/bash\n").join("\n")
end
def shellcheck(script_content)
combined_streams, status = Open3.capture2e("shellcheck --exclude='#{EXCLUDED_RULES}' -", stdin_data: script_content)
[combined_streams, status.success?]
end
def check_job(job)
shellcheck(job_script(job))
end
def check_template(template)
parsed = process_content(template.content)
unless parsed.valid?
warn "#{template.full_name} is invalid: #{parsed.errors.inspect}"
return true
end
results = parsed.jobs.map do |name, job|
out, success = check_job(job)
unless success
puts "The '#{name}' job in #{template.full_name} has shellcheck failures:"
puts out
end
success
end
results.all?
end
end
LintTemplatesBash.run