Compare commits

...
Author SHA1 Message Date
Thomas Boop a4d12de60e glob 0.3.0 release 2022-04-18 15:01:30 -04:00
Thomas Boop e105138efe Revert "Exec 1.2.0 patch"
c9f7927778
2022-04-18 15:01:30 -04:00
Thomas BoopandGitHub 367a6c2423 Exec 1.2.0 patch (#1055) 2022-04-18 14:52:32 -04:00
8f2bd5d713 Added verbose mode in hashFiles (#1052)
* Added verbose mode in hashFiles

* Code formatting

* Change verboseMode arg to verbose

Co-authored-by: Thomas Boop <[email protected]>

* Using verbose instead of verboseMode as arg

Co-authored-by: Thomas Boop <[email protected]>
2022-04-18 14:29:24 -04:00
Anurag ChauhanandGitHub 7654d97eb6 Merge pull request #1050 from actions/fix_cache_error_type
Fix error type so that cache size limit violation is shown as warning( similar to previous error)
2022-04-07 14:46:23 +05:30
Anurag ChauhanandGitHub 0b2505c754 Fix error type so that size limit violation is shown as warning 2022-04-07 09:08:16 +00:00
f8a69bc473 Added cacheSize in ReserveCache API request (#1044)
* Added cacheSize in ReserveCache API request

* minor

* minor

* minor

* Cleanup

* package-lock revert

* Modified tests

* New Response Type

* cleanup

* Linting

* Lint fix

* Resolved comments

* Added tests

* package-lock

* Resolved package-lock mismatch

* Liniting

* Update packages/cache/src/cache.ts

Co-authored-by: Bishal Prasad <[email protected]>

* Linting issue

* Resolved few comments

* version upgrade

* Savecache tests

* RequestUtil test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

Co-authored-by: Apple <[email protected]>
Co-authored-by: Bishal Prasad <[email protected]>
2022-04-04 16:21:58 +05:30
Deepak DahiyaandGitHub 03eca1b0c7 Revert "T dedah/cache size" (#1042) 2022-04-01 02:10:08 +05:30
Deepak DahiyaandGitHub 4b12bd3649 Merge pull request #1041 from t-dedah/t-dedah/cacheSize
T dedah/cache size
2022-04-01 02:07:14 +05:30
Apple 6cd8286138 Resolved comments 2022-04-01 01:41:12 +05:30
Apple 3abbc6c24c Lint fix 2022-04-01 01:16:43 +05:30
Luke TomlinsonandGitHub d594f1e4b3 Fix npm audit (#1040) 2022-03-31 14:40:06 -04:00
Luke TomlinsonandGitHub 4a2602dd58 Fix test for windows 2022 (#1039) 2022-03-31 14:39:39 -04:00
Luke TomlinsonandGitHub 745f129332 Update @actions/github to 5.0.1 (#1038)
* Update @actions/github to 5.0.1

* Fix package-lock.json
2022-03-31 13:53:55 -04:00
Deepak DahiyaandGitHub daa24d7958 Linting 2022-03-31 10:41:54 +00:00
Deepak DahiyaandGitHub bda035c74d cleanup 2022-03-31 09:44:40 +00:00
Deepak DahiyaandGitHub 79acd5bac4 New Response Type 2022-03-31 09:42:59 +00:00
Apple b602df7c05 Modified tests 2022-03-30 13:27:36 +05:30
Deepak DahiyaandGitHub 80a66f3298 package-lock revert 2022-03-30 07:33:48 +00:00
Deepak DahiyaandGitHub 7756e7c4cb Cleanup 2022-03-30 07:22:56 +00:00
Deepak DahiyaandGitHub 6d774fcb59 minor 2022-03-29 22:21:15 +00:00
Deepak DahiyaandGitHub f05c940e43 minor 2022-03-29 22:20:22 +00:00
Deepak DahiyaandGitHub a71585a450 minor 2022-03-29 22:19:10 +00:00
Deepak DahiyaandGitHub 76ac2fcd59 Added cacheSize in ReserveCache API request 2022-03-29 22:17:04 +00:00
20 changed files with 16533 additions and 3079 deletions
+16287 -2997
View File
File diff suppressed because it is too large Load Diff
+33 -1
View File
@@ -1,5 +1,6 @@
import {retry} from '../src/internal/requestUtils' import {retry, retryTypedResponse} from '../src/internal/requestUtils'
import {HttpClientError} from '@actions/http-client' import {HttpClientError} from '@actions/http-client'
import * as requestUtils from '../src/internal/requestUtils'
interface ITestResponse { interface ITestResponse {
statusCode: number statusCode: number
@@ -145,3 +146,34 @@ test('retry converts errors to response object', async () => {
null null
) )
}) })
test('retryTypedResponse gives an error with error message', async () => {
const httpClientError = new HttpClientError(
'The cache filesize must be between 0 and 10 * 1024 * 1024 bytes',
400
)
jest.spyOn(requestUtils, 'retry').mockReturnValue(
new Promise(resolve => {
resolve(httpClientError)
})
)
try {
await retryTypedResponse<string>(
'reserveCache',
async () =>
new Promise(resolve => {
resolve({
statusCode: 400,
result: '',
headers: {},
error: httpClientError
})
})
)
} catch (error) {
expect(error).toHaveProperty(
'message',
'The cache filesize must be between 0 and 10 * 1024 * 1024 bytes'
)
}
})
+117 -13
View File
@@ -5,6 +5,12 @@ import * as cacheHttpClient from '../src/internal/cacheHttpClient'
import * as cacheUtils from '../src/internal/cacheUtils' import * as cacheUtils from '../src/internal/cacheUtils'
import {CacheFilename, CompressionMethod} from '../src/internal/constants' import {CacheFilename, CompressionMethod} from '../src/internal/constants'
import * as tar from '../src/internal/tar' import * as tar from '../src/internal/tar'
import {ITypedResponse} from '@actions/http-client/interfaces'
import {
ReserveCacheResponse,
ITypedResponseWithError
} from '../src/internal/contracts'
import {HttpClientError} from '@actions/http-client'
jest.mock('../src/internal/cacheHttpClient') jest.mock('../src/internal/cacheHttpClient')
jest.mock('../src/internal/cacheUtils') jest.mock('../src/internal/cacheUtils')
@@ -16,16 +22,13 @@ beforeAll(() => {
jest.spyOn(core, 'info').mockImplementation(() => {}) jest.spyOn(core, 'info').mockImplementation(() => {})
jest.spyOn(core, 'warning').mockImplementation(() => {}) jest.spyOn(core, 'warning').mockImplementation(() => {})
jest.spyOn(core, 'error').mockImplementation(() => {}) jest.spyOn(core, 'error').mockImplementation(() => {})
jest.spyOn(cacheUtils, 'getCacheFileName').mockImplementation(cm => { jest.spyOn(cacheUtils, 'getCacheFileName').mockImplementation(cm => {
const actualUtils = jest.requireActual('../src/internal/cacheUtils') const actualUtils = jest.requireActual('../src/internal/cacheUtils')
return actualUtils.getCacheFileName(cm) return actualUtils.getCacheFileName(cm)
}) })
jest.spyOn(cacheUtils, 'resolvePaths').mockImplementation(async filePaths => { jest.spyOn(cacheUtils, 'resolvePaths').mockImplementation(async filePaths => {
return filePaths.map(x => path.resolve(x)) return filePaths.map(x => path.resolve(x))
}) })
jest.spyOn(cacheUtils, 'createTempDirectory').mockImplementation(async () => { jest.spyOn(cacheUtils, 'createTempDirectory').mockImplementation(async () => {
return Promise.resolve('/foo/bar') return Promise.resolve('/foo/bar')
}) })
@@ -70,6 +73,98 @@ test('save with large cache outputs should fail', async () => {
expect(getCompressionMock).toHaveBeenCalledTimes(1) expect(getCompressionMock).toHaveBeenCalledTimes(1)
}) })
test('save with large cache outputs should fail in GHES with error message', async () => {
const filePath = 'node_modules'
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = [path.resolve(filePath)]
const createTarMock = jest.spyOn(tar, 'createTar')
const cacheSize = 11 * 1024 * 1024 * 1024 //~11GB, over the 10GB limit
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(cacheSize)
const compression = CompressionMethod.Gzip
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
jest.spyOn(cacheUtils, 'isGhes').mockReturnValueOnce(true)
const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache')
.mockImplementation(async () => {
const response: ITypedResponseWithError<ReserveCacheResponse> = {
statusCode: 400,
result: null,
headers: {},
error: new HttpClientError(
'The cache filesize must be between 0 and 1073741824 bytes',
400
)
}
return response
})
await expect(saveCache([filePath], primaryKey)).rejects.toThrowError(
'The cache filesize must be between 0 and 1073741824 bytes'
)
const archiveFolder = '/foo/bar'
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
cachePaths,
compression
)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('save with large cache outputs should fail in GHES without error message', async () => {
const filePath = 'node_modules'
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
const cachePaths = [path.resolve(filePath)]
const createTarMock = jest.spyOn(tar, 'createTar')
const cacheSize = 11 * 1024 * 1024 * 1024 //~11GB, over the 10GB limit
jest
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
.mockReturnValueOnce(cacheSize)
const compression = CompressionMethod.Gzip
const getCompressionMock = jest
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
jest.spyOn(cacheUtils, 'isGhes').mockReturnValueOnce(true)
const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache')
.mockImplementation(async () => {
const response: ITypedResponseWithError<ReserveCacheResponse> = {
statusCode: 400,
result: null,
headers: {}
}
return response
})
await expect(saveCache([filePath], primaryKey)).rejects.toThrowError(
'Cache size of ~11264 MB (11811160064 B) is over the data cap limit, not saving cache.'
)
const archiveFolder = '/foo/bar'
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledWith(
archiveFolder,
cachePaths,
compression
)
expect(getCompressionMock).toHaveBeenCalledTimes(1)
})
test('save with reserve cache failure should fail', async () => { test('save with reserve cache failure should fail', async () => {
const paths = ['node_modules'] const paths = ['node_modules']
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43' const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
@@ -77,7 +172,12 @@ test('save with reserve cache failure should fail', async () => {
const reserveCacheMock = jest const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache') .spyOn(cacheHttpClient, 'reserveCache')
.mockImplementation(async () => { .mockImplementation(async () => {
return -1 const response: ITypedResponse<ReserveCacheResponse> = {
statusCode: 500,
result: null,
headers: {}
}
return response
}) })
const createTarMock = jest.spyOn(tar, 'createTar') const createTarMock = jest.spyOn(tar, 'createTar')
@@ -94,7 +194,7 @@ test('save with reserve cache failure should fail', async () => {
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, paths, { expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, paths, {
compressionMethod: compression compressionMethod: compression
}) })
expect(createTarMock).toHaveBeenCalledTimes(0) expect(createTarMock).toHaveBeenCalledTimes(1)
expect(saveCacheMock).toHaveBeenCalledTimes(0) expect(saveCacheMock).toHaveBeenCalledTimes(0)
expect(getCompressionMock).toHaveBeenCalledTimes(1) expect(getCompressionMock).toHaveBeenCalledTimes(1)
}) })
@@ -108,7 +208,12 @@ test('save with server error should fail', async () => {
const reserveCacheMock = jest const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache') .spyOn(cacheHttpClient, 'reserveCache')
.mockImplementation(async () => { .mockImplementation(async () => {
return cacheId const response: ITypedResponse<ReserveCacheResponse> = {
statusCode: 500,
result: {cacheId},
headers: {}
}
return response
}) })
const createTarMock = jest.spyOn(tar, 'createTar') const createTarMock = jest.spyOn(tar, 'createTar')
@@ -130,17 +235,14 @@ test('save with server error should fail', async () => {
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], { expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], {
compressionMethod: compression compressionMethod: compression
}) })
const archiveFolder = '/foo/bar' const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd) const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
expect(createTarMock).toHaveBeenCalledTimes(1) expect(createTarMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledWith( expect(createTarMock).toHaveBeenCalledWith(
archiveFolder, archiveFolder,
cachePaths, cachePaths,
compression compression
) )
expect(saveCacheMock).toHaveBeenCalledTimes(1) expect(saveCacheMock).toHaveBeenCalledTimes(1)
expect(saveCacheMock).toHaveBeenCalledWith(cacheId, archiveFile, undefined) expect(saveCacheMock).toHaveBeenCalledWith(cacheId, archiveFile, undefined)
expect(getCompressionMock).toHaveBeenCalledTimes(1) expect(getCompressionMock).toHaveBeenCalledTimes(1)
@@ -155,7 +257,12 @@ test('save with valid inputs uploads a cache', async () => {
const reserveCacheMock = jest const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache') .spyOn(cacheHttpClient, 'reserveCache')
.mockImplementation(async () => { .mockImplementation(async () => {
return cacheId const response: ITypedResponse<ReserveCacheResponse> = {
statusCode: 500,
result: {cacheId},
headers: {}
}
return response
}) })
const createTarMock = jest.spyOn(tar, 'createTar') const createTarMock = jest.spyOn(tar, 'createTar')
@@ -171,17 +278,14 @@ test('save with valid inputs uploads a cache', async () => {
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], { expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], {
compressionMethod: compression compressionMethod: compression
}) })
const archiveFolder = '/foo/bar' const archiveFolder = '/foo/bar'
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd) const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
expect(createTarMock).toHaveBeenCalledTimes(1) expect(createTarMock).toHaveBeenCalledTimes(1)
expect(createTarMock).toHaveBeenCalledWith( expect(createTarMock).toHaveBeenCalledWith(
archiveFolder, archiveFolder,
cachePaths, cachePaths,
compression compression
) )
expect(saveCacheMock).toHaveBeenCalledTimes(1) expect(saveCacheMock).toHaveBeenCalledTimes(1)
expect(saveCacheMock).toHaveBeenCalledWith(cacheId, archiveFile, undefined) expect(saveCacheMock).toHaveBeenCalledWith(cacheId, archiveFile, undefined)
expect(getCompressionMock).toHaveBeenCalledTimes(1) expect(getCompressionMock).toHaveBeenCalledTimes(1)
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/cache", "name": "@actions/cache",
"version": "2.0.0", "version": "2.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/cache", "name": "@actions/cache",
"version": "2.0.0", "version": "2.0.2",
"preview": true, "preview": true,
"description": "Actions cache lib", "description": "Actions cache lib",
"keywords": [ "keywords": [
+29 -13
View File
@@ -152,17 +152,7 @@ export async function saveCache(
checkKey(key) checkKey(key)
const compressionMethod = await utils.getCompressionMethod() const compressionMethod = await utils.getCompressionMethod()
let cacheId = null
core.debug('Reserving Cache')
const cacheId = await cacheHttpClient.reserveCache(key, paths, {
compressionMethod
})
if (cacheId === -1) {
throw new ReserveCacheError(
`Unable to reserve cache with key ${key}, another job may be creating this cache.`
)
}
core.debug(`Cache ID: ${cacheId}`)
const cachePaths = await utils.resolvePaths(paths) const cachePaths = await utils.resolvePaths(paths)
core.debug('Cache Paths:') core.debug('Cache Paths:')
@@ -181,11 +171,12 @@ export async function saveCache(
if (core.isDebug()) { if (core.isDebug()) {
await listTar(archivePath, compressionMethod) await listTar(archivePath, compressionMethod)
} }
const fileSizeLimit = 10 * 1024 * 1024 * 1024 // 10GB per repo limit const fileSizeLimit = 10 * 1024 * 1024 * 1024 // 10GB per repo limit
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath) const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath)
core.debug(`File Size: ${archiveFileSize}`) core.debug(`File Size: ${archiveFileSize}`)
if (archiveFileSize > fileSizeLimit) {
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
if (archiveFileSize > fileSizeLimit && !utils.isGhes()) {
throw new Error( throw new Error(
`Cache size of ~${Math.round( `Cache size of ~${Math.round(
archiveFileSize / (1024 * 1024) archiveFileSize / (1024 * 1024)
@@ -193,6 +184,31 @@ export async function saveCache(
) )
} }
core.debug('Reserving Cache')
const reserveCacheResponse = await cacheHttpClient.reserveCache(
key,
paths,
{
compressionMethod,
cacheSize: archiveFileSize
}
)
if (reserveCacheResponse?.result?.cacheId) {
cacheId = reserveCacheResponse?.result?.cacheId
} else if (reserveCacheResponse?.statusCode === 400) {
throw new Error(
reserveCacheResponse?.error?.message ??
`Cache size of ~${Math.round(
archiveFileSize / (1024 * 1024)
)} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`
)
} else {
throw new ReserveCacheError(
`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${reserveCacheResponse?.error?.message}`
)
}
core.debug(`Saving Cache (ID: ${cacheId})`) core.debug(`Saving Cache (ID: ${cacheId})`)
await cacheHttpClient.saveCache(cacheId, archivePath, options) await cacheHttpClient.saveCache(cacheId, archivePath, options)
} finally { } finally {
+6 -4
View File
@@ -13,7 +13,8 @@ import {
InternalCacheOptions, InternalCacheOptions,
CommitCacheRequest, CommitCacheRequest,
ReserveCacheRequest, ReserveCacheRequest,
ReserveCacheResponse ReserveCacheResponse,
ITypedResponseWithError
} from './contracts' } from './contracts'
import {downloadCacheHttpClient, downloadCacheStorageSDK} from './downloadUtils' import {downloadCacheHttpClient, downloadCacheStorageSDK} from './downloadUtils'
import { import {
@@ -143,13 +144,14 @@ export async function reserveCache(
key: string, key: string,
paths: string[], paths: string[],
options?: InternalCacheOptions options?: InternalCacheOptions
): Promise<number> { ): Promise<ITypedResponseWithError<ReserveCacheResponse>> {
const httpClient = createHttpClient() const httpClient = createHttpClient()
const version = getCacheVersion(paths, options?.compressionMethod) const version = getCacheVersion(paths, options?.compressionMethod)
const reserveCacheRequest: ReserveCacheRequest = { const reserveCacheRequest: ReserveCacheRequest = {
key, key,
version version,
cacheSize: options?.cacheSize
} }
const response = await retryTypedResponse('reserveCache', async () => const response = await retryTypedResponse('reserveCache', async () =>
httpClient.postJson<ReserveCacheResponse>( httpClient.postJson<ReserveCacheResponse>(
@@ -157,7 +159,7 @@ export async function reserveCache(
reserveCacheRequest reserveCacheRequest
) )
) )
return response?.result?.cacheId ?? -1 return response
} }
function getContentRange(start: number, end: number): string { function getContentRange(start: number, end: number): string {
+7
View File
@@ -123,3 +123,10 @@ export function assertDefined<T>(name: string, value?: T): T {
return value return value
} }
export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
)
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'
}
+8
View File
@@ -1,4 +1,10 @@
import {CompressionMethod} from './constants' import {CompressionMethod} from './constants'
import {ITypedResponse} from '@actions/http-client/interfaces'
import {HttpClientError} from '@actions/http-client'
export interface ITypedResponseWithError<T> extends ITypedResponse<T> {
error?: HttpClientError
}
export interface ArtifactCacheEntry { export interface ArtifactCacheEntry {
cacheKey?: string cacheKey?: string
@@ -14,6 +20,7 @@ export interface CommitCacheRequest {
export interface ReserveCacheRequest { export interface ReserveCacheRequest {
key: string key: string
version?: string version?: string
cacheSize?: number
} }
export interface ReserveCacheResponse { export interface ReserveCacheResponse {
@@ -22,4 +29,5 @@ export interface ReserveCacheResponse {
export interface InternalCacheOptions { export interface InternalCacheOptions {
compressionMethod?: CompressionMethod compressionMethod?: CompressionMethod
cacheSize?: number
} }
+7 -8
View File
@@ -1,10 +1,8 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {HttpCodes, HttpClientError} from '@actions/http-client' import {HttpCodes, HttpClientError} from '@actions/http-client'
import { import {IHttpClientResponse} from '@actions/http-client/interfaces'
IHttpClientResponse,
ITypedResponse
} from '@actions/http-client/interfaces'
import {DefaultRetryDelay, DefaultRetryAttempts} from './constants' import {DefaultRetryDelay, DefaultRetryAttempts} from './constants'
import {ITypedResponseWithError} from './contracts'
export function isSuccessStatusCode(statusCode?: number): boolean { export function isSuccessStatusCode(statusCode?: number): boolean {
if (!statusCode) { if (!statusCode) {
@@ -94,14 +92,14 @@ export async function retry<T>(
export async function retryTypedResponse<T>( export async function retryTypedResponse<T>(
name: string, name: string,
method: () => Promise<ITypedResponse<T>>, method: () => Promise<ITypedResponseWithError<T>>,
maxAttempts = DefaultRetryAttempts, maxAttempts = DefaultRetryAttempts,
delay = DefaultRetryDelay delay = DefaultRetryDelay
): Promise<ITypedResponse<T>> { ): Promise<ITypedResponseWithError<T>> {
return await retry( return await retry(
name, name,
method, method,
(response: ITypedResponse<T>) => response.statusCode, (response: ITypedResponseWithError<T>) => response.statusCode,
maxAttempts, maxAttempts,
delay, delay,
// If the error object contains the statusCode property, extract it and return // If the error object contains the statusCode property, extract it and return
@@ -111,7 +109,8 @@ export async function retryTypedResponse<T>(
return { return {
statusCode: error.statusCode, statusCode: error.statusCode,
result: null, result: null,
headers: {} headers: {},
error
} }
} else { } else {
return undefined return undefined
+2
View File
@@ -1,5 +1,7 @@
# @actions/github Releases # @actions/github Releases
### 5.0.1
- [Update Octokit Dependencies](https://github.com/actions/toolkit/pull/1037)
### 5.0.0 ### 5.0.0
- [Update @actions/github to include latest octokit definitions](https://github.com/actions/toolkit/pull/783) - [Update @actions/github to include latest octokit definitions](https://github.com/actions/toolkit/pull/783)
- [Add urls to context](https://github.com/actions/toolkit/pull/794) - [Add urls to context](https://github.com/actions/toolkit/pull/794)
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "@actions/github", "name": "@actions/github",
"version": "5.0.0", "version": "5.0.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@actions/github", "name": "@actions/github",
"version": "5.0.0", "version": "5.0.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/http-client": "^1.0.11", "@actions/http-client": "^1.0.11",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/github", "name": "@actions/github",
"version": "5.0.0", "version": "5.0.1",
"description": "Actions github lib", "description": "Actions github lib",
"keywords": [ "keywords": [
"github", "github",
+3
View File
@@ -1,5 +1,8 @@
# @actions/glob Releases # @actions/glob Releases
### 0.3.0
- Added a `verbose` option to HashFiles [#1052](https://github.com/actions/toolkit/pull/1052/files)
### 0.2.1 ### 0.2.1
- Update `lockfileVersion` to `v2` in `package-lock.json [#1023](https://github.com/actions/toolkit/pull/1023) - Update `lockfileVersion` to `v2` in `package-lock.json [#1023](https://github.com/actions/toolkit/pull/1023)
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/glob", "name": "@actions/glob",
"version": "0.2.1", "version": "0.3.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/glob", "name": "@actions/glob",
"version": "0.2.1", "version": "0.3.0",
"preview": true, "preview": true,
"description": "Actions glob lib", "description": "Actions glob lib",
"keywords": [ "keywords": [
+3 -2
View File
@@ -26,12 +26,13 @@ export async function create(
*/ */
export async function hashFiles( export async function hashFiles(
patterns: string, patterns: string,
options?: HashFileOptions options?: HashFileOptions,
verbose: Boolean = false
): Promise<string> { ): Promise<string> {
let followSymbolicLinks = true let followSymbolicLinks = true
if (options && typeof options.followSymbolicLinks === 'boolean') { if (options && typeof options.followSymbolicLinks === 'boolean') {
followSymbolicLinks = options.followSymbolicLinks followSymbolicLinks = options.followSymbolicLinks
} }
const globber = await create(patterns, {followSymbolicLinks}) const globber = await create(patterns, {followSymbolicLinks})
return _hashFiles(globber) return _hashFiles(globber, verbose)
} }
+10 -6
View File
@@ -6,19 +6,23 @@ import * as util from 'util'
import * as path from 'path' import * as path from 'path'
import {Globber} from './glob' import {Globber} from './glob'
export async function hashFiles(globber: Globber): Promise<string> { export async function hashFiles(
globber: Globber,
verbose: Boolean = false
): Promise<string> {
const writeDelegate = verbose ? core.info : core.debug
let hasMatch = false let hasMatch = false
const githubWorkspace = process.env['GITHUB_WORKSPACE'] ?? process.cwd() const githubWorkspace = process.env['GITHUB_WORKSPACE'] ?? process.cwd()
const result = crypto.createHash('sha256') const result = crypto.createHash('sha256')
let count = 0 let count = 0
for await (const file of globber.globGenerator()) { for await (const file of globber.globGenerator()) {
core.debug(file) writeDelegate(file)
if (!file.startsWith(`${githubWorkspace}${path.sep}`)) { if (!file.startsWith(`${githubWorkspace}${path.sep}`)) {
core.debug(`Ignore '${file}' since it is not under GITHUB_WORKSPACE.`) writeDelegate(`Ignore '${file}' since it is not under GITHUB_WORKSPACE.`)
continue continue
} }
if (fs.statSync(file).isDirectory()) { if (fs.statSync(file).isDirectory()) {
core.debug(`Skip directory '${file}'.`) writeDelegate(`Skip directory '${file}'.`)
continue continue
} }
const hash = crypto.createHash('sha256') const hash = crypto.createHash('sha256')
@@ -33,10 +37,10 @@ export async function hashFiles(globber: Globber): Promise<string> {
result.end() result.end()
if (hasMatch) { if (hasMatch) {
core.debug(`Found ${count} files to hash.`) writeDelegate(`Found ${count} files to hash.`)
return result.digest('hex') return result.digest('hex')
} else { } else {
core.debug(`No matches found for glob`) writeDelegate(`No matches found for glob`)
return '' return ''
} }
} }
+2 -16
View File
@@ -332,23 +332,9 @@ describe('rmRF', () => {
await assertExists(filePath) await assertExists(filePath)
const fd = await fs.open(filePath, 'r') const fd = await fs.open(filePath, 'r')
await io.rmRF(testPath)
let worked: boolean await assertNotExists(testPath)
try {
await io.rmRF(testPath)
worked = true
} catch (err) {
worked = false
}
if (os.platform() === 'win32') {
expect(worked).toBe(false)
await assertExists(testPath)
} else {
expect(worked).toBe(true)
await assertNotExists(testPath)
}
await fd.close() await fd.close()
await io.rmRF(testPath) await io.rmRF(testPath)
+12 -12
View File
@@ -164,9 +164,9 @@
"dev": true "dev": true
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true "dev": true
}, },
"node_modules/mkdirp": { "node_modules/mkdirp": {
@@ -217,9 +217,9 @@
} }
}, },
"node_modules/pathval": { "node_modules/pathval": {
"version": "1.1.0", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "*" "node": "*"
@@ -404,9 +404,9 @@
"dev": true "dev": true
}, },
"minimist": { "minimist": {
"version": "1.2.5", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true "dev": true
}, },
"mkdirp": { "mkdirp": {
@@ -450,9 +450,9 @@
} }
}, },
"pathval": { "pathval": {
"version": "1.1.0", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"dev": true "dev": true
}, },
"propagate": { "propagate": {