Преглед на файлове

fix: expand merge commit SHA regex and add SHA-256 test cases (#2414)

* fix: expand merge commit SHA regex and add SHA-256 test cases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: add checkCommitInfo SHA coverage

Add checkCommitInfo tests for SHA-1 and SHA-256 merge messages and reject invalid 50-character hex merge heads.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* style: fix Prettier formatting in test and source files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Yashwanth Anantharaju преди 1 месец
родител
ревизия
900f2210b1
променени са 5 файла, в които са добавени 164 реда и са изтрити 4 реда
  1. 10 0
      __test__/input-helper.test.ts
  2. 148 0
      __test__/ref-helper.test.ts
  3. 2 2
      dist/index.js
  4. 1 1
      src/input-helper.ts
  5. 3 1
      src/ref-helper.ts

+ 10 - 0
__test__/input-helper.test.ts

@@ -133,6 +133,16 @@ describe('input-helper tests', () => {
     expect(settings.commit).toBe('1111111111222222222233333333334444444444')
   })
 
+  it('sets ref to empty when explicit sha-256', async () => {
+    inputs.ref =
+      '1111111111222222222233333333334444444444555555555566666666667777'
+    const settings: IGitSourceSettings = await inputHelper.getInputs()
+    expect(settings.ref).toBeFalsy()
+    expect(settings.commit).toBe(
+      '1111111111222222222233333333334444444444555555555566666666667777'
+    )
+  })
+
   it('sets sha to empty when explicit ref', async () => {
     inputs.ref = 'refs/heads/some-other-ref'
     const settings: IGitSourceSettings = await inputHelper.getInputs()

+ 148 - 0
__test__/ref-helper.test.ts

@@ -1,8 +1,12 @@
 import * as assert from 'assert'
+import * as core from '@actions/core'
+import * as github from '@actions/github'
 import * as refHelper from '../lib/ref-helper'
 import {IGitCommandManager} from '../lib/git-command-manager'
 
 const commit = '1234567890123456789012345678901234567890'
+const sha256Commit =
+  '1234567890123456789012345678901234567890123456789012345678901234'
 let git: IGitCommandManager
 
 describe('ref-helper tests', () => {
@@ -37,6 +41,12 @@ describe('ref-helper tests', () => {
     expect(checkoutInfo.startPoint).toBeFalsy()
   })
 
+  it('getCheckoutInfo sha-256 only', async () => {
+    const checkoutInfo = await refHelper.getCheckoutInfo(git, '', sha256Commit)
+    expect(checkoutInfo.ref).toBe(sha256Commit)
+    expect(checkoutInfo.startPoint).toBeFalsy()
+  })
+
   it('getCheckoutInfo refs/heads/', async () => {
     const checkoutInfo = await refHelper.getCheckoutInfo(
       git,
@@ -227,4 +237,142 @@ describe('ref-helper tests', () => {
       '+refs/heads/my/branch:refs/remotes/origin/my/branch'
     )
   })
+
+  describe('checkCommitInfo', () => {
+    const repositoryOwner = 'some-owner'
+    const repositoryName = 'some-repo'
+    const ref = 'refs/pull/123/merge'
+    const sha1Head = '1111111111222222222233333333334444444444'
+    const sha1Base = 'aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd'
+    const sha256Head =
+      '1111111111222222222233333333334444444444555555555566666666667777'
+    const sha256Base =
+      'aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffff0000'
+    let debugSpy: jest.SpyInstance
+    let getOctokitSpy: jest.SpyInstance
+    let repoGetSpy: jest.Mock
+    let originalEventName: string
+    let originalPayload: unknown
+    let originalRef: string
+    let originalSha: string
+
+    function setPullRequestContext(
+      expectedHeadSha: string,
+      expectedBaseSha: string,
+      mergeCommit: string
+    ): void {
+      ;(github.context as any).eventName = 'pull_request'
+      github.context.ref = ref
+      github.context.sha = mergeCommit
+      ;(github.context as any).payload = {
+        action: 'synchronize',
+        after: expectedHeadSha,
+        number: 123,
+        pull_request: {
+          base: {
+            sha: expectedBaseSha
+          }
+        },
+        repository: {
+          private: false
+        }
+      }
+    }
+
+    beforeEach(() => {
+      originalEventName = github.context.eventName
+      originalPayload = github.context.payload
+      originalRef = github.context.ref
+      originalSha = github.context.sha
+
+      jest.spyOn(github.context, 'repo', 'get').mockReturnValue({
+        owner: repositoryOwner,
+        repo: repositoryName
+      })
+      debugSpy = jest.spyOn(core, 'debug').mockImplementation(jest.fn())
+      repoGetSpy = jest.fn(async () => ({}))
+      getOctokitSpy = jest.spyOn(github, 'getOctokit').mockReturnValue({
+        rest: {
+          repos: {
+            get: repoGetSpy
+          }
+        }
+      } as any)
+    })
+
+    afterEach(() => {
+      ;(github.context as any).eventName = originalEventName
+      ;(github.context as any).payload = originalPayload
+      github.context.ref = originalRef
+      github.context.sha = originalSha
+      jest.restoreAllMocks()
+    })
+
+    it('returns early for SHA-1 merge commit', async () => {
+      setPullRequestContext(sha1Head, sha1Base, commit)
+
+      await refHelper.checkCommitInfo(
+        'token',
+        `Merge ${sha1Head} into ${sha1Base}`,
+        repositoryOwner,
+        repositoryName,
+        ref,
+        commit
+      )
+
+      expect(getOctokitSpy).not.toHaveBeenCalled()
+      expect(repoGetSpy).not.toHaveBeenCalled()
+    })
+
+    it('matches SHA-256 merge commit info', async () => {
+      const actualHeadSha =
+        '9999999999888888888877777777776666666666555555555544444444443333'
+      setPullRequestContext(sha256Head, sha256Base, sha256Commit)
+
+      await refHelper.checkCommitInfo(
+        'token',
+        `Merge ${actualHeadSha} into ${sha256Base}`,
+        repositoryOwner,
+        repositoryName,
+        ref,
+        sha256Commit
+      )
+
+      expect(getOctokitSpy).toHaveBeenCalledWith(
+        'token',
+        expect.objectContaining({
+          userAgent: expect.stringContaining(
+            `expected_head_sha=${sha256Head};actual_head_sha=${actualHeadSha}`
+          )
+        })
+      )
+      expect(repoGetSpy).toHaveBeenCalledWith({
+        owner: repositoryOwner,
+        repo: repositoryName
+      })
+      expect(debugSpy).toHaveBeenCalledWith(
+        `Expected head sha ${sha256Head}; actual head sha ${actualHeadSha}`
+      )
+      expect(debugSpy).not.toHaveBeenCalledWith('Unexpected message format')
+    })
+
+    it('does not match 50-char hex as a valid merge', async () => {
+      const invalidHeadSha =
+        '99999999998888888888777777777766666666665555555555'
+      setPullRequestContext(sha1Head, sha1Base, commit)
+
+      await refHelper.checkCommitInfo(
+        'token',
+        `Merge ${invalidHeadSha} into ${sha1Base}`,
+        repositoryOwner,
+        repositoryName,
+        ref,
+        commit
+      )
+
+      expect(getOctokitSpy).not.toHaveBeenCalled()
+      expect(repoGetSpy).not.toHaveBeenCalled()
+      expect(debugSpy).toHaveBeenCalledWith('Unexpected message format')
+    })
+  })
 })

+ 2 - 2
dist/index.js

@@ -2021,7 +2021,7 @@ function getInputs() {
             }
         }
         // SHA?
-        else if (result.ref.match(/^[0-9a-fA-F]{40}$/)) {
+        else if (result.ref.match(/^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/)) {
             result.commit = result.ref;
             result.ref = '';
         }
@@ -2444,7 +2444,7 @@ function checkCommitInfo(token, commitInfo, repositoryOwner, repositoryName, ref
                 return;
             }
             // Extract details from message
-            const match = commitInfo.match(/Merge ([0-9a-f]{40}) into ([0-9a-f]{40})/);
+            const match = commitInfo.match(/Merge ([0-9a-f]{40}|[0-9a-f]{64}) into ([0-9a-f]{40}|[0-9a-f]{64})/);
             if (!match) {
                 core.debug('Unexpected message format');
                 return;

+ 1 - 1
src/input-helper.ts

@@ -71,7 +71,7 @@ export async function getInputs(): Promise<IGitSourceSettings> {
     }
   }
   // SHA?
-  else if (result.ref.match(/^[0-9a-fA-F]{40}$/)) {
+  else if (result.ref.match(/^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/)) {
     result.commit = result.ref
     result.ref = ''
   }

+ 3 - 1
src/ref-helper.ts

@@ -258,7 +258,9 @@ export async function checkCommitInfo(
     }
 
     // Extract details from message
-    const match = commitInfo.match(/Merge ([0-9a-f]{40}) into ([0-9a-f]{40})/)
+    const match = commitInfo.match(
+      /Merge ([0-9a-f]{40}|[0-9a-f]{64}) into ([0-9a-f]{40}|[0-9a-f]{64})/
+    )
     if (!match) {
       core.debug('Unexpected message format')
       return