Skip to content

Commit

Permalink
feat: enhance custom default paths logic to allow specifying a branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Germanov committed Jan 24, 2025
1 parent 742a63d commit 2ea9ba2
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 2 deletions.
53 changes: 51 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,30 @@ export async function getDefaultConfig (server: string, apiURL: string, version:
}
}

function processCustomDefaultsPath(path: string, currentBranch?: string): string {
// Handle absolute GitHub URLs
if (path.startsWith('http')) {
const url = new URL(path)
return url.toString()
}

// Handle relative paths with branch references (org/repo/path@branch)
const branchMatch = path.match(/^([^@]+)@(.+)$/)
if (branchMatch) {
const [, filePath, branch] = branchMatch
return `${process.env.GITHUB_SERVER_URL}/${filePath}?ref=${branch}`
}

// For simple file paths, don't add server URL or branch
if (path.startsWith('./') || path.startsWith('../') || !path.includes('/')) {
return path
}

// Handle organization/repository paths (without branch reference)
const branch = currentBranch ?? process.env.GITHUB_REF_NAME ?? 'main'
return `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/${path}?ref=${branch}`
}

export async function downloadDefaultConfig (server: string, apiURL: string, version: string, token: string, owner: string, repository: string, customDefaultsPaths: string): Promise<UploadResponse> {
let defaultsPaths: string[] = []

Expand All @@ -51,8 +75,11 @@ export async function downloadDefaultConfig (server: string, apiURL: string, ver
defaultsPaths = defaultsPaths.concat([enterpriseDefaultsURL])
}

const currentBranch = process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME
const customDefaultsPathsArray = customDefaultsPaths !== '' ? customDefaultsPaths.split(',') : []
defaultsPaths = defaultsPaths.concat(customDefaultsPathsArray)
defaultsPaths = defaultsPaths.concat(
customDefaultsPathsArray.map(path => processCustomDefaultsPath(path.trim(), currentBranch))
)
const defaultsPathsArgs = defaultsPaths.map((url) => ['--defaultsFile', url]).flat()

const piperPath = internalActionVariables.piperBinPath
Expand All @@ -68,8 +95,30 @@ export async function downloadDefaultConfig (server: string, apiURL: string, ver
if (customDefaultsPathsArray.length === 0) {
defaultConfigs = [defaultConfigs]
}
// Ensure defaultConfigs is always an array
if (!Array.isArray(defaultConfigs)) {
defaultConfigs = [defaultConfigs]
}

// When saving files, sanitize filenames by removing query parameters
const sanitizeFilename = (url: string): string => {
try {
const parsed = new URL(url)
return path.basename(parsed.pathname)
} catch {
return path.basename(url)
}
}

interface DefaultConfig {
filepath: string;
content: string;
}

const savedDefaultsPaths = saveDefaultConfigs(defaultConfigs)
const savedDefaultsPaths = saveDefaultConfigs(defaultConfigs.map((config: DefaultConfig) => ({
...config,
filepath: sanitizeFilename(config.filepath)
})))
const uploadResponse = await uploadDefaultConfigArtifact(savedDefaultsPaths)
exportVariable('defaultsFlags', generateDefaultConfigFlags(savedDefaultsPaths))
return uploadResponse
Expand Down
69 changes: 69 additions & 0 deletions test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,73 @@ describe('Config', () => {

delete process.env.GITHUB_JOB
})

test('Process URLs with branch references', async () => {
process.env.GITHUB_SERVER_URL = 'https://github.com'
process.env.GITHUB_REPOSITORY = 'org/repo'
process.env.GITHUB_REF_NAME = 'main'

const customPaths = [
'org/repo/config.yaml@feature',
'local/config.yaml',
'https://github.com/org/repo/config.yaml?ref=develop',
'shared/config.yaml'
].join(',')

piperExecResultMock = generatePiperGetDefaultsOutput([
'http://mock.test/asset/piper-defaults.yml'
])

const errorCode = await config.downloadDefaultConfig(
'https://github.com',
'https://api.github.com',
'v1.0.0',
'token',
'org',
'repo',
customPaths
)

expect(errorCode).toBe(0)
expect(execute.executePiper).toHaveBeenCalledWith('getDefaults', expect.arrayContaining([
'--defaultsFile',
'http://mock.test/asset/piper-defaults.yml',
'--defaultsFile',
'https://github.com/org/repo/config.yaml?ref=feature',
'--defaultsFile',
'https://github.com/org/repo/local/config.yaml?ref=main',
'--defaultsFile',
'https://github.com/org/repo/config.yaml?ref=develop',
'--defaultsFile',
'https://github.com/org/repo/shared/config.yaml?ref=main'
]))
})

test('Sanitizes filenames when saving', async () => {
const paths = [
'https://github.com/org/repo/config.yaml?ref=feature',
'local/config.yaml'
]

piperExecResultMock = generatePiperGetDefaultsOutput(paths)

const result = await config.downloadDefaultConfig(
'https://github.com',
'https://api.github.com',
'v1.0.0',
'token',
'org',
'repo',
paths.join(',')
)

expect(fs.writeFileSync).toHaveBeenCalledWith(
expect.stringContaining('config.yaml'),
expect.anything()
)
expect(fs.writeFileSync).not.toHaveBeenCalledWith(
expect.stringContaining('?ref='),
expect.anything()
)
})
})

0 comments on commit 2ea9ba2

Please sign in to comment.