Compare commits
246 Commits
bdehamer/m
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
6b63a2bfc3 | |
|
|
290017ff81 | |
|
|
2a876cd69d | |
|
|
f79b906406 | |
|
|
dcae869a03 | |
|
|
23769d04c7 | |
|
|
d3ab50471b | |
|
|
1388fd1cac | |
|
|
5b446d2657 | |
|
|
006d6978c1 | |
|
|
02afeb1577 | |
|
|
d47594b536 | |
|
|
2823824b94 | |
|
|
cbc06d6766 | |
|
|
9bb6708527 | |
|
|
be1151df02 | |
|
|
130842f4e8 | |
|
|
ab82301c62 | |
|
|
fea4f6b5c5 | |
|
|
d3ade9ecfc | |
|
|
fb592eec03 | |
|
|
70e79399a2 | |
|
|
acb230b99a | |
|
|
5e0fa1aaaa | |
|
|
ac2468e605 | |
|
|
3c8fcfce19 | |
|
|
45467b9199 | |
|
|
700a55077d | |
|
|
6fa8f07827 | |
|
|
d16e86a709 | |
|
|
ae3ac0db0c | |
|
|
b319d6afff | |
|
|
b8ac8fc14a | |
|
|
028d621193 | |
|
|
b0d901f9c2 | |
|
|
394e804dc8 | |
|
|
d402248c45 | |
|
|
66e8437b3e | |
|
|
9c7501a5f3 | |
|
|
3b4b5725f0 | |
|
|
9a364e607b | |
|
|
625c3f4856 | |
|
|
1c3a637017 | |
|
|
ec0ca1b19b | |
|
|
57cd003e61 | |
|
|
b5befc6c6d | |
|
|
88a490d2ce | |
|
|
a8d1fb0687 | |
|
|
347c887e54 | |
|
|
d5af54ee78 | |
|
|
44b9401378 | |
|
|
fb5ae2a0e0 | |
|
|
8024983ab0 | |
|
|
d44f9b8f13 | |
|
|
9b4ee219ef | |
|
|
ee5d8970ad | |
|
|
2874e3a741 | |
|
|
ad4afeeff1 | |
|
|
f9bdf6a054 | |
|
|
59c7ebde79 | |
|
|
0c907a43d3 | |
|
|
d1c1fc4108 | |
|
|
36f30e6d37 | |
|
|
308e05bc50 | |
|
|
33a9b6c09c | |
|
|
ddc5fa4ae8 | |
|
|
9b08f07cd3 | |
|
|
d26e9423f4 | |
|
|
714f93aedc | |
|
|
844423665b | |
|
|
f2ba502b92 | |
|
|
1db3130eb3 | |
|
|
ca8a35d78f | |
|
|
f7f057193f | |
|
|
8e146e124e | |
|
|
1ea77a84d7 | |
|
|
7da95b182e | |
|
|
7c689a5156 | |
|
|
8c6c662cda | |
|
|
3898ed70c4 | |
|
|
9a41b33065 | |
|
|
7aea3e735f | |
|
|
b1eb18b224 | |
|
|
48e42b1fdd | |
|
|
b738f10ef3 | |
|
|
8f32f385e0 | |
|
|
011f07d1dc | |
|
|
aa7077acfb | |
|
|
86207b5042 | |
|
|
523ce8ccda | |
|
|
f58042f9cc | |
|
|
091616a0b8 | |
|
|
8da1e670b6 | |
|
|
06f7fd9df1 | |
|
|
0fe20e9d56 | |
|
|
f82db4c00b | |
|
|
b8cca0c71f | |
|
|
6f0cb0c45e | |
|
|
944ede4d09 | |
|
|
227b1ce741 | |
|
|
447ee85f36 | |
|
|
a6be3de743 | |
|
|
26b94036cb | |
|
|
f3e6fb165e | |
|
|
3a607d0f00 | |
|
|
c9316bb4a7 | |
|
|
ec43e5810d | |
|
|
01715621b0 | |
|
|
6c64260c6d | |
|
|
bf3fc9226a | |
|
|
c6723084aa | |
|
|
bcb928642f | |
|
|
8c3fc9ed99 | |
|
|
1ef3214cee | |
|
|
ece2273b24 | |
|
|
717b895584 | |
|
|
8ff772deb1 | |
|
|
8a3652e16d | |
|
|
eb6226501b | |
|
|
d65ee66d9b | |
|
|
6d3feab2bf | |
|
|
79e1d8bb74 | |
|
|
a0907ed2e2 | |
|
|
bd54a2413a | |
|
|
89397db14b | |
|
|
d48d6b62a4 | |
|
|
bab3dcf7f3 | |
|
|
c51178a15e | |
|
|
bbc6082700 | |
|
|
cf3aaeb491 | |
|
|
cf4886cccb | |
|
|
0c5da92b52 | |
|
|
513216f1dd | |
|
|
3c90578c30 | |
|
|
be5a2ce677 | |
|
|
683703c114 | |
|
|
c28e7d4d5f | |
|
|
12e323ae30 | |
|
|
dbb1ea35ff | |
|
|
f31c2921c1 | |
|
|
41b3ce3141 | |
|
|
8d8a914a94 | |
|
|
36db4d62ad | |
|
|
a25b686a45 | |
|
|
957610a37a | |
|
|
6ed621e7d1 | |
|
|
8007c1c535 | |
|
|
6444290c57 | |
|
|
f32d6bc043 | |
|
|
2e4ab87130 | |
|
|
ef199a9ab0 | |
|
|
917a43eb6e | |
|
|
07cac0a6b3 | |
|
|
2046ee6d6b | |
|
|
2b476323c4 | |
|
|
aebe304a19 | |
|
|
e8f276a715 | |
|
|
d156bcaa78 | |
|
|
5ae4c5be28 | |
|
|
d50f1ac1b9 | |
|
|
87cb7035bb | |
|
|
1b1e81526b | |
|
|
525ebf0c50 | |
|
|
07341e11d8 | |
|
|
930c890727 | |
|
|
a410c4a9cf | |
|
|
10277d48ca | |
|
|
857c61a9df | |
|
|
c40bccc9c3 | |
|
|
ff4d4afef8 | |
|
|
4d4bbebd6a | |
|
|
261fcae498 | |
|
|
4059d2af66 | |
|
|
2559a2ac8a | |
|
|
514314311c | |
|
|
957d42e6c5 | |
|
|
39419dd8c3 | |
|
|
d13e6311f1 | |
|
|
6876e2a664 | |
|
|
fc482662af | |
|
|
abd9054c61 | |
|
|
253e837c4d | |
|
|
3ac34ffcb7 | |
|
|
56c5a39afb | |
|
|
7ae578ddd1 | |
|
|
b2d2270685 | |
|
|
0d1d5c7687 | |
|
|
769bb0fea1 | |
|
|
d7ddca4309 | |
|
|
8780507298 | |
|
|
790c56665a | |
|
|
9d8017eadb | |
|
|
20fee3ea63 | |
|
|
7501423b6f | |
|
|
d0cc3418ea | |
|
|
5007821c77 | |
|
|
47c4fa85df | |
|
|
1cd2f8a538 | |
|
|
b85d4e6b38 | |
|
|
dc22dc7cad | |
|
|
8c05dc87d8 | |
|
|
884aa17886 | |
|
|
944e6b78db | |
|
|
d70fb49aaa | |
|
|
3726c11433 | |
|
|
71b40f7024 | |
|
|
83e5e2517b | |
|
|
d5c8a0fa27 | |
|
|
780e24be34 | |
|
|
ec9716b3cc | |
|
|
0bc338adab | |
|
|
5378ea8eca | |
|
|
b95b593ca5 | |
|
|
4fedf471b1 | |
|
|
1b9063ee0e | |
|
|
d096588f08 | |
|
|
662b9d91f5 | |
|
|
a62f530b6f | |
|
|
2995cdf0a1 | |
|
|
f10f9c8217 | |
|
|
c26e6f3aba | |
|
|
2b08dc18f2 | |
|
|
412108cd55 | |
|
|
8fcec1fb58 | |
|
|
95e747361e | |
|
|
aad39a371f | |
|
|
7fe619c58c | |
|
|
e6fb8f1c5d | |
|
|
6a942b304d | |
|
|
340a6b15b5 | |
|
|
e0c069db55 | |
|
|
1f7c2c79e0 | |
|
|
5e8c25d1f5 | |
|
|
3095d112ef | |
|
|
16ef1448d7 | |
|
|
e55409315f | |
|
|
d4385a64a7 | |
|
|
ede05b95d7 | |
|
|
f3c12d5561 | |
|
|
adb9c4a7f4 | |
|
|
01f21badd5 | |
|
|
26f8f84a96 | |
|
|
433f76091b | |
|
|
4426b4ea91 | |
|
|
f522fdf89d | |
|
|
1e0c16f0dc |
|
|
@ -0,0 +1,27 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/packages/artifact"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
# Group minor and patch updates together but keep major separate
|
||||
artifact-minor-patch:
|
||||
update-types:
|
||||
- "minor"
|
||||
- "patch"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/packages/cache"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
# Group minor and patch updates together but keep major separate
|
||||
cache-minor-patch:
|
||||
update-types:
|
||||
- "minor"
|
||||
- "patch"
|
||||
|
|
@ -22,12 +22,12 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set Node.js 20.x
|
||||
uses: actions/setup-node@v4
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 24.x
|
||||
|
||||
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
|
||||
# without these to just compile the artifacts package
|
||||
|
|
@ -47,7 +47,7 @@ jobs:
|
|||
echo -n 'hello from file 2' > artifact-path/second.txt
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const {default: artifact} = require('./packages/artifact/lib/artifact')
|
||||
|
|
@ -77,12 +77,12 @@ jobs:
|
|||
needs: [upload]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set Node.js 20.x
|
||||
uses: actions/setup-node@v4
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 24.x
|
||||
|
||||
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
|
||||
# without these to just compile the artifacts package
|
||||
|
|
@ -96,7 +96,7 @@ jobs:
|
|||
working-directory: packages/artifact
|
||||
|
||||
- name: List and Download Artifacts
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const {default: artifactClient} = require('./packages/artifact/lib/artifact')
|
||||
|
|
@ -165,7 +165,7 @@ jobs:
|
|||
}
|
||||
}
|
||||
- name: Delete Artifacts
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const {default: artifactClient} = require('./packages/artifact/lib/artifact')
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set Node.js 20.x
|
||||
uses: actions/setup-node@v4
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 24.x
|
||||
|
||||
- name: npm install
|
||||
run: npm install
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set Node.js 20.x
|
||||
uses: actions/setup-node@v4
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 24.x
|
||||
|
||||
# In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the
|
||||
# node context. This runs a local action that gets and sets the necessary env variables that are needed
|
||||
|
|
@ -39,9 +39,11 @@ jobs:
|
|||
- name: Install root npm packages
|
||||
run: npm ci
|
||||
|
||||
# We need to install only runtime dependencies (omit dev dependencies) to verify that what we're shipping is all
|
||||
# that is needed
|
||||
- name: Compile cache package
|
||||
run: |
|
||||
npm ci
|
||||
npm ci --omit=dev
|
||||
npm run tsc
|
||||
working-directory: packages/cache
|
||||
|
||||
|
|
|
|||
|
|
@ -17,16 +17,16 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- shell: bash
|
||||
run: |
|
||||
rm "C:\Program Files\Git\usr\bin\tar.exe"
|
||||
|
||||
- name: Set Node.js 20.x
|
||||
uses: actions/setup-node@v1
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 24.x
|
||||
|
||||
# In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the
|
||||
# node context. This runs a local action that gets and sets the necessary env variables that are needed
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
|
|
|||
|
|
@ -6,8 +6,21 @@ on:
|
|||
workflow_dispatch:
|
||||
inputs:
|
||||
package:
|
||||
type: choice
|
||||
required: true
|
||||
description: 'core, artifact, cache, exec, github, glob, http-client, io, tool-cache, attest'
|
||||
description: 'Which package to release'
|
||||
options:
|
||||
- artifact
|
||||
- attest
|
||||
- cache
|
||||
- core
|
||||
- exec
|
||||
- github
|
||||
- glob
|
||||
- http-client
|
||||
- io
|
||||
- tool-cache
|
||||
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
|
@ -15,15 +28,15 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: setup repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: verify package exists
|
||||
run: ls packages/${{ github.event.inputs.package }}
|
||||
|
||||
- name: Set Node.js 20.x
|
||||
uses: actions/setup-node@v4
|
||||
- name: Set Node.js 24.x
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 24.x
|
||||
|
||||
- name: npm install
|
||||
run: npm install
|
||||
|
|
|
|||
|
|
@ -18,19 +18,19 @@ jobs:
|
|||
matrix:
|
||||
runs-on: [ubuntu-latest, macos-latest-large, windows-latest]
|
||||
|
||||
# Node 18 is the current default Node version in hosted runners, so users may still use the toolkit with it when running tests (see https://github.com/actions/toolkit/issues/1841)
|
||||
# Node 20 is the currently support Node version for actions - https://docs.github.com/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runsusing-for-javascript-actions
|
||||
node-version: [18.x, 20.x]
|
||||
# Node 20 is the currently supported stable Node version for actions - https://docs.github.com/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runsusing-for-javascript-actions
|
||||
# Node 24 is the new version being added with support in actions runners
|
||||
node-version: [20.x, 24.x]
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
if: ${{ github.repository_owner == 'actions' }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
- name: Update Octokit
|
||||
working-directory: packages/github
|
||||
run: |
|
||||
|
|
|
|||
38
README.md
38
README.md
|
|
@ -24,7 +24,7 @@ The GitHub Actions ToolKit provides a set of packages to make creating actions e
|
|||
Provides functions for inputs, outputs, results, logging, secrets and variables. Read more [here](packages/core)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/core
|
||||
npm install @actions/core
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ $ npm install @actions/core
|
|||
Provides functions to exec cli tools and process output. Read more [here](packages/exec)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/exec
|
||||
npm install @actions/exec
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ $ npm install @actions/exec
|
|||
Provides functions to search for files matching glob patterns. Read more [here](packages/glob)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/glob
|
||||
npm install @actions/glob
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ $ npm install @actions/glob
|
|||
A lightweight HTTP client optimized for building actions. Read more [here](packages/http-client)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/http-client
|
||||
npm install @actions/http-client
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ $ npm install @actions/http-client
|
|||
Provides disk i/o functions like cp, mv, rmRF, which etc. Read more [here](packages/io)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/io
|
||||
npm install @actions/io
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ Provides functions for downloading and caching tools. e.g. setup-* actions. Rea
|
|||
See @actions/cache for caching workflow dependencies.
|
||||
|
||||
```bash
|
||||
$ npm install @actions/tool-cache
|
||||
npm install @actions/tool-cache
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ $ npm install @actions/tool-cache
|
|||
Provides an Octokit client hydrated with the context that the current action is being run in. Read more [here](packages/github)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/github
|
||||
npm install @actions/github
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ $ npm install @actions/github
|
|||
Provides functions to interact with actions artifacts. Read more [here](packages/artifact)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/artifact
|
||||
npm install @actions/artifact
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ $ npm install @actions/artifact
|
|||
Provides functions to cache dependencies and build outputs to improve workflow execution time. Read more [here](packages/cache)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/cache
|
||||
npm install @actions/cache
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ $ npm install @actions/cache
|
|||
Provides functions to write attestations for workflow artifacts. Read more [here](packages/attest)
|
||||
|
||||
```bash
|
||||
$ npm install @actions/attest
|
||||
npm install @actions/attest
|
||||
```
|
||||
<br/>
|
||||
|
||||
|
|
@ -227,9 +227,23 @@ console.log(`We can even get context data, like the repo: ${context.repo.repo}`)
|
|||
```
|
||||
<br/>
|
||||
|
||||
## Contributing
|
||||
## Note
|
||||
|
||||
We welcome contributions. See [how to contribute](.github/CONTRIBUTING.md).
|
||||
Thank you for your interest in this GitHub repo, 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.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
os: [ubuntu-16.04, windows-2019]
|
||||
runs-on: ${{matrix.os}}
|
||||
actions:
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
version: ${{matrix.node}}
|
||||
- run: |
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ e.g. To use https://github.com/actions/setup-node, users will author:
|
|||
|
||||
```yaml
|
||||
steps:
|
||||
using: actions/setup-node@v4
|
||||
using: actions/setup-node@v5
|
||||
```
|
||||
|
||||
# Define Metadata
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "root",
|
||||
"private": true,
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"audit-all": "lerna run audit-moderate",
|
||||
"bootstrap": "lerna exec -- npm install",
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.4",
|
||||
"@types/node": "^20.5.7",
|
||||
"@types/node": "^24.1.0",
|
||||
"@types/signale": "^1.4.1",
|
||||
"concurrently": "^6.1.0",
|
||||
"eslint": "^8.0.1",
|
||||
|
|
@ -32,5 +32,19 @@
|
|||
"prettier": "^3.0.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"overrides": {
|
||||
"semver": "^7.6.0",
|
||||
"tar": "^6.2.1",
|
||||
"@octokit/plugin-paginate-rest": "^9.2.2",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@octokit/core": "^5.0.3",
|
||||
"tmp": "^0.2.4",
|
||||
"@types/node": "^24.1.0",
|
||||
"brace-expansion": "^2.0.2",
|
||||
"form-data": "^4.0.4",
|
||||
"uri-js": "npm:uri-js-replace@^1.0.1",
|
||||
"node-fetch": "^3.3.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -41,3 +41,4 @@ Any easy way to test changes for the official upload/download actions is to fork
|
|||
1. In the locally cloned fork, link to your local toolkit changes: `npm link @actions/artifact`
|
||||
2. Then, compile your changes with: `npm run release`. The local `dist/index.js` should be updated with your changes.
|
||||
3. Commit and push to your fork, you can then test with a `uses:` in your workflow pointed at your fork.
|
||||
4. The format for the above is `<username>/<repository-name>/@<ref>`, i.e. `me/myrepo/@HEAD`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,41 @@
|
|||
# @actions/artifact Releases
|
||||
|
||||
### 4.0.0
|
||||
|
||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||
- Fix: artifact pagination bugs and configurable artifact count limits [#2165](https://github.com/actions/toolkit/pull/2165)
|
||||
- Fix: reject the promise on timeout [#2124](https://github.com/actions/toolkit/pull/2124)
|
||||
- Update dependency versions
|
||||
|
||||
### 2.3.3
|
||||
|
||||
- Dependency updates [#2049](https://github.com/actions/toolkit/pull/2049)
|
||||
|
||||
### 2.3.2
|
||||
|
||||
- Added masking for Shared Access Signature (SAS) artifact URLs [#1982](https://github.com/actions/toolkit/pull/1982)
|
||||
- Change hash to digest for consistent terminology across runner logs [#1991](https://github.com/actions/toolkit/pull/1991)
|
||||
|
||||
### 2.3.1
|
||||
|
||||
- Fix comment typo on expectedHash. [#1986](https://github.com/actions/toolkit/pull/1986)
|
||||
|
||||
### 2.3.0
|
||||
|
||||
- Allow ArtifactClient to perform digest comparisons, if supplied. [#1975](https://github.com/actions/toolkit/pull/1975)
|
||||
|
||||
### 2.2.2
|
||||
|
||||
- Default concurrency to 5 for uploading artifacts [#1962](https://github.com/actions/toolkit/pull/1962)
|
||||
|
||||
### 2.2.1
|
||||
|
||||
- Add `ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY` and `ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS` environment variables [#1928](https://github.com/actions/toolkit/pull/1928)
|
||||
|
||||
### 2.2.0
|
||||
|
||||
- Return artifact digest on upload [#1896](https://github.com/actions/toolkit/pull/1896)
|
||||
|
||||
### 2.1.11
|
||||
|
||||
- Fixed a bug with relative symlinks resolution [#1844](https://github.com/actions/toolkit/pull/1844)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
import * as config from '../src/internal/shared/config'
|
||||
import os from 'os'
|
||||
|
||||
// Mock the `cpus()` function in the `os` module
|
||||
jest.mock('os', () => {
|
||||
const osActual = jest.requireActual('os')
|
||||
return {
|
||||
...osActual,
|
||||
cpus: jest.fn()
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules()
|
||||
|
|
@ -30,3 +40,110 @@ describe('isGhes', () => {
|
|||
expect(config.isGhes()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('uploadChunkTimeoutEnv', () => {
|
||||
it('should return default 300000 when no env set', () => {
|
||||
expect(config.getUploadChunkTimeout()).toBe(300000)
|
||||
})
|
||||
|
||||
it('should return value set in ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS', () => {
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS = '150000'
|
||||
expect(config.getUploadChunkTimeout()).toBe(150000)
|
||||
})
|
||||
|
||||
it('should throw if value set in ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS is invalid', () => {
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS = 'abc'
|
||||
expect(() => {
|
||||
config.getUploadChunkTimeout()
|
||||
}).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('uploadConcurrencyEnv', () => {
|
||||
it('Concurrency default to 5', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
|
||||
expect(config.getConcurrency()).toBe(5)
|
||||
})
|
||||
|
||||
it('Concurrency max out at 300 on systems with many CPUs', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(32))
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '301'
|
||||
expect(config.getConcurrency()).toBe(300)
|
||||
})
|
||||
|
||||
it('Concurrency can be set to 32 when cpu num is <= 4', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '32'
|
||||
expect(config.getConcurrency()).toBe(32)
|
||||
})
|
||||
|
||||
it('Concurrency can be set 16 * num of cpu when cpu num is > 4', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(6))
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '96'
|
||||
expect(config.getConcurrency()).toBe(96)
|
||||
})
|
||||
|
||||
it('Concurrency can be overridden by env var ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '10'
|
||||
expect(config.getConcurrency()).toBe(10)
|
||||
})
|
||||
|
||||
it('should throw with invalid value of ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = 'abc'
|
||||
expect(() => {
|
||||
config.getConcurrency()
|
||||
}).toThrow()
|
||||
})
|
||||
|
||||
it('should throw if ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY is < 1', () => {
|
||||
;(os.cpus as jest.Mock).mockReturnValue(new Array(4))
|
||||
process.env.ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY = '0'
|
||||
expect(() => {
|
||||
config.getConcurrency()
|
||||
}).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getMaxArtifactListCount', () => {
|
||||
beforeEach(() => {
|
||||
delete process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
|
||||
})
|
||||
|
||||
it('should return default 1000 when no env set', () => {
|
||||
expect(config.getMaxArtifactListCount()).toBe(1000)
|
||||
})
|
||||
|
||||
it('should return value set in ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT', () => {
|
||||
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '2000'
|
||||
expect(config.getMaxArtifactListCount()).toBe(2000)
|
||||
})
|
||||
|
||||
it('should throw if value set in ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT is invalid', () => {
|
||||
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = 'abc'
|
||||
expect(() => {
|
||||
config.getMaxArtifactListCount()
|
||||
}).toThrow(
|
||||
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
|
||||
)
|
||||
})
|
||||
|
||||
it('should throw if ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT is < 1', () => {
|
||||
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '0'
|
||||
expect(() => {
|
||||
config.getMaxArtifactListCount()
|
||||
}).toThrow(
|
||||
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
|
||||
)
|
||||
})
|
||||
|
||||
it('should throw if ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT is negative', () => {
|
||||
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '-100'
|
||||
expect(() => {
|
||||
config.getMaxArtifactListCount()
|
||||
}).toThrow(
|
||||
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -111,6 +111,16 @@ const mockGetArtifactSuccess = jest.fn(() => {
|
|||
}
|
||||
})
|
||||
|
||||
const mockGetArtifactHung = jest.fn(() => {
|
||||
const message = new http.IncomingMessage(new net.Socket())
|
||||
message.statusCode = 200
|
||||
// Don't push any data or call push(null) to end the stream
|
||||
// This creates a stream that hangs and never completes
|
||||
return {
|
||||
message
|
||||
}
|
||||
})
|
||||
|
||||
const mockGetArtifactFailure = jest.fn(() => {
|
||||
const message = new http.IncomingMessage(new net.Socket())
|
||||
message.statusCode = 500
|
||||
|
|
@ -319,14 +329,6 @@ describe('download-artifact', () => {
|
|||
|
||||
const mockGet = jest.fn(async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Resolve with a 200 status code immediately
|
||||
resolve({
|
||||
message: msg,
|
||||
readBody: async () => {
|
||||
return Promise.resolve(`{"ok": true}`)
|
||||
}
|
||||
})
|
||||
|
||||
// Reject with an error after 31 seconds
|
||||
setTimeout(() => {
|
||||
reject(new Error('Request timeout'))
|
||||
|
|
@ -619,4 +621,32 @@ describe('download-artifact', () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('streamExtractExternal', () => {
|
||||
it('should fail if the timeout is exceeded', async () => {
|
||||
const mockSlowGetArtifact = jest.fn(mockGetArtifactHung)
|
||||
|
||||
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||
() => {
|
||||
return {
|
||||
get: mockSlowGetArtifact
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
try {
|
||||
await streamExtractExternal(
|
||||
fixtures.blobStorageUrl,
|
||||
fixtures.workspaceDir,
|
||||
{timeout: 2}
|
||||
)
|
||||
expect(true).toBe(false) // should not be called
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(Error)
|
||||
expect(e.message).toContain('did not respond in 2ms')
|
||||
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||
expect(mockSlowGetArtifact).toHaveBeenCalledTimes(1)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import * as github from '@actions/github'
|
||||
import type {RestEndpointMethods} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/method-types'
|
||||
import type {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/parameters-and-response-types'
|
||||
import {
|
||||
listArtifactsInternal,
|
||||
|
|
@ -10,13 +9,13 @@ import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
|
|||
import * as util from '../src/internal/shared/util'
|
||||
import {noopLogs} from './common'
|
||||
import {Artifact} from '../src/internal/shared/interfaces'
|
||||
import {RequestInterface} from '@octokit/types'
|
||||
|
||||
type MockedListWorkflowRunArtifacts = jest.MockedFunction<
|
||||
RestEndpointMethods['actions']['listWorkflowRunArtifacts']
|
||||
>
|
||||
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
||||
|
||||
jest.mock('@actions/github', () => ({
|
||||
getOctokit: jest.fn().mockReturnValue({
|
||||
request: jest.fn(),
|
||||
rest: {
|
||||
actions: {
|
||||
listWorkflowRunArtifacts: jest.fn()
|
||||
|
|
@ -81,10 +80,10 @@ describe('list-artifact', () => {
|
|||
|
||||
describe('public', () => {
|
||||
it('should return a list of artifacts', async () => {
|
||||
const mockListArtifacts = github.getOctokit(fixtures.token).rest.actions
|
||||
.listWorkflowRunArtifacts as MockedListWorkflowRunArtifacts
|
||||
const mockRequest = github.getOctokit(fixtures.token)
|
||||
.request as MockedRequest
|
||||
|
||||
mockListArtifacts.mockResolvedValueOnce({
|
||||
mockRequest.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
|
|
@ -105,10 +104,10 @@ describe('list-artifact', () => {
|
|||
})
|
||||
|
||||
it('should return the latest artifact when latest is specified', async () => {
|
||||
const mockListArtifacts = github.getOctokit(fixtures.token).rest.actions
|
||||
.listWorkflowRunArtifacts as MockedListWorkflowRunArtifacts
|
||||
const mockRequest = github.getOctokit(fixtures.token)
|
||||
.request as MockedRequest
|
||||
|
||||
mockListArtifacts.mockResolvedValueOnce({
|
||||
mockRequest.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
|
|
@ -129,10 +128,10 @@ describe('list-artifact', () => {
|
|||
})
|
||||
|
||||
it('can return empty artifacts', async () => {
|
||||
const mockListArtifacts = github.getOctokit(fixtures.token).rest.actions
|
||||
.listWorkflowRunArtifacts as MockedListWorkflowRunArtifacts
|
||||
const mockRequest = github.getOctokit(fixtures.token)
|
||||
.request as MockedRequest
|
||||
|
||||
mockListArtifacts.mockResolvedValueOnce({
|
||||
mockRequest.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
|
|
@ -156,10 +155,10 @@ describe('list-artifact', () => {
|
|||
})
|
||||
|
||||
it('should fail if non-200 response', async () => {
|
||||
const mockListArtifacts = github.getOctokit(fixtures.token).rest.actions
|
||||
.listWorkflowRunArtifacts as MockedListWorkflowRunArtifacts
|
||||
const mockRequest = github.getOctokit(fixtures.token)
|
||||
.request as MockedRequest
|
||||
|
||||
mockListArtifacts.mockRejectedValue(new Error('boom'))
|
||||
mockRequest.mockRejectedValueOnce(new Error('boom'))
|
||||
|
||||
await expect(
|
||||
listArtifactsPublic(
|
||||
|
|
@ -171,6 +170,126 @@ describe('list-artifact', () => {
|
|||
)
|
||||
).rejects.toThrow('boom')
|
||||
})
|
||||
|
||||
it('should handle pagination correctly when fetching multiple pages', async () => {
|
||||
const mockRequest = github.getOctokit(fixtures.token)
|
||||
.request as MockedRequest
|
||||
|
||||
const manyArtifacts = Array.from({length: 150}, (_, i) => ({
|
||||
id: i + 1,
|
||||
name: `artifact-${i + 1}`,
|
||||
size: 100,
|
||||
createdAt: new Date('2023-12-01')
|
||||
}))
|
||||
|
||||
mockRequest
|
||||
.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
data: {
|
||||
...artifactsToListResponse(manyArtifacts.slice(0, 100)),
|
||||
total_count: 150
|
||||
}
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
data: {
|
||||
...artifactsToListResponse(manyArtifacts.slice(100, 150)),
|
||||
total_count: 150
|
||||
}
|
||||
})
|
||||
|
||||
const response = await listArtifactsPublic(
|
||||
fixtures.runId,
|
||||
fixtures.owner,
|
||||
fixtures.repo,
|
||||
fixtures.token,
|
||||
false
|
||||
)
|
||||
|
||||
// Verify that both API calls were made
|
||||
expect(mockRequest).toHaveBeenCalledTimes(2)
|
||||
|
||||
// Should return all 150 artifacts across both pages
|
||||
expect(response.artifacts).toHaveLength(150)
|
||||
|
||||
// Verify we got artifacts from both pages
|
||||
expect(response.artifacts[0].name).toBe('artifact-1')
|
||||
expect(response.artifacts[99].name).toBe('artifact-100')
|
||||
expect(response.artifacts[100].name).toBe('artifact-101')
|
||||
expect(response.artifacts[149].name).toBe('artifact-150')
|
||||
})
|
||||
|
||||
it('should respect ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT environment variable', async () => {
|
||||
const originalEnv = process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
|
||||
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = '150'
|
||||
|
||||
jest.resetModules()
|
||||
|
||||
try {
|
||||
const {listArtifactsPublic: listArtifactsPublicReloaded} = await import(
|
||||
'../src/internal/find/list-artifacts'
|
||||
)
|
||||
const githubReloaded = await import('@actions/github')
|
||||
|
||||
const mockRequest = (githubReloaded.getOctokit as jest.Mock)(
|
||||
fixtures.token
|
||||
).request as MockedRequest
|
||||
|
||||
const manyArtifacts = Array.from({length: 200}, (_, i) => ({
|
||||
id: i + 1,
|
||||
name: `artifact-${i + 1}`,
|
||||
size: 100,
|
||||
createdAt: new Date('2023-12-01')
|
||||
}))
|
||||
|
||||
mockRequest
|
||||
.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
data: {
|
||||
...artifactsToListResponse(manyArtifacts.slice(0, 100)),
|
||||
total_count: 200
|
||||
}
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
headers: {},
|
||||
url: '',
|
||||
data: {
|
||||
...artifactsToListResponse(manyArtifacts.slice(100, 150)),
|
||||
total_count: 200
|
||||
}
|
||||
})
|
||||
|
||||
const response = await listArtifactsPublicReloaded(
|
||||
fixtures.runId,
|
||||
fixtures.owner,
|
||||
fixtures.repo,
|
||||
fixtures.token,
|
||||
false
|
||||
)
|
||||
|
||||
// Should only return 150 artifacts due to the limit
|
||||
expect(response.artifacts).toHaveLength(150)
|
||||
expect(response.artifacts[0].name).toBe('artifact-1')
|
||||
expect(response.artifacts[149].name).toBe('artifact-150')
|
||||
} finally {
|
||||
// Restore original environment variable
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT = originalEnv
|
||||
} else {
|
||||
delete process.env.ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT
|
||||
}
|
||||
|
||||
// Reset modules again to restore original state
|
||||
jest.resetModules()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('internal', () => {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ describe('upload-artifact', () => {
|
|||
fixtures.files.map(file => ({
|
||||
sourcePath: path.join(fixtures.uploadDirectory, file.name),
|
||||
destinationPath: file.name,
|
||||
stats: new fs.Stats()
|
||||
stats: fs.statSync(path.join(fixtures.uploadDirectory, file.name))
|
||||
}))
|
||||
)
|
||||
jest.spyOn(config, 'getRuntimeToken').mockReturnValue(fixtures.runtimeToken)
|
||||
|
|
@ -281,7 +281,7 @@ describe('upload-artifact', () => {
|
|||
}
|
||||
)
|
||||
|
||||
const {id, size} = await uploadArtifact(
|
||||
const {id, size, digest} = await uploadArtifact(
|
||||
fixtures.inputs.artifactName,
|
||||
fixtures.files.map(file =>
|
||||
path.join(fixtures.uploadDirectory, file.name)
|
||||
|
|
@ -291,6 +291,8 @@ describe('upload-artifact', () => {
|
|||
|
||||
expect(id).toBe(1)
|
||||
expect(size).toBe(loadedBytes)
|
||||
expect(digest).toBeDefined()
|
||||
expect(digest).toHaveLength(64)
|
||||
|
||||
const extractedDirectory = path.join(
|
||||
fixtures.uploadDirectory,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import * as config from '../src/internal/shared/config'
|
||||
import * as util from '../src/internal/shared/util'
|
||||
import {maskSigUrl, maskSecretUrls} from '../src/internal/shared/util'
|
||||
import {setSecret, debug} from '@actions/core'
|
||||
|
||||
export const testRuntimeToken =
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwic2NwIjoiQWN0aW9ucy5FeGFtcGxlIEFjdGlvbnMuQW5vdGhlckV4YW1wbGU6dGVzdCBBY3Rpb25zLlJlc3VsdHM6Y2U3ZjU0YzctNjFjNy00YWFlLTg4N2YtMzBkYTQ3NWY1ZjFhOmNhMzk1MDg1LTA0MGEtNTI2Yi0yY2U4LWJkYzg1ZjY5Mjc3NCIsImlhdCI6MTUxNjIzOTAyMn0.XYnI_wHPBlUi1mqYveJnnkJhp4dlFjqxzRmISPsqfw8'
|
||||
|
|
@ -59,3 +61,159 @@ describe('get-backend-ids-from-token', () => {
|
|||
)
|
||||
})
|
||||
})
|
||||
|
||||
jest.mock('@actions/core')
|
||||
|
||||
describe('maskSigUrl', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('does nothing if no sig parameter is present', () => {
|
||||
const url = 'https://example.com'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('masks the sig parameter in the middle of the URL and sets it as a secret', () => {
|
||||
const url = 'https://example.com/?param1=value1&sig=12345¶m2=value2'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('12345')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('12345'))
|
||||
})
|
||||
|
||||
it('does nothing if the URL is empty', () => {
|
||||
const url = ''
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('handles URLs with fragments', () => {
|
||||
const url = 'https://example.com?sig=12345#fragment'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('12345')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('12345'))
|
||||
})
|
||||
})
|
||||
|
||||
describe('maskSigUrl handles special characters in signatures', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('handles signatures with slashes', () => {
|
||||
const url = 'https://example.com/?sig=abc/123'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc/123')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%2F123')
|
||||
})
|
||||
|
||||
it('handles signatures with plus signs', () => {
|
||||
const url = 'https://example.com/?sig=abc+123'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc 123')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%20123')
|
||||
})
|
||||
|
||||
it('handles signatures with equals signs', () => {
|
||||
const url = 'https://example.com/?sig=abc=123'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc=123')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%3D123')
|
||||
})
|
||||
|
||||
it('handles already percent-encoded signatures', () => {
|
||||
const url = 'https://example.com/?sig=abc%2F123%3D'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc/123=')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%2F123%3D')
|
||||
})
|
||||
|
||||
it('handles complex Azure SAS signatures', () => {
|
||||
const url =
|
||||
'https://example.com/container/file.txt?sig=nXyQIUj%2F%2F06Cxt80pBRYiiJlYqtPYg5sz%2FvEh5iHAhw%3D&se=2023-12-31'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith(
|
||||
'nXyQIUj//06Cxt80pBRYiiJlYqtPYg5sz/vEh5iHAhw='
|
||||
)
|
||||
expect(setSecret).toHaveBeenCalledWith(
|
||||
'nXyQIUj%2F%2F06Cxt80pBRYiiJlYqtPYg5sz%2FvEh5iHAhw%3D'
|
||||
)
|
||||
})
|
||||
|
||||
it('handles signatures with multiple special characters', () => {
|
||||
const url = 'https://example.com/?sig=a/b+c=d&e=f'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('a/b c=d')
|
||||
expect(setSecret).toHaveBeenCalledWith('a%2Fb%20c%3Dd')
|
||||
})
|
||||
})
|
||||
|
||||
describe('maskSecretUrls', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('masks sig parameters in signed_upload_url and signed_url', () => {
|
||||
const body = {
|
||||
signed_upload_url: 'https://upload.com?sig=upload123',
|
||||
signed_url: 'https://download.com?sig=download123'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).toHaveBeenCalledWith('upload123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('upload123'))
|
||||
expect(setSecret).toHaveBeenCalledWith('download123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('download123'))
|
||||
})
|
||||
|
||||
it('handles case where only upload_url is present', () => {
|
||||
const body = {
|
||||
signed_upload_url: 'https://upload.com?sig=upload123'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).toHaveBeenCalledWith('upload123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('upload123'))
|
||||
})
|
||||
|
||||
it('handles case where only download_url is present', () => {
|
||||
const body = {
|
||||
signed_url: 'https://download.com?sig=download123'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).toHaveBeenCalledWith('download123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('download123'))
|
||||
})
|
||||
|
||||
it('handles case where URLs do not contain sig parameters', () => {
|
||||
const body = {
|
||||
signed_upload_url: 'https://upload.com?token=abc',
|
||||
signed_url: 'https://download.com?token=xyz'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('handles empty string URLs', () => {
|
||||
const body = {
|
||||
signed_upload_url: '',
|
||||
signed_url: ''
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('does nothing if body is not an object or is null', () => {
|
||||
maskSecretUrls(null)
|
||||
expect(debug).toHaveBeenCalledWith('body is not an object or is null')
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('does nothing if signed_upload_url and signed_url are not strings', () => {
|
||||
const body = {
|
||||
signed_upload_url: 123,
|
||||
signed_url: 456
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -40,4 +40,4 @@
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/artifact.ts:7](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/artifact.ts#L7)
|
||||
[src/artifact.ts:7](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/artifact.ts#L7)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:24](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L24)
|
||||
[src/internal/shared/errors.ts:24](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L24)
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ single DeleteArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:248](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L248)
|
||||
[src/internal/client.ts:248](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L248)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ single DownloadArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:138](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L138)
|
||||
[src/internal/client.ts:138](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L138)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ If there are multiple artifacts with the same name in the same workflow run this
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:212](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L212)
|
||||
[src/internal/client.ts:212](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L212)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ ListArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:176](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L176)
|
||||
[src/internal/client.ts:176](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L176)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -190,4 +190,4 @@ single UploadArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:113](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L113)
|
||||
[src/internal/client.ts:113](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L113)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:4](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L4)
|
||||
[src/internal/shared/errors.ts:4](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L4)
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:2](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L2)
|
||||
[src/internal/shared/errors.ts:2](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L2)
|
||||
|
||||
___
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:31](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L31)
|
||||
[src/internal/shared/errors.ts:31](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L31)
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:17](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L17)
|
||||
[src/internal/shared/errors.ts:17](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L17)
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:42](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L42)
|
||||
[src/internal/shared/errors.ts:42](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L42)
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:40](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L40)
|
||||
[src/internal/shared/errors.ts:40](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L40)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -198,4 +198,4 @@ ___
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:49](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L49)
|
||||
[src/internal/shared/errors.ts:49](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L49)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ Error.constructor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:62](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L62)
|
||||
[src/internal/shared/errors.ts:62](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L62)
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
@ -181,4 +181,4 @@ ___
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/errors.ts:68](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/errors.ts#L68)
|
||||
[src/internal/shared/errors.ts:68](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/errors.ts#L68)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ The time when the artifact was created
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:123](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L123)
|
||||
[src/internal/shared/interfaces.ts:128](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L128)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ The ID of the artifact
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:113](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L113)
|
||||
[src/internal/shared/interfaces.ts:118](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L118)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ The name of the artifact
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:108](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L108)
|
||||
[src/internal/shared/interfaces.ts:113](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L113)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -59,4 +59,4 @@ The size of the artifact in bytes
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:118](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L118)
|
||||
[src/internal/shared/interfaces.ts:123](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L123)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ single DeleteArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:103](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L103)
|
||||
[src/internal/client.ts:103](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L103)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ single DownloadArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:89](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L89)
|
||||
[src/internal/client.ts:89](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L89)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ If there are multiple artifacts with the same name in the same workflow run this
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:75](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L75)
|
||||
[src/internal/client.ts:75](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L75)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ ListArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:57](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L57)
|
||||
[src/internal/client.ts:57](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L57)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -156,4 +156,4 @@ single UploadArtifactResponse object
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/client.ts:40](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/client.ts#L40)
|
||||
[src/internal/client.ts:40](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/client.ts#L40)
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ The id of the artifact that was deleted
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:158](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L158)
|
||||
[src/internal/shared/interfaces.ts:163](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L163)
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ Denotes where the artifact will be downloaded to. If not specified then the arti
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:98](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L98)
|
||||
[src/internal/shared/interfaces.ts:103](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L103)
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ The path where the artifact was downloaded to
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:88](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L88)
|
||||
[src/internal/shared/interfaces.ts:93](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L93)
|
||||
|
|
|
|||
|
|
@ -27,4 +27,4 @@ The criteria for finding Artifact(s) out of the scope of the current run.
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:131](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L131)
|
||||
[src/internal/shared/interfaces.ts:136](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L136)
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ Metadata about the artifact that was found
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:57](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L57)
|
||||
[src/internal/shared/interfaces.ts:62](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L62)
|
||||
|
|
|
|||
|
|
@ -21,4 +21,4 @@ In the case of reruns, this can be useful to avoid duplicates
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:68](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L68)
|
||||
[src/internal/shared/interfaces.ts:73](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L73)
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ A list of artifacts that were found
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:78](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L78)
|
||||
[src/internal/shared/interfaces.ts:83](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L83)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ For large files that are not easily compressed, a value of 0 is recommended for
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:47](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L47)
|
||||
[src/internal/shared/interfaces.ts:52](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L52)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -52,4 +52,4 @@ input of 0 assumes default retention setting.
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:36](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L36)
|
||||
[src/internal/shared/interfaces.ts:41](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L41)
|
||||
|
|
|
|||
|
|
@ -8,11 +8,24 @@ Response from the server when an artifact is uploaded
|
|||
|
||||
### Properties
|
||||
|
||||
- [digest](UploadArtifactResponse.md#digest)
|
||||
- [id](UploadArtifactResponse.md#id)
|
||||
- [size](UploadArtifactResponse.md#size)
|
||||
|
||||
## Properties
|
||||
|
||||
### digest
|
||||
|
||||
• `Optional` **digest**: `string`
|
||||
|
||||
The SHA256 digest of the artifact that was created. Not provided if no artifact was uploaded
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:19](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L19)
|
||||
|
||||
___
|
||||
|
||||
### id
|
||||
|
||||
• `Optional` **id**: `number`
|
||||
|
|
@ -22,7 +35,7 @@ This ID can be used as input to other APIs to download, delete or get more infor
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:14](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L14)
|
||||
[src/internal/shared/interfaces.ts:14](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L14)
|
||||
|
||||
___
|
||||
|
||||
|
|
@ -34,4 +47,4 @@ Total size of the artifact in bytes. Not provided if no artifact was uploaded
|
|||
|
||||
#### Defined in
|
||||
|
||||
[src/internal/shared/interfaces.ts:8](https://github.com/actions/toolkit/blob/daf23ba/packages/artifact/src/internal/shared/interfaces.ts#L8)
|
||||
[src/internal/shared/interfaces.ts:8](https://github.com/actions/toolkit/blob/f522fdf/packages/artifact/src/internal/shared/interfaces.ts#L8)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@actions/artifact",
|
||||
"version": "2.1.11",
|
||||
"version": "4.0.0",
|
||||
"preview": true,
|
||||
"description": "Actions artifact lib",
|
||||
"keywords": [
|
||||
|
|
@ -41,24 +41,29 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@actions/github": "^6.0.1",
|
||||
"@actions/http-client": "^2.1.0",
|
||||
"@azure/core-http": "^3.0.5",
|
||||
"@azure/storage-blob": "^12.15.0",
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/core": "^5.2.1",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@protobuf-ts/plugin": "^2.2.3-alpha.1",
|
||||
"archiver": "^7.0.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"twirp-ts": "^2.5.0",
|
||||
"unzip-stream": "^0.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/archiver": "^5.3.2",
|
||||
"@types/unzip-stream": "^0.3.4",
|
||||
"typedoc": "^0.25.4",
|
||||
"typedoc": "^0.28.13",
|
||||
"typedoc-plugin-markdown": "^3.17.1",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"overrides": {
|
||||
"uri-js": "npm:uri-js-replace@^1.0.1",
|
||||
"node-fetch": "^3.3.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export * from './google/protobuf/timestamp'
|
||||
export * from './google/protobuf/wrappers'
|
||||
export * from './results/api/v1/artifact'
|
||||
export * from './results/api/v1/artifact.twirp'
|
||||
export * from './results/api/v1/artifact.twirp-client'
|
||||
|
|
|
|||
|
|
@ -15,6 +15,66 @@ import { MessageType } from "@protobuf-ts/runtime";
|
|||
import { Int64Value } from "../../../google/protobuf/wrappers";
|
||||
import { StringValue } from "../../../google/protobuf/wrappers";
|
||||
import { Timestamp } from "../../../google/protobuf/timestamp";
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.MigrateArtifactRequest
|
||||
*/
|
||||
export interface MigrateArtifactRequest {
|
||||
/**
|
||||
* @generated from protobuf field: string workflow_run_backend_id = 1;
|
||||
*/
|
||||
workflowRunBackendId: string;
|
||||
/**
|
||||
* @generated from protobuf field: string name = 2;
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @generated from protobuf field: google.protobuf.Timestamp expires_at = 3;
|
||||
*/
|
||||
expiresAt?: Timestamp;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.MigrateArtifactResponse
|
||||
*/
|
||||
export interface MigrateArtifactResponse {
|
||||
/**
|
||||
* @generated from protobuf field: bool ok = 1;
|
||||
*/
|
||||
ok: boolean;
|
||||
/**
|
||||
* @generated from protobuf field: string signed_upload_url = 2;
|
||||
*/
|
||||
signedUploadUrl: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.FinalizeMigratedArtifactRequest
|
||||
*/
|
||||
export interface FinalizeMigratedArtifactRequest {
|
||||
/**
|
||||
* @generated from protobuf field: string workflow_run_backend_id = 1;
|
||||
*/
|
||||
workflowRunBackendId: string;
|
||||
/**
|
||||
* @generated from protobuf field: string name = 2;
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @generated from protobuf field: int64 size = 3;
|
||||
*/
|
||||
size: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.FinalizeMigratedArtifactResponse
|
||||
*/
|
||||
export interface FinalizeMigratedArtifactResponse {
|
||||
/**
|
||||
* @generated from protobuf field: bool ok = 1;
|
||||
*/
|
||||
ok: boolean;
|
||||
/**
|
||||
* @generated from protobuf field: int64 artifact_id = 2;
|
||||
*/
|
||||
artifactId: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.CreateArtifactRequest
|
||||
*/
|
||||
|
|
@ -169,6 +229,12 @@ export interface ListArtifactsResponse_MonolithArtifact {
|
|||
* @generated from protobuf field: google.protobuf.Timestamp created_at = 6;
|
||||
*/
|
||||
createdAt?: Timestamp;
|
||||
/**
|
||||
* The SHA-256 digest of the artifact, calculated on upload for upload-artifact v4 & newer
|
||||
*
|
||||
* @generated from protobuf field: google.protobuf.StringValue digest = 7;
|
||||
*/
|
||||
digest?: StringValue;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.GetSignedArtifactURLRequest
|
||||
|
|
@ -227,6 +293,236 @@ export interface DeleteArtifactResponse {
|
|||
artifactId: string;
|
||||
}
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class MigrateArtifactRequest$Type extends MessageType<MigrateArtifactRequest> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.MigrateArtifactRequest", [
|
||||
{ no: 1, name: "workflow_run_backend_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "expires_at", kind: "message", T: () => Timestamp }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<MigrateArtifactRequest>): MigrateArtifactRequest {
|
||||
const message = { workflowRunBackendId: "", name: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<MigrateArtifactRequest>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: MigrateArtifactRequest): MigrateArtifactRequest {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* string workflow_run_backend_id */ 1:
|
||||
message.workflowRunBackendId = reader.string();
|
||||
break;
|
||||
case /* string name */ 2:
|
||||
message.name = reader.string();
|
||||
break;
|
||||
case /* google.protobuf.Timestamp expires_at */ 3:
|
||||
message.expiresAt = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.expiresAt);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: MigrateArtifactRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* string workflow_run_backend_id = 1; */
|
||||
if (message.workflowRunBackendId !== "")
|
||||
writer.tag(1, WireType.LengthDelimited).string(message.workflowRunBackendId);
|
||||
/* string name = 2; */
|
||||
if (message.name !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.name);
|
||||
/* google.protobuf.Timestamp expires_at = 3; */
|
||||
if (message.expiresAt)
|
||||
Timestamp.internalBinaryWrite(message.expiresAt, writer.tag(3, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.MigrateArtifactRequest
|
||||
*/
|
||||
export const MigrateArtifactRequest = new MigrateArtifactRequest$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class MigrateArtifactResponse$Type extends MessageType<MigrateArtifactResponse> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.MigrateArtifactResponse", [
|
||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<MigrateArtifactResponse>): MigrateArtifactResponse {
|
||||
const message = { ok: false, signedUploadUrl: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<MigrateArtifactResponse>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: MigrateArtifactResponse): MigrateArtifactResponse {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* bool ok */ 1:
|
||||
message.ok = reader.bool();
|
||||
break;
|
||||
case /* string signed_upload_url */ 2:
|
||||
message.signedUploadUrl = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: MigrateArtifactResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* bool ok = 1; */
|
||||
if (message.ok !== false)
|
||||
writer.tag(1, WireType.Varint).bool(message.ok);
|
||||
/* string signed_upload_url = 2; */
|
||||
if (message.signedUploadUrl !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.signedUploadUrl);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.MigrateArtifactResponse
|
||||
*/
|
||||
export const MigrateArtifactResponse = new MigrateArtifactResponse$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class FinalizeMigratedArtifactRequest$Type extends MessageType<FinalizeMigratedArtifactRequest> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.FinalizeMigratedArtifactRequest", [
|
||||
{ no: 1, name: "workflow_run_backend_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 2, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "size", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<FinalizeMigratedArtifactRequest>): FinalizeMigratedArtifactRequest {
|
||||
const message = { workflowRunBackendId: "", name: "", size: "0" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<FinalizeMigratedArtifactRequest>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: FinalizeMigratedArtifactRequest): FinalizeMigratedArtifactRequest {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* string workflow_run_backend_id */ 1:
|
||||
message.workflowRunBackendId = reader.string();
|
||||
break;
|
||||
case /* string name */ 2:
|
||||
message.name = reader.string();
|
||||
break;
|
||||
case /* int64 size */ 3:
|
||||
message.size = reader.int64().toString();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: FinalizeMigratedArtifactRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* string workflow_run_backend_id = 1; */
|
||||
if (message.workflowRunBackendId !== "")
|
||||
writer.tag(1, WireType.LengthDelimited).string(message.workflowRunBackendId);
|
||||
/* string name = 2; */
|
||||
if (message.name !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.name);
|
||||
/* int64 size = 3; */
|
||||
if (message.size !== "0")
|
||||
writer.tag(3, WireType.Varint).int64(message.size);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.FinalizeMigratedArtifactRequest
|
||||
*/
|
||||
export const FinalizeMigratedArtifactRequest = new FinalizeMigratedArtifactRequest$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class FinalizeMigratedArtifactResponse$Type extends MessageType<FinalizeMigratedArtifactResponse> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.FinalizeMigratedArtifactResponse", [
|
||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "artifact_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<FinalizeMigratedArtifactResponse>): FinalizeMigratedArtifactResponse {
|
||||
const message = { ok: false, artifactId: "0" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<FinalizeMigratedArtifactResponse>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: FinalizeMigratedArtifactResponse): FinalizeMigratedArtifactResponse {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* bool ok */ 1:
|
||||
message.ok = reader.bool();
|
||||
break;
|
||||
case /* int64 artifact_id */ 2:
|
||||
message.artifactId = reader.int64().toString();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: FinalizeMigratedArtifactResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* bool ok = 1; */
|
||||
if (message.ok !== false)
|
||||
writer.tag(1, WireType.Varint).bool(message.ok);
|
||||
/* int64 artifact_id = 2; */
|
||||
if (message.artifactId !== "0")
|
||||
writer.tag(2, WireType.Varint).int64(message.artifactId);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.FinalizeMigratedArtifactResponse
|
||||
*/
|
||||
export const FinalizeMigratedArtifactResponse = new FinalizeMigratedArtifactResponse$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class CreateArtifactRequest$Type extends MessageType<CreateArtifactRequest> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.CreateArtifactRequest", [
|
||||
|
|
@ -608,7 +904,8 @@ class ListArtifactsResponse_MonolithArtifact$Type extends MessageType<ListArtifa
|
|||
{ no: 3, name: "database_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
|
||||
{ no: 4, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 5, name: "size", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
|
||||
{ no: 6, name: "created_at", kind: "message", T: () => Timestamp }
|
||||
{ no: 6, name: "created_at", kind: "message", T: () => Timestamp },
|
||||
{ no: 7, name: "digest", kind: "message", T: () => StringValue }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<ListArtifactsResponse_MonolithArtifact>): ListArtifactsResponse_MonolithArtifact {
|
||||
|
|
@ -641,6 +938,9 @@ class ListArtifactsResponse_MonolithArtifact$Type extends MessageType<ListArtifa
|
|||
case /* google.protobuf.Timestamp created_at */ 6:
|
||||
message.createdAt = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.createdAt);
|
||||
break;
|
||||
case /* google.protobuf.StringValue digest */ 7:
|
||||
message.digest = StringValue.internalBinaryRead(reader, reader.uint32(), options, message.digest);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
|
|
@ -671,6 +971,9 @@ class ListArtifactsResponse_MonolithArtifact$Type extends MessageType<ListArtifa
|
|||
/* google.protobuf.Timestamp created_at = 6; */
|
||||
if (message.createdAt)
|
||||
Timestamp.internalBinaryWrite(message.createdAt, writer.tag(6, WireType.LengthDelimited).fork(), options).join();
|
||||
/* google.protobuf.StringValue digest = 7; */
|
||||
if (message.digest)
|
||||
StringValue.internalBinaryWrite(message.digest, writer.tag(7, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
|
|
@ -912,5 +1215,7 @@ export const ArtifactService = new ServiceType("github.actions.results.api.v1.Ar
|
|||
{ name: "FinalizeArtifact", options: {}, I: FinalizeArtifactRequest, O: FinalizeArtifactResponse },
|
||||
{ name: "ListArtifacts", options: {}, I: ListArtifactsRequest, O: ListArtifactsResponse },
|
||||
{ name: "GetSignedArtifactURL", options: {}, I: GetSignedArtifactURLRequest, O: GetSignedArtifactURLResponse },
|
||||
{ name: "DeleteArtifact", options: {}, I: DeleteArtifactRequest, O: DeleteArtifactResponse }
|
||||
]);
|
||||
{ name: "DeleteArtifact", options: {}, I: DeleteArtifactRequest, O: DeleteArtifactResponse },
|
||||
{ name: "MigrateArtifact", options: {}, I: MigrateArtifactRequest, O: MigrateArtifactResponse },
|
||||
{ name: "FinalizeMigratedArtifact", options: {}, I: FinalizeMigratedArtifactRequest, O: FinalizeMigratedArtifactResponse }
|
||||
]);
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
import {
|
||||
CreateArtifactRequest,
|
||||
CreateArtifactResponse,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse,
|
||||
ListArtifactsRequest,
|
||||
ListArtifactsResponse,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse,
|
||||
DeleteArtifactRequest,
|
||||
DeleteArtifactResponse,
|
||||
} from "./artifact";
|
||||
|
||||
//==================================//
|
||||
// Client Code //
|
||||
//==================================//
|
||||
|
||||
interface Rpc {
|
||||
request(
|
||||
service: string,
|
||||
method: string,
|
||||
contentType: "application/json" | "application/protobuf",
|
||||
data: object | Uint8Array
|
||||
): Promise<object | Uint8Array>;
|
||||
}
|
||||
|
||||
export interface ArtifactServiceClient {
|
||||
CreateArtifact(
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse>;
|
||||
FinalizeArtifact(
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse>;
|
||||
ListArtifacts(request: ListArtifactsRequest): Promise<ListArtifactsResponse>;
|
||||
GetSignedArtifactURL(
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse>;
|
||||
DeleteArtifact(
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse>;
|
||||
}
|
||||
|
||||
export class ArtifactServiceClientJSON implements ArtifactServiceClient {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
this.CreateArtifact.bind(this);
|
||||
this.FinalizeArtifact.bind(this);
|
||||
this.ListArtifacts.bind(this);
|
||||
this.GetSignedArtifactURL.bind(this);
|
||||
this.DeleteArtifact.bind(this);
|
||||
}
|
||||
CreateArtifact(
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse> {
|
||||
const data = CreateArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"CreateArtifact",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
CreateArtifactResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
FinalizeArtifact(
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse> {
|
||||
const data = FinalizeArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"FinalizeArtifact",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
FinalizeArtifactResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ListArtifacts(request: ListArtifactsRequest): Promise<ListArtifactsResponse> {
|
||||
const data = ListArtifactsRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"ListArtifacts",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
ListArtifactsResponse.fromJson(data as any, { ignoreUnknownFields: true })
|
||||
);
|
||||
}
|
||||
|
||||
GetSignedArtifactURL(
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse> {
|
||||
const data = GetSignedArtifactURLRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"GetSignedArtifactURL",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
GetSignedArtifactURLResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
DeleteArtifact(
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse> {
|
||||
const data = DeleteArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"DeleteArtifact",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
DeleteArtifactResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class ArtifactServiceClientProtobuf implements ArtifactServiceClient {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
this.CreateArtifact.bind(this);
|
||||
this.FinalizeArtifact.bind(this);
|
||||
this.ListArtifacts.bind(this);
|
||||
this.GetSignedArtifactURL.bind(this);
|
||||
this.DeleteArtifact.bind(this);
|
||||
}
|
||||
CreateArtifact(
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse> {
|
||||
const data = CreateArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"CreateArtifact",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
CreateArtifactResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
FinalizeArtifact(
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse> {
|
||||
const data = FinalizeArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"FinalizeArtifact",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
FinalizeArtifactResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
ListArtifacts(request: ListArtifactsRequest): Promise<ListArtifactsResponse> {
|
||||
const data = ListArtifactsRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"ListArtifacts",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
ListArtifactsResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
GetSignedArtifactURL(
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse> {
|
||||
const data = GetSignedArtifactURLRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"GetSignedArtifactURL",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
GetSignedArtifactURLResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
DeleteArtifact(
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse> {
|
||||
const data = DeleteArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"DeleteArtifact",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
DeleteArtifactResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,976 +0,0 @@
|
|||
import {
|
||||
TwirpContext,
|
||||
TwirpServer,
|
||||
RouterEvents,
|
||||
TwirpError,
|
||||
TwirpErrorCode,
|
||||
Interceptor,
|
||||
TwirpContentType,
|
||||
chainInterceptors,
|
||||
} from "twirp-ts";
|
||||
import {
|
||||
CreateArtifactRequest,
|
||||
CreateArtifactResponse,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse,
|
||||
ListArtifactsRequest,
|
||||
ListArtifactsResponse,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse,
|
||||
DeleteArtifactRequest,
|
||||
DeleteArtifactResponse,
|
||||
} from "./artifact";
|
||||
|
||||
//==================================//
|
||||
// Client Code //
|
||||
//==================================//
|
||||
|
||||
interface Rpc {
|
||||
request(
|
||||
service: string,
|
||||
method: string,
|
||||
contentType: "application/json" | "application/protobuf",
|
||||
data: object | Uint8Array
|
||||
): Promise<object | Uint8Array>;
|
||||
}
|
||||
|
||||
export interface ArtifactServiceClient {
|
||||
CreateArtifact(
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse>;
|
||||
FinalizeArtifact(
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse>;
|
||||
ListArtifacts(request: ListArtifactsRequest): Promise<ListArtifactsResponse>;
|
||||
GetSignedArtifactURL(
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse>;
|
||||
DeleteArtifact(
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse>;
|
||||
}
|
||||
|
||||
export class ArtifactServiceClientJSON implements ArtifactServiceClient {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
this.CreateArtifact.bind(this);
|
||||
this.FinalizeArtifact.bind(this);
|
||||
this.ListArtifacts.bind(this);
|
||||
this.GetSignedArtifactURL.bind(this);
|
||||
this.DeleteArtifact.bind(this);
|
||||
}
|
||||
CreateArtifact(
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse> {
|
||||
const data = CreateArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"CreateArtifact",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
CreateArtifactResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
FinalizeArtifact(
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse> {
|
||||
const data = FinalizeArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"FinalizeArtifact",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
FinalizeArtifactResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ListArtifacts(request: ListArtifactsRequest): Promise<ListArtifactsResponse> {
|
||||
const data = ListArtifactsRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"ListArtifacts",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
ListArtifactsResponse.fromJson(data as any, { ignoreUnknownFields: true })
|
||||
);
|
||||
}
|
||||
|
||||
GetSignedArtifactURL(
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse> {
|
||||
const data = GetSignedArtifactURLRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"GetSignedArtifactURL",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
GetSignedArtifactURLResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
DeleteArtifact(
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse> {
|
||||
const data = DeleteArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"DeleteArtifact",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
DeleteArtifactResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class ArtifactServiceClientProtobuf implements ArtifactServiceClient {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
this.CreateArtifact.bind(this);
|
||||
this.FinalizeArtifact.bind(this);
|
||||
this.ListArtifacts.bind(this);
|
||||
this.GetSignedArtifactURL.bind(this);
|
||||
this.DeleteArtifact.bind(this);
|
||||
}
|
||||
CreateArtifact(
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse> {
|
||||
const data = CreateArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"CreateArtifact",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
CreateArtifactResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
FinalizeArtifact(
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse> {
|
||||
const data = FinalizeArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"FinalizeArtifact",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
FinalizeArtifactResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
ListArtifacts(request: ListArtifactsRequest): Promise<ListArtifactsResponse> {
|
||||
const data = ListArtifactsRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"ListArtifacts",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
ListArtifactsResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
GetSignedArtifactURL(
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse> {
|
||||
const data = GetSignedArtifactURLRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"GetSignedArtifactURL",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
GetSignedArtifactURLResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
DeleteArtifact(
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse> {
|
||||
const data = DeleteArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.ArtifactService",
|
||||
"DeleteArtifact",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
DeleteArtifactResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//==================================//
|
||||
// Server Code //
|
||||
//==================================//
|
||||
|
||||
export interface ArtifactServiceTwirp<T extends TwirpContext = TwirpContext> {
|
||||
CreateArtifact(
|
||||
ctx: T,
|
||||
request: CreateArtifactRequest
|
||||
): Promise<CreateArtifactResponse>;
|
||||
FinalizeArtifact(
|
||||
ctx: T,
|
||||
request: FinalizeArtifactRequest
|
||||
): Promise<FinalizeArtifactResponse>;
|
||||
ListArtifacts(
|
||||
ctx: T,
|
||||
request: ListArtifactsRequest
|
||||
): Promise<ListArtifactsResponse>;
|
||||
GetSignedArtifactURL(
|
||||
ctx: T,
|
||||
request: GetSignedArtifactURLRequest
|
||||
): Promise<GetSignedArtifactURLResponse>;
|
||||
DeleteArtifact(
|
||||
ctx: T,
|
||||
request: DeleteArtifactRequest
|
||||
): Promise<DeleteArtifactResponse>;
|
||||
}
|
||||
|
||||
export enum ArtifactServiceMethod {
|
||||
CreateArtifact = "CreateArtifact",
|
||||
FinalizeArtifact = "FinalizeArtifact",
|
||||
ListArtifacts = "ListArtifacts",
|
||||
GetSignedArtifactURL = "GetSignedArtifactURL",
|
||||
DeleteArtifact = "DeleteArtifact",
|
||||
}
|
||||
|
||||
export const ArtifactServiceMethodList = [
|
||||
ArtifactServiceMethod.CreateArtifact,
|
||||
ArtifactServiceMethod.FinalizeArtifact,
|
||||
ArtifactServiceMethod.ListArtifacts,
|
||||
ArtifactServiceMethod.GetSignedArtifactURL,
|
||||
ArtifactServiceMethod.DeleteArtifact,
|
||||
];
|
||||
|
||||
export function createArtifactServiceServer<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(service: ArtifactServiceTwirp<T>) {
|
||||
return new TwirpServer<ArtifactServiceTwirp, T>({
|
||||
service,
|
||||
packageName: "github.actions.results.api.v1",
|
||||
serviceName: "ArtifactService",
|
||||
methodList: ArtifactServiceMethodList,
|
||||
matchRoute: matchArtifactServiceRoute,
|
||||
});
|
||||
}
|
||||
|
||||
function matchArtifactServiceRoute<T extends TwirpContext = TwirpContext>(
|
||||
method: string,
|
||||
events: RouterEvents<T>
|
||||
) {
|
||||
switch (method) {
|
||||
case "CreateArtifact":
|
||||
return async (
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
CreateArtifactRequest,
|
||||
CreateArtifactResponse
|
||||
>[]
|
||||
) => {
|
||||
ctx = { ...ctx, methodName: "CreateArtifact" };
|
||||
await events.onMatch(ctx);
|
||||
return handleArtifactServiceCreateArtifactRequest(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
};
|
||||
case "FinalizeArtifact":
|
||||
return async (
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse
|
||||
>[]
|
||||
) => {
|
||||
ctx = { ...ctx, methodName: "FinalizeArtifact" };
|
||||
await events.onMatch(ctx);
|
||||
return handleArtifactServiceFinalizeArtifactRequest(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
};
|
||||
case "ListArtifacts":
|
||||
return async (
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
ListArtifactsRequest,
|
||||
ListArtifactsResponse
|
||||
>[]
|
||||
) => {
|
||||
ctx = { ...ctx, methodName: "ListArtifacts" };
|
||||
await events.onMatch(ctx);
|
||||
return handleArtifactServiceListArtifactsRequest(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
};
|
||||
case "GetSignedArtifactURL":
|
||||
return async (
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse
|
||||
>[]
|
||||
) => {
|
||||
ctx = { ...ctx, methodName: "GetSignedArtifactURL" };
|
||||
await events.onMatch(ctx);
|
||||
return handleArtifactServiceGetSignedArtifactURLRequest(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
};
|
||||
case "DeleteArtifact":
|
||||
return async (
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
DeleteArtifactRequest,
|
||||
DeleteArtifactResponse
|
||||
>[]
|
||||
) => {
|
||||
ctx = { ...ctx, methodName: "DeleteArtifact" };
|
||||
await events.onMatch(ctx);
|
||||
return handleArtifactServiceDeleteArtifactRequest(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
};
|
||||
default:
|
||||
events.onNotFound();
|
||||
const msg = `no handler found`;
|
||||
throw new TwirpError(TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
|
||||
function handleArtifactServiceCreateArtifactRequest<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, CreateArtifactRequest, CreateArtifactResponse>[]
|
||||
): Promise<string | Uint8Array> {
|
||||
switch (ctx.contentType) {
|
||||
case TwirpContentType.JSON:
|
||||
return handleArtifactServiceCreateArtifactJSON<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
case TwirpContentType.Protobuf:
|
||||
return handleArtifactServiceCreateArtifactProtobuf<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new TwirpError(TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
|
||||
function handleArtifactServiceFinalizeArtifactRequest<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse
|
||||
>[]
|
||||
): Promise<string | Uint8Array> {
|
||||
switch (ctx.contentType) {
|
||||
case TwirpContentType.JSON:
|
||||
return handleArtifactServiceFinalizeArtifactJSON<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
case TwirpContentType.Protobuf:
|
||||
return handleArtifactServiceFinalizeArtifactProtobuf<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new TwirpError(TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
|
||||
function handleArtifactServiceListArtifactsRequest<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, ListArtifactsRequest, ListArtifactsResponse>[]
|
||||
): Promise<string | Uint8Array> {
|
||||
switch (ctx.contentType) {
|
||||
case TwirpContentType.JSON:
|
||||
return handleArtifactServiceListArtifactsJSON<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
case TwirpContentType.Protobuf:
|
||||
return handleArtifactServiceListArtifactsProtobuf<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new TwirpError(TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
|
||||
function handleArtifactServiceGetSignedArtifactURLRequest<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse
|
||||
>[]
|
||||
): Promise<string | Uint8Array> {
|
||||
switch (ctx.contentType) {
|
||||
case TwirpContentType.JSON:
|
||||
return handleArtifactServiceGetSignedArtifactURLJSON<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
case TwirpContentType.Protobuf:
|
||||
return handleArtifactServiceGetSignedArtifactURLProtobuf<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new TwirpError(TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
|
||||
function handleArtifactServiceDeleteArtifactRequest<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, DeleteArtifactRequest, DeleteArtifactResponse>[]
|
||||
): Promise<string | Uint8Array> {
|
||||
switch (ctx.contentType) {
|
||||
case TwirpContentType.JSON:
|
||||
return handleArtifactServiceDeleteArtifactJSON<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
case TwirpContentType.Protobuf:
|
||||
return handleArtifactServiceDeleteArtifactProtobuf<T>(
|
||||
ctx,
|
||||
service,
|
||||
data,
|
||||
interceptors
|
||||
);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new TwirpError(TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
async function handleArtifactServiceCreateArtifactJSON<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, CreateArtifactRequest, CreateArtifactResponse>[]
|
||||
) {
|
||||
let request: CreateArtifactRequest;
|
||||
let response: CreateArtifactResponse;
|
||||
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = CreateArtifactRequest.fromJson(body, {
|
||||
ignoreUnknownFields: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
CreateArtifactRequest,
|
||||
CreateArtifactResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.CreateArtifact(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.CreateArtifact(ctx, request!);
|
||||
}
|
||||
|
||||
return JSON.stringify(
|
||||
CreateArtifactResponse.toJson(response, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
}) as string
|
||||
);
|
||||
}
|
||||
|
||||
async function handleArtifactServiceFinalizeArtifactJSON<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse
|
||||
>[]
|
||||
) {
|
||||
let request: FinalizeArtifactRequest;
|
||||
let response: FinalizeArtifactResponse;
|
||||
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = FinalizeArtifactRequest.fromJson(body, {
|
||||
ignoreUnknownFields: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.FinalizeArtifact(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.FinalizeArtifact(ctx, request!);
|
||||
}
|
||||
|
||||
return JSON.stringify(
|
||||
FinalizeArtifactResponse.toJson(response, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
}) as string
|
||||
);
|
||||
}
|
||||
|
||||
async function handleArtifactServiceListArtifactsJSON<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, ListArtifactsRequest, ListArtifactsResponse>[]
|
||||
) {
|
||||
let request: ListArtifactsRequest;
|
||||
let response: ListArtifactsResponse;
|
||||
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = ListArtifactsRequest.fromJson(body, {
|
||||
ignoreUnknownFields: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
ListArtifactsRequest,
|
||||
ListArtifactsResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.ListArtifacts(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.ListArtifacts(ctx, request!);
|
||||
}
|
||||
|
||||
return JSON.stringify(
|
||||
ListArtifactsResponse.toJson(response, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
}) as string
|
||||
);
|
||||
}
|
||||
|
||||
async function handleArtifactServiceGetSignedArtifactURLJSON<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse
|
||||
>[]
|
||||
) {
|
||||
let request: GetSignedArtifactURLRequest;
|
||||
let response: GetSignedArtifactURLResponse;
|
||||
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = GetSignedArtifactURLRequest.fromJson(body, {
|
||||
ignoreUnknownFields: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.GetSignedArtifactURL(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.GetSignedArtifactURL(ctx, request!);
|
||||
}
|
||||
|
||||
return JSON.stringify(
|
||||
GetSignedArtifactURLResponse.toJson(response, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
}) as string
|
||||
);
|
||||
}
|
||||
|
||||
async function handleArtifactServiceDeleteArtifactJSON<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, DeleteArtifactRequest, DeleteArtifactResponse>[]
|
||||
) {
|
||||
let request: DeleteArtifactRequest;
|
||||
let response: DeleteArtifactResponse;
|
||||
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = DeleteArtifactRequest.fromJson(body, {
|
||||
ignoreUnknownFields: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
DeleteArtifactRequest,
|
||||
DeleteArtifactResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.DeleteArtifact(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.DeleteArtifact(ctx, request!);
|
||||
}
|
||||
|
||||
return JSON.stringify(
|
||||
DeleteArtifactResponse.toJson(response, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
}) as string
|
||||
);
|
||||
}
|
||||
async function handleArtifactServiceCreateArtifactProtobuf<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, CreateArtifactRequest, CreateArtifactResponse>[]
|
||||
) {
|
||||
let request: CreateArtifactRequest;
|
||||
let response: CreateArtifactResponse;
|
||||
|
||||
try {
|
||||
request = CreateArtifactRequest.fromBinary(data);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
CreateArtifactRequest,
|
||||
CreateArtifactResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.CreateArtifact(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.CreateArtifact(ctx, request!);
|
||||
}
|
||||
|
||||
return Buffer.from(CreateArtifactResponse.toBinary(response));
|
||||
}
|
||||
|
||||
async function handleArtifactServiceFinalizeArtifactProtobuf<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse
|
||||
>[]
|
||||
) {
|
||||
let request: FinalizeArtifactRequest;
|
||||
let response: FinalizeArtifactResponse;
|
||||
|
||||
try {
|
||||
request = FinalizeArtifactRequest.fromBinary(data);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
FinalizeArtifactRequest,
|
||||
FinalizeArtifactResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.FinalizeArtifact(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.FinalizeArtifact(ctx, request!);
|
||||
}
|
||||
|
||||
return Buffer.from(FinalizeArtifactResponse.toBinary(response));
|
||||
}
|
||||
|
||||
async function handleArtifactServiceListArtifactsProtobuf<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, ListArtifactsRequest, ListArtifactsResponse>[]
|
||||
) {
|
||||
let request: ListArtifactsRequest;
|
||||
let response: ListArtifactsResponse;
|
||||
|
||||
try {
|
||||
request = ListArtifactsRequest.fromBinary(data);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
ListArtifactsRequest,
|
||||
ListArtifactsResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.ListArtifacts(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.ListArtifacts(ctx, request!);
|
||||
}
|
||||
|
||||
return Buffer.from(ListArtifactsResponse.toBinary(response));
|
||||
}
|
||||
|
||||
async function handleArtifactServiceGetSignedArtifactURLProtobuf<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<
|
||||
T,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse
|
||||
>[]
|
||||
) {
|
||||
let request: GetSignedArtifactURLRequest;
|
||||
let response: GetSignedArtifactURLResponse;
|
||||
|
||||
try {
|
||||
request = GetSignedArtifactURLRequest.fromBinary(data);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
GetSignedArtifactURLRequest,
|
||||
GetSignedArtifactURLResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.GetSignedArtifactURL(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.GetSignedArtifactURL(ctx, request!);
|
||||
}
|
||||
|
||||
return Buffer.from(GetSignedArtifactURLResponse.toBinary(response));
|
||||
}
|
||||
|
||||
async function handleArtifactServiceDeleteArtifactProtobuf<
|
||||
T extends TwirpContext = TwirpContext
|
||||
>(
|
||||
ctx: T,
|
||||
service: ArtifactServiceTwirp,
|
||||
data: Buffer,
|
||||
interceptors?: Interceptor<T, DeleteArtifactRequest, DeleteArtifactResponse>[]
|
||||
) {
|
||||
let request: DeleteArtifactRequest;
|
||||
let response: DeleteArtifactResponse;
|
||||
|
||||
try {
|
||||
request = DeleteArtifactRequest.fromBinary(data);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = chainInterceptors(...interceptors) as Interceptor<
|
||||
T,
|
||||
DeleteArtifactRequest,
|
||||
DeleteArtifactResponse
|
||||
>;
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.DeleteArtifact(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.DeleteArtifact(ctx, request!);
|
||||
}
|
||||
|
||||
return Buffer.from(DeleteArtifactResponse.toBinary(response));
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
import fs from 'fs/promises'
|
||||
import * as crypto from 'crypto'
|
||||
import * as stream from 'stream'
|
||||
|
||||
import * as github from '@actions/github'
|
||||
import * as core from '@actions/core'
|
||||
import * as httpClient from '@actions/http-client'
|
||||
import unzip from 'unzip-stream'
|
||||
import {
|
||||
DownloadArtifactOptions,
|
||||
DownloadArtifactResponse
|
||||
DownloadArtifactResponse,
|
||||
StreamExtractResponse
|
||||
} from '../shared/interfaces'
|
||||
import {getUserAgentString} from '../shared/user-agent'
|
||||
import {getGitHubWorkspaceDir} from '../shared/config'
|
||||
|
|
@ -37,12 +41,14 @@ async function exists(path: string): Promise<boolean> {
|
|||
}
|
||||
}
|
||||
|
||||
async function streamExtract(url: string, directory: string): Promise<void> {
|
||||
async function streamExtract(
|
||||
url: string,
|
||||
directory: string
|
||||
): Promise<StreamExtractResponse> {
|
||||
let retryCount = 0
|
||||
while (retryCount < 5) {
|
||||
try {
|
||||
await streamExtractExternal(url, directory)
|
||||
return
|
||||
return await streamExtractExternal(url, directory)
|
||||
} catch (error) {
|
||||
retryCount++
|
||||
core.debug(
|
||||
|
|
@ -58,8 +64,9 @@ async function streamExtract(url: string, directory: string): Promise<void> {
|
|||
|
||||
export async function streamExtractExternal(
|
||||
url: string,
|
||||
directory: string
|
||||
): Promise<void> {
|
||||
directory: string,
|
||||
opts: {timeout: number} = {timeout: 30 * 1000}
|
||||
): Promise<StreamExtractResponse> {
|
||||
const client = new httpClient.HttpClient(getUserAgentString())
|
||||
const response = await client.get(url)
|
||||
if (response.message.statusCode !== 200) {
|
||||
|
|
@ -68,17 +75,26 @@ export async function streamExtractExternal(
|
|||
)
|
||||
}
|
||||
|
||||
const timeout = 30 * 1000 // 30 seconds
|
||||
let sha256Digest: string | undefined = undefined
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const timerFn = (): void => {
|
||||
response.message.destroy(
|
||||
new Error(`Blob storage chunk did not respond in ${timeout}ms`)
|
||||
const timeoutError = new Error(
|
||||
`Blob storage chunk did not respond in ${opts.timeout}ms`
|
||||
)
|
||||
response.message.destroy(timeoutError)
|
||||
reject(timeoutError)
|
||||
}
|
||||
const timer = setTimeout(timerFn, timeout)
|
||||
const timer = setTimeout(timerFn, opts.timeout)
|
||||
|
||||
response.message
|
||||
const hashStream = crypto.createHash('sha256').setEncoding('hex')
|
||||
const passThrough = new stream.PassThrough()
|
||||
|
||||
response.message.pipe(passThrough)
|
||||
passThrough.pipe(hashStream)
|
||||
const extractStream = passThrough
|
||||
|
||||
extractStream
|
||||
.on('data', () => {
|
||||
timer.refresh()
|
||||
})
|
||||
|
|
@ -92,7 +108,12 @@ export async function streamExtractExternal(
|
|||
.pipe(unzip.Extract({path: directory}))
|
||||
.on('close', () => {
|
||||
clearTimeout(timer)
|
||||
resolve()
|
||||
if (hashStream) {
|
||||
hashStream.end()
|
||||
sha256Digest = hashStream.read() as string
|
||||
core.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`)
|
||||
}
|
||||
resolve({sha256Digest: `sha256:${sha256Digest}`})
|
||||
})
|
||||
.on('error', (error: Error) => {
|
||||
reject(error)
|
||||
|
|
@ -111,6 +132,8 @@ export async function downloadArtifactPublic(
|
|||
|
||||
const api = github.getOctokit(token)
|
||||
|
||||
let digestMismatch = false
|
||||
|
||||
core.info(
|
||||
`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`
|
||||
)
|
||||
|
|
@ -140,13 +163,20 @@ export async function downloadArtifactPublic(
|
|||
|
||||
try {
|
||||
core.info(`Starting download of artifact to: ${downloadPath}`)
|
||||
await streamExtract(location, downloadPath)
|
||||
const extractResponse = await streamExtract(location, downloadPath)
|
||||
core.info(`Artifact download completed successfully.`)
|
||||
if (options?.expectedHash) {
|
||||
if (options?.expectedHash !== extractResponse.sha256Digest) {
|
||||
digestMismatch = true
|
||||
core.debug(`Computed digest: ${extractResponse.sha256Digest}`)
|
||||
core.debug(`Expected digest: ${options.expectedHash}`)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Unable to download and extract artifact: ${error.message}`)
|
||||
}
|
||||
|
||||
return {downloadPath}
|
||||
return {downloadPath, digestMismatch}
|
||||
}
|
||||
|
||||
export async function downloadArtifactInternal(
|
||||
|
|
@ -157,6 +187,8 @@ export async function downloadArtifactInternal(
|
|||
|
||||
const artifactClient = internalArtifactTwirpClient()
|
||||
|
||||
let digestMismatch = false
|
||||
|
||||
const {workflowRunBackendId, workflowJobRunBackendId} =
|
||||
getBackendIdsFromToken()
|
||||
|
||||
|
|
@ -192,13 +224,20 @@ export async function downloadArtifactInternal(
|
|||
|
||||
try {
|
||||
core.info(`Starting download of artifact to: ${downloadPath}`)
|
||||
await streamExtract(signedUrl, downloadPath)
|
||||
const extractResponse = await streamExtract(signedUrl, downloadPath)
|
||||
core.info(`Artifact download completed successfully.`)
|
||||
if (options?.expectedHash) {
|
||||
if (options?.expectedHash !== extractResponse.sha256Digest) {
|
||||
digestMismatch = true
|
||||
core.debug(`Computed digest: ${extractResponse.sha256Digest}`)
|
||||
core.debug(`Expected digest: ${options.expectedHash}`)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Unable to download and extract artifact: ${error.message}`)
|
||||
}
|
||||
|
||||
return {downloadPath}
|
||||
return {downloadPath, digestMismatch}
|
||||
}
|
||||
|
||||
async function resolveOrCreateDirectory(
|
||||
|
|
|
|||
|
|
@ -68,7 +68,10 @@ export async function getArtifactPublic(
|
|||
name: artifact.name,
|
||||
id: artifact.id,
|
||||
size: artifact.size_in_bytes,
|
||||
createdAt: artifact.created_at ? new Date(artifact.created_at) : undefined
|
||||
createdAt: artifact.created_at
|
||||
? new Date(artifact.created_at)
|
||||
: undefined,
|
||||
digest: artifact.digest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +118,8 @@ export async function getArtifactInternal(
|
|||
size: Number(artifact.size),
|
||||
createdAt: artifact.createdAt
|
||||
? Timestamp.toDate(artifact.createdAt)
|
||||
: undefined
|
||||
: undefined,
|
||||
digest: artifact.digest?.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ import {retry} from '@octokit/plugin-retry'
|
|||
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
||||
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
||||
import {getBackendIdsFromToken} from '../shared/util'
|
||||
import {getMaxArtifactListCount} from '../shared/config'
|
||||
import {ListArtifactsRequest, Timestamp} from '../../generated'
|
||||
|
||||
// Limiting to 1000 for perf reasons
|
||||
const maximumArtifactCount = 1000
|
||||
const maximumArtifactCount = getMaxArtifactListCount()
|
||||
const paginationCount = 100
|
||||
const maxNumberOfPages = maximumArtifactCount / paginationCount
|
||||
const maxNumberOfPages = Math.ceil(maximumArtifactCount / paginationCount)
|
||||
|
||||
export async function listArtifactsPublic(
|
||||
workflowRunId: number,
|
||||
|
|
@ -41,14 +41,17 @@ export async function listArtifactsPublic(
|
|||
const github = getOctokit(token, opts, retry, requestLog)
|
||||
|
||||
let currentPageNumber = 1
|
||||
const {data: listArtifactResponse} =
|
||||
await github.rest.actions.listWorkflowRunArtifacts({
|
||||
|
||||
const {data: listArtifactResponse} = await github.request(
|
||||
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts',
|
||||
{
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
run_id: workflowRunId,
|
||||
per_page: paginationCount,
|
||||
page: currentPageNumber
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
let numberOfPages = Math.ceil(
|
||||
listArtifactResponse.total_count / paginationCount
|
||||
|
|
@ -56,7 +59,7 @@ export async function listArtifactsPublic(
|
|||
const totalArtifactCount = listArtifactResponse.total_count
|
||||
if (totalArtifactCount > maximumArtifactCount) {
|
||||
warning(
|
||||
`Workflow run ${workflowRunId} has more than 1000 artifacts. Results will be incomplete as only the first ${maximumArtifactCount} artifacts will be returned`
|
||||
`Workflow run ${workflowRunId} has ${totalArtifactCount} artifacts, exceeding the limit of ${maximumArtifactCount}. Results will be incomplete as only the first ${maximumArtifactCount} artifacts will be returned`
|
||||
)
|
||||
numberOfPages = maxNumberOfPages
|
||||
}
|
||||
|
|
@ -67,27 +70,32 @@ export async function listArtifactsPublic(
|
|||
name: artifact.name,
|
||||
id: artifact.id,
|
||||
size: artifact.size_in_bytes,
|
||||
createdAt: artifact.created_at ? new Date(artifact.created_at) : undefined
|
||||
createdAt: artifact.created_at
|
||||
? new Date(artifact.created_at)
|
||||
: undefined,
|
||||
digest: (artifact as ArtifactResponse).digest
|
||||
})
|
||||
}
|
||||
|
||||
// Move to the next page
|
||||
currentPageNumber++
|
||||
// Iterate over any remaining pages
|
||||
for (
|
||||
currentPageNumber;
|
||||
currentPageNumber < numberOfPages;
|
||||
currentPageNumber <= numberOfPages;
|
||||
currentPageNumber++
|
||||
) {
|
||||
currentPageNumber++
|
||||
debug(`Fetching page ${currentPageNumber} of artifact list`)
|
||||
|
||||
const {data: listArtifactResponse} =
|
||||
await github.rest.actions.listWorkflowRunArtifacts({
|
||||
const {data: listArtifactResponse} = await github.request(
|
||||
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts',
|
||||
{
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
run_id: workflowRunId,
|
||||
per_page: paginationCount,
|
||||
page: currentPageNumber
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
for (const artifact of listArtifactResponse.artifacts) {
|
||||
artifacts.push({
|
||||
|
|
@ -96,7 +104,8 @@ export async function listArtifactsPublic(
|
|||
size: artifact.size_in_bytes,
|
||||
createdAt: artifact.created_at
|
||||
? new Date(artifact.created_at)
|
||||
: undefined
|
||||
: undefined,
|
||||
digest: (artifact as ArtifactResponse).digest
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -132,7 +141,8 @@ export async function listArtifactsInternal(
|
|||
size: Number(artifact.size),
|
||||
createdAt: artifact.createdAt
|
||||
? Timestamp.toDate(artifact.createdAt)
|
||||
: undefined
|
||||
: undefined,
|
||||
digest: artifact.digest?.value
|
||||
}))
|
||||
|
||||
if (latest) {
|
||||
|
|
@ -146,6 +156,18 @@ export async function listArtifactsInternal(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This exists so that we don't have to use 'any' when receiving the artifact list from the GitHub API.
|
||||
* The digest field is not present in OpenAPI/types at time of writing, which necessitates this change.
|
||||
*/
|
||||
interface ArtifactResponse {
|
||||
name: string
|
||||
id: number
|
||||
size_in_bytes: number
|
||||
created_at?: string
|
||||
digest?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a list of artifacts to only include the latest artifact for each name
|
||||
* @param artifacts The artifacts to filter
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {ArtifactServiceClientJSON} from '../../generated'
|
|||
import {getResultsServiceUrl, getRuntimeToken} from './config'
|
||||
import {getUserAgentString} from './user-agent'
|
||||
import {NetworkError, UsageError} from './errors'
|
||||
import {maskSecretUrls} from './util'
|
||||
|
||||
// The twirp http client must implement this interface
|
||||
interface Rpc {
|
||||
|
|
@ -86,6 +87,7 @@ class ArtifactHttpClient implements Rpc {
|
|||
debug(`[Response] - ${response.message.statusCode}`)
|
||||
debug(`Headers: ${JSON.stringify(response.message.headers, null, 2)}`)
|
||||
const body = JSON.parse(rawBody)
|
||||
maskSecretUrls(body)
|
||||
debug(`Body: ${JSON.stringify(body, null, 2)}`)
|
||||
if (this.isSuccessStatusCode(statusCode)) {
|
||||
return {response, body}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os from 'os'
|
||||
import {info} from '@actions/core'
|
||||
|
||||
// Used for controlling the highWaterMark value of the zip that is being streamed
|
||||
// The same value is used as the chunk size that is use during upload to blob storage
|
||||
|
|
@ -44,20 +45,71 @@ export function getGitHubWorkspaceDir(): string {
|
|||
return ghWorkspaceDir
|
||||
}
|
||||
|
||||
// Mimics behavior of azcopy: https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-optimize
|
||||
// If your machine has fewer than 5 CPUs, then the value of this variable is set to 32.
|
||||
// Otherwise, the default value is equal to 16 multiplied by the number of CPUs. The maximum value of this variable is 300.
|
||||
// The maximum value of concurrency is 300.
|
||||
// This value can be changed with ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY variable.
|
||||
export function getConcurrency(): number {
|
||||
const numCPUs = os.cpus().length
|
||||
let concurrencyCap = 32
|
||||
|
||||
if (numCPUs <= 4) {
|
||||
return 32
|
||||
if (numCPUs > 4) {
|
||||
const concurrency = 16 * numCPUs
|
||||
concurrencyCap = concurrency > 300 ? 300 : concurrency
|
||||
}
|
||||
|
||||
const concurrency = 16 * numCPUs
|
||||
return concurrency > 300 ? 300 : concurrency
|
||||
const concurrencyOverride = process.env['ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY']
|
||||
if (concurrencyOverride) {
|
||||
const concurrency = parseInt(concurrencyOverride)
|
||||
if (isNaN(concurrency) || concurrency < 1) {
|
||||
throw new Error(
|
||||
'Invalid value set for ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY env variable'
|
||||
)
|
||||
}
|
||||
|
||||
if (concurrency < concurrencyCap) {
|
||||
info(
|
||||
`Set concurrency based on the value set in ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY.`
|
||||
)
|
||||
return concurrency
|
||||
}
|
||||
|
||||
info(
|
||||
`ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY is higher than the cap of ${concurrencyCap} based on the number of cpus. Set it to the maximum value allowed.`
|
||||
)
|
||||
return concurrencyCap
|
||||
}
|
||||
|
||||
// default concurrency to 5
|
||||
return 5
|
||||
}
|
||||
|
||||
export function getUploadChunkTimeout(): number {
|
||||
return 300_000 // 5 minutes
|
||||
const timeoutVar = process.env['ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS']
|
||||
if (!timeoutVar) {
|
||||
return 300000 // 5 minutes
|
||||
}
|
||||
|
||||
const timeout = parseInt(timeoutVar)
|
||||
if (isNaN(timeout)) {
|
||||
throw new Error(
|
||||
'Invalid value set for ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS env variable'
|
||||
)
|
||||
}
|
||||
|
||||
return timeout
|
||||
}
|
||||
|
||||
// This value can be changed with ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT variable.
|
||||
// Defaults to 1000 as a safeguard for rate limiting.
|
||||
export function getMaxArtifactListCount(): number {
|
||||
const maxCountVar =
|
||||
process.env['ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT'] || '1000'
|
||||
|
||||
const maxCount = parseInt(maxCountVar)
|
||||
if (isNaN(maxCount) || maxCount < 1) {
|
||||
throw new Error(
|
||||
'Invalid value set for ACTIONS_ARTIFACT_MAX_ARTIFACT_COUNT env variable'
|
||||
)
|
||||
}
|
||||
|
||||
return maxCount
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ export interface UploadArtifactResponse {
|
|||
* This ID can be used as input to other APIs to download, delete or get more information about an artifact: https://docs.github.com/en/rest/actions/artifacts
|
||||
*/
|
||||
id?: number
|
||||
|
||||
/**
|
||||
* The SHA256 digest of the artifact that was created. Not provided if no artifact was uploaded
|
||||
*/
|
||||
digest?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,6 +91,11 @@ export interface DownloadArtifactResponse {
|
|||
* The path where the artifact was downloaded to
|
||||
*/
|
||||
downloadPath?: string
|
||||
|
||||
/**
|
||||
* Returns true if the digest of the downloaded artifact does not match the expected hash
|
||||
*/
|
||||
digestMismatch?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,6 +106,20 @@ export interface DownloadArtifactOptions {
|
|||
* Denotes where the artifact will be downloaded to. If not specified then the artifact is download to GITHUB_WORKSPACE
|
||||
*/
|
||||
path?: string
|
||||
|
||||
/**
|
||||
* The hash that was computed for the artifact during upload. If provided, the outcome of the download
|
||||
* will provide a digestMismatch property indicating whether the hash of the downloaded artifact
|
||||
* matches the expected hash.
|
||||
*/
|
||||
expectedHash?: string
|
||||
}
|
||||
|
||||
export interface StreamExtractResponse {
|
||||
/**
|
||||
* The SHA256 hash of the downloaded file
|
||||
*/
|
||||
sha256Digest?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,6 +145,11 @@ export interface Artifact {
|
|||
* The time when the artifact was created
|
||||
*/
|
||||
createdAt?: Date
|
||||
|
||||
/**
|
||||
* The digest of the artifact, computed at time of upload.
|
||||
*/
|
||||
digest?: string
|
||||
}
|
||||
|
||||
// FindOptions are for fetching Artifact(s) out of the scope of the current run.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import * as core from '@actions/core'
|
||||
import {getRuntimeToken} from './config'
|
||||
import jwt_decode from 'jwt-decode'
|
||||
import {debug, setSecret} from '@actions/core'
|
||||
|
||||
export interface BackendIds {
|
||||
workflowRunBackendId: string
|
||||
|
|
@ -69,3 +70,76 @@ export function getBackendIdsFromToken(): BackendIds {
|
|||
|
||||
throw InvalidJwtError
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks the `sig` parameter in a URL and sets it as a secret.
|
||||
*
|
||||
* @param url - The URL containing the signature parameter to mask
|
||||
* @remarks
|
||||
* This function attempts to parse the provided URL and identify the 'sig' query parameter.
|
||||
* If found, it registers both the raw and URL-encoded signature values as secrets using
|
||||
* the Actions `setSecret` API, which prevents them from being displayed in logs.
|
||||
*
|
||||
* The function handles errors gracefully if URL parsing fails, logging them as debug messages.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Mask a signature in an Azure SAS token URL
|
||||
* maskSigUrl('https://example.blob.core.windows.net/container/file.txt?sig=abc123&se=2023-01-01');
|
||||
* ```
|
||||
*/
|
||||
export function maskSigUrl(url: string): void {
|
||||
if (!url) return
|
||||
try {
|
||||
const parsedUrl = new URL(url)
|
||||
const signature = parsedUrl.searchParams.get('sig')
|
||||
if (signature) {
|
||||
setSecret(signature)
|
||||
setSecret(encodeURIComponent(signature))
|
||||
}
|
||||
} catch (error) {
|
||||
debug(
|
||||
`Failed to parse URL: ${url} ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks sensitive information in URLs containing signature parameters.
|
||||
* Currently supports masking 'sig' parameters in the 'signed_upload_url'
|
||||
* and 'signed_download_url' properties of the provided object.
|
||||
*
|
||||
* @param body - The object should contain a signature
|
||||
* @remarks
|
||||
* This function extracts URLs from the object properties and calls maskSigUrl
|
||||
* on each one to redact sensitive signature information. The function doesn't
|
||||
* modify the original object; it only marks the signatures as secrets for
|
||||
* logging purposes.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const responseBody = {
|
||||
* signed_upload_url: 'https://example.com?sig=abc123',
|
||||
* signed_download_url: 'https://example.com?sig=def456'
|
||||
* };
|
||||
* maskSecretUrls(responseBody);
|
||||
* ```
|
||||
*/
|
||||
export function maskSecretUrls(body: Record<string, unknown> | null): void {
|
||||
if (typeof body !== 'object' || body === null) {
|
||||
debug('body is not an object or is null')
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
'signed_upload_url' in body &&
|
||||
typeof body.signed_upload_url === 'string'
|
||||
) {
|
||||
maskSigUrl(body.signed_upload_url)
|
||||
}
|
||||
if ('signed_url' in body && typeof body.signed_url === 'string') {
|
||||
maskSigUrl(body.signed_url)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {BlobClient, BlockBlobUploadStreamOptions} from '@azure/storage-blob'
|
||||
import {TransferProgressEvent} from '@azure/core-http'
|
||||
import {TransferProgressEvent} from '@azure/core-http-compat'
|
||||
import {ZipUploadStream} from './zip'
|
||||
import {
|
||||
getUploadChunkSize,
|
||||
|
|
@ -98,7 +98,7 @@ export async function uploadZipToBlobStorage(
|
|||
|
||||
hashStream.end()
|
||||
sha256Hash = hashStream.read() as string
|
||||
core.info(`SHA256 hash of uploaded artifact zip is ${sha256Hash}`)
|
||||
core.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`)
|
||||
|
||||
if (uploadByteCount === 0) {
|
||||
core.warning(
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ export async function uploadArtifact(
|
|||
|
||||
return {
|
||||
size: uploadResult.uploadSize,
|
||||
digest: uploadResult.sha256Hash,
|
||||
id: Number(artifactId)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,16 @@
|
|||
# @actions/attest Releases
|
||||
|
||||
### 2.0.0
|
||||
|
||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||
- Bump @sigstore/bundle from 3.0.0 to 3.1.0
|
||||
- Bump @sigstore/sign from 3.0.0 to 3.1.0
|
||||
- Bump jose from 5.2.3 to 5.10.0
|
||||
|
||||
### 1.6.0
|
||||
|
||||
- Update `buildSLSAProvenancePredicate` to populate `workflow.ref` field from the `ref` claim in the OIDC token [#1969](https://github.com/actions/toolkit/pull/1969)
|
||||
|
||||
### 1.5.0
|
||||
|
||||
- Bump @actions/core from 1.10.1 to 1.11.1 [#1847](https://github.com/actions/toolkit/pull/1847)
|
||||
|
|
|
|||
|
|
@ -1,47 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`provenance functions buildSLSAProvenancePredicate handle tags including "@" character 1`] = `
|
||||
{
|
||||
"params": {
|
||||
"buildDefinition": {
|
||||
"buildType": "https://actions.github.io/buildtypes/workflow/v1",
|
||||
"externalParameters": {
|
||||
"workflow": {
|
||||
"path": ".github/workflows/main.yml",
|
||||
"ref": "foo@1.0.0",
|
||||
"repository": "https://foo.ghe.com/owner/repo",
|
||||
},
|
||||
},
|
||||
"internalParameters": {
|
||||
"github": {
|
||||
"event_name": "push",
|
||||
"repository_id": "repo-id",
|
||||
"repository_owner_id": "owner-id",
|
||||
"runner_environment": "github-hosted",
|
||||
},
|
||||
},
|
||||
"resolvedDependencies": [
|
||||
{
|
||||
"digest": {
|
||||
"gitCommit": "babca52ab0c93ae16539e5923cb0d7403b9a093b",
|
||||
},
|
||||
"uri": "git+https://foo.ghe.com/owner/repo@refs/heads/main",
|
||||
},
|
||||
],
|
||||
},
|
||||
"runDetails": {
|
||||
"builder": {
|
||||
"id": "https://foo.ghe.com/owner/workflows/.github/workflows/publish.yml@main",
|
||||
},
|
||||
"metadata": {
|
||||
"invocationId": "https://foo.ghe.com/owner/repo/actions/runs/run-id/attempts/run-attempt",
|
||||
},
|
||||
},
|
||||
},
|
||||
"type": "https://slsa.dev/provenance/v1",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`provenance functions buildSLSAProvenancePredicate returns a provenance hydrated from an OIDC token 1`] = `
|
||||
{
|
||||
"params": {
|
||||
|
|
@ -50,7 +8,7 @@ exports[`provenance functions buildSLSAProvenancePredicate returns a provenance
|
|||
"externalParameters": {
|
||||
"workflow": {
|
||||
"path": ".github/workflows/main.yml",
|
||||
"ref": "main",
|
||||
"ref": "refs/heads/main",
|
||||
"repository": "https://foo.ghe.com/owner/repo",
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -75,16 +75,6 @@ describe('provenance functions', () => {
|
|||
const predicate = await buildSLSAProvenancePredicate()
|
||||
expect(predicate).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('handle tags including "@" character', async () => {
|
||||
nock.cleanAll()
|
||||
await mockIssuer({
|
||||
...claims,
|
||||
workflow_ref: 'owner/repo/.github/workflows/main.yml@foo@1.0.0'
|
||||
})
|
||||
const predicate = await buildSLSAProvenancePredicate()
|
||||
expect(predicate).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe('attestProvenance', () => {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@actions/attest",
|
||||
"version": "1.5.0",
|
||||
"version": "2.0.0",
|
||||
"description": "Actions attestation lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
|
|
@ -35,24 +35,24 @@
|
|||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sigstore/mock": "^0.8.0",
|
||||
"@sigstore/mock": "^0.10.0",
|
||||
"@sigstore/rekor-types": "^3.0.0",
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"nock": "^13.5.1",
|
||||
"undici": "^5.28.4"
|
||||
"undici": "^6.20.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/github": "^6.0.0",
|
||||
"@actions/http-client": "^2.2.3",
|
||||
"@octokit/plugin-retry": "^6.0.1",
|
||||
"@sigstore/bundle": "^3.0.0",
|
||||
"@sigstore/sign": "^3.0.0",
|
||||
"jose": "^5.2.3"
|
||||
"@sigstore/bundle": "^3.1.0",
|
||||
"@sigstore/sign": "^3.1.0",
|
||||
"jose": "^5.10.0"
|
||||
},
|
||||
"overrides": {
|
||||
"@octokit/plugin-retry": {
|
||||
"@octokit/core": "^5.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,11 +30,9 @@ export const buildSLSAProvenancePredicate = async (
|
|||
// Split just the path and ref from the workflow string.
|
||||
// owner/repo/.github/workflows/main.yml@main =>
|
||||
// .github/workflows/main.yml, main
|
||||
const [workflowPath, ...workflowRefChunks] = claims.workflow_ref
|
||||
const [workflowPath] = claims.workflow_ref
|
||||
.replace(`${claims.repository}/`, '')
|
||||
.split('@')
|
||||
// Handle case where tag contains `@` (e.g: when using changesets in a monorepo context),
|
||||
const workflowRef = workflowRefChunks.join('@')
|
||||
|
||||
return {
|
||||
type: SLSA_PREDICATE_V1_TYPE,
|
||||
|
|
@ -43,7 +41,7 @@ export const buildSLSAProvenancePredicate = async (
|
|||
buildType: GITHUB_BUILD_TYPE,
|
||||
externalParameters: {
|
||||
workflow: {
|
||||
ref: workflowRef,
|
||||
ref: claims.ref,
|
||||
repository: `${serverURL}/${claims.repository}`,
|
||||
path: workflowPath
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@ export const writeAttestation = async (
|
|||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
headers: options.headers,
|
||||
data: {bundle: attestation}
|
||||
bundle: attestation as {
|
||||
mediaType?: string
|
||||
verificationMaterial?: {[key: string]: unknown}
|
||||
dsseEnvelope?: {[key: string]: unknown}
|
||||
}
|
||||
})
|
||||
|
||||
const data =
|
||||
|
|
|
|||
|
|
@ -1,5 +1,36 @@
|
|||
# @actions/cache Releases
|
||||
|
||||
### 4.1.0
|
||||
|
||||
- Remove client side 10GiB cache size limit check & update twirp client [#2118](https://github.com/actions/toolkit/pull/2118)
|
||||
|
||||
### 4.0.5
|
||||
|
||||
- Reintroduce @protobuf-ts/runtime-rpc as a runtime dependency [#2113](https://github.com/actions/toolkit/pull/2113)
|
||||
|
||||
### 4.0.4
|
||||
|
||||
⚠️ Faulty patch release. Upgrade to 4.0.5 instead.
|
||||
|
||||
- Optimized cache dependencies by moving `@protobuf-ts/plugin` to dev dependencies [#2106](https://github.com/actions/toolkit/pull/2106)
|
||||
- Improved cache service availability determination for different cache service versions (v1 and v2) [#2100](https://github.com/actions/toolkit/pull/2100)
|
||||
- Enhanced server error handling: 5xx HTTP errors are now logged as errors instead of warnings [#2099](https://github.com/actions/toolkit/pull/2099)
|
||||
- Fixed cache hit logging to properly distinguish between exact key matches and restore key matches [#2101](https://github.com/actions/toolkit/pull/2101)
|
||||
|
||||
### 4.0.3
|
||||
|
||||
- Added masking for Shared Access Signature (SAS) cache entry URLs [#1982](https://github.com/actions/toolkit/pull/1982)
|
||||
- Improved debugging by logging both the cache version alongside the keys requested when a cache restore fails [#1994](https://github.com/actions/toolkit/pull/1994)
|
||||
|
||||
### 4.0.2
|
||||
|
||||
- Wrap create failures in ReserveCacheError [#1966](https://github.com/actions/toolkit/pull/1966)
|
||||
|
||||
### 4.0.1
|
||||
|
||||
- Remove runtime dependency on `twirp-ts` [#1947](https://github.com/actions/toolkit/pull/1947)
|
||||
- Cache miss as debug, not warning annotation [#1954](https://github.com/actions/toolkit/pull/1954)
|
||||
|
||||
### 4.0.0
|
||||
|
||||
#### Important changes
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const filePath = process.env[`GITHUB_ENV`]
|
||||
fs.appendFileSync(filePath, `ACTIONS_RUNTIME_TOKEN=${process.env.ACTIONS_RUNTIME_TOKEN}${os.EOL}`, {
|
||||
fs.appendFileSync(filePath, `ACTIONS_CACHE_SERVICE_V2=true${os.EOL}`, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
fs.appendFileSync(filePath, `ACTIONS_CACHE_URL=${process.env.ACTIONS_CACHE_URL}${os.EOL}`, {
|
||||
fs.appendFileSync(filePath, `ACTIONS_RESULTS_URL=${process.env.ACTIONS_RESULTS_URL}${os.EOL}`, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
fs.appendFileSync(filePath, `ACTIONS_RUNTIME_TOKEN=${process.env.ACTIONS_RUNTIME_TOKEN}${os.EOL}`, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
fs.appendFileSync(filePath, `GITHUB_RUN_ID=${process.env.GITHUB_RUN_ID}${os.EOL}`, {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,69 @@
|
|||
import * as cache from '../src/cache'
|
||||
|
||||
test('isFeatureAvailable returns true if server url is set', () => {
|
||||
try {
|
||||
describe('isFeatureAvailable', () => {
|
||||
const originalEnv = process.env
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules()
|
||||
process.env = {...originalEnv}
|
||||
// Clean cache-related environment variables
|
||||
delete process.env['ACTIONS_CACHE_URL']
|
||||
delete process.env['ACTIONS_RESULTS_URL']
|
||||
delete process.env['ACTIONS_CACHE_SERVICE_V2']
|
||||
delete process.env['GITHUB_SERVER_URL']
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
process.env = originalEnv
|
||||
})
|
||||
|
||||
test('returns true for cache service v1 when ACTIONS_CACHE_URL is set', () => {
|
||||
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(true)
|
||||
} finally {
|
||||
delete process.env['ACTIONS_CACHE_URL']
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('isFeatureAvailable returns false if server url is not set', () => {
|
||||
expect(cache.isFeatureAvailable()).toBe(false)
|
||||
test('returns false for cache service v1 when only ACTIONS_RESULTS_URL is set', () => {
|
||||
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(false)
|
||||
})
|
||||
|
||||
test('returns true for cache service v1 when both URLs are set', () => {
|
||||
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
|
||||
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(true)
|
||||
})
|
||||
|
||||
test('returns true for cache service v2 when ACTIONS_RESULTS_URL is set', () => {
|
||||
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
|
||||
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(true)
|
||||
})
|
||||
|
||||
test('returns false for cache service v2 when only ACTIONS_CACHE_URL is set', () => {
|
||||
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
|
||||
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(false)
|
||||
})
|
||||
|
||||
test('returns false when no cache URLs are set', () => {
|
||||
expect(cache.isFeatureAvailable()).toBe(false)
|
||||
})
|
||||
|
||||
test('returns false for cache service v2 when no URLs are set', () => {
|
||||
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
|
||||
expect(cache.isFeatureAvailable()).toBe(false)
|
||||
})
|
||||
|
||||
test('returns true for GHES with v1 even when v2 flag is set', () => {
|
||||
process.env['GITHUB_SERVER_URL'] = 'https://my-enterprise.github.com'
|
||||
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
|
||||
process.env['ACTIONS_CACHE_URL'] = 'http://cache.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(true)
|
||||
})
|
||||
|
||||
test('returns false for GHES with only ACTIONS_RESULTS_URL', () => {
|
||||
process.env['GITHUB_SERVER_URL'] = 'https://my-enterprise.github.com'
|
||||
process.env['ACTIONS_RESULTS_URL'] = 'http://results.com'
|
||||
expect(cache.isFeatureAvailable()).toBe(false)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import * as cacheUtils from '../src/internal/cacheUtils'
|
|||
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
|
||||
import {ArtifactCacheEntry} from '../src/internal/contracts'
|
||||
import * as tar from '../src/internal/tar'
|
||||
import {HttpClientError} from '@actions/http-client'
|
||||
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
|
||||
|
||||
jest.mock('../src/internal/cacheHttpClient')
|
||||
jest.mock('../src/internal/cacheUtils')
|
||||
|
|
@ -73,18 +75,28 @@ test('restore with no cache found', async () => {
|
|||
test('restore with server error should fail', async () => {
|
||||
const paths = ['node_modules']
|
||||
const key = 'node-test'
|
||||
const logWarningMock = jest.spyOn(core, 'warning')
|
||||
const logErrorMock = jest.spyOn(core, 'error')
|
||||
|
||||
jest.spyOn(cacheHttpClient, 'getCacheEntry').mockImplementation(() => {
|
||||
throw new Error('HTTP Error Occurred')
|
||||
})
|
||||
// Set cache service to V2 to test error logging for server errors
|
||||
process.env['ACTIONS_CACHE_SERVICE_V2'] = 'true'
|
||||
process.env['ACTIONS_RESULTS_URL'] = 'https://results.local/'
|
||||
|
||||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'GetCacheEntryDownloadURL')
|
||||
.mockImplementation(() => {
|
||||
throw new HttpClientError('HTTP Error Occurred', 500)
|
||||
})
|
||||
|
||||
const cacheKey = await restoreCache(paths, key)
|
||||
expect(cacheKey).toBe(undefined)
|
||||
expect(logWarningMock).toHaveBeenCalledTimes(1)
|
||||
expect(logWarningMock).toHaveBeenCalledWith(
|
||||
expect(logErrorMock).toHaveBeenCalledTimes(1)
|
||||
expect(logErrorMock).toHaveBeenCalledWith(
|
||||
'Failed to restore: HTTP Error Occurred'
|
||||
)
|
||||
|
||||
// Clean up environment
|
||||
delete process.env['ACTIONS_CACHE_SERVICE_V2']
|
||||
delete process.env['ACTIONS_RESULTS_URL']
|
||||
})
|
||||
|
||||
test('restore with restore keys and no cache found', async () => {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ import * as cacheUtils from '../src/internal/cacheUtils'
|
|||
import * as cacheHttpClient from '../src/internal/cacheHttpClient'
|
||||
import {restoreCache} from '../src/cache'
|
||||
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
|
||||
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp'
|
||||
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
|
||||
import {DownloadOptions} from '../src/options'
|
||||
import {HttpClientError} from '@actions/http-client'
|
||||
|
||||
jest.mock('../src/internal/cacheHttpClient')
|
||||
jest.mock('../src/internal/cacheUtils')
|
||||
|
|
@ -95,18 +96,18 @@ test('restore with no cache found', async () => {
|
|||
test('restore with server error should fail', async () => {
|
||||
const paths = ['node_modules']
|
||||
const key = 'node-test'
|
||||
const logWarningMock = jest.spyOn(core, 'warning')
|
||||
const logErrorMock = jest.spyOn(core, 'error')
|
||||
|
||||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'GetCacheEntryDownloadURL')
|
||||
.mockImplementation(() => {
|
||||
throw new Error('HTTP Error Occurred')
|
||||
throw new HttpClientError('HTTP Error Occurred', 500)
|
||||
})
|
||||
|
||||
const cacheKey = await restoreCache(paths, key)
|
||||
expect(cacheKey).toBe(undefined)
|
||||
expect(logWarningMock).toHaveBeenCalledTimes(1)
|
||||
expect(logWarningMock).toHaveBeenCalledWith(
|
||||
expect(logErrorMock).toHaveBeenCalledTimes(1)
|
||||
expect(logErrorMock).toHaveBeenCalledWith(
|
||||
'Failed to restore: HTTP Error Occurred'
|
||||
)
|
||||
})
|
||||
|
|
@ -115,7 +116,10 @@ test('restore with restore keys and no cache found', async () => {
|
|||
const paths = ['node_modules']
|
||||
const key = 'node-test'
|
||||
const restoreKeys = ['node-']
|
||||
const logWarningMock = jest.spyOn(core, 'warning')
|
||||
const cacheVersion =
|
||||
'd90f107aaeb22920dba0c637a23c37b5bc497b4dfa3b07fe3f79bf88a273c11b'
|
||||
const getCacheVersionMock = jest.spyOn(cacheUtils, 'getCacheVersion')
|
||||
getCacheVersionMock.mockReturnValue(cacheVersion)
|
||||
|
||||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'GetCacheEntryDownloadURL')
|
||||
|
|
@ -130,8 +134,11 @@ test('restore with restore keys and no cache found', async () => {
|
|||
const cacheKey = await restoreCache(paths, key, restoreKeys)
|
||||
|
||||
expect(cacheKey).toBe(undefined)
|
||||
expect(logWarningMock).toHaveBeenCalledWith(
|
||||
`Cache not found for keys: ${[key, ...restoreKeys].join(', ')}`
|
||||
expect(logDebugMock).toHaveBeenCalledWith(
|
||||
`Cache not found for version ${cacheVersion} of keys: ${[
|
||||
key,
|
||||
...restoreKeys
|
||||
].join(', ')}`
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -259,6 +266,7 @@ test('restore with zstd compressed cache found', async () => {
|
|||
const cacheKey = await restoreCache(paths, key, [], options)
|
||||
|
||||
expect(cacheKey).toBe(key)
|
||||
expect(logInfoMock).toHaveBeenCalledWith(`Cache hit for: ${key}`)
|
||||
expect(getCacheVersionMock).toHaveBeenCalledWith(
|
||||
paths,
|
||||
compressionMethod,
|
||||
|
|
@ -336,6 +344,9 @@ test('restore with cache found for restore key', async () => {
|
|||
const cacheKey = await restoreCache(paths, key, restoreKeys, options)
|
||||
|
||||
expect(cacheKey).toBe(restoreKeys[0])
|
||||
expect(logInfoMock).toHaveBeenCalledWith(
|
||||
`Cache hit for restore-key: ${restoreKeys[0]}`
|
||||
)
|
||||
expect(getCacheVersionMock).toHaveBeenCalledWith(
|
||||
paths,
|
||||
compressionMethod,
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@ import * as config from '../src/internal/config'
|
|||
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
|
||||
import * as tar from '../src/internal/tar'
|
||||
import {TypedResponse} from '@actions/http-client/lib/interfaces'
|
||||
import {HttpClientError} from '@actions/http-client'
|
||||
import {
|
||||
ReserveCacheResponse,
|
||||
ITypedResponseWithError
|
||||
} from '../src/internal/contracts'
|
||||
import {HttpClientError} from '@actions/http-client'
|
||||
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
|
||||
|
||||
jest.mock('../src/internal/cacheHttpClient')
|
||||
jest.mock('../src/internal/cacheUtils')
|
||||
|
|
@ -223,46 +224,55 @@ test('save with reserve cache failure should fail', async () => {
|
|||
test('save with server error should fail', async () => {
|
||||
const filePath = 'node_modules'
|
||||
const primaryKey = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const cachePaths = [path.resolve(filePath)]
|
||||
const logWarningMock = jest.spyOn(core, 'warning')
|
||||
const cacheId = 4
|
||||
const reserveCacheMock = jest
|
||||
.spyOn(cacheHttpClient, 'reserveCache')
|
||||
.mockImplementation(async () => {
|
||||
const response: TypedResponse<ReserveCacheResponse> = {
|
||||
statusCode: 500,
|
||||
result: {cacheId},
|
||||
headers: {}
|
||||
}
|
||||
return response
|
||||
})
|
||||
const logErrorMock = jest.spyOn(core, 'error')
|
||||
|
||||
// Mock cache service version to V2
|
||||
const getCacheServiceVersionMock = jest
|
||||
.spyOn(config, 'getCacheServiceVersion')
|
||||
.mockReturnValue('v2')
|
||||
|
||||
// Mock V2 CreateCacheEntry to succeed
|
||||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
signedUploadUrl: 'https://blob-storage.local?signed=true',
|
||||
message: ''
|
||||
})
|
||||
)
|
||||
|
||||
// Mock the FinalizeCacheEntryUpload to succeed (since the error should happen in saveCache)
|
||||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, entryId: '4', message: 'Success'})
|
||||
)
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
|
||||
// Mock the saveCache call to throw a server error
|
||||
const saveCacheMock = jest
|
||||
.spyOn(cacheHttpClient, 'saveCache')
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error('HTTP Error Occurred')
|
||||
throw new HttpClientError('HTTP Error Occurred', 500)
|
||||
})
|
||||
|
||||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockReturnValueOnce(Promise.resolve(compression))
|
||||
|
||||
await saveCache([filePath], primaryKey)
|
||||
expect(logWarningMock).toHaveBeenCalledTimes(1)
|
||||
expect(logWarningMock).toHaveBeenCalledWith(
|
||||
|
||||
expect(logErrorMock).toHaveBeenCalledTimes(1)
|
||||
expect(logErrorMock).toHaveBeenCalledWith(
|
||||
'Failed to save: HTTP Error Occurred'
|
||||
)
|
||||
|
||||
expect(reserveCacheMock).toHaveBeenCalledTimes(1)
|
||||
expect(reserveCacheMock).toHaveBeenCalledWith(primaryKey, [filePath], {
|
||||
cacheSize: undefined,
|
||||
compressionMethod: compression,
|
||||
enableCrossOsArchive: false
|
||||
})
|
||||
expect(createCacheEntryMock).toHaveBeenCalledTimes(1)
|
||||
const archiveFolder = '/foo/bar'
|
||||
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
|
||||
const cachePaths = [path.resolve(filePath)]
|
||||
expect(createTarMock).toHaveBeenCalledTimes(1)
|
||||
expect(createTarMock).toHaveBeenCalledWith(
|
||||
archiveFolder,
|
||||
|
|
@ -270,13 +280,10 @@ test('save with server error should fail', async () => {
|
|||
compression
|
||||
)
|
||||
expect(saveCacheMock).toHaveBeenCalledTimes(1)
|
||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||
cacheId,
|
||||
archiveFile,
|
||||
'',
|
||||
undefined
|
||||
)
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
|
||||
// Restore the getCacheServiceVersion mock to its original state
|
||||
getCacheServiceVersionMock.mockRestore()
|
||||
})
|
||||
|
||||
test('save with valid inputs uploads a cache', async () => {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import * as cacheUtils from '../src/internal/cacheUtils'
|
|||
import {CacheFilename, CompressionMethod} from '../src/internal/constants'
|
||||
import * as config from '../src/internal/config'
|
||||
import * as tar from '../src/internal/tar'
|
||||
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp'
|
||||
import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp-client'
|
||||
import * as cacheHttpClient from '../src/internal/cacheHttpClient'
|
||||
import {UploadOptions} from '../src/options'
|
||||
|
||||
|
|
@ -59,47 +59,14 @@ test('save with missing input should fail', async () => {
|
|||
)
|
||||
})
|
||||
|
||||
test('save with large cache outputs should fail using', async () => {
|
||||
const paths = 'node_modules'
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const cachePaths = [path.resolve(paths)]
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
const logWarningMock = jest.spyOn(core, 'warning')
|
||||
|
||||
const cacheSize = 11 * 1024 * 1024 * 1024 //~11GB, over the 10GB limit
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
.mockReturnValueOnce(cacheSize)
|
||||
const compression = CompressionMethod.Gzip
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockReturnValueOnce(Promise.resolve(compression))
|
||||
|
||||
const cacheId = await saveCache([paths], key)
|
||||
expect(cacheId).toBe(-1)
|
||||
expect(logWarningMock).toHaveBeenCalledWith(
|
||||
'Failed to save: Cache size of ~11264 MB (11811160064 B) is over the 10GB limit, not saving cache.'
|
||||
)
|
||||
|
||||
const archiveFolder = '/foo/bar'
|
||||
|
||||
expect(createTarMock).toHaveBeenCalledWith(
|
||||
archiveFolder,
|
||||
cachePaths,
|
||||
compression
|
||||
)
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test('create cache entry failure', async () => {
|
||||
test('create cache entry failure on non-ok response', async () => {
|
||||
const paths = ['node_modules']
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const infoLogMock = jest.spyOn(core, 'info')
|
||||
|
||||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(Promise.resolve({ok: false, signedUploadUrl: ''}))
|
||||
.mockResolvedValue({ok: false, signedUploadUrl: '', message: ''})
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
const finalizeCacheEntryMock = jest.spyOn(
|
||||
|
|
@ -109,7 +76,7 @@ test('create cache entry failure', async () => {
|
|||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockReturnValueOnce(Promise.resolve(compression))
|
||||
.mockResolvedValueOnce(compression)
|
||||
const archiveFileSize = 1024
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
|
|
@ -133,6 +100,39 @@ test('create cache entry failure', async () => {
|
|||
expect(saveCacheMock).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
test('create cache entry fails on rejected promise', async () => {
|
||||
const paths = ['node_modules']
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const infoLogMock = jest.spyOn(core, 'info')
|
||||
|
||||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockRejectedValue(new Error('Failed to create cache entry'))
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockResolvedValueOnce(compression)
|
||||
const archiveFileSize = 1024
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
.mockReturnValueOnce(archiveFileSize)
|
||||
|
||||
const cacheId = await saveCache(paths, key)
|
||||
expect(cacheId).toBe(-1)
|
||||
expect(infoLogMock).toHaveBeenCalledWith(
|
||||
`Failed to save: Unable to reserve cache with key ${key}, another job may be creating this cache.`
|
||||
)
|
||||
|
||||
expect(createCacheEntryMock).toHaveBeenCalledWith({
|
||||
key,
|
||||
version: cacheUtils.getCacheVersion(paths, compression)
|
||||
})
|
||||
expect(createTarMock).toHaveBeenCalledTimes(1)
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test('save cache fails if a signedUploadURL was not passed', async () => {
|
||||
const paths = 'node_modules'
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
|
|
@ -149,7 +149,7 @@ test('save cache fails if a signedUploadURL was not passed', async () => {
|
|||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL})
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
|
||||
)
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
|
|
@ -207,7 +207,7 @@ test('finalize save cache failure', async () => {
|
|||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL})
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
|
||||
)
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
|
|
@ -227,7 +227,7 @@ test('finalize save cache failure', async () => {
|
|||
|
||||
const finalizeCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
|
||||
.mockReturnValue(Promise.resolve({ok: false, entryId: ''}))
|
||||
.mockReturnValue(Promise.resolve({ok: false, entryId: '', message: ''}))
|
||||
|
||||
const cacheId = await saveCache([paths], key, options)
|
||||
|
||||
|
|
@ -286,7 +286,7 @@ test('save with valid inputs uploads a cache', async () => {
|
|||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL})
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
|
||||
)
|
||||
|
||||
const saveCacheMock = jest.spyOn(cacheHttpClient, 'saveCache')
|
||||
|
|
@ -299,7 +299,9 @@ test('save with valid inputs uploads a cache', async () => {
|
|||
|
||||
const finalizeCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
|
||||
.mockReturnValue(Promise.resolve({ok: true, entryId: cacheId.toString()}))
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, entryId: cacheId.toString(), message: ''})
|
||||
)
|
||||
|
||||
const expectedCacheId = await saveCache([paths], key)
|
||||
|
||||
|
|
@ -327,6 +329,252 @@ test('save with valid inputs uploads a cache', async () => {
|
|||
expect(expectedCacheId).toBe(cacheId)
|
||||
})
|
||||
|
||||
test('save with extremely large cache should succeed in v2 (no size limit)', async () => {
|
||||
const paths = 'node_modules'
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const cachePaths = [path.resolve(paths)]
|
||||
const signedUploadURL = 'https://blob-storage.local?signed=true'
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
// Simulate a very large cache (20GB)
|
||||
const archiveFileSize = 20 * 1024 * 1024 * 1024 // 20GB
|
||||
const options: UploadOptions = {
|
||||
archiveSizeBytes: archiveFileSize,
|
||||
useAzureSdk: true,
|
||||
uploadChunkSize: 64 * 1024 * 1024,
|
||||
uploadConcurrency: 8
|
||||
}
|
||||
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
.mockReturnValueOnce(archiveFileSize)
|
||||
|
||||
const cacheId = 4
|
||||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
|
||||
)
|
||||
|
||||
const saveCacheMock = jest.spyOn(cacheHttpClient, 'saveCache')
|
||||
|
||||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockReturnValue(Promise.resolve(compression))
|
||||
const cacheVersion = cacheUtils.getCacheVersion([paths], compression)
|
||||
|
||||
const finalizeCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, entryId: cacheId.toString(), message: ''})
|
||||
)
|
||||
|
||||
const expectedCacheId = await saveCache([paths], key)
|
||||
|
||||
const archiveFolder = '/foo/bar'
|
||||
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
|
||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||
-1,
|
||||
archiveFile,
|
||||
signedUploadURL,
|
||||
options
|
||||
)
|
||||
expect(createTarMock).toHaveBeenCalledWith(
|
||||
archiveFolder,
|
||||
cachePaths,
|
||||
compression
|
||||
)
|
||||
|
||||
expect(finalizeCacheEntryMock).toHaveBeenCalledWith({
|
||||
key,
|
||||
version: cacheVersion,
|
||||
sizeBytes: archiveFileSize.toString()
|
||||
})
|
||||
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
expect(expectedCacheId).toBe(cacheId)
|
||||
})
|
||||
|
||||
test('save with create cache entry failure and specific error message', async () => {
|
||||
const paths = ['node_modules']
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const infoLogMock = jest.spyOn(core, 'info')
|
||||
const warningLogMock = jest.spyOn(core, 'warning')
|
||||
const errorMessage = 'Cache storage quota exceeded for repository'
|
||||
|
||||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockResolvedValue({ok: false, signedUploadUrl: '', message: errorMessage})
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockResolvedValueOnce(compression)
|
||||
const archiveFileSize = 1024
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
.mockReturnValueOnce(archiveFileSize)
|
||||
|
||||
const cacheId = await saveCache(paths, key)
|
||||
expect(cacheId).toBe(-1)
|
||||
expect(warningLogMock).toHaveBeenCalledWith(
|
||||
`Cache reservation failed: ${errorMessage}`
|
||||
)
|
||||
expect(infoLogMock).toHaveBeenCalledWith(
|
||||
`Failed to save: Unable to reserve cache with key ${key}, another job may be creating this cache.`
|
||||
)
|
||||
|
||||
expect(createCacheEntryMock).toHaveBeenCalledWith({
|
||||
key,
|
||||
version: cacheUtils.getCacheVersion(paths, compression)
|
||||
})
|
||||
expect(createTarMock).toHaveBeenCalledTimes(1)
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
test('save with finalize cache entry failure and specific error message', async () => {
|
||||
const paths = 'node_modules'
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const cachePaths = [path.resolve(paths)]
|
||||
const logWarningMock = jest.spyOn(core, 'warning')
|
||||
const signedUploadURL = 'https://blob-storage.local?signed=true'
|
||||
const archiveFileSize = 1024
|
||||
const errorMessage =
|
||||
'Cache entry finalization failed due to concurrent access'
|
||||
const options: UploadOptions = {
|
||||
archiveSizeBytes: archiveFileSize,
|
||||
useAzureSdk: true,
|
||||
uploadChunkSize: 64 * 1024 * 1024,
|
||||
uploadConcurrency: 8
|
||||
}
|
||||
|
||||
const createCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
|
||||
)
|
||||
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
const saveCacheMock = jest
|
||||
.spyOn(cacheHttpClient, 'saveCache')
|
||||
.mockResolvedValue()
|
||||
|
||||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockReturnValueOnce(Promise.resolve(compression))
|
||||
|
||||
const cacheVersion = cacheUtils.getCacheVersion([paths], compression)
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
.mockReturnValueOnce(archiveFileSize)
|
||||
|
||||
const finalizeCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: false, entryId: '', message: errorMessage})
|
||||
)
|
||||
|
||||
const cacheId = await saveCache([paths], key, options)
|
||||
|
||||
expect(createCacheEntryMock).toHaveBeenCalledWith({
|
||||
key,
|
||||
version: cacheVersion
|
||||
})
|
||||
|
||||
const archiveFolder = '/foo/bar'
|
||||
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
|
||||
expect(createTarMock).toHaveBeenCalledWith(
|
||||
archiveFolder,
|
||||
cachePaths,
|
||||
compression
|
||||
)
|
||||
|
||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||
-1,
|
||||
archiveFile,
|
||||
signedUploadURL,
|
||||
options
|
||||
)
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(finalizeCacheEntryMock).toHaveBeenCalledWith({
|
||||
key,
|
||||
version: cacheVersion,
|
||||
sizeBytes: archiveFileSize.toString()
|
||||
})
|
||||
|
||||
expect(cacheId).toBe(-1)
|
||||
expect(logWarningMock).toHaveBeenCalledWith(errorMessage)
|
||||
})
|
||||
|
||||
test('save with multiple large caches should succeed in v2 (testing 50GB)', async () => {
|
||||
const paths = ['large-dataset', 'node_modules', 'build-artifacts']
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
const cachePaths = paths.map(p => path.resolve(p))
|
||||
const signedUploadURL = 'https://blob-storage.local?signed=true'
|
||||
const createTarMock = jest.spyOn(tar, 'createTar')
|
||||
// Simulate an extremely large cache (50GB)
|
||||
const archiveFileSize = 50 * 1024 * 1024 * 1024 // 50GB
|
||||
const options: UploadOptions = {
|
||||
archiveSizeBytes: archiveFileSize,
|
||||
useAzureSdk: true,
|
||||
uploadChunkSize: 64 * 1024 * 1024,
|
||||
uploadConcurrency: 8
|
||||
}
|
||||
|
||||
jest
|
||||
.spyOn(cacheUtils, 'getArchiveFileSizeInBytes')
|
||||
.mockReturnValueOnce(archiveFileSize)
|
||||
|
||||
const cacheId = 7
|
||||
jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'CreateCacheEntry')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, signedUploadUrl: signedUploadURL, message: ''})
|
||||
)
|
||||
|
||||
const saveCacheMock = jest.spyOn(cacheHttpClient, 'saveCache')
|
||||
|
||||
const compression = CompressionMethod.Zstd
|
||||
const getCompressionMock = jest
|
||||
.spyOn(cacheUtils, 'getCompressionMethod')
|
||||
.mockReturnValue(Promise.resolve(compression))
|
||||
const cacheVersion = cacheUtils.getCacheVersion(paths, compression)
|
||||
|
||||
const finalizeCacheEntryMock = jest
|
||||
.spyOn(CacheServiceClientJSON.prototype, 'FinalizeCacheEntryUpload')
|
||||
.mockReturnValue(
|
||||
Promise.resolve({ok: true, entryId: cacheId.toString(), message: ''})
|
||||
)
|
||||
|
||||
const expectedCacheId = await saveCache(paths, key)
|
||||
|
||||
const archiveFolder = '/foo/bar'
|
||||
const archiveFile = path.join(archiveFolder, CacheFilename.Zstd)
|
||||
expect(saveCacheMock).toHaveBeenCalledWith(
|
||||
-1,
|
||||
archiveFile,
|
||||
signedUploadURL,
|
||||
options
|
||||
)
|
||||
expect(createTarMock).toHaveBeenCalledWith(
|
||||
archiveFolder,
|
||||
cachePaths,
|
||||
compression
|
||||
)
|
||||
|
||||
expect(finalizeCacheEntryMock).toHaveBeenCalledWith({
|
||||
key,
|
||||
version: cacheVersion,
|
||||
sizeBytes: archiveFileSize.toString()
|
||||
})
|
||||
|
||||
expect(getCompressionMock).toHaveBeenCalledTimes(1)
|
||||
expect(expectedCacheId).toBe(cacheId)
|
||||
})
|
||||
|
||||
test('save with non existing path should not save cache using v2 saveCache', async () => {
|
||||
const path = 'node_modules'
|
||||
const key = 'Linux-node-bb828da54c148048dd17899ba9fda624811cfb43'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
import {maskSigUrl, maskSecretUrls} from '../src/internal/shared/util'
|
||||
import {setSecret, debug} from '@actions/core'
|
||||
|
||||
jest.mock('@actions/core')
|
||||
|
||||
describe('maskSigUrl', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('does nothing if no sig parameter is present', () => {
|
||||
const url = 'https://example.com'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('masks the sig parameter in the middle of the URL and sets it as a secret', () => {
|
||||
const url = 'https://example.com/?param1=value1&sig=12345¶m2=value2'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('12345')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('12345'))
|
||||
})
|
||||
|
||||
it('does nothing if the URL is empty', () => {
|
||||
const url = ''
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('handles URLs with fragments', () => {
|
||||
const url = 'https://example.com?sig=12345#fragment'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('12345')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('12345'))
|
||||
})
|
||||
})
|
||||
|
||||
describe('maskSigUrl handles special characters in signatures', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('handles signatures with slashes', () => {
|
||||
const url = 'https://example.com/?sig=abc/123'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc/123')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%2F123')
|
||||
})
|
||||
|
||||
it('handles signatures with plus signs', () => {
|
||||
const url = 'https://example.com/?sig=abc+123'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc 123')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%20123')
|
||||
})
|
||||
|
||||
it('handles signatures with equals signs', () => {
|
||||
const url = 'https://example.com/?sig=abc=123'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc=123')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%3D123')
|
||||
})
|
||||
|
||||
it('handles already percent-encoded signatures', () => {
|
||||
const url = 'https://example.com/?sig=abc%2F123%3D'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('abc/123=')
|
||||
expect(setSecret).toHaveBeenCalledWith('abc%2F123%3D')
|
||||
})
|
||||
|
||||
it('handles complex Azure SAS signatures', () => {
|
||||
const url =
|
||||
'https://example.com/container/file.txt?sig=nXyQIUj%2F%2F06Cxt80pBRYiiJlYqtPYg5sz%2FvEh5iHAhw%3D&se=2023-12-31'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith(
|
||||
'nXyQIUj//06Cxt80pBRYiiJlYqtPYg5sz/vEh5iHAhw='
|
||||
)
|
||||
expect(setSecret).toHaveBeenCalledWith(
|
||||
'nXyQIUj%2F%2F06Cxt80pBRYiiJlYqtPYg5sz%2FvEh5iHAhw%3D'
|
||||
)
|
||||
})
|
||||
|
||||
it('handles signatures with multiple special characters', () => {
|
||||
const url = 'https://example.com/?sig=a/b+c=d&e=f'
|
||||
maskSigUrl(url)
|
||||
expect(setSecret).toHaveBeenCalledWith('a/b c=d')
|
||||
expect(setSecret).toHaveBeenCalledWith('a%2Fb%20c%3Dd')
|
||||
})
|
||||
})
|
||||
|
||||
describe('maskSecretUrls', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('masks sig parameters in signed_upload_url and signed_download_url', () => {
|
||||
const body = {
|
||||
signed_upload_url: 'https://upload.com?sig=upload123',
|
||||
signed_download_url: 'https://download.com?sig=download123'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).toHaveBeenCalledWith('upload123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('upload123'))
|
||||
expect(setSecret).toHaveBeenCalledWith('download123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('download123'))
|
||||
})
|
||||
|
||||
it('handles case where only upload_url is present', () => {
|
||||
const body = {
|
||||
signed_upload_url: 'https://upload.com?sig=upload123'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).toHaveBeenCalledWith('upload123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('upload123'))
|
||||
})
|
||||
|
||||
it('handles case where only download_url is present', () => {
|
||||
const body = {
|
||||
signed_download_url: 'https://download.com?sig=download123'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).toHaveBeenCalledWith('download123')
|
||||
expect(setSecret).toHaveBeenCalledWith(encodeURIComponent('download123'))
|
||||
})
|
||||
|
||||
it('handles case where URLs do not contain sig parameters', () => {
|
||||
const body = {
|
||||
signed_upload_url: 'https://upload.com?token=abc',
|
||||
signed_download_url: 'https://download.com?token=xyz'
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('handles empty string URLs', () => {
|
||||
const body = {
|
||||
signed_upload_url: '',
|
||||
signed_download_url: ''
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('does nothing if body is not an object or is null', () => {
|
||||
maskSecretUrls(null)
|
||||
expect(debug).toHaveBeenCalledWith('body is not an object or is null')
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('does nothing if signed_upload_url and signed_download_url are not strings', () => {
|
||||
const body = {
|
||||
signed_upload_url: 123,
|
||||
signed_download_url: 456
|
||||
}
|
||||
maskSecretUrls(body)
|
||||
expect(setSecret).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@actions/cache",
|
||||
"version": "4.0.0",
|
||||
"version": "5.0.0",
|
||||
"preview": true,
|
||||
"description": "Actions cache lib",
|
||||
"keywords": [
|
||||
|
|
@ -40,17 +40,22 @@
|
|||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.0.1",
|
||||
"@actions/glob": "^0.1.0",
|
||||
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
||||
"@actions/http-client": "^2.1.1",
|
||||
"@actions/io": "^1.0.1",
|
||||
"@azure/abort-controller": "^1.1.0",
|
||||
"@azure/ms-rest-js": "^2.6.0",
|
||||
"@azure/storage-blob": "^12.13.0",
|
||||
"@protobuf-ts/plugin": "^2.9.4",
|
||||
"semver": "^6.3.1",
|
||||
"twirp-ts": "^2.5.0"
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.1.0",
|
||||
"@types/semver": "^6.0.0",
|
||||
"@protobuf-ts/plugin": "^2.9.4",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"overrides": {
|
||||
"uri-js": "npm:uri-js-replace@^1.0.1",
|
||||
"node-fetch": "^3.3.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import {
|
|||
FinalizeCacheEntryUploadResponse,
|
||||
GetCacheEntryDownloadURLRequest
|
||||
} from './generated/results/api/v1/cache'
|
||||
import {CacheFileSizeLimit} from './internal/constants'
|
||||
import {HttpClientError} from '@actions/http-client'
|
||||
export class ValidationError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
|
|
@ -29,6 +29,14 @@ export class ReserveCacheError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class FinalizeCacheError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
this.name = 'FinalizeCacheError'
|
||||
Object.setPrototypeOf(this, FinalizeCacheError.prototype)
|
||||
}
|
||||
}
|
||||
|
||||
function checkPaths(paths: string[]): void {
|
||||
if (!paths || paths.length === 0) {
|
||||
throw new ValidationError(
|
||||
|
|
@ -57,7 +65,18 @@ function checkKey(key: string): void {
|
|||
* @returns boolean return true if Actions cache service feature is available, otherwise false
|
||||
*/
|
||||
export function isFeatureAvailable(): boolean {
|
||||
return !!process.env['ACTIONS_CACHE_URL']
|
||||
const cacheServiceVersion = getCacheServiceVersion()
|
||||
|
||||
// Check availability based on cache service version
|
||||
switch (cacheServiceVersion) {
|
||||
case 'v2':
|
||||
// For v2, we need ACTIONS_RESULTS_URL
|
||||
return !!process.env['ACTIONS_RESULTS_URL']
|
||||
case 'v1':
|
||||
default:
|
||||
// For v1, we only need ACTIONS_CACHE_URL
|
||||
return !!process.env['ACTIONS_CACHE_URL']
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -186,8 +205,17 @@ async function restoreCacheV1(
|
|||
if (typedError.name === ValidationError.name) {
|
||||
throw error
|
||||
} else {
|
||||
// Supress all non-validation cache related errors because caching should be optional
|
||||
core.warning(`Failed to restore: ${(error as Error).message}`)
|
||||
// warn on cache restore failure and continue build
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
if (
|
||||
typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500
|
||||
) {
|
||||
core.error(`Failed to restore: ${(error as Error).message}`)
|
||||
} else {
|
||||
core.warning(`Failed to restore: ${(error as Error).message}`)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Try to delete the archive to save space
|
||||
|
|
@ -256,11 +284,20 @@ async function restoreCacheV2(
|
|||
const response = await twirpClient.GetCacheEntryDownloadURL(request)
|
||||
|
||||
if (!response.ok) {
|
||||
core.warning(`Cache not found for keys: ${keys.join(', ')}`)
|
||||
core.debug(
|
||||
`Cache not found for version ${request.version} of keys: ${keys.join(
|
||||
', '
|
||||
)}`
|
||||
)
|
||||
return undefined
|
||||
}
|
||||
|
||||
core.info(`Cache hit for: ${request.key}`)
|
||||
const isRestoreKeyMatch = request.key !== response.matchedKey
|
||||
if (isRestoreKeyMatch) {
|
||||
core.info(`Cache hit for restore-key: ${response.matchedKey}`)
|
||||
} else {
|
||||
core.info(`Cache hit for: ${response.matchedKey}`)
|
||||
}
|
||||
|
||||
if (options?.lookupOnly) {
|
||||
core.info('Lookup only - skipping download')
|
||||
|
|
@ -301,7 +338,16 @@ async function restoreCacheV2(
|
|||
throw error
|
||||
} else {
|
||||
// Supress all non-validation cache related errors because caching should be optional
|
||||
core.warning(`Failed to restore: ${(error as Error).message}`)
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
if (
|
||||
typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500
|
||||
) {
|
||||
core.error(`Failed to restore: ${(error as Error).message}`)
|
||||
} else {
|
||||
core.warning(`Failed to restore: ${(error as Error).message}`)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
|
|
@ -433,7 +479,16 @@ async function saveCacheV1(
|
|||
} else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`)
|
||||
} else {
|
||||
core.warning(`Failed to save: ${typedError.message}`)
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
if (
|
||||
typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500
|
||||
) {
|
||||
core.error(`Failed to save: ${typedError.message}`)
|
||||
} else {
|
||||
core.warning(`Failed to save: ${typedError.message}`)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Try to delete the archive to save space
|
||||
|
|
@ -502,15 +557,6 @@ async function saveCacheV2(
|
|||
const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath)
|
||||
core.debug(`File Size: ${archiveFileSize}`)
|
||||
|
||||
// For GHES, this check will take place in ReserveCache API with enterprise file size limit
|
||||
if (archiveFileSize > CacheFileSizeLimit && !isGhes()) {
|
||||
throw new Error(
|
||||
`Cache size of ~${Math.round(
|
||||
archiveFileSize / (1024 * 1024)
|
||||
)} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`
|
||||
)
|
||||
}
|
||||
|
||||
// Set the archive size in the options, will be used to display the upload progress
|
||||
options.archiveSizeBytes = archiveFileSize
|
||||
|
||||
|
|
@ -525,8 +571,19 @@ async function saveCacheV2(
|
|||
version
|
||||
}
|
||||
|
||||
const response = await twirpClient.CreateCacheEntry(request)
|
||||
if (!response.ok) {
|
||||
let signedUploadUrl
|
||||
|
||||
try {
|
||||
const response = await twirpClient.CreateCacheEntry(request)
|
||||
if (!response.ok) {
|
||||
if (response.message) {
|
||||
core.warning(`Cache reservation failed: ${response.message}`)
|
||||
}
|
||||
throw new Error(response.message || 'Response was not ok')
|
||||
}
|
||||
signedUploadUrl = response.signedUploadUrl
|
||||
} catch (error) {
|
||||
core.debug(`Failed to reserve cache: ${error}`)
|
||||
throw new ReserveCacheError(
|
||||
`Unable to reserve cache with key ${key}, another job may be creating this cache.`
|
||||
)
|
||||
|
|
@ -536,7 +593,7 @@ async function saveCacheV2(
|
|||
await cacheHttpClient.saveCache(
|
||||
cacheId,
|
||||
archivePath,
|
||||
response.signedUploadUrl,
|
||||
signedUploadUrl,
|
||||
options
|
||||
)
|
||||
|
||||
|
|
@ -551,6 +608,9 @@ async function saveCacheV2(
|
|||
core.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`)
|
||||
|
||||
if (!finalizeResponse.ok) {
|
||||
if (finalizeResponse.message) {
|
||||
throw new FinalizeCacheError(finalizeResponse.message)
|
||||
}
|
||||
throw new Error(
|
||||
`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`
|
||||
)
|
||||
|
|
@ -563,8 +623,19 @@ async function saveCacheV2(
|
|||
throw error
|
||||
} else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`)
|
||||
} else if (typedError.name === FinalizeCacheError.name) {
|
||||
core.warning(typedError.message)
|
||||
} else {
|
||||
core.warning(`Failed to save: ${typedError.message}`)
|
||||
// Log server errors (5xx) as errors, all other errors as warnings
|
||||
if (
|
||||
typedError instanceof HttpClientError &&
|
||||
typeof typedError.statusCode === 'number' &&
|
||||
typedError.statusCode >= 500
|
||||
) {
|
||||
core.error(`Failed to save: ${typedError.message}`)
|
||||
} else {
|
||||
core.warning(`Failed to save: ${typedError.message}`)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Try to delete the archive to save space
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
|
|||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
import { CacheEntry } from "../../entities/v1/cacheentry";
|
||||
import { CacheMetadata } from "../../entities/v1/cachemetadata";
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.CreateCacheEntryRequest
|
||||
|
|
@ -51,6 +50,12 @@ export interface CreateCacheEntryResponse {
|
|||
* @generated from protobuf field: string signed_upload_url = 2;
|
||||
*/
|
||||
signedUploadUrl: string;
|
||||
/**
|
||||
* When !ok, this field may contain a human-readable error message used to create an annotation
|
||||
*
|
||||
* @generated from protobuf field: string message = 3;
|
||||
*/
|
||||
message: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.FinalizeCacheEntryUploadRequest
|
||||
|
|
@ -95,6 +100,12 @@ export interface FinalizeCacheEntryUploadResponse {
|
|||
* @generated from protobuf field: int64 entry_id = 2;
|
||||
*/
|
||||
entryId: string;
|
||||
/**
|
||||
* When !ok, this field may contain a human-readable error message used to create an annotation
|
||||
*
|
||||
* @generated from protobuf field: string message = 3;
|
||||
*/
|
||||
message: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.GetCacheEntryDownloadURLRequest
|
||||
|
|
@ -146,118 +157,6 @@ export interface GetCacheEntryDownloadURLResponse {
|
|||
*/
|
||||
matchedKey: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.DeleteCacheEntryRequest
|
||||
*/
|
||||
export interface DeleteCacheEntryRequest {
|
||||
/**
|
||||
* Scope and other metadata for the cache entry
|
||||
*
|
||||
* @generated from protobuf field: github.actions.results.entities.v1.CacheMetadata metadata = 1;
|
||||
*/
|
||||
metadata?: CacheMetadata;
|
||||
/**
|
||||
* An explicit key for a cache entry
|
||||
*
|
||||
* @generated from protobuf field: string key = 2;
|
||||
*/
|
||||
key: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.DeleteCacheEntryResponse
|
||||
*/
|
||||
export interface DeleteCacheEntryResponse {
|
||||
/**
|
||||
* @generated from protobuf field: bool ok = 1;
|
||||
*/
|
||||
ok: boolean;
|
||||
/**
|
||||
* Cache entry database ID
|
||||
*
|
||||
* @generated from protobuf field: int64 entry_id = 2;
|
||||
*/
|
||||
entryId: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.ListCacheEntriesRequest
|
||||
*/
|
||||
export interface ListCacheEntriesRequest {
|
||||
/**
|
||||
* Scope and other metadata for the cache entry
|
||||
*
|
||||
* @generated from protobuf field: github.actions.results.entities.v1.CacheMetadata metadata = 1;
|
||||
*/
|
||||
metadata?: CacheMetadata;
|
||||
/**
|
||||
* An explicit key for a cache entry
|
||||
*
|
||||
* @generated from protobuf field: string key = 2;
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* Restore keys used for prefix searching
|
||||
*
|
||||
* @generated from protobuf field: repeated string restore_keys = 3;
|
||||
*/
|
||||
restoreKeys: string[];
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.ListCacheEntriesResponse
|
||||
*/
|
||||
export interface ListCacheEntriesResponse {
|
||||
/**
|
||||
* Cache entries in the defined scope
|
||||
*
|
||||
* @generated from protobuf field: repeated github.actions.results.entities.v1.CacheEntry entries = 1;
|
||||
*/
|
||||
entries: CacheEntry[];
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.LookupCacheEntryRequest
|
||||
*/
|
||||
export interface LookupCacheEntryRequest {
|
||||
/**
|
||||
* Scope and other metadata for the cache entry
|
||||
*
|
||||
* @generated from protobuf field: github.actions.results.entities.v1.CacheMetadata metadata = 1;
|
||||
*/
|
||||
metadata?: CacheMetadata;
|
||||
/**
|
||||
* An explicit key for a cache entry
|
||||
*
|
||||
* @generated from protobuf field: string key = 2;
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* Restore keys used for prefix searching
|
||||
*
|
||||
* @generated from protobuf field: repeated string restore_keys = 3;
|
||||
*/
|
||||
restoreKeys: string[];
|
||||
/**
|
||||
* Hash of the compression tool, runner OS and paths cached
|
||||
*
|
||||
* @generated from protobuf field: string version = 4;
|
||||
*/
|
||||
version: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.api.v1.LookupCacheEntryResponse
|
||||
*/
|
||||
export interface LookupCacheEntryResponse {
|
||||
/**
|
||||
* Indicates whether the cache entry exists or not
|
||||
*
|
||||
* @generated from protobuf field: bool exists = 1;
|
||||
*/
|
||||
exists: boolean;
|
||||
/**
|
||||
* Matched cache entry metadata
|
||||
*
|
||||
* @generated from protobuf field: github.actions.results.entities.v1.CacheEntry entry = 2;
|
||||
*/
|
||||
entry?: CacheEntry;
|
||||
}
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class CreateCacheEntryRequest$Type extends MessageType<CreateCacheEntryRequest> {
|
||||
constructor() {
|
||||
|
|
@ -324,11 +223,12 @@ class CreateCacheEntryResponse$Type extends MessageType<CreateCacheEntryResponse
|
|||
constructor() {
|
||||
super("github.actions.results.api.v1.CreateCacheEntryResponse", [
|
||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
{ no: 2, name: "signed_upload_url", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<CreateCacheEntryResponse>): CreateCacheEntryResponse {
|
||||
const message = { ok: false, signedUploadUrl: "" };
|
||||
const message = { ok: false, signedUploadUrl: "", message: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<CreateCacheEntryResponse>(this, message, value);
|
||||
|
|
@ -345,6 +245,9 @@ class CreateCacheEntryResponse$Type extends MessageType<CreateCacheEntryResponse
|
|||
case /* string signed_upload_url */ 2:
|
||||
message.signedUploadUrl = reader.string();
|
||||
break;
|
||||
case /* string message */ 3:
|
||||
message.message = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
|
|
@ -363,6 +266,9 @@ class CreateCacheEntryResponse$Type extends MessageType<CreateCacheEntryResponse
|
|||
/* string signed_upload_url = 2; */
|
||||
if (message.signedUploadUrl !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.signedUploadUrl);
|
||||
/* string message = 3; */
|
||||
if (message.message !== "")
|
||||
writer.tag(3, WireType.LengthDelimited).string(message.message);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
|
|
@ -446,11 +352,12 @@ class FinalizeCacheEntryUploadResponse$Type extends MessageType<FinalizeCacheEnt
|
|||
constructor() {
|
||||
super("github.actions.results.api.v1.FinalizeCacheEntryUploadResponse", [
|
||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
||||
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
|
||||
{ no: 3, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<FinalizeCacheEntryUploadResponse>): FinalizeCacheEntryUploadResponse {
|
||||
const message = { ok: false, entryId: "0" };
|
||||
const message = { ok: false, entryId: "0", message: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<FinalizeCacheEntryUploadResponse>(this, message, value);
|
||||
|
|
@ -467,6 +374,9 @@ class FinalizeCacheEntryUploadResponse$Type extends MessageType<FinalizeCacheEnt
|
|||
case /* int64 entry_id */ 2:
|
||||
message.entryId = reader.int64().toString();
|
||||
break;
|
||||
case /* string message */ 3:
|
||||
message.message = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
|
|
@ -485,6 +395,9 @@ class FinalizeCacheEntryUploadResponse$Type extends MessageType<FinalizeCacheEnt
|
|||
/* int64 entry_id = 2; */
|
||||
if (message.entryId !== "0")
|
||||
writer.tag(2, WireType.Varint).int64(message.entryId);
|
||||
/* string message = 3; */
|
||||
if (message.message !== "")
|
||||
writer.tag(3, WireType.LengthDelimited).string(message.message);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
|
|
@ -624,352 +537,11 @@ class GetCacheEntryDownloadURLResponse$Type extends MessageType<GetCacheEntryDow
|
|||
* @generated MessageType for protobuf message github.actions.results.api.v1.GetCacheEntryDownloadURLResponse
|
||||
*/
|
||||
export const GetCacheEntryDownloadURLResponse = new GetCacheEntryDownloadURLResponse$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class DeleteCacheEntryRequest$Type extends MessageType<DeleteCacheEntryRequest> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.DeleteCacheEntryRequest", [
|
||||
{ no: 1, name: "metadata", kind: "message", T: () => CacheMetadata },
|
||||
{ no: 2, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<DeleteCacheEntryRequest>): DeleteCacheEntryRequest {
|
||||
const message = { key: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<DeleteCacheEntryRequest>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeleteCacheEntryRequest): DeleteCacheEntryRequest {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* github.actions.results.entities.v1.CacheMetadata metadata */ 1:
|
||||
message.metadata = CacheMetadata.internalBinaryRead(reader, reader.uint32(), options, message.metadata);
|
||||
break;
|
||||
case /* string key */ 2:
|
||||
message.key = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: DeleteCacheEntryRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* github.actions.results.entities.v1.CacheMetadata metadata = 1; */
|
||||
if (message.metadata)
|
||||
CacheMetadata.internalBinaryWrite(message.metadata, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
/* string key = 2; */
|
||||
if (message.key !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.key);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.DeleteCacheEntryRequest
|
||||
*/
|
||||
export const DeleteCacheEntryRequest = new DeleteCacheEntryRequest$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class DeleteCacheEntryResponse$Type extends MessageType<DeleteCacheEntryResponse> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.DeleteCacheEntryResponse", [
|
||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "entry_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<DeleteCacheEntryResponse>): DeleteCacheEntryResponse {
|
||||
const message = { ok: false, entryId: "0" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<DeleteCacheEntryResponse>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeleteCacheEntryResponse): DeleteCacheEntryResponse {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* bool ok */ 1:
|
||||
message.ok = reader.bool();
|
||||
break;
|
||||
case /* int64 entry_id */ 2:
|
||||
message.entryId = reader.int64().toString();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: DeleteCacheEntryResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* bool ok = 1; */
|
||||
if (message.ok !== false)
|
||||
writer.tag(1, WireType.Varint).bool(message.ok);
|
||||
/* int64 entry_id = 2; */
|
||||
if (message.entryId !== "0")
|
||||
writer.tag(2, WireType.Varint).int64(message.entryId);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.DeleteCacheEntryResponse
|
||||
*/
|
||||
export const DeleteCacheEntryResponse = new DeleteCacheEntryResponse$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class ListCacheEntriesRequest$Type extends MessageType<ListCacheEntriesRequest> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.ListCacheEntriesRequest", [
|
||||
{ no: 1, name: "metadata", kind: "message", T: () => CacheMetadata },
|
||||
{ no: 2, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "restore_keys", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<ListCacheEntriesRequest>): ListCacheEntriesRequest {
|
||||
const message = { key: "", restoreKeys: [] };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<ListCacheEntriesRequest>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ListCacheEntriesRequest): ListCacheEntriesRequest {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* github.actions.results.entities.v1.CacheMetadata metadata */ 1:
|
||||
message.metadata = CacheMetadata.internalBinaryRead(reader, reader.uint32(), options, message.metadata);
|
||||
break;
|
||||
case /* string key */ 2:
|
||||
message.key = reader.string();
|
||||
break;
|
||||
case /* repeated string restore_keys */ 3:
|
||||
message.restoreKeys.push(reader.string());
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: ListCacheEntriesRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* github.actions.results.entities.v1.CacheMetadata metadata = 1; */
|
||||
if (message.metadata)
|
||||
CacheMetadata.internalBinaryWrite(message.metadata, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
/* string key = 2; */
|
||||
if (message.key !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.key);
|
||||
/* repeated string restore_keys = 3; */
|
||||
for (let i = 0; i < message.restoreKeys.length; i++)
|
||||
writer.tag(3, WireType.LengthDelimited).string(message.restoreKeys[i]);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.ListCacheEntriesRequest
|
||||
*/
|
||||
export const ListCacheEntriesRequest = new ListCacheEntriesRequest$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class ListCacheEntriesResponse$Type extends MessageType<ListCacheEntriesResponse> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.ListCacheEntriesResponse", [
|
||||
{ no: 1, name: "entries", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => CacheEntry }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<ListCacheEntriesResponse>): ListCacheEntriesResponse {
|
||||
const message = { entries: [] };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<ListCacheEntriesResponse>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ListCacheEntriesResponse): ListCacheEntriesResponse {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* repeated github.actions.results.entities.v1.CacheEntry entries */ 1:
|
||||
message.entries.push(CacheEntry.internalBinaryRead(reader, reader.uint32(), options));
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: ListCacheEntriesResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* repeated github.actions.results.entities.v1.CacheEntry entries = 1; */
|
||||
for (let i = 0; i < message.entries.length; i++)
|
||||
CacheEntry.internalBinaryWrite(message.entries[i], writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.ListCacheEntriesResponse
|
||||
*/
|
||||
export const ListCacheEntriesResponse = new ListCacheEntriesResponse$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class LookupCacheEntryRequest$Type extends MessageType<LookupCacheEntryRequest> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.LookupCacheEntryRequest", [
|
||||
{ no: 1, name: "metadata", kind: "message", T: () => CacheMetadata },
|
||||
{ no: 2, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "restore_keys", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 4, name: "version", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<LookupCacheEntryRequest>): LookupCacheEntryRequest {
|
||||
const message = { key: "", restoreKeys: [], version: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<LookupCacheEntryRequest>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LookupCacheEntryRequest): LookupCacheEntryRequest {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* github.actions.results.entities.v1.CacheMetadata metadata */ 1:
|
||||
message.metadata = CacheMetadata.internalBinaryRead(reader, reader.uint32(), options, message.metadata);
|
||||
break;
|
||||
case /* string key */ 2:
|
||||
message.key = reader.string();
|
||||
break;
|
||||
case /* repeated string restore_keys */ 3:
|
||||
message.restoreKeys.push(reader.string());
|
||||
break;
|
||||
case /* string version */ 4:
|
||||
message.version = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: LookupCacheEntryRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* github.actions.results.entities.v1.CacheMetadata metadata = 1; */
|
||||
if (message.metadata)
|
||||
CacheMetadata.internalBinaryWrite(message.metadata, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
/* string key = 2; */
|
||||
if (message.key !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.key);
|
||||
/* repeated string restore_keys = 3; */
|
||||
for (let i = 0; i < message.restoreKeys.length; i++)
|
||||
writer.tag(3, WireType.LengthDelimited).string(message.restoreKeys[i]);
|
||||
/* string version = 4; */
|
||||
if (message.version !== "")
|
||||
writer.tag(4, WireType.LengthDelimited).string(message.version);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.LookupCacheEntryRequest
|
||||
*/
|
||||
export const LookupCacheEntryRequest = new LookupCacheEntryRequest$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class LookupCacheEntryResponse$Type extends MessageType<LookupCacheEntryResponse> {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.LookupCacheEntryResponse", [
|
||||
{ no: 1, name: "exists", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "entry", kind: "message", T: () => CacheEntry }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<LookupCacheEntryResponse>): LookupCacheEntryResponse {
|
||||
const message = { exists: false };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<LookupCacheEntryResponse>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: LookupCacheEntryResponse): LookupCacheEntryResponse {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* bool exists */ 1:
|
||||
message.exists = reader.bool();
|
||||
break;
|
||||
case /* github.actions.results.entities.v1.CacheEntry entry */ 2:
|
||||
message.entry = CacheEntry.internalBinaryRead(reader, reader.uint32(), options, message.entry);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: LookupCacheEntryResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* bool exists = 1; */
|
||||
if (message.exists !== false)
|
||||
writer.tag(1, WireType.Varint).bool(message.exists);
|
||||
/* github.actions.results.entities.v1.CacheEntry entry = 2; */
|
||||
if (message.entry)
|
||||
CacheEntry.internalBinaryWrite(message.entry, writer.tag(2, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.LookupCacheEntryResponse
|
||||
*/
|
||||
export const LookupCacheEntryResponse = new LookupCacheEntryResponse$Type();
|
||||
/**
|
||||
* @generated ServiceType for protobuf service github.actions.results.api.v1.CacheService
|
||||
*/
|
||||
export const CacheService = new ServiceType("github.actions.results.api.v1.CacheService", [
|
||||
{ name: "CreateCacheEntry", options: {}, I: CreateCacheEntryRequest, O: CreateCacheEntryResponse },
|
||||
{ name: "FinalizeCacheEntryUpload", options: {}, I: FinalizeCacheEntryUploadRequest, O: FinalizeCacheEntryUploadResponse },
|
||||
{ name: "GetCacheEntryDownloadURL", options: {}, I: GetCacheEntryDownloadURLRequest, O: GetCacheEntryDownloadURLResponse },
|
||||
{ name: "DeleteCacheEntry", options: {}, I: DeleteCacheEntryRequest, O: DeleteCacheEntryResponse },
|
||||
{ name: "ListCacheEntries", options: {}, I: ListCacheEntriesRequest, O: ListCacheEntriesResponse },
|
||||
{ name: "LookupCacheEntry", options: {}, I: LookupCacheEntryRequest, O: LookupCacheEntryResponse }
|
||||
{ name: "GetCacheEntryDownloadURL", options: {}, I: GetCacheEntryDownloadURLRequest, O: GetCacheEntryDownloadURLResponse }
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,157 @@
|
|||
import {
|
||||
CreateCacheEntryRequest,
|
||||
CreateCacheEntryResponse,
|
||||
FinalizeCacheEntryUploadRequest,
|
||||
FinalizeCacheEntryUploadResponse,
|
||||
GetCacheEntryDownloadURLRequest,
|
||||
GetCacheEntryDownloadURLResponse,
|
||||
} from "./cache";
|
||||
|
||||
//==================================//
|
||||
// Client Code //
|
||||
//==================================//
|
||||
|
||||
interface Rpc {
|
||||
request(
|
||||
service: string,
|
||||
method: string,
|
||||
contentType: "application/json" | "application/protobuf",
|
||||
data: object | Uint8Array
|
||||
): Promise<object | Uint8Array>;
|
||||
}
|
||||
|
||||
export interface CacheServiceClient {
|
||||
CreateCacheEntry(
|
||||
request: CreateCacheEntryRequest
|
||||
): Promise<CreateCacheEntryResponse>;
|
||||
FinalizeCacheEntryUpload(
|
||||
request: FinalizeCacheEntryUploadRequest
|
||||
): Promise<FinalizeCacheEntryUploadResponse>;
|
||||
GetCacheEntryDownloadURL(
|
||||
request: GetCacheEntryDownloadURLRequest
|
||||
): Promise<GetCacheEntryDownloadURLResponse>;
|
||||
}
|
||||
|
||||
export class CacheServiceClientJSON implements CacheServiceClient {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
this.CreateCacheEntry.bind(this);
|
||||
this.FinalizeCacheEntryUpload.bind(this);
|
||||
this.GetCacheEntryDownloadURL.bind(this);
|
||||
}
|
||||
CreateCacheEntry(
|
||||
request: CreateCacheEntryRequest
|
||||
): Promise<CreateCacheEntryResponse> {
|
||||
const data = CreateCacheEntryRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.CacheService",
|
||||
"CreateCacheEntry",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
CreateCacheEntryResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
FinalizeCacheEntryUpload(
|
||||
request: FinalizeCacheEntryUploadRequest
|
||||
): Promise<FinalizeCacheEntryUploadResponse> {
|
||||
const data = FinalizeCacheEntryUploadRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.CacheService",
|
||||
"FinalizeCacheEntryUpload",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
FinalizeCacheEntryUploadResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
GetCacheEntryDownloadURL(
|
||||
request: GetCacheEntryDownloadURLRequest
|
||||
): Promise<GetCacheEntryDownloadURLResponse> {
|
||||
const data = GetCacheEntryDownloadURLRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.CacheService",
|
||||
"GetCacheEntryDownloadURL",
|
||||
"application/json",
|
||||
data as object
|
||||
);
|
||||
return promise.then((data) =>
|
||||
GetCacheEntryDownloadURLResponse.fromJson(data as any, {
|
||||
ignoreUnknownFields: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class CacheServiceClientProtobuf implements CacheServiceClient {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
this.CreateCacheEntry.bind(this);
|
||||
this.FinalizeCacheEntryUpload.bind(this);
|
||||
this.GetCacheEntryDownloadURL.bind(this);
|
||||
}
|
||||
CreateCacheEntry(
|
||||
request: CreateCacheEntryRequest
|
||||
): Promise<CreateCacheEntryResponse> {
|
||||
const data = CreateCacheEntryRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.CacheService",
|
||||
"CreateCacheEntry",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
CreateCacheEntryResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
FinalizeCacheEntryUpload(
|
||||
request: FinalizeCacheEntryUploadRequest
|
||||
): Promise<FinalizeCacheEntryUploadResponse> {
|
||||
const data = FinalizeCacheEntryUploadRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.CacheService",
|
||||
"FinalizeCacheEntryUpload",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
FinalizeCacheEntryUploadResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
|
||||
GetCacheEntryDownloadURL(
|
||||
request: GetCacheEntryDownloadURLRequest
|
||||
): Promise<GetCacheEntryDownloadURLResponse> {
|
||||
const data = GetCacheEntryDownloadURLRequest.toBinary(request);
|
||||
const promise = this.rpc.request(
|
||||
"github.actions.results.api.v1.CacheService",
|
||||
"GetCacheEntryDownloadURL",
|
||||
"application/protobuf",
|
||||
data
|
||||
);
|
||||
return promise.then((data) =>
|
||||
GetCacheEntryDownloadURLResponse.fromBinary(data as Uint8Array)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,163 +0,0 @@
|
|||
// @generated by protobuf-ts 2.9.1 with parameter long_type_string,client_none,generate_dependencies
|
||||
// @generated from protobuf file "results/entities/v1/cacheentry.proto" (package "github.actions.results.entities.v1", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
import { Timestamp } from "../../../google/protobuf/timestamp";
|
||||
/**
|
||||
* @generated from protobuf message github.actions.results.entities.v1.CacheEntry
|
||||
*/
|
||||
export interface CacheEntry {
|
||||
/**
|
||||
* An explicit key for a cache entry
|
||||
*
|
||||
* @generated from protobuf field: string key = 1;
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* SHA256 hex digest of the cache archive
|
||||
*
|
||||
* @generated from protobuf field: string hash = 2;
|
||||
*/
|
||||
hash: string;
|
||||
/**
|
||||
* Cache entry size in bytes
|
||||
*
|
||||
* @generated from protobuf field: int64 size_bytes = 3;
|
||||
*/
|
||||
sizeBytes: string;
|
||||
/**
|
||||
* Access scope
|
||||
*
|
||||
* @generated from protobuf field: string scope = 4;
|
||||
*/
|
||||
scope: string;
|
||||
/**
|
||||
* Version SHA256 hex digest
|
||||
*
|
||||
* @generated from protobuf field: string version = 5;
|
||||
*/
|
||||
version: string;
|
||||
/**
|
||||
* When the cache entry was created
|
||||
*
|
||||
* @generated from protobuf field: google.protobuf.Timestamp created_at = 6;
|
||||
*/
|
||||
createdAt?: Timestamp;
|
||||
/**
|
||||
* When the cache entry was last accessed
|
||||
*
|
||||
* @generated from protobuf field: google.protobuf.Timestamp last_accessed_at = 7;
|
||||
*/
|
||||
lastAccessedAt?: Timestamp;
|
||||
/**
|
||||
* When the cache entry is set to expire
|
||||
*
|
||||
* @generated from protobuf field: google.protobuf.Timestamp expires_at = 8;
|
||||
*/
|
||||
expiresAt?: Timestamp;
|
||||
}
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class CacheEntry$Type extends MessageType<CacheEntry> {
|
||||
constructor() {
|
||||
super("github.actions.results.entities.v1.CacheEntry", [
|
||||
{ no: 1, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 2, name: "hash", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "size_bytes", kind: "scalar", T: 3 /*ScalarType.INT64*/ },
|
||||
{ no: 4, name: "scope", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 5, name: "version", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 6, name: "created_at", kind: "message", T: () => Timestamp },
|
||||
{ no: 7, name: "last_accessed_at", kind: "message", T: () => Timestamp },
|
||||
{ no: 8, name: "expires_at", kind: "message", T: () => Timestamp }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<CacheEntry>): CacheEntry {
|
||||
const message = { key: "", hash: "", sizeBytes: "0", scope: "", version: "" };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<CacheEntry>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CacheEntry): CacheEntry {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* string key */ 1:
|
||||
message.key = reader.string();
|
||||
break;
|
||||
case /* string hash */ 2:
|
||||
message.hash = reader.string();
|
||||
break;
|
||||
case /* int64 size_bytes */ 3:
|
||||
message.sizeBytes = reader.int64().toString();
|
||||
break;
|
||||
case /* string scope */ 4:
|
||||
message.scope = reader.string();
|
||||
break;
|
||||
case /* string version */ 5:
|
||||
message.version = reader.string();
|
||||
break;
|
||||
case /* google.protobuf.Timestamp created_at */ 6:
|
||||
message.createdAt = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.createdAt);
|
||||
break;
|
||||
case /* google.protobuf.Timestamp last_accessed_at */ 7:
|
||||
message.lastAccessedAt = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.lastAccessedAt);
|
||||
break;
|
||||
case /* google.protobuf.Timestamp expires_at */ 8:
|
||||
message.expiresAt = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.expiresAt);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: CacheEntry, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* string key = 1; */
|
||||
if (message.key !== "")
|
||||
writer.tag(1, WireType.LengthDelimited).string(message.key);
|
||||
/* string hash = 2; */
|
||||
if (message.hash !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.hash);
|
||||
/* int64 size_bytes = 3; */
|
||||
if (message.sizeBytes !== "0")
|
||||
writer.tag(3, WireType.Varint).int64(message.sizeBytes);
|
||||
/* string scope = 4; */
|
||||
if (message.scope !== "")
|
||||
writer.tag(4, WireType.LengthDelimited).string(message.scope);
|
||||
/* string version = 5; */
|
||||
if (message.version !== "")
|
||||
writer.tag(5, WireType.LengthDelimited).string(message.version);
|
||||
/* google.protobuf.Timestamp created_at = 6; */
|
||||
if (message.createdAt)
|
||||
Timestamp.internalBinaryWrite(message.createdAt, writer.tag(6, WireType.LengthDelimited).fork(), options).join();
|
||||
/* google.protobuf.Timestamp last_accessed_at = 7; */
|
||||
if (message.lastAccessedAt)
|
||||
Timestamp.internalBinaryWrite(message.lastAccessedAt, writer.tag(7, WireType.LengthDelimited).fork(), options).join();
|
||||
/* google.protobuf.Timestamp expires_at = 8; */
|
||||
if (message.expiresAt)
|
||||
Timestamp.internalBinaryWrite(message.expiresAt, writer.tag(8, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.entities.v1.CacheEntry
|
||||
*/
|
||||
export const CacheEntry = new CacheEntry$Type();
|
||||
|
|
@ -5,7 +5,8 @@ import {getCacheServiceURL} from '../config'
|
|||
import {getRuntimeToken} from '../cacheUtils'
|
||||
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
||||
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
|
||||
import {CacheServiceClientJSON} from '../../generated/results/api/v1/cache.twirp'
|
||||
import {CacheServiceClientJSON} from '../../generated/results/api/v1/cache.twirp-client'
|
||||
import {maskSecretUrls} from './util'
|
||||
|
||||
// The twirp http client must implement this interface
|
||||
interface Rpc {
|
||||
|
|
@ -94,6 +95,7 @@ class CacheServiceClient implements Rpc {
|
|||
debug(`[Response] - ${response.message.statusCode}`)
|
||||
debug(`Headers: ${JSON.stringify(response.message.headers, null, 2)}`)
|
||||
const body = JSON.parse(rawBody)
|
||||
maskSecretUrls(body)
|
||||
debug(`Body: ${JSON.stringify(body, null, 2)}`)
|
||||
if (this.isSuccessStatusCode(statusCode)) {
|
||||
return {response, body}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
import {debug, setSecret} from '@actions/core'
|
||||
|
||||
/**
|
||||
* Masks the `sig` parameter in a URL and sets it as a secret.
|
||||
*
|
||||
* @param url - The URL containing the signature parameter to mask
|
||||
* @remarks
|
||||
* This function attempts to parse the provided URL and identify the 'sig' query parameter.
|
||||
* If found, it registers both the raw and URL-encoded signature values as secrets using
|
||||
* the Actions `setSecret` API, which prevents them from being displayed in logs.
|
||||
*
|
||||
* The function handles errors gracefully if URL parsing fails, logging them as debug messages.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Mask a signature in an Azure SAS token URL
|
||||
* maskSigUrl('https://example.blob.core.windows.net/container/file.txt?sig=abc123&se=2023-01-01');
|
||||
* ```
|
||||
*/
|
||||
export function maskSigUrl(url: string): void {
|
||||
if (!url) return
|
||||
try {
|
||||
const parsedUrl = new URL(url)
|
||||
const signature = parsedUrl.searchParams.get('sig')
|
||||
if (signature) {
|
||||
setSecret(signature)
|
||||
setSecret(encodeURIComponent(signature))
|
||||
}
|
||||
} catch (error) {
|
||||
debug(
|
||||
`Failed to parse URL: ${url} ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks sensitive information in URLs containing signature parameters.
|
||||
* Currently supports masking 'sig' parameters in the 'signed_upload_url'
|
||||
* and 'signed_download_url' properties of the provided object.
|
||||
*
|
||||
* @param body - The object should contain a signature
|
||||
* @remarks
|
||||
* This function extracts URLs from the object properties and calls maskSigUrl
|
||||
* on each one to redact sensitive signature information. The function doesn't
|
||||
* modify the original object; it only marks the signatures as secrets for
|
||||
* logging purposes.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const responseBody = {
|
||||
* signed_upload_url: 'https://blob.core.windows.net/?sig=abc123',
|
||||
* signed_download_url: 'https://blob.core/windows.net/?sig=def456'
|
||||
* };
|
||||
* maskSecretUrls(responseBody);
|
||||
* ```
|
||||
*/
|
||||
export function maskSecretUrls(body: Record<string, unknown> | null): void {
|
||||
if (typeof body !== 'object' || body === null) {
|
||||
debug('body is not an object or is null')
|
||||
return
|
||||
}
|
||||
if (
|
||||
'signed_upload_url' in body &&
|
||||
typeof body.signed_upload_url === 'string'
|
||||
) {
|
||||
maskSigUrl(body.signed_upload_url)
|
||||
}
|
||||
if (
|
||||
'signed_download_url' in body &&
|
||||
typeof body.signed_download_url === 'string'
|
||||
) {
|
||||
maskSigUrl(body.signed_download_url)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ import * as core from '@actions/core';
|
|||
|
||||
#### Inputs/Outputs
|
||||
|
||||
Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` set to be false, the input should have a default value in `action.yml`.
|
||||
Action inputs can be read with `getInput` which returns a `string` or `getBooleanInput` which parses a boolean based on the [yaml 1.2 specification](https://yaml.org/spec/1.2/spec.html#id2804923). If `required` is set to be false, the input should have a default value in `action.yml`.
|
||||
|
||||
Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled.
|
||||
|
||||
|
|
|
|||
|
|
@ -11,14 +11,37 @@ export interface CommandProperties {
|
|||
}
|
||||
|
||||
/**
|
||||
* Commands
|
||||
* Issues a command to the GitHub Actions runner
|
||||
*
|
||||
* @param command - The command name to issue
|
||||
* @param properties - Additional properties for the command (key-value pairs)
|
||||
* @param message - The message to include with the command
|
||||
* @remarks
|
||||
* This function outputs a specially formatted string to stdout that the Actions
|
||||
* runner interprets as a command. These commands can control workflow behavior,
|
||||
* set outputs, create annotations, mask values, and more.
|
||||
*
|
||||
* Command Format:
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Issue a warning annotation
|
||||
* issueCommand('warning', {}, 'This is a warning message');
|
||||
* // Output: ::warning::This is a warning message
|
||||
*
|
||||
* // Set an environment variable
|
||||
* issueCommand('set-env', { name: 'MY_VAR' }, 'some value');
|
||||
* // Output: ::set-env name=MY_VAR::some value
|
||||
*
|
||||
* // Add a secret mask
|
||||
* issueCommand('add-mask', {}, 'secretValue123');
|
||||
* // Output: ::add-mask::secretValue123
|
||||
* ```
|
||||
*
|
||||
* @internal
|
||||
* This is an internal utility function that powers the public API functions
|
||||
* such as setSecret, warning, error, and exportVariable.
|
||||
*/
|
||||
export function issueCommand(
|
||||
command: string,
|
||||
|
|
|
|||
|
|
@ -94,7 +94,32 @@ export function exportVariable(name: string, val: any): void {
|
|||
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*
|
||||
* @param secret - Value of the secret to be masked
|
||||
* @remarks
|
||||
* This function instructs the Actions runner to mask the specified value in any
|
||||
* logs produced during the workflow run. Once registered, the secret value will
|
||||
* be replaced with asterisks (***) whenever it appears in console output, logs,
|
||||
* or error messages.
|
||||
*
|
||||
* This is useful for protecting sensitive information such as:
|
||||
* - API keys
|
||||
* - Access tokens
|
||||
* - Authentication credentials
|
||||
* - URL parameters containing signatures (SAS tokens)
|
||||
*
|
||||
* Note that masking only affects future logs; any previous appearances of the
|
||||
* secret in logs before calling this function will remain unmasked.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Register an API token as a secret
|
||||
* const apiToken = "abc123xyz456";
|
||||
* setSecret(apiToken);
|
||||
*
|
||||
* // Now any logs containing this value will show *** instead
|
||||
* console.log(`Using token: ${apiToken}`); // Outputs: "Using token: ***"
|
||||
* ```
|
||||
*/
|
||||
export function setSecret(secret: string): void {
|
||||
issueCommand('add-mask', {}, secret)
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ export async function getDetails(): Promise<{
|
|||
...(await (isWindows
|
||||
? getWindowsInfo()
|
||||
: isMacOS
|
||||
? getMacOsInfo()
|
||||
: getLinuxInfo())),
|
||||
? getMacOsInfo()
|
||||
: getLinuxInfo())),
|
||||
platform,
|
||||
arch,
|
||||
isWindows,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
# @actions/exec Releases
|
||||
|
||||
### 2.0.0
|
||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||
- Bump @actions/io dependency from ^1.0.1 to ^2.0.0
|
||||
|
||||
### 1.1.1
|
||||
- Update `lockfileVersion` to `v2` in `package-lock.json [#1024](https://github.com/actions/toolkit/pull/1024)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,22 @@
|
|||
{
|
||||
"name": "@actions/exec",
|
||||
"version": "1.1.1",
|
||||
"lockfileVersion": 2,
|
||||
"version": "2.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@actions/exec",
|
||||
"version": "1.1.1",
|
||||
"version": "2.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
"@actions/io": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.1.tgz",
|
||||
"integrity": "sha512-rhq+tfZukbtaus7xyUtwKfuiCRXd1hWSfmJNEpFgBQJ4woqPEpsBw04awicjwz9tyG2/MVhAEMfVn664Cri5zA=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/io": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.1.tgz",
|
||||
"integrity": "sha512-rhq+tfZukbtaus7xyUtwKfuiCRXd1hWSfmJNEpFgBQJ4woqPEpsBw04awicjwz9tyG2/MVhAEMfVn664Cri5zA=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-2.0.0.tgz",
|
||||
"integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@actions/exec",
|
||||
"version": "1.1.1",
|
||||
"version": "2.0.0",
|
||||
"description": "Actions exec lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
|
|
@ -36,6 +36,6 @@
|
|||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
"@actions/io": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
# @actions/github Releases
|
||||
|
||||
### 6.0.1
|
||||
|
||||
- Dependency updates [#2043](https://github.com/actions/toolkit/pull/2043)
|
||||
- Add `context.runAttempt` [#1588](https://github.com/actions/toolkit/pull/1588)
|
||||
|
||||
### 6.0.0
|
||||
- Support the latest Octokit in @actions/github [#1553](https://github.com/actions/toolkit/pull/1553)
|
||||
- Drop support of NodeJS v14, v16
|
||||
|
|
|
|||
|
|
@ -1,36 +1,41 @@
|
|||
{
|
||||
"name": "@actions/github",
|
||||
"version": "6.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"version": "6.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@actions/github",
|
||||
"version": "6.0.0",
|
||||
"version": "6.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.2.0",
|
||||
"@octokit/core": "^5.0.1",
|
||||
"@octokit/plugin-paginate-rest": "^9.0.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^10.0.0"
|
||||
"@octokit/plugin-paginate-rest": "^9.2.2",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"undici": "^5.28.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"proxy": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz",
|
||||
"integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
|
||||
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
|
|
@ -39,20 +44,22 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz",
|
||||
"integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==",
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz",
|
||||
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^4.0.0",
|
||||
"@octokit/graphql": "^7.0.0",
|
||||
"@octokit/request": "^8.0.2",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"@octokit/graphql": "^7.1.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@octokit/types": "^13.0.0",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
|
|
@ -61,12 +68,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz",
|
||||
"integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==",
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -74,12 +81,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
|
||||
"integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz",
|
||||
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^8.0.1",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/types": "^13.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -87,47 +95,80 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz",
|
||||
"integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
||||
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0"
|
||||
"@octokit/types": "^12.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=5"
|
||||
"@octokit/core": "5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||
"version": "12.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.0.tgz",
|
||||
"integrity": "sha512-16VkwE2v6rXU+/gBsYC62M8lKWOphY5Lg4wpjYnVE9Zbu0J6IwiT5kILoj1YOB53XLmcJR+Nqp8DmifOPY4H3g==",
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
|
||||
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0"
|
||||
"@octokit/types": "^12.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=5"
|
||||
"@octokit/core": "5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
|
||||
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||
"version": "12.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
|
||||
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "8.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.4.tgz",
|
||||
"integrity": "sha512-M0aaFfpGPEKrg7XoA/gwgRvc9MSXHRO2Ioki1qrPDbl1e9YhjIwVoHE7HIKmv/m3idzldj//xBujcFNqGX6ENA==",
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
||||
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^9.0.0",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"@octokit/endpoint": "^9.0.6",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -135,11 +176,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz",
|
||||
"integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
||||
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^12.0.0",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
|
|
@ -148,11 +190,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
|
||||
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^19.0.0"
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
|
|
@ -160,6 +203,7 @@
|
|||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
|
|
@ -172,6 +216,7 @@
|
|||
"resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz",
|
||||
"integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"camelcase": "5.0.0",
|
||||
"chalk": "2.4.2",
|
||||
|
|
@ -189,15 +234,17 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
|
||||
"integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw=="
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
|
||||
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
|
@ -207,6 +254,7 @@
|
|||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
|
|
@ -221,6 +269,7 @@
|
|||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
|
|
@ -229,15 +278,17 @@
|
|||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
|
|
@ -251,13 +302,15 @@
|
|||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"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,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
|
|
@ -267,23 +320,17 @@
|
|||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/leven": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||
"integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -293,34 +340,41 @@
|
|||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz",
|
||||
"integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz",
|
||||
"integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy/-/proxy-2.2.0.tgz",
|
||||
"integrity": "sha512-nYclNIWj9UpXbVJ3W5EXIYiGR88AKZoGt90kyh3zoOBY5QW+7bbtPvMFgKGD4VJmpS3UXQXtlGXSg3lRNLOFLg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"args": "^5.0.3",
|
||||
"basic-auth-parser": "0.0.2-1",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"bin": {
|
||||
"proxy": "dist/bin/proxy.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
|
|
@ -330,6 +384,7 @@
|
|||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
|
|
@ -341,14 +396,16 @@
|
|||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.25.4",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
|
||||
"integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
|
|
@ -357,284 +414,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/http-client": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz",
|
||||
"integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==",
|
||||
"requires": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"@fastify/busboy": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
|
||||
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ=="
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA=="
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz",
|
||||
"integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^4.0.0",
|
||||
"@octokit/graphql": "^7.0.0",
|
||||
"@octokit/request": "^8.0.2",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz",
|
||||
"integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^12.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
|
||||
"integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==",
|
||||
"requires": {
|
||||
"@octokit/request": "^8.0.1",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz",
|
||||
"integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^12.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.0.tgz",
|
||||
"integrity": "sha512-16VkwE2v6rXU+/gBsYC62M8lKWOphY5Lg4wpjYnVE9Zbu0J6IwiT5kILoj1YOB53XLmcJR+Nqp8DmifOPY4H3g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^12.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "8.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.4.tgz",
|
||||
"integrity": "sha512-M0aaFfpGPEKrg7XoA/gwgRvc9MSXHRO2Ioki1qrPDbl1e9YhjIwVoHE7HIKmv/m3idzldj//xBujcFNqGX6ENA==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^9.0.0",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^12.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz",
|
||||
"integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^12.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
|
||||
"integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"args": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz",
|
||||
"integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "5.0.0",
|
||||
"chalk": "2.4.2",
|
||||
"leven": "2.1.0",
|
||||
"mri": "1.1.4"
|
||||
}
|
||||
},
|
||||
"basic-auth-parser": {
|
||||
"version": "0.0.2-1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth-parser/-/basic-auth-parser-0.0.2-1.tgz",
|
||||
"integrity": "sha512-GFj8iVxo9onSU6BnnQvVwqvxh60UcSHJEDnIk3z4B6iOjsKSmqe+ibW0Rsz7YO7IE1HG3D3tqCNIidP46SZVdQ==",
|
||||
"dev": true
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
|
||||
"integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw=="
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
|
||||
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
|
||||
"dev": true
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"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
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"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
|
||||
},
|
||||
"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
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"leven": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||
"integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
|
||||
"dev": true
|
||||
},
|
||||
"mri": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz",
|
||||
"integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"proxy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz",
|
||||
"integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"args": "^5.0.3",
|
||||
"basic-auth-parser": "0.0.2-1",
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
},
|
||||
"undici": {
|
||||
"version": "5.25.4",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
|
||||
"integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
|
||||
"requires": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@actions/github",
|
||||
"version": "6.0.0",
|
||||
"version": "6.0.1",
|
||||
"description": "Actions github lib",
|
||||
"keywords": [
|
||||
"github",
|
||||
|
|
@ -40,10 +40,13 @@
|
|||
"dependencies": {
|
||||
"@actions/http-client": "^2.2.0",
|
||||
"@octokit/core": "^5.0.1",
|
||||
"@octokit/plugin-paginate-rest": "^9.0.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^10.0.0"
|
||||
"@octokit/plugin-paginate-rest": "^9.2.2",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
|
||||
"@octokit/request": "^8.4.1",
|
||||
"@octokit/request-error": "^5.1.1",
|
||||
"undici": "^5.28.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"proxy": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,21 +3,6 @@
|
|||
"version": "0.5.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"description": "Actions glob lib",
|
||||
"files": [
|
||||
"lib",
|
||||
"!.DS_Store"
|
||||
],
|
||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/glob",
|
||||
"keywords": [
|
||||
"github",
|
||||
"actions",
|
||||
"glob"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/glob.js",
|
||||
"preview": true,
|
||||
"types": "lib/glob.d.ts",
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@actions/glob",
|
||||
|
|
@ -29,31 +14,60 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/exec": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
|
||||
"integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6"
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
|
@ -62,12 +76,14 @@
|
|||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -79,37 +95,22 @@
|
|||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
"node_modules/undici": {
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib",
|
||||
"test": "__tests__"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"directory": "packages/glob",
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/actions/toolkit.git"
|
||||
},
|
||||
"scripts": {
|
||||
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
|
||||
"test": "echo \"Error: run tests from root\" && exit 1",
|
||||
"tsc": "tsc"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export async function hashFiles(
|
|||
let hasMatch = false
|
||||
const githubWorkspace = currentWorkspace
|
||||
? currentWorkspace
|
||||
: process.env['GITHUB_WORKSPACE'] ?? process.cwd()
|
||||
: (process.env['GITHUB_WORKSPACE'] ?? process.cwd())
|
||||
const result = crypto.createHash('sha256')
|
||||
let count = 0
|
||||
for await (const file of globber.globGenerator()) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ A lightweight HTTP client optimized for building actions.
|
|||
- HTTP client with TypeScript generics and async/await/Promises
|
||||
- Typings included!
|
||||
- [Proxy support](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-self-hosted-runners#using-a-proxy-server-with-self-hosted-runners) just works with actions and the runner
|
||||
- Targets ES2019 (runner runs actions with node 12+). Only supported on node 12+.
|
||||
- Targets ES2019 (runner runs actions with node 24+). Only supported on node 20+.
|
||||
- Basic, Bearer and PAT Support out of the box. Extensible handlers for others.
|
||||
- Redirects supported
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ export NODE_DEBUG=http
|
|||
|
||||
## Node support
|
||||
|
||||
The http-client is built using the latest LTS version of Node 12. It may work on previous node LTS versions but it's tested and officially supported on Node12+.
|
||||
The http-client is built using Node 24. It may work on previous node LTS versions but it's tested and officially supported on Node 20+.
|
||||
|
||||
## Support and Versioning
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
## Releases
|
||||
|
||||
## 3.0.0
|
||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||
|
||||
## 2.2.3
|
||||
- Fixed an issue where proxy username and password were not handled correctly [#1799](https://github.com/actions/toolkit/pull/1799)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ describe('auth', () => {
|
|||
bh
|
||||
])
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
|
|
@ -26,7 +26,7 @@ describe('auth', () => {
|
|||
'base64'
|
||||
).toString()
|
||||
expect(creds).toBe('johndoe:password')
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does basic http get request with pat token auth', async () => {
|
||||
|
|
@ -38,7 +38,7 @@ describe('auth', () => {
|
|||
ph
|
||||
])
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
|
|
@ -49,7 +49,7 @@ describe('auth', () => {
|
|||
'base64'
|
||||
).toString()
|
||||
expect(creds).toBe(`PAT:${token}`)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does basic http get request with pat token auth', async () => {
|
||||
|
|
@ -60,13 +60,13 @@ describe('auth', () => {
|
|||
ph
|
||||
])
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
const auth: string = obj.headers.authorization
|
||||
expect(auth).toBe(`Bearer ${token}`)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -37,41 +37,41 @@ describe('basics', () => {
|
|||
// "user-agent": "typed-test-client-tests"
|
||||
// },
|
||||
// "origin": "173.95.152.44",
|
||||
// "url": "http://postman-echo.com/get"
|
||||
// "url": "https://postman-echo.com/get"
|
||||
// }
|
||||
|
||||
it('does basic http get request', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(obj.headers['user-agent']).toBeTruthy()
|
||||
})
|
||||
|
||||
it('does basic http get request with no user agent', async () => {
|
||||
const http: httpm.HttpClient = new httpm.HttpClient()
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(obj.headers['user-agent']).toBeFalsy()
|
||||
})
|
||||
|
||||
/* TODO write a mock rather then relying on a third party
|
||||
it('does basic https get request', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
*/
|
||||
it('does basic http get request with default headers', async () => {
|
||||
|
|
@ -86,14 +86,14 @@ describe('basics', () => {
|
|||
}
|
||||
)
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.headers.accept).toBe('application/json')
|
||||
expect(obj.headers['content-type']).toBe('application/json')
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does basic http get request with merged headers', async () => {
|
||||
|
|
@ -108,7 +108,7 @@ describe('basics', () => {
|
|||
}
|
||||
)
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
'http://postman-echo.com/get',
|
||||
'https://postman-echo.com/get',
|
||||
{
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
|
|
@ -120,18 +120,18 @@ describe('basics', () => {
|
|||
expect(obj.headers['content-type']).toBe(
|
||||
'application/x-www-form-urlencoded'
|
||||
)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('pipes a get request', async () => {
|
||||
return new Promise<void>(async resolve => {
|
||||
const file = fs.createWriteStream(sampleFilePath)
|
||||
;(await _http.get('http://postman-echo.com/get')).message
|
||||
;(await _http.get('https://postman-echo.com/get')).message
|
||||
.pipe(file)
|
||||
.on('close', () => {
|
||||
const body: string = fs.readFileSync(sampleFilePath).toString()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
|
@ -139,32 +139,32 @@ describe('basics', () => {
|
|||
|
||||
it('does basic get request with redirects', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
`http://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'http://postman-echo.com/get'
|
||||
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'https://postman-echo.com/get'
|
||||
)}`
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does basic get request with redirects (303)', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
`http://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'http://postman-echo.com/get'
|
||||
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'https://postman-echo.com/get'
|
||||
)}&status_code=303`
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('returns 404 for not found get request on redirect', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
`http://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'http://postman-echo.com/status/404'
|
||||
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'https://postman-echo.com/status/404'
|
||||
)}&status_code=303`
|
||||
)
|
||||
expect(res.message.statusCode).toBe(404)
|
||||
|
|
@ -178,8 +178,8 @@ describe('basics', () => {
|
|||
{allowRedirects: false}
|
||||
)
|
||||
const res: httpm.HttpClientResponse = await http.get(
|
||||
`http://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'http://postman-echo.com/get'
|
||||
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'https://postman-echo.com/get'
|
||||
)}`
|
||||
)
|
||||
expect(res.message.statusCode).toBe(302)
|
||||
|
|
@ -192,8 +192,8 @@ describe('basics', () => {
|
|||
authorization: 'shhh'
|
||||
}
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
`http://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'http://www.postman-echo.com/get'
|
||||
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'https://www.postman-echo.com/get'
|
||||
)}`,
|
||||
headers
|
||||
)
|
||||
|
|
@ -205,7 +205,7 @@ describe('basics', () => {
|
|||
expect(obj.headers[httpm.Headers.Accept]).toBe('application/json')
|
||||
expect(obj.headers['Authorization']).toBeUndefined()
|
||||
expect(obj.headers['authorization']).toBeUndefined()
|
||||
expect(obj.url).toBe('http://www.postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://www.postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does not pass Auth with diff hostname redirects', async () => {
|
||||
|
|
@ -214,8 +214,8 @@ describe('basics', () => {
|
|||
Authorization: 'shhh'
|
||||
}
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
`http://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'http://www.postman-echo.com/get'
|
||||
`https://postman-echo.com/redirect-to?url=${encodeURIComponent(
|
||||
'https://www.postman-echo.com/get'
|
||||
)}`,
|
||||
headers
|
||||
)
|
||||
|
|
@ -227,19 +227,19 @@ describe('basics', () => {
|
|||
expect(obj.headers[httpm.Headers.Accept]).toBe('application/json')
|
||||
expect(obj.headers['Authorization']).toBeUndefined()
|
||||
expect(obj.headers['authorization']).toBeUndefined()
|
||||
expect(obj.url).toBe('http://www.postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://www.postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does basic head request', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.head(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
})
|
||||
|
||||
it('does basic http delete request', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.del(
|
||||
'http://postman-echo.com/delete'
|
||||
'https://postman-echo.com/delete'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
|
|
@ -249,32 +249,32 @@ describe('basics', () => {
|
|||
it('does basic http post request', async () => {
|
||||
const b = 'Hello World!'
|
||||
const res: httpm.HttpClientResponse = await _http.post(
|
||||
'http://postman-echo.com/post',
|
||||
'https://postman-echo.com/post',
|
||||
b
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.data).toBe(b)
|
||||
expect(obj.url).toBe('http://postman-echo.com/post')
|
||||
expect(obj.url).toBe('https://postman-echo.com/post')
|
||||
})
|
||||
|
||||
it('does basic http patch request', async () => {
|
||||
const b = 'Hello World!'
|
||||
const res: httpm.HttpClientResponse = await _http.patch(
|
||||
'http://postman-echo.com/patch',
|
||||
'https://postman-echo.com/patch',
|
||||
b
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.data).toBe(b)
|
||||
expect(obj.url).toBe('http://postman-echo.com/patch')
|
||||
expect(obj.url).toBe('https://postman-echo.com/patch')
|
||||
})
|
||||
|
||||
it('does basic http options request', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.options(
|
||||
'http://postman-echo.com'
|
||||
'https://postman-echo.com'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
await res.readBody()
|
||||
|
|
@ -282,7 +282,7 @@ describe('basics', () => {
|
|||
|
||||
it('returns 404 for not found get request', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
'http://postman-echo.com/status/404'
|
||||
'https://postman-echo.com/status/404'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(404)
|
||||
await res.readBody()
|
||||
|
|
@ -290,11 +290,11 @@ describe('basics', () => {
|
|||
|
||||
it('gets a json object', async () => {
|
||||
const jsonObj = await _http.getJson<HttpBinData>(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(jsonObj.statusCode).toBe(200)
|
||||
expect(jsonObj.result).toBeDefined()
|
||||
expect(jsonObj.result?.url).toBe('http://postman-echo.com/get')
|
||||
expect(jsonObj.result?.url).toBe('https://postman-echo.com/get')
|
||||
expect(jsonObj.result?.headers[httpm.Headers.Accept]).toBe(
|
||||
httpm.MediaTypes.ApplicationJson
|
||||
)
|
||||
|
|
@ -305,7 +305,7 @@ describe('basics', () => {
|
|||
|
||||
it('getting a non existent json object returns null', async () => {
|
||||
const jsonObj = await _http.getJson<HttpBinData>(
|
||||
'http://postman-echo.com/status/404'
|
||||
'https://postman-echo.com/status/404'
|
||||
)
|
||||
expect(jsonObj.statusCode).toBe(404)
|
||||
expect(jsonObj.result).toBeNull()
|
||||
|
|
@ -314,12 +314,12 @@ describe('basics', () => {
|
|||
it('posts a json object', async () => {
|
||||
const res = {name: 'foo'}
|
||||
const restRes = await _http.postJson<HttpBinData>(
|
||||
'http://postman-echo.com/post',
|
||||
'https://postman-echo.com/post',
|
||||
res
|
||||
)
|
||||
expect(restRes.statusCode).toBe(200)
|
||||
expect(restRes.result).toBeDefined()
|
||||
expect(restRes.result?.url).toBe('http://postman-echo.com/post')
|
||||
expect(restRes.result?.url).toBe('https://postman-echo.com/post')
|
||||
expect(restRes.result?.json.name).toBe('foo')
|
||||
expect(restRes.result?.headers[httpm.Headers.Accept]).toBe(
|
||||
httpm.MediaTypes.ApplicationJson
|
||||
|
|
@ -335,12 +335,12 @@ describe('basics', () => {
|
|||
it('puts a json object', async () => {
|
||||
const res = {name: 'foo'}
|
||||
const restRes = await _http.putJson<HttpBinData>(
|
||||
'http://postman-echo.com/put',
|
||||
'https://postman-echo.com/put',
|
||||
res
|
||||
)
|
||||
expect(restRes.statusCode).toBe(200)
|
||||
expect(restRes.result).toBeDefined()
|
||||
expect(restRes.result?.url).toBe('http://postman-echo.com/put')
|
||||
expect(restRes.result?.url).toBe('https://postman-echo.com/put')
|
||||
expect(restRes.result?.json.name).toBe('foo')
|
||||
|
||||
expect(restRes.result?.headers[httpm.Headers.Accept]).toBe(
|
||||
|
|
@ -357,12 +357,12 @@ describe('basics', () => {
|
|||
it('patch a json object', async () => {
|
||||
const res = {name: 'foo'}
|
||||
const restRes = await _http.patchJson<HttpBinData>(
|
||||
'http://postman-echo.com/patch',
|
||||
'https://postman-echo.com/patch',
|
||||
res
|
||||
)
|
||||
expect(restRes.statusCode).toBe(200)
|
||||
expect(restRes.result).toBeDefined()
|
||||
expect(restRes.result?.url).toBe('http://postman-echo.com/patch')
|
||||
expect(restRes.result?.url).toBe('https://postman-echo.com/patch')
|
||||
expect(restRes.result?.json.name).toBe('foo')
|
||||
expect(restRes.result?.headers[httpm.Headers.Accept]).toBe(
|
||||
httpm.MediaTypes.ApplicationJson
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ describe('headers', () => {
|
|||
it('preserves existing headers on getJson', async () => {
|
||||
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
|
||||
let jsonObj = await _http.getJson<any>(
|
||||
'http://postman-echo.com/get',
|
||||
'https://postman-echo.com/get',
|
||||
additionalHeaders
|
||||
)
|
||||
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('foo')
|
||||
|
|
@ -26,7 +26,7 @@ describe('headers', () => {
|
|||
[httpm.Headers.Accept]: 'baz'
|
||||
}
|
||||
}
|
||||
jsonObj = await httpWithHeaders.getJson<any>('http://postman-echo.com/get')
|
||||
jsonObj = await httpWithHeaders.getJson<any>('https://postman-echo.com/get')
|
||||
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
|
||||
expect(jsonObj.headers[httpm.Headers.ContentType]).toContain(
|
||||
httpm.MediaTypes.ApplicationJson
|
||||
|
|
@ -36,7 +36,7 @@ describe('headers', () => {
|
|||
it('preserves existing headers on postJson', async () => {
|
||||
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
|
||||
let jsonObj = await _http.postJson<any>(
|
||||
'http://postman-echo.com/post',
|
||||
'https://postman-echo.com/post',
|
||||
{},
|
||||
additionalHeaders
|
||||
)
|
||||
|
|
@ -52,7 +52,7 @@ describe('headers', () => {
|
|||
}
|
||||
}
|
||||
jsonObj = await httpWithHeaders.postJson<any>(
|
||||
'http://postman-echo.com/post',
|
||||
'https://postman-echo.com/post',
|
||||
{}
|
||||
)
|
||||
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
|
||||
|
|
@ -64,7 +64,7 @@ describe('headers', () => {
|
|||
it('preserves existing headers on putJson', async () => {
|
||||
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
|
||||
let jsonObj = await _http.putJson<any>(
|
||||
'http://postman-echo.com/put',
|
||||
'https://postman-echo.com/put',
|
||||
{},
|
||||
additionalHeaders
|
||||
)
|
||||
|
|
@ -80,7 +80,7 @@ describe('headers', () => {
|
|||
}
|
||||
}
|
||||
jsonObj = await httpWithHeaders.putJson<any>(
|
||||
'http://postman-echo.com/put',
|
||||
'https://postman-echo.com/put',
|
||||
{}
|
||||
)
|
||||
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
|
||||
|
|
@ -92,7 +92,7 @@ describe('headers', () => {
|
|||
it('preserves existing headers on patchJson', async () => {
|
||||
const additionalHeaders = {[httpm.Headers.Accept]: 'foo'}
|
||||
let jsonObj = await _http.patchJson<any>(
|
||||
'http://postman-echo.com/patch',
|
||||
'https://postman-echo.com/patch',
|
||||
{},
|
||||
additionalHeaders
|
||||
)
|
||||
|
|
@ -108,7 +108,7 @@ describe('headers', () => {
|
|||
}
|
||||
}
|
||||
jsonObj = await httpWithHeaders.patchJson<any>(
|
||||
'http://postman-echo.com/patch',
|
||||
'https://postman-echo.com/patch',
|
||||
{}
|
||||
)
|
||||
expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz')
|
||||
|
|
|
|||
|
|
@ -13,30 +13,30 @@ describe('basics', () => {
|
|||
|
||||
it.each([true, false])('creates Agent with keepAlive %s', keepAlive => {
|
||||
const http = new httpm.HttpClient('http-client-tests', [], {keepAlive})
|
||||
const agent = http.getAgent('http://postman-echo.com')
|
||||
const agent = http.getAgent('https://postman-echo.com')
|
||||
expect(agent).toHaveProperty('keepAlive', keepAlive)
|
||||
})
|
||||
|
||||
it('does basic http get request with keepAlive true', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
})
|
||||
|
||||
it('does basic head request with keepAlive true', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.head(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
})
|
||||
|
||||
it('does basic http delete request with keepAlive true', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.del(
|
||||
'http://postman-echo.com/delete'
|
||||
'https://postman-echo.com/delete'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
|
|
@ -46,32 +46,32 @@ describe('basics', () => {
|
|||
it('does basic http post request with keepAlive true', async () => {
|
||||
const b = 'Hello World!'
|
||||
const res: httpm.HttpClientResponse = await _http.post(
|
||||
'http://postman-echo.com/post',
|
||||
'https://postman-echo.com/post',
|
||||
b
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.data).toBe(b)
|
||||
expect(obj.url).toBe('http://postman-echo.com/post')
|
||||
expect(obj.url).toBe('https://postman-echo.com/post')
|
||||
})
|
||||
|
||||
it('does basic http patch request with keepAlive true', async () => {
|
||||
const b = 'Hello World!'
|
||||
const res: httpm.HttpClientResponse = await _http.patch(
|
||||
'http://postman-echo.com/patch',
|
||||
'https://postman-echo.com/patch',
|
||||
b
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.data).toBe(b)
|
||||
expect(obj.url).toBe('http://postman-echo.com/patch')
|
||||
expect(obj.url).toBe('https://postman-echo.com/patch')
|
||||
})
|
||||
|
||||
it('does basic http options request with keepAlive true', async () => {
|
||||
const res: httpm.HttpClientResponse = await _http.options(
|
||||
'http://postman-echo.com'
|
||||
'https://postman-echo.com'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
await res.readBody()
|
||||
|
|
|
|||
|
|
@ -196,16 +196,16 @@ describe('proxy', () => {
|
|||
})
|
||||
|
||||
it('HttpClient does basic http get request through proxy', async () => {
|
||||
process.env['http_proxy'] = _proxyUrl
|
||||
process.env['https_proxy'] = _proxyUrl
|
||||
const httpClient = new httpm.HttpClient()
|
||||
const res: httpm.HttpClientResponse = await httpClient.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(_proxyConnects).toEqual(['postman-echo.com:80'])
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(_proxyConnects).toEqual(['postman-echo.com:443'])
|
||||
})
|
||||
|
||||
it('HttpClient does basic http get request when bypass proxy', async () => {
|
||||
|
|
@ -213,12 +213,12 @@ describe('proxy', () => {
|
|||
process.env['no_proxy'] = 'postman-echo.com'
|
||||
const httpClient = new httpm.HttpClient()
|
||||
const res: httpm.HttpClientResponse = await httpClient.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(_proxyConnects).toHaveLength(0)
|
||||
})
|
||||
|
||||
|
|
@ -228,12 +228,12 @@ describe('proxy', () => {
|
|||
process.env['https_proxy'] = _proxyUrl
|
||||
const httpClient = new httpm.HttpClient()
|
||||
const res: httpm.HttpClientResponse = await httpClient.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(_proxyConnects).toEqual(['postman-echo.com:443'])
|
||||
})
|
||||
*/
|
||||
|
|
@ -243,12 +243,12 @@ describe('proxy', () => {
|
|||
process.env['no_proxy'] = 'postman-echo.com'
|
||||
const httpClient = new httpm.HttpClient()
|
||||
const res: httpm.HttpClientResponse = await httpClient.get(
|
||||
'http://postman-echo.com/get'
|
||||
'https://postman-echo.com/get'
|
||||
)
|
||||
expect(res.message.statusCode).toBe(200)
|
||||
const body: string = await res.readBody()
|
||||
const obj = JSON.parse(body)
|
||||
expect(obj.url).toBe('http://postman-echo.com/get')
|
||||
expect(obj.url).toBe('https://postman-echo.com/get')
|
||||
expect(_proxyConnects).toHaveLength(0)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,43 +1,49 @@
|
|||
{
|
||||
"name": "@actions/http-client",
|
||||
"version": "2.2.3",
|
||||
"lockfileVersion": 2,
|
||||
"version": "3.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@actions/http-client",
|
||||
"version": "2.2.3",
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
"undici": "^5.28.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "20.7.1",
|
||||
"@types/node": "24.1.0",
|
||||
"@types/proxy": "^1.0.1",
|
||||
"@types/tunnel": "0.0.3",
|
||||
"proxy": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
|
||||
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz",
|
||||
"integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==",
|
||||
"dev": true
|
||||
"version": "24.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
|
||||
"integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/proxy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/proxy/-/proxy-1.0.2.tgz",
|
||||
"integrity": "sha512-NDNsg7YuClVzEenn9SUButu43blypWvljGsIkDV7HI4N9apjrS0aeeMTUG0PYa71lD1AvIgvjkBagqHDiomDjA==",
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/proxy/-/proxy-1.0.4.tgz",
|
||||
"integrity": "sha512-KnYy7hpp3wXQ2U0ExvCMF9BvWZ6h2aI0XWb8g705mn26Zmn2HO/eLRi6UuhHELA6MNJtYtiZYWv38gobJN0xXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
|
|
@ -47,6 +53,7 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz",
|
||||
"integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
|
|
@ -56,6 +63,7 @@
|
|||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
|
|
@ -68,6 +76,7 @@
|
|||
"resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz",
|
||||
"integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"camelcase": "5.0.0",
|
||||
"chalk": "2.4.2",
|
||||
|
|
@ -89,6 +98,7 @@
|
|||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
|
||||
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
|
@ -98,6 +108,7 @@
|
|||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
|
|
@ -112,6 +123,7 @@
|
|||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
|
|
@ -120,15 +132,17 @@
|
|||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
|
|
@ -144,6 +158,7 @@
|
|||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
|
|
@ -153,6 +168,7 @@
|
|||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
|
|
@ -162,6 +178,7 @@
|
|||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||
"integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -171,26 +188,32 @@
|
|||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz",
|
||||
"integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz",
|
||||
"integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy/-/proxy-2.2.0.tgz",
|
||||
"integrity": "sha512-nYclNIWj9UpXbVJ3W5EXIYiGR88AKZoGt90kyh3zoOBY5QW+7bbtPvMFgKGD4VJmpS3UXQXtlGXSg3lRNLOFLg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"args": "^5.0.3",
|
||||
"basic-auth-parser": "0.0.2-1",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"bin": {
|
||||
"proxy": "dist/bin/proxy.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
|
|
@ -200,6 +223,7 @@
|
|||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
|
|
@ -211,182 +235,29 @@
|
|||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.25.4",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
|
||||
"integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/busboy": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
|
||||
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz",
|
||||
"integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/proxy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/proxy/-/proxy-1.0.2.tgz",
|
||||
"integrity": "sha512-NDNsg7YuClVzEenn9SUButu43blypWvljGsIkDV7HI4N9apjrS0aeeMTUG0PYa71lD1AvIgvjkBagqHDiomDjA==",
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
|
||||
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tunnel": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz",
|
||||
"integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"args": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz",
|
||||
"integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "5.0.0",
|
||||
"chalk": "2.4.2",
|
||||
"leven": "2.1.0",
|
||||
"mri": "1.1.4"
|
||||
}
|
||||
},
|
||||
"basic-auth-parser": {
|
||||
"version": "0.0.2-1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth-parser/-/basic-auth-parser-0.0.2-1.tgz",
|
||||
"integrity": "sha512-GFj8iVxo9onSU6BnnQvVwqvxh60UcSHJEDnIk3z4B6iOjsKSmqe+ibW0Rsz7YO7IE1HG3D3tqCNIidP46SZVdQ==",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
|
||||
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
|
||||
"dev": true
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"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
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"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
|
||||
},
|
||||
"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
|
||||
},
|
||||
"leven": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||
"integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
|
||||
"dev": true
|
||||
},
|
||||
"mri": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz",
|
||||
"integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"proxy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz",
|
||||
"integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"args": "^5.0.3",
|
||||
"basic-auth-parser": "0.0.2-1",
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
},
|
||||
"undici": {
|
||||
"version": "5.25.4",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
|
||||
"integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
|
||||
"requires": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
}
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@actions/http-client",
|
||||
"version": "2.2.3",
|
||||
"version": "3.0.0",
|
||||
"description": "Actions Http Client",
|
||||
"keywords": [
|
||||
"github",
|
||||
|
|
@ -39,13 +39,16 @@
|
|||
"url": "https://github.com/actions/toolkit/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "20.7.1",
|
||||
"@types/node": "24.1.0",
|
||||
"@types/tunnel": "0.0.3",
|
||||
"proxy": "^2.1.1",
|
||||
"@types/proxy": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
"undici": "^5.28.5"
|
||||
},
|
||||
"overrides": {
|
||||
"uri-js": "npm:uri-js-replace@^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue