@@ -164,33 +164,18 @@ func deleteCaches(opts *DeleteOptions, client *api.Client, repo ghrepo.Interface
164164 cs := opts .IO .ColorScheme ()
165165 repoName := ghrepo .FullName (repo )
166166 opts .IO .StartProgressIndicator ()
167- base := fmt .Sprintf ("repos/%s/actions/caches" , repoName )
168167
168+ totalDeleted := 0
169169 for _ , cache := range toDelete {
170- // TODO(babakks): We use two different endpoints here which have different
171- // response schemas:
172- //
173- // 1. /repos/OWNER/REPO/actions/caches/ID (for deleting by cache ID)
174- // - returns HTTP 204 (NO CONTENT) on success
175- // 2. /repos/OWNER/REPO/actions/caches?key=KEY[&ref=REF] (for deleting by cache key, and optionally a ref)
176- // - returns HTTP 200 on success including information about the deleted caches
177- //
178- // So, if/when we decided to use the data in the response body we need
179- // to be careful with parsing. Probably want to split these API calls
180- // into separate functions.
181-
182- path := ""
170+ var count int
171+ var err error
183172 if id , ok := parseCacheID (cache ); ok {
184- path = fmt .Sprintf ("%s/%d" , base , id )
173+ err = deleteCacheByID (client , repo , id )
174+ count = 1
185175 } else {
186- path = fmt .Sprintf ("%s?key=%s" , base , url .QueryEscape (cache ))
187-
188- if opts .Ref != "" {
189- path += fmt .Sprintf ("&ref=%s" , url .QueryEscape (opts .Ref ))
190- }
176+ count , err = deleteCacheByKey (client , repo , cache , opts .Ref )
191177 }
192178
193- err := client .REST (repo .RepoHost (), "DELETE" , path , nil , nil )
194179 if err != nil {
195180 var httpErr api.HTTPError
196181 if errors .As (err , & httpErr ) {
@@ -207,17 +192,45 @@ func deleteCaches(opts *DeleteOptions, client *api.Client, repo ghrepo.Interface
207192 opts .IO .StopProgressIndicator ()
208193 return err
209194 }
195+
196+ totalDeleted += count
210197 }
211198
212199 opts .IO .StopProgressIndicator ()
213200
214201 if opts .IO .IsStdoutTTY () {
215- fmt .Fprintf (opts .IO .Out , "%s Deleted %s from %s\n " , cs .SuccessIcon (), text .Pluralize (len ( toDelete ) , "cache" ), repoName )
202+ fmt .Fprintf (opts .IO .Out , "%s Deleted %s from %s\n " , cs .SuccessIcon (), text .Pluralize (totalDeleted , "cache" ), repoName )
216203 }
217204
218205 return nil
219206}
220207
208+ func deleteCacheByID (client * api.Client , repo ghrepo.Interface , id int ) error {
209+ // returns HTTP 204 (NO CONTENT) on success
210+ path := fmt .Sprintf ("repos/%s/actions/caches/%d" , ghrepo .FullName (repo ), id )
211+ return client .REST (repo .RepoHost (), "DELETE" , path , nil , nil )
212+ }
213+
214+ // deleteCacheByKey deletes cache entries by given key (and optional ref) and
215+ // returns the number of deleted entries.
216+ //
217+ // Note that a key/ref combination does not necessarily map to a single cache
218+ // entry. There may be more than one entries with the same key/ref combination,
219+ // but those entries will have different IDs.
220+ func deleteCacheByKey (client * api.Client , repo ghrepo.Interface , key , ref string ) (int , error ) {
221+ path := fmt .Sprintf ("repos/%s/actions/caches?key=%s" , ghrepo .FullName (repo ), url .QueryEscape (key ))
222+ if ref != "" {
223+ path += fmt .Sprintf ("&ref=%s" , url .QueryEscape (ref ))
224+ }
225+ var payload shared.CachePayload
226+ err := client .REST (repo .RepoHost (), "DELETE" , path , nil , & payload )
227+ if err != nil {
228+ return 0 , err
229+ }
230+
231+ return payload .TotalCount , nil
232+ }
233+
221234func parseCacheID (arg string ) (int , bool ) {
222235 id , err := strconv .Atoi (arg )
223236 return id , err == nil
0 commit comments