Complete functionality for handling remote config file

This commit is contained in:
cnagadya
2022-11-04 14:51:41 +00:00
parent 97e5a607ba
commit b4a2fbfa16
10 changed files with 267 additions and 154 deletions

View File

@@ -48,7 +48,6 @@ function validateLicenses(
}
export async function readConfig(): Promise<ConfigurationOptions> {
const externalToken = getOptionalInput('config-repository-token')
const remoteConfigFile = getOptionalInput('remote-config-file')
const repoConfigFile = getOptionalInput('config-file')
@@ -56,14 +55,14 @@ export async function readConfig(): Promise<ConfigurationOptions> {
let remoteConfig: ConfigurationOptions = {}
let repoConfig: ConfigurationOptions = {}
if (externalToken !== undefined) {
if (remoteConfigFile === undefined) {
throw new Error('Missing required parameter: remote-config-file.')
}
remoteConfig = readConfigFile(await getRemoteConfig(remoteConfigFile))
if (remoteConfigFile !== undefined) {
const fileContents = readConfigFile(await getRemoteConfig(remoteConfigFile))
remoteConfig = {...remoteConfig, ...fileContents}
}
if (repoConfigFile !== undefined) {
repoConfig = readConfigFile(getRepoConfig(repoConfigFile))
const fileContents = readConfigFile(getRepoConfig(repoConfigFile))
repoConfig = {...repoConfig, ...fileContents}
}
// the reasoning behind reading the inline config when an external
// config file is provided is that we still want to allow users to
@@ -121,22 +120,26 @@ export function readInlineConfig(): ConfigurationOptions {
}
export function readConfigFile(configData: string): ConfigurationOptions {
const data = YAML.parse(configData)
for (const key of Object.keys(data)) {
if (key === 'allow-licenses' || key === 'deny-licenses') {
validateLicenses(key, data[key])
}
// get rid of the ugly dashes from the actions conventions
if (key.includes('-')) {
data[key.replace(/-/g, '_')] = data[key]
delete data[key]
try {
const data = YAML.parse(configData)
for (const key of Object.keys(data)) {
if (key === 'allow-licenses' || key === 'deny-licenses') {
validateLicenses(key, data[key])
}
// get rid of the ugly dashes from the actions conventions
if (key.includes('-')) {
data[key.replace(/-/g, '_')] = data[key]
delete data[key]
}
}
const values = ConfigurationOptionsSchema.parse(data)
return values
} catch (error) {
throw error
}
const values = ConfigurationOptionsSchema.parse(data)
return values
}
function getRepoConfig(filePath: string): string {
export function getRepoConfig(filePath: string): string {
try {
return fs.readFileSync(path.resolve(filePath), 'utf-8')
} catch (error) {
@@ -151,11 +154,14 @@ async function getRemoteConfig(configFile: string): Promise<string> {
const pieces = format.exec(configFile)
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
throw new Error('Invalid remote config file format.')
throw new Error(
'Invalid remote-config-file value. Expected format: OWNER/REPOSITORY/FILENAME@BRANCH '
)
}
try {
const {data} = await octokitClient(
'config-repository-token'
'remote-config-repo-token',
false
).rest.repos.getContent({
mediaType: {
format: 'raw'
@@ -165,13 +171,12 @@ async function getRemoteConfig(configFile: string): Promise<string> {
path: pieces.groups.path,
ref: pieces.groups.ref
})
if (data === undefined) {
throw new Error('Invalid content')
}
// When using mediaType.format = 'raw', the response.data is a string but this is not reflected
// in the return type of getContent. So we're casting the return value to a string.
return z.string().parse(data as unknown)
} catch (error) {
throw error
core.debug(error as string)
throw new Error('Error fetching remote config file')
}
}

View File

@@ -1,6 +1,6 @@
import spdxSatisfies from 'spdx-satisfies'
import {Change, Changes} from './schemas'
import {isSPDXValid, octokitClient as octokitClient} from './utils'
import {isSPDXValid, octokitClient} from './utils'
/**
* Loops through a list of changes, filtering and returning the

View File

@@ -18,7 +18,7 @@ import {groupDependenciesByManifest} from './utils'
async function run(): Promise<void> {
try {
const config = readConfig()
const config = await readConfig()
const refs = getRefs(config, github.context)
const changes = await dependencyGraph.compare({

View File

@@ -41,8 +41,15 @@ export function isSPDXValid(license: string): boolean {
}
}
export function octokitClient(token = 'repo-token'): Octokit {
return new Octokit({
auth: core.getInput(token, {required: true})
})
export function octokitClient(token = 'repo-token', required = true): Octokit {
const opts: Record<string, unknown> = {}
// auth is only added if token is present.
// For remote-config-files in public repos, the token is optional so it could be undefined
const auth = core.getInput(token, {required})
if (auth !== undefined) {
opts['auth'] = auth
}
return new Octokit(opts)
}