Skip to content

Instantly share code, notes, and snippets.

@Lutzifer
Last active May 23, 2023 09:04
Show Gist options
  • Save Lutzifer/5c7235d55fd087d48c6ae63fba07c692 to your computer and use it in GitHub Desktop.
Save Lutzifer/5c7235d55fd087d48c6ae63fba07c692 to your computer and use it in GitHub Desktop.
A fastlane lane that updates all GitHub Actions in all Workflows to their latest version. Also caches versions (for 10 mins) to reduce chance of being cut off from the GitHub API. Needs jq as dependency.
desc "Update Github Actions"
lane :update_github_actions do
Dir.chdir("..") do
commitishCacheFolder = "#{ENV["HOME"]}/.githubActionsUpdater/caches/githubCommitishs"
tagsCacheFolder = "#{ENV["HOME"]}/.githubActionsUpdater/caches/githubTags"
FileUtils.mkdir_p commitishCacheFolder
FileUtils.mkdir_p tagsCacheFolder
Dir.glob(".github/workflows/*.yml") do |workflowFile|
# Get list of dependencies
dependencies = %x(cat #{workflowFile} | grep "uses" | grep "@" | cut -d ":" -f2 | cut -d "@" -f 1 | sort -u ).split("\n").collect(&:strip)
workflow = File.read(workflowFile)
dependencies.each do |dependency|
dependencyTagJSONFilePath = "#{tagsCacheFolder}/#{dependency.gsub("/", "_")}.json"
puts "Checking if tag for #{dependency} is cached"
tag = nil
if File.file?(dependencyTagJSONFilePath)
readTagJson = JSON.parse(File.read(dependencyTagJSONFilePath))
now = DateTime.now().to_time.to_i
cacheTime = DateTime.parse(readTagJson["date"]).to_time.to_i
if now - cacheTime <= (10 * 60)
tag = readTagJson["tag"].gsub(%Q(""), "")
end
end
puts tag
puts("https://api.github.com/repos/#{dependency}/releases/latest")
if tag.nil?
puts "loading tag from remote"
tag = %x(curl -s https://api.github.com/repos/#{dependency}/releases | jq '.[] | .tag_name' | sort -V | tail -n 1).strip.gsub(%Q("), "")
puts "Got tag of dependency #{dependency} from API: #{tag}"
tagJson = {
:date => DateTime.now(),
:tag => tag,
}
File.write(dependencyTagJSONFilePath, tagJson.to_json)
end
dependencyCommitishJSONFilePath = "#{commitishCacheFolder}/#{dependency.gsub("/", "_")}.json"
puts "Checking if commitish for #{dependency} is cached"
commitish = nil
if File.file?(dependencyCommitishJSONFilePath)
readCommitishJson = JSON.parse(File.read(dependencyCommitishJSONFilePath))
now = DateTime.now().to_time.to_i
cacheTime = DateTime.parse(readTagJson["date"]).to_time.to_i
if now - cacheTime <= (10 * 60)
commitish = readCommitishJson["commitish"].gsub(%Q(""), "")
end
end
puts commitish
puts("https://api.github.com/repos/#{dependency}/releases/latest")
if commitish.nil?
puts "loading tag from remote"
puts "https://api.github.com/repos/#{dependency}/git/ref/tags/#{tag}"
commitish = %x(curl -s https://api.github.com/repos/#{dependency}/git/ref/tags/#{tag} | jq '.object.sha').strip.gsub(%Q("), "")
puts "Got commitish of dependency #{dependency} from API: #{commitish}"
commitishJson = {
:date => DateTime.now(),
:commitish => commitish,
}
File.write(dependencyCommitishJSONFilePath, commitishJson.to_json)
end
if not commitish.nil? and not commitish.eql? "null"
workflow = workflow.gsub(/#{dependency}@.*/, "#{dependency}@#{commitish} \##{tag}")
end
end
File.write(workflowFile, workflow)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment