mirror of
https://github.com/actions/checkout.git
synced 2025-10-18 22:09:21 +08:00
Compare commits
2 Commits
users/eric
...
96498f7ec0
Author | SHA1 | Date | |
---|---|---|---|
|
96498f7ec0 | ||
|
2427e94287 |
4
.github/workflows/check-dist.yml
vendored
4
.github/workflows/check-dist.yml
vendored
@@ -24,10 +24,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
|
|
||||||
- name: Set Node.js 24.x
|
- name: Set Node.js 20.x
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 24.x
|
node-version: 20.x
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
11
.github/workflows/test.yml
vendored
11
.github/workflows/test.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 24.x
|
node-version: 20.x
|
||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
@@ -302,15 +302,12 @@ jobs:
|
|||||||
# Clone this repo
|
# Clone this repo
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4.1.6
|
uses: actions/checkout@v4.1.6
|
||||||
with:
|
|
||||||
path: actions-checkout
|
|
||||||
|
|
||||||
# Basic checkout using git
|
# Basic checkout using git
|
||||||
- name: Checkout basic
|
- name: Checkout basic
|
||||||
id: checkout
|
id: checkout
|
||||||
uses: ./actions-checkout
|
uses: ./
|
||||||
with:
|
with:
|
||||||
path: cloned-using-local-action
|
|
||||||
ref: test-data/v2/basic
|
ref: test-data/v2/basic
|
||||||
|
|
||||||
# Verify output
|
# Verify output
|
||||||
@@ -328,3 +325,7 @@ jobs:
|
|||||||
echo "Expected commit to be 82f71901cf8c021332310dcc8cdba84c4193ff5d"
|
echo "Expected commit to be 82f71901cf8c021332310dcc8cdba84c4193ff5d"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# needed to make checkout post cleanup succeed
|
||||||
|
- name: Fix Checkout
|
||||||
|
uses: actions/checkout@v4.1.6
|
||||||
|
1
.github/workflows/update-main-version.yml
vendored
1
.github/workflows/update-main-version.yml
vendored
@@ -11,7 +11,6 @@ on:
|
|||||||
type: choice
|
type: choice
|
||||||
description: The major version to update
|
description: The major version to update
|
||||||
options:
|
options:
|
||||||
- v5
|
|
||||||
- v4
|
- v4
|
||||||
- v3
|
- v3
|
||||||
- v2
|
- v2
|
||||||
|
4
.licenses/npm/@octokit/endpoint.dep.yml
generated
4
.licenses/npm/@octokit/endpoint.dep.yml
generated
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: "@octokit/endpoint"
|
name: "@octokit/endpoint"
|
||||||
version: 9.0.6
|
version: 9.0.5
|
||||||
type: npm
|
type: npm
|
||||||
summary: Turns REST API endpoints into generic request options
|
summary: Turns REST API endpoints into generic request options
|
||||||
homepage:
|
homepage:
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- sources: LICENSE
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: "@octokit/plugin-paginate-rest"
|
name: "@octokit/plugin-paginate-rest"
|
||||||
version: 9.2.2
|
version: 9.2.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: Octokit plugin to paginate REST API endpoint responses
|
summary: Octokit plugin to paginate REST API endpoint responses
|
||||||
homepage:
|
homepage:
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- sources: LICENSE
|
||||||
|
4
.licenses/npm/@octokit/request-error.dep.yml
generated
4
.licenses/npm/@octokit/request-error.dep.yml
generated
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: "@octokit/request-error"
|
name: "@octokit/request-error"
|
||||||
version: 5.1.1
|
version: 5.1.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: Error class for Octokit request errors
|
summary: Error class for Octokit request errors
|
||||||
homepage:
|
homepage:
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- sources: LICENSE
|
||||||
|
4
.licenses/npm/@octokit/request.dep.yml
generated
4
.licenses/npm/@octokit/request.dep.yml
generated
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: "@octokit/request"
|
name: "@octokit/request"
|
||||||
version: 8.4.1
|
version: 8.4.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: Send parameterized requests to GitHub's APIs with sensible defaults in browsers
|
summary: Send parameterized requests to GitHub's APIs with sensible defaults in browsers
|
||||||
and Node
|
and Node
|
||||||
homepage:
|
homepage:
|
||||||
license: mit
|
license: mit
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- sources: LICENSE
|
||||||
|
2
.licenses/npm/undici.dep.yml
generated
2
.licenses/npm/undici.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: undici
|
name: undici
|
||||||
version: 5.29.0
|
version: 5.28.4
|
||||||
type: npm
|
type: npm
|
||||||
summary: An HTTP/1.1 client, written from scratch for Node.js
|
summary: An HTTP/1.1 client, written from scratch for Node.js
|
||||||
homepage: https://undici.nodejs.org
|
homepage: https://undici.nodejs.org
|
||||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,18 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## V5.0.0
|
|
||||||
* Update actions checkout to use node 24 by @salmanmkc in https://github.com/actions/checkout/pull/2226
|
|
||||||
|
|
||||||
|
|
||||||
## V4.3.0
|
|
||||||
* docs: update README.md by @motss in https://github.com/actions/checkout/pull/1971
|
|
||||||
* Add internal repos for checking out multiple repositories by @mouismail in https://github.com/actions/checkout/pull/1977
|
|
||||||
* Documentation update - add recommended permissions to Readme by @benwells in https://github.com/actions/checkout/pull/2043
|
|
||||||
* Adjust positioning of user email note and permissions heading by @joshmgross in https://github.com/actions/checkout/pull/2044
|
|
||||||
* Update README.md by @nebuk89 in https://github.com/actions/checkout/pull/2194
|
|
||||||
* Update CODEOWNERS for actions by @TingluoHuang in https://github.com/actions/checkout/pull/2224
|
|
||||||
* Update package dependencies by @salmanmkc in https://github.com/actions/checkout/pull/2236
|
|
||||||
|
|
||||||
## v4.2.2
|
## v4.2.2
|
||||||
* `url-helper.ts` now leverages well-known environment variables by @jww3 in https://github.com/actions/checkout/pull/1941
|
* `url-helper.ts` now leverages well-known environment variables by @jww3 in https://github.com/actions/checkout/pull/1941
|
||||||
* Expand unit test coverage for `isGhes` by @jww3 in https://github.com/actions/checkout/pull/1946
|
* Expand unit test coverage for `isGhes` by @jww3 in https://github.com/actions/checkout/pull/1946
|
||||||
|
@@ -1 +1 @@
|
|||||||
* @actions/actions-runtime
|
* @actions/actions-launch
|
||||||
|
104
README.md
104
README.md
@@ -1,13 +1,5 @@
|
|||||||
[](https://github.com/actions/checkout/actions/workflows/test.yml)
|
[](https://github.com/actions/checkout/actions/workflows/test.yml)
|
||||||
|
|
||||||
# Checkout V5
|
|
||||||
|
|
||||||
## What's new
|
|
||||||
|
|
||||||
- Updated to the node24 runtime
|
|
||||||
- This requires a minimum Actions Runner version of [v2.327.1](https://github.com/actions/runner/releases/tag/v2.327.1) to run.
|
|
||||||
|
|
||||||
|
|
||||||
# Checkout V4
|
# Checkout V4
|
||||||
|
|
||||||
This action checks-out your repository under `$GITHUB_WORKSPACE`, so your workflow can access it.
|
This action checks-out your repository under `$GITHUB_WORKSPACE`, so your workflow can access it.
|
||||||
@@ -18,24 +10,6 @@ The auth token is persisted in the local git config. This enables your scripts t
|
|||||||
|
|
||||||
When Git 2.18 or higher is not in your PATH, falls back to the REST API to download the files.
|
When Git 2.18 or higher is not in your PATH, falls back to the REST API to download the files.
|
||||||
|
|
||||||
### Note
|
|
||||||
|
|
||||||
Thank you for your interest in this GitHub action, however, right now we are not taking contributions.
|
|
||||||
|
|
||||||
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in.
|
|
||||||
|
|
||||||
We are taking the following steps to better direct requests related to GitHub Actions, including:
|
|
||||||
|
|
||||||
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
|
|
||||||
|
|
||||||
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
|
|
||||||
|
|
||||||
3. Security Issues should be handled as per our [security.md](security.md)
|
|
||||||
|
|
||||||
We will still provide security updates for this project and fix major breaking changes during this time.
|
|
||||||
|
|
||||||
You are welcome to still raise bugs in this repo.
|
|
||||||
|
|
||||||
# What's new
|
# What's new
|
||||||
|
|
||||||
Please refer to the [release page](https://github.com/actions/checkout/releases/latest) for the latest release notes.
|
Please refer to the [release page](https://github.com/actions/checkout/releases/latest) for the latest release notes.
|
||||||
@@ -44,7 +18,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
|
|
||||||
<!-- start usage -->
|
<!-- start usage -->
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Repository name with owner. For example, actions/checkout
|
# Repository name with owner. For example, actions/checkout
|
||||||
# Default: ${{ github.repository }}
|
# Default: ${{ github.repository }}
|
||||||
@@ -157,33 +131,24 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
|
|
||||||
# Scenarios
|
# Scenarios
|
||||||
|
|
||||||
- [Checkout V5](#checkout-v5)
|
- [Fetch only the root files](#Fetch-only-the-root-files)
|
||||||
- [What's new](#whats-new)
|
- [Fetch only the root files and `.github` and `src` folder](#Fetch-only-the-root-files-and-github-and-src-folder)
|
||||||
- [Checkout V4](#checkout-v4)
|
- [Fetch only a single file](#Fetch-only-a-single-file)
|
||||||
- [Note](#note)
|
- [Fetch all history for all tags and branches](#Fetch-all-history-for-all-tags-and-branches)
|
||||||
- [What's new](#whats-new-1)
|
- [Checkout a different branch](#Checkout-a-different-branch)
|
||||||
- [Usage](#usage)
|
- [Checkout HEAD^](#Checkout-HEAD)
|
||||||
- [Scenarios](#scenarios)
|
- [Checkout multiple repos (side by side)](#Checkout-multiple-repos-side-by-side)
|
||||||
- [Fetch only the root files](#fetch-only-the-root-files)
|
- [Checkout multiple repos (nested)](#Checkout-multiple-repos-nested)
|
||||||
- [Fetch only the root files and `.github` and `src` folder](#fetch-only-the-root-files-and-github-and-src-folder)
|
- [Checkout multiple repos (private)](#Checkout-multiple-repos-private)
|
||||||
- [Fetch only a single file](#fetch-only-a-single-file)
|
- [Checkout pull request HEAD commit instead of merge commit](#Checkout-pull-request-HEAD-commit-instead-of-merge-commit)
|
||||||
- [Fetch all history for all tags and branches](#fetch-all-history-for-all-tags-and-branches)
|
- [Checkout pull request on closed event](#Checkout-pull-request-on-closed-event)
|
||||||
- [Checkout a different branch](#checkout-a-different-branch)
|
- [Push a commit using the built-in token](#Push-a-commit-using-the-built-in-token)
|
||||||
- [Checkout HEAD^](#checkout-head)
|
- [Push a commit to a PR using the built-in token](#Push-a-commit-to-a-PR-using-the-built-in-token)
|
||||||
- [Checkout multiple repos (side by side)](#checkout-multiple-repos-side-by-side)
|
|
||||||
- [Checkout multiple repos (nested)](#checkout-multiple-repos-nested)
|
|
||||||
- [Checkout multiple repos (private)](#checkout-multiple-repos-private)
|
|
||||||
- [Checkout pull request HEAD commit instead of merge commit](#checkout-pull-request-head-commit-instead-of-merge-commit)
|
|
||||||
- [Checkout pull request on closed event](#checkout-pull-request-on-closed-event)
|
|
||||||
- [Push a commit using the built-in token](#push-a-commit-using-the-built-in-token)
|
|
||||||
- [Push a commit to a PR using the built-in token](#push-a-commit-to-a-pr-using-the-built-in-token)
|
|
||||||
- [Recommended permissions](#recommended-permissions)
|
|
||||||
- [License](#license)
|
|
||||||
|
|
||||||
## Fetch only the root files
|
## Fetch only the root files
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
sparse-checkout: .
|
sparse-checkout: .
|
||||||
```
|
```
|
||||||
@@ -191,7 +156,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
## Fetch only the root files and `.github` and `src` folder
|
## Fetch only the root files and `.github` and `src` folder
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
sparse-checkout: |
|
sparse-checkout: |
|
||||||
.github
|
.github
|
||||||
@@ -201,7 +166,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
## Fetch only a single file
|
## Fetch only a single file
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
sparse-checkout: |
|
sparse-checkout: |
|
||||||
README.md
|
README.md
|
||||||
@@ -211,7 +176,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
## Fetch all history for all tags and branches
|
## Fetch all history for all tags and branches
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
```
|
```
|
||||||
@@ -219,7 +184,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
## Checkout a different branch
|
## Checkout a different branch
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: my-branch
|
ref: my-branch
|
||||||
```
|
```
|
||||||
@@ -227,7 +192,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
## Checkout HEAD^
|
## Checkout HEAD^
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
- run: git checkout HEAD^
|
- run: git checkout HEAD^
|
||||||
@@ -237,12 +202,12 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: main
|
path: main
|
||||||
|
|
||||||
- name: Checkout tools repo
|
- name: Checkout tools repo
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: my-org/my-tools
|
repository: my-org/my-tools
|
||||||
path: my-tools
|
path: my-tools
|
||||||
@@ -253,10 +218,10 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Checkout tools repo
|
- name: Checkout tools repo
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: my-org/my-tools
|
repository: my-org/my-tools
|
||||||
path: my-tools
|
path: my-tools
|
||||||
@@ -267,12 +232,12 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: main
|
path: main
|
||||||
|
|
||||||
- name: Checkout private tools
|
- name: Checkout private tools
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: my-org/my-private-tools
|
repository: my-org/my-private-tools
|
||||||
token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
|
token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
|
||||||
@@ -285,7 +250,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
|||||||
## Checkout pull request HEAD commit instead of merge commit
|
## Checkout pull request HEAD commit instead of merge commit
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
```
|
```
|
||||||
@@ -301,7 +266,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
```
|
```
|
||||||
|
|
||||||
## Push a commit using the built-in token
|
## Push a commit using the built-in token
|
||||||
@@ -312,7 +277,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- run: |
|
- run: |
|
||||||
date > generated.txt
|
date > generated.txt
|
||||||
# Note: the following account information will not work on GHES
|
# Note: the following account information will not work on GHES
|
||||||
@@ -334,7 +299,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
- run: |
|
- run: |
|
||||||
@@ -346,17 +311,8 @@ jobs:
|
|||||||
git commit -m "generated"
|
git commit -m "generated"
|
||||||
git push
|
git push
|
||||||
```
|
```
|
||||||
|
|
||||||
*NOTE:* The user email is `{user.id}+{user.login}@users.noreply.github.com`. See users API: https://api.github.com/users/github-actions%5Bbot%5D
|
*NOTE:* The user email is `{user.id}+{user.login}@users.noreply.github.com`. See users API: https://api.github.com/users/github-actions%5Bbot%5D
|
||||||
|
|
||||||
# Recommended permissions
|
|
||||||
|
|
||||||
When using the `checkout` action in your GitHub Actions workflow, it is recommended to set the following `GITHUB_TOKEN` permissions to ensure proper functionality, unless alternative auth is provided via the `token` or `ssh-key` inputs:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
|
@@ -86,29 +86,16 @@ describe('git-auth-helper tests', () => {
|
|||||||
// Act
|
// Act
|
||||||
await authHelper.configureAuth()
|
await authHelper.configureAuth()
|
||||||
|
|
||||||
// Assert config - check that .git/config contains includeIf entries
|
// Assert config
|
||||||
const localConfigContent = (
|
const configContent = (
|
||||||
await fs.promises.readFile(localGitConfigPath)
|
await fs.promises.readFile(localGitConfigPath)
|
||||||
).toString()
|
).toString()
|
||||||
expect(
|
|
||||||
localConfigContent.indexOf('includeIf.gitdir:')
|
|
||||||
).toBeGreaterThanOrEqual(0)
|
|
||||||
|
|
||||||
// Assert credentials config file contains the actual credentials
|
|
||||||
const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter(
|
|
||||||
f => f.startsWith('git-credentials-') && f.endsWith('.config')
|
|
||||||
)
|
|
||||||
expect(credentialsFiles.length).toBe(1)
|
|
||||||
const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0])
|
|
||||||
const credentialsContent = (
|
|
||||||
await fs.promises.readFile(credentialsConfigPath)
|
|
||||||
).toString()
|
|
||||||
const basicCredential = Buffer.from(
|
const basicCredential = Buffer.from(
|
||||||
`x-access-token:${settings.authToken}`,
|
`x-access-token:${settings.authToken}`,
|
||||||
'utf8'
|
'utf8'
|
||||||
).toString('base64')
|
).toString('base64')
|
||||||
expect(
|
expect(
|
||||||
credentialsContent.indexOf(
|
configContent.indexOf(
|
||||||
`http.${expectedServerUrl}/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
`http.${expectedServerUrl}/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
||||||
)
|
)
|
||||||
).toBeGreaterThanOrEqual(0)
|
).toBeGreaterThanOrEqual(0)
|
||||||
@@ -133,7 +120,7 @@ describe('git-auth-helper tests', () => {
|
|||||||
'inject https://github.com as github server url'
|
'inject https://github.com as github server url'
|
||||||
it(configureAuth_AcceptsGitHubServerUrlSetToGHEC, async () => {
|
it(configureAuth_AcceptsGitHubServerUrlSetToGHEC, async () => {
|
||||||
await testAuthHeader(
|
await testAuthHeader(
|
||||||
configureAuth_AcceptsGitHubServerUrlSetToGHEC,
|
configureAuth_AcceptsGitHubServerUrl,
|
||||||
'https://github.com'
|
'https://github.com'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -154,17 +141,12 @@ describe('git-auth-helper tests', () => {
|
|||||||
// Act
|
// Act
|
||||||
await authHelper.configureAuth()
|
await authHelper.configureAuth()
|
||||||
|
|
||||||
// Assert config - check credentials config file (not local .git/config)
|
// Assert config
|
||||||
const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter(
|
const configContent = (
|
||||||
f => f.startsWith('git-credentials-') && f.endsWith('.config')
|
await fs.promises.readFile(localGitConfigPath)
|
||||||
)
|
|
||||||
expect(credentialsFiles.length).toBe(1)
|
|
||||||
const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0])
|
|
||||||
const credentialsContent = (
|
|
||||||
await fs.promises.readFile(credentialsConfigPath)
|
|
||||||
).toString()
|
).toString()
|
||||||
expect(
|
expect(
|
||||||
credentialsContent.indexOf(
|
configContent.indexOf(
|
||||||
`http.https://github.com/.extraheader AUTHORIZATION`
|
`http.https://github.com/.extraheader AUTHORIZATION`
|
||||||
)
|
)
|
||||||
).toBeGreaterThanOrEqual(0)
|
).toBeGreaterThanOrEqual(0)
|
||||||
@@ -269,16 +251,13 @@ describe('git-auth-helper tests', () => {
|
|||||||
expectedSshCommand
|
expectedSshCommand
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assert git config
|
// Asserty git config
|
||||||
const gitConfigLines = (await fs.promises.readFile(localGitConfigPath))
|
const gitConfigLines = (await fs.promises.readFile(localGitConfigPath))
|
||||||
.toString()
|
.toString()
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.filter(x => x)
|
.filter(x => x)
|
||||||
// Should have includeIf entries pointing to credentials file
|
expect(gitConfigLines).toHaveLength(1)
|
||||||
expect(gitConfigLines.length).toBeGreaterThan(0)
|
expect(gitConfigLines[0]).toMatch(/^http\./)
|
||||||
expect(
|
|
||||||
gitConfigLines.some(line => line.indexOf('includeIf.gitdir:') >= 0)
|
|
||||||
).toBeTruthy()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const configureAuth_setsSshCommandWhenPersistCredentialsTrue =
|
const configureAuth_setsSshCommandWhenPersistCredentialsTrue =
|
||||||
@@ -440,20 +419,8 @@ describe('git-auth-helper tests', () => {
|
|||||||
expect(
|
expect(
|
||||||
configContent.indexOf('value-from-global-config')
|
configContent.indexOf('value-from-global-config')
|
||||||
).toBeGreaterThanOrEqual(0)
|
).toBeGreaterThanOrEqual(0)
|
||||||
// Global config should have include.path pointing to credentials file
|
|
||||||
expect(configContent.indexOf('include.path')).toBeGreaterThanOrEqual(0)
|
|
||||||
|
|
||||||
// Check credentials in the separate config file
|
|
||||||
const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter(
|
|
||||||
f => f.startsWith('git-credentials-') && f.endsWith('.config')
|
|
||||||
)
|
|
||||||
expect(credentialsFiles.length).toBeGreaterThan(0)
|
|
||||||
const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0])
|
|
||||||
const credentialsContent = (
|
|
||||||
await fs.promises.readFile(credentialsConfigPath)
|
|
||||||
).toString()
|
|
||||||
expect(
|
expect(
|
||||||
credentialsContent.indexOf(
|
configContent.indexOf(
|
||||||
`http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
`http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
||||||
)
|
)
|
||||||
).toBeGreaterThanOrEqual(0)
|
).toBeGreaterThanOrEqual(0)
|
||||||
@@ -496,20 +463,8 @@ describe('git-auth-helper tests', () => {
|
|||||||
const configContent = (
|
const configContent = (
|
||||||
await fs.promises.readFile(path.join(git.env['HOME'], '.gitconfig'))
|
await fs.promises.readFile(path.join(git.env['HOME'], '.gitconfig'))
|
||||||
).toString()
|
).toString()
|
||||||
// Global config should have include.path pointing to credentials file
|
|
||||||
expect(configContent.indexOf('include.path')).toBeGreaterThanOrEqual(0)
|
|
||||||
|
|
||||||
// Check credentials in the separate config file
|
|
||||||
const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter(
|
|
||||||
f => f.startsWith('git-credentials-') && f.endsWith('.config')
|
|
||||||
)
|
|
||||||
expect(credentialsFiles.length).toBeGreaterThan(0)
|
|
||||||
const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0])
|
|
||||||
const credentialsContent = (
|
|
||||||
await fs.promises.readFile(credentialsConfigPath)
|
|
||||||
).toString()
|
|
||||||
expect(
|
expect(
|
||||||
credentialsContent.indexOf(
|
configContent.indexOf(
|
||||||
`http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
`http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}`
|
||||||
)
|
)
|
||||||
).toBeGreaterThanOrEqual(0)
|
).toBeGreaterThanOrEqual(0)
|
||||||
@@ -595,15 +550,15 @@ describe('git-auth-helper tests', () => {
|
|||||||
await authHelper.configureSubmoduleAuth()
|
await authHelper.configureSubmoduleAuth()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
// Should configure insteadOf (2 calls for two values)
|
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(4)
|
||||||
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(3)
|
|
||||||
expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch(
|
expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch(
|
||||||
/unset-all.*insteadOf/
|
/unset-all.*insteadOf/
|
||||||
)
|
)
|
||||||
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(
|
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/http.*extraheader/)
|
||||||
|
expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch(
|
||||||
/url.*insteadOf.*git@github.com:/
|
/url.*insteadOf.*git@github.com:/
|
||||||
)
|
)
|
||||||
expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch(
|
expect(mockSubmoduleForeach.mock.calls[3][0]).toMatch(
|
||||||
/url.*insteadOf.*org-123456@github.com:/
|
/url.*insteadOf.*org-123456@github.com:/
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -634,12 +589,12 @@ describe('git-auth-helper tests', () => {
|
|||||||
await authHelper.configureSubmoduleAuth()
|
await authHelper.configureSubmoduleAuth()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
// Should configure sshCommand (1 call)
|
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(3)
|
||||||
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(2)
|
|
||||||
expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch(
|
expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch(
|
||||||
/unset-all.*insteadOf/
|
/unset-all.*insteadOf/
|
||||||
)
|
)
|
||||||
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/core\.sshCommand/)
|
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/http.*extraheader/)
|
||||||
|
expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch(/core\.sshCommand/)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -705,35 +660,19 @@ describe('git-auth-helper tests', () => {
|
|||||||
await setup(removeAuth_removesToken)
|
await setup(removeAuth_removesToken)
|
||||||
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
||||||
await authHelper.configureAuth()
|
await authHelper.configureAuth()
|
||||||
|
let gitConfigContent = (
|
||||||
// Sanity check - verify includeIf entries exist in local config
|
|
||||||
let localConfigContent = (
|
|
||||||
await fs.promises.readFile(localGitConfigPath)
|
await fs.promises.readFile(localGitConfigPath)
|
||||||
).toString()
|
).toString()
|
||||||
expect(
|
expect(gitConfigContent.indexOf('http.')).toBeGreaterThanOrEqual(0) // sanity check
|
||||||
localConfigContent.indexOf('includeIf.gitdir:')
|
|
||||||
).toBeGreaterThanOrEqual(0)
|
|
||||||
|
|
||||||
// Sanity check - verify credentials file exists
|
|
||||||
let credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter(
|
|
||||||
f => f.startsWith('git-credentials-') && f.endsWith('.config')
|
|
||||||
)
|
|
||||||
expect(credentialsFiles.length).toBe(1)
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await authHelper.removeAuth()
|
await authHelper.removeAuth()
|
||||||
|
|
||||||
// Assert includeIf entries removed from local git config
|
// Assert git config
|
||||||
localConfigContent = (
|
gitConfigContent = (
|
||||||
await fs.promises.readFile(localGitConfigPath)
|
await fs.promises.readFile(localGitConfigPath)
|
||||||
).toString()
|
).toString()
|
||||||
expect(localConfigContent.indexOf('includeIf.gitdir:')).toBeLessThan(0)
|
expect(gitConfigContent.indexOf('http.')).toBeLessThan(0)
|
||||||
|
|
||||||
// Assert credentials config file deleted
|
|
||||||
credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter(
|
|
||||||
f => f.startsWith('git-credentials-') && f.endsWith('.config')
|
|
||||||
)
|
|
||||||
expect(credentialsFiles.length).toBe(0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const removeGlobalConfig_removesOverride =
|
const removeGlobalConfig_removesOverride =
|
||||||
@@ -762,52 +701,6 @@ describe('git-auth-helper tests', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const testCredentialsConfigPath_matchesCredentialsConfigPaths =
|
|
||||||
'testCredentialsConfigPath matches credentials config paths'
|
|
||||||
it(testCredentialsConfigPath_matchesCredentialsConfigPaths, async () => {
|
|
||||||
// Arrange
|
|
||||||
await setup(testCredentialsConfigPath_matchesCredentialsConfigPaths)
|
|
||||||
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
|
||||||
|
|
||||||
// Get a real credentials config path
|
|
||||||
const credentialsConfigPath = await (
|
|
||||||
authHelper as any
|
|
||||||
).getCredentialsConfigPath()
|
|
||||||
|
|
||||||
// Act & Assert
|
|
||||||
expect(
|
|
||||||
(authHelper as any).testCredentialsConfigPath(credentialsConfigPath)
|
|
||||||
).toBe(true)
|
|
||||||
expect(
|
|
||||||
(authHelper as any).testCredentialsConfigPath(
|
|
||||||
'/some/path/git-credentials-12345678-abcd-1234-5678-123456789012.config'
|
|
||||||
)
|
|
||||||
).toBe(true)
|
|
||||||
expect(
|
|
||||||
(authHelper as any).testCredentialsConfigPath(
|
|
||||||
'/some/path/git-credentials-abcdef12-3456-7890-abcd-ef1234567890.config'
|
|
||||||
)
|
|
||||||
).toBe(true)
|
|
||||||
|
|
||||||
// Test invalid paths
|
|
||||||
expect(
|
|
||||||
(authHelper as any).testCredentialsConfigPath(
|
|
||||||
'/some/path/other-config.config'
|
|
||||||
)
|
|
||||||
).toBe(false)
|
|
||||||
expect(
|
|
||||||
(authHelper as any).testCredentialsConfigPath(
|
|
||||||
'/some/path/git-credentials-invalid.config'
|
|
||||||
)
|
|
||||||
).toBe(false)
|
|
||||||
expect(
|
|
||||||
(authHelper as any).testCredentialsConfigPath(
|
|
||||||
'/some/path/git-credentials-.config'
|
|
||||||
)
|
|
||||||
).toBe(false)
|
|
||||||
expect((authHelper as any).testCredentialsConfigPath('')).toBe(false)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
async function setup(testName: string): Promise<void> {
|
async function setup(testName: string): Promise<void> {
|
||||||
@@ -822,7 +715,6 @@ async function setup(testName: string): Promise<void> {
|
|||||||
await fs.promises.mkdir(tempHomedir, {recursive: true})
|
await fs.promises.mkdir(tempHomedir, {recursive: true})
|
||||||
process.env['RUNNER_TEMP'] = runnerTemp
|
process.env['RUNNER_TEMP'] = runnerTemp
|
||||||
process.env['HOME'] = tempHomedir
|
process.env['HOME'] = tempHomedir
|
||||||
process.env['GITHUB_WORKSPACE'] = workspace
|
|
||||||
|
|
||||||
// Create git config
|
// Create git config
|
||||||
globalGitConfigPath = path.join(tempHomedir, '.gitconfig')
|
globalGitConfigPath = path.join(tempHomedir, '.gitconfig')
|
||||||
@@ -841,20 +733,10 @@ async function setup(testName: string): Promise<void> {
|
|||||||
checkout: jest.fn(),
|
checkout: jest.fn(),
|
||||||
checkoutDetach: jest.fn(),
|
checkoutDetach: jest.fn(),
|
||||||
config: jest.fn(
|
config: jest.fn(
|
||||||
async (
|
async (key: string, value: string, globalConfig?: boolean) => {
|
||||||
key: string,
|
const configPath = globalConfig
|
||||||
value: string,
|
? path.join(git.env['HOME'] || tempHomedir, '.gitconfig')
|
||||||
globalConfig?: boolean,
|
: localGitConfigPath
|
||||||
add?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
) => {
|
|
||||||
const configPath =
|
|
||||||
configFile ||
|
|
||||||
(globalConfig
|
|
||||||
? path.join(git.env['HOME'] || tempHomedir, '.gitconfig')
|
|
||||||
: localGitConfigPath)
|
|
||||||
// Ensure directory exists
|
|
||||||
await fs.promises.mkdir(path.dirname(configPath), {recursive: true})
|
|
||||||
await fs.promises.appendFile(configPath, `\n${key} ${value}`)
|
await fs.promises.appendFile(configPath, `\n${key} ${value}`)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
@@ -874,7 +756,6 @@ async function setup(testName: string): Promise<void> {
|
|||||||
env: {},
|
env: {},
|
||||||
fetch: jest.fn(),
|
fetch: jest.fn(),
|
||||||
getDefaultBranch: jest.fn(),
|
getDefaultBranch: jest.fn(),
|
||||||
getSubmoduleConfigPaths: jest.fn(async () => []),
|
|
||||||
getWorkingDirectory: jest.fn(() => workspace),
|
getWorkingDirectory: jest.fn(() => workspace),
|
||||||
init: jest.fn(),
|
init: jest.fn(),
|
||||||
isDetached: jest.fn(),
|
isDetached: jest.fn(),
|
||||||
@@ -913,57 +794,8 @@ async function setup(testName: string): Promise<void> {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
tryConfigUnsetValue: jest.fn(
|
|
||||||
async (
|
|
||||||
key: string,
|
|
||||||
value: string,
|
|
||||||
globalConfig?: boolean
|
|
||||||
): Promise<boolean> => {
|
|
||||||
const configPath = globalConfig
|
|
||||||
? path.join(git.env['HOME'] || tempHomedir, '.gitconfig')
|
|
||||||
: localGitConfigPath
|
|
||||||
let content = await fs.promises.readFile(configPath)
|
|
||||||
let lines = content
|
|
||||||
.toString()
|
|
||||||
.split('\n')
|
|
||||||
.filter(x => x)
|
|
||||||
.filter(x => !(x.startsWith(key) && x.includes(value)))
|
|
||||||
await fs.promises.writeFile(configPath, lines.join('\n'))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
),
|
|
||||||
tryDisableAutomaticGarbageCollection: jest.fn(),
|
tryDisableAutomaticGarbageCollection: jest.fn(),
|
||||||
tryGetFetchUrl: jest.fn(),
|
tryGetFetchUrl: jest.fn(),
|
||||||
tryGetConfigValues: jest.fn(
|
|
||||||
async (key: string, globalConfig?: boolean): Promise<string[]> => {
|
|
||||||
const configPath = globalConfig
|
|
||||||
? path.join(git.env['HOME'] || tempHomedir, '.gitconfig')
|
|
||||||
: localGitConfigPath
|
|
||||||
const content = await fs.promises.readFile(configPath)
|
|
||||||
const lines = content
|
|
||||||
.toString()
|
|
||||||
.split('\n')
|
|
||||||
.filter(x => x && x.startsWith(key))
|
|
||||||
.map(x => x.substring(key.length).trim())
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
),
|
|
||||||
tryGetConfigKeys: jest.fn(
|
|
||||||
async (pattern: string, globalConfig?: boolean): Promise<string[]> => {
|
|
||||||
const configPath = globalConfig
|
|
||||||
? path.join(git.env['HOME'] || tempHomedir, '.gitconfig')
|
|
||||||
: localGitConfigPath
|
|
||||||
const content = await fs.promises.readFile(configPath)
|
|
||||||
const lines = content
|
|
||||||
.toString()
|
|
||||||
.split('\n')
|
|
||||||
.filter(x => x)
|
|
||||||
const keys = lines
|
|
||||||
.filter(x => new RegExp(pattern).test(x.split(' ')[0]))
|
|
||||||
.map(x => x.split(' ')[0])
|
|
||||||
return [...new Set(keys)] // Remove duplicates
|
|
||||||
}
|
|
||||||
),
|
|
||||||
tryReset: jest.fn(),
|
tryReset: jest.fn(),
|
||||||
version: jest.fn()
|
version: jest.fn()
|
||||||
}
|
}
|
||||||
@@ -998,7 +830,6 @@ async function setup(testName: string): Promise<void> {
|
|||||||
|
|
||||||
async function getActualSshKeyPath(): Promise<string> {
|
async function getActualSshKeyPath(): Promise<string> {
|
||||||
let actualTempFiles = (await fs.promises.readdir(runnerTemp))
|
let actualTempFiles = (await fs.promises.readdir(runnerTemp))
|
||||||
.filter(x => !x.startsWith('git-credentials-')) // Exclude credentials config file
|
|
||||||
.sort()
|
.sort()
|
||||||
.map(x => path.join(runnerTemp, x))
|
.map(x => path.join(runnerTemp, x))
|
||||||
if (actualTempFiles.length === 0) {
|
if (actualTempFiles.length === 0) {
|
||||||
@@ -1012,7 +843,6 @@ async function getActualSshKeyPath(): Promise<string> {
|
|||||||
|
|
||||||
async function getActualSshKnownHostsPath(): Promise<string> {
|
async function getActualSshKnownHostsPath(): Promise<string> {
|
||||||
let actualTempFiles = (await fs.promises.readdir(runnerTemp))
|
let actualTempFiles = (await fs.promises.readdir(runnerTemp))
|
||||||
.filter(x => !x.startsWith('git-credentials-')) // Exclude credentials config file
|
|
||||||
.sort()
|
.sort()
|
||||||
.map(x => path.join(runnerTemp, x))
|
.map(x => path.join(runnerTemp, x))
|
||||||
if (actualTempFiles.length === 0) {
|
if (actualTempFiles.length === 0) {
|
||||||
|
@@ -471,7 +471,6 @@ async function setup(testName: string): Promise<void> {
|
|||||||
configExists: jest.fn(),
|
configExists: jest.fn(),
|
||||||
fetch: jest.fn(),
|
fetch: jest.fn(),
|
||||||
getDefaultBranch: jest.fn(),
|
getDefaultBranch: jest.fn(),
|
||||||
getSubmoduleConfigPaths: jest.fn(async () => []),
|
|
||||||
getWorkingDirectory: jest.fn(() => repositoryPath),
|
getWorkingDirectory: jest.fn(() => repositoryPath),
|
||||||
init: jest.fn(),
|
init: jest.fn(),
|
||||||
isDetached: jest.fn(),
|
isDetached: jest.fn(),
|
||||||
@@ -494,15 +493,12 @@ async function setup(testName: string): Promise<void> {
|
|||||||
return true
|
return true
|
||||||
}),
|
}),
|
||||||
tryConfigUnset: jest.fn(),
|
tryConfigUnset: jest.fn(),
|
||||||
tryConfigUnsetValue: jest.fn(),
|
|
||||||
tryDisableAutomaticGarbageCollection: jest.fn(),
|
tryDisableAutomaticGarbageCollection: jest.fn(),
|
||||||
tryGetFetchUrl: jest.fn(async () => {
|
tryGetFetchUrl: jest.fn(async () => {
|
||||||
// Sanity check - this function shouldn't be called when the .git directory doesn't exist
|
// Sanity check - this function shouldn't be called when the .git directory doesn't exist
|
||||||
await fs.promises.stat(path.join(repositoryPath, '.git'))
|
await fs.promises.stat(path.join(repositoryPath, '.git'))
|
||||||
return repositoryUrl
|
return repositoryUrl
|
||||||
}),
|
}),
|
||||||
tryGetConfigValues: jest.fn(),
|
|
||||||
tryGetConfigKeys: jest.fn(),
|
|
||||||
tryReset: jest.fn(async () => {
|
tryReset: jest.fn(async () => {
|
||||||
return true
|
return true
|
||||||
}),
|
}),
|
||||||
|
@@ -17,7 +17,7 @@ fi
|
|||||||
|
|
||||||
echo "Testing persisted credential"
|
echo "Testing persisted credential"
|
||||||
pushd ./submodules-recursive/submodule-level-1/submodule-level-2
|
pushd ./submodules-recursive/submodule-level-1/submodule-level-2
|
||||||
git config --local --includes --name-only --get-regexp http.+extraheader && git fetch
|
git config --local --name-only --get-regexp http.+extraheader && git fetch
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
echo "Failed to validate persisted credential"
|
echo "Failed to validate persisted credential"
|
||||||
popd
|
popd
|
||||||
|
@@ -17,7 +17,7 @@ fi
|
|||||||
|
|
||||||
echo "Testing persisted credential"
|
echo "Testing persisted credential"
|
||||||
pushd ./submodules-true/submodule-level-1
|
pushd ./submodules-true/submodule-level-1
|
||||||
git config --local --includes --name-only --get-regexp http.+extraheader && git fetch
|
git config --local --name-only --get-regexp http.+extraheader && git fetch
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
echo "Failed to validate persisted credential"
|
echo "Failed to validate persisted credential"
|
||||||
popd
|
popd
|
||||||
|
@@ -104,6 +104,6 @@ outputs:
|
|||||||
commit:
|
commit:
|
||||||
description: 'The commit SHA that was checked out'
|
description: 'The commit SHA that was checked out'
|
||||||
runs:
|
runs:
|
||||||
using: node24
|
using: node20
|
||||||
main: dist/index.js
|
main: dist/index.js
|
||||||
post: dist/index.js
|
post: dist/index.js
|
||||||
|
434
dist/index.js
vendored
434
dist/index.js
vendored
@@ -162,7 +162,6 @@ class GitAuthHelper {
|
|||||||
this.sshKeyPath = '';
|
this.sshKeyPath = '';
|
||||||
this.sshKnownHostsPath = '';
|
this.sshKnownHostsPath = '';
|
||||||
this.temporaryHomePath = '';
|
this.temporaryHomePath = '';
|
||||||
this.credentialsConfigPath = ''; // Path to separate credentials config file in RUNNER_TEMP
|
|
||||||
this.git = gitCommandManager;
|
this.git = gitCommandManager;
|
||||||
this.settings = gitSourceSettings || {};
|
this.settings = gitSourceSettings || {};
|
||||||
// Token auth header
|
// Token auth header
|
||||||
@@ -230,17 +229,15 @@ class GitAuthHelper {
|
|||||||
configureGlobalAuth() {
|
configureGlobalAuth() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// 'configureTempGlobalConfig' noops if already set, just returns the path
|
// 'configureTempGlobalConfig' noops if already set, just returns the path
|
||||||
yield this.configureTempGlobalConfig();
|
const newGitConfigPath = yield this.configureTempGlobalConfig();
|
||||||
try {
|
try {
|
||||||
// Configure the token
|
// Configure the token
|
||||||
yield this.configureToken(true);
|
yield this.configureToken(newGitConfigPath, true);
|
||||||
// Configure HTTPS instead of SSH
|
// Configure HTTPS instead of SSH
|
||||||
yield this.git.tryConfigUnset(this.insteadOfKey, true);
|
yield this.git.tryConfigUnset(this.insteadOfKey, true);
|
||||||
if (!this.settings.sshKey) {
|
if (!this.settings.sshKey) {
|
||||||
for (const insteadOfValue of this.insteadOfValues) {
|
for (const insteadOfValue of this.insteadOfValues) {
|
||||||
yield this.git.config(this.insteadOfKey, insteadOfValue, true, // globalConfig?
|
yield this.git.config(this.insteadOfKey, insteadOfValue, true, true);
|
||||||
true // add?
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,34 +252,19 @@ class GitAuthHelper {
|
|||||||
configureSubmoduleAuth() {
|
configureSubmoduleAuth() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// Remove possible previous HTTPS instead of SSH
|
// Remove possible previous HTTPS instead of SSH
|
||||||
yield this.removeSubmoduleGitConfig(this.insteadOfKey);
|
yield this.removeGitConfig(this.insteadOfKey, true);
|
||||||
if (this.settings.persistCredentials) {
|
if (this.settings.persistCredentials) {
|
||||||
// Get the credentials config file path in RUNNER_TEMP
|
// Configure a placeholder value. This approach avoids the credential being captured
|
||||||
const credentialsConfigPath = this.getCredentialsConfigPath();
|
// by process creation audit events, which are commonly logged. For more information,
|
||||||
// Container credentials config path
|
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||||
const containerCredentialsPath = path.posix.join('/github/runner_temp', path.basename(credentialsConfigPath));
|
const output = yield this.git.submoduleForeach(
|
||||||
// Get submodule config file paths.
|
// wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline
|
||||||
const configPaths = yield this.git.getSubmoduleConfigPaths(this.settings.nestedSubmodules);
|
`sh -c "git config --local '${this.tokenConfigKey}' '${this.tokenPlaceholderConfigValue}' && git config --local --show-origin --name-only --get-regexp remote.origin.url"`, this.settings.nestedSubmodules);
|
||||||
// For each submodule, configure includeIf entries pointing to the shared credentials file.
|
// Replace the placeholder
|
||||||
// Configure both host and container paths to support Docker container actions.
|
const configPaths = output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || [];
|
||||||
for (const configPath of configPaths) {
|
for (const configPath of configPaths) {
|
||||||
// Submodule Git directory
|
core.debug(`Replacing token placeholder in '${configPath}'`);
|
||||||
let submoduleGitDir = path.dirname(configPath); // The config file is at .git/modules/submodule-name/config
|
yield this.replaceTokenPlaceholder(configPath);
|
||||||
submoduleGitDir = submoduleGitDir.replace(/\\/g, '/'); // Use forward slashes, even on Windows
|
|
||||||
// Configure host includeIf
|
|
||||||
yield this.git.config(`includeIf.gitdir:${submoduleGitDir}.path`, credentialsConfigPath, false, // globalConfig?
|
|
||||||
false, // add?
|
|
||||||
configPath);
|
|
||||||
// Container submodule git directory
|
|
||||||
const githubWorkspace = process.env['GITHUB_WORKSPACE'];
|
|
||||||
assert.ok(githubWorkspace, 'GITHUB_WORKSPACE is not defined');
|
|
||||||
let relativeSubmoduleGitDir = path.relative(githubWorkspace, submoduleGitDir);
|
|
||||||
relativeSubmoduleGitDir = relativeSubmoduleGitDir.replace(/\\/g, '/'); // Use forward slashes, even on Windows
|
|
||||||
const containerSubmoduleGitDir = path.posix.join('/github/workspace', relativeSubmoduleGitDir);
|
|
||||||
// Configure container includeIf
|
|
||||||
yield this.git.config(`includeIf.gitdir:${containerSubmoduleGitDir}.path`, containerCredentialsPath, false, // globalConfig?
|
|
||||||
false, // add?
|
|
||||||
configPath);
|
|
||||||
}
|
}
|
||||||
if (this.settings.sshKey) {
|
if (this.settings.sshKey) {
|
||||||
// Configure core.sshCommand
|
// Configure core.sshCommand
|
||||||
@@ -313,10 +295,6 @@ class GitAuthHelper {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Configures SSH authentication by writing the SSH key and known hosts,
|
|
||||||
* and setting up the GIT_SSH_COMMAND environment variable.
|
|
||||||
*/
|
|
||||||
configureSsh() {
|
configureSsh() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!this.settings.sshKey) {
|
if (!this.settings.sshKey) {
|
||||||
@@ -373,88 +351,43 @@ class GitAuthHelper {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
configureToken(configPath, globalConfig) {
|
||||||
* Configures token-based authentication by creating a credentials config file
|
|
||||||
* and setting up includeIf entries to reference it.
|
|
||||||
* @param globalConfig Whether to configure global config instead of local
|
|
||||||
*/
|
|
||||||
configureToken(globalConfig) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// Get the credentials config file path in RUNNER_TEMP
|
// Validate args
|
||||||
const credentialsConfigPath = this.getCredentialsConfigPath();
|
assert.ok((configPath && globalConfig) || (!configPath && !globalConfig), 'Unexpected configureToken parameter combinations');
|
||||||
// Write placeholder to the separate credentials config file using git config.
|
// Default config path
|
||||||
// This approach avoids the credential being captured by process creation audit events,
|
if (!configPath && !globalConfig) {
|
||||||
// which are commonly logged. For more information, refer to
|
configPath = path.join(this.git.getWorkingDirectory(), '.git', 'config');
|
||||||
// https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
}
|
||||||
yield this.git.config(this.tokenConfigKey, this.tokenPlaceholderConfigValue, false, // globalConfig?
|
// Configure a placeholder value. This approach avoids the credential being captured
|
||||||
false, // add?
|
// by process creation audit events, which are commonly logged. For more information,
|
||||||
credentialsConfigPath);
|
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||||
// Replace the placeholder in the credentials config file
|
yield this.git.config(this.tokenConfigKey, this.tokenPlaceholderConfigValue, globalConfig);
|
||||||
let content = (yield fs.promises.readFile(credentialsConfigPath)).toString();
|
// Replace the placeholder
|
||||||
|
yield this.replaceTokenPlaceholder(configPath || '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
replaceTokenPlaceholder(configPath) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
assert.ok(configPath, 'configPath is not defined');
|
||||||
|
let content = (yield fs.promises.readFile(configPath)).toString();
|
||||||
const placeholderIndex = content.indexOf(this.tokenPlaceholderConfigValue);
|
const placeholderIndex = content.indexOf(this.tokenPlaceholderConfigValue);
|
||||||
if (placeholderIndex < 0 ||
|
if (placeholderIndex < 0 ||
|
||||||
placeholderIndex != content.lastIndexOf(this.tokenPlaceholderConfigValue)) {
|
placeholderIndex != content.lastIndexOf(this.tokenPlaceholderConfigValue)) {
|
||||||
throw new Error(`Unable to replace auth placeholder in ${credentialsConfigPath}`);
|
throw new Error(`Unable to replace auth placeholder in ${configPath}`);
|
||||||
}
|
}
|
||||||
assert.ok(this.tokenConfigValue, 'tokenConfigValue is not defined');
|
assert.ok(this.tokenConfigValue, 'tokenConfigValue is not defined');
|
||||||
content = content.replace(this.tokenPlaceholderConfigValue, this.tokenConfigValue);
|
content = content.replace(this.tokenPlaceholderConfigValue, this.tokenConfigValue);
|
||||||
yield fs.promises.writeFile(credentialsConfigPath, content);
|
yield fs.promises.writeFile(configPath, content);
|
||||||
// Add include or includeIf to reference the credentials config
|
|
||||||
if (globalConfig) {
|
|
||||||
// Global config file is temporary
|
|
||||||
yield this.git.config('include.path', credentialsConfigPath, true // globalConfig?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Host git directory
|
|
||||||
let gitDir = path.join(this.git.getWorkingDirectory(), '.git');
|
|
||||||
gitDir = gitDir.replace(/\\/g, '/'); // Use forward slashes, even on Windows
|
|
||||||
// Configure host includeIf
|
|
||||||
const hostIncludeKey = `includeIf.gitdir:${gitDir}.path`;
|
|
||||||
yield this.git.config(hostIncludeKey, credentialsConfigPath);
|
|
||||||
// Container git directory
|
|
||||||
const workingDirectory = this.git.getWorkingDirectory();
|
|
||||||
const githubWorkspace = process.env['GITHUB_WORKSPACE'];
|
|
||||||
assert.ok(githubWorkspace, 'GITHUB_WORKSPACE is not defined');
|
|
||||||
let relativePath = path.relative(githubWorkspace, workingDirectory);
|
|
||||||
relativePath = relativePath.replace(/\\/g, '/'); // Use forward slashes, even on Windows
|
|
||||||
const containerGitDir = path.posix.join('/github/workspace', relativePath, '.git');
|
|
||||||
// Container credentials config path
|
|
||||||
const containerCredentialsPath = path.posix.join('/github/runner_temp', path.basename(credentialsConfigPath));
|
|
||||||
// Configure container includeIf
|
|
||||||
const containerIncludeKey = `includeIf.gitdir:${containerGitDir}.path`;
|
|
||||||
yield this.git.config(containerIncludeKey, containerCredentialsPath);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Gets or creates the path to the credentials config file in RUNNER_TEMP.
|
|
||||||
* @returns The absolute path to the credentials config file
|
|
||||||
*/
|
|
||||||
getCredentialsConfigPath() {
|
|
||||||
if (this.credentialsConfigPath) {
|
|
||||||
return this.credentialsConfigPath;
|
|
||||||
}
|
|
||||||
const runnerTemp = process.env['RUNNER_TEMP'] || '';
|
|
||||||
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined');
|
|
||||||
// Create a unique filename for this checkout instance
|
|
||||||
const configFileName = `git-credentials-${(0, uuid_1.v4)()}.config`;
|
|
||||||
this.credentialsConfigPath = path.join(runnerTemp, configFileName);
|
|
||||||
core.debug(`Credentials config path: ${this.credentialsConfigPath}`);
|
|
||||||
return this.credentialsConfigPath;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes SSH authentication configuration by cleaning up SSH keys,
|
|
||||||
* known hosts files, and SSH command configurations.
|
|
||||||
*/
|
|
||||||
removeSsh() {
|
removeSsh() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
var _a, _b;
|
var _a;
|
||||||
// SSH key
|
// SSH key
|
||||||
const keyPath = this.sshKeyPath || stateHelper.SshKeyPath;
|
const keyPath = this.sshKeyPath || stateHelper.SshKeyPath;
|
||||||
if (keyPath) {
|
if (keyPath) {
|
||||||
try {
|
try {
|
||||||
core.info(`Removing SSH key '${keyPath}'`);
|
|
||||||
yield io.rmRF(keyPath);
|
yield io.rmRF(keyPath);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -466,136 +399,37 @@ class GitAuthHelper {
|
|||||||
const knownHostsPath = this.sshKnownHostsPath || stateHelper.SshKnownHostsPath;
|
const knownHostsPath = this.sshKnownHostsPath || stateHelper.SshKnownHostsPath;
|
||||||
if (knownHostsPath) {
|
if (knownHostsPath) {
|
||||||
try {
|
try {
|
||||||
core.info(`Removing SSH known hosts '${knownHostsPath}'`);
|
|
||||||
yield io.rmRF(knownHostsPath);
|
yield io.rmRF(knownHostsPath);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (_b) {
|
||||||
core.debug(`${(_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err}`);
|
// Intentionally empty
|
||||||
core.warning(`Failed to remove SSH known hosts '${knownHostsPath}'`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SSH command
|
// SSH command
|
||||||
core.info('Removing SSH command configuration');
|
|
||||||
yield this.removeGitConfig(SSH_COMMAND_KEY);
|
yield this.removeGitConfig(SSH_COMMAND_KEY);
|
||||||
yield this.removeSubmoduleGitConfig(SSH_COMMAND_KEY);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Removes token-based authentication by cleaning up HTTP headers,
|
|
||||||
* includeIf entries, and credentials config files.
|
|
||||||
*/
|
|
||||||
removeToken() {
|
removeToken() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
var _a;
|
// HTTP extra header
|
||||||
// Remove HTTP extra header
|
|
||||||
core.info('Removing HTTP extra header');
|
|
||||||
yield this.removeGitConfig(this.tokenConfigKey);
|
yield this.removeGitConfig(this.tokenConfigKey);
|
||||||
yield this.removeSubmoduleGitConfig(this.tokenConfigKey);
|
|
||||||
// Collect credentials config paths that need to be removed
|
|
||||||
const credentialsPaths = new Set();
|
|
||||||
// Remove includeIf entries that point to git-credentials-*.config files
|
|
||||||
core.info('Removing includeIf entries pointing to credentials config files');
|
|
||||||
const mainCredentialsPaths = yield this.removeIncludeIfCredentials();
|
|
||||||
mainCredentialsPaths.forEach(path => credentialsPaths.add(path));
|
|
||||||
// Remove submodule includeIf entries that point to git-credentials-*.config files
|
|
||||||
const submoduleConfigPaths = yield this.git.getSubmoduleConfigPaths(true);
|
|
||||||
for (const configPath of submoduleConfigPaths) {
|
|
||||||
const submoduleCredentialsPaths = yield this.removeIncludeIfCredentials(configPath);
|
|
||||||
submoduleCredentialsPaths.forEach(path => credentialsPaths.add(path));
|
|
||||||
}
|
|
||||||
// Remove credentials config files
|
|
||||||
for (const credentialsPath of credentialsPaths) {
|
|
||||||
// Only remove credentials config files if they are under RUNNER_TEMP
|
|
||||||
const runnerTemp = process.env['RUNNER_TEMP'];
|
|
||||||
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined');
|
|
||||||
if (credentialsPath.startsWith(runnerTemp)) {
|
|
||||||
try {
|
|
||||||
core.info(`Removing credentials config '${credentialsPath}'`);
|
|
||||||
yield io.rmRF(credentialsPath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
core.debug(`${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
||||||
core.warning(`Failed to remove credentials config '${credentialsPath}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
core.debug(`Skipping removal of credentials config '${credentialsPath}' - not under RUNNER_TEMP`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
removeGitConfig(configKey_1) {
|
||||||
* Removes a git config key from the local repository config.
|
return __awaiter(this, arguments, void 0, function* (configKey, submoduleOnly = false) {
|
||||||
* @param configKey The git config key to remove
|
if (!submoduleOnly) {
|
||||||
*/
|
if ((yield this.git.configExists(configKey)) &&
|
||||||
removeGitConfig(configKey) {
|
!(yield this.git.tryConfigUnset(configKey))) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
// Load the config contents
|
||||||
if ((yield this.git.configExists(configKey)) &&
|
core.warning(`Failed to remove '${configKey}' from the git config`);
|
||||||
!(yield this.git.tryConfigUnset(configKey))) {
|
}
|
||||||
// Load the config contents
|
|
||||||
core.warning(`Failed to remove '${configKey}' from the git config`);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes a git config key from all submodule configs.
|
|
||||||
* @param configKey The git config key to remove
|
|
||||||
*/
|
|
||||||
removeSubmoduleGitConfig(configKey) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const pattern = regexpHelper.escape(configKey);
|
const pattern = regexpHelper.escape(configKey);
|
||||||
yield this.git.submoduleForeach(
|
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.
|
// 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);
|
`sh -c "git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :"`, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Removes includeIf entries that point to git-credentials-*.config files.
|
|
||||||
* @param configPath Optional path to a specific git config file to operate on
|
|
||||||
* @returns Array of unique credentials config file paths that were found and removed
|
|
||||||
*/
|
|
||||||
removeIncludeIfCredentials(configPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const credentialsPaths = new Set();
|
|
||||||
try {
|
|
||||||
// Get all includeIf.gitdir keys
|
|
||||||
const keys = yield this.git.tryGetConfigKeys('^includeIf\\.gitdir:', false, // globalConfig?
|
|
||||||
configPath);
|
|
||||||
for (const key of keys) {
|
|
||||||
// Get all values for this key
|
|
||||||
const values = yield this.git.tryGetConfigValues(key, false, // globalConfig?
|
|
||||||
configPath);
|
|
||||||
if (values.length > 0) {
|
|
||||||
// Remove only values that match git-credentials-<uuid>.config pattern
|
|
||||||
for (const value of values) {
|
|
||||||
if (this.testCredentialsConfigPath(value)) {
|
|
||||||
credentialsPaths.add(value);
|
|
||||||
yield this.git.tryConfigUnsetValue(key, value, false, configPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// Ignore errors - this is cleanup code
|
|
||||||
if (configPath) {
|
|
||||||
core.debug(`Error during includeIf cleanup for ${configPath}: ${err}`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
core.debug(`Error during includeIf cleanup: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Array.from(credentialsPaths);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Tests if a path matches the git-credentials-*.config pattern.
|
|
||||||
* @param path The path to test
|
|
||||||
* @returns True if the path matches the credentials config pattern
|
|
||||||
*/
|
|
||||||
testCredentialsConfigPath(path) {
|
|
||||||
return /git-credentials-[0-9a-f-]+\.config$/i.test(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -793,15 +627,9 @@ class GitCommandManager {
|
|||||||
yield this.execGit(args);
|
yield this.execGit(args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
config(configKey, configValue, globalConfig, add, configFile) {
|
config(configKey, configValue, globalConfig, add) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const args = ['config'];
|
const args = ['config', globalConfig ? '--global' : '--local'];
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local');
|
|
||||||
}
|
|
||||||
if (add) {
|
if (add) {
|
||||||
args.push('--add');
|
args.push('--add');
|
||||||
}
|
}
|
||||||
@@ -878,16 +706,6 @@ class GitCommandManager {
|
|||||||
throw new Error('Unexpected output when retrieving default branch');
|
throw new Error('Unexpected output when retrieving default branch');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getSubmoduleConfigPaths(recursive) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Get submodule config file paths.
|
|
||||||
// Use `--show-origin` to get the config file path for each submodule.
|
|
||||||
const output = yield this.submoduleForeach(`git config --local --show-origin --name-only --get-regexp remote.origin.url`, recursive);
|
|
||||||
// Extract config file paths from the output (lines starting with "file:").
|
|
||||||
const configPaths = output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || [];
|
|
||||||
return configPaths;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getWorkingDirectory() {
|
getWorkingDirectory() {
|
||||||
return this.workingDirectory;
|
return this.workingDirectory;
|
||||||
}
|
}
|
||||||
@@ -1018,20 +836,6 @@ class GitCommandManager {
|
|||||||
return output.exitCode === 0;
|
return output.exitCode === 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
tryConfigUnsetValue(configKey, configValue, globalConfig, configFile) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const args = ['config'];
|
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local');
|
|
||||||
}
|
|
||||||
args.push('--unset', configKey, configValue);
|
|
||||||
const output = yield this.execGit(args, true);
|
|
||||||
return output.exitCode === 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tryDisableAutomaticGarbageCollection() {
|
tryDisableAutomaticGarbageCollection() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const output = yield this.execGit(['config', '--local', 'gc.auto', '0'], true);
|
const output = yield this.execGit(['config', '--local', 'gc.auto', '0'], true);
|
||||||
@@ -1051,46 +855,6 @@ class GitCommandManager {
|
|||||||
return stdout;
|
return stdout;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
tryGetConfigValues(configKey, globalConfig, configFile) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const args = ['config'];
|
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local');
|
|
||||||
}
|
|
||||||
args.push('--get-all', configKey);
|
|
||||||
const output = yield this.execGit(args, true);
|
|
||||||
if (output.exitCode !== 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return output.stdout
|
|
||||||
.trim()
|
|
||||||
.split('\n')
|
|
||||||
.filter(value => value.trim());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tryGetConfigKeys(pattern, globalConfig, configFile) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const args = ['config'];
|
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local');
|
|
||||||
}
|
|
||||||
args.push('--name-only', '--get-regexp', pattern);
|
|
||||||
const output = yield this.execGit(args, true);
|
|
||||||
if (output.exitCode !== 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return output.stdout
|
|
||||||
.trim()
|
|
||||||
.split('\n')
|
|
||||||
.filter(key => key.trim());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tryReset() {
|
tryReset() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const output = yield this.execGit(['reset', '--hard', 'HEAD'], true);
|
const output = yield this.execGit(['reset', '--hard', 'HEAD'], true);
|
||||||
@@ -8038,7 +7802,7 @@ module.exports = __toCommonJS(dist_src_exports);
|
|||||||
var import_universal_user_agent = __nccwpck_require__(5030);
|
var import_universal_user_agent = __nccwpck_require__(5030);
|
||||||
|
|
||||||
// pkg/dist-src/version.js
|
// pkg/dist-src/version.js
|
||||||
var VERSION = "9.0.6";
|
var VERSION = "9.0.5";
|
||||||
|
|
||||||
// pkg/dist-src/defaults.js
|
// pkg/dist-src/defaults.js
|
||||||
var userAgent = `octokit-endpoint.js/${VERSION} ${(0, import_universal_user_agent.getUserAgent)()}`;
|
var userAgent = `octokit-endpoint.js/${VERSION} ${(0, import_universal_user_agent.getUserAgent)()}`;
|
||||||
@@ -8143,9 +7907,9 @@ function addQueryParameters(url, parameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pkg/dist-src/util/extract-url-variable-names.js
|
// pkg/dist-src/util/extract-url-variable-names.js
|
||||||
var urlVariableRegex = /\{[^{}}]+\}/g;
|
var urlVariableRegex = /\{[^}]+\}/g;
|
||||||
function removeNonChars(variableName) {
|
function removeNonChars(variableName) {
|
||||||
return variableName.replace(/(?:^\W+)|(?:(?<!\W)\W+$)/g, "").split(/,/);
|
return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
|
||||||
}
|
}
|
||||||
function extractUrlVariableNames(url) {
|
function extractUrlVariableNames(url) {
|
||||||
const matches = url.match(urlVariableRegex);
|
const matches = url.match(urlVariableRegex);
|
||||||
@@ -8331,7 +8095,7 @@ function parse(options) {
|
|||||||
}
|
}
|
||||||
if (url.endsWith("/graphql")) {
|
if (url.endsWith("/graphql")) {
|
||||||
if (options.mediaType.previews?.length) {
|
if (options.mediaType.previews?.length) {
|
||||||
const previewsFromAcceptHeader = headers.accept.match(/(?<![\w-])[\w-]+(?=-preview)/g) || [];
|
const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
|
||||||
headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map((preview) => {
|
headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map((preview) => {
|
||||||
const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json";
|
const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json";
|
||||||
return `application/vnd.github.${preview}-preview${format}`;
|
return `application/vnd.github.${preview}-preview${format}`;
|
||||||
@@ -8580,7 +8344,7 @@ __export(dist_src_exports, {
|
|||||||
module.exports = __toCommonJS(dist_src_exports);
|
module.exports = __toCommonJS(dist_src_exports);
|
||||||
|
|
||||||
// pkg/dist-src/version.js
|
// pkg/dist-src/version.js
|
||||||
var VERSION = "9.2.2";
|
var VERSION = "9.2.1";
|
||||||
|
|
||||||
// pkg/dist-src/normalize-paginated-list-response.js
|
// pkg/dist-src/normalize-paginated-list-response.js
|
||||||
function normalizePaginatedListResponse(response) {
|
function normalizePaginatedListResponse(response) {
|
||||||
@@ -8628,7 +8392,7 @@ function iterator(octokit, route, parameters) {
|
|||||||
const response = await requestMethod({ method, url, headers });
|
const response = await requestMethod({ method, url, headers });
|
||||||
const normalizedResponse = normalizePaginatedListResponse(response);
|
const normalizedResponse = normalizePaginatedListResponse(response);
|
||||||
url = ((normalizedResponse.headers.link || "").match(
|
url = ((normalizedResponse.headers.link || "").match(
|
||||||
/<([^<>]+)>;\s*rel="next"/
|
/<([^>]+)>;\s*rel="next"/
|
||||||
) || [])[1];
|
) || [])[1];
|
||||||
return { value: normalizedResponse };
|
return { value: normalizedResponse };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -11180,7 +10944,7 @@ var RequestError = class extends Error {
|
|||||||
if (options.request.headers.authorization) {
|
if (options.request.headers.authorization) {
|
||||||
requestCopy.headers = Object.assign({}, options.request.headers, {
|
requestCopy.headers = Object.assign({}, options.request.headers, {
|
||||||
authorization: options.request.headers.authorization.replace(
|
authorization: options.request.headers.authorization.replace(
|
||||||
/(?<! ) .*$/,
|
/ .*$/,
|
||||||
" [REDACTED]"
|
" [REDACTED]"
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@@ -11248,7 +11012,7 @@ var import_endpoint = __nccwpck_require__(9440);
|
|||||||
var import_universal_user_agent = __nccwpck_require__(5030);
|
var import_universal_user_agent = __nccwpck_require__(5030);
|
||||||
|
|
||||||
// pkg/dist-src/version.js
|
// pkg/dist-src/version.js
|
||||||
var VERSION = "8.4.1";
|
var VERSION = "8.4.0";
|
||||||
|
|
||||||
// pkg/dist-src/is-plain-object.js
|
// pkg/dist-src/is-plain-object.js
|
||||||
function isPlainObject(value) {
|
function isPlainObject(value) {
|
||||||
@@ -11307,7 +11071,7 @@ function fetchWrapper(requestOptions) {
|
|||||||
headers[keyAndValue[0]] = keyAndValue[1];
|
headers[keyAndValue[0]] = keyAndValue[1];
|
||||||
}
|
}
|
||||||
if ("deprecation" in headers) {
|
if ("deprecation" in headers) {
|
||||||
const matches = headers.link && headers.link.match(/<([^<>]+)>; rel="deprecation"/);
|
const matches = headers.link && headers.link.match(/<([^>]+)>; rel="deprecation"/);
|
||||||
const deprecationLink = matches && matches.pop();
|
const deprecationLink = matches && matches.pop();
|
||||||
log.warn(
|
log.warn(
|
||||||
`[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}`
|
`[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}`
|
||||||
@@ -18961,7 +18725,7 @@ module.exports = {
|
|||||||
|
|
||||||
|
|
||||||
const { parseSetCookie } = __nccwpck_require__(4408)
|
const { parseSetCookie } = __nccwpck_require__(4408)
|
||||||
const { stringify } = __nccwpck_require__(3121)
|
const { stringify, getHeadersList } = __nccwpck_require__(3121)
|
||||||
const { webidl } = __nccwpck_require__(1744)
|
const { webidl } = __nccwpck_require__(1744)
|
||||||
const { Headers } = __nccwpck_require__(554)
|
const { Headers } = __nccwpck_require__(554)
|
||||||
|
|
||||||
@@ -19037,13 +18801,14 @@ function getSetCookies (headers) {
|
|||||||
|
|
||||||
webidl.brandCheck(headers, Headers, { strict: false })
|
webidl.brandCheck(headers, Headers, { strict: false })
|
||||||
|
|
||||||
const cookies = headers.getSetCookie()
|
const cookies = getHeadersList(headers).cookies
|
||||||
|
|
||||||
if (!cookies) {
|
if (!cookies) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
return cookies.map((pair) => parseSetCookie(pair))
|
// In older versions of undici, cookies is a list of name:value.
|
||||||
|
return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19471,15 +19236,14 @@ module.exports = {
|
|||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3121:
|
/***/ 3121:
|
||||||
/***/ ((module) => {
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
/**
|
const assert = __nccwpck_require__(9491)
|
||||||
* @param {string} value
|
const { kHeadersList } = __nccwpck_require__(2785)
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
function isCTLExcludingHtab (value) {
|
function isCTLExcludingHtab (value) {
|
||||||
if (value.length === 0) {
|
if (value.length === 0) {
|
||||||
return false
|
return false
|
||||||
@@ -19740,13 +19504,31 @@ function stringify (cookie) {
|
|||||||
return out.join('; ')
|
return out.join('; ')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let kHeadersListNode
|
||||||
|
|
||||||
|
function getHeadersList (headers) {
|
||||||
|
if (headers[kHeadersList]) {
|
||||||
|
return headers[kHeadersList]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!kHeadersListNode) {
|
||||||
|
kHeadersListNode = Object.getOwnPropertySymbols(headers).find(
|
||||||
|
(symbol) => symbol.description === 'headers list'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(kHeadersListNode, 'Headers cannot be parsed')
|
||||||
|
}
|
||||||
|
|
||||||
|
const headersList = headers[kHeadersListNode]
|
||||||
|
assert(headersList)
|
||||||
|
|
||||||
|
return headersList
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isCTLExcludingHtab,
|
isCTLExcludingHtab,
|
||||||
validateCookieName,
|
stringify,
|
||||||
validateCookiePath,
|
getHeadersList
|
||||||
validateCookieValue,
|
|
||||||
toIMFDate,
|
|
||||||
stringify
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -21675,14 +21457,6 @@ const { isUint8Array, isArrayBuffer } = __nccwpck_require__(9830)
|
|||||||
const { File: UndiciFile } = __nccwpck_require__(8511)
|
const { File: UndiciFile } = __nccwpck_require__(8511)
|
||||||
const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685)
|
const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685)
|
||||||
|
|
||||||
let random
|
|
||||||
try {
|
|
||||||
const crypto = __nccwpck_require__(6005)
|
|
||||||
random = (max) => crypto.randomInt(0, max)
|
|
||||||
} catch {
|
|
||||||
random = (max) => Math.floor(Math.random(max))
|
|
||||||
}
|
|
||||||
|
|
||||||
let ReadableStream = globalThis.ReadableStream
|
let ReadableStream = globalThis.ReadableStream
|
||||||
|
|
||||||
/** @type {globalThis['File']} */
|
/** @type {globalThis['File']} */
|
||||||
@@ -21768,7 +21542,7 @@ function extractBody (object, keepalive = false) {
|
|||||||
// Set source to a copy of the bytes held by object.
|
// Set source to a copy of the bytes held by object.
|
||||||
source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength))
|
source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength))
|
||||||
} else if (util.isFormDataLike(object)) {
|
} else if (util.isFormDataLike(object)) {
|
||||||
const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, '0')}`
|
const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}`
|
||||||
const prefix = `--${boundary}\r\nContent-Disposition: form-data`
|
const prefix = `--${boundary}\r\nContent-Disposition: form-data`
|
||||||
|
|
||||||
/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
|
/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
|
||||||
@@ -23750,7 +23524,6 @@ const {
|
|||||||
isValidHeaderName,
|
isValidHeaderName,
|
||||||
isValidHeaderValue
|
isValidHeaderValue
|
||||||
} = __nccwpck_require__(2538)
|
} = __nccwpck_require__(2538)
|
||||||
const util = __nccwpck_require__(3837)
|
|
||||||
const { webidl } = __nccwpck_require__(1744)
|
const { webidl } = __nccwpck_require__(1744)
|
||||||
const assert = __nccwpck_require__(9491)
|
const assert = __nccwpck_require__(9491)
|
||||||
|
|
||||||
@@ -24304,9 +24077,6 @@ Object.defineProperties(Headers.prototype, {
|
|||||||
[Symbol.toStringTag]: {
|
[Symbol.toStringTag]: {
|
||||||
value: 'Headers',
|
value: 'Headers',
|
||||||
configurable: true
|
configurable: true
|
||||||
},
|
|
||||||
[util.inspect.custom]: {
|
|
||||||
enumerable: false
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -33483,20 +33253,6 @@ class Pool extends PoolBase {
|
|||||||
? { ...options.interceptors }
|
? { ...options.interceptors }
|
||||||
: undefined
|
: undefined
|
||||||
this[kFactory] = factory
|
this[kFactory] = factory
|
||||||
|
|
||||||
this.on('connectionError', (origin, targets, error) => {
|
|
||||||
// If a connection error occurs, we remove the client from the pool,
|
|
||||||
// and emit a connectionError event. They will not be re-used.
|
|
||||||
// Fixes https://github.com/nodejs/undici/issues/3895
|
|
||||||
for (const target of targets) {
|
|
||||||
// Do not use kRemoveClient here, as it will close the client,
|
|
||||||
// but the client cannot be closed in this state.
|
|
||||||
const idx = this[kClients].indexOf(target)
|
|
||||||
if (idx !== -1) {
|
|
||||||
this[kClients].splice(idx, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[kGetDispatcher] () {
|
[kGetDispatcher] () {
|
||||||
@@ -36652,14 +36408,6 @@ module.exports = require("net");
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 6005:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
module.exports = require("node:crypto");
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 5673:
|
/***/ 5673:
|
||||||
/***/ ((module) => {
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
332
package-lock.json
generated
332
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "checkout",
|
"name": "checkout",
|
||||||
"version": "5.0.0",
|
"version": "4.2.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "checkout",
|
"name": "checkout",
|
||||||
"version": "5.0.0",
|
"version": "4.2.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^20.12.12",
|
||||||
"@types/uuid": "^9.0.8",
|
"@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",
|
||||||
@@ -129,15 +129,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.27.1",
|
"version": "7.24.2",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
|
||||||
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-validator-identifier": "^7.27.1",
|
"@babel/highlight": "^7.24.2",
|
||||||
"js-tokens": "^4.0.0",
|
"picocolors": "^1.0.0"
|
||||||
"picocolors": "^1.1.1"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -312,21 +310,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-string-parser": {
|
"node_modules/@babel/helper-string-parser": {
|
||||||
"version": "7.27.1",
|
"version": "7.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
|
||||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
"integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-validator-identifier": {
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
"version": "7.27.1",
|
"version": "7.22.20",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -341,28 +337,110 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helpers": {
|
"node_modules/@babel/helpers": {
|
||||||
"version": "7.28.2",
|
"version": "7.24.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz",
|
||||||
"integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==",
|
"integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/template": "^7.27.2",
|
"@babel/template": "^7.24.0",
|
||||||
"@babel/types": "^7.28.2"
|
"@babel/traverse": "^7.24.1",
|
||||||
|
"@babel/types": "^7.24.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/highlight": {
|
||||||
"version": "7.28.0",
|
"version": "7.24.2",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
|
||||||
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
|
"integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.28.0"
|
"@babel/helper-validator-identifier": "^7.22.20",
|
||||||
|
"chalk": "^2.4.2",
|
||||||
|
"js-tokens": "^4.0.0",
|
||||||
|
"picocolors": "^1.0.0"
|
||||||
},
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/chalk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^3.2.1",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"supports-color": "^5.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/color-convert": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight/node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/parser": {
|
||||||
|
"version": "7.24.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
|
||||||
|
"integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
|
||||||
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
},
|
},
|
||||||
@@ -548,25 +626,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.28.2",
|
"version": "7.24.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
|
||||||
"integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==",
|
"integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"dependencies": {
|
||||||
|
"regenerator-runtime": "^0.14.0"
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.27.2",
|
"version": "7.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
|
||||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
"integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.23.5",
|
||||||
"@babel/parser": "^7.27.2",
|
"@babel/parser": "^7.24.0",
|
||||||
"@babel/types": "^7.27.1"
|
"@babel/types": "^7.24.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -603,14 +682,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.28.2",
|
"version": "7.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
|
||||||
"integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
|
"integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-string-parser": "^7.27.1",
|
"@babel/helper-string-parser": "^7.23.4",
|
||||||
"@babel/helper-validator-identifier": "^7.27.1"
|
"@babel/helper-validator-identifier": "^7.22.20",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -670,11 +749,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
|
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -730,11 +808,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
|
"node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -1266,10 +1343,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/endpoint": {
|
"node_modules/@octokit/endpoint": {
|
||||||
"version": "9.0.6",
|
"version": "9.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz",
|
||||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
"integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^13.1.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
@@ -1297,10 +1373,9 @@
|
|||||||
"integrity": "sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q=="
|
"integrity": "sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-paginate-rest": {
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
"version": "9.2.2",
|
"version": "9.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz",
|
||||||
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
"integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^12.6.0"
|
"@octokit/types": "^12.6.0"
|
||||||
},
|
},
|
||||||
@@ -1352,13 +1427,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "8.4.1",
|
"version": "8.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz",
|
||||||
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
"integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/endpoint": "^9.0.6",
|
"@octokit/endpoint": "^9.0.1",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^5.1.0",
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^13.1.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
},
|
},
|
||||||
@@ -1367,10 +1441,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request-error": {
|
"node_modules/@octokit/request-error": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz",
|
||||||
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
"integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^13.1.0",
|
||||||
"deprecation": "^2.0.0",
|
"deprecation": "^2.0.0",
|
||||||
@@ -1515,12 +1588,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.1.0",
|
"version": "20.12.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
|
||||||
"integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
|
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.8.0"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/stack-utils": {
|
"node_modules/@types/stack-utils": {
|
||||||
@@ -2165,11 +2238,10 @@
|
|||||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
|
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0"
|
"balanced-match": "^1.0.0"
|
||||||
}
|
}
|
||||||
@@ -2430,11 +2502,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
"shebang-command": "^2.0.0",
|
"shebang-command": "^2.0.0",
|
||||||
@@ -3104,11 +3175,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
|
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -3203,11 +3273,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": {
|
"node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -3302,11 +3371,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint/node_modules/brace-expansion": {
|
"node_modules/eslint/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -3768,11 +3836,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/glob/node_modules/brace-expansion": {
|
"node_modules/glob/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -4568,11 +4635,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jake/node_modules/brace-expansion": {
|
"node_modules/jake/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -5182,8 +5248,7 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
@@ -5463,13 +5528,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/micromatch": {
|
"node_modules/micromatch": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": "^3.0.3",
|
"braces": "^3.0.2",
|
||||||
"picomatch": "^2.3.1"
|
"picomatch": "^2.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -5805,11 +5869,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"license": "ISC"
|
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
@@ -6052,6 +6115,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/regenerator-runtime": {
|
||||||
|
"version": "0.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||||
|
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/regexp.prototype.flags": {
|
"node_modules/regexp.prototype.flags": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
|
||||||
@@ -6553,11 +6622,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/test-exclude/node_modules/brace-expansion": {
|
"node_modules/test-exclude/node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -6587,6 +6655,15 @@
|
|||||||
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
|
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/to-fast-properties": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
@@ -6853,10 +6930,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "5.29.0",
|
"version": "5.28.4",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/busboy": "^2.0.0"
|
"@fastify/busboy": "^2.0.0"
|
||||||
},
|
},
|
||||||
@@ -6865,9 +6941,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.8.0",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/universal-user-agent": {
|
"node_modules/universal-user-agent": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "checkout",
|
"name": "checkout",
|
||||||
"version": "5.0.0",
|
"version": "4.2.2",
|
||||||
"description": "checkout action",
|
"description": "checkout action",
|
||||||
"main": "lib/main.js",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^20.12.12",
|
||||||
"@types/uuid": "^9.0.8",
|
"@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",
|
||||||
|
@@ -43,7 +43,6 @@ class GitAuthHelper {
|
|||||||
private sshKeyPath = ''
|
private sshKeyPath = ''
|
||||||
private sshKnownHostsPath = ''
|
private sshKnownHostsPath = ''
|
||||||
private temporaryHomePath = ''
|
private temporaryHomePath = ''
|
||||||
private credentialsConfigPath = '' // Path to separate credentials config file in RUNNER_TEMP
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
gitCommandManager: IGitCommandManager,
|
gitCommandManager: IGitCommandManager,
|
||||||
@@ -68,7 +67,7 @@ class GitAuthHelper {
|
|||||||
this.insteadOfValues.push(`git@${serverUrl.hostname}:`)
|
this.insteadOfValues.push(`git@${serverUrl.hostname}:`)
|
||||||
if (this.settings.workflowOrganizationId) {
|
if (this.settings.workflowOrganizationId) {
|
||||||
this.insteadOfValues.push(
|
this.insteadOfValues.push(
|
||||||
`org-${this.settings.workflowOrganizationId}@github.com:`
|
`org-${this.settings.workflowOrganizationId}@${serverUrl.hostname}:`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,21 +126,16 @@ class GitAuthHelper {
|
|||||||
|
|
||||||
async configureGlobalAuth(): Promise<void> {
|
async configureGlobalAuth(): Promise<void> {
|
||||||
// 'configureTempGlobalConfig' noops if already set, just returns the path
|
// 'configureTempGlobalConfig' noops if already set, just returns the path
|
||||||
await this.configureTempGlobalConfig()
|
const newGitConfigPath = await this.configureTempGlobalConfig()
|
||||||
try {
|
try {
|
||||||
// Configure the token
|
// Configure the token
|
||||||
await this.configureToken(true)
|
await this.configureToken(newGitConfigPath, true)
|
||||||
|
|
||||||
// Configure HTTPS instead of SSH
|
// Configure HTTPS instead of SSH
|
||||||
await this.git.tryConfigUnset(this.insteadOfKey, true)
|
await this.git.tryConfigUnset(this.insteadOfKey, true)
|
||||||
if (!this.settings.sshKey) {
|
if (!this.settings.sshKey) {
|
||||||
for (const insteadOfValue of this.insteadOfValues) {
|
for (const insteadOfValue of this.insteadOfValues) {
|
||||||
await this.git.config(
|
await this.git.config(this.insteadOfKey, insteadOfValue, true, true)
|
||||||
this.insteadOfKey,
|
|
||||||
insteadOfValue,
|
|
||||||
true, // globalConfig?
|
|
||||||
true // add?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -156,60 +150,24 @@ class GitAuthHelper {
|
|||||||
|
|
||||||
async configureSubmoduleAuth(): Promise<void> {
|
async configureSubmoduleAuth(): Promise<void> {
|
||||||
// Remove possible previous HTTPS instead of SSH
|
// Remove possible previous HTTPS instead of SSH
|
||||||
await this.removeSubmoduleGitConfig(this.insteadOfKey)
|
await this.removeGitConfig(this.insteadOfKey, true)
|
||||||
|
|
||||||
if (this.settings.persistCredentials) {
|
if (this.settings.persistCredentials) {
|
||||||
// Get the credentials config file path in RUNNER_TEMP
|
// Configure a placeholder value. This approach avoids the credential being captured
|
||||||
const credentialsConfigPath = this.getCredentialsConfigPath()
|
// 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
|
||||||
// Container credentials config path
|
const output = await this.git.submoduleForeach(
|
||||||
const containerCredentialsPath = path.posix.join(
|
// wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline
|
||||||
'/github/runner_temp',
|
`sh -c "git config --local '${this.tokenConfigKey}' '${this.tokenPlaceholderConfigValue}' && git config --local --show-origin --name-only --get-regexp remote.origin.url"`,
|
||||||
path.basename(credentialsConfigPath)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get submodule config file paths.
|
|
||||||
const configPaths = await this.git.getSubmoduleConfigPaths(
|
|
||||||
this.settings.nestedSubmodules
|
this.settings.nestedSubmodules
|
||||||
)
|
)
|
||||||
|
|
||||||
// For each submodule, configure includeIf entries pointing to the shared credentials file.
|
// Replace the placeholder
|
||||||
// Configure both host and container paths to support Docker container actions.
|
const configPaths: string[] =
|
||||||
|
output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || []
|
||||||
for (const configPath of configPaths) {
|
for (const configPath of configPaths) {
|
||||||
// Submodule Git directory
|
core.debug(`Replacing token placeholder in '${configPath}'`)
|
||||||
let submoduleGitDir = path.dirname(configPath) // The config file is at .git/modules/submodule-name/config
|
await this.replaceTokenPlaceholder(configPath)
|
||||||
submoduleGitDir = submoduleGitDir.replace(/\\/g, '/') // Use forward slashes, even on Windows
|
|
||||||
|
|
||||||
// Configure host includeIf
|
|
||||||
await this.git.config(
|
|
||||||
`includeIf.gitdir:${submoduleGitDir}.path`,
|
|
||||||
credentialsConfigPath,
|
|
||||||
false, // globalConfig?
|
|
||||||
false, // add?
|
|
||||||
configPath
|
|
||||||
)
|
|
||||||
|
|
||||||
// Container submodule git directory
|
|
||||||
const githubWorkspace = process.env['GITHUB_WORKSPACE']
|
|
||||||
assert.ok(githubWorkspace, 'GITHUB_WORKSPACE is not defined')
|
|
||||||
let relativeSubmoduleGitDir = path.relative(
|
|
||||||
githubWorkspace,
|
|
||||||
submoduleGitDir
|
|
||||||
)
|
|
||||||
relativeSubmoduleGitDir = relativeSubmoduleGitDir.replace(/\\/g, '/') // Use forward slashes, even on Windows
|
|
||||||
const containerSubmoduleGitDir = path.posix.join(
|
|
||||||
'/github/workspace',
|
|
||||||
relativeSubmoduleGitDir
|
|
||||||
)
|
|
||||||
|
|
||||||
// Configure container includeIf
|
|
||||||
await this.git.config(
|
|
||||||
`includeIf.gitdir:${containerSubmoduleGitDir}.path`,
|
|
||||||
containerCredentialsPath,
|
|
||||||
false, // globalConfig?
|
|
||||||
false, // add?
|
|
||||||
configPath
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.settings.sshKey) {
|
if (this.settings.sshKey) {
|
||||||
@@ -243,10 +201,6 @@ class GitAuthHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures SSH authentication by writing the SSH key and known hosts,
|
|
||||||
* and setting up the GIT_SSH_COMMAND environment variable.
|
|
||||||
*/
|
|
||||||
private async configureSsh(): Promise<void> {
|
private async configureSsh(): Promise<void> {
|
||||||
if (!this.settings.sshKey) {
|
if (!this.settings.sshKey) {
|
||||||
return
|
return
|
||||||
@@ -318,116 +272,57 @@ class GitAuthHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private async configureToken(
|
||||||
* Configures token-based authentication by creating a credentials config file
|
configPath?: string,
|
||||||
* and setting up includeIf entries to reference it.
|
globalConfig?: boolean
|
||||||
* @param globalConfig Whether to configure global config instead of local
|
): Promise<void> {
|
||||||
*/
|
// Validate args
|
||||||
private async configureToken(globalConfig?: boolean): Promise<void> {
|
assert.ok(
|
||||||
// Get the credentials config file path in RUNNER_TEMP
|
(configPath && globalConfig) || (!configPath && !globalConfig),
|
||||||
const credentialsConfigPath = this.getCredentialsConfigPath()
|
'Unexpected configureToken parameter combinations'
|
||||||
|
)
|
||||||
|
|
||||||
// Write placeholder to the separate credentials config file using git config.
|
// Default config path
|
||||||
// This approach avoids the credential being captured by process creation audit events,
|
if (!configPath && !globalConfig) {
|
||||||
// which are commonly logged. For more information, refer to
|
configPath = path.join(this.git.getWorkingDirectory(), '.git', 'config')
|
||||||
// https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
}
|
||||||
|
|
||||||
|
// Configure a placeholder value. This approach avoids the credential being captured
|
||||||
|
// 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
|
||||||
await this.git.config(
|
await this.git.config(
|
||||||
this.tokenConfigKey,
|
this.tokenConfigKey,
|
||||||
this.tokenPlaceholderConfigValue,
|
this.tokenPlaceholderConfigValue,
|
||||||
false, // globalConfig?
|
globalConfig
|
||||||
false, // add?
|
|
||||||
credentialsConfigPath
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Replace the placeholder in the credentials config file
|
// Replace the placeholder
|
||||||
let content = (await fs.promises.readFile(credentialsConfigPath)).toString()
|
await this.replaceTokenPlaceholder(configPath || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
private async replaceTokenPlaceholder(configPath: string): Promise<void> {
|
||||||
|
assert.ok(configPath, 'configPath is not defined')
|
||||||
|
let content = (await fs.promises.readFile(configPath)).toString()
|
||||||
const placeholderIndex = content.indexOf(this.tokenPlaceholderConfigValue)
|
const placeholderIndex = content.indexOf(this.tokenPlaceholderConfigValue)
|
||||||
if (
|
if (
|
||||||
placeholderIndex < 0 ||
|
placeholderIndex < 0 ||
|
||||||
placeholderIndex != content.lastIndexOf(this.tokenPlaceholderConfigValue)
|
placeholderIndex != content.lastIndexOf(this.tokenPlaceholderConfigValue)
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(`Unable to replace auth placeholder in ${configPath}`)
|
||||||
`Unable to replace auth placeholder in ${credentialsConfigPath}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
assert.ok(this.tokenConfigValue, 'tokenConfigValue is not defined')
|
assert.ok(this.tokenConfigValue, 'tokenConfigValue is not defined')
|
||||||
content = content.replace(
|
content = content.replace(
|
||||||
this.tokenPlaceholderConfigValue,
|
this.tokenPlaceholderConfigValue,
|
||||||
this.tokenConfigValue
|
this.tokenConfigValue
|
||||||
)
|
)
|
||||||
await fs.promises.writeFile(credentialsConfigPath, content)
|
await fs.promises.writeFile(configPath, content)
|
||||||
|
|
||||||
// Add include or includeIf to reference the credentials config
|
|
||||||
if (globalConfig) {
|
|
||||||
// Global config file is temporary
|
|
||||||
await this.git.config(
|
|
||||||
'include.path',
|
|
||||||
credentialsConfigPath,
|
|
||||||
true // globalConfig?
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Host git directory
|
|
||||||
let gitDir = path.join(this.git.getWorkingDirectory(), '.git')
|
|
||||||
gitDir = gitDir.replace(/\\/g, '/') // Use forward slashes, even on Windows
|
|
||||||
|
|
||||||
// Configure host includeIf
|
|
||||||
const hostIncludeKey = `includeIf.gitdir:${gitDir}.path`
|
|
||||||
await this.git.config(hostIncludeKey, credentialsConfigPath)
|
|
||||||
|
|
||||||
// Container git directory
|
|
||||||
const workingDirectory = this.git.getWorkingDirectory()
|
|
||||||
const githubWorkspace = process.env['GITHUB_WORKSPACE']
|
|
||||||
assert.ok(githubWorkspace, 'GITHUB_WORKSPACE is not defined')
|
|
||||||
let relativePath = path.relative(githubWorkspace, workingDirectory)
|
|
||||||
relativePath = relativePath.replace(/\\/g, '/') // Use forward slashes, even on Windows
|
|
||||||
const containerGitDir = path.posix.join(
|
|
||||||
'/github/workspace',
|
|
||||||
relativePath,
|
|
||||||
'.git'
|
|
||||||
)
|
|
||||||
|
|
||||||
// Container credentials config path
|
|
||||||
const containerCredentialsPath = path.posix.join(
|
|
||||||
'/github/runner_temp',
|
|
||||||
path.basename(credentialsConfigPath)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Configure container includeIf
|
|
||||||
const containerIncludeKey = `includeIf.gitdir:${containerGitDir}.path`
|
|
||||||
await this.git.config(containerIncludeKey, containerCredentialsPath)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets or creates the path to the credentials config file in RUNNER_TEMP.
|
|
||||||
* @returns The absolute path to the credentials config file
|
|
||||||
*/
|
|
||||||
private getCredentialsConfigPath(): string {
|
|
||||||
if (this.credentialsConfigPath) {
|
|
||||||
return this.credentialsConfigPath
|
|
||||||
}
|
|
||||||
|
|
||||||
const runnerTemp = process.env['RUNNER_TEMP'] || ''
|
|
||||||
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
|
|
||||||
|
|
||||||
// Create a unique filename for this checkout instance
|
|
||||||
const configFileName = `git-credentials-${uuid()}.config`
|
|
||||||
this.credentialsConfigPath = path.join(runnerTemp, configFileName)
|
|
||||||
|
|
||||||
core.debug(`Credentials config path: ${this.credentialsConfigPath}`)
|
|
||||||
return this.credentialsConfigPath
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes SSH authentication configuration by cleaning up SSH keys,
|
|
||||||
* known hosts files, and SSH command configurations.
|
|
||||||
*/
|
|
||||||
private async removeSsh(): Promise<void> {
|
private async removeSsh(): Promise<void> {
|
||||||
// SSH key
|
// SSH key
|
||||||
const keyPath = this.sshKeyPath || stateHelper.SshKeyPath
|
const keyPath = this.sshKeyPath || stateHelper.SshKeyPath
|
||||||
if (keyPath) {
|
if (keyPath) {
|
||||||
try {
|
try {
|
||||||
core.info(`Removing SSH key '${keyPath}'`)
|
|
||||||
await io.rmRF(keyPath)
|
await io.rmRF(keyPath)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
core.debug(`${(err as any)?.message ?? err}`)
|
core.debug(`${(err as any)?.message ?? err}`)
|
||||||
@@ -440,149 +335,40 @@ class GitAuthHelper {
|
|||||||
this.sshKnownHostsPath || stateHelper.SshKnownHostsPath
|
this.sshKnownHostsPath || stateHelper.SshKnownHostsPath
|
||||||
if (knownHostsPath) {
|
if (knownHostsPath) {
|
||||||
try {
|
try {
|
||||||
core.info(`Removing SSH known hosts '${knownHostsPath}'`)
|
|
||||||
await io.rmRF(knownHostsPath)
|
await io.rmRF(knownHostsPath)
|
||||||
} catch (err) {
|
} catch {
|
||||||
core.debug(`${(err as any)?.message ?? err}`)
|
// Intentionally empty
|
||||||
core.warning(`Failed to remove SSH known hosts '${knownHostsPath}'`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSH command
|
// SSH command
|
||||||
core.info('Removing SSH command configuration')
|
|
||||||
await this.removeGitConfig(SSH_COMMAND_KEY)
|
await this.removeGitConfig(SSH_COMMAND_KEY)
|
||||||
await this.removeSubmoduleGitConfig(SSH_COMMAND_KEY)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes token-based authentication by cleaning up HTTP headers,
|
|
||||||
* includeIf entries, and credentials config files.
|
|
||||||
*/
|
|
||||||
private async removeToken(): Promise<void> {
|
private async removeToken(): Promise<void> {
|
||||||
// Remove HTTP extra header
|
// HTTP extra header
|
||||||
core.info('Removing HTTP extra header')
|
|
||||||
await this.removeGitConfig(this.tokenConfigKey)
|
await this.removeGitConfig(this.tokenConfigKey)
|
||||||
await this.removeSubmoduleGitConfig(this.tokenConfigKey)
|
}
|
||||||
|
|
||||||
// Collect credentials config paths that need to be removed
|
private async removeGitConfig(
|
||||||
const credentialsPaths = new Set<string>()
|
configKey: string,
|
||||||
|
submoduleOnly: boolean = false
|
||||||
// Remove includeIf entries that point to git-credentials-*.config files
|
): Promise<void> {
|
||||||
core.info('Removing includeIf entries pointing to credentials config files')
|
if (!submoduleOnly) {
|
||||||
const mainCredentialsPaths = await this.removeIncludeIfCredentials()
|
if (
|
||||||
mainCredentialsPaths.forEach(path => credentialsPaths.add(path))
|
(await this.git.configExists(configKey)) &&
|
||||||
|
!(await this.git.tryConfigUnset(configKey))
|
||||||
// Remove submodule includeIf entries that point to git-credentials-*.config files
|
) {
|
||||||
const submoduleConfigPaths = await this.git.getSubmoduleConfigPaths(true)
|
// Load the config contents
|
||||||
for (const configPath of submoduleConfigPaths) {
|
core.warning(`Failed to remove '${configKey}' from the git config`)
|
||||||
const submoduleCredentialsPaths =
|
|
||||||
await this.removeIncludeIfCredentials(configPath)
|
|
||||||
submoduleCredentialsPaths.forEach(path => credentialsPaths.add(path))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove credentials config files
|
|
||||||
for (const credentialsPath of credentialsPaths) {
|
|
||||||
// Only remove credentials config files if they are under RUNNER_TEMP
|
|
||||||
const runnerTemp = process.env['RUNNER_TEMP']
|
|
||||||
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
|
|
||||||
if (credentialsPath.startsWith(runnerTemp)) {
|
|
||||||
try {
|
|
||||||
core.info(`Removing credentials config '${credentialsPath}'`)
|
|
||||||
await io.rmRF(credentialsPath)
|
|
||||||
} catch (err) {
|
|
||||||
core.debug(`${(err as any)?.message ?? err}`)
|
|
||||||
core.warning(
|
|
||||||
`Failed to remove credentials config '${credentialsPath}'`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
core.debug(
|
|
||||||
`Skipping removal of credentials config '${credentialsPath}' - not under RUNNER_TEMP`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a git config key from the local repository config.
|
|
||||||
* @param configKey The git config key to remove
|
|
||||||
*/
|
|
||||||
private async removeGitConfig(configKey: string): Promise<void> {
|
|
||||||
if (
|
|
||||||
(await this.git.configExists(configKey)) &&
|
|
||||||
!(await this.git.tryConfigUnset(configKey))
|
|
||||||
) {
|
|
||||||
// Load the config contents
|
|
||||||
core.warning(`Failed to remove '${configKey}' from the git config`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a git config key from all submodule configs.
|
|
||||||
* @param configKey The git config key to remove
|
|
||||||
*/
|
|
||||||
private async removeSubmoduleGitConfig(configKey: string): Promise<void> {
|
|
||||||
const pattern = regexpHelper.escape(configKey)
|
const pattern = regexpHelper.escape(configKey)
|
||||||
await this.git.submoduleForeach(
|
await 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.
|
// 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}' || :"`,
|
`sh -c "git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :"`,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes includeIf entries that point to git-credentials-*.config files.
|
|
||||||
* @param configPath Optional path to a specific git config file to operate on
|
|
||||||
* @returns Array of unique credentials config file paths that were found and removed
|
|
||||||
*/
|
|
||||||
private async removeIncludeIfCredentials(
|
|
||||||
configPath?: string
|
|
||||||
): Promise<string[]> {
|
|
||||||
const credentialsPaths = new Set<string>()
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Get all includeIf.gitdir keys
|
|
||||||
const keys = await this.git.tryGetConfigKeys(
|
|
||||||
'^includeIf\\.gitdir:',
|
|
||||||
false, // globalConfig?
|
|
||||||
configPath
|
|
||||||
)
|
|
||||||
|
|
||||||
for (const key of keys) {
|
|
||||||
// Get all values for this key
|
|
||||||
const values = await this.git.tryGetConfigValues(
|
|
||||||
key,
|
|
||||||
false, // globalConfig?
|
|
||||||
configPath
|
|
||||||
)
|
|
||||||
if (values.length > 0) {
|
|
||||||
// Remove only values that match git-credentials-<uuid>.config pattern
|
|
||||||
for (const value of values) {
|
|
||||||
if (this.testCredentialsConfigPath(value)) {
|
|
||||||
credentialsPaths.add(value)
|
|
||||||
await this.git.tryConfigUnsetValue(key, value, false, configPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
// Ignore errors - this is cleanup code
|
|
||||||
if (configPath) {
|
|
||||||
core.debug(`Error during includeIf cleanup for ${configPath}: ${err}`)
|
|
||||||
} else {
|
|
||||||
core.debug(`Error during includeIf cleanup: ${err}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.from(credentialsPaths)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests if a path matches the git-credentials-*.config pattern.
|
|
||||||
* @param path The path to test
|
|
||||||
* @returns True if the path matches the credentials config pattern
|
|
||||||
*/
|
|
||||||
private testCredentialsConfigPath(path: string): boolean {
|
|
||||||
return /git-credentials-[0-9a-f-]+\.config$/i.test(path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,7 @@ export interface IGitCommandManager {
|
|||||||
configKey: string,
|
configKey: string,
|
||||||
configValue: string,
|
configValue: string,
|
||||||
globalConfig?: boolean,
|
globalConfig?: boolean,
|
||||||
add?: boolean,
|
add?: boolean
|
||||||
configFile?: string
|
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
configExists(configKey: string, globalConfig?: boolean): Promise<boolean>
|
configExists(configKey: string, globalConfig?: boolean): Promise<boolean>
|
||||||
fetch(
|
fetch(
|
||||||
@@ -42,7 +41,6 @@ export interface IGitCommandManager {
|
|||||||
}
|
}
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
getDefaultBranch(repositoryUrl: string): Promise<string>
|
getDefaultBranch(repositoryUrl: string): Promise<string>
|
||||||
getSubmoduleConfigPaths(recursive: boolean): Promise<string[]>
|
|
||||||
getWorkingDirectory(): string
|
getWorkingDirectory(): string
|
||||||
init(): Promise<void>
|
init(): Promise<void>
|
||||||
isDetached(): Promise<boolean>
|
isDetached(): Promise<boolean>
|
||||||
@@ -61,24 +59,8 @@ export interface IGitCommandManager {
|
|||||||
tagExists(pattern: string): Promise<boolean>
|
tagExists(pattern: string): Promise<boolean>
|
||||||
tryClean(): Promise<boolean>
|
tryClean(): Promise<boolean>
|
||||||
tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean>
|
tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean>
|
||||||
tryConfigUnsetValue(
|
|
||||||
configKey: string,
|
|
||||||
configValue: string,
|
|
||||||
globalConfig?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
): Promise<boolean>
|
|
||||||
tryDisableAutomaticGarbageCollection(): Promise<boolean>
|
tryDisableAutomaticGarbageCollection(): Promise<boolean>
|
||||||
tryGetFetchUrl(): Promise<string>
|
tryGetFetchUrl(): Promise<string>
|
||||||
tryGetConfigValues(
|
|
||||||
configKey: string,
|
|
||||||
globalConfig?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
): Promise<string[]>
|
|
||||||
tryGetConfigKeys(
|
|
||||||
pattern: string,
|
|
||||||
globalConfig?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
): Promise<string[]>
|
|
||||||
tryReset(): Promise<boolean>
|
tryReset(): Promise<boolean>
|
||||||
version(): Promise<GitVersion>
|
version(): Promise<GitVersion>
|
||||||
}
|
}
|
||||||
@@ -241,15 +223,9 @@ class GitCommandManager {
|
|||||||
configKey: string,
|
configKey: string,
|
||||||
configValue: string,
|
configValue: string,
|
||||||
globalConfig?: boolean,
|
globalConfig?: boolean,
|
||||||
add?: boolean,
|
add?: boolean
|
||||||
configFile?: string
|
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const args: string[] = ['config']
|
const args: string[] = ['config', globalConfig ? '--global' : '--local']
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile)
|
|
||||||
} else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local')
|
|
||||||
}
|
|
||||||
if (add) {
|
if (add) {
|
||||||
args.push('--add')
|
args.push('--add')
|
||||||
}
|
}
|
||||||
@@ -347,21 +323,6 @@ class GitCommandManager {
|
|||||||
throw new Error('Unexpected output when retrieving default branch')
|
throw new Error('Unexpected output when retrieving default branch')
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSubmoduleConfigPaths(recursive: boolean): Promise<string[]> {
|
|
||||||
// Get submodule config file paths.
|
|
||||||
// Use `--show-origin` to get the config file path for each submodule.
|
|
||||||
const output = await this.submoduleForeach(
|
|
||||||
`git config --local --show-origin --name-only --get-regexp remote.origin.url`,
|
|
||||||
recursive
|
|
||||||
)
|
|
||||||
|
|
||||||
// Extract config file paths from the output (lines starting with "file:").
|
|
||||||
const configPaths =
|
|
||||||
output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || []
|
|
||||||
|
|
||||||
return configPaths
|
|
||||||
}
|
|
||||||
|
|
||||||
getWorkingDirectory(): string {
|
getWorkingDirectory(): string {
|
||||||
return this.workingDirectory
|
return this.workingDirectory
|
||||||
}
|
}
|
||||||
@@ -494,24 +455,6 @@ class GitCommandManager {
|
|||||||
return output.exitCode === 0
|
return output.exitCode === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
async tryConfigUnsetValue(
|
|
||||||
configKey: string,
|
|
||||||
configValue: string,
|
|
||||||
globalConfig?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
): Promise<boolean> {
|
|
||||||
const args = ['config']
|
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile)
|
|
||||||
} else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local')
|
|
||||||
}
|
|
||||||
args.push('--unset', configKey, configValue)
|
|
||||||
|
|
||||||
const output = await this.execGit(args, true)
|
|
||||||
return output.exitCode === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
async tryDisableAutomaticGarbageCollection(): Promise<boolean> {
|
async tryDisableAutomaticGarbageCollection(): Promise<boolean> {
|
||||||
const output = await this.execGit(
|
const output = await this.execGit(
|
||||||
['config', '--local', 'gc.auto', '0'],
|
['config', '--local', 'gc.auto', '0'],
|
||||||
@@ -538,56 +481,6 @@ class GitCommandManager {
|
|||||||
return stdout
|
return stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
async tryGetConfigValues(
|
|
||||||
configKey: string,
|
|
||||||
globalConfig?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
): Promise<string[]> {
|
|
||||||
const args = ['config']
|
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile)
|
|
||||||
} else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local')
|
|
||||||
}
|
|
||||||
args.push('--get-all', configKey)
|
|
||||||
|
|
||||||
const output = await this.execGit(args, true)
|
|
||||||
|
|
||||||
if (output.exitCode !== 0) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
return output.stdout
|
|
||||||
.trim()
|
|
||||||
.split('\n')
|
|
||||||
.filter(value => value.trim())
|
|
||||||
}
|
|
||||||
|
|
||||||
async tryGetConfigKeys(
|
|
||||||
pattern: string,
|
|
||||||
globalConfig?: boolean,
|
|
||||||
configFile?: string
|
|
||||||
): Promise<string[]> {
|
|
||||||
const args = ['config']
|
|
||||||
if (configFile) {
|
|
||||||
args.push('--file', configFile)
|
|
||||||
} else {
|
|
||||||
args.push(globalConfig ? '--global' : '--local')
|
|
||||||
}
|
|
||||||
args.push('--name-only', '--get-regexp', pattern)
|
|
||||||
|
|
||||||
const output = await this.execGit(args, true)
|
|
||||||
|
|
||||||
if (output.exitCode !== 0) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
return output.stdout
|
|
||||||
.trim()
|
|
||||||
.split('\n')
|
|
||||||
.filter(key => key.trim())
|
|
||||||
}
|
|
||||||
|
|
||||||
async tryReset(): Promise<boolean> {
|
async tryReset(): Promise<boolean> {
|
||||||
const output = await this.execGit(['reset', '--hard', 'HEAD'], true)
|
const output = await this.execGit(['reset', '--hard', 'HEAD'], true)
|
||||||
return output.exitCode === 0
|
return output.exitCode === 0
|
||||||
|
@@ -120,7 +120,7 @@ function updateUsage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateUsage(
|
updateUsage(
|
||||||
'actions/checkout@v5',
|
'actions/checkout@v4',
|
||||||
path.join(__dirname, '..', '..', 'action.yml'),
|
path.join(__dirname, '..', '..', 'action.yml'),
|
||||||
path.join(__dirname, '..', '..', 'README.md')
|
path.join(__dirname, '..', '..', 'README.md')
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user