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 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) }