Last active
May 23, 2023 09:04
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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