Replace forked cache by official npm (#21)

* Replace forked cache by official npm

* Follow the same validation as @action/cache

* Remove debug log
This commit is contained in:
Tam Mach
2020-05-23 19:25:16 +10:00
committed by GitHub
parent 04eca20383
commit 3395f777a4
9 changed files with 2289 additions and 1581 deletions

View File

@ -1,9 +1,11 @@
import * as cache from "@actions/cache"
import * as core from "@actions/core"
import restore from "cache/lib/restore"
import save from "cache/lib/save"
import * as crypto from "crypto"
import * as fs from "fs"
import { Events, State } from "./constants"
import * as utils from "./utils/actionUtils"
function checksumFile(hashName: string, path: string): Promise<string> {
return new Promise((resolve, reject) => {
const hash = crypto.createHash(hashName)
@ -52,30 +54,82 @@ async function buildCacheKeys(): Promise<string[]> {
}
export async function restoreCache(): Promise<void> {
if (!utils.isValidEvent()) {
utils.logWarning(
`Event Validation Error: The event type ${process.env[Events.Key]} is not supported because it's not tied to a branch or tag ref.`
)
return
}
const startedAt = Date.now()
const keys = await buildCacheKeys()
const primaryKey = keys.pop()
const restoreKeys = keys.reverse()
core.info(`Primary analysis cache key is '${primaryKey}', restore keys are '${restoreKeys.join(` | `)}'`)
process.env[`INPUT_RESTORE-KEYS`] = restoreKeys.join(`\n`)
process.env.INPUT_KEY = primaryKey
process.env.INPUT_PATH = getCacheDirs().join(`\n`)
// Tell golangci-lint to use our cache directory.
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir()
await restore()
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`)
if (!primaryKey) {
utils.logWarning(`Invalid primary key`)
return
}
core.saveState(State.CachePrimaryKey, primaryKey)
try {
const cacheKey = await cache.restoreCache(getCacheDirs(), primaryKey, restoreKeys)
if (!cacheKey) {
core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(", ")}`)
return
}
// Store the matched cache key
utils.setCacheState(cacheKey)
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey)
utils.setCacheHitOutput(isExactKeyMatch)
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`)
} catch (error) {
if (error.name === cache.ValidationError.name) {
throw error
} else {
core.warning(error.message)
}
}
}
export async function saveCache(): Promise<void> {
// Validate inputs, this can cause task failure
if (!utils.isValidEvent()) {
utils.logWarning(
`Event Validation Error: The event type ${process.env[Events.Key]} is not supported because it's not tied to a branch or tag ref.`
)
return
}
const startedAt = Date.now()
const cacheDirs = getCacheDirs()
process.env.INPUT_PATH = cacheDirs.join(`\n`)
const primaryKey = core.getState(State.CachePrimaryKey)
if (!primaryKey) {
utils.logWarning(`Error retrieving key from state.`)
return
}
await save()
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`)
const state = utils.getCacheState()
if (utils.isExactKeyMatch(primaryKey, state)) {
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`)
return
}
try {
await cache.saveCache(cacheDirs, primaryKey)
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`)
} catch (error) {
if (error.name === cache.ValidationError.name) {
throw error
} else if (error.name === cache.ReserveCacheError.name) {
core.info(error.message)
} else {
core.info(`[warning] ${error.message}`)
}
}
}

22
src/constants.ts Normal file
View File

@ -0,0 +1,22 @@
export enum Inputs {
Key = "key",
Path = "path",
RestoreKeys = "restore-keys",
}
export enum Outputs {
CacheHit = "cache-hit",
}
export enum State {
CachePrimaryKey = "CACHE_KEY",
CacheMatchedKey = "CACHE_RESULT",
}
export enum Events {
Key = "GITHUB_EVENT_NAME",
Push = "push",
PullRequest = "pull_request",
}
export const RefKey = "GITHUB_REF"

47
src/utils/actionUtils.ts Normal file
View File

@ -0,0 +1,47 @@
import * as core from "@actions/core"
import { Outputs, RefKey, State } from "../constants"
export function isExactKeyMatch(key: string, cacheKey?: string): boolean {
return !!(
cacheKey &&
cacheKey.localeCompare(key, undefined, {
sensitivity: "accent",
}) === 0
)
}
export function setCacheState(state: string): void {
core.saveState(State.CacheMatchedKey, state)
}
export function setCacheHitOutput(isCacheHit: boolean): void {
core.setOutput(Outputs.CacheHit, isCacheHit.toString())
}
export function setOutputAndState(key: string, cacheKey?: string): void {
setCacheHitOutput(isExactKeyMatch(key, cacheKey))
// Store the matched cache key if it exists
cacheKey && setCacheState(cacheKey)
}
export function getCacheState(): string | undefined {
const cacheKey = core.getState(State.CacheMatchedKey)
if (cacheKey) {
core.debug(`Cache state/key: ${cacheKey}`)
return cacheKey
}
return undefined
}
export function logWarning(message: string): void {
const warningPrefix = "[warning]"
core.info(`${warningPrefix}${message}`)
}
// Cache token authorized for all events that are tied to a ref
// See GitHub Context https://help.github.com/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context
export function isValidEvent(): boolean {
return RefKey in process.env && Boolean(process.env[RefKey])
}