Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cache deletion #1783

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions packages/cache/src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export class ReserveCacheError extends Error {
}
}

export class DeleteCacheError extends Error {
constructor(message: string) {
super(message)
this.name = 'DeleteCacheError'
Object.setPrototypeOf(this, DeleteCacheError.prototype)
}
}

function checkPaths(paths: string[]): void {
if (!paths || paths.length === 0) {
throw new ValidationError(
Expand Down Expand Up @@ -258,3 +266,44 @@ export async function saveCache(

return cacheId
}

/**
* Deletes a cache item with the specified key
*
* @param key an explicit key for the cache to delete
* @param ref only delete items with key for this reference The ref for a branch should be formatted as
* refs/heads/<branch name>. To reference a pull request use refs/pull/<number>/merge.
*/
export async function deleteCacheWithKey(
key: string,
ref?: string
): Promise<number> {
checkKey(key)

core.debug(`Deleting Cache with key "${key}" and ref "${ref}"`)
const deleteCacheResponse = await cacheHttpClient.deleteCacheWithKey(key, ref)
if (deleteCacheResponse?.statusCode !== 200) {
throw new DeleteCacheError(
`Unable to delete cache with key ${key}. More details: ${deleteCacheResponse?.error?.message}`
)
}

return deleteCacheResponse?.result?.totalCount
}

/**
* Deletes a cache item with the specified id
*
* @param id an explicit id for the cache to delete
*/
export async function deleteCacheWithId(id: number): Promise<number> {
core.debug(`Deleting Cache with id ${id.toString()}`)
const deleteCacheResponse = await cacheHttpClient.deleteCacheWithId(id)
if (deleteCacheResponse?.statusCode !== 204) {
throw new DeleteCacheError(
`Unable to delete cache with id ${id}. More details: ${deleteCacheResponse?.error?.message}`
)
}

return deleteCacheResponse?.result?.totalCount
}
34 changes: 33 additions & 1 deletion packages/cache/src/internal/cacheHttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
ReserveCacheRequest,
ReserveCacheResponse,
ITypedResponseWithError,
ArtifactCacheList
ArtifactCacheList,
DeleteCacheResponse
} from './contracts'
import {
downloadCacheHttpClient,
Expand Down Expand Up @@ -227,6 +228,37 @@ export async function reserveCache(
return response
}

export async function deleteCacheWithKey(
key: string,
ref?: string
): Promise<ITypedResponseWithError<DeleteCacheResponse>> {
const httpClient = createHttpClient()

const response = await retryTypedResponse('deleteCache', async () =>
httpClient.deleteJson<DeleteCacheResponse>(
ref != null
? getCacheApiUrl(`caches?key=${key}&ref=${ref}`)
: getCacheApiUrl(`caches?key=${key}`)
)
)

return response
}

export async function deleteCacheWithId(
id: number
): Promise<ITypedResponseWithError<DeleteCacheResponse>> {
const httpClient = createHttpClient()

const response = await retryTypedResponse('deleteCache', async () =>
httpClient.deleteJson<DeleteCacheResponse>(
getCacheApiUrl(`caches/${id.toString()}`)
)
)

return response
}

function getContentRange(start: number, end: number): string {
// Format: `bytes start-end/filesize
// start and end are inclusive
Expand Down
4 changes: 4 additions & 0 deletions packages/cache/src/internal/contracts.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export interface ReserveCacheResponse {
cacheId: number
}

export interface DeleteCacheResponse {
totalCount: number
}

export interface InternalCacheOptions {
compressionMethod?: CompressionMethod
enableCrossOsArchive?: boolean
Expand Down
21 changes: 21 additions & 0 deletions packages/http-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,27 @@ export class HttpClient {
return this._processResponse<T>(res, this.requestOptions)
}

async deleteJson<T>(
requestUrl: string,
additionalHeaders: http.OutgoingHttpHeaders = {}
): Promise<ifm.TypedResponse<T>> {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(
additionalHeaders,
Headers.Accept,
MediaTypes.ApplicationJson
)
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(
additionalHeaders,
Headers.ContentType,
MediaTypes.ApplicationJson
)
const res: HttpClientResponse = await this.del(
requestUrl,
additionalHeaders
)
return this._processResponse<T>(res, this.requestOptions)
}

/**
* Makes a raw http request.
* All other methods such as get, post, patch, and request ultimately call this.
Expand Down