331d02c7e2
* feat: support github server url for pushing to fork (#1315) Co-authored-by: Kevin Zhu <kevin.zhu@sap.com> * fix: code formatting * test: fix tests for getRemoteUrl Co-authored-by: MildC <kevin.xizhu@gmail.com> Co-authored-by: Kevin Zhu <kevin.zhu@sap.com>
170 lines
4 KiB
TypeScript
170 lines
4 KiB
TypeScript
import * as core from '@actions/core'
|
|
import * as fs from 'fs'
|
|
import * as path from 'path'
|
|
|
|
export function getInputAsArray(
|
|
name: string,
|
|
options?: core.InputOptions
|
|
): string[] {
|
|
return getStringAsArray(core.getInput(name, options))
|
|
}
|
|
|
|
export function getStringAsArray(str: string): string[] {
|
|
return str
|
|
.split(/[\n,]+/)
|
|
.map(s => s.trim())
|
|
.filter(x => x !== '')
|
|
}
|
|
|
|
export function getRepoPath(relativePath?: string): string {
|
|
let githubWorkspacePath = process.env['GITHUB_WORKSPACE']
|
|
if (!githubWorkspacePath) {
|
|
throw new Error('GITHUB_WORKSPACE not defined')
|
|
}
|
|
githubWorkspacePath = path.resolve(githubWorkspacePath)
|
|
core.debug(`githubWorkspacePath: ${githubWorkspacePath}`)
|
|
|
|
let repoPath = githubWorkspacePath
|
|
if (relativePath) repoPath = path.resolve(repoPath, relativePath)
|
|
|
|
core.debug(`repoPath: ${repoPath}`)
|
|
return repoPath
|
|
}
|
|
|
|
interface RemoteDetail {
|
|
hostname: string
|
|
protocol: string
|
|
repository: string
|
|
}
|
|
|
|
export function getRemoteDetail(remoteUrl: string): RemoteDetail {
|
|
// Parse the protocol and github repository from a URL
|
|
// e.g. HTTPS, peter-evans/create-pull-request
|
|
const githubUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com'
|
|
|
|
const githubServerMatch = githubUrl.match(/^https?:\/\/(.+)$/i)
|
|
if (!githubServerMatch) {
|
|
throw new Error('Could not parse GitHub Server name')
|
|
}
|
|
|
|
const hostname = githubServerMatch[1]
|
|
|
|
const httpsUrlPattern = new RegExp(
|
|
'^https?://.*@?' + hostname + '/(.+/.+?)(\\.git)?$',
|
|
'i'
|
|
)
|
|
const sshUrlPattern = new RegExp('^git@' + hostname + ':(.+/.+)\\.git$', 'i')
|
|
|
|
const httpsMatch = remoteUrl.match(httpsUrlPattern)
|
|
if (httpsMatch) {
|
|
return {
|
|
hostname,
|
|
protocol: 'HTTPS',
|
|
repository: httpsMatch[1]
|
|
}
|
|
}
|
|
|
|
const sshMatch = remoteUrl.match(sshUrlPattern)
|
|
if (sshMatch) {
|
|
return {
|
|
hostname,
|
|
protocol: 'SSH',
|
|
repository: sshMatch[1]
|
|
}
|
|
}
|
|
|
|
throw new Error(
|
|
`The format of '${remoteUrl}' is not a valid GitHub repository URL`
|
|
)
|
|
}
|
|
|
|
export function getRemoteUrl(
|
|
protocol: string,
|
|
hostname: string,
|
|
repository: string
|
|
): string {
|
|
return protocol == 'HTTPS'
|
|
? `https://${hostname}/${repository}`
|
|
: `git@${hostname}:${repository}.git`
|
|
}
|
|
|
|
export function secondsSinceEpoch(): number {
|
|
const now = new Date()
|
|
return Math.round(now.getTime() / 1000)
|
|
}
|
|
|
|
export function randomString(): string {
|
|
return Math.random().toString(36).substr(2, 7)
|
|
}
|
|
|
|
interface DisplayNameEmail {
|
|
name: string
|
|
email: string
|
|
}
|
|
|
|
export function parseDisplayNameEmail(
|
|
displayNameEmail: string
|
|
): DisplayNameEmail {
|
|
// Parse the name and email address from a string in the following format
|
|
// Display Name <email@address.com>
|
|
const pattern = /^([^<]+)\s*<([^>]+)>$/i
|
|
|
|
// Check we have a match
|
|
const match = displayNameEmail.match(pattern)
|
|
if (!match) {
|
|
throw new Error(
|
|
`The format of '${displayNameEmail}' is not a valid email address with display name`
|
|
)
|
|
}
|
|
|
|
// Check that name and email are not just whitespace
|
|
const name = match[1].trim()
|
|
const email = match[2].trim()
|
|
if (!name || !email) {
|
|
throw new Error(
|
|
`The format of '${displayNameEmail}' is not a valid email address with display name`
|
|
)
|
|
}
|
|
|
|
return {
|
|
name: name,
|
|
email: email
|
|
}
|
|
}
|
|
|
|
export function fileExistsSync(path: string): boolean {
|
|
if (!path) {
|
|
throw new Error("Arg 'path' must not be empty")
|
|
}
|
|
|
|
let stats: fs.Stats
|
|
try {
|
|
stats = fs.statSync(path)
|
|
} catch (error) {
|
|
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
return false
|
|
}
|
|
|
|
throw new Error(
|
|
`Encountered an error when checking whether path '${path}' exists: ${getErrorMessage(
|
|
error
|
|
)}`
|
|
)
|
|
}
|
|
|
|
if (!stats.isDirectory()) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
function hasErrorCode(error: any): error is {code: string} {
|
|
return typeof (error && error.code) === 'string'
|
|
}
|
|
|
|
export function getErrorMessage(error: unknown) {
|
|
if (error instanceof Error) return error.message
|
|
return String(error)
|
|
}
|