Skip to content

Instantly share code, notes, and snippets.

@lauraBaakman
Last active May 25, 2023 10:24
Show Gist options
  • Save lauraBaakman/c0ba5847d4eea4a17aeca5e82852c48e to your computer and use it in GitHub Desktop.
Save lauraBaakman/c0ba5847d4eea4a17aeca5e82852c48e to your computer and use it in GitHub Desktop.
A quick 'n dirty script to create an issue for every package that is not up to date according to `npm outdated`
require 'open3'
require 'logger'
require 'json'
require 'rainbow'
require 'pry'
logger = Logger.new($stdout)
logger.formatter = proc do |severity, _datetime, _progname, msg|
colors = {
"WARN" => :indianred,
"INFO" => :blue,
"ERROR" => :red,
"FATAL" => :red,
}
Rainbow("#{severity.ljust(5)} -- #{msg}\n").send(colors.fetch(severity, :black))
end
PROJECT_NAME = "Frontend Maintenance"
BODY = "This issue was automatically generated, close it if it is nonsensical."
CLOSE_COMMENT = "This issue was closed automatically as the dependency is currently up-to-date."
LABELS = 'maintenance,dependencies'
stdout, status = Open3.capture2("npm outdated --json")
dependencies = JSON.parse(stdout)
dependencies.each do |name, data|
repository = data["dependent"]
latest_version = data["latest"]
wanted_version = data["wanted"] # version we should have according to version specification in package.json
current_version = data["current"]
if current_version.nil? || latest_version.nil? || wanted_version.nil?
logger.warn("Insufficient data available for dependency #{name}")
next
end
search_command = "gh issue list --repo 'payt/#{repository}' --label '#{LABELS}' --search '\"Update #{name}\"' --json title,number,url"
stdout, stderr, status = Open3.capture3(search_command)
unless status.success?
logger.error("Could not fetch issues associated with #{name} with '#{search_command}'. Encountered the error: #{stderr}")
logger.error("Exiting as this issue is likely to occur for the other dependencies as well.")
exit(-1)
end
existing_issues = JSON.parse(stdout)
existing_issues.filter! do |issue|
issue["title"] =~ Regexp.new("Update #{name} from (\\d\.?)+ to (\\d\.?)+ in #{repository}")
end
if current_version == latest_version then
logger.info("#{name} is up to date")
if existing_issues.one?
issue = existing_issues.first
close_command = "gh issue close #{issue["url"]} --comment '#{CLOSE_COMMENT}' -r completed"
stdout, stderr, status = Open3.capture3(close_command)
if status.success? then
logger.info("Closed issue #{issue["number"]} #{issue["url"]}.")
else
logger.error("Could not close issue #{issue["url"]} with '#{close_command}'. Encounterd the error: #{stderr}")
end
elsif existing_issues.any?
logger.error("Multiple possibly matching issues where found: #{existing_issues.map{|issue| issue["url"]}.join(", ")}. Close them manually if applicable.")
end
next
end
if wanted_version == latest_version then
logger.warn("Update #{name} by running 'npm install'.")
next
end
title = "Update #{name} from #{current_version} to #{latest_version} in #{repository}"
create_command = "gh issue create --repo 'payt/#{repository}' --project '#{PROJECT_NAME}' --title '#{title}' --body '#{BODY}' --label '#{LABELS}'"
# Do not use this to run the script multiple times in a row! Github takes a while to let issues be found!
if existing_issues.one?
existing_issue = existing_issues.first
logger.info("An issue already exists for #{name}: '#{existing_issue.fetch("title")}'.")
unless(existing_issue["title"] == title)
logger.info("Updating issue #{existing_issue.fetch("number")} (#{existing_issue.fetch("url")}).")
update_command = "gh issue edit #{existing_issue.fetch("number")} --repo 'payt/#{repository}' --title '#{title}'"
stdout, stderr, status = Open3.capture3(update_command)
unless status.success?
logger.error("Could not update an issue with '#{update_command}'. Encountered the error #{stderr}")
end
end
next
elsif existing_issues.any?
logger.error("Multiple possibly matching issues where found: #{existing_issues.map{|issue| issue["url"]}.join(", ")}. Use '#{create_command}' to manually create the issue.")
next
else
stdout, stderr, status = Open3.capture3(create_command)
if status.success?
logger.info("Created an issue for #{name}: #{stdout.strip}")
else
logger.error("Could not create an issue with '#{create_command}'. Encountered the error: #{stderr}")
next
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment