@@ -75,7 +75,7 @@ export function prepareLocalRunEnvironment() {
7575/**
7676 * Gets the SHA of the commit that is currently checked out.
7777 */
78- export const getCommitOid = async function ( ) : Promise < string > {
78+ export const getCommitOid = async function ( ref = "HEAD" ) : Promise < string > {
7979 // Try to use git to get the current commit SHA. If that fails then
8080 // log but otherwise silently fall back to using the SHA from the environment.
8181 // The only time these two values will differ is during analysis of a PR when
@@ -87,7 +87,7 @@ export const getCommitOid = async function (): Promise<string> {
8787 let commitOid = "" ;
8888 await new toolrunner . ToolRunner (
8989 await safeWhich . safeWhich ( "git" ) ,
90- [ "rev-parse" , "HEAD" ] ,
90+ [ "rev-parse" , ref ] ,
9191 {
9292 silent : true ,
9393 listeners : {
@@ -425,19 +425,32 @@ export async function getRef(): Promise<string> {
425425 // Will be in the form "refs/heads/master" on a push event
426426 // or in the form "refs/pull/N/merge" on a pull_request event
427427 const ref = getRequiredEnvParam ( "GITHUB_REF" ) ;
428+ const sha = getRequiredEnvParam ( "GITHUB_SHA" ) ;
428429
429430 // For pull request refs we want to detect whether the workflow
430431 // has run `git checkout HEAD^2` to analyze the 'head' ref rather
431432 // than the 'merge' ref. If so, we want to convert the ref that
432433 // we report back.
433434 const pull_ref_regex = / r e f s \/ p u l l \/ ( \d + ) \/ m e r g e / ;
434- const checkoutSha = await getCommitOid ( ) ;
435+ if ( ! pull_ref_regex . test ( ref ) ) {
436+ return ref ;
437+ }
438+
439+ const head = await getCommitOid ( "HEAD" ) ;
435440
436- if (
437- pull_ref_regex . test ( ref ) &&
438- checkoutSha !== getRequiredEnvParam ( "GITHUB_SHA" )
439- ) {
440- return ref . replace ( pull_ref_regex , "refs/pull/$1/head" ) ;
441+ // in actions/checkout@v 2 we can check if git rev-parse HEAD == GITHUB_SHA
442+ // in actions/checkout@v 1 this may not be true as it checks out the repository
443+ // using GITHUB_REF. There is a subtle race condition where
444+ // git rev-parse GITHUB_REF != GITHUB_SHA, so we must check
445+ // git git-parse GITHUB_REF == git rev-parse HEAD instead.
446+ const hasChangedRef = sha !== head && ( await getCommitOid ( ref ) ) !== head ;
447+
448+ if ( hasChangedRef ) {
449+ const newRef = ref . replace ( pull_ref_regex , "refs/pull/$1/head" ) ;
450+ core . debug (
451+ `No longer on merge commit, rewriting ref from ${ ref } to ${ newRef } .`
452+ ) ;
453+ return newRef ;
441454 } else {
442455 return ref ;
443456 }
0 commit comments