1
0
Fork 0

Add isGhes gate and refactor to clean up circular dependencies

pull/1857/head
Bassem Dghaidi 2024-11-21 04:01:44 -08:00 committed by GitHub
parent ab58a59f33
commit 267841d7bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 79 additions and 64 deletions

View File

@ -1,4 +1,4 @@
import {promises as fs} from 'fs'
import { promises as fs } from 'fs'
import * as path from 'path'
import * as cacheUtils from '../src/internal/cacheUtils'
@ -42,23 +42,3 @@ test('resolvePaths works on github workspace directory', async () => {
const paths = await cacheUtils.resolvePaths([workspace])
expect(paths.length).toBeGreaterThan(0)
})
test('isGhes returns false for github.com', async () => {
process.env.GITHUB_SERVER_URL = 'https://github.com'
expect(cacheUtils.isGhes()).toBe(false)
})
test('isGhes returns false for ghe.com', async () => {
process.env.GITHUB_SERVER_URL = 'https://somedomain.ghe.com'
expect(cacheUtils.isGhes()).toBe(false)
})
test('isGhes returns true for enterprise URL', async () => {
process.env.GITHUB_SERVER_URL = 'https://my-enterprise.github.com'
expect(cacheUtils.isGhes()).toBe(true)
})
test('isGhes returns false for ghe.localhost', () => {
process.env.GITHUB_SERVER_URL = 'https://my.domain.ghe.localhost'
expect(cacheUtils.isGhes()).toBe(false)
})

26
packages/cache/__tests__/config.test.ts vendored Normal file
View File

@ -0,0 +1,26 @@
import { promises as fs } from 'fs'
import * as config from '../src/internal/config'
beforeEach(() => {
jest.resetModules()
})
test('isGhes returns false for github.com', async () => {
process.env.GITHUB_SERVER_URL = 'https://github.com'
expect(config.isGhes()).toBe(false)
})
test('isGhes returns false for ghe.com', async () => {
process.env.GITHUB_SERVER_URL = 'https://somedomain.ghe.com'
expect(config.isGhes()).toBe(false)
})
test('isGhes returns true for enterprise URL', async () => {
process.env.GITHUB_SERVER_URL = 'https://my-enterprise.github.com'
expect(config.isGhes()).toBe(true)
})
test('isGhes returns false for ghe.localhost', () => {
process.env.GITHUB_SERVER_URL = 'https://my.domain.ghe.localhost'
expect(config.isGhes()).toBe(false)
})

View File

@ -1,27 +1,29 @@
import * as core from '@actions/core'
import * as path from 'path'
import {saveCache} from '../src/cache'
import { saveCache } from '../src/cache'
import * as cacheHttpClient from '../src/internal/cacheHttpClient'
import * as cacheUtils from '../src/internal/cacheUtils'
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
import * as config from '../src/internal/config'
import { CacheFilename, CompressionMethod } from '../src/internal/constants'
import * as tar from '../src/internal/tar'
import {TypedResponse} from '@actions/http-client/lib/interfaces'
import { TypedResponse } from '@actions/http-client/lib/interfaces'
import {
ReserveCacheResponse,
ITypedResponseWithError
} from '../src/internal/contracts'
import {HttpClientError} from '@actions/http-client'
import { HttpClientError } from '@actions/http-client'
jest.mock('../src/internal/cacheHttpClient')
jest.mock('../src/internal/cacheUtils')
jest.mock('../src/internal/config')
jest.mock('../src/internal/tar')
beforeAll(() => {
jest.spyOn(console, 'log').mockImplementation(() => {})
jest.spyOn(core, 'debug').mockImplementation(() => {})
jest.spyOn(core, 'info').mockImplementation(() => {})
jest.spyOn(core, 'warning').mockImplementation(() => {})
jest.spyOn(core, 'error').mockImplementation(() => {})
jest.spyOn(console, 'log').mockImplementation(() => { })
jest.spyOn(core, 'debug').mockImplementation(() => { })
jest.spyOn(core, 'info').mockImplementation(() => { })
jest.spyOn(core, 'warning').mockImplementation(() => { })
jest.spyOn(core, 'error').mockImplementation(() => { })
jest.spyOn(cacheUtils, 'getCacheFileName').mockImplementation(cm => {
const actualUtils = jest.requireActual('../src/internal/cacheUtils')
return actualUtils.getCacheFileName(cm)
@ -94,7 +96,7 @@ test('save with large cache outputs should fail in GHES with error message', asy
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
jest.spyOn(cacheUtils, 'isGhes').mockReturnValueOnce(true)
jest.spyOn(config, 'isGhes').mockReturnValueOnce(true)
const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache')
@ -146,7 +148,7 @@ test('save with large cache outputs should fail in GHES without error message',
.spyOn(cacheUtils, 'getCompressionMethod')
.mockReturnValueOnce(Promise.resolve(compression))
jest.spyOn(cacheUtils, 'isGhes').mockReturnValueOnce(true)
jest.spyOn(config, 'isGhes').mockReturnValueOnce(true)
const reserveCacheMock = jest
.spyOn(cacheHttpClient, 'reserveCache')
@ -229,7 +231,7 @@ test('save with server error should fail', async () => {
.mockImplementation(async () => {
const response: TypedResponse<ReserveCacheResponse> = {
statusCode: 500,
result: {cacheId},
result: { cacheId },
headers: {}
}
return response
@ -283,7 +285,7 @@ test('save with valid inputs uploads a cache', async () => {
.mockImplementation(async () => {
const response: TypedResponse<ReserveCacheResponse> = {
statusCode: 500,
result: {cacheId},
result: { cacheId },
headers: {}
}
return response

View File

@ -1,20 +1,20 @@
import * as core from '@actions/core'
import * as path from 'path'
import * as config from './internal/config'
import * as utils from './internal/cacheUtils'
import * as cacheHttpClient from './internal/cacheHttpClient'
import * as cacheTwirpClient from './internal/shared/cacheTwirpClient'
import {DownloadOptions, UploadOptions} from './options'
import {createTar, extractTar, listTar} from './internal/tar'
import { getCacheServiceVersion, isGhes } from './internal/config'
import { DownloadOptions, UploadOptions } from './options'
import { createTar, extractTar, listTar } from './internal/tar'
import {
CreateCacheEntryRequest,
FinalizeCacheEntryUploadRequest,
FinalizeCacheEntryUploadResponse,
GetCacheEntryDownloadURLRequest
} from './generated/results/api/v1/cache'
import {CacheFileSizeLimit} from './internal/constants'
import {UploadCacheFile} from './internal/blob/upload-cache'
import {DownloadCacheFile} from './internal/blob/download-cache'
import { CacheFileSizeLimit } from './internal/constants'
import { uploadCacheFile } from './internal/blob/upload-cache'
import { downloadCacheFile } from './internal/blob/download-cache'
export class ValidationError extends Error {
constructor(message: string) {
super(message)
@ -81,7 +81,7 @@ export async function restoreCache(
): Promise<string | undefined> {
checkPaths(paths)
const cacheServiceVersion: string = config.getCacheServiceVersion()
const cacheServiceVersion: string = getCacheServiceVersion()
switch (cacheServiceVersion) {
case 'v2':
return await restoreCacheV2(
@ -269,7 +269,7 @@ async function restoreCacheV2(
core.debug(`Archive path: ${archivePath}`)
core.debug(`Starting download of archive to: ${archivePath}`)
await DownloadCacheFile(response.signedDownloadUrl, archivePath)
await downloadCacheFile(response.signedDownloadUrl, archivePath)
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath)
core.info(
@ -317,7 +317,7 @@ export async function saveCache(
checkPaths(paths)
checkKey(key)
const cacheServiceVersion: string = config.getCacheServiceVersion()
const cacheServiceVersion: string = getCacheServiceVersion()
switch (cacheServiceVersion) {
case 'v2':
return await saveCacheV2(paths, key, options, enableCrossOsArchive)
@ -373,7 +373,7 @@ async function saveCacheV1(
core.debug(`File Size: ${archiveFileSize}`)
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
if (archiveFileSize > fileSizeLimit && !utils.isGhes()) {
if (archiveFileSize > fileSizeLimit && !isGhes()) {
throw new Error(
`Cache size of ~${Math.round(
archiveFileSize / (1024 * 1024)
@ -397,9 +397,9 @@ async function saveCacheV1(
} 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.`
`Cache size of ~${Math.round(
archiveFileSize / (1024 * 1024)
)} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`
)
} else {
throw new ReserveCacheError(
@ -477,7 +477,7 @@ async function saveCacheV2(
core.debug(`File Size: ${archiveFileSize}`)
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
if (archiveFileSize > CacheFileSizeLimit && !utils.isGhes()) {
if (archiveFileSize > CacheFileSizeLimit && !isGhes()) {
throw new Error(
`Cache size of ~${Math.round(
archiveFileSize / (1024 * 1024)
@ -504,7 +504,7 @@ async function saveCacheV2(
}
core.debug(`Attempting to upload cache located at: ${archivePath}`)
await UploadCacheFile(response.signedUploadUrl, archivePath)
await uploadCacheFile(response.signedUploadUrl, archivePath)
const finalizeRequest: FinalizeCacheEntryUploadRequest = {
key,

View File

@ -6,7 +6,7 @@ import {
BlobDownloadOptions
} from '@azure/storage-blob'
export async function DownloadCacheFile(
export async function downloadCacheFile(
signedUploadURL: string,
archivePath: string
): Promise<{}> {

View File

@ -5,7 +5,7 @@ import {
BlockBlobParallelUploadOptions
} from '@azure/storage-blob'
export async function UploadCacheFile(
export async function uploadCacheFile(
signedUploadURL: string,
archivePath: string
): Promise<{}> {

View File

@ -133,19 +133,6 @@ export function assertDefined<T>(name: string, value?: T): T {
return value
}
export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
)
const hostname = ghUrl.hostname.trimEnd().toUpperCase()
const isGitHubHost = hostname === 'GITHUB.COM'
const isGheHost =
hostname.endsWith('.GHE.COM') || hostname.endsWith('.GHE.LOCALHOST')
return !isGitHubHost && !isGheHost
}
export function getCacheVersion(
paths: string[],
compressionMethod?: CompressionMethod,

View File

@ -1,9 +1,29 @@
export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
)
const hostname = ghUrl.hostname.trimEnd().toUpperCase()
const isGitHubHost = hostname === 'GITHUB.COM'
const isGheHost = hostname.endsWith('.GHE.COM')
const isLocalHost = hostname.endsWith('.LOCALHOST')
return !isGitHubHost && !isGheHost && !isLocalHost
}
export function getCacheServiceVersion(): string {
// Cache service v2 is not supported on GHES. We will default to
// cache service v1 even if the feature flag was enabled by user.
if (isGhes()) return 'v1'
return process.env['ACTIONS_CACHE_SERVICE_V2'] ? 'v2' : 'v1'
}
export function getCacheServiceURL(): string {
const version = getCacheServiceVersion()
// Based on the version of the cache service, we will determine which
// URL to use.
switch (version) {
case 'v1':
return (