Class: Kettle::Dev::GhaShaPinsCLI::PersistentActionCache

Inherits:
Object
  • Object
show all
Defined in:
lib/kettle/dev/gha_sha_pins_cli.rb

Overview

Persistent cache of GitHub Action release versions and target SHAs.

Constant Summary collapse

VERSION =
1

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:, ttl_seconds: DEFAULT_CACHE_TTL_SECONDS, clock: -> { Time.now }) ⇒ PersistentActionCache

Returns a new instance of PersistentActionCache.



909
910
911
912
913
914
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 909

def initialize(path:, ttl_seconds: DEFAULT_CACHE_TTL_SECONDS, clock: -> { Time.now })
  @path = path
  @ttl_seconds = ttl_seconds
  @clock = clock
  @data = nil
end

Class Method Details

.default_pathObject



901
902
903
904
905
906
907
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 901

def self.default_path
  state_home = ENV["XDG_STATE_HOME"]
  state_home = File.join(Dir.home, ".local", "state") if state_home.to_s.empty?
  File.join(state_home, "kettle-dev", "gha-sha-pins-cache.json")
rescue ArgumentError
  nil
end

Instance Method Details

#ref_sha(repo_ref, ref, fresh: true) ⇒ Object



960
961
962
963
964
965
966
967
968
969
970
971
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 960

def ref_sha(repo_ref, ref, fresh: true)
  action = action_data(repo_ref)
  return nil unless action

  refs = action.fetch("refs", {})
  entry = refs[ref.to_s]
  return nil unless entry
  return nil if fresh && !fresh_entry?(entry)

  sha = entry["sha"].to_s
  sha.empty? ? nil : sha
end

#to_hObject



986
987
988
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 986

def to_h
  data
end

#versions_for_repo(repo_ref, fresh: true) ⇒ Object



916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 916

def versions_for_repo(repo_ref, fresh: true)
  action = action_data(repo_ref)
  return nil unless action

  versions = action.fetch("versions", {}).values
  return nil if versions.empty?

  entries = if fresh
    versions.select { |entry| fresh_entry?(entry) }
  else
    versions
  end
  return nil if entries.empty?
  return nil if fresh && entries.length != versions.length

  entries.filter_map { |entry| deserialize_version_entry(entry) }
    .sort_by { |entry| entry[:version_obj] }
    .reverse
end

#write_ref_sha(repo_ref, ref, sha) ⇒ Object



973
974
975
976
977
978
979
980
981
982
983
984
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 973

def write_ref_sha(repo_ref, ref, sha)
  return if @path.to_s.empty?
  return if repo_ref.to_s.empty? || ref.to_s.empty? || sha.to_s.empty?

  action = data.fetch("actions")[repo_ref] ||= {}
  refs = action["refs"] ||= {}
  refs[ref.to_s] = {
    "sha" => sha.to_s[0, 40],
    "cached_at" => @clock.call.utc.iso8601
  }
  save!
end

#write_versions(repo_ref, versions) ⇒ Object



936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
# File 'lib/kettle/dev/gha_sha_pins_cli.rb', line 936

def write_versions(repo_ref, versions)
  return if @path.to_s.empty?
  return if repo_ref.to_s.empty?

  action = data.fetch("actions")[repo_ref] ||= {}
  stored_versions = action["versions"] ||= {}
  timestamp = @clock.call.utc.iso8601

  versions.each do |entry|
    version = entry[:version].to_s
    next if version.empty?

    stored_versions[version] = {
      "tag" => entry[:tag].to_s,
      "version" => version,
      "sha" => entry[:sha].to_s,
      "cached_at" => timestamp
    }
  end

  action["targets"] = target_cache(stored_versions.values)
  save!
end