2023-05-25 18:22:24 +00:00
|
|
|
import * as core from '@actions/core'
|
|
|
|
|
|
|
|
import {Env} from './env'
|
|
|
|
import {Inputs} from './inputs'
|
|
|
|
import {
|
|
|
|
canDiffCommits,
|
|
|
|
getHeadSha,
|
2023-05-25 23:39:26 +00:00
|
|
|
getParentSha,
|
2023-05-25 18:22:24 +00:00
|
|
|
getPreviousGitTag,
|
|
|
|
gitFetch,
|
|
|
|
gitFetchSubmodules,
|
|
|
|
gitLog,
|
|
|
|
gitLsRemote,
|
|
|
|
verifyCommitSha
|
|
|
|
} from './utils'
|
|
|
|
|
|
|
|
const getCurrentSHA = async ({
|
|
|
|
inputs,
|
|
|
|
workingDirectory
|
|
|
|
}: {
|
|
|
|
inputs: Inputs
|
|
|
|
workingDirectory: string
|
|
|
|
}): Promise<string> => {
|
|
|
|
let currentSha = inputs.sha
|
|
|
|
core.debug('Getting current SHA...')
|
|
|
|
|
|
|
|
if (inputs.until) {
|
|
|
|
core.debug(`Getting base SHA for '${inputs.until}'...`)
|
|
|
|
try {
|
|
|
|
currentSha = await gitLog({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
2023-05-25 23:16:16 +00:00
|
|
|
'--format=%H',
|
2023-05-25 18:22:24 +00:00
|
|
|
'-n',
|
|
|
|
'1',
|
|
|
|
'--date',
|
|
|
|
'local',
|
|
|
|
'--until',
|
|
|
|
inputs.until
|
|
|
|
]
|
|
|
|
})
|
|
|
|
} catch (error) {
|
|
|
|
core.error(
|
|
|
|
`Invalid until date: ${inputs.until}. ${(error as Error).message}`
|
|
|
|
)
|
|
|
|
throw error
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!currentSha) {
|
|
|
|
currentSha = await getHeadSha({cwd: workingDirectory})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await verifyCommitSha({sha: currentSha, cwd: workingDirectory})
|
|
|
|
core.debug(`Current SHA: ${currentSha}`)
|
|
|
|
|
|
|
|
return currentSha
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface DiffResult {
|
|
|
|
previousSha: string
|
|
|
|
currentSha: string
|
|
|
|
currentBranch: string
|
|
|
|
targetBranch: string
|
|
|
|
diff: string
|
2023-05-26 16:48:32 +00:00
|
|
|
initialCommit?: boolean
|
2023-05-25 18:22:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const getSHAForPushEvent = async (
|
|
|
|
inputs: Inputs,
|
|
|
|
env: Env,
|
|
|
|
workingDirectory: string,
|
|
|
|
isShallow: boolean,
|
|
|
|
hasSubmodule: boolean,
|
|
|
|
gitExtraArgs: string[],
|
|
|
|
isTag: boolean
|
|
|
|
): Promise<DiffResult> => {
|
2023-05-25 23:39:26 +00:00
|
|
|
let targetBranch = env.GITHUB_REF_NAME
|
2023-05-25 18:22:24 +00:00
|
|
|
const currentBranch = targetBranch
|
|
|
|
let initialCommit = false
|
|
|
|
|
|
|
|
if (isShallow) {
|
|
|
|
core.info('Repository is shallow, fetching more history...')
|
|
|
|
|
|
|
|
if (isTag) {
|
|
|
|
const sourceBranch = env.GITHUB_EVENT_BASE_REF.replace('refs/heads/', '')
|
|
|
|
await gitFetch({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`,
|
|
|
|
'origin',
|
|
|
|
`+refs/tags/${sourceBranch}:refs/remotes/origin/${sourceBranch}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
await gitFetch({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`,
|
|
|
|
'origin',
|
|
|
|
`+refs/heads/${targetBranch}:refs/remotes/origin/${targetBranch}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasSubmodule) {
|
|
|
|
await gitFetchSubmodules({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentSha = await getCurrentSHA({inputs, workingDirectory})
|
|
|
|
let previousSha = inputs.baseSha
|
|
|
|
const diff = '..'
|
|
|
|
|
|
|
|
if (previousSha && currentSha && currentBranch && targetBranch) {
|
|
|
|
if (previousSha === currentSha) {
|
|
|
|
core.error(
|
|
|
|
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
|
|
|
)
|
|
|
|
core.error(
|
|
|
|
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
|
|
|
)
|
|
|
|
throw new Error('Similar commit hashes detected.')
|
|
|
|
}
|
|
|
|
|
|
|
|
await verifyCommitSha({sha: previousSha, cwd: workingDirectory})
|
2023-05-26 03:14:24 +00:00
|
|
|
core.debug(`Previous SHA: ${previousSha}`)
|
2023-05-25 18:22:24 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
previousSha,
|
|
|
|
currentSha,
|
|
|
|
currentBranch,
|
|
|
|
targetBranch,
|
|
|
|
diff
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!previousSha) {
|
|
|
|
core.debug('Getting previous SHA...')
|
|
|
|
if (inputs.since) {
|
|
|
|
core.debug(`Getting base SHA for '${inputs.since}'...`)
|
|
|
|
try {
|
2023-05-25 23:16:16 +00:00
|
|
|
const allCommitsFrom = await gitLog({
|
2023-05-25 18:22:24 +00:00
|
|
|
cwd: workingDirectory,
|
2023-05-25 23:16:16 +00:00
|
|
|
args: ['--format=%H', '--date', 'local', '--since', inputs.since]
|
2023-05-25 18:22:24 +00:00
|
|
|
})
|
2023-05-25 23:16:16 +00:00
|
|
|
|
|
|
|
if (allCommitsFrom) {
|
|
|
|
const allCommitsFromArray = allCommitsFrom.split('\n')
|
|
|
|
previousSha = allCommitsFromArray[allCommitsFromArray.length - 1]
|
|
|
|
}
|
2023-05-25 18:22:24 +00:00
|
|
|
} catch (error) {
|
|
|
|
core.error(
|
|
|
|
`Invalid since date: ${inputs.since}. ${(error as Error).message}`
|
|
|
|
)
|
|
|
|
throw error
|
|
|
|
}
|
|
|
|
} else if (isTag) {
|
|
|
|
core.debug('Getting previous SHA for tag...')
|
|
|
|
const {sha, tag} = await getPreviousGitTag({cwd: workingDirectory})
|
|
|
|
previousSha = sha
|
|
|
|
targetBranch = tag
|
|
|
|
} else {
|
2023-05-25 23:39:26 +00:00
|
|
|
core.debug('Getting previous SHA for last remote commit...')
|
|
|
|
if (env.GITHUB_EVENT_FORCED === 'false' || !env.GITHUB_EVENT_FORCED) {
|
|
|
|
previousSha = env.GITHUB_EVENT_BEFORE
|
2023-05-25 18:22:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
!previousSha ||
|
|
|
|
previousSha === '0000000000000000000000000000000000000000'
|
|
|
|
) {
|
2023-05-25 23:39:26 +00:00
|
|
|
previousSha = await getParentSha({
|
|
|
|
cwd: workingDirectory
|
|
|
|
})
|
2023-05-26 03:14:24 +00:00
|
|
|
} else if (
|
|
|
|
(await verifyCommitSha({
|
|
|
|
sha: previousSha,
|
|
|
|
cwd: workingDirectory,
|
|
|
|
showAsErrorMessage: false
|
|
|
|
})) !== 0
|
|
|
|
) {
|
|
|
|
core.warning(
|
|
|
|
`Previous commit ${previousSha} is not valid. Using parent commit.`
|
|
|
|
)
|
|
|
|
previousSha = await getParentSha({
|
|
|
|
cwd: workingDirectory
|
|
|
|
})
|
2023-05-25 18:22:24 +00:00
|
|
|
}
|
|
|
|
|
2023-05-26 16:48:32 +00:00
|
|
|
if (!previousSha || previousSha === currentSha) {
|
|
|
|
previousSha = await getParentSha({
|
|
|
|
cwd: workingDirectory
|
|
|
|
})
|
|
|
|
|
|
|
|
if (!previousSha) {
|
2023-05-25 18:22:24 +00:00
|
|
|
core.warning('Initial commit detected no previous commit found.')
|
|
|
|
initialCommit = true
|
|
|
|
previousSha = currentSha
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await verifyCommitSha({sha: previousSha, cwd: workingDirectory})
|
|
|
|
core.debug(`Previous SHA: ${previousSha}`)
|
|
|
|
|
|
|
|
core.debug(`Target branch: ${targetBranch}`)
|
|
|
|
core.debug(`Current branch: ${currentBranch}`)
|
|
|
|
|
|
|
|
if (!initialCommit && previousSha === currentSha) {
|
|
|
|
core.error(
|
|
|
|
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
|
|
|
)
|
|
|
|
core.error(
|
|
|
|
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
|
|
|
)
|
|
|
|
throw new Error('Similar commit hashes detected.')
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
previousSha,
|
|
|
|
currentSha,
|
|
|
|
currentBranch,
|
|
|
|
targetBranch,
|
2023-05-26 16:48:32 +00:00
|
|
|
diff,
|
|
|
|
initialCommit
|
2023-05-25 18:22:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const getSHAForPullRequestEvent = async (
|
|
|
|
inputs: Inputs,
|
|
|
|
env: Env,
|
|
|
|
workingDirectory: string,
|
|
|
|
isShallow: boolean,
|
|
|
|
hasSubmodule: boolean,
|
|
|
|
gitExtraArgs: string[]
|
|
|
|
): Promise<DiffResult> => {
|
|
|
|
let targetBranch = env.GITHUB_EVENT_PULL_REQUEST_BASE_REF
|
|
|
|
const currentBranch = env.GITHUB_EVENT_PULL_REQUEST_HEAD_REF
|
|
|
|
if (inputs.sinceLastRemoteCommit) {
|
|
|
|
targetBranch = currentBranch
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isShallow) {
|
|
|
|
core.info('Repository is shallow, fetching more history...')
|
|
|
|
|
|
|
|
const prFetchExitCode = await gitFetch({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
'origin',
|
|
|
|
`pull/${env.GITHUB_EVENT_PULL_REQUEST_NUMBER}/head:${currentBranch}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
|
|
|
if (prFetchExitCode !== 0) {
|
|
|
|
await gitFetch({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`,
|
|
|
|
'origin',
|
|
|
|
`+refs/heads/${currentBranch}*:refs/remotes/origin/${currentBranch}*`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!inputs.sinceLastRemoteCommit) {
|
|
|
|
core.debug('Fetching target branch...')
|
|
|
|
await gitFetch({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`,
|
|
|
|
'origin',
|
|
|
|
`+refs/heads/${targetBranch}:refs/remotes/origin/${targetBranch}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
|
|
|
if (hasSubmodule) {
|
|
|
|
await gitFetchSubmodules({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentSha = await getCurrentSHA({inputs, workingDirectory})
|
|
|
|
let previousSha = inputs.baseSha
|
|
|
|
let diff = '...'
|
|
|
|
|
|
|
|
if (previousSha && currentSha && currentBranch && targetBranch) {
|
|
|
|
if (previousSha === currentSha) {
|
|
|
|
core.error(
|
|
|
|
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
|
|
|
)
|
|
|
|
core.error(
|
|
|
|
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
|
|
|
)
|
|
|
|
throw new Error('Similar commit hashes detected.')
|
|
|
|
}
|
|
|
|
|
|
|
|
await verifyCommitSha({sha: currentSha, cwd: workingDirectory})
|
2023-05-26 03:14:24 +00:00
|
|
|
core.debug(`Previous SHA: ${previousSha}`)
|
2023-05-25 18:22:24 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
previousSha,
|
|
|
|
currentSha,
|
|
|
|
currentBranch,
|
|
|
|
targetBranch,
|
|
|
|
diff
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
!env.GITHUB_EVENT_PULL_REQUEST_BASE_REF ||
|
|
|
|
env.GITHUB_EVENT_HEAD_REPO_FORK === 'true'
|
|
|
|
) {
|
|
|
|
diff = '..'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!previousSha) {
|
|
|
|
if (inputs.sinceLastRemoteCommit) {
|
|
|
|
previousSha = env.GITHUB_EVENT_BEFORE
|
|
|
|
|
|
|
|
if (!previousSha) {
|
|
|
|
previousSha = await gitLsRemote({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [currentBranch]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
(await verifyCommitSha({
|
|
|
|
sha: previousSha,
|
|
|
|
cwd: workingDirectory,
|
|
|
|
showAsErrorMessage: false
|
|
|
|
})) !== 0
|
|
|
|
) {
|
|
|
|
previousSha = env.GITHUB_EVENT_PULL_REQUEST_BASE_SHA
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
previousSha = env.GITHUB_EVENT_PULL_REQUEST_BASE_SHA
|
|
|
|
|
|
|
|
if (!previousSha) {
|
|
|
|
previousSha = await gitLsRemote({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [targetBranch]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isShallow) {
|
|
|
|
if (
|
|
|
|
await canDiffCommits({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
sha1: previousSha,
|
|
|
|
sha2: currentSha,
|
|
|
|
diff
|
|
|
|
})
|
|
|
|
) {
|
|
|
|
core.debug(
|
|
|
|
'Merge base is not in the local history, fetching remote target branch...'
|
|
|
|
)
|
|
|
|
|
|
|
|
for (let i = 1; i <= 10; i++) {
|
|
|
|
await gitFetch({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
args: [
|
|
|
|
...gitExtraArgs,
|
|
|
|
'-u',
|
|
|
|
'--progress',
|
|
|
|
`--deepen=${inputs.fetchDepth}`,
|
|
|
|
'origin',
|
|
|
|
`+refs/heads/${targetBranch}:refs/remotes/origin/${targetBranch}`
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
|
|
|
if (
|
|
|
|
await canDiffCommits({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
sha1: previousSha,
|
|
|
|
sha2: currentSha,
|
|
|
|
diff
|
|
|
|
})
|
|
|
|
) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
core.debug(
|
|
|
|
'Merge base is not in the local history, fetching remote target branch again...'
|
|
|
|
)
|
|
|
|
core.debug(`Attempt ${i}/10`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!previousSha || previousSha === currentSha) {
|
|
|
|
previousSha = env.GITHUB_EVENT_PULL_REQUEST_BASE_SHA
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
!(await canDiffCommits({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
sha1: previousSha,
|
|
|
|
sha2: currentSha,
|
|
|
|
diff
|
|
|
|
}))
|
|
|
|
) {
|
|
|
|
diff = '..'
|
|
|
|
}
|
|
|
|
|
|
|
|
await verifyCommitSha({sha: previousSha, cwd: workingDirectory})
|
|
|
|
core.debug(`Previous SHA: ${previousSha}`)
|
|
|
|
|
|
|
|
if (
|
|
|
|
!(await canDiffCommits({
|
|
|
|
cwd: workingDirectory,
|
|
|
|
sha1: previousSha,
|
|
|
|
sha2: currentSha,
|
|
|
|
diff
|
|
|
|
}))
|
|
|
|
) {
|
|
|
|
throw new Error(
|
|
|
|
`Unable to determine a difference between ${previousSha}${diff}${currentSha}`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (previousSha === currentSha) {
|
|
|
|
core.error(
|
|
|
|
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
|
|
|
)
|
|
|
|
core.error(
|
|
|
|
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
|
|
|
)
|
|
|
|
throw new Error('Similar commit hashes detected.')
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
previousSha,
|
|
|
|
currentSha,
|
|
|
|
currentBranch,
|
|
|
|
targetBranch,
|
|
|
|
diff
|
|
|
|
}
|
|
|
|
}
|