|
1 | | -import * as core from "@actions/core"; |
2 | | -import { HttpClient } from "@actions/http-client"; |
3 | | -import { RequestOptions } from "@actions/http-client/lib/interfaces"; |
4 | | -import { BearerCredentialHandler } from "@actions/http-client/lib/auth"; |
5 | | -import * as crypto from "crypto"; |
6 | | - |
7 | | -const versionSalt = "1.0"; |
8 | 1 | export const cacheKey = "harden-runner-cacheKey"; |
9 | 2 | export const cacheFile = "/home/agent/cache.txt"; |
10 | 3 |
|
11 | | -function getCacheApiUrl(resource: string): string { |
12 | | - const baseUrl: string = process.env["ACTIONS_CACHE_URL"] || ""; |
13 | | - if (!baseUrl) { |
14 | | - throw new Error("Cache Service Url not found, unable to restore cache."); |
15 | | - } |
16 | | - |
17 | | - const url = `${baseUrl}_apis/artifactcache/${resource}`; |
18 | | - core.debug(`Resource Url: ${url}`); |
19 | | - return url; |
20 | | -} |
21 | | - |
22 | | -function createAcceptHeader(type: string, apiVersion: string): string { |
23 | | - return `${type};api-version=${apiVersion}`; |
24 | | -} |
25 | | - |
26 | | -function getRequestOptions(): RequestOptions { |
27 | | - const token = process.env["ACTIONS_RUNTIME_TOKEN"] || ""; |
28 | | - |
29 | | - const requestOptions: RequestOptions = { |
30 | | - headers: { |
31 | | - Accept: createAcceptHeader("application/json", "6.0-preview.1"), |
32 | | - Authorization: `Bearer ${token}`, |
33 | | - }, |
34 | | - }; |
35 | | - |
36 | | - return requestOptions; |
37 | | -} |
38 | | - |
39 | | -function createHttpClient(): HttpClient { |
40 | | - const token = process.env["ACTIONS_RUNTIME_TOKEN"] || ""; |
41 | | - const bhandler = new BearerCredentialHandler(token); |
42 | | - return new HttpClient("actions/cache", [bhandler], getRequestOptions()); |
43 | | -} |
44 | | - |
45 | | -export function getCacheVersion( |
46 | | - paths: string[], |
47 | | - compressionMethod?: CompressionMethod |
48 | | -): string { |
49 | | - const components = paths.concat( |
50 | | - !compressionMethod || compressionMethod === CompressionMethod.Gzip |
51 | | - ? [] |
52 | | - : [compressionMethod] |
53 | | - ); |
54 | | - |
55 | | - // Add salt to cache version to support breaking changes in cache entry |
56 | | - components.push(versionSalt); |
57 | | - |
58 | | - return crypto.createHash("sha256").update(components.join("|")).digest("hex"); |
59 | | -} |
60 | | - |
61 | | -export async function getCacheEntry( |
62 | | - keys: string[], |
63 | | - paths: string[], |
64 | | - options?: InternalCacheOptions |
65 | | -): Promise<ArtifactCacheEntry | null> { |
66 | | - const httpClient = createHttpClient(); |
67 | | - const version = getCacheVersion(paths, options?.compressionMethod); |
68 | | - const resource = `cache?keys=${encodeURIComponent( |
69 | | - keys.join(",") |
70 | | - )}&version=${version}`; |
71 | | - |
72 | | - const response = await httpClient.getJson<ArtifactCacheEntry>( |
73 | | - getCacheApiUrl(resource) |
74 | | - ); |
75 | | - if (response.statusCode === 204) { |
76 | | - throw new Error("Request returned 204 status"); |
77 | | - } |
78 | | - if (!isSuccessStatusCode(response.statusCode)) { |
79 | | - throw new Error(`Cache service responded with ${response.statusCode}`); |
80 | | - } |
81 | | - |
82 | | - const cacheResult = response.result; |
83 | | - const cacheDownloadUrl = cacheResult?.archiveLocation; |
84 | | - if (!cacheDownloadUrl) { |
85 | | - throw new Error("Cache still be done, but not found."); |
86 | | - } |
87 | | - |
88 | | - return cacheResult; |
89 | | -} |
90 | | - |
91 | | -export interface InternalCacheOptions { |
92 | | - compressionMethod?: CompressionMethod; |
93 | | - cacheSize?: number; |
94 | | -} |
95 | | - |
96 | 4 | export interface ArtifactCacheEntry { |
97 | 5 | cacheKey?: string; |
98 | 6 | scope?: string; |
99 | 7 | creationTime?: string; |
100 | 8 | archiveLocation?: string; |
101 | 9 | } |
102 | 10 |
|
103 | | -function isSuccessStatusCode(statusCode?: number): boolean { |
104 | | - if (!statusCode) { |
105 | | - return false; |
106 | | - } |
107 | | - return statusCode >= 200 && statusCode < 300; |
108 | | -} |
109 | | - |
110 | 11 | export enum CompressionMethod { |
111 | 12 | Gzip = "gzip", |
112 | 13 | // Long range mode was added to zstd in v1.3.2. |
|
0 commit comments