@@ -17,25 +17,77 @@ def execute
1717 )
1818 return nil if pipeline . response . status == 404
1919
20- reticulum_sha = pipeline . body . sha
21-
22- components = { }
23-
24- Pyxis ::Project . components . each do |project_name |
25- component_project_class = Pyxis ::Project . const_get ( project_name )
26- version_file = "versions/#{ component_project_class . component_name } "
27-
28- begin
29- version_content = GithubClient . octokit . contents ( Project ::Reticulum . github_path , path : version_file ,
30- ref : reticulum_sha )
31- version = Base64 . decode64 ( version_content . content )
32- components [ component_project_class . component_name ] = version
33- rescue Octokit ::NotFound
34- logger . warn ( "Version file not found for #{ component_project_class . component_name } at SHA #{ reticulum_sha } " )
35- end
20+ jobs = GitlabClient . paginate_json (
21+ GitlabClient . client ,
22+ "/api/v4/projects/#{ Project ::Reticulum . api_gitlab_path } /pipelines/#{ build_id } /jobs"
23+ )
24+
25+ manifests = find_manifests ( jobs )
26+
27+ components = {
28+ reticulum : pipeline . body . sha ,
29+ }
30+
31+ manifests . each do |image |
32+ component = image . first . to_sym
33+ next if components . key? ( component )
34+
35+ image_tag = image . length == 1 ? build_id : "#{ build_id } -#{ image . last } "
36+
37+ components [ component ] = revision_for ( "code0-tech/reticulum/ci-builds/#{ component } " , image_tag )
3638 end
3739
38- components
40+ components . compact
41+ end
42+
43+ private
44+
45+ def ghcr_client
46+ @ghcr_client ||= GenericFaraday . create ( { url : 'https://ghcr.io' } )
47+ end
48+
49+ def token_for ( image )
50+ response = ghcr_client . get_json (
51+ 'token' ,
52+ {
53+ scope : "repository:#{ image } :pull" ,
54+ service : 'ghcr.io' ,
55+ }
56+ )
57+
58+ logger . warn ( 'Failed to retrieve token' , image : image ) unless response . response . status == 200
59+
60+ response . body . token
61+ end
62+
63+ def revision_for ( image , tag )
64+ token = token_for ( image )
65+
66+ response = ghcr_client . get_json (
67+ "v2/#{ image } /manifests/#{ tag } " ,
68+ { } ,
69+ {
70+ Authorization : "Bearer #{ token } " ,
71+ Accept : 'application/vnd.oci.image.index.v1+json' ,
72+ }
73+ )
74+
75+ logger . warn ( 'Failed to retrieve tag for image' , image : image , tag : tag ) unless response . response . status == 200
76+
77+ response . body . annotations &.[]( 'org.opencontainers.image.version' )
78+ end
79+
80+ def find_manifests ( jobs )
81+ jobs . map { |job | job [ 'name' ] }
82+ . select { |job | job . start_with? ( 'manifest:' ) }
83+ . map { |job | job . delete_prefix ( 'manifest:' ) }
84+ . sort
85+ . map { |job | job . split ( ': ' ) }
86+ . map do |image |
87+ next image if image . length == 1
88+
89+ [ image . first , image . last . delete_prefix ( '[' ) . delete_suffix ( ']' ) ]
90+ end
3991 end
4092 end
4193 end
0 commit comments