mirror of https://github.com/actions/checkout
Compare commits
4 Commits
9cc48bc1c2
...
1bcc353802
| Author | SHA1 | Date |
|---|---|---|
|
|
1bcc353802 | |
|
|
3d3c42e5aa | |
|
|
28802689a1 | |
|
|
fcdb15c322 |
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -1,5 +1,18 @@
|
|||
# Changelog
|
||||
|
||||
## v7.0.1
|
||||
* Bump github/codeql-action from 3 to 4 by @dependabot[bot] in https://github.com/actions/checkout/pull/2475
|
||||
* Bump actions/setup-node from 4 to 6 by @dependabot[bot] in https://github.com/actions/checkout/pull/2477
|
||||
* Bump docker/build-push-action from 6.5.0 to 7.2.0 by @dependabot[bot] in https://github.com/actions/checkout/pull/2478
|
||||
* Bump docker/login-action from 3.3.0 to 4.2.0 by @dependabot[bot] in https://github.com/actions/checkout/pull/2479
|
||||
* Bump actions/checkout from 6 to 7 by @dependabot[bot] in https://github.com/actions/checkout/pull/2488
|
||||
* Bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in https://github.com/actions/checkout/pull/2476
|
||||
* eslint 9 by @dependabot[bot] in https://github.com/actions/checkout/pull/2474
|
||||
* Bump the minor-actions-dependencies group with 2 updates by @dependabot[bot] in https://github.com/actions/checkout/pull/2499
|
||||
* skip running unsafe pr check if input is default by @aiqiaoy in https://github.com/actions/checkout/pull/2518
|
||||
* trim only ascii whitespace for branch by @aiqiaoy in https://github.com/actions/checkout/pull/2521
|
||||
* escape values passed to --unset by @aiqiaoy in https://github.com/actions/checkout/pull/2530
|
||||
|
||||
## v7.0.0
|
||||
* Block checking out fork PR for pull_request_target and workflow_run by @aiqiaoy in https://github.com/actions/checkout/pull/2454
|
||||
* Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by @dependabot[bot] in https://github.com/actions/checkout/pull/2458
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@ jest.unstable_mockModule('@actions/core', () => ({
|
|||
// Dynamic imports after mocking
|
||||
const {RetryHelper} = await import('../src/retry-helper.js')
|
||||
|
||||
let retryHelper: any
|
||||
|
||||
describe('retry-helper tests', () => {
|
||||
beforeAll(() => {
|
||||
retryHelper = new RetryHelper(3, 0, 0)
|
||||
// @actions/core is mocked at module load above; nothing to set up here.
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -40,14 +38,22 @@ describe('retry-helper tests', () => {
|
|||
})
|
||||
|
||||
it('first attempt succeeds', async () => {
|
||||
const retryHelper: any = new RetryHelper(3, 1, 10)
|
||||
const sleep = jest.fn().mockResolvedValue(undefined)
|
||||
retryHelper.sleep = sleep
|
||||
|
||||
const actual = await retryHelper.execute(async () => {
|
||||
return 'some result'
|
||||
})
|
||||
expect(actual).toBe('some result')
|
||||
expect(info).toHaveLength(0)
|
||||
expect(sleep).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('second attempt succeeds', async () => {
|
||||
const retryHelper: any = new RetryHelper(3, 1, 10)
|
||||
const sleep = jest.fn().mockResolvedValue(undefined)
|
||||
retryHelper.sleep = sleep
|
||||
let attempts = 0
|
||||
const actual = await retryHelper.execute(() => {
|
||||
if (++attempts == 1) {
|
||||
|
|
@ -60,10 +66,15 @@ describe('retry-helper tests', () => {
|
|||
expect(actual).toBe('some result')
|
||||
expect(info).toHaveLength(2)
|
||||
expect(info[0]).toBe('some error')
|
||||
expect(info[1]).toMatch(/Waiting .+ seconds before trying again/)
|
||||
expect(info[1]).toBe('Waiting 1 seconds before trying again')
|
||||
expect(sleep).toHaveBeenCalledTimes(1)
|
||||
expect(sleep).toHaveBeenCalledWith(1)
|
||||
})
|
||||
|
||||
it('third attempt succeeds', async () => {
|
||||
const retryHelper: any = new RetryHelper(3, 1, 10)
|
||||
const sleep = jest.fn().mockResolvedValue(undefined)
|
||||
retryHelper.sleep = sleep
|
||||
let attempts = 0
|
||||
const actual = await retryHelper.execute(() => {
|
||||
if (++attempts < 3) {
|
||||
|
|
@ -76,12 +87,18 @@ describe('retry-helper tests', () => {
|
|||
expect(actual).toBe('some result')
|
||||
expect(info).toHaveLength(4)
|
||||
expect(info[0]).toBe('some error 1')
|
||||
expect(info[1]).toMatch(/Waiting .+ seconds before trying again/)
|
||||
expect(info[1]).toBe('Waiting 1 seconds before trying again')
|
||||
expect(info[2]).toBe('some error 2')
|
||||
expect(info[3]).toMatch(/Waiting .+ seconds before trying again/)
|
||||
expect(info[3]).toBe('Waiting 2 seconds before trying again')
|
||||
expect(sleep).toHaveBeenCalledTimes(2)
|
||||
expect(sleep).toHaveBeenNthCalledWith(1, 1)
|
||||
expect(sleep).toHaveBeenNthCalledWith(2, 2)
|
||||
})
|
||||
|
||||
it('all attempts fail succeeds', async () => {
|
||||
const retryHelper: any = new RetryHelper(3, 1, 10)
|
||||
const sleep = jest.fn().mockResolvedValue(undefined)
|
||||
retryHelper.sleep = sleep
|
||||
let attempts = 0
|
||||
let error: Error = null as unknown as Error
|
||||
try {
|
||||
|
|
@ -95,8 +112,42 @@ describe('retry-helper tests', () => {
|
|||
expect(attempts).toBe(3)
|
||||
expect(info).toHaveLength(4)
|
||||
expect(info[0]).toBe('some error 1')
|
||||
expect(info[1]).toMatch(/Waiting .+ seconds before trying again/)
|
||||
expect(info[1]).toBe('Waiting 1 seconds before trying again')
|
||||
expect(info[2]).toBe('some error 2')
|
||||
expect(info[3]).toMatch(/Waiting .+ seconds before trying again/)
|
||||
expect(info[3]).toBe('Waiting 2 seconds before trying again')
|
||||
expect(sleep).toHaveBeenCalledTimes(2)
|
||||
expect(sleep).toHaveBeenNthCalledWith(1, 1)
|
||||
expect(sleep).toHaveBeenNthCalledWith(2, 2)
|
||||
})
|
||||
|
||||
it('server-side 500 errors are retried with exponential backoff', async () => {
|
||||
const retryHelper: any = new RetryHelper(4, 2, 10)
|
||||
const sleep = jest.fn().mockResolvedValue(undefined)
|
||||
retryHelper.sleep = sleep
|
||||
let attempts = 0
|
||||
|
||||
const actual = await retryHelper.execute(() => {
|
||||
if (++attempts < 3) {
|
||||
const error: Error & {status?: number} = new Error(
|
||||
`server error ${attempts}`
|
||||
)
|
||||
error.status = 500
|
||||
throw error
|
||||
}
|
||||
|
||||
return Promise.resolve('some result')
|
||||
})
|
||||
|
||||
expect(actual).toBe('some result')
|
||||
expect(attempts).toBe(3)
|
||||
expect(info).toEqual([
|
||||
'server error 1',
|
||||
'Waiting 2 seconds before trying again',
|
||||
'server error 2',
|
||||
'Waiting 4 seconds before trying again'
|
||||
])
|
||||
expect(sleep).toHaveBeenCalledTimes(2)
|
||||
expect(sleep).toHaveBeenNthCalledWith(1, 2)
|
||||
expect(sleep).toHaveBeenNthCalledWith(2, 4)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -35491,7 +35491,7 @@ class retry_helper_RetryHelper {
|
|||
info(err?.message);
|
||||
}
|
||||
// Sleep
|
||||
const seconds = this.getSleepAmount();
|
||||
const seconds = this.getSleepAmount(attempt);
|
||||
info(`Waiting ${seconds} seconds before trying again`);
|
||||
await this.sleep(seconds);
|
||||
attempt++;
|
||||
|
|
@ -35499,9 +35499,11 @@ class retry_helper_RetryHelper {
|
|||
// Last attempt
|
||||
return await action();
|
||||
}
|
||||
getSleepAmount() {
|
||||
return (Math.floor(Math.random() * (this.maxSeconds - this.minSeconds + 1)) +
|
||||
this.minSeconds);
|
||||
getSleepAmount(attempt) {
|
||||
if (this.minSeconds === 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(this.minSeconds * Math.pow(2, attempt - 1), this.maxSeconds);
|
||||
}
|
||||
async sleep(seconds) {
|
||||
return new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
||||
|
|
@ -35913,7 +35915,7 @@ class GitCommandManager {
|
|||
else {
|
||||
args.push(globalConfig ? '--global' : '--local');
|
||||
}
|
||||
args.push('--unset', configKey, configValue);
|
||||
args.push('--unset', configKey, regexp_helper_escape(configValue));
|
||||
const output = await this.execGit(args, true);
|
||||
return output.exitCode === 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "checkout",
|
||||
"version": "7.0.0",
|
||||
"version": "7.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "checkout",
|
||||
"version": "7.0.0",
|
||||
"version": "7.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^3.0.1",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "checkout",
|
||||
"version": "7.0.0",
|
||||
"version": "7.0.1",
|
||||
"description": "checkout action",
|
||||
"type": "module",
|
||||
"main": "lib/main.js",
|
||||
|
|
|
|||
|
|
@ -510,7 +510,7 @@ class GitCommandManager {
|
|||
} else {
|
||||
args.push(globalConfig ? '--global' : '--local')
|
||||
}
|
||||
args.push('--unset', configKey, configValue)
|
||||
args.push('--unset', configKey, regexpHelper.escape(configValue))
|
||||
|
||||
const output = await this.execGit(args, true)
|
||||
return output.exitCode === 0
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export class RetryHelper {
|
|||
}
|
||||
|
||||
// Sleep
|
||||
const seconds = this.getSleepAmount()
|
||||
const seconds = this.getSleepAmount(attempt)
|
||||
core.info(`Waiting ${seconds} seconds before trying again`)
|
||||
await this.sleep(seconds)
|
||||
attempt++
|
||||
|
|
@ -43,11 +43,12 @@ export class RetryHelper {
|
|||
return await action()
|
||||
}
|
||||
|
||||
private getSleepAmount(): number {
|
||||
return (
|
||||
Math.floor(Math.random() * (this.maxSeconds - this.minSeconds + 1)) +
|
||||
this.minSeconds
|
||||
)
|
||||
private getSleepAmount(attempt: number): number {
|
||||
if (this.minSeconds === 0) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Math.min(this.minSeconds * Math.pow(2, attempt - 1), this.maxSeconds)
|
||||
}
|
||||
|
||||
private async sleep(seconds: number): Promise<void> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue