mirror of
https://github.com/actions/checkout.git
synced 2026-06-29 18:13:51 +08:00
Compare commits
3 Commits
26bf18e514
...
v6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df4cb1c069 | ||
|
|
1cce3390c2 | ||
|
|
900f2210b1 |
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v6.0.3
|
||||||
|
* Fix checkout init for SHA-256 repositories by @yaananth in https://github.com/actions/checkout/pull/2439
|
||||||
|
* fix: expand merge commit SHA regex and add SHA-256 test cases by @yaananth in https://github.com/actions/checkout/pull/2414
|
||||||
|
|
||||||
## v6.0.2
|
## v6.0.2
|
||||||
* Fix tag handling: preserve annotations and explicit fetch-tags by @ericsciple in https://github.com/actions/checkout/pull/2356
|
* Fix tag handling: preserve annotations and explicit fetch-tags by @ericsciple in https://github.com/actions/checkout/pull/2356
|
||||||
|
|
||||||
|
|||||||
@@ -378,6 +378,59 @@ describe('Test fetchDepth and fetchTags options', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('repository initialization object format', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
|
||||||
|
jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
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', () => {
|
describe('git user-agent with orchestration ID', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
|
jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
|
||||||
|
|||||||
98
__test__/github-api-helper.test.ts
Normal file
98
__test__/github-api-helper.test.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
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 request: jest.Mock
|
||||||
|
|
||||||
|
function mockHashAlgorithmApi(hashAlgorithm: string): void {
|
||||||
|
request = jest.fn(async () => ({
|
||||||
|
data: {
|
||||||
|
hash_algorithm: hashAlgorithm
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
getOctokitSpy = jest.spyOn(github, 'getOctokit').mockReturnValue({
|
||||||
|
request
|
||||||
|
} as any)
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
debugSpy = jest.spyOn(core, 'debug').mockImplementation(jest.fn())
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('detects SHA-256 from the repository hash algorithm endpoint', async () => {
|
||||||
|
mockHashAlgorithmApi('sha256')
|
||||||
|
|
||||||
|
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(request).toHaveBeenCalledWith(
|
||||||
|
'GET /repos/{owner}/{repo}/hash-algorithm',
|
||||||
|
{owner: 'owner', repo: 'repo'}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('detects SHA-1 from the repository hash algorithm endpoint', async () => {
|
||||||
|
mockHashAlgorithmApi('sha1')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||||
|
).resolves.toEqual({format: 'sha1', succeeded: true})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('detects object format from an existing commit without API calls', async () => {
|
||||||
|
const commitSha =
|
||||||
|
'9422233ca7ee1b17f1e905d0e141faf0c401556c41cdc6acd71c6bd685da2e92'
|
||||||
|
getOctokitSpy = jest.spyOn(github, 'getOctokit')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
githubApiHelper.tryGetRepositoryObjectFormat(
|
||||||
|
'token',
|
||||||
|
'owner',
|
||||||
|
'repo',
|
||||||
|
undefined,
|
||||||
|
commitSha
|
||||||
|
)
|
||||||
|
).resolves.toEqual({format: 'sha256', succeeded: true})
|
||||||
|
|
||||||
|
expect(getOctokitSpy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns unsuccessful when the hash algorithm endpoint value is not recognized', async () => {
|
||||||
|
mockHashAlgorithmApi('unknown')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||||
|
).resolves.toEqual({format: '', succeeded: false})
|
||||||
|
expect(debugSpy).toHaveBeenCalledWith(
|
||||||
|
'Unable to determine repository object format from hash-algorithm endpoint'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns unsuccessful when the hash algorithm API lookup fails', async () => {
|
||||||
|
request = jest.fn(async () => {
|
||||||
|
throw new Error('not found')
|
||||||
|
})
|
||||||
|
jest.spyOn(github, 'getOctokit').mockReturnValue({
|
||||||
|
request
|
||||||
|
} as any)
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
githubApiHelper.tryGetRepositoryObjectFormat('token', 'owner', 'repo')
|
||||||
|
).resolves.toEqual({format: '', succeeded: false})
|
||||||
|
expect(debugSpy).toHaveBeenCalledWith(
|
||||||
|
'Unable to determine repository object format from hash-algorithm endpoint: not found'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -133,6 +133,16 @@ describe('input-helper tests', () => {
|
|||||||
expect(settings.commit).toBe('1111111111222222222233333333334444444444')
|
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 () => {
|
it('sets sha to empty when explicit ref', async () => {
|
||||||
inputs.ref = 'refs/heads/some-other-ref'
|
inputs.ref = 'refs/heads/some-other-ref'
|
||||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
import * as assert from 'assert'
|
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 * as refHelper from '../lib/ref-helper'
|
||||||
import {IGitCommandManager} from '../lib/git-command-manager'
|
import {IGitCommandManager} from '../lib/git-command-manager'
|
||||||
|
|
||||||
const commit = '1234567890123456789012345678901234567890'
|
const commit = '1234567890123456789012345678901234567890'
|
||||||
|
const sha256Commit =
|
||||||
|
'1234567890123456789012345678901234567890123456789012345678901234'
|
||||||
let git: IGitCommandManager
|
let git: IGitCommandManager
|
||||||
|
|
||||||
describe('ref-helper tests', () => {
|
describe('ref-helper tests', () => {
|
||||||
@@ -37,6 +41,12 @@ describe('ref-helper tests', () => {
|
|||||||
expect(checkoutInfo.startPoint).toBeFalsy()
|
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 () => {
|
it('getCheckoutInfo refs/heads/', async () => {
|
||||||
const checkoutInfo = await refHelper.getCheckoutInfo(
|
const checkoutInfo = await refHelper.getCheckoutInfo(
|
||||||
git,
|
git,
|
||||||
@@ -227,4 +237,142 @@ describe('ref-helper tests', () => {
|
|||||||
'+refs/heads/my/branch:refs/remotes/origin/my/branch'
|
'+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')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
59
dist/index.js
vendored
59
dist/index.js
vendored
@@ -896,9 +896,14 @@ class GitCommandManager {
|
|||||||
getWorkingDirectory() {
|
getWorkingDirectory() {
|
||||||
return this.workingDirectory;
|
return this.workingDirectory;
|
||||||
}
|
}
|
||||||
init() {
|
init(objectFormat) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
yield this.execGit(['init', this.workingDirectory]);
|
const args = ['init'];
|
||||||
|
if (objectFormat === 'sha256') {
|
||||||
|
args.push('--object-format=sha256');
|
||||||
|
}
|
||||||
|
args.push(this.workingDirectory);
|
||||||
|
yield this.execGit(args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
isDetached() {
|
isDetached() {
|
||||||
@@ -1486,8 +1491,17 @@ function getSource(settings) {
|
|||||||
stateHelper.setRepositoryPath(settings.repositoryPath);
|
stateHelper.setRepositoryPath(settings.repositoryPath);
|
||||||
// Initialize the repository
|
// Initialize the repository
|
||||||
if (!fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))) {
|
if (!fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))) {
|
||||||
|
core.startGroup('Determining repository object format');
|
||||||
|
const objectFormatResult = yield githubApiHelper.tryGetRepositoryObjectFormat(settings.authToken, settings.repositoryOwner, settings.repositoryName, settings.githubServerUrl, settings.commit);
|
||||||
|
const objectFormat = objectFormatResult.succeeded
|
||||||
|
? objectFormatResult.format
|
||||||
|
: '';
|
||||||
|
if (objectFormat === 'sha256') {
|
||||||
|
core.info('Detected SHA-256 repository object format');
|
||||||
|
}
|
||||||
|
core.endGroup();
|
||||||
core.startGroup('Initializing the repository');
|
core.startGroup('Initializing the repository');
|
||||||
yield git.init();
|
yield git.init(objectFormat);
|
||||||
yield git.remoteAdd('origin', repositoryUrl);
|
yield git.remoteAdd('origin', repositoryUrl);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
}
|
}
|
||||||
@@ -1810,6 +1824,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.downloadRepository = downloadRepository;
|
exports.downloadRepository = downloadRepository;
|
||||||
exports.getDefaultBranch = getDefaultBranch;
|
exports.getDefaultBranch = getDefaultBranch;
|
||||||
|
exports.tryGetRepositoryObjectFormat = tryGetRepositoryObjectFormat;
|
||||||
const assert = __importStar(__nccwpck_require__(9491));
|
const assert = __importStar(__nccwpck_require__(9491));
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
@@ -1911,6 +1926,40 @@ function getDefaultBranch(authToken, owner, repo, baseUrl) {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function tryGetRepositoryObjectFormat(authToken, owner, repo, baseUrl, commit) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
var _a;
|
||||||
|
const commitFormat = getObjectFormat(commit);
|
||||||
|
if (commitFormat) {
|
||||||
|
return { format: commitFormat, succeeded: true };
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const octokit = github.getOctokit(authToken, {
|
||||||
|
baseUrl: (0, url_helper_1.getServerApiUrl)(baseUrl)
|
||||||
|
});
|
||||||
|
const response = yield octokit.request('GET /repos/{owner}/{repo}/hash-algorithm', { owner, repo });
|
||||||
|
const hashAlgorithm = response.data.hash_algorithm;
|
||||||
|
if (hashAlgorithm === 'sha256' || hashAlgorithm === 'sha1') {
|
||||||
|
return { format: hashAlgorithm, succeeded: true };
|
||||||
|
}
|
||||||
|
core.debug('Unable to determine repository object format from hash-algorithm endpoint');
|
||||||
|
return { format: '', succeeded: false };
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
core.debug(`Unable to determine repository object format from hash-algorithm endpoint: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
||||||
|
return { format: '', succeeded: false };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getObjectFormat(sha) {
|
||||||
|
if (/^[0-9a-fA-F]{64}$/.test(sha || '')) {
|
||||||
|
return 'sha256';
|
||||||
|
}
|
||||||
|
if (/^[0-9a-fA-F]{40}$/.test(sha || '')) {
|
||||||
|
return 'sha1';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
function downloadArchive(authToken, owner, repo, ref, commit, baseUrl) {
|
function downloadArchive(authToken, owner, repo, ref, commit, baseUrl) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const octokit = github.getOctokit(authToken, {
|
const octokit = github.getOctokit(authToken, {
|
||||||
@@ -2021,7 +2070,7 @@ function getInputs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SHA?
|
// 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.commit = result.ref;
|
||||||
result.ref = '';
|
result.ref = '';
|
||||||
}
|
}
|
||||||
@@ -2444,7 +2493,7 @@ function checkCommitInfo(token, commitInfo, repositoryOwner, repositoryName, ref
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Extract details from message
|
// 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) {
|
if (!match) {
|
||||||
core.debug('Unexpected message format');
|
core.debug('Unexpected message format');
|
||||||
return;
|
return;
|
||||||
|
|||||||
22
package-lock.json
generated
22
package-lock.json
generated
@@ -13,11 +13,13 @@
|
|||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.0",
|
||||||
"@actions/io": "^1.1.3",
|
"@actions/io": "^1.1.3",
|
||||||
"@actions/tool-cache": "^2.0.1"
|
"@actions/tool-cache": "^2.0.1",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^24.1.0",
|
||||||
|
"@types/uuid": "^9.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
||||||
"@typescript-eslint/parser": "^7.9.0",
|
"@typescript-eslint/parser": "^7.9.0",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
@@ -1527,6 +1529,12 @@
|
|||||||
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
|
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/uuid": {
|
||||||
|
"version": "9.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||||
|
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/yargs": {
|
"node_modules/@types/yargs": {
|
||||||
"version": "17.0.32",
|
"version": "17.0.32",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||||
@@ -6906,6 +6914,18 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/v8-to-istanbul": {
|
"node_modules/v8-to-istanbul": {
|
||||||
"version": "9.2.0",
|
"version": "9.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz",
|
||||||
|
|||||||
@@ -32,11 +32,13 @@
|
|||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.0",
|
||||||
"@actions/io": "^1.1.3",
|
"@actions/io": "^1.1.3",
|
||||||
"@actions/tool-cache": "^2.0.1"
|
"@actions/tool-cache": "^2.0.1",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^24.1.0",
|
||||||
|
"@types/uuid": "^9.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
||||||
"@typescript-eslint/parser": "^7.9.0",
|
"@typescript-eslint/parser": "^7.9.0",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import * as path from 'path'
|
|||||||
import * as regexpHelper from './regexp-helper'
|
import * as regexpHelper from './regexp-helper'
|
||||||
import * as stateHelper from './state-helper'
|
import * as stateHelper from './state-helper'
|
||||||
import * as urlHelper from './url-helper'
|
import * as urlHelper from './url-helper'
|
||||||
|
import {v4 as uuid} from 'uuid'
|
||||||
import {IGitCommandManager} from './git-command-manager'
|
import {IGitCommandManager} from './git-command-manager'
|
||||||
import {IGitSourceSettings} from './git-source-settings'
|
import {IGitSourceSettings} from './git-source-settings'
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ class GitAuthHelper {
|
|||||||
// Create a temp home directory
|
// Create a temp home directory
|
||||||
const runnerTemp = process.env['RUNNER_TEMP'] || ''
|
const runnerTemp = process.env['RUNNER_TEMP'] || ''
|
||||||
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
|
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
|
||||||
const uniqueId = crypto.randomUUID()
|
const uniqueId = uuid()
|
||||||
this.temporaryHomePath = path.join(runnerTemp, uniqueId)
|
this.temporaryHomePath = path.join(runnerTemp, uniqueId)
|
||||||
await fs.promises.mkdir(this.temporaryHomePath, {recursive: true})
|
await fs.promises.mkdir(this.temporaryHomePath, {recursive: true})
|
||||||
|
|
||||||
@@ -254,7 +255,7 @@ class GitAuthHelper {
|
|||||||
// Write key
|
// Write key
|
||||||
const runnerTemp = process.env['RUNNER_TEMP'] || ''
|
const runnerTemp = process.env['RUNNER_TEMP'] || ''
|
||||||
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
|
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
|
||||||
const uniqueId = crypto.randomUUID()
|
const uniqueId = uuid()
|
||||||
this.sshKeyPath = path.join(runnerTemp, uniqueId)
|
this.sshKeyPath = path.join(runnerTemp, uniqueId)
|
||||||
stateHelper.setSshKeyPath(this.sshKeyPath)
|
stateHelper.setSshKeyPath(this.sshKeyPath)
|
||||||
await fs.promises.mkdir(runnerTemp, {recursive: true})
|
await fs.promises.mkdir(runnerTemp, {recursive: true})
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export interface IGitCommandManager {
|
|||||||
getDefaultBranch(repositoryUrl: string): Promise<string>
|
getDefaultBranch(repositoryUrl: string): Promise<string>
|
||||||
getSubmoduleConfigPaths(recursive: boolean): Promise<string[]>
|
getSubmoduleConfigPaths(recursive: boolean): Promise<string[]>
|
||||||
getWorkingDirectory(): string
|
getWorkingDirectory(): string
|
||||||
init(): Promise<void>
|
init(objectFormat?: string): Promise<void>
|
||||||
isDetached(): Promise<boolean>
|
isDetached(): Promise<boolean>
|
||||||
lfsFetch(ref: string): Promise<void>
|
lfsFetch(ref: string): Promise<void>
|
||||||
lfsInstall(): Promise<void>
|
lfsInstall(): Promise<void>
|
||||||
@@ -364,8 +364,14 @@ class GitCommandManager {
|
|||||||
return this.workingDirectory
|
return this.workingDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(): Promise<void> {
|
async init(objectFormat?: string): Promise<void> {
|
||||||
await this.execGit(['init', this.workingDirectory])
|
const args = ['init']
|
||||||
|
if (objectFormat === 'sha256') {
|
||||||
|
args.push('--object-format=sha256')
|
||||||
|
}
|
||||||
|
args.push(this.workingDirectory)
|
||||||
|
|
||||||
|
await this.execGit(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
async isDetached(): Promise<boolean> {
|
async isDetached(): Promise<boolean> {
|
||||||
|
|||||||
@@ -109,8 +109,25 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
|
|||||||
if (
|
if (
|
||||||
!fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))
|
!fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))
|
||||||
) {
|
) {
|
||||||
|
core.startGroup('Determining repository object format')
|
||||||
|
const objectFormatResult =
|
||||||
|
await githubApiHelper.tryGetRepositoryObjectFormat(
|
||||||
|
settings.authToken,
|
||||||
|
settings.repositoryOwner,
|
||||||
|
settings.repositoryName,
|
||||||
|
settings.githubServerUrl,
|
||||||
|
settings.commit
|
||||||
|
)
|
||||||
|
const objectFormat = objectFormatResult.succeeded
|
||||||
|
? objectFormatResult.format
|
||||||
|
: ''
|
||||||
|
if (objectFormat === 'sha256') {
|
||||||
|
core.info('Detected SHA-256 repository object format')
|
||||||
|
}
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
core.startGroup('Initializing the repository')
|
core.startGroup('Initializing the repository')
|
||||||
await git.init()
|
await git.init(objectFormat)
|
||||||
await git.remoteAdd('origin', repositoryUrl)
|
await git.remoteAdd('origin', repositoryUrl)
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,16 @@ import * as io from '@actions/io'
|
|||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as retryHelper from './retry-helper'
|
import * as retryHelper from './retry-helper'
|
||||||
import * as toolCache from '@actions/tool-cache'
|
import * as toolCache from '@actions/tool-cache'
|
||||||
|
import {v4 as uuid} from 'uuid'
|
||||||
import {getServerApiUrl} from './url-helper'
|
import {getServerApiUrl} from './url-helper'
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32'
|
const IS_WINDOWS = process.platform === 'win32'
|
||||||
|
|
||||||
|
export interface RepositoryObjectFormatResult {
|
||||||
|
format: string
|
||||||
|
succeeded: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export async function downloadRepository(
|
export async function downloadRepository(
|
||||||
authToken: string,
|
authToken: string,
|
||||||
owner: string,
|
owner: string,
|
||||||
@@ -33,7 +39,7 @@ export async function downloadRepository(
|
|||||||
|
|
||||||
// Write archive to disk
|
// Write archive to disk
|
||||||
core.info('Writing archive to disk')
|
core.info('Writing archive to disk')
|
||||||
const uniqueId = crypto.randomUUID()
|
const uniqueId = uuid()
|
||||||
const archivePath = IS_WINDOWS
|
const archivePath = IS_WINDOWS
|
||||||
? path.join(repositoryPath, `${uniqueId}.zip`)
|
? path.join(repositoryPath, `${uniqueId}.zip`)
|
||||||
: path.join(repositoryPath, `${uniqueId}.tar.gz`)
|
: path.join(repositoryPath, `${uniqueId}.tar.gz`)
|
||||||
@@ -121,6 +127,53 @@ export async function getDefaultBranch(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function tryGetRepositoryObjectFormat(
|
||||||
|
authToken: string,
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
baseUrl?: string,
|
||||||
|
commit?: string
|
||||||
|
): Promise<RepositoryObjectFormatResult> {
|
||||||
|
const commitFormat = getObjectFormat(commit)
|
||||||
|
if (commitFormat) {
|
||||||
|
return {format: commitFormat, succeeded: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const octokit = github.getOctokit(authToken, {
|
||||||
|
baseUrl: getServerApiUrl(baseUrl)
|
||||||
|
})
|
||||||
|
const response = await octokit.request(
|
||||||
|
'GET /repos/{owner}/{repo}/hash-algorithm',
|
||||||
|
{owner, repo}
|
||||||
|
)
|
||||||
|
const hashAlgorithm = response.data.hash_algorithm
|
||||||
|
if (hashAlgorithm === 'sha256' || hashAlgorithm === 'sha1') {
|
||||||
|
return {format: hashAlgorithm, succeeded: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.debug(
|
||||||
|
'Unable to determine repository object format from hash-algorithm endpoint'
|
||||||
|
)
|
||||||
|
return {format: '', succeeded: false}
|
||||||
|
} catch (err) {
|
||||||
|
core.debug(
|
||||||
|
`Unable to determine repository object format from hash-algorithm endpoint: ${(err as any)?.message ?? err}`
|
||||||
|
)
|
||||||
|
return {format: '', succeeded: false}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getObjectFormat(sha?: string): string {
|
||||||
|
if (/^[0-9a-fA-F]{64}$/.test(sha || '')) {
|
||||||
|
return 'sha256'
|
||||||
|
}
|
||||||
|
if (/^[0-9a-fA-F]{40}$/.test(sha || '')) {
|
||||||
|
return 'sha1'
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
async function downloadArchive(
|
async function downloadArchive(
|
||||||
authToken: string,
|
authToken: string,
|
||||||
owner: string,
|
owner: string,
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SHA?
|
// 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.commit = result.ref
|
||||||
result.ref = ''
|
result.ref = ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,7 +258,9 @@ export async function checkCommitInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract details from message
|
// 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) {
|
if (!match) {
|
||||||
core.debug('Unexpected message format')
|
core.debug('Unexpected message format')
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user