@@ -57,19 +57,101 @@ _ATTRS = {
5757}
5858
5959def _helm_repo_impl (repository_ctx ):
60- repository_ctx .report_progress ("Downloading Helm releases info" )
61- repository_ctx .download (
62- url = ["https://api.github.com/repos/helm/helm/releases" ],
63- output = "versions.json" ,
64- )
65- versions = repository_ctx .read ("versions.json" )
60+ """Fetch Helm binary for the specified version and platform.
61+
62+ This implementation handles GitHub API pagination to ensure we fetch
63+ all releases, not just the first 100.
64+ """
65+ repository_ctx .report_progress ("Fetching Helm release information from GitHub" )
66+
67+ # Collect all releases across multiple pages
68+ all_releases = []
69+ page = 1
70+ max_pages = 20 # Safety limit to prevent infinite loops
71+
72+ while page <= max_pages :
73+ repository_ctx .report_progress ("Fetching releases page {}" .format (page ))
74+
75+ # Use curl with -I to first get headers and check for Link header
76+ header_result = repository_ctx .execute (
77+ ["curl" , "-sI" , "https://api.github.com/repos/helm/helm/releases?per_page=100&page={}" .format (page )],
78+ timeout = 30 ,
79+ quiet = True ,
80+ )
81+
82+ if header_result .return_code != 0 :
83+ fail ("Failed to fetch release headers from GitHub API: {}" .format (header_result .stderr ))
84+
85+ # Now fetch the actual data
86+ data_result = repository_ctx .execute (
87+ ["curl" , "-s" , "https://api.github.com/repos/helm/helm/releases?per_page=100&page={}" .format (page )],
88+ timeout = 60 ,
89+ quiet = True ,
90+ )
91+
92+ if data_result .return_code != 0 :
93+ fail ("Failed to fetch releases from GitHub API (page {}): {}" .format (page , data_result .stderr ))
94+
95+ # Parse the JSON response
96+ try :
97+ page_releases = json .decode (data_result .stdout )
98+ except :
99+ fail ("Failed to parse GitHub API response on page {}. Response: {}" .format (
100+ page ,
101+ data_result .stdout [:500 ] if len (data_result .stdout ) > 500 else data_result .stdout
102+ ))
103+
104+ # Validate response format
105+ if type (page_releases ) != "list" :
106+ # Check if we hit rate limiting or other API errors
107+ if type (page_releases ) == "dict" and "message" in page_releases :
108+ fail ("GitHub API error: {}" .format (page_releases .get ("message" , "Unknown error" )))
109+ fail ("Unexpected response format from GitHub API on page {}" .format (page ))
110+
111+ # Add releases from this page
112+ all_releases .extend (page_releases )
113+
114+ # Check if there's a next page by examining the Link header
115+ has_next_page = False
116+ for line in header_result .stdout .split ("\n " ):
117+ if line .lower ().startswith ("link:" ):
118+ # GitHub includes rel="next" in Link header if there are more pages
119+ if 'rel="next"' in line :
120+ has_next_page = True
121+ break
122+
123+ # Stop if no more pages or empty page
124+ if not has_next_page or len (page_releases ) == 0 :
125+ break
126+
127+ page += 1
128+
129+ repository_ctx .report_progress ("Processed {} releases from GitHub API" .format (len (all_releases )))
130+
131+ # Search for the requested version
66132 version_found = False
67- for v in json .decode (versions ):
68- version = v ["tag_name" ].lstrip ("v" )
133+ for release in all_releases :
134+ if "tag_name" not in release :
135+ continue
136+ version = release ["tag_name" ].lstrip ("v" )
69137 if version == repository_ctx .attr .helm_version :
70138 version_found = True
139+ break
140+
71141 if not version_found :
72- fail ("did not find {} version in https://api.github.com/repos/helm/helm/releases" .format (repository_ctx .attr .helm_version ))
142+ # Provide helpful error message with available versions
143+ available_versions = []
144+ for release in all_releases [:20 ]: # Show first 20 versions
145+ if "tag_name" in release :
146+ available_versions .append (release ["tag_name" ].lstrip ("v" ))
147+
148+ fail ("""Helm version '{}' not found among {} available releases.
149+ Recent versions include: {}
150+ Check https://github.com/helm/helm/releases for all available versions.""" .format (
151+ repository_ctx .attr .helm_version ,
152+ len (all_releases ),
153+ ", " .join (available_versions )
154+ ))
73155
74156 file_url = "https://get.helm.sh/helm-v{}-{}.tar.gz" .format (repository_ctx .attr .helm_version , repository_ctx .attr .platform )
75157
0 commit comments