mirror of
https://github.com/actions/checkout.git
synced 2026-05-22 20:11:54 +00:00
Fix checkout init for SHA-256 repositories
This commit is contained in:
parent
900f2210b1
commit
f279b42429
8 changed files with 489 additions and 7 deletions
|
|
@ -1103,6 +1103,7 @@ async function setup(testName: string): Promise<void> {
|
|||
),
|
||||
tryDisableAutomaticGarbageCollection: jest.fn(),
|
||||
tryGetFetchUrl: jest.fn(),
|
||||
tryGetObjectFormat: jest.fn(async () => ({format: '', succeeded: true})),
|
||||
tryGetConfigValues: jest.fn(
|
||||
async (
|
||||
key: string,
|
||||
|
|
|
|||
|
|
@ -378,6 +378,169 @@ describe('Test fetchDepth and fetchTags options', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('repository object format', () => {
|
||||
beforeEach(async () => {
|
||||
jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
|
||||
jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('detects SHA-256 from a 64-character HEAD oid', async () => {
|
||||
mockExec.mockImplementation((path, args, options) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('git version 2.50.1'))
|
||||
}
|
||||
|
||||
if (args.includes('ls-remote')) {
|
||||
options.listeners.stdout(
|
||||
Buffer.from(
|
||||
'ref: refs/heads/main\tHEAD\n' +
|
||||
'9422233ca7ee1b17f1e905d0e141faf0c401556c41cdc6acd71c6bd685da2e92\tHEAD\n'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
jest.spyOn(exec, 'exec').mockImplementation(mockExec)
|
||||
|
||||
git = await commandManager.createCommandManager('test', false, false)
|
||||
|
||||
const objectFormat = await git.tryGetObjectFormat(
|
||||
'https://github.com/example/repo'
|
||||
)
|
||||
|
||||
expect(objectFormat).toEqual({format: 'sha256', succeeded: true})
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
[
|
||||
'-c',
|
||||
'protocol.version=2',
|
||||
'ls-remote',
|
||||
'--quiet',
|
||||
'--exit-code',
|
||||
'--symref',
|
||||
'https://github.com/example/repo',
|
||||
'HEAD'
|
||||
],
|
||||
expect.objectContaining({
|
||||
ignoreReturnCode: true,
|
||||
silent: true
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('detects SHA-1 from a 40-character HEAD oid', async () => {
|
||||
mockExec.mockImplementation((path, args, options) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('git version 2.50.1'))
|
||||
}
|
||||
|
||||
if (args.includes('ls-remote')) {
|
||||
options.listeners.stdout(
|
||||
Buffer.from(
|
||||
'ref: refs/heads/main\tHEAD\n' +
|
||||
'c988866043f035e6a46509872215f91d879044c9\tHEAD\n'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
jest.spyOn(exec, 'exec').mockImplementation(mockExec)
|
||||
|
||||
git = await commandManager.createCommandManager('test', false, false)
|
||||
|
||||
await expect(
|
||||
git.tryGetObjectFormat('https://github.com/example/repo')
|
||||
).resolves.toEqual({format: 'sha1', succeeded: true})
|
||||
})
|
||||
|
||||
it('returns unsuccessful when HEAD does not resolve to a recognized object id', async () => {
|
||||
mockExec.mockImplementation((path, args, options) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('git version 2.50.1'))
|
||||
}
|
||||
|
||||
if (args.includes('ls-remote')) {
|
||||
options.listeners.stdout(Buffer.from('ref: refs/heads/main\tHEAD\n'))
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
jest.spyOn(exec, 'exec').mockImplementation(mockExec)
|
||||
|
||||
git = await commandManager.createCommandManager('test', false, false)
|
||||
|
||||
await expect(
|
||||
git.tryGetObjectFormat('https://github.com/example/repo')
|
||||
).resolves.toEqual({format: '', succeeded: false})
|
||||
})
|
||||
|
||||
it('returns unsuccessful when object format detection cannot reach the remote', async () => {
|
||||
mockExec.mockImplementation((path, args, options) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('git version 2.50.1'))
|
||||
return 0
|
||||
}
|
||||
|
||||
return 128
|
||||
})
|
||||
jest.spyOn(exec, 'exec').mockImplementation(mockExec)
|
||||
|
||||
git = await commandManager.createCommandManager('test', false, false)
|
||||
|
||||
await expect(
|
||||
git.tryGetObjectFormat('https://github.com/example/repo')
|
||||
).resolves.toEqual({format: '', succeeded: false})
|
||||
})
|
||||
|
||||
it('initializes SHA-256 repositories with the matching object format', async () => {
|
||||
mockExec.mockImplementation((path, args, options) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('git version 2.50.1'))
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
jest.spyOn(exec, 'exec').mockImplementation(mockExec)
|
||||
|
||||
git = await commandManager.createCommandManager('test', false, false)
|
||||
|
||||
await git.init('sha256')
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
['init', '--object-format=sha256', 'test'],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('initializes SHA-1 repositories with existing default arguments', async () => {
|
||||
mockExec.mockImplementation((path, args, options) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('git version 2.50.1'))
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
jest.spyOn(exec, 'exec').mockImplementation(mockExec)
|
||||
|
||||
git = await commandManager.createCommandManager('test', false, false)
|
||||
|
||||
await git.init('sha1')
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
['init', 'test'],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('git user-agent with orchestration ID', () => {
|
||||
beforeEach(async () => {
|
||||
jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
|
||||
|
|
|
|||
|
|
@ -501,6 +501,7 @@ async function setup(testName: string): Promise<void> {
|
|||
await fs.promises.stat(path.join(repositoryPath, '.git'))
|
||||
return repositoryUrl
|
||||
}),
|
||||
tryGetObjectFormat: jest.fn(async () => ({format: '', succeeded: true})),
|
||||
tryGetConfigValues: jest.fn(),
|
||||
tryGetConfigKeys: jest.fn(),
|
||||
tryReset: jest.fn(async () => {
|
||||
|
|
|
|||
104
__test__/github-api-helper.test.ts
Normal file
104
__test__/github-api-helper.test.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import * as githubApiHelper from '../lib/github-api-helper'
|
||||
|
||||
describe('github-api-helper object format', () => {
|
||||
let getOctokitSpy: jest.SpyInstance
|
||||
let debugSpy: jest.SpyInstance
|
||||
let repoGet: jest.Mock
|
||||
let branchGet: jest.Mock
|
||||
|
||||
function mockObjectFormatApi(defaultBranch: string, commitSha: string): void {
|
||||
repoGet = jest.fn(async () => ({
|
||||
data: {
|
||||
default_branch: defaultBranch
|
||||
}
|
||||
}))
|
||||
branchGet = jest.fn(async () => ({
|
||||
data: {
|
||||
commit: {
|
||||
sha: commitSha
|
||||
}
|
||||
}
|
||||
}))
|
||||
getOctokitSpy = jest.spyOn(github, 'getOctokit').mockReturnValue({
|
||||
rest: {
|
||||
repos: {
|
||||
get: repoGet,
|
||||
getBranch: branchGet
|
||||
}
|
||||
}
|
||||
} as any)
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
debugSpy = jest.spyOn(core, 'debug').mockImplementation(jest.fn())
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('detects SHA-256 from the default branch commit SHA', async () => {
|
||||
const commitSha =
|
||||
'9422233ca7ee1b17f1e905d0e141faf0c401556c41cdc6acd71c6bd685da2e92'
|
||||
mockObjectFormatApi('main', commitSha)
|
||||
|
||||
await expect(
|
||||
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||
).resolves.toEqual({format: 'sha256', succeeded: true})
|
||||
|
||||
expect(getOctokitSpy).toHaveBeenCalledWith(
|
||||
'token',
|
||||
expect.objectContaining({baseUrl: 'https://api.github.com'})
|
||||
)
|
||||
expect(repoGet).toHaveBeenCalledWith({owner: 'owner', repo: 'repo'})
|
||||
expect(branchGet).toHaveBeenCalledWith({
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
branch: 'main'
|
||||
})
|
||||
})
|
||||
|
||||
it('detects SHA-1 from the default branch commit SHA', async () => {
|
||||
mockObjectFormatApi('main', 'c988866043f035e6a46509872215f91d879044c9')
|
||||
|
||||
await expect(
|
||||
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||
).resolves.toEqual({format: 'sha1', succeeded: true})
|
||||
})
|
||||
|
||||
it('returns unsuccessful when the default branch commit SHA is not recognized', async () => {
|
||||
mockObjectFormatApi('main', 'not-a-sha')
|
||||
|
||||
await expect(
|
||||
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||
).resolves.toEqual({format: '', succeeded: false})
|
||||
expect(debugSpy).toHaveBeenCalledWith(
|
||||
'Unable to determine repository object format from default branch'
|
||||
)
|
||||
})
|
||||
|
||||
it('returns unsuccessful when the repository API lookup fails', async () => {
|
||||
repoGet = jest.fn(async () => {
|
||||
throw new Error('not found')
|
||||
})
|
||||
branchGet = jest.fn()
|
||||
jest.spyOn(github, 'getOctokit').mockReturnValue({
|
||||
rest: {
|
||||
repos: {
|
||||
get: repoGet,
|
||||
getBranch: branchGet
|
||||
}
|
||||
}
|
||||
} as any)
|
||||
|
||||
await expect(
|
||||
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||
).resolves.toEqual({format: '', succeeded: false})
|
||||
expect(branchGet).not.toHaveBeenCalled()
|
||||
expect(debugSpy).toHaveBeenCalledWith(
|
||||
'Unable to determine repository object format: not found'
|
||||
)
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue