Skip to content

Commit

Permalink
Fix issue to get cache endpoint (#253)
Browse files Browse the repository at this point in the history
  • Loading branch information
varunsh-coder committed Mar 10, 2023
1 parent cbe5226 commit 1f99358
Show file tree
Hide file tree
Showing 8 changed files with 62,385 additions and 7,648 deletions.
452 changes: 251 additions & 201 deletions dist/post/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/post/index.js.map

Large diffs are not rendered by default.

69,442 changes: 62,112 additions & 7,330 deletions dist/pre/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/pre/index.js.map

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "step-security-harden-runner",
"version": "2.2.0",
"version": "2.2.1",
"description": "Security agent for GitHub-hosted runner to monitor the build process",
"main": "index.js",
"scripts": {
Expand All @@ -23,7 +23,7 @@
},
"homepage": "https://github.com/step-security/harden-runner#readme",
"dependencies": {
"@actions/cache": "^3.0.4",
"@actions/cache": "^3.1.4",
"@actions/core": "^1.5.0",
"@actions/exec": "^1.1.0",
"@actions/github": "^5.0.0",
Expand Down
99 changes: 0 additions & 99 deletions src/cache.ts
@@ -1,112 +1,13 @@
import * as core from "@actions/core";
import { HttpClient } from "@actions/http-client";
import { RequestOptions } from "@actions/http-client/lib/interfaces";
import { BearerCredentialHandler } from "@actions/http-client/lib/auth";
import * as crypto from "crypto";

const versionSalt = "1.0";
export const cacheKey = "harden-runner-cacheKey";
export const cacheFile = "/home/agent/cache.txt";

function getCacheApiUrl(resource: string): string {
const baseUrl: string = process.env["ACTIONS_CACHE_URL"] || "";
if (!baseUrl) {
throw new Error("Cache Service Url not found, unable to restore cache.");
}

const url = `${baseUrl}_apis/artifactcache/${resource}`;
core.debug(`Resource Url: ${url}`);
return url;
}

function createAcceptHeader(type: string, apiVersion: string): string {
return `${type};api-version=${apiVersion}`;
}

function getRequestOptions(): RequestOptions {
const token = process.env["ACTIONS_RUNTIME_TOKEN"] || "";

const requestOptions: RequestOptions = {
headers: {
Accept: createAcceptHeader("application/json", "6.0-preview.1"),
Authorization: `Bearer ${token}`,
},
};

return requestOptions;
}

function createHttpClient(): HttpClient {
const token = process.env["ACTIONS_RUNTIME_TOKEN"] || "";
const bhandler = new BearerCredentialHandler(token);
return new HttpClient("actions/cache", [bhandler], getRequestOptions());
}

export function getCacheVersion(
paths: string[],
compressionMethod?: CompressionMethod
): string {
const components = paths.concat(
!compressionMethod || compressionMethod === CompressionMethod.Gzip
? []
: [compressionMethod]
);

// Add salt to cache version to support breaking changes in cache entry
components.push(versionSalt);

return crypto.createHash("sha256").update(components.join("|")).digest("hex");
}

export async function getCacheEntry(
keys: string[],
paths: string[],
options?: InternalCacheOptions
): Promise<ArtifactCacheEntry | null> {
const httpClient = createHttpClient();
const version = getCacheVersion(paths, options?.compressionMethod);
const resource = `cache?keys=${encodeURIComponent(
keys.join(",")
)}&version=${version}`;

const response = await httpClient.getJson<ArtifactCacheEntry>(
getCacheApiUrl(resource)
);
if (response.statusCode === 204) {
throw new Error("Request returned 204 status");
}
if (!isSuccessStatusCode(response.statusCode)) {
throw new Error(`Cache service responded with ${response.statusCode}`);
}

const cacheResult = response.result;
const cacheDownloadUrl = cacheResult?.archiveLocation;
if (!cacheDownloadUrl) {
throw new Error("Cache still be done, but not found.");
}

return cacheResult;
}

export interface InternalCacheOptions {
compressionMethod?: CompressionMethod;
cacheSize?: number;
}

export interface ArtifactCacheEntry {
cacheKey?: string;
scope?: string;
creationTime?: string;
archiveLocation?: string;
}

function isSuccessStatusCode(statusCode?: number): boolean {
if (!statusCode) {
return false;
}
return statusCode >= 200 && statusCode < 300;
}

export enum CompressionMethod {
Gzip = "gzip",
// Long range mode was added to zstd in v1.3.2.
Expand Down
14 changes: 9 additions & 5 deletions src/setup.ts
Expand Up @@ -11,13 +11,16 @@ import isDocker from "is-docker";
import { context } from "@actions/github";
import { EOL } from "os";
import {
cacheFile,
ArtifactCacheEntry,
cacheKey,
cacheFile,
CompressionMethod,
getCacheEntry,
isValidEvent,
} from "./cache";

import {getCacheEntry} from "@actions/cache/lib/internal/cacheHttpClient"
import * as utils from '@actions/cache/lib/internal/cacheUtils'

(async () => {
try {
if (process.platform !== "linux") {
Expand Down Expand Up @@ -90,15 +93,16 @@ import {

if (isValidEvent()) {
try {
const cacheEntry = await getCacheEntry([cacheKey], [cacheFile], {
compressionMethod: CompressionMethod.ZstdWithoutLong,
let compressionMethod:CompressionMethod = await utils.getCompressionMethod()
const cacheEntry:ArtifactCacheEntry = await getCacheEntry([cacheKey], [cacheFile], {
compressionMethod: compressionMethod,
});
const url = new URL(cacheEntry.archiveLocation);
core.info(`Adding cacheHost: ${url.hostname}:443 to allowed-endpoints`);
confg.allowed_endpoints += ` ${url.hostname}:443`;
} catch (exception) {
// some exception has occurred.
core.info("Unable to fetch cacheURL");
core.info(`Unable to fetch cacheURL`);
if (confg.egress_policy === "block") {
core.info("Switching egress-policy to audit mode");
confg.egress_policy = "audit";
Expand Down

0 comments on commit 1f99358

Please sign in to comment.