mirror of
https://github.com/actions/checkout.git
synced 2026-07-07 07:45:48 +03:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2567532d7 | |||
| a2aea0833e | |||
| 9cfad70759 | |||
| 2e578352d9 | |||
| ee0669bd1c | |||
| dc323e67f1 |
@@ -44,7 +44,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# If dist/ was different than expected, upload the expected version as an artifact
|
# If dist/ was different than expected, upload the expected version as an artifact
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v4
|
||||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ jobs:
|
|||||||
options: --dns 127.0.0.1
|
options: --dns 127.0.0.1
|
||||||
services:
|
services:
|
||||||
squid-proxy:
|
squid-proxy:
|
||||||
image: datadog/squid:latest
|
image: ubuntu/squid:latest
|
||||||
ports:
|
ports:
|
||||||
- 3128:3128
|
- 3128:3128
|
||||||
env:
|
env:
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/core"
|
name: "@actions/core"
|
||||||
version: 1.2.6
|
version: 1.10.0
|
||||||
type: npm
|
type: npm
|
||||||
summary:
|
summary: Actions core lib
|
||||||
homepage:
|
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE.md
|
- sources: LICENSE.md
|
||||||
|
|||||||
Generated
+32
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: "@actions/http-client"
|
||||||
|
version: 2.0.1
|
||||||
|
type: npm
|
||||||
|
summary: Actions Http Client
|
||||||
|
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
|
||||||
|
license: mit
|
||||||
|
licenses:
|
||||||
|
- sources: LICENSE
|
||||||
|
text: |
|
||||||
|
Actions Http Client for Node.js
|
||||||
|
|
||||||
|
Copyright (c) GitHub, Inc.
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
notices: []
|
||||||
Generated
+4
-2
@@ -1,13 +1,15 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/io"
|
name: "@actions/io"
|
||||||
version: 1.0.1
|
version: 1.1.2
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions io lib
|
summary: Actions io lib
|
||||||
homepage: https://github.com/actions/toolkit/tree/master/packages/io
|
homepage: https://github.com/actions/toolkit/tree/main/packages/io
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE.md
|
- sources: LICENSE.md
|
||||||
text: |-
|
text: |-
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright 2019 GitHub
|
Copyright 2019 GitHub
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: node-fetch
|
name: node-fetch
|
||||||
version: 2.6.5
|
version: 2.6.7
|
||||||
type: npm
|
type: npm
|
||||||
summary: A light-weight module that brings window.fetch to node.js
|
summary: A light-weight module that brings window.fetch to node.js
|
||||||
homepage: https://github.com/bitinn/node-fetch
|
homepage: https://github.com/bitinn/node-fetch
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: qs
|
name: qs
|
||||||
version: 6.10.1
|
version: 6.11.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: A querystring parser that supports nesting and arrays, with a depth limit
|
summary: A querystring parser that supports nesting and arrays, with a depth limit
|
||||||
homepage: https://github.com/ljharb/qs
|
homepage: https://github.com/ljharb/qs
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: uuid
|
|||||||
version: 3.3.3
|
version: 3.3.3
|
||||||
type: npm
|
type: npm
|
||||||
summary: RFC4122 (v1, v4, and v5) UUIDs
|
summary: RFC4122 (v1, v4, and v5) UUIDs
|
||||||
homepage: https://github.com/kelektiv/node-uuid#readme
|
homepage:
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE.md
|
- sources: LICENSE.md
|
||||||
Generated
+20
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: uuid
|
||||||
|
version: 8.3.2
|
||||||
|
type: npm
|
||||||
|
summary: RFC4122 (v1, v4, and v5) UUIDs
|
||||||
|
homepage:
|
||||||
|
license: mit
|
||||||
|
licenses:
|
||||||
|
- sources: LICENSE.md
|
||||||
|
text: |
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
notices: []
|
||||||
@@ -110,6 +110,15 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous
|
|||||||
# config --global --add safe.directory <path>`
|
# config --global --add safe.directory <path>`
|
||||||
# Default: true
|
# Default: true
|
||||||
set-safe-directory: ''
|
set-safe-directory: ''
|
||||||
|
|
||||||
|
# Required to check out fork pull request code from a workflow triggered by
|
||||||
|
# `pull_request_target` or `workflow_run`. These workflows run with the base
|
||||||
|
# repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner
|
||||||
|
# access; fetching and executing a fork's code in that trusted context commonly
|
||||||
|
# leads to "pwn request" vulnerabilities. Set to `true` only after reviewing the
|
||||||
|
# risks at https://gh.io/securely-using-pull_request_target.
|
||||||
|
# Default: false
|
||||||
|
allow-unsafe-pr-checkout: ''
|
||||||
```
|
```
|
||||||
<!-- end usage -->
|
<!-- end usage -->
|
||||||
|
|
||||||
|
|||||||
@@ -778,7 +778,8 @@ async function setup(testName: string): Promise<void> {
|
|||||||
sshKnownHosts: '',
|
sshKnownHosts: '',
|
||||||
sshStrict: true,
|
sshStrict: true,
|
||||||
workflowOrganizationId: 123456,
|
workflowOrganizationId: 123456,
|
||||||
setSafeDirectory: true
|
setSafeDirectory: true,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ describe('input-helper tests', () => {
|
|||||||
expect(settings.repositoryOwner).toBe('some-owner')
|
expect(settings.repositoryOwner).toBe('some-owner')
|
||||||
expect(settings.repositoryPath).toBe(gitHubWorkspace)
|
expect(settings.repositoryPath).toBe(gitHubWorkspace)
|
||||||
expect(settings.setSafeDirectory).toBe(true)
|
expect(settings.setSafeDirectory).toBe(true)
|
||||||
|
expect(settings.allowUnsafePrCheckout).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('qualifies ref', async () => {
|
it('qualifies ref', async () => {
|
||||||
|
|||||||
@@ -0,0 +1,267 @@
|
|||||||
|
import * as github from '@actions/github'
|
||||||
|
import {assertSafePrCheckout} from '../lib/unsafe-pr-checkout-helper'
|
||||||
|
|
||||||
|
// Shallow clone original @actions/github context
|
||||||
|
const originalContext = {...github.context}
|
||||||
|
const originalEventName = github.context.eventName
|
||||||
|
const originalPayload = github.context.payload
|
||||||
|
|
||||||
|
const BASE_REPO_ID = 100
|
||||||
|
const FORK_REPO_ID = 200
|
||||||
|
const PR_HEAD_SHA = '1111111111111111111111111111111111111111'
|
||||||
|
const PR_MERGE_SHA = '2222222222222222222222222222222222222222'
|
||||||
|
const SAFE_BASE_SHA = '3333333333333333333333333333333333333333'
|
||||||
|
const WORKFLOW_RUN_HEAD_COMMIT_SHA = '4444444444444444444444444444444444444444'
|
||||||
|
const BASE_QUALIFIED_REPO = 'some-owner/some-repo'
|
||||||
|
const FORK_QUALIFIED_REPO = 'another-repo/fork'
|
||||||
|
|
||||||
|
function setContext(eventName: string, payload: object): void {
|
||||||
|
;(github.context as {eventName: string}).eventName = eventName
|
||||||
|
;(github.context as {payload: object}).payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
function forkPullRequestTargetPayload(): object {
|
||||||
|
return {
|
||||||
|
repository: {id: BASE_REPO_ID},
|
||||||
|
pull_request: {
|
||||||
|
head: {
|
||||||
|
sha: PR_HEAD_SHA,
|
||||||
|
repo: {id: FORK_REPO_ID, full_name: FORK_QUALIFIED_REPO}
|
||||||
|
},
|
||||||
|
merge_commit_sha: PR_MERGE_SHA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sameRepoPullRequestTargetPayload(): object {
|
||||||
|
return {
|
||||||
|
repository: {id: BASE_REPO_ID},
|
||||||
|
pull_request: {
|
||||||
|
head: {
|
||||||
|
sha: PR_HEAD_SHA,
|
||||||
|
repo: {id: BASE_REPO_ID, full_name: BASE_QUALIFIED_REPO}
|
||||||
|
},
|
||||||
|
merge_commit_sha: PR_MERGE_SHA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function forkWorkflowRunPayload(): object {
|
||||||
|
return {
|
||||||
|
repository: {id: BASE_REPO_ID},
|
||||||
|
workflow_run: {
|
||||||
|
event: 'pull_request',
|
||||||
|
head_commit: {id: WORKFLOW_RUN_HEAD_COMMIT_SHA},
|
||||||
|
head_repository: {id: FORK_REPO_ID, full_name: FORK_QUALIFIED_REPO}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('unsafe-pr-checkout-helper', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(github.context, 'repo', 'get').mockReturnValue({
|
||||||
|
owner: 'some-owner',
|
||||||
|
repo: 'some-repo'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
;(github.context as {eventName: string}).eventName = originalEventName
|
||||||
|
;(github.context as {payload: object}).payload = originalPayload
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
;(github.context as {eventName: string}).eventName =
|
||||||
|
originalContext.eventName
|
||||||
|
;(github.context as {payload: object}).payload = originalContext.payload
|
||||||
|
jest.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows pull_request events untouched', () => {
|
||||||
|
setContext('pull_request', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: 'attacker/fork',
|
||||||
|
ref: 'refs/pull/1/merge',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).not.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows pull_request_target default checkout (base branch)', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: 'refs/heads/main',
|
||||||
|
commit: SAFE_BASE_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).not.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows same-repo pull_request_target checkout of PR head', () => {
|
||||||
|
setContext('pull_request_target', sameRepoPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: PR_HEAD_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).not.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target fork PR head SHA checkout', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: PR_HEAD_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow(/Refusing to check out fork pull request code/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target fork PR merge_commit_sha checkout', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: PR_MERGE_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow(/allow-unsafe-pr-checkout/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target fork PR ref pattern (head)', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: 'refs/pull/42/head',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target fork PR ref pattern (merge)', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: 'refs/pull/42/merge',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target when repository points at the fork', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: FORK_QUALIFIED_REPO,
|
||||||
|
ref: 'refs/heads/main',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows pull_request_target checkout of an unrelated third-party repo', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: 'some-other/unrelated',
|
||||||
|
ref: 'refs/heads/main',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).not.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target ignoring repository case differences', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: FORK_QUALIFIED_REPO.toUpperCase(),
|
||||||
|
ref: '',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses pull_request_target ignoring commit SHA case differences', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: PR_HEAD_SHA.toUpperCase(),
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows pull_request_target fork PR checkout when opted in', () => {
|
||||||
|
setContext('pull_request_target', forkPullRequestTargetPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: 'refs/pull/42/merge',
|
||||||
|
commit: '',
|
||||||
|
allowUnsafePrCheckout: true
|
||||||
|
})
|
||||||
|
).not.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses workflow_run fork PR head_commit.id checkout', () => {
|
||||||
|
setContext('workflow_run', forkWorkflowRunPayload())
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: WORKFLOW_RUN_HEAD_COMMIT_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refuses workflow_run with pull_request_target underlying event', () => {
|
||||||
|
const payload = forkWorkflowRunPayload() as {
|
||||||
|
workflow_run: {event: string}
|
||||||
|
}
|
||||||
|
payload.workflow_run.event = 'pull_request_target'
|
||||||
|
setContext('workflow_run', payload)
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: WORKFLOW_RUN_HEAD_COMMIT_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows workflow_run same-repo PR (head_repository.id matches base)', () => {
|
||||||
|
const payload = forkWorkflowRunPayload() as {
|
||||||
|
workflow_run: {head_repository: {id: number}}
|
||||||
|
}
|
||||||
|
payload.workflow_run.head_repository.id = BASE_REPO_ID
|
||||||
|
setContext('workflow_run', payload)
|
||||||
|
expect(() =>
|
||||||
|
assertSafePrCheckout({
|
||||||
|
qualifiedRepository: BASE_QUALIFIED_REPO,
|
||||||
|
ref: '',
|
||||||
|
commit: WORKFLOW_RUN_HEAD_COMMIT_SHA,
|
||||||
|
allowUnsafePrCheckout: false
|
||||||
|
})
|
||||||
|
).not.toThrow()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -71,6 +71,15 @@ inputs:
|
|||||||
set-safe-directory:
|
set-safe-directory:
|
||||||
description: Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory <path>`
|
description: Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory <path>`
|
||||||
default: true
|
default: true
|
||||||
|
allow-unsafe-pr-checkout:
|
||||||
|
description: >
|
||||||
|
Required to check out fork pull request code from a workflow triggered by
|
||||||
|
`pull_request_target` or `workflow_run`. These workflows run with the
|
||||||
|
base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and
|
||||||
|
runner access; fetching and executing a fork's code in that trusted
|
||||||
|
context commonly leads to "pwn request" vulnerabilities. Set to `true`
|
||||||
|
only after reviewing the risks at https://gh.io/securely-using-pull_request_target.
|
||||||
|
default: false
|
||||||
runs:
|
runs:
|
||||||
using: node12
|
using: node12
|
||||||
main: dist/index.js
|
main: dist/index.js
|
||||||
|
|||||||
Vendored
+330
-121
@@ -98,6 +98,25 @@ module.exports = Octokit;
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
@@ -108,11 +127,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const childProcess = __webpack_require__(129);
|
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
||||||
const path = __webpack_require__(622);
|
const assert_1 = __webpack_require__(357);
|
||||||
|
const childProcess = __importStar(__webpack_require__(129));
|
||||||
|
const path = __importStar(__webpack_require__(622));
|
||||||
const util_1 = __webpack_require__(669);
|
const util_1 = __webpack_require__(669);
|
||||||
const ioUtil = __webpack_require__(672);
|
const ioUtil = __importStar(__webpack_require__(672));
|
||||||
const exec = util_1.promisify(childProcess.exec);
|
const exec = util_1.promisify(childProcess.exec);
|
||||||
|
const execFile = util_1.promisify(childProcess.execFile);
|
||||||
/**
|
/**
|
||||||
* Copies a file or folder.
|
* Copies a file or folder.
|
||||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||||
@@ -123,14 +145,14 @@ const exec = util_1.promisify(childProcess.exec);
|
|||||||
*/
|
*/
|
||||||
function cp(source, dest, options = {}) {
|
function cp(source, dest, options = {}) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const { force, recursive } = readCopyOptions(options);
|
const { force, recursive, copySourceDirectory } = readCopyOptions(options);
|
||||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
||||||
// Dest is an existing file, but not forcing
|
// Dest is an existing file, but not forcing
|
||||||
if (destStat && destStat.isFile() && !force) {
|
if (destStat && destStat.isFile() && !force) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If dest is an existing directory, should copy inside.
|
// If dest is an existing directory, should copy inside.
|
||||||
const newDest = destStat && destStat.isDirectory()
|
const newDest = destStat && destStat.isDirectory() && copySourceDirectory
|
||||||
? path.join(dest, path.basename(source))
|
? path.join(dest, path.basename(source))
|
||||||
: dest;
|
: dest;
|
||||||
if (!(yield ioUtil.exists(source))) {
|
if (!(yield ioUtil.exists(source))) {
|
||||||
@@ -195,12 +217,22 @@ function rmRF(inputPath) {
|
|||||||
if (ioUtil.IS_WINDOWS) {
|
if (ioUtil.IS_WINDOWS) {
|
||||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||||||
|
// Check for invalid characters
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
||||||
|
if (/[*"<>|]/.test(inputPath)) {
|
||||||
|
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
|
const cmdPath = ioUtil.getCmdPath();
|
||||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
if (yield ioUtil.isDirectory(inputPath, true)) {
|
||||||
yield exec(`rd /s /q "${inputPath}"`);
|
yield exec(`${cmdPath} /s /c "rd /s /q "%inputPath%""`, {
|
||||||
|
env: { inputPath }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
yield exec(`del /f /a "${inputPath}"`);
|
yield exec(`${cmdPath} /s /c "del /f /a "%inputPath%""`, {
|
||||||
|
env: { inputPath }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -233,7 +265,7 @@ function rmRF(inputPath) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
yield exec(`rm -rf "${inputPath}"`);
|
yield execFile(`rm`, [`-rf`, `${inputPath}`]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
yield ioUtil.unlink(inputPath);
|
yield ioUtil.unlink(inputPath);
|
||||||
@@ -251,7 +283,8 @@ exports.rmRF = rmRF;
|
|||||||
*/
|
*/
|
||||||
function mkdirP(fsPath) {
|
function mkdirP(fsPath) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
yield ioUtil.mkdirP(fsPath);
|
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||||
|
yield ioUtil.mkdir(fsPath, { recursive: true });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.mkdirP = mkdirP;
|
exports.mkdirP = mkdirP;
|
||||||
@@ -279,62 +312,80 @@ function which(tool, check) {
|
|||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
try {
|
const matches = yield findInPath(tool);
|
||||||
// build the list of extensions to try
|
if (matches && matches.length > 0) {
|
||||||
const extensions = [];
|
return matches[0];
|
||||||
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
|
|
||||||
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
|
|
||||||
if (extension) {
|
|
||||||
extensions.push(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if it's rooted, return it if exists. otherwise return empty.
|
|
||||||
if (ioUtil.isRooted(tool)) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
|
||||||
if (filePath) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
// if any path separators, return empty
|
|
||||||
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
// build the list of directories
|
|
||||||
//
|
|
||||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
|
||||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
|
||||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
|
||||||
// across platforms.
|
|
||||||
const directories = [];
|
|
||||||
if (process.env.PATH) {
|
|
||||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
|
||||||
if (p) {
|
|
||||||
directories.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// return the first match
|
|
||||||
for (const directory of directories) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
|
|
||||||
if (filePath) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
throw new Error(`which failed with message ${err.message}`);
|
|
||||||
}
|
}
|
||||||
|
return '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.which = which;
|
exports.which = which;
|
||||||
|
/**
|
||||||
|
* Returns a list of all occurrences of the given tool on the system path.
|
||||||
|
*
|
||||||
|
* @returns Promise<string[]> the paths of the tool
|
||||||
|
*/
|
||||||
|
function findInPath(tool) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!tool) {
|
||||||
|
throw new Error("parameter 'tool' is required");
|
||||||
|
}
|
||||||
|
// build the list of extensions to try
|
||||||
|
const extensions = [];
|
||||||
|
if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {
|
||||||
|
for (const extension of process.env['PATHEXT'].split(path.delimiter)) {
|
||||||
|
if (extension) {
|
||||||
|
extensions.push(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if it's rooted, return it if exists. otherwise return empty.
|
||||||
|
if (ioUtil.isRooted(tool)) {
|
||||||
|
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
||||||
|
if (filePath) {
|
||||||
|
return [filePath];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
// if any path separators, return empty
|
||||||
|
if (tool.includes(path.sep)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
// build the list of directories
|
||||||
|
//
|
||||||
|
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
||||||
|
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||||||
|
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
||||||
|
// across platforms.
|
||||||
|
const directories = [];
|
||||||
|
if (process.env.PATH) {
|
||||||
|
for (const p of process.env.PATH.split(path.delimiter)) {
|
||||||
|
if (p) {
|
||||||
|
directories.push(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// find all matches
|
||||||
|
const matches = [];
|
||||||
|
for (const directory of directories) {
|
||||||
|
const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);
|
||||||
|
if (filePath) {
|
||||||
|
matches.push(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.findInPath = findInPath;
|
||||||
function readCopyOptions(options) {
|
function readCopyOptions(options) {
|
||||||
const force = options.force == null ? true : options.force;
|
const force = options.force == null ? true : options.force;
|
||||||
const recursive = Boolean(options.recursive);
|
const recursive = Boolean(options.recursive);
|
||||||
return { force, recursive };
|
const copySourceDirectory = options.copySourceDirectory == null
|
||||||
|
? true
|
||||||
|
: Boolean(options.copySourceDirectory);
|
||||||
|
return { force, recursive, copySourceDirectory };
|
||||||
}
|
}
|
||||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
@@ -4689,7 +4740,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.checkCommitInfo = exports.testRef = exports.getRefSpec = exports.getRefSpecForAllHistory = exports.getCheckoutInfo = exports.tagsRefSpec = void 0;
|
exports.fromPayload = exports.checkCommitInfo = exports.testRef = exports.getRefSpec = exports.getRefSpecForAllHistory = exports.getCheckoutInfo = exports.tagsRefSpec = void 0;
|
||||||
const url_1 = __webpack_require__(835);
|
const url_1 = __webpack_require__(835);
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
const github = __importStar(__webpack_require__(469));
|
const github = __importStar(__webpack_require__(469));
|
||||||
@@ -4907,6 +4958,7 @@ exports.checkCommitInfo = checkCommitInfo;
|
|||||||
function fromPayload(path) {
|
function fromPayload(path) {
|
||||||
return select(github.context.payload, path);
|
return select(github.context.payload, path);
|
||||||
}
|
}
|
||||||
|
exports.fromPayload = fromPayload;
|
||||||
function select(obj, path) {
|
function select(obj, path) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -7064,7 +7116,9 @@ class GitAuthHelper {
|
|||||||
// Configure a placeholder value. This approach avoids the credential being captured
|
// Configure a placeholder value. This approach avoids the credential being captured
|
||||||
// by process creation audit events, which are commonly logged. For more information,
|
// by process creation audit events, which are commonly logged. For more information,
|
||||||
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||||
const output = yield this.git.submoduleForeach(`git config --local '${this.tokenConfigKey}' '${this.tokenPlaceholderConfigValue}' && git config --local --show-origin --name-only --get-regexp remote.origin.url`, this.settings.nestedSubmodules);
|
const output = yield this.git.submoduleForeach(
|
||||||
|
// wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline
|
||||||
|
`sh -c "git config --local '${this.tokenConfigKey}' '${this.tokenPlaceholderConfigValue}' && git config --local --show-origin --name-only --get-regexp remote.origin.url"`, this.settings.nestedSubmodules);
|
||||||
// Replace the placeholder
|
// Replace the placeholder
|
||||||
const configPaths = output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || [];
|
const configPaths = output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || [];
|
||||||
for (const configPath of configPaths) {
|
for (const configPath of configPaths) {
|
||||||
@@ -7138,7 +7192,7 @@ class GitAuthHelper {
|
|||||||
if (this.settings.sshKnownHosts) {
|
if (this.settings.sshKnownHosts) {
|
||||||
knownHosts += `# Begin from input known hosts\n${this.settings.sshKnownHosts}\n# end from input known hosts\n`;
|
knownHosts += `# Begin from input known hosts\n${this.settings.sshKnownHosts}\n# end from input known hosts\n`;
|
||||||
}
|
}
|
||||||
knownHosts += `# Begin implicitly added github.com\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n# End implicitly added github.com\n`;
|
knownHosts += `# Begin implicitly added github.com\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\n# End implicitly added github.com\n`;
|
||||||
this.sshKnownHostsPath = path.join(runnerTemp, `${uniqueId}_known_hosts`);
|
this.sshKnownHostsPath = path.join(runnerTemp, `${uniqueId}_known_hosts`);
|
||||||
stateHelper.setSshKnownHostsPath(this.sshKnownHostsPath);
|
stateHelper.setSshKnownHostsPath(this.sshKnownHostsPath);
|
||||||
yield fs.promises.writeFile(this.sshKnownHostsPath, knownHosts);
|
yield fs.promises.writeFile(this.sshKnownHostsPath, knownHosts);
|
||||||
@@ -7231,7 +7285,9 @@ class GitAuthHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const pattern = regexpHelper.escape(configKey);
|
const pattern = regexpHelper.escape(configKey);
|
||||||
yield this.git.submoduleForeach(`git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :`, true);
|
yield this.git.submoduleForeach(
|
||||||
|
// wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline
|
||||||
|
`sh -c "git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :"`, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10567,7 +10623,7 @@ Object.defineProperty(Response.prototype, Symbol.toStringTag, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const INTERNALS$2 = Symbol('Request internals');
|
const INTERNALS$2 = Symbol('Request internals');
|
||||||
const URL = whatwgUrl.URL;
|
const URL = Url.URL || whatwgUrl.URL;
|
||||||
|
|
||||||
// fix an issue where "format", "parse" aren't a named export for node <10
|
// fix an issue where "format", "parse" aren't a named export for node <10
|
||||||
const parse_url = Url.parse;
|
const parse_url = Url.parse;
|
||||||
@@ -10830,9 +10886,17 @@ AbortError.prototype = Object.create(Error.prototype);
|
|||||||
AbortError.prototype.constructor = AbortError;
|
AbortError.prototype.constructor = AbortError;
|
||||||
AbortError.prototype.name = 'AbortError';
|
AbortError.prototype.name = 'AbortError';
|
||||||
|
|
||||||
|
const URL$1 = Url.URL || whatwgUrl.URL;
|
||||||
|
|
||||||
// fix an issue where "PassThrough", "resolve" aren't a named export for node <10
|
// fix an issue where "PassThrough", "resolve" aren't a named export for node <10
|
||||||
const PassThrough$1 = Stream.PassThrough;
|
const PassThrough$1 = Stream.PassThrough;
|
||||||
const resolve_url = Url.resolve;
|
|
||||||
|
const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) {
|
||||||
|
const orig = new URL$1(original).hostname;
|
||||||
|
const dest = new URL$1(destination).hostname;
|
||||||
|
|
||||||
|
return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch function
|
* Fetch function
|
||||||
@@ -10920,7 +10984,19 @@ function fetch(url, opts) {
|
|||||||
const location = headers.get('Location');
|
const location = headers.get('Location');
|
||||||
|
|
||||||
// HTTP fetch step 5.3
|
// HTTP fetch step 5.3
|
||||||
const locationURL = location === null ? null : resolve_url(request.url, location);
|
let locationURL = null;
|
||||||
|
try {
|
||||||
|
locationURL = location === null ? null : new URL$1(location, request.url).toString();
|
||||||
|
} catch (err) {
|
||||||
|
// error here can only be invalid URL in Location: header
|
||||||
|
// do not throw when options.redirect == manual
|
||||||
|
// let the user extract the errorneous redirect URL
|
||||||
|
if (request.redirect !== 'manual') {
|
||||||
|
reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect'));
|
||||||
|
finalize();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HTTP fetch step 5.5
|
// HTTP fetch step 5.5
|
||||||
switch (request.redirect) {
|
switch (request.redirect) {
|
||||||
@@ -10968,6 +11044,12 @@ function fetch(url, opts) {
|
|||||||
size: request.size
|
size: request.size
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!isDomainOrSubdomain(request.url, locationURL)) {
|
||||||
|
for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) {
|
||||||
|
requestOpts.headers.delete(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HTTP-redirect fetch step 9
|
// HTTP-redirect fetch step 9
|
||||||
if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
|
if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
|
||||||
reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
|
reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
|
||||||
@@ -13241,6 +13323,102 @@ function getNextPage (octokit, link, headers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 554:
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.assertSafePrCheckout = void 0;
|
||||||
|
const github = __importStar(__webpack_require__(469));
|
||||||
|
const ref_helper_1 = __webpack_require__(227);
|
||||||
|
const PR_REF_PATTERN = /^refs\/pull\/[0-9]+\/(?:head|merge)$/;
|
||||||
|
function assertSafePrCheckout(input) {
|
||||||
|
if (input.allowUnsafePrCheckout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const eventName = github.context.eventName;
|
||||||
|
if (eventName !== 'pull_request_target' && eventName !== 'workflow_run') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const baseRepoId = (0, ref_helper_1.fromPayload)('repository.id');
|
||||||
|
if (typeof baseRepoId !== 'number') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let prHeadRepoId;
|
||||||
|
let prHeadRepoFullName;
|
||||||
|
const prShas = [];
|
||||||
|
if (eventName === 'pull_request_target') {
|
||||||
|
prHeadRepoId = (0, ref_helper_1.fromPayload)('pull_request.head.repo.id');
|
||||||
|
prHeadRepoFullName = (0, ref_helper_1.fromPayload)('pull_request.head.repo.full_name');
|
||||||
|
pushIfSha(prShas, (0, ref_helper_1.fromPayload)('pull_request.head.sha'));
|
||||||
|
pushIfSha(prShas, (0, ref_helper_1.fromPayload)('pull_request.merge_commit_sha'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const wrEvent = (0, ref_helper_1.fromPayload)('workflow_run.event');
|
||||||
|
if (typeof wrEvent !== 'string' || !wrEvent.startsWith('pull_request')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prHeadRepoId = (0, ref_helper_1.fromPayload)('workflow_run.head_repository.id');
|
||||||
|
prHeadRepoFullName = (0, ref_helper_1.fromPayload)('workflow_run.head_repository.full_name');
|
||||||
|
pushIfSha(prShas, (0, ref_helper_1.fromPayload)('workflow_run.head_commit.id'));
|
||||||
|
// For `pull_request_target`-triggered workflow_run, `head_sha` is the base
|
||||||
|
// default branch SHA (not the PR head)
|
||||||
|
if (wrEvent !== 'pull_request_target') {
|
||||||
|
pushIfSha(prShas, (0, ref_helper_1.fromPayload)('workflow_run.head_sha'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// (A) Fork PR?
|
||||||
|
if (typeof prHeadRepoId !== 'number' || prHeadRepoId === baseRepoId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// (B) We cannot check for all fork PR refs so check to see
|
||||||
|
// if the resolved input points to the fork PR sha we have in the payload
|
||||||
|
const repositoryMatchesPrHead = typeof prHeadRepoFullName === 'string' &&
|
||||||
|
input.qualifiedRepository.toLowerCase() === prHeadRepoFullName.toLowerCase();
|
||||||
|
const refMatchesPullPattern = PR_REF_PATTERN.test(input.ref);
|
||||||
|
const commitMatchesPrHeadSha = !!input.commit && prShas.includes(input.commit.toLowerCase());
|
||||||
|
if (!repositoryMatchesPrHead &&
|
||||||
|
!refMatchesPullPattern &&
|
||||||
|
!commitMatchesPrHeadSha) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Error(`Refusing to check out fork pull request code from a '${eventName}' workflow. ` +
|
||||||
|
`This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch ` +
|
||||||
|
`cache scope, and runner access. Fetching and executing a fork's code in that trusted ` +
|
||||||
|
`context commonly leads to "pwn request" vulnerabilities. To opt in, review the risks ` +
|
||||||
|
`at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' ` +
|
||||||
|
`on the actions/checkout step.`);
|
||||||
|
}
|
||||||
|
exports.assertSafePrCheckout = assertSafePrCheckout;
|
||||||
|
function pushIfSha(target, value) {
|
||||||
|
if (typeof value === 'string' && value.length > 0) {
|
||||||
|
target.push(value.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 558:
|
/***/ 558:
|
||||||
@@ -13809,6 +13987,7 @@ var encode = function encode(str, defaultEncoder, charset, kind, format) {
|
|||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
||||||
|
/* eslint operator-linebreak: [2, "before"] */
|
||||||
out += hexTable[0xF0 | (c >> 18)]
|
out += hexTable[0xF0 | (c >> 18)]
|
||||||
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
||||||
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
||||||
@@ -16310,6 +16489,25 @@ module.exports = require("util");
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
@@ -16321,9 +16519,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
};
|
};
|
||||||
var _a;
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const assert_1 = __webpack_require__(357);
|
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rename = exports.readlink = exports.readdir = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
||||||
const fs = __webpack_require__(747);
|
const fs = __importStar(__webpack_require__(747));
|
||||||
const path = __webpack_require__(622);
|
const path = __importStar(__webpack_require__(622));
|
||||||
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
exports.IS_WINDOWS = process.platform === 'win32';
|
||||||
function exists(fsPath) {
|
function exists(fsPath) {
|
||||||
@@ -16364,49 +16562,6 @@ function isRooted(p) {
|
|||||||
return p.startsWith('/');
|
return p.startsWith('/');
|
||||||
}
|
}
|
||||||
exports.isRooted = isRooted;
|
exports.isRooted = isRooted;
|
||||||
/**
|
|
||||||
* Recursively create a directory at `fsPath`.
|
|
||||||
*
|
|
||||||
* This implementation is optimistic, meaning it attempts to create the full
|
|
||||||
* path first, and backs up the path stack from there.
|
|
||||||
*
|
|
||||||
* @param fsPath The path to create
|
|
||||||
* @param maxDepth The maximum recursion depth
|
|
||||||
* @param depth The current recursion depth
|
|
||||||
*/
|
|
||||||
function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
|
||||||
fsPath = path.resolve(fsPath);
|
|
||||||
if (depth >= maxDepth)
|
|
||||||
return exports.mkdir(fsPath);
|
|
||||||
try {
|
|
||||||
yield exports.mkdir(fsPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
switch (err.code) {
|
|
||||||
case 'ENOENT': {
|
|
||||||
yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
|
|
||||||
yield exports.mkdir(fsPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
let stats;
|
|
||||||
try {
|
|
||||||
stats = yield exports.stat(fsPath);
|
|
||||||
}
|
|
||||||
catch (err2) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
if (!stats.isDirectory())
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mkdirP = mkdirP;
|
|
||||||
/**
|
/**
|
||||||
* Best effort attempt to determine whether a file exists and is executable.
|
* Best effort attempt to determine whether a file exists and is executable.
|
||||||
* @param filePath file path to check
|
* @param filePath file path to check
|
||||||
@@ -16503,6 +16658,12 @@ function isUnixExecutable(stats) {
|
|||||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||||
}
|
}
|
||||||
|
// Get the path of cmd.exe in windows
|
||||||
|
function getCmdPath() {
|
||||||
|
var _a;
|
||||||
|
return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
|
||||||
|
}
|
||||||
|
exports.getCmdPath = getCmdPath;
|
||||||
//# sourceMappingURL=io-util.js.map
|
//# sourceMappingURL=io-util.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -17452,7 +17613,7 @@ var parseObject = function (chain, val, options, valuesParsed) {
|
|||||||
) {
|
) {
|
||||||
obj = [];
|
obj = [];
|
||||||
obj[index] = leaf;
|
obj[index] = leaf;
|
||||||
} else {
|
} else if (cleanRoot !== '__proto__') {
|
||||||
obj[cleanRoot] = leaf;
|
obj[cleanRoot] = leaf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18308,6 +18469,7 @@ const core = __importStar(__webpack_require__(470));
|
|||||||
const fsHelper = __importStar(__webpack_require__(618));
|
const fsHelper = __importStar(__webpack_require__(618));
|
||||||
const github = __importStar(__webpack_require__(469));
|
const github = __importStar(__webpack_require__(469));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
|
const unsafePrCheckoutHelper = __importStar(__webpack_require__(554));
|
||||||
const workflowContextHelper = __importStar(__webpack_require__(642));
|
const workflowContextHelper = __importStar(__webpack_require__(642));
|
||||||
function getInputs() {
|
function getInputs() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
@@ -18401,6 +18563,17 @@ function getInputs() {
|
|||||||
// Set safe.directory in git global config.
|
// Set safe.directory in git global config.
|
||||||
result.setSafeDirectory =
|
result.setSafeDirectory =
|
||||||
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE';
|
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE';
|
||||||
|
// Allow unsafe PR checkout (opt-in for pull_request_target / workflow_run fork PRs)
|
||||||
|
result.allowUnsafePrCheckout =
|
||||||
|
(core.getInput('allow-unsafe-pr-checkout') || 'false').toUpperCase() ===
|
||||||
|
'TRUE';
|
||||||
|
core.debug(`allow unsafe PR checkout = ${result.allowUnsafePrCheckout}`);
|
||||||
|
unsafePrCheckoutHelper.assertSafePrCheckout({
|
||||||
|
qualifiedRepository,
|
||||||
|
ref: result.ref,
|
||||||
|
commit: result.commit,
|
||||||
|
allowUnsafePrCheckout: result.allowUnsafePrCheckout
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -34581,6 +34754,7 @@ var arrayPrefixGenerators = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var isArray = Array.isArray;
|
var isArray = Array.isArray;
|
||||||
|
var split = String.prototype.split;
|
||||||
var push = Array.prototype.push;
|
var push = Array.prototype.push;
|
||||||
var pushToArray = function (arr, valueOrArray) {
|
var pushToArray = function (arr, valueOrArray) {
|
||||||
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
||||||
@@ -34617,10 +34791,13 @@ var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
|
|||||||
|| typeof v === 'bigint';
|
|| typeof v === 'bigint';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var sentinel = {};
|
||||||
|
|
||||||
var stringify = function stringify(
|
var stringify = function stringify(
|
||||||
object,
|
object,
|
||||||
prefix,
|
prefix,
|
||||||
generateArrayPrefix,
|
generateArrayPrefix,
|
||||||
|
commaRoundTrip,
|
||||||
strictNullHandling,
|
strictNullHandling,
|
||||||
skipNulls,
|
skipNulls,
|
||||||
encoder,
|
encoder,
|
||||||
@@ -34636,8 +34813,23 @@ var stringify = function stringify(
|
|||||||
) {
|
) {
|
||||||
var obj = object;
|
var obj = object;
|
||||||
|
|
||||||
if (sideChannel.has(object)) {
|
var tmpSc = sideChannel;
|
||||||
throw new RangeError('Cyclic object value');
|
var step = 0;
|
||||||
|
var findFlag = false;
|
||||||
|
while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
|
||||||
|
// Where object last appeared in the ref tree
|
||||||
|
var pos = tmpSc.get(object);
|
||||||
|
step += 1;
|
||||||
|
if (typeof pos !== 'undefined') {
|
||||||
|
if (pos === step) {
|
||||||
|
throw new RangeError('Cyclic object value');
|
||||||
|
} else {
|
||||||
|
findFlag = true; // Break while
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof tmpSc.get(sentinel) === 'undefined') {
|
||||||
|
step = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof filter === 'function') {
|
if (typeof filter === 'function') {
|
||||||
@@ -34664,6 +34856,14 @@ var stringify = function stringify(
|
|||||||
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
||||||
if (encoder) {
|
if (encoder) {
|
||||||
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
|
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
|
||||||
|
if (generateArrayPrefix === 'comma' && encodeValuesOnly) {
|
||||||
|
var valuesArray = split.call(String(obj), ',');
|
||||||
|
var valuesJoined = '';
|
||||||
|
for (var i = 0; i < valuesArray.length; ++i) {
|
||||||
|
valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
|
||||||
|
}
|
||||||
|
return [formatter(keyValue) + (commaRoundTrip && isArray(obj) && valuesArray.length === 1 ? '[]' : '') + '=' + valuesJoined];
|
||||||
|
}
|
||||||
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
|
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
|
||||||
}
|
}
|
||||||
return [formatter(prefix) + '=' + formatter(String(obj))];
|
return [formatter(prefix) + '=' + formatter(String(obj))];
|
||||||
@@ -34678,7 +34878,7 @@ var stringify = function stringify(
|
|||||||
var objKeys;
|
var objKeys;
|
||||||
if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
||||||
// we need to join elements in
|
// we need to join elements in
|
||||||
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
|
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
|
||||||
} else if (isArray(filter)) {
|
} else if (isArray(filter)) {
|
||||||
objKeys = filter;
|
objKeys = filter;
|
||||||
} else {
|
} else {
|
||||||
@@ -34686,24 +34886,28 @@ var stringify = function stringify(
|
|||||||
objKeys = sort ? keys.sort(sort) : keys;
|
objKeys = sort ? keys.sort(sort) : keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < objKeys.length; ++i) {
|
var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? prefix + '[]' : prefix;
|
||||||
var key = objKeys[i];
|
|
||||||
var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
|
for (var j = 0; j < objKeys.length; ++j) {
|
||||||
|
var key = objKeys[j];
|
||||||
|
var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
|
||||||
|
|
||||||
if (skipNulls && value === null) {
|
if (skipNulls && value === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyPrefix = isArray(obj)
|
var keyPrefix = isArray(obj)
|
||||||
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
|
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix
|
||||||
: prefix + (allowDots ? '.' + key : '[' + key + ']');
|
: adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']');
|
||||||
|
|
||||||
sideChannel.set(object, true);
|
sideChannel.set(object, step);
|
||||||
var valueSideChannel = getSideChannel();
|
var valueSideChannel = getSideChannel();
|
||||||
|
valueSideChannel.set(sentinel, sideChannel);
|
||||||
pushToArray(values, stringify(
|
pushToArray(values, stringify(
|
||||||
value,
|
value,
|
||||||
keyPrefix,
|
keyPrefix,
|
||||||
generateArrayPrefix,
|
generateArrayPrefix,
|
||||||
|
commaRoundTrip,
|
||||||
strictNullHandling,
|
strictNullHandling,
|
||||||
skipNulls,
|
skipNulls,
|
||||||
encoder,
|
encoder,
|
||||||
@@ -34727,7 +34931,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
|||||||
return defaults;
|
return defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
|
||||||
throw new TypeError('Encoder has to be a function.');
|
throw new TypeError('Encoder has to be a function.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34800,6 +35004,10 @@ module.exports = function (object, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
|
var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
|
||||||
|
if (opts && 'commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {
|
||||||
|
throw new TypeError('`commaRoundTrip` must be a boolean, or absent');
|
||||||
|
}
|
||||||
|
var commaRoundTrip = generateArrayPrefix === 'comma' && opts && opts.commaRoundTrip;
|
||||||
|
|
||||||
if (!objKeys) {
|
if (!objKeys) {
|
||||||
objKeys = Object.keys(obj);
|
objKeys = Object.keys(obj);
|
||||||
@@ -34820,6 +35028,7 @@ module.exports = function (object, opts) {
|
|||||||
obj[key],
|
obj[key],
|
||||||
key,
|
key,
|
||||||
generateArrayPrefix,
|
generateArrayPrefix,
|
||||||
|
commaRoundTrip,
|
||||||
options.strictNullHandling,
|
options.strictNullHandling,
|
||||||
options.skipNulls,
|
options.skipNulls,
|
||||||
options.encode ? options.encoder : null,
|
options.encode ? options.encoder : null,
|
||||||
|
|||||||
Generated
+484
-3670
File diff suppressed because it is too large
Load Diff
+5
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "checkout",
|
"name": "checkout",
|
||||||
"version": "2.0.2",
|
"version": "2.6.0",
|
||||||
"description": "checkout action",
|
"description": "checkout action",
|
||||||
"main": "lib/main.js",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/github": "^2.2.0",
|
"@actions/github": "^2.2.0",
|
||||||
"@actions/io": "^1.0.1",
|
"@actions/io": "^1.1.2",
|
||||||
"@actions/tool-cache": "^1.1.2",
|
"@actions/tool-cache": "^1.1.2",
|
||||||
"uuid": "^3.3.3"
|
"uuid": "^3.3.3"
|
||||||
},
|
},
|
||||||
@@ -39,11 +39,12 @@
|
|||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/node": "^12.7.12",
|
"@types/node": "^12.7.12",
|
||||||
"@types/uuid": "^3.4.6",
|
"@types/uuid": "^3.4.6",
|
||||||
"@typescript-eslint/parser": "^5.1.0",
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
"@zeit/ncc": "^0.20.5",
|
"@zeit/ncc": "^0.20.5",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-github": "^4.3.2",
|
"eslint-plugin-github": "^4.3.2",
|
||||||
"eslint-plugin-jest": "^25.2.2",
|
"eslint-plugin-jest": "^25.7.0",
|
||||||
"jest": "^27.3.0",
|
"jest": "^27.3.0",
|
||||||
"jest-circus": "^27.3.0",
|
"jest-circus": "^27.3.0",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
|
|||||||
@@ -157,7 +157,8 @@ class GitAuthHelper {
|
|||||||
// by process creation audit events, which are commonly logged. For more information,
|
// by process creation audit events, which are commonly logged. For more information,
|
||||||
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||||
const output = await this.git.submoduleForeach(
|
const output = await this.git.submoduleForeach(
|
||||||
`git config --local '${this.tokenConfigKey}' '${this.tokenPlaceholderConfigValue}' && git config --local --show-origin --name-only --get-regexp remote.origin.url`,
|
// wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline
|
||||||
|
`sh -c "git config --local '${this.tokenConfigKey}' '${this.tokenPlaceholderConfigValue}' && git config --local --show-origin --name-only --get-regexp remote.origin.url"`,
|
||||||
this.settings.nestedSubmodules
|
this.settings.nestedSubmodules
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -246,7 +247,7 @@ class GitAuthHelper {
|
|||||||
if (this.settings.sshKnownHosts) {
|
if (this.settings.sshKnownHosts) {
|
||||||
knownHosts += `# Begin from input known hosts\n${this.settings.sshKnownHosts}\n# end from input known hosts\n`
|
knownHosts += `# Begin from input known hosts\n${this.settings.sshKnownHosts}\n# end from input known hosts\n`
|
||||||
}
|
}
|
||||||
knownHosts += `# Begin implicitly added github.com\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n# End implicitly added github.com\n`
|
knownHosts += `# Begin implicitly added github.com\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\n# End implicitly added github.com\n`
|
||||||
this.sshKnownHostsPath = path.join(runnerTemp, `${uniqueId}_known_hosts`)
|
this.sshKnownHostsPath = path.join(runnerTemp, `${uniqueId}_known_hosts`)
|
||||||
stateHelper.setSshKnownHostsPath(this.sshKnownHostsPath)
|
stateHelper.setSshKnownHostsPath(this.sshKnownHostsPath)
|
||||||
await fs.promises.writeFile(this.sshKnownHostsPath, knownHosts)
|
await fs.promises.writeFile(this.sshKnownHostsPath, knownHosts)
|
||||||
@@ -365,7 +366,8 @@ class GitAuthHelper {
|
|||||||
|
|
||||||
const pattern = regexpHelper.escape(configKey)
|
const pattern = regexpHelper.escape(configKey)
|
||||||
await this.git.submoduleForeach(
|
await this.git.submoduleForeach(
|
||||||
`git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :`,
|
// wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline
|
||||||
|
`sh -c "git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :"`,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,4 +83,10 @@ export interface IGitSourceSettings {
|
|||||||
* Indicates whether to add repositoryPath as safe.directory in git global config
|
* Indicates whether to add repositoryPath as safe.directory in git global config
|
||||||
*/
|
*/
|
||||||
setSafeDirectory: boolean
|
setSafeDirectory: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opt-in to allow checking out fork pull request code from a workflow
|
||||||
|
* triggered by pull_request_target or workflow_run.
|
||||||
|
*/
|
||||||
|
allowUnsafePrCheckout: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import * as core from '@actions/core'
|
|||||||
import * as fsHelper from './fs-helper'
|
import * as fsHelper from './fs-helper'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
import * as unsafePrCheckoutHelper from './unsafe-pr-checkout-helper'
|
||||||
import * as workflowContextHelper from './workflow-context-helper'
|
import * as workflowContextHelper from './workflow-context-helper'
|
||||||
import {IGitSourceSettings} from './git-source-settings'
|
import {IGitSourceSettings} from './git-source-settings'
|
||||||
|
|
||||||
@@ -125,5 +126,19 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
|||||||
// Set safe.directory in git global config.
|
// Set safe.directory in git global config.
|
||||||
result.setSafeDirectory =
|
result.setSafeDirectory =
|
||||||
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE'
|
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE'
|
||||||
|
|
||||||
|
// Allow unsafe PR checkout (opt-in for pull_request_target / workflow_run fork PRs)
|
||||||
|
result.allowUnsafePrCheckout =
|
||||||
|
(core.getInput('allow-unsafe-pr-checkout') || 'false').toUpperCase() ===
|
||||||
|
'TRUE'
|
||||||
|
core.debug(`allow unsafe PR checkout = ${result.allowUnsafePrCheckout}`)
|
||||||
|
|
||||||
|
unsafePrCheckoutHelper.assertSafePrCheckout({
|
||||||
|
qualifiedRepository,
|
||||||
|
ref: result.ref,
|
||||||
|
commit: result.commit,
|
||||||
|
allowUnsafePrCheckout: result.allowUnsafePrCheckout
|
||||||
|
})
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ set -e
|
|||||||
src/misc/licensed-download.sh
|
src/misc/licensed-download.sh
|
||||||
|
|
||||||
echo 'Running: licensed cached'
|
echo 'Running: licensed cached'
|
||||||
_temp/licensed-3.3.1/licensed status
|
_temp/licensed-3.6.0/licensed status
|
||||||
@@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ ! -f _temp/licensed-3.3.1.done ]; then
|
if [ ! -f _temp/licensed-3.6.0.done ]; then
|
||||||
echo 'Clearing temp'
|
echo 'Clearing temp'
|
||||||
rm -rf _temp/licensed-3.3.1 || true
|
rm -rf _temp/licensed-3.6.0 || true
|
||||||
|
|
||||||
echo 'Downloading licensed'
|
echo 'Downloading licensed'
|
||||||
mkdir -p _temp/licensed-3.3.1
|
mkdir -p _temp/licensed-3.6.0
|
||||||
pushd _temp/licensed-3.3.1
|
pushd _temp/licensed-3.6.0
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.3.1/licensed-3.3.1-darwin-x64.tar.gz
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.6.0/licensed-3.6.0-darwin-x64.tar.gz
|
||||||
else
|
else
|
||||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.3.1/licensed-3.3.1-linux-x64.tar.gz
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.6.0/licensed-3.6.0-linux-x64.tar.gz
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo 'Extracting licenesed'
|
echo 'Extracting licenesed'
|
||||||
tar -xzf licensed.tar.gz
|
tar -xzf licensed.tar.gz
|
||||||
popd
|
popd
|
||||||
touch _temp/licensed-3.3.1.done
|
touch _temp/licensed-3.6.0.done
|
||||||
else
|
else
|
||||||
echo 'Licensed already downloaded'
|
echo 'Licensed already downloaded'
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ set -e
|
|||||||
src/misc/licensed-download.sh
|
src/misc/licensed-download.sh
|
||||||
|
|
||||||
echo 'Running: licensed cached'
|
echo 'Running: licensed cached'
|
||||||
_temp/licensed-3.3.1/licensed cache
|
_temp/licensed-3.6.0/licensed cache
|
||||||
+1
-1
@@ -259,7 +259,7 @@ export async function checkCommitInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fromPayload(path: string): any {
|
export function fromPayload(path: string): any {
|
||||||
return select(github.context.payload, path)
|
return select(github.context.payload, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import * as github from '@actions/github'
|
||||||
|
import {fromPayload} from './ref-helper'
|
||||||
|
|
||||||
|
const PR_REF_PATTERN = /^refs\/pull\/[0-9]+\/(?:head|merge)$/
|
||||||
|
|
||||||
|
export interface IUnsafePrCheckoutInput {
|
||||||
|
qualifiedRepository: string
|
||||||
|
ref: string
|
||||||
|
commit: string | undefined
|
||||||
|
allowUnsafePrCheckout: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function assertSafePrCheckout(input: IUnsafePrCheckoutInput): void {
|
||||||
|
if (input.allowUnsafePrCheckout) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventName = github.context.eventName
|
||||||
|
if (eventName !== 'pull_request_target' && eventName !== 'workflow_run') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseRepoId = fromPayload('repository.id')
|
||||||
|
if (typeof baseRepoId !== 'number') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let prHeadRepoId: unknown
|
||||||
|
let prHeadRepoFullName: unknown
|
||||||
|
const prShas: string[] = []
|
||||||
|
|
||||||
|
if (eventName === 'pull_request_target') {
|
||||||
|
prHeadRepoId = fromPayload('pull_request.head.repo.id')
|
||||||
|
prHeadRepoFullName = fromPayload('pull_request.head.repo.full_name')
|
||||||
|
pushIfSha(prShas, fromPayload('pull_request.head.sha'))
|
||||||
|
pushIfSha(prShas, fromPayload('pull_request.merge_commit_sha'))
|
||||||
|
} else {
|
||||||
|
const wrEvent = fromPayload('workflow_run.event')
|
||||||
|
if (typeof wrEvent !== 'string' || !wrEvent.startsWith('pull_request')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prHeadRepoId = fromPayload('workflow_run.head_repository.id')
|
||||||
|
prHeadRepoFullName = fromPayload('workflow_run.head_repository.full_name')
|
||||||
|
pushIfSha(prShas, fromPayload('workflow_run.head_commit.id'))
|
||||||
|
// For `pull_request_target`-triggered workflow_run, `head_sha` is the base
|
||||||
|
// default branch SHA (not the PR head)
|
||||||
|
if (wrEvent !== 'pull_request_target') {
|
||||||
|
pushIfSha(prShas, fromPayload('workflow_run.head_sha'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (A) Fork PR?
|
||||||
|
if (typeof prHeadRepoId !== 'number' || prHeadRepoId === baseRepoId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// (B) We cannot check for all fork PR refs so check to see
|
||||||
|
// if the resolved input points to the fork PR sha we have in the payload
|
||||||
|
const repositoryMatchesPrHead =
|
||||||
|
typeof prHeadRepoFullName === 'string' &&
|
||||||
|
input.qualifiedRepository.toLowerCase() === prHeadRepoFullName.toLowerCase()
|
||||||
|
const refMatchesPullPattern = PR_REF_PATTERN.test(input.ref)
|
||||||
|
const commitMatchesPrHeadSha =
|
||||||
|
!!input.commit && prShas.includes(input.commit.toLowerCase())
|
||||||
|
|
||||||
|
if (
|
||||||
|
!repositoryMatchesPrHead &&
|
||||||
|
!refMatchesPullPattern &&
|
||||||
|
!commitMatchesPrHeadSha
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
`Refusing to check out fork pull request code from a '${eventName}' workflow. ` +
|
||||||
|
`This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch ` +
|
||||||
|
`cache scope, and runner access. Fetching and executing a fork's code in that trusted ` +
|
||||||
|
`context commonly leads to "pwn request" vulnerabilities. To opt in, review the risks ` +
|
||||||
|
`at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' ` +
|
||||||
|
`on the actions/checkout step.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushIfSha(target: string[], value: unknown): void {
|
||||||
|
if (typeof value === 'string' && value.length > 0) {
|
||||||
|
target.push(value.toLowerCase())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user