Compare commits
158 Commits
version-bumps
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| cf80afb392 | |||
| 0607d7a54b | |||
| 36d90eb54c | |||
| 4ee32849b4 | |||
| d76f9fe99a | |||
| 7e08d73d76 | |||
| 8b842d839b | |||
| 16cd46c365 | |||
| 75b8dd1009 | |||
| a7c6618070 | |||
| 54ad3ca9ba | |||
| 3c424f0d63 | |||
| d9346d8d93 | |||
| 1f375f130a | |||
| 140509034c | |||
| b68d046fe3 | |||
| e4598e374b | |||
| 14a090004e | |||
| 3643ce2db4 | |||
| ffeb50bd02 | |||
| b0917c5a37 | |||
| a8ea745713 | |||
| 0df75b91ff | |||
| 233d556477 | |||
| 23cbecacad | |||
| 74fcfdbd10 | |||
| 20647b6bcf | |||
| 6bd5e50ee1 | |||
| 44d43b5490 | |||
| 76ac4dd95f | |||
| 632b2cbff6 | |||
| 73bdb59ac2 | |||
| 22d35395d4 | |||
| ed4fdc98c4 | |||
| 6211ca9cbd | |||
| 99dfdab194 | |||
| 6ec76cbf3d | |||
| 7c6cc28ed5 | |||
| 8f62bc23d1 | |||
| bbaffb4bb3 | |||
| c23cc6e61c | |||
| 943ff82d3d | |||
| 06bca4509d | |||
| 21229dc09e | |||
| 6fd292ebdd | |||
| 89f01c9125 | |||
| 85466c0f54 | |||
| bd4fb086f1 | |||
| 49c3d09c01 | |||
| 91d76bea50 | |||
| 69f29a1b1c | |||
| 7987771a2b | |||
| 605cc18397 | |||
| 27e5a955bf | |||
| 6fe3c0f3e6 | |||
| 8c90e2297a | |||
| 8351a5d84d | |||
| 5203b671f1 | |||
| 975fcbd402 | |||
| ffae274475 | |||
| 1c20378379 | |||
| 0be0a6ef89 | |||
| ae29a2751b | |||
| b48854e1ac | |||
| 9d912b1840 | |||
| 7a0147b5c6 | |||
| 5793b08cd9 | |||
| ed3ea3b5ba | |||
| c9c663babe | |||
| 0fc1805b46 | |||
| a6e9f4bab2 | |||
| 758b556388 | |||
| 9e060cb3e1 | |||
| 5501ba08b7 | |||
| 4446f00fc7 | |||
| 965dcc7493 | |||
| d464f9dd60 | |||
| c9ab4f9548 | |||
| a2986ee511 | |||
| e827417593 | |||
| b05d26b3fa | |||
| ecdfc18bf2 | |||
| e8e0ce7ad8 | |||
| dc6427f3c3 | |||
| 76339b5f68 | |||
| c0ef67ec49 | |||
| 968fd7f8d3 | |||
| 9b27fa97f9 | |||
| 065cf9f0b1 | |||
| b77f226465 | |||
| f61ae48376 | |||
| 4236fc3e78 | |||
| f366966232 | |||
| bd561a6765 | |||
| 26490f0d3b | |||
| ee91adfbc4 | |||
| a039cff4a1 | |||
| 9dd77993e7 | |||
| dd1bb93c72 | |||
| 7292b3508f | |||
| 4a47af6481 | |||
| a68693e20a | |||
| acf4bd70fb | |||
| 7ae5c2f423 | |||
| d5470e6023 | |||
| e68ab4b91a | |||
| d3a48dd52f | |||
| c4d47c1922 | |||
| 5fc5cdde44 | |||
| 2a9d836b08 | |||
| 3a3b073ef2 | |||
| d3a0fb260e | |||
| be4fdc505f | |||
| 6be37922c5 | |||
| dfc20acda2 | |||
| dc1fec82a6 | |||
| 9339b3573b | |||
| 67a08de5c7 | |||
| d73fffceed | |||
| 16f0b3d28e | |||
| 398e2cb68b | |||
| 4b9031fa77 | |||
| 959cb66bd5 | |||
| 3e0b611f99 | |||
| 83c13c81ba | |||
| bccbba401a | |||
| 3a191eecf6 | |||
| 97f5a6f0dc | |||
| 48a7cdbf9c | |||
| 3f1933edf9 | |||
| 2215c8e5aa | |||
| af6de2cb95 | |||
| 1dc58e3080 | |||
| 20596c1d96 | |||
| 557f80fd03 | |||
| 32c52bb78a | |||
| 6d9a3fe547 | |||
| 4e1c194b34 | |||
| 09cb71a033 | |||
| 2506e78e82 | |||
| f8003d52ff | |||
| e263dfb89d | |||
| 2e53bd8485 | |||
| b5e3b25b34 | |||
| b71834a510 | |||
| c6f0239e63 | |||
| c655f38a0f | |||
| cf8caa4e0d | |||
| 8734e578c6 | |||
| 74ac6db523 | |||
| 6fc2f678c8 | |||
| 5ef62e14dd | |||
| 7b29e67278 | |||
| 9d2227dbb0 | |||
| 5a8462ec27 | |||
| fcaf488df6 | |||
| 2b48e40e62 | |||
| 44ec738e27 |
@@ -57,3 +57,8 @@ This will ask you some questions about the new package. Start with `0.0.0` as th
|
|||||||
```
|
```
|
||||||
|
|
||||||
3. Start developing 😄.
|
3. Start developing 😄.
|
||||||
|
|
||||||
|
## Releasing Packages
|
||||||
|
|
||||||
|
For information on how packages are published to npm, including workflow inputs, dist-tags, and safety guards, see the [release documentation](../docs/release.md).
|
||||||
|
|
||||||
|
|||||||
@@ -71,10 +71,143 @@ jobs:
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Successfully blocked second artifact upload')
|
console.log('Successfully blocked second artifact upload')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upload-single-file:
|
||||||
|
name: Upload Single File (no zip)
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
runs-on: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.runs-on }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Set Node.js 24.x
|
||||||
|
uses: actions/setup-node@v5
|
||||||
|
with:
|
||||||
|
node-version: 24.x
|
||||||
|
|
||||||
|
- name: Install root npm packages
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Compile artifact package
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run tsc
|
||||||
|
working-directory: packages/artifact
|
||||||
|
|
||||||
|
- name: Create file that will be uploaded
|
||||||
|
run: |
|
||||||
|
echo -n 'hello from single file upload' > single-file-${{ matrix.runs-on }}.txt
|
||||||
|
|
||||||
|
- name: Upload Single File Artifact (skipArchive)
|
||||||
|
uses: actions/github-script@v8
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const {default: artifact} = require('./packages/artifact/lib/artifact')
|
||||||
|
|
||||||
|
const artifactName = 'my-single-file-${{ matrix.runs-on }}'
|
||||||
|
console.log('artifactName: ' + artifactName)
|
||||||
|
|
||||||
|
const uploadResult = await artifact.uploadArtifact(
|
||||||
|
artifactName,
|
||||||
|
['single-file-${{ matrix.runs-on }}.txt'],
|
||||||
|
'./',
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
console.log(uploadResult)
|
||||||
|
|
||||||
|
const size = uploadResult.size
|
||||||
|
const id = uploadResult.id
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
throw new Error('Artifact ID is missing from upload result')
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Successfully uploaded single file artifact ${id}`)
|
||||||
|
|
||||||
|
upload-html-file:
|
||||||
|
name: Upload HTML File (no zip)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Set Node.js 24.x
|
||||||
|
uses: actions/setup-node@v5
|
||||||
|
with:
|
||||||
|
node-version: 24.x
|
||||||
|
|
||||||
|
- name: Install root npm packages
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Compile artifact package
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run tsc
|
||||||
|
working-directory: packages/artifact
|
||||||
|
|
||||||
|
- name: Create HTML file
|
||||||
|
run: |
|
||||||
|
cat > report.html << 'EOF'
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Artifact Upload Test Report</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; color: #24292f; }
|
||||||
|
h1 { border-bottom: 1px solid #d0d7de; padding-bottom: 8px; }
|
||||||
|
.success { color: #1a7f37; }
|
||||||
|
.info { background: #ddf4ff; border: 1px solid #54aeff; border-radius: 6px; padding: 12px 16px; margin: 16px 0; }
|
||||||
|
table { border-collapse: collapse; width: 100%; margin: 16px 0; }
|
||||||
|
th, td { border: 1px solid #d0d7de; padding: 8px 12px; text-align: left; }
|
||||||
|
th { background: #f6f8fa; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Artifact Upload Test Report</h1>
|
||||||
|
<div class="info">
|
||||||
|
<strong>This HTML file was uploaded as a single un-zipped artifact.</strong>
|
||||||
|
If you can see this in the browser, the feature is working correctly!
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<tr><th>Property</th><th>Value</th></tr>
|
||||||
|
<tr><td>Upload method</td><td><code>skipArchive: true</code></td></tr>
|
||||||
|
<tr><td>Content-Type</td><td><code>text/html</code></td></tr>
|
||||||
|
<tr><td>File</td><td><code>report.html</code></td></tr>
|
||||||
|
</table>
|
||||||
|
<p class="success">✔ Single file upload is working!</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Upload HTML Artifact (skipArchive)
|
||||||
|
uses: actions/github-script@v8
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const {default: artifact} = require('./packages/artifact/lib/artifact')
|
||||||
|
|
||||||
|
const uploadResult = await artifact.uploadArtifact(
|
||||||
|
'test-report',
|
||||||
|
['report.html'],
|
||||||
|
'./',
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
console.log(uploadResult)
|
||||||
|
console.log(`Successfully uploaded HTML artifact ${uploadResult.id}`)
|
||||||
|
console.log('This artifact is intentionally kept for manual browser verification')
|
||||||
|
|
||||||
verify:
|
verify:
|
||||||
name: Verify and Delete
|
name: Verify and Delete
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [upload]
|
needs: [upload, upload-single-file, upload-html-file]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
@@ -164,6 +297,71 @@ jobs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- name: Download and Verify Single File Artifacts
|
||||||
|
uses: actions/github-script@v8
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const {default: artifactClient} = require('./packages/artifact/lib/artifact')
|
||||||
|
|
||||||
|
const {readFile} = require('fs/promises')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const findBy = {
|
||||||
|
repositoryOwner: process.env.GITHUB_REPOSITORY.split('/')[0],
|
||||||
|
repositoryName: process.env.GITHUB_REPOSITORY.split('/')[1],
|
||||||
|
token: '${{ secrets.GITHUB_TOKEN }}',
|
||||||
|
workflowRunId: process.env.GITHUB_RUN_ID
|
||||||
|
}
|
||||||
|
|
||||||
|
const listResult = await artifactClient.listArtifacts({latest: true, findBy})
|
||||||
|
const expectedSingleFiles = [
|
||||||
|
'single-file-ubuntu-latest.txt',
|
||||||
|
'single-file-windows-latest.txt',
|
||||||
|
'single-file-macos-latest.txt'
|
||||||
|
]
|
||||||
|
|
||||||
|
// Single file artifacts are named after the file basename
|
||||||
|
const singleFileArtifacts = listResult.artifacts.filter(a =>
|
||||||
|
expectedSingleFiles.includes(a.name)
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log('Found single file artifacts:', singleFileArtifacts.length)
|
||||||
|
|
||||||
|
if (singleFileArtifacts.length !== 3) {
|
||||||
|
console.log('Unexpected single file artifacts:', singleFileArtifacts)
|
||||||
|
throw new Error(
|
||||||
|
`Expected 3 single-file artifacts but found ${singleFileArtifacts.length}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const artifact of singleFileArtifacts) {
|
||||||
|
const downloadDir = `single-file-download-${artifact.id}`
|
||||||
|
const {downloadPath} = await artifactClient.downloadArtifact(artifact.id, {
|
||||||
|
path: downloadDir,
|
||||||
|
findBy
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('Downloaded single file artifact to:', downloadPath)
|
||||||
|
|
||||||
|
const filePath = path.join(
|
||||||
|
process.env.GITHUB_WORKSPACE,
|
||||||
|
downloadPath,
|
||||||
|
artifact.name
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log('Checking file:', filePath)
|
||||||
|
|
||||||
|
const content = await readFile(filePath, 'utf8')
|
||||||
|
if (content.trim() !== 'hello from single file upload') {
|
||||||
|
throw new Error(
|
||||||
|
`Expected single file to contain 'hello from single file upload' but found '${content}'`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Successfully verified single file artifact ${artifact.id}`)
|
||||||
|
}
|
||||||
|
|
||||||
- name: Delete Artifacts
|
- name: Delete Artifacts
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
@@ -173,11 +371,19 @@ jobs:
|
|||||||
const artifactsToDelete = [
|
const artifactsToDelete = [
|
||||||
'my-artifact-ubuntu-latest',
|
'my-artifact-ubuntu-latest',
|
||||||
'my-artifact-windows-latest',
|
'my-artifact-windows-latest',
|
||||||
'my-artifact-macos-latest'
|
'my-artifact-macos-latest',
|
||||||
|
'single-file-ubuntu-latest.txt',
|
||||||
|
'single-file-windows-latest.txt',
|
||||||
|
'single-file-macos-latest.txt'
|
||||||
]
|
]
|
||||||
|
|
||||||
for (const artifactName of artifactsToDelete) {
|
for (const artifactName of artifactsToDelete) {
|
||||||
const {id} = await artifactClient.deleteArtifact(artifactName)
|
try {
|
||||||
|
const {id} = await artifactClient.deleteArtifact(artifactName)
|
||||||
|
console.log(`Deleted artifact '${artifactName}' (ID: ${id})`)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`Could not delete artifact '${artifactName}': ${err.message}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const {artifacts} = await artifactClient.listArtifacts({latest: true})
|
const {artifacts} = await artifactClient.listArtifacts({latest: true})
|
||||||
|
|||||||
@@ -55,10 +55,8 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache
|
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache
|
||||||
|
|
||||||
# We're using node -e to call the functions directly available in the @actions/cache package
|
|
||||||
- name: Save cache using saveCache()
|
- name: Save cache using saveCache()
|
||||||
run: |
|
run: node packages/cache/__tests__/save-cache.mjs ${{ runner.os }} ${{ github.run_id }}
|
||||||
node -e "Promise.resolve(require('./packages/cache/lib/cache').saveCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
|
|
||||||
|
|
||||||
- name: Delete cache folders before restoring
|
- name: Delete cache folders before restoring
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -67,8 +65,7 @@ jobs:
|
|||||||
rm -rf ~/test-cache
|
rm -rf ~/test-cache
|
||||||
|
|
||||||
- name: Restore cache using restoreCache() with http-client
|
- name: Restore cache using restoreCache() with http-client
|
||||||
run: |
|
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} false
|
||||||
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}',[],{useAzureSdk: false}))"
|
|
||||||
|
|
||||||
- name: Verify cache restored with http-client
|
- name: Verify cache restored with http-client
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -83,8 +80,7 @@ jobs:
|
|||||||
rm -rf ~/test-cache
|
rm -rf ~/test-cache
|
||||||
|
|
||||||
- name: Restore cache using restoreCache() with Azure SDK
|
- name: Restore cache using restoreCache() with Azure SDK
|
||||||
run: |
|
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} true
|
||||||
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
|
|
||||||
|
|
||||||
- name: Verify cache restored with Azure SDK
|
- name: Verify cache restored with Azure SDK
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -52,10 +52,8 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache
|
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache
|
||||||
|
|
||||||
# We're using node -e to call the functions directly available in the @actions/cache package
|
|
||||||
- name: Save cache using saveCache()
|
- name: Save cache using saveCache()
|
||||||
run: |
|
run: node packages/cache/__tests__/save-cache.mjs ${{ runner.os }} ${{ github.run_id }}
|
||||||
node -e "Promise.resolve(require('./packages/cache/lib/cache').saveCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
|
|
||||||
|
|
||||||
- name: Delete cache folders before restoring
|
- name: Delete cache folders before restoring
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -64,8 +62,7 @@ jobs:
|
|||||||
rm -rf ~/test-cache
|
rm -rf ~/test-cache
|
||||||
|
|
||||||
- name: Restore cache using restoreCache() with http-client
|
- name: Restore cache using restoreCache() with http-client
|
||||||
run: |
|
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} false
|
||||||
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}',[],{useAzureSdk: false}))"
|
|
||||||
|
|
||||||
- name: Verify cache restored with http-client
|
- name: Verify cache restored with http-client
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -80,8 +77,7 @@ jobs:
|
|||||||
rm -rf ~/test-cache
|
rm -rf ~/test-cache
|
||||||
|
|
||||||
- name: Restore cache using restoreCache() with Azure SDK
|
- name: Restore cache using restoreCache() with Azure SDK
|
||||||
run: |
|
run: node packages/cache/__tests__/restore-cache.mjs ${{ runner.os }} ${{ github.run_id }} true
|
||||||
node -e "Promise.resolve(require('./packages/cache/lib/cache').restoreCache(['test-cache','~/test-cache'],'test-${{ runner.os }}-${{ github.run_id }}'))"
|
|
||||||
|
|
||||||
- name: Verify cache restored with Azure SDK
|
- name: Verify cache restored with Azure SDK
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Publish NPM
|
name: Publish NPM
|
||||||
|
|
||||||
run-name: Publish NPM - ${{ github.event.inputs.package }}
|
run-name: Publish NPM - ${{ inputs.package }} from ${{ inputs.branch }}
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -20,21 +20,37 @@ on:
|
|||||||
- http-client
|
- http-client
|
||||||
- io
|
- io
|
||||||
- tool-cache
|
- tool-cache
|
||||||
|
branch:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: 'main'
|
||||||
|
description: 'Branch to release from'
|
||||||
|
npm-tag:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: 'latest'
|
||||||
|
description: 'npm dist-tag for the release. Use "latest" for main branch releases. For non-main branches, use a non-semver tag like "v1-longlived". Semver values (e.g. "5.0.0") are not valid dist-tags and will be rejected by npm.'
|
||||||
|
test-all:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
description: 'Run tests for all packages instead of only the package being published'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest-large
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: setup repo
|
- name: setup repo
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.branch }}
|
||||||
|
|
||||||
- name: verify package exists
|
- name: verify package exists
|
||||||
run: ls packages/${{ github.event.inputs.package }}
|
run: ls packages/${{ github.event.inputs.package }}
|
||||||
|
|
||||||
- name: Set Node.js 24.x
|
- name: Set Node.js 24.x
|
||||||
uses: actions/setup-node@v5
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 24.x
|
node-version: 24.x
|
||||||
|
|
||||||
@@ -48,20 +64,25 @@ jobs:
|
|||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
run: npm run test
|
run: |
|
||||||
|
if [ "${{ inputs.test-all }}" = "true" ]; then
|
||||||
|
npm run test
|
||||||
|
else
|
||||||
|
npm run test -- --testPathPattern="packages/${{ inputs.package }}"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: pack
|
- name: pack
|
||||||
run: npm pack
|
run: npm pack
|
||||||
working-directory: packages/${{ github.event.inputs.package }}
|
working-directory: packages/${{ github.event.inputs.package }}
|
||||||
|
|
||||||
- name: upload artifact
|
- name: upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: ${{ github.event.inputs.package }}
|
name: ${{ github.event.inputs.package }}
|
||||||
path: packages/${{ github.event.inputs.package }}/*.tgz
|
path: packages/${{ github.event.inputs.package }}/*.tgz
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
runs-on: macos-latest-large
|
runs-on: ubuntu-slim
|
||||||
needs: test
|
needs: test
|
||||||
environment: npm-publish
|
environment: npm-publish
|
||||||
permissions:
|
permissions:
|
||||||
@@ -70,29 +91,35 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set Node.js 24.x
|
- name: Set Node.js 24.x
|
||||||
uses: actions/setup-node@v5
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 24.x
|
node-version: 24.x
|
||||||
|
|
||||||
- name: download artifact
|
- name: download artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v8
|
||||||
with:
|
with:
|
||||||
name: ${{ github.event.inputs.package }}
|
name: ${{ inputs.package }}
|
||||||
|
|
||||||
|
- name: guard against publishing latest from non-main branch
|
||||||
|
if: inputs.branch != 'main' && inputs.npm-tag == 'latest'
|
||||||
|
run: |
|
||||||
|
echo "::error::Publishing with the 'latest' dist-tag from a non-main branch ('${{ inputs.branch }}') is not allowed. Use the package major version as the tag (e.g. v5)."
|
||||||
|
exit 1
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
run: npm publish --provenance *.tgz
|
run: npm publish --provenance --tag "${{ inputs.npm-tag }}" *.tgz
|
||||||
|
|
||||||
- name: notify slack on failure
|
- name: notify slack on failure
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
curl -X POST -H 'Content-type: application/json' --data '{"text":":pb__failed: Failed to publish a new version of ${{ github.event.inputs.package }}"}' $SLACK_WEBHOOK
|
curl -X POST -H 'Content-type: application/json' --data '{"text":":pb__failed: Failed to publish a new version of ${{ inputs.package }} from ${{ inputs.branch }} (tag: ${{ inputs.npm-tag }})"}' $SLACK_WEBHOOK
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK }}
|
||||||
|
|
||||||
- name: notify slack on success
|
- name: notify slack on success
|
||||||
if: success()
|
if: success()
|
||||||
run: |
|
run: |
|
||||||
curl -X POST -H 'Content-type: application/json' --data '{"text":":dance: Successfully published a new version of ${{ github.event.inputs.package }}"}' $SLACK_WEBHOOK
|
curl -X POST -H 'Content-type: application/json' --data '{"text":":dance: Successfully published a new version of ${{ inputs.package }} from ${{ inputs.branch }} (tag: ${{ inputs.npm-tag }})"}' $SLACK_WEBHOOK
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK }}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
@@ -0,0 +1,82 @@
|
|||||||
|
# Releasing Packages
|
||||||
|
|
||||||
|
Packages are published to npm via the **Publish NPM** workflow ([`.github/workflows/releases.yml`](../.github/workflows/releases.yml)). The workflow is triggered manually through `workflow_dispatch` from the GitHub Actions UI.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
The workflow has two jobs:
|
||||||
|
|
||||||
|
1. **test** — Checks out the specified branch, installs dependencies, bootstraps the monorepo, builds all packages, runs tests, then packs the target package into a `.tgz` archive and uploads it as a workflow artifact.
|
||||||
|
2. **publish** — Downloads the packed artifact and publishes it to npm with `--provenance` (OIDC-based). Sends a Slack notification on success or failure. Requires the `npm-publish` environment.
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
|
||||||
|
| Input | Type | Required | Default | Description |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `package` | choice | **yes** | — | Which package to release. One of: `artifact`, `attest`, `cache`, `core`, `exec`, `github`, `glob`, `http-client`, `io`, `tool-cache`. |
|
||||||
|
| `branch` | string | no | `main` | The branch to check out and release from. |
|
||||||
|
| `npm-tag` | string | no | `latest` | The npm dist-tag to publish under. See [Dist-tags](#dist-tags) below. |
|
||||||
|
| `test-all` | boolean | no | `false` | When `false`, only tests for the selected package are run. Set to `true` to run the full test suite across all packages. |
|
||||||
|
|
||||||
|
## Dist-tags
|
||||||
|
|
||||||
|
npm dist-tags control which version users get when they `npm install @actions/<package>` (or `@<tag>`).
|
||||||
|
|
||||||
|
> **Important:** npm dist-tags **cannot** be valid semver strings. Values like `5.0.0` or `1.2.3` will be rejected by npm. Use a descriptive name instead.
|
||||||
|
|
||||||
|
- **`latest`** — The default tag. This is what users get with a plain `npm install`. Should only be used for releases from `main`.
|
||||||
|
- **Custom tags** (e.g. `v1-longlived`) — Used for releases from long-lived or experimental branches.
|
||||||
|
|
||||||
|
Examples of **valid** dist-tags: `latest`, `next`, `beta`, `v1-longlived`
|
||||||
|
Examples of **invalid** dist-tags: `5.0.0`, `1.2.3`, `6.0.0-rc.1` (these are semver and will be rejected)
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|---|
|
||||||
|
| npm distribution tags |
|
||||||
|
|
||||||
|
### Safety guard
|
||||||
|
|
||||||
|
The workflow **blocks** publishing with the `latest` dist-tag from any branch other than `main`. This prevents accidentally overwriting `latest` with a version from an older or experimental branch. If you're releasing from a non-main branch, use the package's major version as the tag (e.g. `v5`).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Standard release from main
|
||||||
|
|
||||||
|
Use default inputs — just pick the package:
|
||||||
|
|
||||||
|
| Input | Value |
|
||||||
|
|---|---|
|
||||||
|
| `package` | `core` |
|
||||||
|
| `branch` | `main` (default) |
|
||||||
|
| `npm-tag` | `latest` (default) |
|
||||||
|
| `test-all` | `false` (default) |
|
||||||
|
|
||||||
|
This publishes the version in `packages/core/package.json` on `main` as `@actions/core@latest`.
|
||||||
|
|
||||||
|
### Patch release from a long-lived branch
|
||||||
|
|
||||||
|
| Input | Value |
|
||||||
|
|---|---|
|
||||||
|
| `package` | `artifact` |
|
||||||
|
| `branch` | `releases/v5` |
|
||||||
|
| `npm-tag` | `v5` |
|
||||||
|
| `test-all` | `false` (default) |
|
||||||
|
|
||||||
|
This publishes the version in `packages/artifact/package.json` on the `releases/v5` branch under the `v5` dist-tag. The `latest` tag remains untouched.
|
||||||
|
|
||||||
|
### Release with full test suite
|
||||||
|
|
||||||
|
| Input | Value |
|
||||||
|
|---|---|
|
||||||
|
| `package` | `cache` |
|
||||||
|
| `branch` | `main` (default) |
|
||||||
|
| `npm-tag` | `latest` (default) |
|
||||||
|
| `test-all` | `true` |
|
||||||
|
|
||||||
|
Same as a standard release, but runs tests for all packages before publishing.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- You must have permission to trigger workflows on this repository.
|
||||||
|
- The `npm-publish` environment must be configured with npm credentials and OIDC.
|
||||||
|
- The `SLACK` secret must be set for Slack notifications to work.
|
||||||
+29
-2
@@ -4,8 +4,35 @@ module.exports = {
|
|||||||
roots: ['<rootDir>/packages'],
|
roots: ['<rootDir>/packages'],
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
testMatch: ['**/__tests__/*.test.ts'],
|
testMatch: ['**/__tests__/*.test.ts'],
|
||||||
transform: {
|
moduleNameMapper: {
|
||||||
'^.+\\.ts$': ['ts-jest', {isolatedModules: true, diagnostics: {warnOnly: true}}]
|
'^(\\.{1,2}/.*)\\.js$': '$1',
|
||||||
|
'^@actions/core$': '<rootDir>/packages/core/lib/core.js',
|
||||||
|
'^@actions/exec$': '<rootDir>/packages/exec/lib/exec.js',
|
||||||
|
'^@actions/io$': '<rootDir>/packages/io/lib/io.js',
|
||||||
|
'^@actions/io/lib/io-util$': '<rootDir>/packages/io/lib/io-util.js',
|
||||||
|
'^@actions/http-client$': '<rootDir>/packages/http-client/lib/index.js',
|
||||||
|
'^@actions/http-client/lib/auth$': '<rootDir>/packages/http-client/lib/auth.js',
|
||||||
|
'^@actions/http-client/lib/interfaces$': '<rootDir>/packages/http-client/lib/interfaces.js',
|
||||||
|
'^@actions/github$': '<rootDir>/packages/github/lib/github.js',
|
||||||
|
'^@actions/github/lib/utils$': '<rootDir>/packages/github/lib/utils.js',
|
||||||
|
'^@actions/glob$': '<rootDir>/packages/glob/lib/glob.js',
|
||||||
|
'^@actions/tool-cache$': '<rootDir>/packages/tool-cache/lib/tool-cache.js',
|
||||||
|
'^@actions/cache$': '<rootDir>/packages/cache/lib/cache.js',
|
||||||
|
'^@actions/attest$': '<rootDir>/packages/attest/lib/index.js'
|
||||||
},
|
},
|
||||||
|
transform: {
|
||||||
|
'^.+\\.(ts|js)$': ['ts-jest', {
|
||||||
|
diagnostics: {warnOnly: true},
|
||||||
|
tsconfig: {
|
||||||
|
allowJs: true,
|
||||||
|
esModuleInterop: true,
|
||||||
|
module: 'commonjs',
|
||||||
|
moduleResolution: 'node'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
transformIgnorePatterns: [
|
||||||
|
'/node_modules/(?!(@octokit|@actions/github|@actions/http-client|@actions/io|@actions/exec|@actions/core|@actions/glob|@actions/tool-cache|@actions/cache|@actions/attest|universal-user-agent|before-after-hook)/)'
|
||||||
|
],
|
||||||
verbose: true
|
verbose: true
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+103
-101
@@ -2956,67 +2956,67 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/auth-token": {
|
"node_modules/@octokit/auth-token": {
|
||||||
"version": "4.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
|
||||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
"integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/core": {
|
"node_modules/@octokit/core": {
|
||||||
"version": "5.2.2",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
|
||||||
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==",
|
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-token": "^4.0.0",
|
"@octokit/auth-token": "^6.0.0",
|
||||||
"@octokit/graphql": "^7.1.0",
|
"@octokit/graphql": "^9.0.3",
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request": "^10.0.6",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^7.0.2",
|
||||||
"@octokit/types": "^13.0.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"before-after-hook": "^2.2.0",
|
"before-after-hook": "^4.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^7.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/endpoint": {
|
"node_modules/@octokit/endpoint": {
|
||||||
"version": "9.0.6",
|
"version": "11.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz",
|
||||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
"integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^7.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/graphql": {
|
"node_modules/@octokit/graphql": {
|
||||||
"version": "7.1.1",
|
"version": "9.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
|
||||||
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==",
|
"integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request": "^10.0.6",
|
||||||
"@octokit/types": "^13.0.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^7.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/openapi-types": {
|
||||||
"version": "24.2.0",
|
"version": "27.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
|
||||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -3028,36 +3028,19 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-paginate-rest": {
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
"version": "9.2.2",
|
"version": "14.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
|
||||||
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^12.6.0"
|
"@octokit/types": "^16.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@octokit/core": "5"
|
"@octokit/core": ">=6"
|
||||||
}
|
|
||||||
},
|
|
||||||
"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==",
|
|
||||||
"dev": true,
|
|
||||||
"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==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/openapi-types": "^20.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-request-log": {
|
"node_modules/@octokit/plugin-request-log": {
|
||||||
@@ -3105,34 +3088,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "8.4.1",
|
"version": "10.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz",
|
||||||
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
"integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/endpoint": "^9.0.6",
|
"@octokit/endpoint": "^11.0.2",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^7.0.2",
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"fast-content-type-parse": "^3.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request-error": {
|
"node_modules/@octokit/request-error": {
|
||||||
"version": "5.1.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
|
||||||
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^16.0.0"
|
||||||
"deprecation": "^2.0.0",
|
|
||||||
"once": "^1.4.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/rest": {
|
"node_modules/@octokit/rest": {
|
||||||
@@ -3152,13 +3134,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/types": {
|
"node_modules/@octokit/types": {
|
||||||
"version": "13.10.0",
|
"version": "16.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
|
||||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^24.2.0"
|
"@octokit/openapi-types": "^27.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@parcel/watcher": {
|
"node_modules/@parcel/watcher": {
|
||||||
@@ -4340,15 +4322,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.12.2",
|
"version": "1.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.1.tgz",
|
||||||
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
|
"integrity": "sha512-WOG+Jj8ZOvR0a3rAn+Tuf1UQJRxw5venr6DgdbJzngJE3qG7X0kL83CZGpdHMxEm+ZK3seAbvFsw4FfOfP9vxg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.11",
|
||||||
"form-data": "^4.0.4",
|
"form-data": "^4.0.5",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axobject-query": {
|
"node_modules/axobject-query": {
|
||||||
@@ -4516,9 +4498,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/before-after-hook": {
|
"node_modules/before-after-hook": {
|
||||||
"version": "2.2.3",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
|
||||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
|
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
@@ -6986,6 +6968,23 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-content-type-parse": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fastify"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fastify"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@@ -7216,9 +7215,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.3.3",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||||
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
|
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -7236,9 +7235,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.11",
|
"version": "1.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
||||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -10762,9 +10761,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.23",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -13279,9 +13278,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
|
||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -13571,11 +13570,14 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/proxy-from-env": {
|
"node_modules/proxy-from-env": {
|
||||||
"version": "1.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
|
||||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pure-rand": {
|
"node_modules/pure-rand": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
@@ -15859,9 +15861,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/universal-user-agent": {
|
"node_modules/universal-user-agent": {
|
||||||
"version": "6.0.1",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
|
||||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
|||||||
+4
-4
@@ -36,10 +36,10 @@
|
|||||||
"overrides": {
|
"overrides": {
|
||||||
"semver": "^7.6.0",
|
"semver": "^7.6.0",
|
||||||
"tar": "^6.2.1",
|
"tar": "^6.2.1",
|
||||||
"@octokit/plugin-paginate-rest": "^9.2.2",
|
"@octokit/plugin-paginate-rest": "^14.0.0",
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request": "^10.0.7",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^7.1.0",
|
||||||
"@octokit/core": "^5.0.3",
|
"@octokit/core": "^7.0.6",
|
||||||
"tmp": "^0.2.4",
|
"tmp": "^0.2.4",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^24.1.0",
|
||||||
"brace-expansion": "^2.0.2",
|
"brace-expansion": "^2.0.2",
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Interact programmatically with [Actions Artifacts](https://docs.github.com/en/ac
|
|||||||
|
|
||||||
This is the core library that powers the [`@actions/upload-artifact`](https://github.com/actions/upload-artifact) and [`@actions/download-artifact`](https://github.com/actions/download-artifact) actions.
|
This is the core library that powers the [`@actions/upload-artifact`](https://github.com/actions/upload-artifact) and [`@actions/download-artifact`](https://github.com/actions/download-artifact) actions.
|
||||||
|
|
||||||
|
|
||||||
- [`@actions/artifact`](#actionsartifact)
|
- [`@actions/artifact`](#actionsartifact)
|
||||||
- [v2 - What's New](#v2---whats-new)
|
- [v2 - What's New](#v2---whats-new)
|
||||||
- [Improvements](#improvements)
|
- [Improvements](#improvements)
|
||||||
|
|||||||
@@ -1,129 +1,161 @@
|
|||||||
# @actions/artifact Releases
|
# @actions/artifact Releases
|
||||||
|
|
||||||
### 4.0.0
|
## 6.2.1
|
||||||
|
|
||||||
|
- Support the RFC 5987 `filename*` field in the `content-disposition` header. This allows us to correctly download files and artifacts with Chinese/Japanese/Korean (among other) characters in their name.
|
||||||
|
|
||||||
|
## 6.2.0
|
||||||
|
|
||||||
|
- Support uploading single un-archived files (not zipped). Direct uploads are only supported for artifacts version 7+ (based on the major version of `actions/upload-artifact`). Callers must pass the `skipArchive` option to `uploadArtifact`. Only single files can be uploaded at a time right now. Default behavior should remain unchanged if `skipArchive = false`. When `skipArchive = true`, the name of the file is used as the name of the artifact for consistency with the downloads: you upload `artifact.txt`, you download `artifact.txt`.
|
||||||
|
|
||||||
|
## 6.1.0
|
||||||
|
|
||||||
|
- Support downloading non-zip artifacts. Zipped artifacts will be decompressed automatically (with an optional override). Un-zipped artifacts will be downloaded as-is.
|
||||||
|
|
||||||
|
## 6.0.0
|
||||||
|
|
||||||
|
- **Breaking change**: Package is now ESM-only
|
||||||
|
- CommonJS consumers must use dynamic `import()` instead of `require()`
|
||||||
|
|
||||||
|
## 5.0.3
|
||||||
|
|
||||||
|
- Bump `@actions/http-client` to `3.0.2`
|
||||||
|
|
||||||
|
## 5.0.1
|
||||||
|
|
||||||
|
- Fix Node.js 24 punycode deprecation warning by updating `@azure/storage-blob` from `^12.15.0` to `^12.29.1` [#2211](https://github.com/actions/toolkit/pull/2211)
|
||||||
|
- Removed direct `@azure/core-http` dependency (now uses `@azure/core-rest-pipeline` via storage-blob)
|
||||||
|
|
||||||
|
## 5.0.0
|
||||||
|
|
||||||
|
- Dependency updates for Node.js 24 runtime support
|
||||||
|
- Update `@actions/core` to v2
|
||||||
|
- Update `@actions/http-client` to v3
|
||||||
|
|
||||||
|
## 4.0.0
|
||||||
|
|
||||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
- 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: 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)
|
- Fix: reject the promise on timeout [#2124](https://github.com/actions/toolkit/pull/2124)
|
||||||
- Update dependency versions
|
- Update dependency versions
|
||||||
|
|
||||||
### 2.3.3
|
## 2.3.3
|
||||||
|
|
||||||
- Dependency updates [#2049](https://github.com/actions/toolkit/pull/2049)
|
- Dependency updates [#2049](https://github.com/actions/toolkit/pull/2049)
|
||||||
|
|
||||||
### 2.3.2
|
## 2.3.2
|
||||||
|
|
||||||
- Added masking for Shared Access Signature (SAS) artifact URLs [#1982](https://github.com/actions/toolkit/pull/1982)
|
- 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)
|
- Change hash to digest for consistent terminology across runner logs [#1991](https://github.com/actions/toolkit/pull/1991)
|
||||||
|
|
||||||
### 2.3.1
|
## 2.3.1
|
||||||
|
|
||||||
- Fix comment typo on expectedHash. [#1986](https://github.com/actions/toolkit/pull/1986)
|
- Fix comment typo on expectedHash. [#1986](https://github.com/actions/toolkit/pull/1986)
|
||||||
|
|
||||||
### 2.3.0
|
## 2.3.0
|
||||||
|
|
||||||
- Allow ArtifactClient to perform digest comparisons, if supplied. [#1975](https://github.com/actions/toolkit/pull/1975)
|
- Allow ArtifactClient to perform digest comparisons, if supplied. [#1975](https://github.com/actions/toolkit/pull/1975)
|
||||||
|
|
||||||
### 2.2.2
|
## 2.2.2
|
||||||
|
|
||||||
- Default concurrency to 5 for uploading artifacts [#1962](https://github.com/actions/toolkit/pull/1962)
|
- Default concurrency to 5 for uploading artifacts [#1962](https://github.com/actions/toolkit/pull/1962)
|
||||||
|
|
||||||
### 2.2.1
|
## 2.2.1
|
||||||
|
|
||||||
- Add `ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY` and `ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS` environment variables [#1928](https://github.com/actions/toolkit/pull/1928)
|
- Add `ACTIONS_ARTIFACT_UPLOAD_CONCURRENCY` and `ACTIONS_ARTIFACT_UPLOAD_TIMEOUT_MS` environment variables [#1928](https://github.com/actions/toolkit/pull/1928)
|
||||||
|
|
||||||
### 2.2.0
|
## 2.2.0
|
||||||
|
|
||||||
- Return artifact digest on upload [#1896](https://github.com/actions/toolkit/pull/1896)
|
- Return artifact digest on upload [#1896](https://github.com/actions/toolkit/pull/1896)
|
||||||
|
|
||||||
### 2.1.11
|
## 2.1.11
|
||||||
|
|
||||||
- Fixed a bug with relative symlinks resolution [#1844](https://github.com/actions/toolkit/pull/1844)
|
- Fixed a bug with relative symlinks resolution [#1844](https://github.com/actions/toolkit/pull/1844)
|
||||||
- Use native `crypto` [#1815](https://github.com/actions/toolkit/pull/1815)
|
- Use native `crypto` [#1815](https://github.com/actions/toolkit/pull/1815)
|
||||||
|
|
||||||
### 2.1.10
|
## 2.1.10
|
||||||
|
|
||||||
- Fixed a regression with symlinks not being automatically resolved [#1830](https://github.com/actions/toolkit/pull/1830)
|
- Fixed a regression with symlinks not being automatically resolved [#1830](https://github.com/actions/toolkit/pull/1830)
|
||||||
- Fixed a regression with chunk timeout [#1786](https://github.com/actions/toolkit/pull/1786)
|
- Fixed a regression with chunk timeout [#1786](https://github.com/actions/toolkit/pull/1786)
|
||||||
|
|
||||||
### 2.1.9
|
## 2.1.9
|
||||||
|
|
||||||
- Fixed artifact upload chunk timeout logic [#1774](https://github.com/actions/toolkit/pull/1774)
|
- Fixed artifact upload chunk timeout logic [#1774](https://github.com/actions/toolkit/pull/1774)
|
||||||
- Use lazy stream to prevent issues with open file limits [#1771](https://github.com/actions/toolkit/pull/1771)
|
- Use lazy stream to prevent issues with open file limits [#1771](https://github.com/actions/toolkit/pull/1771)
|
||||||
|
|
||||||
### 2.1.8
|
## 2.1.8
|
||||||
|
|
||||||
- Allows `*.localhost` domains for hostname checks for local development.
|
- Allows `*.localhost` domains for hostname checks for local development.
|
||||||
|
|
||||||
### 2.1.7
|
## 2.1.7
|
||||||
|
|
||||||
- Update unzip-stream dependency and reverted to using `unzip.Extract()`
|
- Update unzip-stream dependency and reverted to using `unzip.Extract()`
|
||||||
|
|
||||||
### 2.1.6
|
## 2.1.6
|
||||||
|
|
||||||
- Will retry on invalid request responses.
|
- Will retry on invalid request responses.
|
||||||
|
|
||||||
### 2.1.5
|
## 2.1.5
|
||||||
|
|
||||||
- Bumped `archiver` dependency to 7.0.1
|
- Bumped `archiver` dependency to 7.0.1
|
||||||
|
|
||||||
### 2.1.4
|
## 2.1.4
|
||||||
|
|
||||||
- Adds info-level logging for zip extraction
|
- Adds info-level logging for zip extraction
|
||||||
|
|
||||||
### 2.1.3
|
## 2.1.3
|
||||||
|
|
||||||
- Fixes a bug in the extract logic updated in 2.1.2
|
- Fixes a bug in the extract logic updated in 2.1.2
|
||||||
|
|
||||||
### 2.1.2
|
## 2.1.2
|
||||||
|
|
||||||
- Updated the stream extract functionality to use `unzip.Parse()` instead of `unzip.Extract()` for greater control of unzipping artifacts
|
- Updated the stream extract functionality to use `unzip.Parse()` instead of `unzip.Extract()` for greater control of unzipping artifacts
|
||||||
|
|
||||||
### 2.1.1
|
## 2.1.1
|
||||||
|
|
||||||
- Updated `isGhes` check to include `.ghe.com` and `.ghe.localhost` as accepted hosts
|
- Updated `isGhes` check to include `.ghe.com` and `.ghe.localhost` as accepted hosts
|
||||||
|
|
||||||
### 2.1.0
|
## 2.1.0
|
||||||
|
|
||||||
- Added `ArtifactClient#deleteArtifact` to delete artifacts by name [#1626](https://github.com/actions/toolkit/pull/1626)
|
- Added `ArtifactClient#deleteArtifact` to delete artifacts by name [#1626](https://github.com/actions/toolkit/pull/1626)
|
||||||
- Update error messaging to be more useful [#1628](https://github.com/actions/toolkit/pull/1628)
|
- Update error messaging to be more useful [#1628](https://github.com/actions/toolkit/pull/1628)
|
||||||
|
|
||||||
### 2.0.1
|
## 2.0.1
|
||||||
|
|
||||||
- Patch to fix transient request timeouts https://github.com/actions/download-artifact/issues/249
|
- Patch to fix transient request timeouts <https://github.com/actions/download-artifact/issues/249>
|
||||||
|
|
||||||
### 2.0.0
|
## 2.0.0
|
||||||
|
|
||||||
- Major release. Supports new Artifact backend for improved speed, reliability and behavior.
|
- Major release. Supports new Artifact backend for improved speed, reliability and behavior.
|
||||||
- Numerous API changes, [some breaking](./README.md#breaking-changes).
|
- Numerous API changes, [some breaking](./README.md#breaking-changes).
|
||||||
|
|
||||||
- [Blog post with more info](https://github.blog/2024-02-12-get-started-with-v4-of-github-actions-artifacts/)
|
- [Blog post with more info](https://github.blog/2024-02-12-get-started-with-v4-of-github-actions-artifacts/)
|
||||||
|
|
||||||
### 1.1.1
|
## 1.1.1
|
||||||
|
|
||||||
- Fixed a bug in Node16 where if an HTTP download finished too quickly (<1ms, e.g. when it's mocked) we attempt to delete a temp file that has not been created yet [#1278](https://github.com/actions/toolkit/pull/1278/commits/b9de68a590daf37c6747e38d3cb4f1dd2cfb791c)
|
- Fixed a bug in Node16 where if an HTTP download finished too quickly (<1ms, e.g. when it's mocked) we attempt to delete a temp file that has not been created yet [#1278](https://github.com/actions/toolkit/pull/1278/commits/b9de68a590daf37c6747e38d3cb4f1dd2cfb791c)
|
||||||
|
|
||||||
### 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
- Add `x-actions-results-crc64` and `x-actions-results-md5` checksum headers on upload [#1063](https://github.com/actions/toolkit/pull/1063)
|
- Add `x-actions-results-crc64` and `x-actions-results-md5` checksum headers on upload [#1063](https://github.com/actions/toolkit/pull/1063)
|
||||||
|
|
||||||
### 1.0.2
|
## 1.0.2
|
||||||
|
|
||||||
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
|
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
|
||||||
|
|
||||||
### 1.0.1
|
## 1.0.1
|
||||||
|
|
||||||
- Update to v2.0.0 of `@actions/http-client`
|
- Update to v2.0.0 of `@actions/http-client`
|
||||||
|
|
||||||
### 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
- Update `lockfileVersion` to `v2` in `package-lock.json` [#1009](https://github.com/actions/toolkit/pull/1009)
|
- Update `lockfileVersion` to `v2` in `package-lock.json` [#1009](https://github.com/actions/toolkit/pull/1009)
|
||||||
|
|
||||||
### 0.6.1
|
## 0.6.1
|
||||||
|
|
||||||
- Fix for failing 0 byte file uploads on Windows [#962](https://github.com/actions/toolkit/pull/962)
|
- Fix for failing 0 byte file uploads on Windows [#962](https://github.com/actions/toolkit/pull/962)
|
||||||
|
|
||||||
### 0.6.0
|
## 0.6.0
|
||||||
|
|
||||||
- Support upload from named pipes [#748](https://github.com/actions/toolkit/pull/748)
|
- Support upload from named pipes [#748](https://github.com/actions/toolkit/pull/748)
|
||||||
- Fixes to percentage values being greater than 100% when downloading all artifacts [#889](https://github.com/actions/toolkit/pull/889)
|
- Fixes to percentage values being greater than 100% when downloading all artifacts [#889](https://github.com/actions/toolkit/pull/889)
|
||||||
@@ -132,49 +164,49 @@
|
|||||||
- Faster upload speeds for certain types of large files by exempting gzip compression [#956](https://github.com/actions/toolkit/pull/956)
|
- Faster upload speeds for certain types of large files by exempting gzip compression [#956](https://github.com/actions/toolkit/pull/956)
|
||||||
- More detailed logging when dealing with chunked uploads [#957](https://github.com/actions/toolkit/pull/957)
|
- More detailed logging when dealing with chunked uploads [#957](https://github.com/actions/toolkit/pull/957)
|
||||||
|
|
||||||
### 0.5.2
|
## 0.5.2
|
||||||
|
|
||||||
- Add HTTP 500 as a retryable status code for artifact upload and download.
|
- Add HTTP 500 as a retryable status code for artifact upload and download.
|
||||||
|
|
||||||
### 0.5.1
|
## 0.5.1
|
||||||
|
|
||||||
- Bump @actions/http-client to version 1.0.11 to fix proxy related issues during artifact upload and download
|
- Bump @actions/http-client to version 1.0.11 to fix proxy related issues during artifact upload and download
|
||||||
|
|
||||||
### 0.5.0
|
## 0.5.0
|
||||||
|
|
||||||
- Improved retry-ability for all http calls during artifact upload and download if an error is encountered
|
- Improved retry-ability for all http calls during artifact upload and download if an error is encountered
|
||||||
|
|
||||||
### 0.4.2
|
## 0.4.2
|
||||||
|
|
||||||
- Improved retry-ability when a partial artifact download is encountered
|
- Improved retry-ability when a partial artifact download is encountered
|
||||||
|
|
||||||
### 0.4.1
|
## 0.4.1
|
||||||
|
|
||||||
- Update to latest @actions/core version
|
- Update to latest @actions/core version
|
||||||
|
|
||||||
### 0.4.0
|
## 0.4.0
|
||||||
|
|
||||||
- Add option to specify custom retentions on artifacts
|
- Add option to specify custom retentions on artifacts
|
||||||
-
|
|
||||||
### 0.3.5
|
## 0.3.5
|
||||||
|
|
||||||
- Retry in the event of a 413 response
|
- Retry in the event of a 413 response
|
||||||
|
|
||||||
### 0.3.3
|
## 0.3.3
|
||||||
|
|
||||||
- Increase chunk size during upload from 4MB to 8MB
|
- Increase chunk size during upload from 4MB to 8MB
|
||||||
- Improve user-agent strings during API calls to help internally diagnose issues
|
- Improve user-agent strings during API calls to help internally diagnose issues
|
||||||
|
|
||||||
### 0.3.2
|
## 0.3.2
|
||||||
|
|
||||||
- Fix to ensure readstreams get correctly reset in the event of a retry
|
- Fix to ensure readstreams get correctly reset in the event of a retry
|
||||||
|
|
||||||
### 0.3.1
|
## 0.3.1
|
||||||
|
|
||||||
- Fix to ensure temporary gzip files get correctly deleted during artifact upload
|
- Fix to ensure temporary gzip files get correctly deleted during artifact upload
|
||||||
- Remove spaces as a forbidden character during upload
|
- Remove spaces as a forbidden character during upload
|
||||||
|
|
||||||
### 0.3.0
|
## 0.3.0
|
||||||
|
|
||||||
- Fixes to gzip decompression when downloading artifacts
|
- Fixes to gzip decompression when downloading artifacts
|
||||||
- Support handling 429 response codes
|
- Support handling 429 response codes
|
||||||
@@ -183,13 +215,13 @@
|
|||||||
- Clearer error message if storage quota has been reached
|
- Clearer error message if storage quota has been reached
|
||||||
- Improved logging and output during artifact download
|
- Improved logging and output during artifact download
|
||||||
|
|
||||||
### 0.2.0
|
## 0.2.0
|
||||||
|
|
||||||
- Fixes to TCP connections not closing
|
- Fixes to TCP connections not closing
|
||||||
- GZip file compression to speed up downloads
|
- GZip file compression to speed up downloads
|
||||||
- Improved logging and output
|
- Improved logging and output
|
||||||
- Extra documentation
|
- Extra documentation
|
||||||
|
|
||||||
### 0.1.0
|
## 0.1.0
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import * as http from 'http'
|
import * as http from 'http'
|
||||||
import * as net from 'net'
|
import * as net from 'net'
|
||||||
import {HttpClient} from '@actions/http-client'
|
import {HttpClient} from '@actions/http-client'
|
||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import {internalArtifactTwirpClient} from '../src/internal/shared/artifact-twirp-client'
|
import {internalArtifactTwirpClient} from '../src/internal/shared/artifact-twirp-client.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
import {NetworkError, UsageError} from '../src/internal/shared/errors'
|
import {NetworkError, UsageError} from '../src/internal/shared/errors.js'
|
||||||
|
|
||||||
jest.mock('@actions/http-client')
|
jest.mock('@actions/http-client')
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
|
|
||||||
// Mock the `cpus()` function in the `os` module
|
// Mock the `cpus()` function in the `os` module
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import type {RequestInterface} from '@octokit/types'
|
|||||||
import {
|
import {
|
||||||
deleteArtifactInternal,
|
deleteArtifactInternal,
|
||||||
deleteArtifactPublic
|
deleteArtifactPublic
|
||||||
} from '../src/internal/delete/delete-artifact'
|
} from '../src/internal/delete/delete-artifact.js'
|
||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
|
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated/index.js'
|
||||||
import * as util from '../src/internal/shared/util'
|
import * as util from '../src/internal/shared/util.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
|
|
||||||
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import {
|
|||||||
downloadArtifactInternal,
|
downloadArtifactInternal,
|
||||||
downloadArtifactPublic,
|
downloadArtifactPublic,
|
||||||
streamExtractExternal
|
streamExtractExternal
|
||||||
} from '../src/internal/download/download-artifact'
|
} from '../src/internal/download/download-artifact.js'
|
||||||
import {getUserAgentString} from '../src/internal/shared/user-agent'
|
import {getUserAgentString} from '../src/internal/shared/user-agent.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import {ArtifactServiceClientJSON} from '../src/generated'
|
import {ArtifactServiceClientJSON} from '../src/generated/index.js'
|
||||||
import * as util from '../src/internal/shared/util'
|
import * as util from '../src/internal/shared/util.js'
|
||||||
|
|
||||||
type MockedDownloadArtifact = jest.MockedFunction<
|
type MockedDownloadArtifact = jest.MockedFunction<
|
||||||
RestEndpointMethods['actions']['downloadArtifact']
|
RestEndpointMethods['actions']['downloadArtifact']
|
||||||
@@ -104,6 +104,7 @@ const cleanup = async (): Promise<void> => {
|
|||||||
const mockGetArtifactSuccess = jest.fn(() => {
|
const mockGetArtifactSuccess = jest.fn(() => {
|
||||||
const message = new http.IncomingMessage(new net.Socket())
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
message.statusCode = 200
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/zip'
|
||||||
message.push(fs.readFileSync(fixtures.exampleArtifact.path))
|
message.push(fs.readFileSync(fixtures.exampleArtifact.path))
|
||||||
message.push(null)
|
message.push(null)
|
||||||
return {
|
return {
|
||||||
@@ -114,6 +115,7 @@ const mockGetArtifactSuccess = jest.fn(() => {
|
|||||||
const mockGetArtifactHung = jest.fn(() => {
|
const mockGetArtifactHung = jest.fn(() => {
|
||||||
const message = new http.IncomingMessage(new net.Socket())
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
message.statusCode = 200
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/zip'
|
||||||
// Don't push any data or call push(null) to end the stream
|
// Don't push any data or call push(null) to end the stream
|
||||||
// This creates a stream that hangs and never completes
|
// This creates a stream that hangs and never completes
|
||||||
return {
|
return {
|
||||||
@@ -134,6 +136,7 @@ const mockGetArtifactFailure = jest.fn(() => {
|
|||||||
const mockGetArtifactMalicious = jest.fn(() => {
|
const mockGetArtifactMalicious = jest.fn(() => {
|
||||||
const message = new http.IncomingMessage(new net.Socket())
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
message.statusCode = 200
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/zip'
|
||||||
message.push(fs.readFileSync(path.join(__dirname, 'fixtures', 'evil.zip'))) // evil.zip contains files that are formatted x/../../etc/hosts
|
message.push(fs.readFileSync(path.join(__dirname, 'fixtures', 'evil.zip'))) // evil.zip contains files that are formatted x/../../etc/hosts
|
||||||
message.push(null)
|
message.push(null)
|
||||||
return {
|
return {
|
||||||
@@ -619,10 +622,17 @@ describe('download-artifact', () => {
|
|||||||
...fixtures.backendIds,
|
...fixtures.backendIds,
|
||||||
name: fixtures.artifactName
|
name: fixtures.artifactName
|
||||||
})
|
})
|
||||||
})
|
}, 38000)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('streamExtractExternal', () => {
|
describe('streamExtractExternal', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await setup()
|
||||||
|
// Create workspace directory for streamExtractExternal tests
|
||||||
|
await fs.promises.mkdir(fixtures.workspaceDir, {recursive: true})
|
||||||
|
})
|
||||||
|
afterEach(cleanup)
|
||||||
|
|
||||||
it('should fail if the timeout is exceeded', async () => {
|
it('should fail if the timeout is exceeded', async () => {
|
||||||
const mockSlowGetArtifact = jest.fn(mockGetArtifactHung)
|
const mockSlowGetArtifact = jest.fn(mockGetArtifactHung)
|
||||||
|
|
||||||
@@ -641,12 +651,451 @@ describe('download-artifact', () => {
|
|||||||
{timeout: 2}
|
{timeout: 2}
|
||||||
)
|
)
|
||||||
expect(true).toBe(false) // should not be called
|
expect(true).toBe(false) // should not be called
|
||||||
} catch (e) {
|
} catch (error: unknown) {
|
||||||
|
const e = error as Error
|
||||||
expect(e).toBeInstanceOf(Error)
|
expect(e).toBeInstanceOf(Error)
|
||||||
expect(e.message).toContain('did not respond in 2ms')
|
expect(e.message).toContain('did not respond in 2ms')
|
||||||
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
expect(mockSlowGetArtifact).toHaveBeenCalledTimes(1)
|
expect(mockSlowGetArtifact).toHaveBeenCalledTimes(1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should extract zip file when content-type is application/zip', async () => {
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetArtifactSuccess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify files were extracted (not saved as a single file)
|
||||||
|
await expectExtractedArchive(fixtures.workspaceDir)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should save raw file without extracting when content-type is not a zip', async () => {
|
||||||
|
const rawFileContent = 'This is a raw text file, not a zip'
|
||||||
|
const rawFileName = 'my-artifact.txt'
|
||||||
|
|
||||||
|
const mockGetRawFile = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'text/plain'
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${rawFileName}"`
|
||||||
|
message.push(Buffer.from(rawFileContent))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetRawFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify file was saved as-is, not extracted
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, rawFileName)
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath, 'utf8')).toBe(rawFileContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should save raw file with default name when content-disposition is missing', async () => {
|
||||||
|
const rawFileContent = 'Binary content here'
|
||||||
|
|
||||||
|
const mockGetRawFileNoDisposition = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/octet-stream'
|
||||||
|
// No content-disposition header
|
||||||
|
message.push(Buffer.from(rawFileContent))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetRawFileNoDisposition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify file was saved with default name 'artifact'
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, 'artifact')
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath, 'utf8')).toBe(rawFileContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not attempt to unzip when content-type is image/png', async () => {
|
||||||
|
const pngFileName = 'screenshot.png'
|
||||||
|
// Simple PNG header bytes for testing
|
||||||
|
const pngContent = Buffer.from([
|
||||||
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a
|
||||||
|
])
|
||||||
|
|
||||||
|
const mockGetPngFile = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'image/png'
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${pngFileName}"`
|
||||||
|
message.push(pngContent)
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetPngFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify PNG was saved as-is
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, pngFileName)
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath)).toEqual(pngContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should extract when content-type is application/x-zip-compressed', async () => {
|
||||||
|
const mockGetZipCompressed = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/x-zip-compressed'
|
||||||
|
message.push(fs.readFileSync(fixtures.exampleArtifact.path))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetZipCompressed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify files were extracted
|
||||||
|
await expectExtractedArchive(fixtures.workspaceDir)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should extract zip when URL ends with .zip even if content-type is not application/zip', async () => {
|
||||||
|
const blobUrlWithZipExtension =
|
||||||
|
'https://blob-storage.local/artifact.zip?sig=abc123'
|
||||||
|
|
||||||
|
const mockGetZipByUrl = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
// Azure Blob Storage may return a generic content-type
|
||||||
|
message.headers['content-type'] = 'application/octet-stream'
|
||||||
|
message.push(fs.readFileSync(fixtures.exampleArtifact.path))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetZipByUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
blobUrlWithZipExtension,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify files were extracted based on URL .zip extension
|
||||||
|
await expectExtractedArchive(fixtures.workspaceDir)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should skip decompression when skipDecompress option is true even for zip content-type', async () => {
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetArtifactSuccess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir,
|
||||||
|
{skipDecompress: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify zip was saved as-is, not extracted
|
||||||
|
// When skipDecompress is true, the file should be saved with default name 'artifact'
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, 'artifact')
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
// The saved file should be the raw zip content
|
||||||
|
const savedContent = fs.readFileSync(savedFilePath)
|
||||||
|
const originalZipContent = fs.readFileSync(fixtures.exampleArtifact.path)
|
||||||
|
expect(savedContent).toEqual(originalZipContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sanitize path traversal attempts in Content-Disposition filename', async () => {
|
||||||
|
const rawFileContent = 'malicious content'
|
||||||
|
const maliciousFileName = '../../../etc/passwd'
|
||||||
|
|
||||||
|
const mockGetMaliciousFile = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'text/plain'
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${maliciousFileName}"`
|
||||||
|
message.push(Buffer.from(rawFileContent))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetMaliciousFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify file was saved with sanitized name (just 'passwd', not the full path)
|
||||||
|
const sanitizedFileName = 'passwd'
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, sanitizedFileName)
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath, 'utf8')).toBe(rawFileContent)
|
||||||
|
|
||||||
|
// Verify the file was NOT written outside the workspace directory
|
||||||
|
const maliciousPath = path.resolve(
|
||||||
|
fixtures.workspaceDir,
|
||||||
|
maliciousFileName
|
||||||
|
)
|
||||||
|
expect(fs.existsSync(maliciousPath)).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle encoded path traversal attempts in Content-Disposition filename', async () => {
|
||||||
|
const rawFileContent = 'encoded malicious content'
|
||||||
|
// URL encoded version of ../../../etc/passwd
|
||||||
|
const encodedMaliciousFileName = '..%2F..%2F..%2Fetc%2Fpasswd'
|
||||||
|
|
||||||
|
const mockGetEncodedMaliciousFile = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/octet-stream'
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${encodedMaliciousFileName}"`
|
||||||
|
message.push(Buffer.from(rawFileContent))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetEncodedMaliciousFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// After decoding and sanitizing, should just be 'passwd'
|
||||||
|
const sanitizedFileName = 'passwd'
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, sanitizedFileName)
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath, 'utf8')).toBe(rawFileContent)
|
||||||
|
|
||||||
|
// Verify the file was NOT written outside the workspace directory
|
||||||
|
const maliciousPathEncoded = path.resolve(
|
||||||
|
fixtures.workspaceDir,
|
||||||
|
encodedMaliciousFileName
|
||||||
|
)
|
||||||
|
expect(fs.existsSync(maliciousPathEncoded)).toBe(false)
|
||||||
|
|
||||||
|
const maliciousPath = path.resolve(
|
||||||
|
fixtures.workspaceDir,
|
||||||
|
'../../../etc/passwd'
|
||||||
|
)
|
||||||
|
expect(fs.existsSync(maliciousPath)).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should correctly handle Content-Disposition with filename* parameter (RFC 5987)', async () => {
|
||||||
|
const rawFileContent = 'content with rfc5987 encoding'
|
||||||
|
const expectedFileName = '报告-土-x.txt'
|
||||||
|
const asciiFileName = '__-_-x.txt'
|
||||||
|
|
||||||
|
const mockGetRfc5987File = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'text/plain'
|
||||||
|
// Server sends both: filename with _ fallbacks, filename* with UTF-8 encoding
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${asciiFileName}"; filename*=UTF-8''${encodeURIComponent(expectedFileName)}`
|
||||||
|
message.push(Buffer.from(rawFileContent, 'utf8'))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetRfc5987File
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, expectedFileName)
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath, 'utf8')).toBe(rawFileContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle zip artifacts with Chinese characters in the artifact name', async () => {
|
||||||
|
// Simulate Azure Blob Storage URL with rscd containing Chinese filename
|
||||||
|
const chineseArtifactName = 'probe-土-x'
|
||||||
|
const asciiArtifactName = 'probe-_-x'
|
||||||
|
const blobUrlWithChineseName = `https://blob-storage.local/artifact.zip?rscd=${encodeURIComponent(`attachment; filename="${asciiArtifactName}.zip"; filename*=UTF-8''${encodeURIComponent(`${chineseArtifactName}.zip`)}`)}&rsct=application%2Fzip&sig=abc123`
|
||||||
|
|
||||||
|
const mockGetZip = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'application/zip'
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${asciiArtifactName}.zip"; filename*=UTF-8''${encodeURIComponent(`${chineseArtifactName}.zip`)}`
|
||||||
|
message.push(fs.readFileSync(fixtures.exampleArtifact.path))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetZip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(blobUrlWithChineseName, fixtures.workspaceDir)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Zip should be extracted normally regardless of Chinese artifact name
|
||||||
|
await expectExtractedArchive(fixtures.workspaceDir)
|
||||||
|
})
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['土', '_'], // U+571F - known to cause 400 errors
|
||||||
|
['日', '_'], // U+65E5 - reported to work fine
|
||||||
|
['中文测试', '____'], // multiple Chinese characters
|
||||||
|
['文件-2026年', '__-2026_'], // mixed Chinese and numbers
|
||||||
|
['データ', '___'], // Japanese katakana
|
||||||
|
['테스트', '___'] // Korean characters
|
||||||
|
])(
|
||||||
|
'should prefer filename* over filename for non-ASCII character %s (%s)',
|
||||||
|
async (chars, asciiReplacement) => {
|
||||||
|
const rawFileContent = `content for ${chars}`
|
||||||
|
const expectedFileName = `artifact-${chars}.txt`
|
||||||
|
const asciiFileName = `artifact-${asciiReplacement}.txt`
|
||||||
|
|
||||||
|
const mockGetFile = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
message.headers['content-type'] = 'text/plain'
|
||||||
|
// Server sends filename with _ replacing non-ASCII, filename* with proper encoding
|
||||||
|
message.headers['content-disposition'] =
|
||||||
|
`attachment; filename="${asciiFileName}"; filename*=UTF-8''${encodeURIComponent(expectedFileName)}`
|
||||||
|
message.push(Buffer.from(rawFileContent, 'utf8'))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
const savedFilePath = path.join(fixtures.workspaceDir, expectedFileName)
|
||||||
|
expect(fs.existsSync(savedFilePath)).toBe(true)
|
||||||
|
expect(fs.readFileSync(savedFilePath, 'utf8')).toBe(rawFileContent)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ import type {RequestInterface} from '@octokit/types'
|
|||||||
import {
|
import {
|
||||||
getArtifactInternal,
|
getArtifactInternal,
|
||||||
getArtifactPublic
|
getArtifactPublic
|
||||||
} from '../src/internal/find/get-artifact'
|
} from '../src/internal/find/get-artifact.js'
|
||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
|
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated/index.js'
|
||||||
import * as util from '../src/internal/shared/util'
|
import * as util from '../src/internal/shared/util.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
import {
|
import {
|
||||||
ArtifactNotFoundError,
|
ArtifactNotFoundError,
|
||||||
InvalidResponseError
|
InvalidResponseError
|
||||||
} from '../src/internal/shared/errors'
|
} from '../src/internal/shared/errors.js'
|
||||||
|
|
||||||
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import type {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-method
|
|||||||
import {
|
import {
|
||||||
listArtifactsInternal,
|
listArtifactsInternal,
|
||||||
listArtifactsPublic
|
listArtifactsPublic
|
||||||
} from '../src/internal/find/list-artifacts'
|
} from '../src/internal/find/list-artifacts.js'
|
||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated'
|
import {ArtifactServiceClientJSON, Timestamp} from '../src/generated/index.js'
|
||||||
import * as util from '../src/internal/shared/util'
|
import * as util from '../src/internal/shared/util.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
import {Artifact} from '../src/internal/shared/interfaces'
|
import {Artifact} from '../src/internal/shared/interfaces.js'
|
||||||
import {RequestInterface} from '@octokit/types'
|
import {RequestInterface} from '@octokit/types'
|
||||||
|
|
||||||
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
type MockedRequest = jest.MockedFunction<RequestInterface<object>>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
validateArtifactName,
|
validateArtifactName,
|
||||||
validateFilePath
|
validateFilePath
|
||||||
} from '../src/internal/upload/path-and-artifact-name-validation'
|
} from '../src/internal/upload/path-and-artifact-name-validation.js'
|
||||||
|
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
|
|
||||||
describe('Path and artifact name validation', () => {
|
describe('Path and artifact name validation', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {Timestamp} from '../src/generated'
|
import {Timestamp} from '../src/generated/index.js'
|
||||||
import * as retention from '../src/internal/upload/retention'
|
import * as retention from '../src/internal/upload/retention.js'
|
||||||
|
|
||||||
describe('retention', () => {
|
describe('retention', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import * as fs from 'fs'
|
||||||
|
import * as path from 'path'
|
||||||
|
import {createRawFileUploadStream} from '../src/internal/upload/stream.js'
|
||||||
|
import {noopLogs} from './common.js'
|
||||||
|
|
||||||
|
const fixtures = {
|
||||||
|
testDirectory: path.join(__dirname, '_temp', 'stream-test'),
|
||||||
|
testFile: path.join(__dirname, '_temp', 'stream-test', 'test-file.txt'),
|
||||||
|
testContent: 'hello stream test'
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('createRawFileUploadStream', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
fs.mkdirSync(fixtures.testDirectory, {recursive: true})
|
||||||
|
fs.writeFileSync(fixtures.testFile, fixtures.testContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
noopLogs()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should stream file contents through the upload stream', async () => {
|
||||||
|
const uploadStream = await createRawFileUploadStream(fixtures.testFile)
|
||||||
|
|
||||||
|
const chunks: Buffer[] = []
|
||||||
|
const result = await new Promise<string>((resolve, reject) => {
|
||||||
|
uploadStream.on('data', chunk => chunks.push(Buffer.from(chunk)))
|
||||||
|
uploadStream.on('end', () =>
|
||||||
|
resolve(Buffer.concat(chunks).toString('utf-8'))
|
||||||
|
)
|
||||||
|
uploadStream.on('error', reject)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result).toBe(fixtures.testContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should propagate file read errors through the upload stream', async () => {
|
||||||
|
// Use a directory path — createReadStream on a directory fails cross-platform
|
||||||
|
// Mock lstat to return a non-symlink result so we reach createReadStream
|
||||||
|
const dirPath = fixtures.testDirectory
|
||||||
|
jest
|
||||||
|
.spyOn(fs.promises, 'lstat')
|
||||||
|
.mockResolvedValue({isSymbolicLink: () => false} as fs.Stats)
|
||||||
|
|
||||||
|
const uploadStream = await createRawFileUploadStream(dirPath)
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
uploadStream.on('data', resolve)
|
||||||
|
uploadStream.on('end', resolve)
|
||||||
|
uploadStream.on('error', reject)
|
||||||
|
})
|
||||||
|
).rejects.toThrow('An error has occurred during file read for the artifact')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import * as uploadZipSpecification from '../src/internal/upload/upload-zip-specification'
|
import * as uploadZipSpecification from '../src/internal/upload/upload-zip-specification.js'
|
||||||
import * as zip from '../src/internal/upload/zip'
|
import * as zip from '../src/internal/upload/zip.js'
|
||||||
import * as util from '../src/internal/shared/util'
|
import * as util from '../src/internal/shared/util.js'
|
||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import {ArtifactServiceClientJSON} from '../src/generated'
|
import {ArtifactServiceClientJSON} from '../src/generated/index.js'
|
||||||
import * as blobUpload from '../src/internal/upload/blob-upload'
|
import * as blobUpload from '../src/internal/upload/blob-upload.js'
|
||||||
import {uploadArtifact} from '../src/internal/upload/upload-artifact'
|
import {uploadArtifact} from '../src/internal/upload/upload-artifact.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
import {FilesNotFoundError} from '../src/internal/shared/errors'
|
import {FilesNotFoundError} from '../src/internal/shared/errors.js'
|
||||||
|
import * as stream from '../src/internal/upload/stream.js'
|
||||||
import {BlockBlobUploadStreamOptions} from '@azure/storage-blob'
|
import {BlockBlobUploadStreamOptions} from '@azure/storage-blob'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
@@ -150,7 +151,7 @@ describe('upload-artifact', () => {
|
|||||||
it('should return false if the creation request fails', async () => {
|
it('should return false if the creation request fails', async () => {
|
||||||
jest
|
jest
|
||||||
.spyOn(zip, 'createZipUploadStream')
|
.spyOn(zip, 'createZipUploadStream')
|
||||||
.mockReturnValue(Promise.resolve(new zip.ZipUploadStream(1)))
|
.mockReturnValue(Promise.resolve(new stream.WaterMarkedUploadStream(1)))
|
||||||
jest
|
jest
|
||||||
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
.mockReturnValue(Promise.resolve({ok: false, signedUploadUrl: ''}))
|
.mockReturnValue(Promise.resolve({ok: false, signedUploadUrl: ''}))
|
||||||
@@ -167,7 +168,7 @@ describe('upload-artifact', () => {
|
|||||||
it('should return false if blob storage upload is unsuccessful', async () => {
|
it('should return false if blob storage upload is unsuccessful', async () => {
|
||||||
jest
|
jest
|
||||||
.spyOn(zip, 'createZipUploadStream')
|
.spyOn(zip, 'createZipUploadStream')
|
||||||
.mockReturnValue(Promise.resolve(new zip.ZipUploadStream(1)))
|
.mockReturnValue(Promise.resolve(new stream.WaterMarkedUploadStream(1)))
|
||||||
jest
|
jest
|
||||||
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
.mockReturnValue(
|
.mockReturnValue(
|
||||||
@@ -177,7 +178,7 @@ describe('upload-artifact', () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
jest
|
jest
|
||||||
.spyOn(blobUpload, 'uploadZipToBlobStorage')
|
.spyOn(blobUpload, 'uploadToBlobStorage')
|
||||||
.mockReturnValue(Promise.reject(new Error('boom')))
|
.mockReturnValue(Promise.reject(new Error('boom')))
|
||||||
|
|
||||||
const uploadResp = uploadArtifact(
|
const uploadResp = uploadArtifact(
|
||||||
@@ -192,7 +193,7 @@ describe('upload-artifact', () => {
|
|||||||
it('should reject if finalize artifact fails', async () => {
|
it('should reject if finalize artifact fails', async () => {
|
||||||
jest
|
jest
|
||||||
.spyOn(zip, 'createZipUploadStream')
|
.spyOn(zip, 'createZipUploadStream')
|
||||||
.mockReturnValue(Promise.resolve(new zip.ZipUploadStream(1)))
|
.mockReturnValue(Promise.resolve(new stream.WaterMarkedUploadStream(1)))
|
||||||
jest
|
jest
|
||||||
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
.mockReturnValue(
|
.mockReturnValue(
|
||||||
@@ -201,7 +202,7 @@ describe('upload-artifact', () => {
|
|||||||
signedUploadUrl: 'https://signed-upload-url.com'
|
signedUploadUrl: 'https://signed-upload-url.com'
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
jest.spyOn(blobUpload, 'uploadZipToBlobStorage').mockReturnValue(
|
jest.spyOn(blobUpload, 'uploadToBlobStorage').mockReturnValue(
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
uploadSize: 1234,
|
uploadSize: 1234,
|
||||||
sha256Hash: 'test-sha256-hash'
|
sha256Hash: 'test-sha256-hash'
|
||||||
@@ -370,4 +371,284 @@ describe('upload-artifact', () => {
|
|||||||
|
|
||||||
await expect(uploadResp).rejects.toThrow('Upload progress stalled.')
|
await expect(uploadResp).rejects.toThrow('Upload progress stalled.')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('skipArchive option', () => {
|
||||||
|
it('should throw an error if skipArchive is true and files array is empty', async () => {
|
||||||
|
const uploadResp = uploadArtifact(
|
||||||
|
fixtures.inputs.artifactName,
|
||||||
|
[],
|
||||||
|
fixtures.inputs.rootDirectory,
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
await expect(uploadResp).rejects.toThrow(FilesNotFoundError)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw an error if skipArchive is true and multiple files are provided', async () => {
|
||||||
|
const uploadResp = uploadArtifact(
|
||||||
|
fixtures.inputs.artifactName,
|
||||||
|
fixtures.inputs.files,
|
||||||
|
fixtures.inputs.rootDirectory,
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
await expect(uploadResp).rejects.toThrow(
|
||||||
|
'skipArchive option is only supported when uploading a single file'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should upload a single file without archiving when skipArchive is true', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(uploadZipSpecification, 'getUploadZipSpecification')
|
||||||
|
.mockRestore()
|
||||||
|
|
||||||
|
const singleFile = path.join(fixtures.uploadDirectory, 'file1.txt')
|
||||||
|
const expectedContent = 'test 1 file content'
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
signedUploadUrl: 'https://signed-upload-url.local'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'FinalizeArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
artifactId: '1'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
let uploadedContent = ''
|
||||||
|
let loadedBytes = 0
|
||||||
|
uploadStreamMock.mockImplementation(
|
||||||
|
async (
|
||||||
|
stream: NodeJS.ReadableStream,
|
||||||
|
bufferSize?: number,
|
||||||
|
maxConcurrency?: number,
|
||||||
|
options?: BlockBlobUploadStreamOptions
|
||||||
|
) => {
|
||||||
|
const {onProgress} = options || {}
|
||||||
|
|
||||||
|
onProgress?.({loadedBytes: 0})
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
stream.on('data', chunk => {
|
||||||
|
loadedBytes += chunk.length
|
||||||
|
uploadedContent += chunk.toString()
|
||||||
|
onProgress?.({loadedBytes})
|
||||||
|
})
|
||||||
|
stream.on('end', () => {
|
||||||
|
onProgress?.({loadedBytes})
|
||||||
|
resolve({})
|
||||||
|
})
|
||||||
|
stream.on('error', err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const {id, size, digest} = await uploadArtifact(
|
||||||
|
fixtures.inputs.artifactName,
|
||||||
|
[singleFile],
|
||||||
|
fixtures.uploadDirectory,
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(id).toBe(1)
|
||||||
|
expect(size).toBe(loadedBytes)
|
||||||
|
expect(digest).toBeDefined()
|
||||||
|
expect(digest).toHaveLength(64)
|
||||||
|
// Verify the uploaded content is the raw file, not a zip
|
||||||
|
expect(uploadedContent).toBe(expectedContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should use the correct MIME type when skipArchive is true', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(uploadZipSpecification, 'getUploadZipSpecification')
|
||||||
|
.mockRestore()
|
||||||
|
|
||||||
|
const singleFile = path.join(fixtures.uploadDirectory, 'file1.txt')
|
||||||
|
|
||||||
|
const createArtifactSpy = jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
signedUploadUrl: 'https://signed-upload-url.local'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'FinalizeArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
artifactId: '1'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
uploadStreamMock.mockImplementation(
|
||||||
|
async (
|
||||||
|
stream: NodeJS.ReadableStream,
|
||||||
|
bufferSize?: number,
|
||||||
|
maxConcurrency?: number,
|
||||||
|
options?: BlockBlobUploadStreamOptions
|
||||||
|
) => {
|
||||||
|
const {onProgress} = options || {}
|
||||||
|
onProgress?.({loadedBytes: 0})
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
stream.on('data', chunk => {
|
||||||
|
onProgress?.({loadedBytes: chunk.length})
|
||||||
|
})
|
||||||
|
stream.on('end', () => {
|
||||||
|
resolve({})
|
||||||
|
})
|
||||||
|
stream.on('error', err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await uploadArtifact(
|
||||||
|
fixtures.inputs.artifactName,
|
||||||
|
[singleFile],
|
||||||
|
fixtures.uploadDirectory,
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verify CreateArtifact was called with the correct MIME type for .txt file
|
||||||
|
expect(createArtifactSpy).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
mimeType: expect.objectContaining({value: 'text/plain'})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should use application/zip MIME type when skipArchive is false', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(uploadZipSpecification, 'getUploadZipSpecification')
|
||||||
|
.mockRestore()
|
||||||
|
|
||||||
|
const createArtifactSpy = jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
signedUploadUrl: 'https://signed-upload-url.local'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'FinalizeArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
artifactId: '1'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
uploadStreamMock.mockImplementation(
|
||||||
|
async (
|
||||||
|
stream: NodeJS.ReadableStream,
|
||||||
|
bufferSize?: number,
|
||||||
|
maxConcurrency?: number,
|
||||||
|
options?: BlockBlobUploadStreamOptions
|
||||||
|
) => {
|
||||||
|
const {onProgress} = options || {}
|
||||||
|
onProgress?.({loadedBytes: 0})
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
stream.on('data', chunk => {
|
||||||
|
onProgress?.({loadedBytes: chunk.length})
|
||||||
|
})
|
||||||
|
stream.on('end', () => {
|
||||||
|
resolve({})
|
||||||
|
})
|
||||||
|
stream.on('error', err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await uploadArtifact(
|
||||||
|
fixtures.inputs.artifactName,
|
||||||
|
fixtures.files.map(file =>
|
||||||
|
path.join(fixtures.uploadDirectory, file.name)
|
||||||
|
),
|
||||||
|
fixtures.uploadDirectory
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verify CreateArtifact was called with application/zip MIME type
|
||||||
|
expect(createArtifactSpy).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
mimeType: expect.objectContaining({value: 'application/zip'})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should use the file basename as artifact name when skipArchive is true', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(uploadZipSpecification, 'getUploadZipSpecification')
|
||||||
|
.mockRestore()
|
||||||
|
|
||||||
|
const singleFile = path.join(fixtures.uploadDirectory, 'file1.txt')
|
||||||
|
|
||||||
|
const createArtifactSpy = jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'CreateArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
signedUploadUrl: 'https://signed-upload-url.local'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
jest
|
||||||
|
.spyOn(ArtifactServiceClientJSON.prototype, 'FinalizeArtifact')
|
||||||
|
.mockReturnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
artifactId: '1'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
uploadStreamMock.mockImplementation(
|
||||||
|
async (
|
||||||
|
stream: NodeJS.ReadableStream,
|
||||||
|
bufferSize?: number,
|
||||||
|
maxConcurrency?: number,
|
||||||
|
options?: BlockBlobUploadStreamOptions
|
||||||
|
) => {
|
||||||
|
const {onProgress} = options || {}
|
||||||
|
onProgress?.({loadedBytes: 0})
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
stream.on('data', chunk => {
|
||||||
|
onProgress?.({loadedBytes: chunk.length})
|
||||||
|
})
|
||||||
|
stream.on('end', () => {
|
||||||
|
resolve({})
|
||||||
|
})
|
||||||
|
stream.on('error', err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await uploadArtifact(
|
||||||
|
'original-name',
|
||||||
|
[singleFile],
|
||||||
|
fixtures.uploadDirectory,
|
||||||
|
{skipArchive: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verify CreateArtifact was called with the file basename, not the original name
|
||||||
|
expect(createArtifactSpy).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
name: 'file1.txt'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import {promises as fs} from 'fs'
|
|||||||
import {
|
import {
|
||||||
getUploadZipSpecification,
|
getUploadZipSpecification,
|
||||||
validateRootDirectory
|
validateRootDirectory
|
||||||
} from '../src/internal/upload/upload-zip-specification'
|
} from '../src/internal/upload/upload-zip-specification.js'
|
||||||
import {noopLogs} from './common'
|
import {noopLogs} from './common.js'
|
||||||
|
|
||||||
const root = path.join(__dirname, '_temp', 'upload-specification')
|
const root = path.join(__dirname, '_temp', 'upload-specification')
|
||||||
const goodItem1Path = path.join(
|
const goodItem1Path = path.join(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config.js'
|
||||||
import * as util from '../src/internal/shared/util'
|
import * as util from '../src/internal/shared/util.js'
|
||||||
import {maskSigUrl, maskSecretUrls} from '../src/internal/shared/util'
|
import {maskSigUrl, maskSecretUrls} from '../src/internal/shared/util.js'
|
||||||
import {setSecret, debug} from '@actions/core'
|
import {setSecret, debug} from '@actions/core'
|
||||||
|
|
||||||
export const testRuntimeToken =
|
export const testRuntimeToken =
|
||||||
|
|||||||
Generated
+266
-935
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/artifact",
|
"name": "@actions/artifact",
|
||||||
"version": "4.0.0",
|
"version": "6.2.1",
|
||||||
"preview": true,
|
"preview": true,
|
||||||
"description": "Actions artifact lib",
|
"description": "Actions artifact lib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -10,8 +10,15 @@
|
|||||||
],
|
],
|
||||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/artifact",
|
"homepage": "https://github.com/actions/toolkit/tree/main/packages/artifact",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
"main": "lib/artifact.js",
|
"main": "lib/artifact.js",
|
||||||
"types": "lib/artifact.d.ts",
|
"types": "lib/artifact.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./lib/artifact.d.ts",
|
||||||
|
"import": "./lib/artifact.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib",
|
"lib": "lib",
|
||||||
"test": "__tests__"
|
"test": "__tests__"
|
||||||
@@ -32,7 +39,7 @@
|
|||||||
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
|
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
|
||||||
"test": "cd ../../ && npm run test ./packages/artifact",
|
"test": "cd ../../ && npm run test ./packages/artifact",
|
||||||
"bootstrap": "cd ../../ && npm run bootstrap",
|
"bootstrap": "cd ../../ && npm run bootstrap",
|
||||||
"tsc-run": "tsc",
|
"tsc-run": "tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/",
|
||||||
"tsc": "npm run bootstrap && npm run tsc-run",
|
"tsc": "npm run bootstrap && npm run tsc-run",
|
||||||
"gen:docs": "typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"
|
"gen:docs": "typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"
|
||||||
},
|
},
|
||||||
@@ -40,27 +47,27 @@
|
|||||||
"url": "https://github.com/actions/toolkit/issues"
|
"url": "https://github.com/actions/toolkit/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^2.0.0",
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/github": "^6.0.1",
|
"@actions/github": "^9.0.0",
|
||||||
"@actions/http-client": "^3.0.0",
|
"@actions/http-client": "^4.0.0",
|
||||||
"@azure/core-http": "^3.0.5",
|
"@azure/storage-blob": "^12.30.0",
|
||||||
"@azure/storage-blob": "^12.15.0",
|
"@octokit/core": "^7.0.6",
|
||||||
"@octokit/core": "^5.2.1",
|
"@octokit/plugin-request-log": "^6.0.0",
|
||||||
"@octokit/plugin-request-log": "^1.0.4",
|
"@octokit/plugin-retry": "^8.0.0",
|
||||||
"@octokit/plugin-retry": "^3.0.9",
|
"@octokit/request": "^10.0.7",
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request-error": "^7.1.0",
|
||||||
"@octokit/request-error": "^5.1.1",
|
|
||||||
"@protobuf-ts/plugin": "^2.2.3-alpha.1",
|
"@protobuf-ts/plugin": "^2.2.3-alpha.1",
|
||||||
|
"@protobuf-ts/runtime": "^2.9.4",
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^4.0.0",
|
||||||
"unzip-stream": "^0.3.1"
|
"unzip-stream": "^0.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/archiver": "^5.3.2",
|
"@types/archiver": "^7.0.0",
|
||||||
"@types/unzip-stream": "^0.3.4",
|
"@types/unzip-stream": "^0.3.4",
|
||||||
"typedoc": "^0.28.13",
|
"typedoc": "^0.28.16",
|
||||||
"typedoc-plugin-markdown": "^3.17.1",
|
"typedoc-plugin-markdown": "^4.9.0",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"uri-js": "npm:uri-js-replace@^1.0.1",
|
"uri-js": "npm:uri-js-replace@^1.0.1",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {ArtifactClient, DefaultArtifactClient} from './internal/client'
|
import {ArtifactClient, DefaultArtifactClient} from './internal/client.js'
|
||||||
|
|
||||||
export * from './internal/shared/interfaces'
|
export * from './internal/shared/interfaces.js'
|
||||||
export * from './internal/shared/errors'
|
export * from './internal/shared/errors.js'
|
||||||
export * from './internal/client'
|
export * from './internal/client.js'
|
||||||
|
|
||||||
const client: ArtifactClient = new DefaultArtifactClient()
|
const client: ArtifactClient = new DefaultArtifactClient()
|
||||||
export default client
|
export default client
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export * from './google/protobuf/timestamp'
|
export * from './google/protobuf/timestamp.js'
|
||||||
export * from './google/protobuf/wrappers'
|
export * from './google/protobuf/wrappers.js'
|
||||||
export * from './results/api/v1/artifact'
|
export * from './results/api/v1/artifact.js'
|
||||||
export * from './results/api/v1/artifact.twirp-client'
|
export * from './results/api/v1/artifact.twirp-client.js'
|
||||||
|
|||||||
@@ -12,69 +12,9 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
|
|||||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||||
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
||||||
import { MessageType } from "@protobuf-ts/runtime";
|
import { MessageType } from "@protobuf-ts/runtime";
|
||||||
import { Int64Value } from "../../../google/protobuf/wrappers";
|
import { Int64Value } from "../../../google/protobuf/wrappers.js";
|
||||||
import { StringValue } from "../../../google/protobuf/wrappers";
|
import { StringValue } from "../../../google/protobuf/wrappers.js";
|
||||||
import { Timestamp } from "../../../google/protobuf/timestamp";
|
import { Timestamp } from "../../../google/protobuf/timestamp.js";
|
||||||
/**
|
|
||||||
* @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
|
* @generated from protobuf message github.actions.results.api.v1.CreateArtifactRequest
|
||||||
*/
|
*/
|
||||||
@@ -99,6 +39,10 @@ export interface CreateArtifactRequest {
|
|||||||
* @generated from protobuf field: int32 version = 5;
|
* @generated from protobuf field: int32 version = 5;
|
||||||
*/
|
*/
|
||||||
version: number;
|
version: number;
|
||||||
|
/**
|
||||||
|
* @generated from protobuf field: google.protobuf.StringValue mime_type = 6;
|
||||||
|
*/
|
||||||
|
mimeType?: StringValue; // optional
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @generated from protobuf message github.actions.results.api.v1.CreateArtifactResponse
|
* @generated from protobuf message github.actions.results.api.v1.CreateArtifactResponse
|
||||||
@@ -293,236 +237,6 @@ export interface DeleteArtifactResponse {
|
|||||||
artifactId: string;
|
artifactId: string;
|
||||||
}
|
}
|
||||||
// @generated message type with reflection information, may provide speed optimized methods
|
// @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> {
|
class CreateArtifactRequest$Type extends MessageType<CreateArtifactRequest> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("github.actions.results.api.v1.CreateArtifactRequest", [
|
super("github.actions.results.api.v1.CreateArtifactRequest", [
|
||||||
@@ -530,7 +244,8 @@ class CreateArtifactRequest$Type extends MessageType<CreateArtifactRequest> {
|
|||||||
{ no: 2, name: "workflow_job_run_backend_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
{ no: 2, name: "workflow_job_run_backend_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||||
{ no: 3, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
{ no: 3, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||||
{ no: 4, name: "expires_at", kind: "message", T: () => Timestamp },
|
{ no: 4, name: "expires_at", kind: "message", T: () => Timestamp },
|
||||||
{ no: 5, name: "version", kind: "scalar", T: 5 /*ScalarType.INT32*/ }
|
{ no: 5, name: "version", kind: "scalar", T: 5 /*ScalarType.INT32*/ },
|
||||||
|
{ no: 6, name: "mime_type", kind: "message", T: () => StringValue }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
create(value?: PartialMessage<CreateArtifactRequest>): CreateArtifactRequest {
|
create(value?: PartialMessage<CreateArtifactRequest>): CreateArtifactRequest {
|
||||||
@@ -560,6 +275,9 @@ class CreateArtifactRequest$Type extends MessageType<CreateArtifactRequest> {
|
|||||||
case /* int32 version */ 5:
|
case /* int32 version */ 5:
|
||||||
message.version = reader.int32();
|
message.version = reader.int32();
|
||||||
break;
|
break;
|
||||||
|
case /* google.protobuf.StringValue mime_type */ 6:
|
||||||
|
message.mimeType = StringValue.internalBinaryRead(reader, reader.uint32(), options, message.mimeType);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
let u = options.readUnknownField;
|
let u = options.readUnknownField;
|
||||||
if (u === "throw")
|
if (u === "throw")
|
||||||
@@ -587,6 +305,9 @@ class CreateArtifactRequest$Type extends MessageType<CreateArtifactRequest> {
|
|||||||
/* int32 version = 5; */
|
/* int32 version = 5; */
|
||||||
if (message.version !== 0)
|
if (message.version !== 0)
|
||||||
writer.tag(5, WireType.Varint).int32(message.version);
|
writer.tag(5, WireType.Varint).int32(message.version);
|
||||||
|
/* google.protobuf.StringValue mime_type = 6; */
|
||||||
|
if (message.mimeType)
|
||||||
|
StringValue.internalBinaryWrite(message.mimeType, writer.tag(6, WireType.LengthDelimited).fork(), options).join();
|
||||||
let u = options.writeUnknownFields;
|
let u = options.writeUnknownFields;
|
||||||
if (u !== false)
|
if (u !== false)
|
||||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||||
@@ -852,7 +573,7 @@ export const ListArtifactsRequest = new ListArtifactsRequest$Type();
|
|||||||
class ListArtifactsResponse$Type extends MessageType<ListArtifactsResponse> {
|
class ListArtifactsResponse$Type extends MessageType<ListArtifactsResponse> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("github.actions.results.api.v1.ListArtifactsResponse", [
|
super("github.actions.results.api.v1.ListArtifactsResponse", [
|
||||||
{ no: 1, name: "artifacts", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ListArtifactsResponse_MonolithArtifact }
|
{ no: 1, name: "artifacts", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => ListArtifactsResponse_MonolithArtifact }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
create(value?: PartialMessage<ListArtifactsResponse>): ListArtifactsResponse {
|
create(value?: PartialMessage<ListArtifactsResponse>): ListArtifactsResponse {
|
||||||
@@ -1215,7 +936,5 @@ export const ArtifactService = new ServiceType("github.actions.results.api.v1.Ar
|
|||||||
{ name: "FinalizeArtifact", options: {}, I: FinalizeArtifactRequest, O: FinalizeArtifactResponse },
|
{ name: "FinalizeArtifact", options: {}, I: FinalizeArtifactRequest, O: FinalizeArtifactResponse },
|
||||||
{ name: "ListArtifacts", options: {}, I: ListArtifactsRequest, O: ListArtifactsResponse },
|
{ name: "ListArtifacts", options: {}, I: ListArtifactsRequest, O: ListArtifactsResponse },
|
||||||
{ name: "GetSignedArtifactURL", options: {}, I: GetSignedArtifactURLRequest, O: GetSignedArtifactURLResponse },
|
{ 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 }
|
|
||||||
]);
|
]);
|
||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
GetSignedArtifactURLResponse,
|
GetSignedArtifactURLResponse,
|
||||||
DeleteArtifactRequest,
|
DeleteArtifactRequest,
|
||||||
DeleteArtifactResponse,
|
DeleteArtifactResponse,
|
||||||
} from "./artifact";
|
} from "./artifact.js";
|
||||||
|
|
||||||
//==================================//
|
//==================================//
|
||||||
// Client Code //
|
// Client Code //
|
||||||
@@ -229,4 +229,4 @@ export class ArtifactServiceClientProtobuf implements ArtifactServiceClient {
|
|||||||
DeleteArtifactResponse.fromBinary(data as Uint8Array)
|
DeleteArtifactResponse.fromBinary(data as Uint8Array)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import {warning} from '@actions/core'
|
import {warning} from '@actions/core'
|
||||||
import {isGhes} from './shared/config'
|
import {isGhes} from './shared/config.js'
|
||||||
import {
|
import {
|
||||||
UploadArtifactOptions,
|
UploadArtifactOptions,
|
||||||
UploadArtifactResponse,
|
UploadArtifactResponse,
|
||||||
@@ -10,19 +10,22 @@ import {
|
|||||||
DownloadArtifactResponse,
|
DownloadArtifactResponse,
|
||||||
FindOptions,
|
FindOptions,
|
||||||
DeleteArtifactResponse
|
DeleteArtifactResponse
|
||||||
} from './shared/interfaces'
|
} from './shared/interfaces.js'
|
||||||
import {uploadArtifact} from './upload/upload-artifact'
|
import {uploadArtifact} from './upload/upload-artifact.js'
|
||||||
import {
|
import {
|
||||||
downloadArtifactPublic,
|
downloadArtifactPublic,
|
||||||
downloadArtifactInternal
|
downloadArtifactInternal
|
||||||
} from './download/download-artifact'
|
} from './download/download-artifact.js'
|
||||||
import {
|
import {
|
||||||
deleteArtifactPublic,
|
deleteArtifactPublic,
|
||||||
deleteArtifactInternal
|
deleteArtifactInternal
|
||||||
} from './delete/delete-artifact'
|
} from './delete/delete-artifact.js'
|
||||||
import {getArtifactPublic, getArtifactInternal} from './find/get-artifact'
|
import {getArtifactPublic, getArtifactInternal} from './find/get-artifact.js'
|
||||||
import {listArtifactsPublic, listArtifactsInternal} from './find/list-artifacts'
|
import {
|
||||||
import {GHESNotSupportedError} from './shared/errors'
|
listArtifactsPublic,
|
||||||
|
listArtifactsInternal
|
||||||
|
} from './find/list-artifacts.js'
|
||||||
|
import {GHESNotSupportedError} from './shared/errors.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic interface for the artifact client.
|
* Generic interface for the artifact client.
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import {info, debug} from '@actions/core'
|
import {info, debug} from '@actions/core'
|
||||||
import {getOctokit} from '@actions/github'
|
import {getOctokit} from '@actions/github'
|
||||||
import {DeleteArtifactResponse} from '../shared/interfaces'
|
import {DeleteArtifactResponse} from '../shared/interfaces.js'
|
||||||
import {getUserAgentString} from '../shared/user-agent'
|
import {getUserAgentString} from '../shared/user-agent.js'
|
||||||
import {getRetryOptions} from '../find/retry-options'
|
import {getRetryOptions} from '../find/retry-options.js'
|
||||||
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
|
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
|
||||||
import {requestLog} from '@octokit/plugin-request-log'
|
import {requestLog} from '@octokit/plugin-request-log'
|
||||||
import {retry} from '@octokit/plugin-retry'
|
import {retry} from '@octokit/plugin-retry'
|
||||||
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
import type {OctokitOptions} from '@octokit/core/types'
|
||||||
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
|
||||||
import {getBackendIdsFromToken} from '../shared/util'
|
import {getBackendIdsFromToken} from '../shared/util.js'
|
||||||
import {
|
import {
|
||||||
DeleteArtifactRequest,
|
DeleteArtifactRequest,
|
||||||
ListArtifactsRequest,
|
ListArtifactsRequest,
|
||||||
StringValue
|
StringValue
|
||||||
} from '../../generated'
|
} from '../../generated/index.js'
|
||||||
import {getArtifactPublic} from '../find/get-artifact'
|
import {getArtifactPublic} from '../find/get-artifact.js'
|
||||||
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors'
|
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors.js'
|
||||||
|
|
||||||
export async function deleteArtifactPublic(
|
export async function deleteArtifactPublic(
|
||||||
artifactName: string,
|
artifactName: string,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
|
import * as fsSync from 'fs'
|
||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as stream from 'stream'
|
import * as stream from 'stream'
|
||||||
|
import * as path from 'path'
|
||||||
|
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
@@ -10,17 +12,17 @@ import {
|
|||||||
DownloadArtifactOptions,
|
DownloadArtifactOptions,
|
||||||
DownloadArtifactResponse,
|
DownloadArtifactResponse,
|
||||||
StreamExtractResponse
|
StreamExtractResponse
|
||||||
} from '../shared/interfaces'
|
} from '../shared/interfaces.js'
|
||||||
import {getUserAgentString} from '../shared/user-agent'
|
import {getUserAgentString} from '../shared/user-agent.js'
|
||||||
import {getGitHubWorkspaceDir} from '../shared/config'
|
import {getGitHubWorkspaceDir} from '../shared/config.js'
|
||||||
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
|
||||||
import {
|
import {
|
||||||
GetSignedArtifactURLRequest,
|
GetSignedArtifactURLRequest,
|
||||||
Int64Value,
|
Int64Value,
|
||||||
ListArtifactsRequest
|
ListArtifactsRequest
|
||||||
} from '../../generated'
|
} from '../../generated/index.js'
|
||||||
import {getBackendIdsFromToken} from '../shared/util'
|
import {getBackendIdsFromToken} from '../shared/util.js'
|
||||||
import {ArtifactNotFoundError} from '../shared/errors'
|
import {ArtifactNotFoundError} from '../shared/errors.js'
|
||||||
|
|
||||||
const scrubQueryParameters = (url: string): string => {
|
const scrubQueryParameters = (url: string): string => {
|
||||||
const parsed = new URL(url)
|
const parsed = new URL(url)
|
||||||
@@ -43,12 +45,13 @@ async function exists(path: string): Promise<boolean> {
|
|||||||
|
|
||||||
async function streamExtract(
|
async function streamExtract(
|
||||||
url: string,
|
url: string,
|
||||||
directory: string
|
directory: string,
|
||||||
|
skipDecompress?: boolean
|
||||||
): Promise<StreamExtractResponse> {
|
): Promise<StreamExtractResponse> {
|
||||||
let retryCount = 0
|
let retryCount = 0
|
||||||
while (retryCount < 5) {
|
while (retryCount < 5) {
|
||||||
try {
|
try {
|
||||||
return await streamExtractExternal(url, directory)
|
return await streamExtractExternal(url, directory, {skipDecompress})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
retryCount++
|
retryCount++
|
||||||
core.debug(
|
core.debug(
|
||||||
@@ -65,8 +68,9 @@ async function streamExtract(
|
|||||||
export async function streamExtractExternal(
|
export async function streamExtractExternal(
|
||||||
url: string,
|
url: string,
|
||||||
directory: string,
|
directory: string,
|
||||||
opts: {timeout: number} = {timeout: 30 * 1000}
|
opts: {timeout?: number; skipDecompress?: boolean} = {}
|
||||||
): Promise<StreamExtractResponse> {
|
): Promise<StreamExtractResponse> {
|
||||||
|
const {timeout = 30 * 1000, skipDecompress = false} = opts
|
||||||
const client = new httpClient.HttpClient(getUserAgentString())
|
const client = new httpClient.HttpClient(getUserAgentString())
|
||||||
const response = await client.get(url)
|
const response = await client.get(url)
|
||||||
if (response.message.statusCode !== 200) {
|
if (response.message.statusCode !== 200) {
|
||||||
@@ -75,49 +79,97 @@ export async function streamExtractExternal(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contentType = response.message.headers['content-type'] || ''
|
||||||
|
const mimeType = contentType.split(';', 1)[0].trim().toLowerCase()
|
||||||
|
|
||||||
|
// Check if the URL path ends with .zip (ignoring query parameters)
|
||||||
|
const urlPath = new URL(url).pathname.toLowerCase()
|
||||||
|
const urlEndsWithZip = urlPath.endsWith('.zip')
|
||||||
|
|
||||||
|
const isZip =
|
||||||
|
mimeType === 'application/zip' ||
|
||||||
|
mimeType === 'application/x-zip-compressed' ||
|
||||||
|
mimeType === 'application/zip-compressed' ||
|
||||||
|
urlEndsWithZip
|
||||||
|
|
||||||
|
// Extract filename from Content-Disposition header
|
||||||
|
// Prefer filename* (RFC 5987) which supports UTF-8 encoded filenames,
|
||||||
|
// fall back to filename which may contain ASCII-only replacements
|
||||||
|
const contentDisposition =
|
||||||
|
response.message.headers['content-disposition'] || ''
|
||||||
|
let fileName = 'artifact'
|
||||||
|
const filenameStar = contentDisposition.match(
|
||||||
|
/filename\*\s*=\s*UTF-8''([^;\r\n]*)/i
|
||||||
|
)
|
||||||
|
const filenamePlain = contentDisposition.match(
|
||||||
|
/(?<!\*)filename\s*=\s*['"]?([^;\r\n"']*)['"]?/i
|
||||||
|
)
|
||||||
|
const rawName = filenameStar?.[1] || filenamePlain?.[1]
|
||||||
|
if (rawName) {
|
||||||
|
// Sanitize fileName to prevent path traversal attacks
|
||||||
|
// Use path.basename to extract only the filename component
|
||||||
|
fileName = path.basename(decodeURIComponent(rawName.trim()))
|
||||||
|
}
|
||||||
|
|
||||||
|
core.debug(
|
||||||
|
`Content-Type: ${contentType}, mimeType: ${mimeType}, urlEndsWithZip: ${urlEndsWithZip}, isZip: ${isZip}, skipDecompress: ${skipDecompress}`
|
||||||
|
)
|
||||||
|
core.debug(
|
||||||
|
`Content-Disposition: ${contentDisposition}, fileName: ${fileName}`
|
||||||
|
)
|
||||||
|
|
||||||
let sha256Digest: string | undefined = undefined
|
let sha256Digest: string | undefined = undefined
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timerFn = (): void => {
|
const timerFn = (): void => {
|
||||||
const timeoutError = new Error(
|
const timeoutError = new Error(
|
||||||
`Blob storage chunk did not respond in ${opts.timeout}ms`
|
`Blob storage chunk did not respond in ${timeout}ms`
|
||||||
)
|
)
|
||||||
response.message.destroy(timeoutError)
|
response.message.destroy(timeoutError)
|
||||||
reject(timeoutError)
|
reject(timeoutError)
|
||||||
}
|
}
|
||||||
const timer = setTimeout(timerFn, opts.timeout)
|
const timer = setTimeout(timerFn, timeout)
|
||||||
|
|
||||||
|
const onError = (error: Error): void => {
|
||||||
|
core.debug(`response.message: Artifact download failed: ${error.message}`)
|
||||||
|
clearTimeout(timer)
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
|
||||||
const hashStream = crypto.createHash('sha256').setEncoding('hex')
|
const hashStream = crypto.createHash('sha256').setEncoding('hex')
|
||||||
const passThrough = new stream.PassThrough()
|
const passThrough = new stream.PassThrough()
|
||||||
|
|
||||||
response.message.pipe(passThrough)
|
|
||||||
passThrough.pipe(hashStream)
|
|
||||||
const extractStream = passThrough
|
|
||||||
|
|
||||||
extractStream
|
|
||||||
.on('data', () => {
|
.on('data', () => {
|
||||||
timer.refresh()
|
timer.refresh()
|
||||||
})
|
})
|
||||||
.on('error', (error: Error) => {
|
.on('error', onError)
|
||||||
core.debug(
|
|
||||||
`response.message: Artifact download failed: ${error.message}`
|
response.message.pipe(passThrough)
|
||||||
)
|
passThrough.pipe(hashStream)
|
||||||
clearTimeout(timer)
|
|
||||||
reject(error)
|
const onClose = (): void => {
|
||||||
})
|
clearTimeout(timer)
|
||||||
.pipe(unzip.Extract({path: directory}))
|
if (hashStream) {
|
||||||
.on('close', () => {
|
hashStream.end()
|
||||||
clearTimeout(timer)
|
sha256Digest = hashStream.read() as string
|
||||||
if (hashStream) {
|
core.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`)
|
||||||
hashStream.end()
|
}
|
||||||
sha256Digest = hashStream.read() as string
|
resolve({sha256Digest: `sha256:${sha256Digest}`})
|
||||||
core.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`)
|
}
|
||||||
}
|
|
||||||
resolve({sha256Digest: `sha256:${sha256Digest}`})
|
if (isZip && !skipDecompress) {
|
||||||
})
|
// Extract zip file
|
||||||
.on('error', (error: Error) => {
|
passThrough
|
||||||
reject(error)
|
.pipe(unzip.Extract({path: directory}))
|
||||||
})
|
.on('close', onClose)
|
||||||
|
.on('error', onError)
|
||||||
|
} else {
|
||||||
|
// Save raw file without extracting
|
||||||
|
const filePath = path.join(directory, fileName)
|
||||||
|
const writeStream = fsSync.createWriteStream(filePath)
|
||||||
|
|
||||||
|
core.info(`Downloading raw file (non-zip) to: ${filePath}`)
|
||||||
|
passThrough.pipe(writeStream).on('close', onClose).on('error', onError)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +215,11 @@ export async function downloadArtifactPublic(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
core.info(`Starting download of artifact to: ${downloadPath}`)
|
core.info(`Starting download of artifact to: ${downloadPath}`)
|
||||||
const extractResponse = await streamExtract(location, downloadPath)
|
const extractResponse = await streamExtract(
|
||||||
|
location,
|
||||||
|
downloadPath,
|
||||||
|
options?.skipDecompress
|
||||||
|
)
|
||||||
core.info(`Artifact download completed successfully.`)
|
core.info(`Artifact download completed successfully.`)
|
||||||
if (options?.expectedHash) {
|
if (options?.expectedHash) {
|
||||||
if (options?.expectedHash !== extractResponse.sha256Digest) {
|
if (options?.expectedHash !== extractResponse.sha256Digest) {
|
||||||
@@ -224,7 +280,11 @@ export async function downloadArtifactInternal(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
core.info(`Starting download of artifact to: ${downloadPath}`)
|
core.info(`Starting download of artifact to: ${downloadPath}`)
|
||||||
const extractResponse = await streamExtract(signedUrl, downloadPath)
|
const extractResponse = await streamExtract(
|
||||||
|
signedUrl,
|
||||||
|
downloadPath,
|
||||||
|
options?.skipDecompress
|
||||||
|
)
|
||||||
core.info(`Artifact download completed successfully.`)
|
core.info(`Artifact download completed successfully.`)
|
||||||
if (options?.expectedHash) {
|
if (options?.expectedHash) {
|
||||||
if (options?.expectedHash !== extractResponse.sha256Digest) {
|
if (options?.expectedHash !== extractResponse.sha256Digest) {
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
import {getOctokit} from '@actions/github'
|
import {getOctokit} from '@actions/github'
|
||||||
import {retry} from '@octokit/plugin-retry'
|
import {retry} from '@octokit/plugin-retry'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
import type {OctokitOptions} from '@octokit/core/types'
|
||||||
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
|
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
|
||||||
import {getRetryOptions} from './retry-options'
|
import {getRetryOptions} from './retry-options.js'
|
||||||
import {requestLog} from '@octokit/plugin-request-log'
|
import {requestLog} from '@octokit/plugin-request-log'
|
||||||
import {GetArtifactResponse} from '../shared/interfaces'
|
import {GetArtifactResponse} from '../shared/interfaces.js'
|
||||||
import {getBackendIdsFromToken} from '../shared/util'
|
import {getBackendIdsFromToken} from '../shared/util.js'
|
||||||
import {getUserAgentString} from '../shared/user-agent'
|
import {getUserAgentString} from '../shared/user-agent.js'
|
||||||
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
|
||||||
import {ListArtifactsRequest, StringValue, Timestamp} from '../../generated'
|
import {
|
||||||
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors'
|
ListArtifactsRequest,
|
||||||
|
StringValue,
|
||||||
|
Timestamp
|
||||||
|
} from '../../generated/index.js'
|
||||||
|
import {ArtifactNotFoundError, InvalidResponseError} from '../shared/errors.js'
|
||||||
|
|
||||||
export async function getArtifactPublic(
|
export async function getArtifactPublic(
|
||||||
artifactName: string,
|
artifactName: string,
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import {info, warning, debug} from '@actions/core'
|
import {info, warning, debug} from '@actions/core'
|
||||||
import {getOctokit} from '@actions/github'
|
import {getOctokit} from '@actions/github'
|
||||||
import {ListArtifactsResponse, Artifact} from '../shared/interfaces'
|
import {ListArtifactsResponse, Artifact} from '../shared/interfaces.js'
|
||||||
import {getUserAgentString} from '../shared/user-agent'
|
import {getUserAgentString} from '../shared/user-agent.js'
|
||||||
import {getRetryOptions} from './retry-options'
|
import {getRetryOptions} from './retry-options.js'
|
||||||
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
|
import {defaults as defaultGitHubOptions} from '@actions/github/lib/utils'
|
||||||
import {requestLog} from '@octokit/plugin-request-log'
|
import {requestLog} from '@octokit/plugin-request-log'
|
||||||
import {retry} from '@octokit/plugin-retry'
|
import {retry} from '@octokit/plugin-retry'
|
||||||
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
import type {OctokitOptions} from '@octokit/core/types'
|
||||||
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
|
||||||
import {getBackendIdsFromToken} from '../shared/util'
|
import {getBackendIdsFromToken} from '../shared/util.js'
|
||||||
import {getMaxArtifactListCount} from '../shared/config'
|
import {getMaxArtifactListCount} from '../shared/config.js'
|
||||||
import {ListArtifactsRequest, Timestamp} from '../../generated'
|
import {ListArtifactsRequest, Timestamp} from '../../generated/index.js'
|
||||||
|
|
||||||
const maximumArtifactCount = getMaxArtifactListCount()
|
const maximumArtifactCount = getMaxArtifactListCount()
|
||||||
const paginationCount = 100
|
const paginationCount = 100
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {OctokitOptions} from '@octokit/core/dist-types/types'
|
import type {OctokitOptions} from '@octokit/core/types'
|
||||||
import {RequestRequestOptions} from '@octokit/types'
|
import {RequestRequestOptions} from '@octokit/types'
|
||||||
|
|
||||||
export type RetryOptions = {
|
export type RetryOptions = {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
|
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
|
||||||
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
||||||
import {info, debug} from '@actions/core'
|
import {info, debug} from '@actions/core'
|
||||||
import {ArtifactServiceClientJSON} from '../../generated'
|
import {ArtifactServiceClientJSON} from '../../generated/index.js'
|
||||||
import {getResultsServiceUrl, getRuntimeToken} from './config'
|
import {getResultsServiceUrl, getRuntimeToken} from './config.js'
|
||||||
import {getUserAgentString} from './user-agent'
|
import {getUserAgentString} from './user-agent.js'
|
||||||
import {NetworkError, UsageError} from './errors'
|
import {NetworkError, UsageError} from './errors.js'
|
||||||
import {maskSecretUrls} from './util'
|
import {maskSecretUrls} from './util.js'
|
||||||
|
|
||||||
// The twirp http client must implement this interface
|
// The twirp http client must implement this interface
|
||||||
interface Rpc {
|
interface Rpc {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export class NetworkError extends Error {
|
|||||||
|
|
||||||
export class UsageError extends Error {
|
export class UsageError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
const message = `Artifact storage quota has been hit. Unable to upload any new artifacts. Usage is recalculated every 6-12 hours.\nMore info on storage limits: https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#calculating-minute-and-storage-spending`
|
const message = `Artifact storage quota has been hit. Unable to upload any new artifacts.\nMore info on storage limits: https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#calculating-minute-and-storage-spending`
|
||||||
super(message)
|
super(message)
|
||||||
this.name = 'UsageError'
|
this.name = 'UsageError'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ export interface UploadArtifactOptions {
|
|||||||
* For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads.
|
* For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads.
|
||||||
*/
|
*/
|
||||||
compressionLevel?: number
|
compressionLevel?: number
|
||||||
|
/**
|
||||||
|
* If true, the artifact will be uploaded without being archived (zipped).
|
||||||
|
* This is only supported when uploading a single file.
|
||||||
|
* When using this option, the artifact will not be compressed.
|
||||||
|
* When using this option, the name parameter passed to the upload is ignored. Instead, the name of the file is used as the name of the artifact.
|
||||||
|
*/
|
||||||
|
skipArchive?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +120,12 @@ export interface DownloadArtifactOptions {
|
|||||||
* matches the expected hash.
|
* matches the expected hash.
|
||||||
*/
|
*/
|
||||||
expectedHash?: string
|
expectedHash?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, the downloaded artifact will not be automatically extracted/decompressed.
|
||||||
|
* The artifact will be saved as-is to the destination path.
|
||||||
|
*/
|
||||||
|
skipDecompress?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StreamExtractResponse {
|
export interface StreamExtractResponse {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// This file exists as a CommonJS module to read the version from package.json.
|
||||||
|
// In an ESM package, using `require()` directly in .ts files requires disabling
|
||||||
|
// ESLint rules and doesn't work reliably across all Node.js versions.
|
||||||
|
// By keeping this as a .cjs file, we can use require() naturally and export
|
||||||
|
// the version for the ESM modules to import.
|
||||||
|
const packageJson = require('../../../package.json')
|
||||||
|
module.exports = { version: packageJson.version }
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
import {version} from './package-version.cjs'
|
||||||
const packageJson = require('../../../package.json')
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that this User Agent String is used in all HTTP calls so that we can monitor telemetry between different versions of this package
|
* Ensure that this User Agent String is used in all HTTP calls so that we can monitor telemetry between different versions of this package
|
||||||
*/
|
*/
|
||||||
export function getUserAgentString(): string {
|
export function getUserAgentString(): string {
|
||||||
return `@actions/artifact-${packageJson.version}`
|
return `@actions/artifact-${version}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {getRuntimeToken} from './config'
|
import {getRuntimeToken} from './config.js'
|
||||||
import jwt_decode from 'jwt-decode'
|
import {jwtDecode} from 'jwt-decode'
|
||||||
import {debug, setSecret} from '@actions/core'
|
import {debug, setSecret} from '@actions/core'
|
||||||
|
|
||||||
export interface BackendIds {
|
export interface BackendIds {
|
||||||
@@ -20,7 +20,7 @@ const InvalidJwtError = new Error(
|
|||||||
// workflow run and workflow job run backend ids
|
// workflow run and workflow job run backend ids
|
||||||
export function getBackendIdsFromToken(): BackendIds {
|
export function getBackendIdsFromToken(): BackendIds {
|
||||||
const token = getRuntimeToken()
|
const token = getRuntimeToken()
|
||||||
const decoded = jwt_decode<ActionsToken>(token)
|
const decoded = jwtDecode<ActionsToken>(token)
|
||||||
if (!decoded.scp) {
|
if (!decoded.scp) {
|
||||||
throw InvalidJwtError
|
throw InvalidJwtError
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import {BlobClient, BlockBlobUploadStreamOptions} from '@azure/storage-blob'
|
import {BlobClient, BlockBlobUploadStreamOptions} from '@azure/storage-blob'
|
||||||
import {TransferProgressEvent} from '@azure/core-http-compat'
|
import {TransferProgressEvent} from '@azure/core-http-compat'
|
||||||
import {ZipUploadStream} from './zip'
|
import {WaterMarkedUploadStream} from './stream.js'
|
||||||
import {
|
import {
|
||||||
getUploadChunkSize,
|
getUploadChunkSize,
|
||||||
getConcurrency,
|
getConcurrency,
|
||||||
getUploadChunkTimeout
|
getUploadChunkTimeout
|
||||||
} from '../shared/config'
|
} from '../shared/config.js'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as stream from 'stream'
|
import * as stream from 'stream'
|
||||||
import {NetworkError} from '../shared/errors'
|
import {NetworkError} from '../shared/errors.js'
|
||||||
|
|
||||||
export interface BlobUploadResponse {
|
export interface BlobUploadResponse {
|
||||||
/**
|
/**
|
||||||
@@ -23,9 +23,10 @@ export interface BlobUploadResponse {
|
|||||||
sha256Hash?: string
|
sha256Hash?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadZipToBlobStorage(
|
export async function uploadToBlobStorage(
|
||||||
authenticatedUploadURL: string,
|
authenticatedUploadURL: string,
|
||||||
zipUploadStream: ZipUploadStream
|
uploadStream: WaterMarkedUploadStream,
|
||||||
|
contentType: string
|
||||||
): Promise<BlobUploadResponse> {
|
): Promise<BlobUploadResponse> {
|
||||||
let uploadByteCount = 0
|
let uploadByteCount = 0
|
||||||
let lastProgressTime = Date.now()
|
let lastProgressTime = Date.now()
|
||||||
@@ -51,7 +52,7 @@ export async function uploadZipToBlobStorage(
|
|||||||
const blockBlobClient = blobClient.getBlockBlobClient()
|
const blockBlobClient = blobClient.getBlockBlobClient()
|
||||||
|
|
||||||
core.debug(
|
core.debug(
|
||||||
`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`
|
`Uploading artifact to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}, contentType: ${contentType}`
|
||||||
)
|
)
|
||||||
|
|
||||||
const uploadCallback = (progress: TransferProgressEvent): void => {
|
const uploadCallback = (progress: TransferProgressEvent): void => {
|
||||||
@@ -61,24 +62,24 @@ export async function uploadZipToBlobStorage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const options: BlockBlobUploadStreamOptions = {
|
const options: BlockBlobUploadStreamOptions = {
|
||||||
blobHTTPHeaders: {blobContentType: 'zip'},
|
blobHTTPHeaders: {blobContentType: contentType},
|
||||||
onProgress: uploadCallback,
|
onProgress: uploadCallback,
|
||||||
abortSignal: abortController.signal
|
abortSignal: abortController.signal
|
||||||
}
|
}
|
||||||
|
|
||||||
let sha256Hash: string | undefined = undefined
|
let sha256Hash: string | undefined = undefined
|
||||||
const uploadStream = new stream.PassThrough()
|
const blobUploadStream = new stream.PassThrough()
|
||||||
const hashStream = crypto.createHash('sha256')
|
const hashStream = crypto.createHash('sha256')
|
||||||
|
|
||||||
zipUploadStream.pipe(uploadStream) // This stream is used for the upload
|
uploadStream.pipe(blobUploadStream) // This stream is used for the upload
|
||||||
zipUploadStream.pipe(hashStream).setEncoding('hex') // This stream is used to compute a hash of the zip content that gets used. Integrity check
|
uploadStream.pipe(hashStream).setEncoding('hex') // This stream is used to compute a hash of the content for integrity check
|
||||||
|
|
||||||
core.info('Beginning upload of artifact content to blob storage')
|
core.info('Beginning upload of artifact content to blob storage')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.race([
|
await Promise.race([
|
||||||
blockBlobClient.uploadStream(
|
blockBlobClient.uploadStream(
|
||||||
uploadStream,
|
blobUploadStream,
|
||||||
bufferSize,
|
bufferSize,
|
||||||
maxConcurrency,
|
maxConcurrency,
|
||||||
options
|
options
|
||||||
@@ -98,7 +99,7 @@ export async function uploadZipToBlobStorage(
|
|||||||
|
|
||||||
hashStream.end()
|
hashStream.end()
|
||||||
sha256Hash = hashStream.read() as string
|
sha256Hash = hashStream.read() as string
|
||||||
core.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`)
|
core.info(`SHA256 digest of uploaded artifact is ${sha256Hash}`)
|
||||||
|
|
||||||
if (uploadByteCount === 0) {
|
if (uploadByteCount === 0) {
|
||||||
core.warning(
|
core.warning(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Timestamp} from '../../generated'
|
import {Timestamp} from '../../generated/index.js'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
|
|
||||||
export function getExpiration(retentionDays?: number): Timestamp | undefined {
|
export function getExpiration(retentionDays?: number): Timestamp | undefined {
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import * as stream from 'stream'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
import {realpath} from 'fs/promises'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import {getUploadChunkSize} from '../shared/config.js'
|
||||||
|
|
||||||
|
// Custom stream transformer so we can set the highWaterMark property
|
||||||
|
// See https://github.com/nodejs/node/issues/8855
|
||||||
|
export class WaterMarkedUploadStream extends stream.Transform {
|
||||||
|
constructor(bufferSize: number) {
|
||||||
|
super({
|
||||||
|
highWaterMark: bufferSize
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
_transform(chunk: any, enc: any, cb: any): void {
|
||||||
|
cb(null, chunk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createRawFileUploadStream(
|
||||||
|
filePath: string
|
||||||
|
): Promise<WaterMarkedUploadStream> {
|
||||||
|
core.debug(`Creating raw file upload stream for: ${filePath}`)
|
||||||
|
|
||||||
|
const bufferSize = getUploadChunkSize()
|
||||||
|
const uploadStream = new WaterMarkedUploadStream(bufferSize)
|
||||||
|
|
||||||
|
// Check if symlink and resolve the source path
|
||||||
|
let sourcePath = filePath
|
||||||
|
const stats = await fs.promises.lstat(filePath)
|
||||||
|
if (stats.isSymbolicLink()) {
|
||||||
|
sourcePath = await realpath(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a read stream from the file and pipe it to the upload stream
|
||||||
|
const fileStream = fs.createReadStream(sourcePath, {
|
||||||
|
highWaterMark: bufferSize
|
||||||
|
})
|
||||||
|
|
||||||
|
fileStream.on('error', error => {
|
||||||
|
core.error('An error has occurred while reading the file for upload')
|
||||||
|
core.error(String(error))
|
||||||
|
uploadStream.destroy(
|
||||||
|
new Error('An error has occurred during file read for the artifact')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
fileStream.pipe(uploadStream)
|
||||||
|
|
||||||
|
return uploadStream
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import * as path from 'path'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps file extensions to MIME types
|
||||||
|
*/
|
||||||
|
const mimeTypes: Record<string, string> = {
|
||||||
|
// Text
|
||||||
|
'.txt': 'text/plain',
|
||||||
|
'.html': 'text/html',
|
||||||
|
'.htm': 'text/html',
|
||||||
|
'.css': 'text/css',
|
||||||
|
'.csv': 'text/csv',
|
||||||
|
'.xml': 'text/xml',
|
||||||
|
'.md': 'text/markdown',
|
||||||
|
|
||||||
|
// JavaScript/JSON
|
||||||
|
'.js': 'application/javascript',
|
||||||
|
'.mjs': 'application/javascript',
|
||||||
|
'.json': 'application/json',
|
||||||
|
|
||||||
|
// Images
|
||||||
|
'.png': 'image/png',
|
||||||
|
'.jpg': 'image/jpeg',
|
||||||
|
'.jpeg': 'image/jpeg',
|
||||||
|
'.gif': 'image/gif',
|
||||||
|
'.svg': 'image/svg+xml',
|
||||||
|
'.webp': 'image/webp',
|
||||||
|
'.ico': 'image/x-icon',
|
||||||
|
'.bmp': 'image/bmp',
|
||||||
|
'.tiff': 'image/tiff',
|
||||||
|
'.tif': 'image/tiff',
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
'.mp3': 'audio/mpeg',
|
||||||
|
'.wav': 'audio/wav',
|
||||||
|
'.ogg': 'audio/ogg',
|
||||||
|
'.flac': 'audio/flac',
|
||||||
|
|
||||||
|
// Video
|
||||||
|
'.mp4': 'video/mp4',
|
||||||
|
'.webm': 'video/webm',
|
||||||
|
'.avi': 'video/x-msvideo',
|
||||||
|
'.mov': 'video/quicktime',
|
||||||
|
|
||||||
|
// Documents
|
||||||
|
'.pdf': 'application/pdf',
|
||||||
|
'.doc': 'application/msword',
|
||||||
|
'.docx':
|
||||||
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
'.xls': 'application/vnd.ms-excel',
|
||||||
|
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
'.ppt': 'application/vnd.ms-powerpoint',
|
||||||
|
'.pptx':
|
||||||
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||||
|
|
||||||
|
// Archives
|
||||||
|
'.zip': 'application/zip',
|
||||||
|
'.tar': 'application/x-tar',
|
||||||
|
'.gz': 'application/gzip',
|
||||||
|
'.rar': 'application/vnd.rar',
|
||||||
|
'.7z': 'application/x-7z-compressed',
|
||||||
|
|
||||||
|
// Code/Data
|
||||||
|
'.wasm': 'application/wasm',
|
||||||
|
'.yaml': 'application/x-yaml',
|
||||||
|
'.yml': 'application/x-yaml',
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
'.woff': 'font/woff',
|
||||||
|
'.woff2': 'font/woff2',
|
||||||
|
'.ttf': 'font/ttf',
|
||||||
|
'.otf': 'font/otf',
|
||||||
|
'.eot': 'application/vnd.ms-fontobject'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MIME type for a file based on its extension
|
||||||
|
*/
|
||||||
|
export function getMimeType(filePath: string): string {
|
||||||
|
const ext = path.extname(filePath).toLowerCase()
|
||||||
|
return mimeTypes[ext] || 'application/octet-stream'
|
||||||
|
}
|
||||||
@@ -1,25 +1,29 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
import * as path from 'path'
|
||||||
import {
|
import {
|
||||||
UploadArtifactOptions,
|
UploadArtifactOptions,
|
||||||
UploadArtifactResponse
|
UploadArtifactResponse
|
||||||
} from '../shared/interfaces'
|
} from '../shared/interfaces.js'
|
||||||
import {getExpiration} from './retention'
|
import {getExpiration} from './retention.js'
|
||||||
import {validateArtifactName} from './path-and-artifact-name-validation'
|
import {validateArtifactName} from './path-and-artifact-name-validation.js'
|
||||||
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client.js'
|
||||||
import {
|
import {
|
||||||
UploadZipSpecification,
|
UploadZipSpecification,
|
||||||
getUploadZipSpecification,
|
getUploadZipSpecification,
|
||||||
validateRootDirectory
|
validateRootDirectory
|
||||||
} from './upload-zip-specification'
|
} from './upload-zip-specification.js'
|
||||||
import {getBackendIdsFromToken} from '../shared/util'
|
import {getBackendIdsFromToken} from '../shared/util.js'
|
||||||
import {uploadZipToBlobStorage} from './blob-upload'
|
import {uploadToBlobStorage} from './blob-upload.js'
|
||||||
import {createZipUploadStream} from './zip'
|
import {createZipUploadStream} from './zip.js'
|
||||||
|
import {createRawFileUploadStream, WaterMarkedUploadStream} from './stream.js'
|
||||||
import {
|
import {
|
||||||
CreateArtifactRequest,
|
CreateArtifactRequest,
|
||||||
FinalizeArtifactRequest,
|
FinalizeArtifactRequest,
|
||||||
StringValue
|
StringValue
|
||||||
} from '../../generated'
|
} from '../../generated/index.js'
|
||||||
import {FilesNotFoundError, InvalidResponseError} from '../shared/errors'
|
import {FilesNotFoundError, InvalidResponseError} from '../shared/errors.js'
|
||||||
|
import {getMimeType} from './types.js'
|
||||||
|
|
||||||
export async function uploadArtifact(
|
export async function uploadArtifact(
|
||||||
name: string,
|
name: string,
|
||||||
@@ -27,19 +31,43 @@ export async function uploadArtifact(
|
|||||||
rootDirectory: string,
|
rootDirectory: string,
|
||||||
options?: UploadArtifactOptions | undefined
|
options?: UploadArtifactOptions | undefined
|
||||||
): Promise<UploadArtifactResponse> {
|
): Promise<UploadArtifactResponse> {
|
||||||
|
let artifactFileName = `${name}.zip`
|
||||||
|
if (options?.skipArchive) {
|
||||||
|
if (files.length === 0) {
|
||||||
|
throw new FilesNotFoundError([])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.length > 1) {
|
||||||
|
throw new Error(
|
||||||
|
'skipArchive option is only supported when uploading a single file'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(files[0])) {
|
||||||
|
throw new FilesNotFoundError(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactFileName = path.basename(files[0])
|
||||||
|
name = artifactFileName
|
||||||
|
}
|
||||||
|
|
||||||
validateArtifactName(name)
|
validateArtifactName(name)
|
||||||
validateRootDirectory(rootDirectory)
|
validateRootDirectory(rootDirectory)
|
||||||
|
|
||||||
const zipSpecification: UploadZipSpecification[] = getUploadZipSpecification(
|
let zipSpecification: UploadZipSpecification[] = []
|
||||||
files,
|
|
||||||
rootDirectory
|
if (!options?.skipArchive) {
|
||||||
)
|
zipSpecification = getUploadZipSpecification(files, rootDirectory)
|
||||||
if (zipSpecification.length === 0) {
|
|
||||||
throw new FilesNotFoundError(
|
if (zipSpecification.length === 0) {
|
||||||
zipSpecification.flatMap(s => (s.sourcePath ? [s.sourcePath] : []))
|
throw new FilesNotFoundError(
|
||||||
)
|
zipSpecification.flatMap(s => (s.sourcePath ? [s.sourcePath] : []))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contentType = getMimeType(artifactFileName)
|
||||||
|
|
||||||
// get the IDs needed for the artifact creation
|
// get the IDs needed for the artifact creation
|
||||||
const backendIds = getBackendIdsFromToken()
|
const backendIds = getBackendIdsFromToken()
|
||||||
|
|
||||||
@@ -51,7 +79,8 @@ export async function uploadArtifact(
|
|||||||
workflowRunBackendId: backendIds.workflowRunBackendId,
|
workflowRunBackendId: backendIds.workflowRunBackendId,
|
||||||
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
|
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
|
||||||
name,
|
name,
|
||||||
version: 4
|
mimeType: StringValue.create({value: contentType}),
|
||||||
|
version: 7
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is a retention period, add it to the request
|
// if there is a retention period, add it to the request
|
||||||
@@ -68,15 +97,24 @@ export async function uploadArtifact(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const zipUploadStream = await createZipUploadStream(
|
let stream: WaterMarkedUploadStream
|
||||||
zipSpecification,
|
|
||||||
options?.compressionLevel
|
|
||||||
)
|
|
||||||
|
|
||||||
// Upload zip to blob storage
|
if (options?.skipArchive) {
|
||||||
const uploadResult = await uploadZipToBlobStorage(
|
// Upload raw file without archiving
|
||||||
|
stream = await createRawFileUploadStream(files[0])
|
||||||
|
} else {
|
||||||
|
// Create and upload zip archive
|
||||||
|
stream = await createZipUploadStream(
|
||||||
|
zipSpecification,
|
||||||
|
options?.compressionLevel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`Uploading artifact: ${artifactFileName}`)
|
||||||
|
const uploadResult = await uploadToBlobStorage(
|
||||||
createArtifactResp.signedUploadUrl,
|
createArtifactResp.signedUploadUrl,
|
||||||
zipUploadStream
|
stream,
|
||||||
|
contentType
|
||||||
)
|
)
|
||||||
|
|
||||||
// finalize the artifact
|
// finalize the artifact
|
||||||
@@ -105,7 +143,7 @@ export async function uploadArtifact(
|
|||||||
|
|
||||||
const artifactId = BigInt(finalizeArtifactResp.artifactId)
|
const artifactId = BigInt(finalizeArtifactResp.artifactId)
|
||||||
core.info(
|
core.info(
|
||||||
`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`
|
`Artifact ${name} successfully finalized. Artifact ID ${artifactId}`
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import {info} from '@actions/core'
|
import {info} from '@actions/core'
|
||||||
import {normalize, resolve} from 'path'
|
import {normalize, resolve} from 'path'
|
||||||
import {validateFilePath} from './path-and-artifact-name-validation'
|
import {validateFilePath} from './path-and-artifact-name-validation.js'
|
||||||
|
|
||||||
export interface UploadZipSpecification {
|
export interface UploadZipSpecification {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,31 +1,16 @@
|
|||||||
import * as stream from 'stream'
|
|
||||||
import {realpath} from 'fs/promises'
|
import {realpath} from 'fs/promises'
|
||||||
import * as archiver from 'archiver'
|
import archiver from 'archiver'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {UploadZipSpecification} from './upload-zip-specification'
|
import {UploadZipSpecification} from './upload-zip-specification.js'
|
||||||
import {getUploadChunkSize} from '../shared/config'
|
import {getUploadChunkSize} from '../shared/config.js'
|
||||||
|
import {WaterMarkedUploadStream} from './stream.js'
|
||||||
|
|
||||||
export const DEFAULT_COMPRESSION_LEVEL = 6
|
export const DEFAULT_COMPRESSION_LEVEL = 6
|
||||||
|
|
||||||
// Custom stream transformer so we can set the highWaterMark property
|
|
||||||
// See https://github.com/nodejs/node/issues/8855
|
|
||||||
export class ZipUploadStream extends stream.Transform {
|
|
||||||
constructor(bufferSize: number) {
|
|
||||||
super({
|
|
||||||
highWaterMark: bufferSize
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
_transform(chunk: any, enc: any, cb: any): void {
|
|
||||||
cb(null, chunk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createZipUploadStream(
|
export async function createZipUploadStream(
|
||||||
uploadSpecification: UploadZipSpecification[],
|
uploadSpecification: UploadZipSpecification[],
|
||||||
compressionLevel: number = DEFAULT_COMPRESSION_LEVEL
|
compressionLevel: number = DEFAULT_COMPRESSION_LEVEL
|
||||||
): Promise<ZipUploadStream> {
|
): Promise<WaterMarkedUploadStream> {
|
||||||
core.debug(
|
core.debug(
|
||||||
`Creating Artifact archive with compressionLevel: ${compressionLevel}`
|
`Creating Artifact archive with compressionLevel: ${compressionLevel}`
|
||||||
)
|
)
|
||||||
@@ -60,7 +45,7 @@ export async function createZipUploadStream(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bufferSize = getUploadChunkSize()
|
const bufferSize = getUploadChunkSize()
|
||||||
const zipUploadStream = new ZipUploadStream(bufferSize)
|
const zipUploadStream = new WaterMarkedUploadStream(bufferSize)
|
||||||
|
|
||||||
core.debug(
|
core.debug(
|
||||||
`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`
|
`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
|
"module": "node16",
|
||||||
|
"moduleResolution": "node16",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@actions/core": [
|
"@actions/core": [
|
||||||
"../core"
|
"../core"
|
||||||
|
|||||||
+39
-12
@@ -1,17 +1,43 @@
|
|||||||
# @actions/attest Releases
|
# @actions/attest Releases
|
||||||
|
|
||||||
### 2.0.0
|
## 3.2.0
|
||||||
|
|
||||||
|
- Add custom user-agent for more API calls [#2321](https://github.com/actions/toolkit/pull/2321)
|
||||||
|
|
||||||
|
## 3.1.0
|
||||||
|
|
||||||
|
- Add support for `ACTIONS_ORCHESTRATION_ID` in user-agent [#2320](https://github.com/actions/toolkit/pull/2320)
|
||||||
|
|
||||||
|
## 3.0.0
|
||||||
|
|
||||||
|
- **Breaking change**: Package is now ESM-only
|
||||||
|
- CommonJS consumers must use dynamic `import()` instead of `require()`
|
||||||
|
- Bump `@actions/core` to `^3.0.0`
|
||||||
|
- Bump `@actions/http-client` to `^4.0.0`
|
||||||
|
|
||||||
|
## 2.2.1
|
||||||
|
|
||||||
|
- Bump `@actions/http-client` to `3.0.2`
|
||||||
|
- Bump `undici` to `6.23.0`
|
||||||
|
|
||||||
|
## 2.2.0
|
||||||
|
|
||||||
|
- Bump @actions/core from 1.11.1 to 2.0.2
|
||||||
|
- Bump @actions/github from 6.0.0 to 7.0.0
|
||||||
|
- Bump @actions/http-client from 2.2.3 to 3.0.1
|
||||||
|
|
||||||
|
## 2.0.0
|
||||||
|
|
||||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
- 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/bundle from 3.0.0 to 3.1.0
|
||||||
- Bump @sigstore/sign 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
|
- Bump jose from 5.2.3 to 5.10.0
|
||||||
|
|
||||||
### 1.6.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)
|
- 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
|
## 1.5.0
|
||||||
|
|
||||||
- Bump @actions/core from 1.10.1 to 1.11.1 [#1847](https://github.com/actions/toolkit/pull/1847)
|
- Bump @actions/core from 1.10.1 to 1.11.1 [#1847](https://github.com/actions/toolkit/pull/1847)
|
||||||
- Bump @sigstore/bundle from 2.3.2 to 3.0.0 [#1846](https://github.com/actions/toolkit/pull/1846)
|
- Bump @sigstore/bundle from 2.3.2 to 3.0.0 [#1846](https://github.com/actions/toolkit/pull/1846)
|
||||||
@@ -19,23 +45,24 @@
|
|||||||
- Support for generating multi-subject attestations [#1864](https://github.com/actions/toolkit/pull/1865)
|
- Support for generating multi-subject attestations [#1864](https://github.com/actions/toolkit/pull/1865)
|
||||||
- Fix bug in `buildSLSAProvenancePredicate` related to `workflow_ref` OIDC token claims containing the "@" symbol in the tag name [#1863](https://github.com/actions/toolkit/pull/1863)
|
- Fix bug in `buildSLSAProvenancePredicate` related to `workflow_ref` OIDC token claims containing the "@" symbol in the tag name [#1863](https://github.com/actions/toolkit/pull/1863)
|
||||||
|
|
||||||
### 1.4.2
|
## 1.4.2
|
||||||
|
|
||||||
- Fix bug in `buildSLSAProvenancePredicate`/`attestProvenance` when generating provenance statement for enterprise account using customized OIDC issuer value [#1823](https://github.com/actions/toolkit/pull/1823)
|
- Fix bug in `buildSLSAProvenancePredicate`/`attestProvenance` when generating provenance statement for enterprise account using customized OIDC issuer value [#1823](https://github.com/actions/toolkit/pull/1823)
|
||||||
|
|
||||||
### 1.4.1
|
## 1.4.1
|
||||||
|
|
||||||
- Bump @actions/http-client from 2.2.1 to 2.2.3 [#1805](https://github.com/actions/toolkit/pull/1805)
|
- Bump @actions/http-client from 2.2.1 to 2.2.3 [#1805](https://github.com/actions/toolkit/pull/1805)
|
||||||
|
|
||||||
### 1.4.0
|
## 1.4.0
|
||||||
|
|
||||||
- Add new `headers` parameter to the `attest` and `attestProvenance` functions [#1790](https://github.com/actions/toolkit/pull/1790)
|
- Add new `headers` parameter to the `attest` and `attestProvenance` functions [#1790](https://github.com/actions/toolkit/pull/1790)
|
||||||
- Update `buildSLSAProvenancePredicate`/`attestProvenance` to automatically derive default OIDC issuer URL from current execution context [#1796](https://github.com/actions/toolkit/pull/1796)
|
- Update `buildSLSAProvenancePredicate`/`attestProvenance` to automatically derive default OIDC issuer URL from current execution context [#1796](https://github.com/actions/toolkit/pull/1796)
|
||||||
### 1.3.1
|
|
||||||
|
## 1.3.1
|
||||||
|
|
||||||
- Fix bug with proxy support when retrieving JWKS for OIDC issuer [#1776](https://github.com/actions/toolkit/pull/1776)
|
- Fix bug with proxy support when retrieving JWKS for OIDC issuer [#1776](https://github.com/actions/toolkit/pull/1776)
|
||||||
|
|
||||||
### 1.3.0
|
## 1.3.0
|
||||||
|
|
||||||
- Dynamic construction of Sigstore API URLs [#1735](https://github.com/actions/toolkit/pull/1735)
|
- Dynamic construction of Sigstore API URLs [#1735](https://github.com/actions/toolkit/pull/1735)
|
||||||
- Switch to new GH provenance build type [#1745](https://github.com/actions/toolkit/pull/1745)
|
- Switch to new GH provenance build type [#1745](https://github.com/actions/toolkit/pull/1745)
|
||||||
@@ -43,21 +70,21 @@
|
|||||||
- Bump @sigstore/bundle from 2.3.0 to 2.3.2 [#1738](https://github.com/actions/toolkit/pull/1738)
|
- Bump @sigstore/bundle from 2.3.0 to 2.3.2 [#1738](https://github.com/actions/toolkit/pull/1738)
|
||||||
- Bump @sigstore/sign from 2.3.0 to 2.3.2 [#1738](https://github.com/actions/toolkit/pull/1738)
|
- Bump @sigstore/sign from 2.3.0 to 2.3.2 [#1738](https://github.com/actions/toolkit/pull/1738)
|
||||||
|
|
||||||
### 1.2.1
|
## 1.2.1
|
||||||
|
|
||||||
- Retry request on attestation persistence failure [#1725](https://github.com/actions/toolkit/pull/1725)
|
- Retry request on attestation persistence failure [#1725](https://github.com/actions/toolkit/pull/1725)
|
||||||
|
|
||||||
### 1.2.0
|
## 1.2.0
|
||||||
|
|
||||||
- Generate attestations using the v0.3 Sigstore bundle format [#1701](https://github.com/actions/toolkit/pull/1701)
|
- Generate attestations using the v0.3 Sigstore bundle format [#1701](https://github.com/actions/toolkit/pull/1701)
|
||||||
- Bump @sigstore/bundle from 2.2.0 to 2.3.0 [#1701](https://github.com/actions/toolkit/pull/1701)
|
- Bump @sigstore/bundle from 2.2.0 to 2.3.0 [#1701](https://github.com/actions/toolkit/pull/1701)
|
||||||
- Bump @sigstore/sign from 2.2.3 to 2.3.0 [#1701](https://github.com/actions/toolkit/pull/1701)
|
- Bump @sigstore/sign from 2.2.3 to 2.3.0 [#1701](https://github.com/actions/toolkit/pull/1701)
|
||||||
- Remove dependency on make-fetch-happen [#1714](https://github.com/actions/toolkit/pull/1714)
|
- Remove dependency on make-fetch-happen [#1714](https://github.com/actions/toolkit/pull/1714)
|
||||||
|
|
||||||
### 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
- Updates the `attestProvenance` function to retrieve a token from the GitHub OIDC provider and use the token claims to populate the provenance statement [#1693](https://github.com/actions/toolkit/pull/1693)
|
- Updates the `attestProvenance` function to retrieve a token from the GitHub OIDC provider and use the token claims to populate the provenance statement [#1693](https://github.com/actions/toolkit/pull/1693)
|
||||||
|
|
||||||
### 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|||||||
Generated
+145
-196
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/attest",
|
"name": "@actions/attest",
|
||||||
"version": "2.1.0",
|
"version": "3.2.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@actions/attest",
|
"name": "@actions/attest",
|
||||||
"version": "2.1.0",
|
"version": "3.2.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^9.0.0",
|
||||||
"@actions/http-client": "^2.2.3",
|
"@actions/http-client": "^4.0.0",
|
||||||
"@octokit/plugin-retry": "^6.0.1",
|
"@octokit/plugin-retry": "^8.0.3",
|
||||||
"@sigstore/bundle": "^3.1.0",
|
"@sigstore/bundle": "^3.1.0",
|
||||||
"@sigstore/sign": "^3.1.0",
|
"@sigstore/sign": "^3.1.0",
|
||||||
"jose": "^5.10.0"
|
"jose": "^5.10.0"
|
||||||
@@ -22,92 +22,78 @@
|
|||||||
"@sigstore/rekor-types": "^3.0.0",
|
"@sigstore/rekor-types": "^3.0.0",
|
||||||
"@types/jsonwebtoken": "^9.0.6",
|
"@types/jsonwebtoken": "^9.0.6",
|
||||||
"nock": "^13.5.1",
|
"nock": "^13.5.1",
|
||||||
"undici": "^6.20.0"
|
"undici": "^6.23.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
"version": "1.11.1",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
|
||||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/http-client": "^2.0.1"
|
"@actions/http-client": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/exec": {
|
"node_modules/@actions/exec": {
|
||||||
"version": "1.1.1",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
|
||||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/io": "^1.0.1"
|
"@actions/io": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/github": {
|
"node_modules/@actions/github": {
|
||||||
"version": "6.0.1",
|
"version": "9.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/github/-/github-9.0.0.tgz",
|
||||||
"integrity": "sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==",
|
"integrity": "sha512-yJ0RoswsAaKcvkmpCE4XxBRiy/whH2SdTBHWzs0gi4wkqTDhXMChjSdqBz/F4AeiDlP28rQqL33iHb+kjAMX6w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/http-client": "^2.2.0",
|
"@actions/http-client": "^3.0.2",
|
||||||
"@octokit/core": "^5.0.1",
|
"@octokit/core": "^7.0.6",
|
||||||
"@octokit/plugin-paginate-rest": "^9.2.2",
|
"@octokit/plugin-paginate-rest": "^14.0.0",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
|
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request": "^10.0.7",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^7.1.0",
|
||||||
"undici": "^5.28.5"
|
"undici": "^6.23.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/github/node_modules/undici": {
|
"node_modules/@actions/github/node_modules/@actions/http-client": {
|
||||||
"version": "5.29.0",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@fastify/busboy": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@actions/http-client": {
|
|
||||||
"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",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6",
|
"tunnel": "^0.0.6",
|
||||||
"undici": "^5.25.4"
|
"undici": "^6.23.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/http-client/node_modules/undici": {
|
"node_modules/@actions/github/node_modules/@actions/http-client/node_modules/undici": {
|
||||||
"version": "5.29.0",
|
"version": "6.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/http-client": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/busboy": "^2.0.0"
|
"tunnel": "^0.0.6",
|
||||||
},
|
"undici": "^6.23.0"
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/io": {
|
"node_modules/@actions/io": {
|
||||||
"version": "1.1.3",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
|
||||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==",
|
||||||
"license": "MIT"
|
"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/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
@@ -179,178 +165,147 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/auth-token": {
|
"node_modules/@octokit/auth-token": {
|
||||||
"version": "4.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
|
||||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
"integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/core": {
|
"node_modules/@octokit/core": {
|
||||||
"version": "5.2.2",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
|
||||||
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==",
|
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-token": "^4.0.0",
|
"@octokit/auth-token": "^6.0.0",
|
||||||
"@octokit/graphql": "^7.1.0",
|
"@octokit/graphql": "^9.0.3",
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request": "^10.0.6",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^7.0.2",
|
||||||
"@octokit/types": "^13.0.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"before-after-hook": "^2.2.0",
|
"before-after-hook": "^4.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^7.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/endpoint": {
|
"node_modules/@octokit/endpoint": {
|
||||||
"version": "9.0.6",
|
"version": "11.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz",
|
||||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
"integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^7.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/graphql": {
|
"node_modules/@octokit/graphql": {
|
||||||
"version": "7.1.1",
|
"version": "9.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
|
||||||
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==",
|
"integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/request": "^8.4.1",
|
"@octokit/request": "^10.0.6",
|
||||||
"@octokit/types": "^13.0.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^7.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/openapi-types": {
|
||||||
"version": "24.2.0",
|
"version": "27.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
|
||||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-paginate-rest": {
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
"version": "9.2.2",
|
"version": "14.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
|
||||||
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
|
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^12.6.0"
|
"@octokit/types": "^16.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@octokit/core": "5"
|
"@octokit/core": ">=6"
|
||||||
}
|
|
||||||
},
|
|
||||||
"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": {
|
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
"version": "10.4.1",
|
"version": "17.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
|
||||||
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
|
"integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^12.6.0"
|
"@octokit/types": "^16.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@octokit/core": "5"
|
"@octokit/core": ">=6"
|
||||||
}
|
|
||||||
},
|
|
||||||
"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/plugin-retry": {
|
"node_modules/@octokit/plugin-retry": {
|
||||||
"version": "6.1.0",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.0.3.tgz",
|
||||||
"integrity": "sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig==",
|
"integrity": "sha512-vKGx1i3MC0za53IzYBSBXcrhmd+daQDzuZfYDd52X5S0M2otf3kVZTVP8bLA3EkU0lTvd1WEC2OlNNa4G+dohA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/request-error": "^5.0.0",
|
"@octokit/request-error": "^7.0.2",
|
||||||
"@octokit/types": "^13.0.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"bottleneck": "^2.15.3"
|
"bottleneck": "^2.15.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@octokit/core": "5"
|
"@octokit/core": ">=7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "8.4.1",
|
"version": "10.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz",
|
||||||
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
|
"integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/endpoint": "^9.0.6",
|
"@octokit/endpoint": "^11.0.2",
|
||||||
"@octokit/request-error": "^5.1.1",
|
"@octokit/request-error": "^7.0.2",
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^16.0.0",
|
||||||
"universal-user-agent": "^6.0.0"
|
"fast-content-type-parse": "^3.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request-error": {
|
"node_modules/@octokit/request-error": {
|
||||||
"version": "5.1.1",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
|
||||||
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
|
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^13.1.0",
|
"@octokit/types": "^16.0.0"
|
||||||
"deprecation": "^2.0.0",
|
|
||||||
"once": "^1.4.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/types": {
|
"node_modules/@octokit/types": {
|
||||||
"version": "13.10.0",
|
"version": "16.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
|
||||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^24.2.0"
|
"@octokit/openapi-types": "^27.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@peculiar/asn1-cms": {
|
"node_modules/@peculiar/asn1-cms": {
|
||||||
@@ -711,9 +666,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/before-after-hook": {
|
"node_modules/before-after-hook": {
|
||||||
"version": "2.2.3",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
|
||||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
|
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/bottleneck": {
|
"node_modules/bottleneck": {
|
||||||
@@ -832,12 +787,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/deprecation": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/eastasianwidth": {
|
"node_modules/eastasianwidth": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||||
@@ -866,6 +815,22 @@
|
|||||||
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
|
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-content-type-parse": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fastify"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fastify"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/foreground-child": {
|
"node_modules/foreground-child": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||||
@@ -1236,15 +1201,6 @@
|
|||||||
"node": ">= 10.13"
|
"node": ">= 10.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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/p-map": {
|
"node_modules/p-map": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz",
|
||||||
@@ -1573,9 +1529,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tar": {
|
"node_modules/tar": {
|
||||||
"version": "7.5.2",
|
"version": "7.5.10",
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.10.tgz",
|
||||||
"integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==",
|
"integrity": "sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==",
|
||||||
"license": "BlueOak-1.0.0",
|
"license": "BlueOak-1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@isaacs/fs-minipass": "^4.0.0",
|
"@isaacs/fs-minipass": "^4.0.0",
|
||||||
@@ -1625,10 +1581,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.21.3",
|
"version": "6.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
||||||
"integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
|
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
@@ -1666,9 +1621,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/universal-user-agent": {
|
"node_modules/universal-user-agent": {
|
||||||
"version": "6.0.1",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
|
||||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/webcrypto-core": {
|
"node_modules/webcrypto-core": {
|
||||||
@@ -1791,12 +1746,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/attest",
|
"name": "@actions/attest",
|
||||||
"version": "2.1.0",
|
"version": "3.2.0",
|
||||||
"description": "Actions attestation lib",
|
"description": "Actions attestation lib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"github",
|
"github",
|
||||||
@@ -9,8 +9,15 @@
|
|||||||
],
|
],
|
||||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/attest",
|
"homepage": "https://github.com/actions/toolkit/tree/main/packages/attest",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./lib/index.d.ts",
|
||||||
|
"import": "./lib/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib",
|
"lib": "lib",
|
||||||
"test": "__tests__"
|
"test": "__tests__"
|
||||||
@@ -29,7 +36,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: run tests from root\" && exit 1",
|
"test": "echo \"Error: run tests from root\" && exit 1",
|
||||||
"tsc": "tsc"
|
"tsc": "tsc && cp src/internal/package-version.cjs lib/internal/"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/actions/toolkit/issues"
|
"url": "https://github.com/actions/toolkit/issues"
|
||||||
@@ -39,20 +46,15 @@
|
|||||||
"@sigstore/rekor-types": "^3.0.0",
|
"@sigstore/rekor-types": "^3.0.0",
|
||||||
"@types/jsonwebtoken": "^9.0.6",
|
"@types/jsonwebtoken": "^9.0.6",
|
||||||
"nock": "^13.5.1",
|
"nock": "^13.5.1",
|
||||||
"undici": "^6.20.0"
|
"undici": "^6.23.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^9.0.0",
|
||||||
"@actions/http-client": "^2.2.3",
|
"@actions/http-client": "^4.0.0",
|
||||||
"@octokit/plugin-retry": "^6.0.1",
|
"@octokit/plugin-retry": "^8.0.3",
|
||||||
"@sigstore/bundle": "^3.1.0",
|
"@sigstore/bundle": "^3.1.0",
|
||||||
"@sigstore/sign": "^3.1.0",
|
"@sigstore/sign": "^3.1.0",
|
||||||
"jose": "^5.10.0"
|
"jose": "^5.10.0"
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"@octokit/plugin-retry": {
|
|
||||||
"@octokit/core": "^5.2.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import {retry} from '@octokit/plugin-retry'
|
import {retry} from '@octokit/plugin-retry'
|
||||||
import {RequestHeaders} from '@octokit/types'
|
import {RequestHeaders} from '@octokit/types'
|
||||||
|
import {getUserAgent} from './internal/utils.js'
|
||||||
|
|
||||||
const CREATE_STORAGE_RECORD_REQUEST =
|
const CREATE_STORAGE_RECORD_REQUEST =
|
||||||
'POST /orgs/{owner}/artifacts/metadata/storage-record'
|
'POST /orgs/{owner}/artifacts/metadata/storage-record'
|
||||||
@@ -52,10 +53,16 @@ export async function createStorageRecord(
|
|||||||
): Promise<number[]> {
|
): Promise<number[]> {
|
||||||
const retries = retryAttempts ?? DEFAULT_RETRY_COUNT
|
const retries = retryAttempts ?? DEFAULT_RETRY_COUNT
|
||||||
const octokit = github.getOctokit(token, {retry: {retries}}, retry)
|
const octokit = github.getOctokit(token, {retry: {retries}}, retry)
|
||||||
|
|
||||||
|
const headersWithUserAgent = {
|
||||||
|
'User-Agent': getUserAgent(),
|
||||||
|
...headers
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await octokit.request(CREATE_STORAGE_RECORD_REQUEST, {
|
const response = await octokit.request(CREATE_STORAGE_RECORD_REQUEST, {
|
||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
headers,
|
headers: headersWithUserAgent,
|
||||||
...buildRequestParams(artifactOptions, packageRegistryOptions)
|
...buildRequestParams(artifactOptions, packageRegistryOptions)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {bundleToJSON} from '@sigstore/bundle'
|
import {bundleToJSON} from '@sigstore/bundle'
|
||||||
import {X509Certificate} from 'crypto'
|
import {X509Certificate} from 'crypto'
|
||||||
import {SigstoreInstance, signingEndpoints} from './endpoints'
|
import {SigstoreInstance, signingEndpoints} from './endpoints.js'
|
||||||
import {buildIntotoStatement} from './intoto'
|
import {buildIntotoStatement} from './intoto.js'
|
||||||
import {Payload, signPayload} from './sign'
|
import {Payload, signPayload} from './sign.js'
|
||||||
import {writeAttestation} from './store'
|
import {writeAttestation} from './store.js'
|
||||||
|
|
||||||
import type {Bundle} from '@sigstore/sign'
|
import type {Bundle} from '@sigstore/sign'
|
||||||
import type {Attestation, Predicate, Subject} from './shared.types'
|
import type {Attestation, Predicate, Subject} from './shared.types.js'
|
||||||
|
|
||||||
const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json'
|
const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json'
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
export {createStorageRecord} from './artifactMetadata'
|
export {
|
||||||
export {AttestOptions, attest} from './attest'
|
createStorageRecord,
|
||||||
|
ArtifactOptions,
|
||||||
|
PackageRegistryOptions
|
||||||
|
} from './artifactMetadata.js'
|
||||||
|
export {AttestOptions, attest} from './attest.js'
|
||||||
export {
|
export {
|
||||||
AttestProvenanceOptions,
|
AttestProvenanceOptions,
|
||||||
attestProvenance,
|
attestProvenance,
|
||||||
buildSLSAProvenancePredicate
|
buildSLSAProvenancePredicate
|
||||||
} from './provenance'
|
} from './provenance.js'
|
||||||
|
|
||||||
export type {SerializedBundle} from '@sigstore/bundle'
|
export type {SerializedBundle} from '@sigstore/bundle'
|
||||||
export type {Attestation, Predicate, Subject} from './shared.types'
|
export type {Attestation, Predicate, Subject} from './shared.types.js'
|
||||||
|
export type {SigstoreInstance} from './endpoints.js'
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// This file exists as a CommonJS module to read the version from package.json.
|
||||||
|
// In an ESM package, using `require()` directly in .ts files requires disabling
|
||||||
|
// ESLint rules and doesn't work reliably across all Node.js versions.
|
||||||
|
// By keeping this as a .cjs file, we can use require() naturally and export
|
||||||
|
// the version for the ESM modules to import.
|
||||||
|
const packageJson = require('../../package.json')
|
||||||
|
module.exports = {version: packageJson.version}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import {version} from './package-version.cjs'
|
||||||
|
|
||||||
|
export const getUserAgent = (): string => {
|
||||||
|
const baseUserAgent = `@actions/attest-${version}`
|
||||||
|
|
||||||
|
const orchId = process.env['ACTIONS_ORCHESTRATION_ID']
|
||||||
|
if (orchId) {
|
||||||
|
// Sanitize the orchestration ID to ensure it contains only valid characters
|
||||||
|
// Valid characters: 0-9, a-z, _, -, .
|
||||||
|
const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_')
|
||||||
|
return `${baseUserAgent} actions_orchestration_id/${sanitizedId}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseUserAgent
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Predicate, Subject} from './shared.types'
|
import {Predicate, Subject} from './shared.types.js'
|
||||||
|
|
||||||
const INTOTO_STATEMENT_V1_TYPE = 'https://in-toto.io/Statement/v1'
|
const INTOTO_STATEMENT_V1_TYPE = 'https://in-toto.io/Statement/v1'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {attest, AttestOptions} from './attest'
|
import {attest, AttestOptions} from './attest.js'
|
||||||
import {getIDTokenClaims} from './oidc'
|
import {getIDTokenClaims} from './oidc.js'
|
||||||
import type {Attestation, Predicate} from './shared.types'
|
import type {Attestation, Predicate} from './shared.types.js'
|
||||||
|
|
||||||
const SLSA_PREDICATE_V1_TYPE = 'https://slsa.dev/provenance/v1'
|
const SLSA_PREDICATE_V1_TYPE = 'https://slsa.dev/provenance/v1'
|
||||||
const GITHUB_BUILD_TYPE = 'https://actions.github.io/buildtypes/workflow/v1'
|
const GITHUB_BUILD_TYPE = 'https://actions.github.io/buildtypes/workflow/v1'
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import {retry} from '@octokit/plugin-retry'
|
import {retry} from '@octokit/plugin-retry'
|
||||||
import {RequestHeaders} from '@octokit/types'
|
import {RequestHeaders} from '@octokit/types'
|
||||||
|
import {getUserAgent} from './internal/utils.js'
|
||||||
|
|
||||||
const CREATE_ATTESTATION_REQUEST = 'POST /repos/{owner}/{repo}/attestations'
|
const CREATE_ATTESTATION_REQUEST = 'POST /repos/{owner}/{repo}/attestations'
|
||||||
const DEFAULT_RETRY_COUNT = 5
|
const DEFAULT_RETRY_COUNT = 5
|
||||||
@@ -24,11 +25,16 @@ export const writeAttestation = async (
|
|||||||
const retries = options.retry ?? DEFAULT_RETRY_COUNT
|
const retries = options.retry ?? DEFAULT_RETRY_COUNT
|
||||||
const octokit = github.getOctokit(token, {retry: {retries}}, retry)
|
const octokit = github.getOctokit(token, {retry: {retries}}, retry)
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
'User-Agent': getUserAgent(),
|
||||||
|
...options.headers
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await octokit.request(CREATE_ATTESTATION_REQUEST, {
|
const response = await octokit.request(CREATE_ATTESTATION_REQUEST, {
|
||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
repo: github.context.repo.repo,
|
repo: github.context.repo.repo,
|
||||||
headers: options.headers,
|
headers,
|
||||||
bundle: attestation as {
|
bundle: attestation as {
|
||||||
mediaType?: string
|
mediaType?: string
|
||||||
verificationMaterial?: {[key: string]: unknown}
|
verificationMaterial?: {[key: string]: unknown}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"rootDir": "./src"
|
"rootDir": "./src",
|
||||||
|
"module": "node16",
|
||||||
|
"moduleResolution": "node16"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src"
|
"./src"
|
||||||
|
|||||||
Vendored
+72
-50
@@ -1,6 +1,28 @@
|
|||||||
# @actions/cache Releases
|
# @actions/cache Releases
|
||||||
|
|
||||||
### 5.0.0
|
## 6.0.0
|
||||||
|
|
||||||
|
- **Breaking change**: Package is now ESM-only
|
||||||
|
- CommonJS consumers must use dynamic `import()` instead of `require()`
|
||||||
|
|
||||||
|
## 5.0.5
|
||||||
|
|
||||||
|
- Bump `@actions/glob` to `0.5.1`
|
||||||
|
|
||||||
|
## 5.0.4
|
||||||
|
|
||||||
|
- Bump `@actions/http-client` to `3.0.2`
|
||||||
|
|
||||||
|
## 5.0.3
|
||||||
|
|
||||||
|
Prevent retries for rate limited cache operations [2243](https://github.com/actions/toolkit/pull/2243).
|
||||||
|
|
||||||
|
## 5.0.1
|
||||||
|
|
||||||
|
- Fix Node.js 24 punycode deprecation warning by updating `@azure/storage-blob` from `^12.13.0` to `^12.29.1` [#2213](https://github.com/actions/toolkit/pull/2213)
|
||||||
|
- Newer storage-blob uses `@azure/core-rest-pipeline` instead of deprecated `@azure/core-http`, which eliminates the transitive dependency on `node-fetch@2` → `whatwg-url@5` → `tr46@0.0.3` that used the deprecated punycode module
|
||||||
|
|
||||||
|
## 5.0.0
|
||||||
|
|
||||||
- Remove `@azure/ms-rest-js` dependency [#2197](https://github.com/actions/toolkit/pull/2197)
|
- Remove `@azure/ms-rest-js` dependency [#2197](https://github.com/actions/toolkit/pull/2197)
|
||||||
- The `TransferProgressEvent` type is now imported from `@azure/core-rest-pipeline` instead of `@azure/ms-rest-js`
|
- The `TransferProgressEvent` type is now imported from `@azure/core-rest-pipeline` instead of `@azure/ms-rest-js`
|
||||||
@@ -12,15 +34,15 @@
|
|||||||
- Add support for Node.js 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
- Add support for Node.js 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||||
- Add `node-fetch` override to resolve audit vulnerabilities [#2110](https://github.com/actions/toolkit/pull/2110)
|
- Add `node-fetch` override to resolve audit vulnerabilities [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||||
|
|
||||||
### 4.1.0
|
## 4.1.0
|
||||||
|
|
||||||
- Remove client side 10GiB cache size limit check & update twirp client [#2118](https://github.com/actions/toolkit/pull/2118)
|
- Remove client side 10GiB cache size limit check & update twirp client [#2118](https://github.com/actions/toolkit/pull/2118)
|
||||||
|
|
||||||
### 4.0.5
|
## 4.0.5
|
||||||
|
|
||||||
- Reintroduce @protobuf-ts/runtime-rpc as a runtime dependency [#2113](https://github.com/actions/toolkit/pull/2113)
|
- Reintroduce @protobuf-ts/runtime-rpc as a runtime dependency [#2113](https://github.com/actions/toolkit/pull/2113)
|
||||||
|
|
||||||
### 4.0.4
|
## 4.0.4
|
||||||
|
|
||||||
⚠️ Faulty patch release. Upgrade to 4.0.5 instead.
|
⚠️ Faulty patch release. Upgrade to 4.0.5 instead.
|
||||||
|
|
||||||
@@ -29,23 +51,23 @@
|
|||||||
- Enhanced server error handling: 5xx HTTP errors are now logged as errors instead of warnings [#2099](https://github.com/actions/toolkit/pull/2099)
|
- 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)
|
- 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
|
## 4.0.3
|
||||||
|
|
||||||
- Added masking for Shared Access Signature (SAS) cache entry URLs [#1982](https://github.com/actions/toolkit/pull/1982)
|
- 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)
|
- 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
|
## 4.0.2
|
||||||
|
|
||||||
- Wrap create failures in ReserveCacheError [#1966](https://github.com/actions/toolkit/pull/1966)
|
- Wrap create failures in ReserveCacheError [#1966](https://github.com/actions/toolkit/pull/1966)
|
||||||
|
|
||||||
### 4.0.1
|
## 4.0.1
|
||||||
|
|
||||||
- Remove runtime dependency on `twirp-ts` [#1947](https://github.com/actions/toolkit/pull/1947)
|
- 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)
|
- Cache miss as debug, not warning annotation [#1954](https://github.com/actions/toolkit/pull/1954)
|
||||||
|
|
||||||
### 4.0.0
|
## 4.0.0
|
||||||
|
|
||||||
#### Important changes
|
### Important changes
|
||||||
|
|
||||||
The cache backend service has been rewritten from the ground up for improved performance and reliability. The [@actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) package now integrates with the new cache service (v2) APIs.
|
The cache backend service has been rewritten from the ground up for improved performance and reliability. The [@actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) package now integrates with the new cache service (v2) APIs.
|
||||||
|
|
||||||
@@ -59,182 +81,182 @@ Upgrading to the recommended version should not break or require any changes to
|
|||||||
|
|
||||||
Read more about the change & access the migration guide: [reference to the announcement](https://github.com/actions/toolkit/discussions/1890).
|
Read more about the change & access the migration guide: [reference to the announcement](https://github.com/actions/toolkit/discussions/1890).
|
||||||
|
|
||||||
#### Minor changes
|
### Minor changes
|
||||||
|
|
||||||
- Update `@actions/core` to `1.11.0`
|
- Update `@actions/core` to `1.11.0`
|
||||||
- Update `semver` `6.3.1`
|
- Update `semver` `6.3.1`
|
||||||
- Add `twirp-ts` `2.5.0` to dependencies
|
- Add `twirp-ts` `2.5.0` to dependencies
|
||||||
|
|
||||||
### 3.3.0
|
## 3.3.0
|
||||||
|
|
||||||
- Update `@actions/core` to `1.11.1`
|
- Update `@actions/core` to `1.11.1`
|
||||||
- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824), [#1842](https://github.com/actions/toolkit/pull/1842)
|
- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824), [#1842](https://github.com/actions/toolkit/pull/1842)
|
||||||
|
|
||||||
### 3.2.4
|
## 3.2.4
|
||||||
|
|
||||||
- Updated `isGhes` check to include `.ghe.com` and `.ghe.localhost` as accepted hosts
|
- Updated `isGhes` check to include `.ghe.com` and `.ghe.localhost` as accepted hosts
|
||||||
|
|
||||||
### 3.2.3
|
## 3.2.3
|
||||||
|
|
||||||
- Fixed a bug that mutated path arguments to `getCacheVersion` [#1378](https://github.com/actions/toolkit/pull/1378)
|
- Fixed a bug that mutated path arguments to `getCacheVersion` [#1378](https://github.com/actions/toolkit/pull/1378)
|
||||||
|
|
||||||
### 3.2.2
|
## 3.2.2
|
||||||
|
|
||||||
- Add new default cache download method to improve performance and reduce hangs [#1484](https://github.com/actions/toolkit/pull/1484)
|
- Add new default cache download method to improve performance and reduce hangs [#1484](https://github.com/actions/toolkit/pull/1484)
|
||||||
|
|
||||||
### 3.2.1
|
## 3.2.1
|
||||||
|
|
||||||
- Updated @azure/storage-blob to `v12.13.0`
|
- Updated @azure/storage-blob to `v12.13.0`
|
||||||
|
|
||||||
### 3.2.0
|
## 3.2.0
|
||||||
|
|
||||||
- Add `lookupOnly` to cache restore `DownloadOptions`.
|
- Add `lookupOnly` to cache restore `DownloadOptions`.
|
||||||
|
|
||||||
### 3.1.4
|
## 3.1.4
|
||||||
|
|
||||||
- Fix zstd not being used due to `zstd --version` output change in zstd 1.5.4 release. See [#1353](https://github.com/actions/toolkit/pull/1353).
|
- Fix zstd not being used due to `zstd --version` output change in zstd 1.5.4 release. See [#1353](https://github.com/actions/toolkit/pull/1353).
|
||||||
|
|
||||||
### 3.1.3
|
## 3.1.3
|
||||||
|
|
||||||
- Fix to prevent from setting MYSYS environement variable globally [#1329](https://github.com/actions/toolkit/pull/1329).
|
- Fix to prevent from setting MYSYS environement variable globally [#1329](https://github.com/actions/toolkit/pull/1329).
|
||||||
|
|
||||||
### 3.1.2
|
## 3.1.2
|
||||||
|
|
||||||
- Fix issue with symlink restoration on windows.
|
- Fix issue with symlink restoration on windows.
|
||||||
|
|
||||||
### 3.1.1
|
## 3.1.1
|
||||||
|
|
||||||
- Reverted changes in 3.1.0 to fix issue with symlink restoration on windows.
|
- Reverted changes in 3.1.0 to fix issue with symlink restoration on windows.
|
||||||
- Added support for verbose logging about cache version during cache miss.
|
- Added support for verbose logging about cache version during cache miss.
|
||||||
|
|
||||||
### 3.1.0
|
## 3.1.0
|
||||||
|
|
||||||
- Update actions/cache on windows to use gnu tar and zstd by default
|
- Update actions/cache on windows to use gnu tar and zstd by default
|
||||||
- Update actions/cache on windows to fallback to bsdtar and zstd if gnu tar is not available.
|
- Update actions/cache on windows to fallback to bsdtar and zstd if gnu tar is not available.
|
||||||
- Added support for fallback to gzip to restore old caches on windows.
|
- Added support for fallback to gzip to restore old caches on windows.
|
||||||
|
|
||||||
### 3.1.0-beta.3
|
## 3.1.0-beta.3
|
||||||
|
|
||||||
- Bug Fixes for fallback to gzip to restore old caches on windows and bsdtar if gnutar is not available.
|
- Bug Fixes for fallback to gzip to restore old caches on windows and bsdtar if gnutar is not available.
|
||||||
|
|
||||||
### 3.1.0-beta.2
|
## 3.1.0-beta.2
|
||||||
|
|
||||||
- Added support for fallback to gzip to restore old caches on windows.
|
- Added support for fallback to gzip to restore old caches on windows.
|
||||||
|
|
||||||
### 3.0.6
|
## 3.0.6
|
||||||
|
|
||||||
- Added `@azure/abort-controller` to dependencies to fix compatibility issue with ESM [#1208](https://github.com/actions/toolkit/issues/1208)
|
- Added `@azure/abort-controller` to dependencies to fix compatibility issue with ESM [#1208](https://github.com/actions/toolkit/issues/1208)
|
||||||
|
|
||||||
### 3.0.5
|
## 3.0.5
|
||||||
|
|
||||||
- Update `@actions/cache` to use `@actions/core@^1.10.0`
|
- Update `@actions/cache` to use `@actions/core@^1.10.0`
|
||||||
|
|
||||||
### 3.0.4
|
## 3.0.4
|
||||||
|
|
||||||
- Fix zstd not working for windows on gnu tar in issues [#888](https://github.com/actions/cache/issues/888) and [#891](https://github.com/actions/cache/issues/891).
|
- Fix zstd not working for windows on gnu tar in issues [#888](https://github.com/actions/cache/issues/888) and [#891](https://github.com/actions/cache/issues/891).
|
||||||
- Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
|
- Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable `SEGMENT_DOWNLOAD_TIMEOUT_MINS`. Default is 60 minutes.
|
||||||
|
|
||||||
### 3.0.3
|
## 3.0.3
|
||||||
|
|
||||||
- Bug fixes for download stuck issue [#810](https://github.com/actions/cache/issues/810).
|
- Bug fixes for download stuck issue [#810](https://github.com/actions/cache/issues/810).
|
||||||
|
|
||||||
### 3.0.2
|
## 3.0.2
|
||||||
|
|
||||||
- Added 1 hour timeout for the download stuck issue [#810](https://github.com/actions/cache/issues/810).
|
- Added 1 hour timeout for the download stuck issue [#810](https://github.com/actions/cache/issues/810).
|
||||||
|
|
||||||
### 3.0.1
|
## 3.0.1
|
||||||
|
|
||||||
- Fix [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory.
|
- Fix [#833](https://github.com/actions/cache/issues/833) - cache doesn't work with github workspace directory.
|
||||||
- Fix [#809](https://github.com/actions/cache/issues/809) `zstd -d: no such file or directory` error on AWS self-hosted runners.
|
- Fix [#809](https://github.com/actions/cache/issues/809) `zstd -d: no such file or directory` error on AWS self-hosted runners.
|
||||||
|
|
||||||
### 3.0.0
|
## 3.0.0
|
||||||
|
|
||||||
- Updated actions/cache to suppress Actions cache server error and log warning for those error [#1122](https://github.com/actions/toolkit/pull/1122)
|
- Updated actions/cache to suppress Actions cache server error and log warning for those error [#1122](https://github.com/actions/toolkit/pull/1122)
|
||||||
|
|
||||||
### 2.0.6
|
## 2.0.6
|
||||||
|
|
||||||
- Fix `Tar failed with error: The process '/usr/bin/tar' failed with exit code 1` issue when temp directory where tar is getting created is actually the subdirectory of the path mentioned by the user for caching. ([issue](https://github.com/actions/cache/issues/689))
|
- Fix `Tar failed with error: The process '/usr/bin/tar' failed with exit code 1` issue when temp directory where tar is getting created is actually the subdirectory of the path mentioned by the user for caching. ([issue](https://github.com/actions/cache/issues/689))
|
||||||
|
|
||||||
### 2.0.5
|
## 2.0.5
|
||||||
|
|
||||||
- Fix to avoid saving empty cache when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
|
- Fix to avoid saving empty cache when no files are available for caching. ([issue](https://github.com/actions/cache/issues/624))
|
||||||
|
|
||||||
### 2.0.4
|
## 2.0.4
|
||||||
|
|
||||||
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
|
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
|
||||||
|
|
||||||
### 2.0.3
|
## 2.0.3
|
||||||
|
|
||||||
- Update to v2.0.0 of `@actions/http-client`
|
- Update to v2.0.0 of `@actions/http-client`
|
||||||
|
|
||||||
### 2.0.0
|
## 2.0.0
|
||||||
|
|
||||||
- Added support to check if Actions cache service feature is available or not [#1028](https://github.com/actions/toolkit/pull/1028)
|
- Added support to check if Actions cache service feature is available or not [#1028](https://github.com/actions/toolkit/pull/1028)
|
||||||
|
|
||||||
### 1.0.11
|
## 1.0.11
|
||||||
|
|
||||||
- Fix file downloads > 2GB([issue](https://github.com/actions/cache/issues/773))
|
- Fix file downloads > 2GB([issue](https://github.com/actions/cache/issues/773))
|
||||||
|
|
||||||
### 1.0.10
|
## 1.0.10
|
||||||
|
|
||||||
- Update `lockfileVersion` to `v2` in `package-lock.json [#1022](https://github.com/actions/toolkit/pull/1022)
|
- Update `lockfileVersion` to `v2` in `package-lock.json [#1022](https://github.com/actions/toolkit/pull/1022)
|
||||||
|
|
||||||
### 1.0.9
|
## 1.0.9
|
||||||
|
|
||||||
- Use @azure/ms-rest-js v2.6.0
|
- Use @azure/ms-rest-js v2.6.0
|
||||||
- Use @azure/storage-blob v12.8.0
|
- Use @azure/storage-blob v12.8.0
|
||||||
|
|
||||||
### 1.0.8
|
## 1.0.8
|
||||||
|
|
||||||
- Increase the allowed artifact cache size from 5GB to 10GB ([issue](https://github.com/actions/cache/discussions/497))
|
- Increase the allowed artifact cache size from 5GB to 10GB ([issue](https://github.com/actions/cache/discussions/497))
|
||||||
|
|
||||||
### 1.0.7
|
## 1.0.7
|
||||||
|
|
||||||
- Fixes permissions issue extracting archives with GNU tar on macOS ([issue](https://github.com/actions/cache/issues/527))
|
- Fixes permissions issue extracting archives with GNU tar on macOS ([issue](https://github.com/actions/cache/issues/527))
|
||||||
|
|
||||||
### 1.0.6
|
## 1.0.6
|
||||||
|
|
||||||
- Make caching more verbose [#650](https://github.com/actions/toolkit/pull/650)
|
- Make caching more verbose [#650](https://github.com/actions/toolkit/pull/650)
|
||||||
- Use GNU tar on macOS if available [#701](https://github.com/actions/toolkit/pull/701)
|
- Use GNU tar on macOS if available [#701](https://github.com/actions/toolkit/pull/701)
|
||||||
|
|
||||||
### 1.0.5
|
## 1.0.5
|
||||||
|
|
||||||
- Fix to ensure Windows cache paths get resolved correctly
|
- Fix to ensure Windows cache paths get resolved correctly
|
||||||
|
|
||||||
### 1.0.4
|
## 1.0.4
|
||||||
|
|
||||||
- Use @actions/core v1.2.6
|
- Use @actions/core v1.2.6
|
||||||
- Fixes uploadChunk to throw an error if any unsuccessful response code is received
|
- Fixes uploadChunk to throw an error if any unsuccessful response code is received
|
||||||
|
|
||||||
### 1.0.3
|
## 1.0.3
|
||||||
|
|
||||||
- Use http-client v1.0.9
|
- Use http-client v1.0.9
|
||||||
- Fixes error handling so retries are not attempted on non-retryable errors (409 Conflict, for example)
|
- Fixes error handling so retries are not attempted on non-retryable errors (409 Conflict, for example)
|
||||||
- Adds 5 second delay between retry attempts
|
- Adds 5 second delay between retry attempts
|
||||||
|
|
||||||
### 1.0.2
|
## 1.0.2
|
||||||
|
|
||||||
- Use posix archive format to add support for some tools
|
- Use posix archive format to add support for some tools
|
||||||
|
|
||||||
### 1.0.1
|
## 1.0.1
|
||||||
|
|
||||||
- Fix bug in downloading large files (> 2 GBs) with the Azure SDK
|
- Fix bug in downloading large files (> 2 GBs) with the Azure SDK
|
||||||
|
|
||||||
### 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
- Downloads Azure-hosted caches using the Azure SDK for speed and reliability
|
- Downloads Azure-hosted caches using the Azure SDK for speed and reliability
|
||||||
- Displays download progress
|
- Displays download progress
|
||||||
- Includes changes that break compatibility with earlier versions, including:
|
- Includes changes that break compatibility with earlier versions, including:
|
||||||
- `retry`, `retryTypedResponse`, and `retryHttpClientResponse` moved from `cacheHttpClient` to `requestUtils`
|
- `retry`, `retryTypedResponse`, and `retryHttpClientResponse` moved from `cacheHttpClient` to `requestUtils`
|
||||||
|
|
||||||
### 0.2.1
|
## 0.2.1
|
||||||
|
|
||||||
- Fix to await async function getCompressionMethod
|
- Fix to await async function getCompressionMethod
|
||||||
|
|
||||||
### 0.2.0
|
## 0.2.0
|
||||||
|
|
||||||
- Fixes issues with the zstd compression algorithm on Windows and Ubuntu 16.04 [#469](https://github.com/actions/toolkit/pull/469)
|
- Fixes issues with the zstd compression algorithm on Windows and Ubuntu 16.04 [#469](https://github.com/actions/toolkit/pull/469)
|
||||||
|
|
||||||
### 0.1.0
|
## 0.1.0
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name: 'Set env variables'
|
name: 'Set env variables'
|
||||||
description: 'Sets certain env variables so that e2e restore and save cache can be tested in a shell'
|
description: 'Sets certain env variables so that e2e restore and save cache can be tested in a shell'
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node20'
|
||||||
main: 'index.js'
|
main: 'index.js'
|
||||||
+4
-3
@@ -1,8 +1,9 @@
|
|||||||
// Certain env variables are not set by default in a shell context and are only available in a node context from a running action
|
// Certain env variables are not set by default in a shell context and are only available in a node context from a running action
|
||||||
// In order to be able to restore and save cache e2e in a shell when running CI tests, we need these env variables set
|
// In order to be able to restore and save cache e2e in a shell when running CI tests, we need these env variables set
|
||||||
const fs = require('fs');
|
import fs from 'fs'
|
||||||
const os = require('os');
|
import os from 'os'
|
||||||
const filePath = process.env[`GITHUB_ENV`]
|
|
||||||
|
const filePath = process.env['GITHUB_ENV']
|
||||||
fs.appendFileSync(filePath, `ACTIONS_CACHE_SERVICE_V2=true${os.EOL}`, {
|
fs.appendFileSync(filePath, `ACTIONS_CACHE_SERVICE_V2=true${os.EOL}`, {
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
})
|
})
|
||||||
|
|||||||
+174
@@ -0,0 +1,174 @@
|
|||||||
|
import * as http from 'http'
|
||||||
|
import * as net from 'net'
|
||||||
|
import {HttpClient} from '@actions/http-client'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as config from '../src/internal/config'
|
||||||
|
import * as cacheUtils from '../src/internal/cacheUtils'
|
||||||
|
import {internalCacheTwirpClient} from '../src/internal/shared/cacheTwirpClient'
|
||||||
|
|
||||||
|
jest.mock('@actions/http-client')
|
||||||
|
|
||||||
|
const clientOptions = {
|
||||||
|
maxAttempts: 5,
|
||||||
|
retryIntervalMs: 1,
|
||||||
|
retryMultiplier: 1.5
|
||||||
|
}
|
||||||
|
|
||||||
|
// noopLogs mocks the console.log and core.* functions to prevent output in the console while testing
|
||||||
|
const noopLogs = (): void => {
|
||||||
|
jest.spyOn(console, 'log').mockImplementation(() => {})
|
||||||
|
jest.spyOn(core, 'debug').mockImplementation(() => {})
|
||||||
|
jest.spyOn(core, 'info').mockImplementation(() => {})
|
||||||
|
jest.spyOn(core, 'warning').mockImplementation(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('cacheTwirpClient', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
noopLogs()
|
||||||
|
jest
|
||||||
|
.spyOn(config, 'getCacheServiceURL')
|
||||||
|
.mockReturnValue('http://localhost:8080')
|
||||||
|
jest.spyOn(cacheUtils, 'getRuntimeToken').mockReturnValue('token')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail immediately on 429 rate limit without retrying', async () => {
|
||||||
|
const mockPost = jest.fn(() => {
|
||||||
|
const msg = new http.IncomingMessage(new net.Socket())
|
||||||
|
msg.statusCode = 429
|
||||||
|
msg.statusMessage = 'Too Many Requests'
|
||||||
|
return {
|
||||||
|
message: msg,
|
||||||
|
readBody: async () => {
|
||||||
|
return Promise.resolve(`{"ok": false}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
post: mockPost
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const client = internalCacheTwirpClient(clientOptions)
|
||||||
|
await expect(
|
||||||
|
client.CreateCacheEntry({
|
||||||
|
key: 'test-key',
|
||||||
|
version: 'test-version'
|
||||||
|
})
|
||||||
|
).rejects.toThrow(
|
||||||
|
'Failed to CreateCacheEntry: Rate limited: Failed request: (429) Too Many Requests'
|
||||||
|
)
|
||||||
|
|
||||||
|
// Should only be called once - no retries for 429
|
||||||
|
expect(mockPost).toHaveBeenCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should log warning with retry-after header on 429', async () => {
|
||||||
|
const warningSpy = jest.spyOn(core, 'warning')
|
||||||
|
|
||||||
|
const mockPost = jest.fn(() => {
|
||||||
|
const msg = new http.IncomingMessage(new net.Socket())
|
||||||
|
msg.statusCode = 429
|
||||||
|
msg.statusMessage = 'Too Many Requests'
|
||||||
|
msg.headers = {'retry-after': '60'}
|
||||||
|
return {
|
||||||
|
message: msg,
|
||||||
|
readBody: async () => {
|
||||||
|
return Promise.resolve(`{"ok": false}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
post: mockPost
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const client = internalCacheTwirpClient(clientOptions)
|
||||||
|
await expect(
|
||||||
|
client.CreateCacheEntry({
|
||||||
|
key: 'test-key',
|
||||||
|
version: 'test-version'
|
||||||
|
})
|
||||||
|
).rejects.toThrow('Rate limited')
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledTimes(1)
|
||||||
|
expect(warningSpy).toHaveBeenCalledWith(
|
||||||
|
"You've hit a rate limit, your rate limit will reset in 60 seconds"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not log warning if retry-after header is missing on 429', async () => {
|
||||||
|
const warningSpy = jest.spyOn(core, 'warning')
|
||||||
|
|
||||||
|
const mockPost = jest.fn(() => {
|
||||||
|
const msg = new http.IncomingMessage(new net.Socket())
|
||||||
|
msg.statusCode = 429
|
||||||
|
msg.statusMessage = 'Too Many Requests'
|
||||||
|
// No retry-after header
|
||||||
|
return {
|
||||||
|
message: msg,
|
||||||
|
readBody: async () => {
|
||||||
|
return Promise.resolve(`{"ok": false}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
post: mockPost
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const client = internalCacheTwirpClient(clientOptions)
|
||||||
|
await expect(
|
||||||
|
client.CreateCacheEntry({
|
||||||
|
key: 'test-key',
|
||||||
|
version: 'test-version'
|
||||||
|
})
|
||||||
|
).rejects.toThrow('Rate limited')
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledTimes(1)
|
||||||
|
expect(warningSpy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not log warning if retry-after header is invalid on 429', async () => {
|
||||||
|
const warningSpy = jest.spyOn(core, 'warning')
|
||||||
|
|
||||||
|
const mockPost = jest.fn(() => {
|
||||||
|
const msg = new http.IncomingMessage(new net.Socket())
|
||||||
|
msg.statusCode = 429
|
||||||
|
msg.statusMessage = 'Too Many Requests'
|
||||||
|
msg.headers = {'retry-after': 'invalid'}
|
||||||
|
return {
|
||||||
|
message: msg,
|
||||||
|
readBody: async () => {
|
||||||
|
return Promise.resolve(`{"ok": false}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
;(HttpClient as unknown as jest.Mock).mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
post: mockPost
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const client = internalCacheTwirpClient(clientOptions)
|
||||||
|
await expect(
|
||||||
|
client.CreateCacheEntry({
|
||||||
|
key: 'test-key',
|
||||||
|
version: 'test-version'
|
||||||
|
})
|
||||||
|
).rejects.toThrow('Rate limited')
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledTimes(1)
|
||||||
|
expect(warningSpy).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Helper script to restore cache for e2e testing
|
||||||
|
import * as cache from '../lib/cache.js'
|
||||||
|
|
||||||
|
const [prefix, runId, useAzureSdk] = process.argv.slice(2)
|
||||||
|
|
||||||
|
if (!prefix || !runId) {
|
||||||
|
console.error('Usage: restore-cache.mjs <prefix> <runId> [useAzureSdk]')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = `test-${prefix}-${runId}`
|
||||||
|
const paths = ['test-cache', '~/test-cache']
|
||||||
|
const options = {useAzureSdk: useAzureSdk !== 'false'}
|
||||||
|
|
||||||
|
console.log(`Restoring cache with key: ${key}`)
|
||||||
|
console.log(`Paths: ${paths.join(', ')}`)
|
||||||
|
console.log(`Using Azure SDK: ${options.useAzureSdk}`)
|
||||||
|
|
||||||
|
const maxRetries = 3
|
||||||
|
const retryDelayMs = 5000
|
||||||
|
|
||||||
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
|
try {
|
||||||
|
console.log(`Attempt ${attempt} of ${maxRetries}`)
|
||||||
|
const restoredKey = await cache.restoreCache(paths, key, [], options)
|
||||||
|
|
||||||
|
if (restoredKey) {
|
||||||
|
console.log(`Cache restored with key: ${restoredKey}`)
|
||||||
|
process.exit(0)
|
||||||
|
} else {
|
||||||
|
console.log('Cache not found on this attempt')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error on attempt ${attempt}:`, error.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attempt < maxRetries) {
|
||||||
|
console.log(`Waiting ${retryDelayMs / 1000}s before retry...`)
|
||||||
|
await new Promise(resolve => setTimeout(resolve, retryDelayMs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(`Failed to restore cache after ${maxRetries} attempts`)
|
||||||
|
process.exit(1)
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Helper script to save cache for e2e testing
|
||||||
|
import * as cache from '../lib/cache.js'
|
||||||
|
|
||||||
|
const [prefix, runId] = process.argv.slice(2)
|
||||||
|
|
||||||
|
if (!prefix || !runId) {
|
||||||
|
console.error('Usage: save-cache.mjs <prefix> <runId>')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = `test-${prefix}-${runId}`
|
||||||
|
const paths = ['test-cache', '~/test-cache']
|
||||||
|
|
||||||
|
console.log(`Saving cache with key: ${key}`)
|
||||||
|
console.log(`Paths: ${paths.join(', ')}`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cacheId = await cache.saveCache(paths, key)
|
||||||
|
console.log(`Cache saved with ID: ${cacheId}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error saving cache:', error)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
+59
-200
@@ -1,122 +1,86 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/cache",
|
"name": "@actions/cache",
|
||||||
"version": "5.0.0",
|
"version": "6.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@actions/cache",
|
"name": "@actions/cache",
|
||||||
"version": "5.0.0",
|
"version": "6.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^2.0.0",
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.6.1",
|
||||||
"@actions/http-client": "^3.0.0",
|
"@actions/http-client": "^4.0.0",
|
||||||
"@actions/io": "^2.0.0",
|
"@actions/io": "^3.0.0",
|
||||||
"@azure/abort-controller": "^1.1.0",
|
|
||||||
"@azure/core-rest-pipeline": "^1.22.0",
|
"@azure/core-rest-pipeline": "^1.22.0",
|
||||||
"@azure/storage-blob": "^12.13.0",
|
"@azure/storage-blob": "^12.30.0",
|
||||||
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
||||||
"semver": "^6.3.1"
|
"semver": "^7.7.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@protobuf-ts/plugin": "^2.9.4",
|
"@protobuf-ts/plugin": "^2.9.4",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^25.1.0",
|
||||||
"@types/semver": "^6.0.0",
|
"@types/semver": "^7.7.1",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
"version": "2.0.1",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
|
||||||
"integrity": "sha512-oBfqT3GwkvLlo1fjvhQLQxuwZCGTarTE5OuZ2Wg10hvhBj7LRIlF611WT4aZS6fDhO5ZKlY7lCAZTlpmyaHaeg==",
|
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/http-client": "^3.0.0"
|
"@actions/http-client": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/exec": {
|
"node_modules/@actions/exec": {
|
||||||
"version": "2.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
|
||||||
"integrity": "sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw==",
|
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/io": "^2.0.0"
|
"@actions/io": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/glob": {
|
"node_modules/@actions/glob": {
|
||||||
"version": "0.5.0",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.6.1.tgz",
|
||||||
"integrity": "sha512-tST2rjPvJLRZLuT9NMUtyBjvj9Yo0MiJS3ow004slMvm8GFM+Zv9HvMJ7HWzfUyJnGrJvDsYkWBaaG3YKXRtCw==",
|
"integrity": "sha512-K4+2Ac5ILcf2ySdJCha+Pop9NcKjxqCL4xL4zI50dgB2PbXgC0+AcP011xfH4Of6b4QEJJg8dyZYv7zl4byTsw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.1",
|
"@actions/core": "^3.0.0",
|
||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/glob/node_modules/@actions/core": {
|
|
||||||
"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/exec": "^1.1.1",
|
|
||||||
"@actions/http-client": "^2.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@actions/glob/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/glob/node_modules/@actions/http-client": {
|
|
||||||
"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/@actions/glob/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/@actions/http-client": {
|
"node_modules/@actions/http-client": {
|
||||||
"version": "3.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
|
||||||
"integrity": "sha512-1s3tXAfVMSz9a4ZEBkXXRQD4QhY3+GAsWSbaYpeknPOKEeyRiU3lH+bHiLMZdo2x/fIeQ/hscL1wCkDLVM2DZQ==",
|
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6",
|
"tunnel": "^0.0.6",
|
||||||
"undici": "^5.28.5"
|
"undici": "^6.23.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/io": {
|
"node_modules/@actions/io": {
|
||||||
"version": "2.0.0",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
|
||||||
"integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==",
|
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@azure/abort-controller": {
|
"node_modules/@azure/abort-controller": {
|
||||||
"version": "1.1.0",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
||||||
"integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==",
|
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.2.0"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-auth": {
|
"node_modules/@azure/core-auth": {
|
||||||
@@ -133,18 +97,6 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-auth/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-client": {
|
"node_modules/@azure/core-client": {
|
||||||
"version": "1.10.1",
|
"version": "1.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz",
|
||||||
@@ -163,18 +115,6 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-client/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-http-compat": {
|
"node_modules/@azure/core-http-compat": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.1.tgz",
|
||||||
@@ -189,18 +129,6 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-lro": {
|
"node_modules/@azure/core-lro": {
|
||||||
"version": "2.7.2",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz",
|
||||||
@@ -216,18 +144,6 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-lro/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-paging": {
|
"node_modules/@azure/core-paging": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz",
|
||||||
@@ -258,18 +174,6 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-rest-pipeline/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-tracing": {
|
"node_modules/@azure/core-tracing": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz",
|
||||||
@@ -296,18 +200,6 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/core-util/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/core-xml": {
|
"node_modules/@azure/core-xml": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.5.0.tgz",
|
||||||
@@ -335,9 +227,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/storage-blob": {
|
"node_modules/@azure/storage-blob": {
|
||||||
"version": "12.29.1",
|
"version": "12.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.30.0.tgz",
|
||||||
"integrity": "sha512-7ktyY0rfTM0vo7HvtK6E3UvYnI9qfd6Oz6z/+92VhGRveWng3kJwMKeUpqmW/NmwcDNbxHpSlldG+vsUnRFnBg==",
|
"integrity": "sha512-peDCR8blSqhsAKDbpSP/o55S4sheNwSrblvCaHUZ5xUI73XA7ieUGGwrONgD/Fng0EoDe1VOa3fAQ7+WGB3Ocg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^2.1.2",
|
"@azure/abort-controller": "^2.1.2",
|
||||||
@@ -351,7 +243,7 @@
|
|||||||
"@azure/core-util": "^1.11.0",
|
"@azure/core-util": "^1.11.0",
|
||||||
"@azure/core-xml": "^1.4.5",
|
"@azure/core-xml": "^1.4.5",
|
||||||
"@azure/logger": "^1.1.4",
|
"@azure/logger": "^1.1.4",
|
||||||
"@azure/storage-common": "^12.1.1",
|
"@azure/storage-common": "^12.2.0",
|
||||||
"events": "^3.0.0",
|
"events": "^3.0.0",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
@@ -359,22 +251,10 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/storage-blob/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@azure/storage-common": {
|
"node_modules/@azure/storage-common": {
|
||||||
"version": "12.1.1",
|
"version": "12.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.2.0.tgz",
|
||||||
"integrity": "sha512-eIOH1pqFwI6UmVNnDQvmFeSg0XppuzDLFeUNO/Xht7ODAzRLgGDh7h550pSxoA+lPDxBl1+D2m/KG3jWzCUjTg==",
|
"integrity": "sha512-YZLxiJ3vBAAnFbG3TFuAMUlxZRexjQX5JDQxOkFGb6e2TpoxH3xyHI6idsMe/QrWtj41U/KoqBxlayzhS+LlwA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^2.1.2",
|
"@azure/abort-controller": "^2.1.2",
|
||||||
@@ -391,18 +271,6 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@azure/storage-common/node_modules/@azure/abort-controller": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@bufbuild/protobuf": {
|
"node_modules/@bufbuild/protobuf": {
|
||||||
"version": "2.10.1",
|
"version": "2.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.10.1.tgz",
|
||||||
@@ -436,15 +304,6 @@
|
|||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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/@protobuf-ts/plugin": {
|
"node_modules/@protobuf-ts/plugin": {
|
||||||
"version": "2.11.1",
|
"version": "2.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.1.tgz",
|
||||||
@@ -504,9 +363,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.10.2",
|
"version": "25.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz",
|
||||||
"integrity": "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==",
|
"integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -514,9 +373,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
"version": "6.2.7",
|
"version": "7.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
|
||||||
"integrity": "sha512-blctEWbzUFzQx799RZjzzIdBJOXmE37YYEyDtKkx5Dg+V7o/zyyAxLPiI98A2jdTtDgxZleMdfV+7p8WbRJ1OQ==",
|
"integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -667,12 +526,15 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "7.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/strnum": {
|
"node_modules/strnum": {
|
||||||
@@ -717,15 +579,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "5.29.0",
|
"version": "6.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
|
||||||
"@fastify/busboy": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0"
|
"node": ">=18.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
|
|||||||
Vendored
+20
-15
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/cache",
|
"name": "@actions/cache",
|
||||||
"version": "5.0.0",
|
"version": "6.0.0",
|
||||||
"preview": true,
|
|
||||||
"description": "Actions cache lib",
|
"description": "Actions cache lib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"github",
|
"github",
|
||||||
@@ -10,8 +9,15 @@
|
|||||||
],
|
],
|
||||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/cache",
|
"homepage": "https://github.com/actions/toolkit/tree/main/packages/cache",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
"main": "lib/cache.js",
|
"main": "lib/cache.js",
|
||||||
"types": "lib/cache.d.ts",
|
"types": "lib/cache.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./lib/cache.d.ts",
|
||||||
|
"import": "./lib/cache.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib",
|
"lib": "lib",
|
||||||
"test": "__tests__"
|
"test": "__tests__"
|
||||||
@@ -31,31 +37,30 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
|
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
|
||||||
"test": "echo \"Error: run tests from root\" && exit 1",
|
"test": "echo \"Error: run tests from root\" && exit 1",
|
||||||
"tsc": "tsc"
|
"tsc": "tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/actions/toolkit/issues"
|
"url": "https://github.com/actions/toolkit/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^2.0.0",
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.6.1",
|
||||||
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
"@actions/http-client": "^4.0.0",
|
||||||
"@actions/http-client": "^3.0.0",
|
"@actions/io": "^3.0.0",
|
||||||
"@actions/io": "^2.0.0",
|
|
||||||
"@azure/abort-controller": "^1.1.0",
|
|
||||||
"@azure/core-rest-pipeline": "^1.22.0",
|
"@azure/core-rest-pipeline": "^1.22.0",
|
||||||
"@azure/storage-blob": "^12.13.0",
|
"@azure/storage-blob": "^12.30.0",
|
||||||
"semver": "^6.3.1"
|
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
||||||
|
"semver": "^7.7.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.1.0",
|
|
||||||
"@types/semver": "^6.0.0",
|
|
||||||
"@protobuf-ts/plugin": "^2.9.4",
|
"@protobuf-ts/plugin": "^2.9.4",
|
||||||
|
"@types/node": "^25.1.0",
|
||||||
|
"@types/semver": "^7.7.1",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"uri-js": "npm:uri-js-replace@^1.0.1",
|
"uri-js": "npm:uri-js-replace@^1.0.1",
|
||||||
"node-fetch": "^3.3.2"
|
"node-fetch": "^3.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+9
-7
@@ -1,18 +1,20 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as utils from './internal/cacheUtils'
|
import * as utils from './internal/cacheUtils.js'
|
||||||
import * as cacheHttpClient from './internal/cacheHttpClient'
|
import * as cacheHttpClient from './internal/cacheHttpClient.js'
|
||||||
import * as cacheTwirpClient from './internal/shared/cacheTwirpClient'
|
import * as cacheTwirpClient from './internal/shared/cacheTwirpClient.js'
|
||||||
import {getCacheServiceVersion, isGhes} from './internal/config'
|
import {getCacheServiceVersion, isGhes} from './internal/config.js'
|
||||||
import {DownloadOptions, UploadOptions} from './options'
|
import {DownloadOptions, UploadOptions} from './options.js'
|
||||||
import {createTar, extractTar, listTar} from './internal/tar'
|
import {createTar, extractTar, listTar} from './internal/tar.js'
|
||||||
import {
|
import {
|
||||||
CreateCacheEntryRequest,
|
CreateCacheEntryRequest,
|
||||||
FinalizeCacheEntryUploadRequest,
|
FinalizeCacheEntryUploadRequest,
|
||||||
FinalizeCacheEntryUploadResponse,
|
FinalizeCacheEntryUploadResponse,
|
||||||
GetCacheEntryDownloadURLRequest
|
GetCacheEntryDownloadURLRequest
|
||||||
} from './generated/results/api/v1/cache'
|
} from './generated/results/api/v1/cache.js'
|
||||||
import {HttpClientError} from '@actions/http-client'
|
import {HttpClientError} from '@actions/http-client'
|
||||||
|
|
||||||
|
export type {DownloadOptions, UploadOptions}
|
||||||
export class ValidationError extends Error {
|
export class ValidationError extends Error {
|
||||||
constructor(message: string) {
|
constructor(message: string) {
|
||||||
super(message)
|
super(message)
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
|
|||||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||||
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
||||||
import { MessageType } from "@protobuf-ts/runtime";
|
import { MessageType } from "@protobuf-ts/runtime";
|
||||||
import { CacheMetadata } from "../../entities/v1/cachemetadata";
|
import { CacheMetadata } from "../../entities/v1/cachemetadata.js";
|
||||||
/**
|
/**
|
||||||
* @generated from protobuf message github.actions.results.api.v1.CreateCacheEntryRequest
|
* @generated from protobuf message github.actions.results.api.v1.CreateCacheEntryRequest
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
FinalizeCacheEntryUploadResponse,
|
FinalizeCacheEntryUploadResponse,
|
||||||
GetCacheEntryDownloadURLRequest,
|
GetCacheEntryDownloadURLRequest,
|
||||||
GetCacheEntryDownloadURLResponse,
|
GetCacheEntryDownloadURLResponse,
|
||||||
} from "./cache";
|
} from "./cache.js";
|
||||||
|
|
||||||
//==================================//
|
//==================================//
|
||||||
// Client Code //
|
// Client Code //
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import type { PartialMessage } from "@protobuf-ts/runtime";
|
|||||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||||
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
||||||
import { MessageType } from "@protobuf-ts/runtime";
|
import { MessageType } from "@protobuf-ts/runtime";
|
||||||
import { CacheScope } from "./cachescope";
|
import { CacheScope } from "./cachescope.js";
|
||||||
/**
|
/**
|
||||||
* @generated from protobuf message github.actions.results.entities.v1.CacheMetadata
|
* @generated from protobuf message github.actions.results.entities.v1.CacheMetadata
|
||||||
*/
|
*/
|
||||||
|
|||||||
+8
-8
@@ -7,8 +7,8 @@ import {
|
|||||||
} from '@actions/http-client/lib/interfaces'
|
} from '@actions/http-client/lib/interfaces'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import {URL} from 'url'
|
import {URL} from 'url'
|
||||||
import * as utils from './cacheUtils'
|
import * as utils from './cacheUtils.js'
|
||||||
import {uploadCacheArchiveSDK} from './uploadUtils'
|
import {uploadCacheArchiveSDK} from './uploadUtils.js'
|
||||||
import {
|
import {
|
||||||
ArtifactCacheEntry,
|
ArtifactCacheEntry,
|
||||||
InternalCacheOptions,
|
InternalCacheOptions,
|
||||||
@@ -17,25 +17,25 @@ import {
|
|||||||
ReserveCacheResponse,
|
ReserveCacheResponse,
|
||||||
ITypedResponseWithError,
|
ITypedResponseWithError,
|
||||||
ArtifactCacheList
|
ArtifactCacheList
|
||||||
} from './contracts'
|
} from './contracts.js'
|
||||||
import {
|
import {
|
||||||
downloadCacheHttpClient,
|
downloadCacheHttpClient,
|
||||||
downloadCacheHttpClientConcurrent,
|
downloadCacheHttpClientConcurrent,
|
||||||
downloadCacheStorageSDK
|
downloadCacheStorageSDK
|
||||||
} from './downloadUtils'
|
} from './downloadUtils.js'
|
||||||
import {
|
import {
|
||||||
DownloadOptions,
|
DownloadOptions,
|
||||||
UploadOptions,
|
UploadOptions,
|
||||||
getDownloadOptions,
|
getDownloadOptions,
|
||||||
getUploadOptions
|
getUploadOptions
|
||||||
} from '../options'
|
} from '../options.js'
|
||||||
import {
|
import {
|
||||||
isSuccessStatusCode,
|
isSuccessStatusCode,
|
||||||
retryHttpClientResponse,
|
retryHttpClientResponse,
|
||||||
retryTypedResponse
|
retryTypedResponse
|
||||||
} from './requestUtils'
|
} from './requestUtils.js'
|
||||||
import {getCacheServiceURL} from './config'
|
import {getCacheServiceURL} from './config.js'
|
||||||
import {getUserAgentString} from './shared/user-agent'
|
import {getUserAgentString} from './shared/user-agent.js'
|
||||||
|
|
||||||
function getCacheApiUrl(resource: string): string {
|
function getCacheApiUrl(resource: string): string {
|
||||||
const baseUrl: string = getCacheServiceURL()
|
const baseUrl: string = getCacheServiceURL()
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
|||||||
CacheFilename,
|
CacheFilename,
|
||||||
CompressionMethod,
|
CompressionMethod,
|
||||||
GnuTarPathOnWindows
|
GnuTarPathOnWindows
|
||||||
} from './constants'
|
} from './constants.js'
|
||||||
|
|
||||||
const versionSalt = '1.0'
|
const versionSalt = '1.0'
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import {CompressionMethod} from './constants'
|
import {CompressionMethod} from './constants.js'
|
||||||
import {TypedResponse} from '@actions/http-client/lib/interfaces'
|
import {TypedResponse} from '@actions/http-client/lib/interfaces'
|
||||||
import {HttpClientError} from '@actions/http-client'
|
import {HttpClientError} from '@actions/http-client'
|
||||||
|
|
||||||
+4
-6
@@ -7,12 +7,10 @@ import * as fs from 'fs'
|
|||||||
import * as stream from 'stream'
|
import * as stream from 'stream'
|
||||||
import * as util from 'util'
|
import * as util from 'util'
|
||||||
|
|
||||||
import * as utils from './cacheUtils'
|
import * as utils from './cacheUtils.js'
|
||||||
import {SocketTimeout} from './constants'
|
import {SocketTimeout} from './constants.js'
|
||||||
import {DownloadOptions} from '../options'
|
import {DownloadOptions} from '../options.js'
|
||||||
import {retryHttpClientResponse} from './requestUtils'
|
import {retryHttpClientResponse} from './requestUtils.js'
|
||||||
|
|
||||||
import {AbortController} from '@azure/abort-controller'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pipes the body of a HTTP response to a stream
|
* Pipes the body of a HTTP response to a stream
|
||||||
|
|||||||
+2
-2
@@ -4,8 +4,8 @@ import {
|
|||||||
HttpClientError,
|
HttpClientError,
|
||||||
HttpClientResponse
|
HttpClientResponse
|
||||||
} from '@actions/http-client'
|
} from '@actions/http-client'
|
||||||
import {DefaultRetryDelay, DefaultRetryAttempts} from './constants'
|
import {DefaultRetryDelay, DefaultRetryAttempts} from './constants.js'
|
||||||
import {ITypedResponseWithError} from './contracts'
|
import {ITypedResponseWithError} from './contracts.js'
|
||||||
|
|
||||||
export function isSuccessStatusCode(statusCode?: number): boolean {
|
export function isSuccessStatusCode(statusCode?: number): boolean {
|
||||||
if (!statusCode) {
|
if (!statusCode) {
|
||||||
|
|||||||
+27
-9
@@ -1,12 +1,12 @@
|
|||||||
import {info, debug} from '@actions/core'
|
import {info, debug, warning} from '@actions/core'
|
||||||
import {getUserAgentString} from './user-agent'
|
import {getUserAgentString} from './user-agent.js'
|
||||||
import {NetworkError, UsageError} from './errors'
|
import {NetworkError, RateLimitError, UsageError} from './errors.js'
|
||||||
import {getCacheServiceURL} from '../config'
|
import {getCacheServiceURL} from '../config.js'
|
||||||
import {getRuntimeToken} from '../cacheUtils'
|
import {getRuntimeToken} from '../cacheUtils.js'
|
||||||
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
||||||
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
|
import {HttpClient, HttpClientResponse, HttpCodes} from '@actions/http-client'
|
||||||
import {CacheServiceClientJSON} from '../../generated/results/api/v1/cache.twirp-client'
|
import {CacheServiceClientJSON} from '../../generated/results/api/v1/cache.twirp-client.js'
|
||||||
import {maskSecretUrls} from './util'
|
import {maskSecretUrls} from './util.js'
|
||||||
|
|
||||||
// The twirp http client must implement this interface
|
// The twirp http client must implement this interface
|
||||||
interface Rpc {
|
interface Rpc {
|
||||||
@@ -109,6 +109,21 @@ class CacheServiceClient implements Rpc {
|
|||||||
|
|
||||||
errorMessage = `${errorMessage}: ${body.msg}`
|
errorMessage = `${errorMessage}: ${body.msg}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle rate limiting - don't retry, just warn and exit
|
||||||
|
// For more info, see https://docs.github.com/en/actions/reference/limits
|
||||||
|
if (statusCode === HttpCodes.TooManyRequests) {
|
||||||
|
const retryAfterHeader = response.message.headers['retry-after']
|
||||||
|
if (retryAfterHeader) {
|
||||||
|
const parsedSeconds = parseInt(retryAfterHeader, 10)
|
||||||
|
if (!isNaN(parsedSeconds) && parsedSeconds > 0) {
|
||||||
|
warning(
|
||||||
|
`You've hit a rate limit, your rate limit will reset in ${parsedSeconds} seconds`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RateLimitError(`Rate limited: ${errorMessage}`)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof SyntaxError) {
|
if (error instanceof SyntaxError) {
|
||||||
debug(`Raw Body: ${rawBody}`)
|
debug(`Raw Body: ${rawBody}`)
|
||||||
@@ -118,6 +133,10 @@ class CacheServiceClient implements Rpc {
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error instanceof RateLimitError) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
if (NetworkError.isNetworkErrorCode(error?.code)) {
|
if (NetworkError.isNetworkErrorCode(error?.code)) {
|
||||||
throw new NetworkError(error?.code)
|
throw new NetworkError(error?.code)
|
||||||
}
|
}
|
||||||
@@ -162,8 +181,7 @@ class CacheServiceClient implements Rpc {
|
|||||||
HttpCodes.BadGateway,
|
HttpCodes.BadGateway,
|
||||||
HttpCodes.GatewayTimeout,
|
HttpCodes.GatewayTimeout,
|
||||||
HttpCodes.InternalServerError,
|
HttpCodes.InternalServerError,
|
||||||
HttpCodes.ServiceUnavailable,
|
HttpCodes.ServiceUnavailable
|
||||||
HttpCodes.TooManyRequests
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return retryableStatusCodes.includes(statusCode)
|
return retryableStatusCodes.includes(statusCode)
|
||||||
|
|||||||
+8
-1
@@ -60,7 +60,7 @@ export class NetworkError extends Error {
|
|||||||
|
|
||||||
export class UsageError extends Error {
|
export class UsageError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
const message = `Cache storage quota has been hit. Unable to upload any new cache entries. Usage is recalculated every 6-12 hours.\nMore info on storage limits: https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#calculating-minute-and-storage-spending`
|
const message = `Cache storage quota has been hit. Unable to upload any new cache entries.\nMore info on storage limits: https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#calculating-minute-and-storage-spending`
|
||||||
super(message)
|
super(message)
|
||||||
this.name = 'UsageError'
|
this.name = 'UsageError'
|
||||||
}
|
}
|
||||||
@@ -70,3 +70,10 @@ export class UsageError extends Error {
|
|||||||
return msg.includes('insufficient usage')
|
return msg.includes('insufficient usage')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RateLimitError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message)
|
||||||
|
this.name = 'RateLimitError'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// This file exists as a CommonJS module to read the version from package.json.
|
||||||
|
// In an ESM package, using `require()` directly in .ts files requires disabling
|
||||||
|
// ESLint rules and doesn't work reliably across all Node.js versions.
|
||||||
|
// By keeping this as a .cjs file, we can use require() naturally and export
|
||||||
|
// the version for the ESM modules to import.
|
||||||
|
const packageJson = require('../../../package.json')
|
||||||
|
module.exports = { version: packageJson.version }
|
||||||
+2
-3
@@ -1,9 +1,8 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
import {version} from './package-version.cjs'
|
||||||
const packageJson = require('../../../package.json')
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that this User Agent String is used in all HTTP calls so that we can monitor telemetry between different versions of this package
|
* Ensure that this User Agent String is used in all HTTP calls so that we can monitor telemetry between different versions of this package
|
||||||
*/
|
*/
|
||||||
export function getUserAgentString(): string {
|
export function getUserAgentString(): string {
|
||||||
return `@actions/cache-${packageJson.version}`
|
return `@actions/cache-${version}`
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -2,15 +2,15 @@ import {exec} from '@actions/exec'
|
|||||||
import * as io from '@actions/io'
|
import * as io from '@actions/io'
|
||||||
import {existsSync, writeFileSync} from 'fs'
|
import {existsSync, writeFileSync} from 'fs'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as utils from './cacheUtils'
|
import * as utils from './cacheUtils.js'
|
||||||
import {ArchiveTool} from './contracts'
|
import {ArchiveTool} from './contracts.js'
|
||||||
import {
|
import {
|
||||||
CompressionMethod,
|
CompressionMethod,
|
||||||
SystemTarPathOnWindows,
|
SystemTarPathOnWindows,
|
||||||
ArchiveToolType,
|
ArchiveToolType,
|
||||||
TarFilename,
|
TarFilename,
|
||||||
ManifestFilename
|
ManifestFilename
|
||||||
} from './constants'
|
} from './constants.js'
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32'
|
const IS_WINDOWS = process.platform === 'win32'
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@ import {
|
|||||||
BlockBlobParallelUploadOptions
|
BlockBlobParallelUploadOptions
|
||||||
} from '@azure/storage-blob'
|
} from '@azure/storage-blob'
|
||||||
import {TransferProgressEvent} from '@azure/core-rest-pipeline'
|
import {TransferProgressEvent} from '@azure/core-rest-pipeline'
|
||||||
import {InvalidResponseError} from './shared/errors'
|
import {InvalidResponseError} from './shared/errors.js'
|
||||||
import {UploadOptions} from '../options'
|
import {UploadOptions} from '../options.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for tracking the upload state and displaying stats.
|
* Class for tracking the upload state and displaying stats.
|
||||||
|
|||||||
Vendored
+2
@@ -4,6 +4,8 @@
|
|||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
|
"module": "node16",
|
||||||
|
"moduleResolution": "node16",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es6",
|
"es6",
|
||||||
"dom"
|
"dom"
|
||||||
|
|||||||
@@ -1,70 +1,103 @@
|
|||||||
# @actions/core Releases
|
# @actions/core Releases
|
||||||
|
|
||||||
|
## 3.0.1
|
||||||
|
|
||||||
|
- Bump `undici` from `6.23.0` to `6.24.1` [#2348](https://github.com/actions/toolkit/pull/2348)
|
||||||
|
|
||||||
|
## 3.0.0
|
||||||
|
|
||||||
|
- **Breaking change**: Package is now ESM-only
|
||||||
|
- CommonJS consumers must use dynamic `import()` instead of `require()`
|
||||||
|
|
||||||
|
## 2.0.3
|
||||||
|
|
||||||
|
- Bump `@actions/http-client` to `3.0.2`
|
||||||
|
|
||||||
## 2.0.1
|
## 2.0.1
|
||||||
|
|
||||||
- Bump @actions/exec from 1.1.1 to 2.0.0 [#2199](https://github.com/actions/toolkit/pull/2199)
|
- Bump @actions/exec from 1.1.1 to 2.0.0 [#2199](https://github.com/actions/toolkit/pull/2199)
|
||||||
|
|
||||||
## 2.0.0
|
## 2.0.0
|
||||||
|
|
||||||
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
- Add support for Node 24 [#2110](https://github.com/actions/toolkit/pull/2110)
|
||||||
- Bump @actions/http-client from 2.0.1 to 3.0.0
|
- Bump @actions/http-client from 2.0.1 to 3.0.0
|
||||||
|
|
||||||
## 1.11.1
|
## 1.11.1
|
||||||
|
|
||||||
- Fix uses of `crypto.randomUUID` on Node 18 and earlier [#1842](https://github.com/actions/toolkit/pull/1842)
|
- Fix uses of `crypto.randomUUID` on Node 18 and earlier [#1842](https://github.com/actions/toolkit/pull/1842)
|
||||||
|
|
||||||
### 1.11.0
|
### 1.11.0
|
||||||
|
|
||||||
- Add platform info utilities [#1551](https://github.com/actions/toolkit/pull/1551)
|
- Add platform info utilities [#1551](https://github.com/actions/toolkit/pull/1551)
|
||||||
- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824)
|
- Remove dependency on `uuid` package [#1824](https://github.com/actions/toolkit/pull/1824)
|
||||||
|
|
||||||
### 1.10.1
|
### 1.10.1
|
||||||
|
|
||||||
- Fix error message reference in oidc utils [#1511](https://github.com/actions/toolkit/pull/1511)
|
- Fix error message reference in oidc utils [#1511](https://github.com/actions/toolkit/pull/1511)
|
||||||
|
|
||||||
### 1.10.0
|
### 1.10.0
|
||||||
|
|
||||||
- `saveState` and `setOutput` now use environment files if available [#1178](https://github.com/actions/toolkit/pull/1178)
|
- `saveState` and `setOutput` now use environment files if available [#1178](https://github.com/actions/toolkit/pull/1178)
|
||||||
- `getMultilineInput` now correctly trims whitespace by default [#1185](https://github.com/actions/toolkit/pull/1185)
|
- `getMultilineInput` now correctly trims whitespace by default [#1185](https://github.com/actions/toolkit/pull/1185)
|
||||||
|
|
||||||
### 1.9.1
|
### 1.9.1
|
||||||
|
|
||||||
- Randomize delimiter when calling `core.exportVariable`
|
- Randomize delimiter when calling `core.exportVariable`
|
||||||
|
|
||||||
### 1.9.0
|
### 1.9.0
|
||||||
|
|
||||||
- Added `toPosixPath`, `toWin32Path` and `toPlatformPath` utilities [#1102](https://github.com/actions/toolkit/pull/1102)
|
- Added `toPosixPath`, `toWin32Path` and `toPlatformPath` utilities [#1102](https://github.com/actions/toolkit/pull/1102)
|
||||||
|
|
||||||
### 1.8.2
|
### 1.8.2
|
||||||
|
|
||||||
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
|
- Update to v2.0.1 of `@actions/http-client` [#1087](https://github.com/actions/toolkit/pull/1087)
|
||||||
|
|
||||||
### 1.8.1
|
### 1.8.1
|
||||||
|
|
||||||
- Update to v2.0.0 of `@actions/http-client`
|
- Update to v2.0.0 of `@actions/http-client`
|
||||||
|
|
||||||
### 1.8.0
|
### 1.8.0
|
||||||
|
|
||||||
- Deprecate `markdownSummary` extension export in favor of `summary`
|
- Deprecate `markdownSummary` extension export in favor of `summary`
|
||||||
- https://github.com/actions/toolkit/pull/1072
|
- <https://github.com/actions/toolkit/pull/1072>
|
||||||
- https://github.com/actions/toolkit/pull/1073
|
- <https://github.com/actions/toolkit/pull/1073>
|
||||||
|
|
||||||
### 1.7.0
|
### 1.7.0
|
||||||
|
|
||||||
- [Added `markdownSummary` extension](https://github.com/actions/toolkit/pull/1014)
|
- [Added `markdownSummary` extension](https://github.com/actions/toolkit/pull/1014)
|
||||||
|
|
||||||
### 1.6.0
|
### 1.6.0
|
||||||
|
|
||||||
- [Added OIDC Client function `getIDToken`](https://github.com/actions/toolkit/pull/919)
|
- [Added OIDC Client function `getIDToken`](https://github.com/actions/toolkit/pull/919)
|
||||||
- [Added `file` parameter to `AnnotationProperties`](https://github.com/actions/toolkit/pull/896)
|
- [Added `file` parameter to `AnnotationProperties`](https://github.com/actions/toolkit/pull/896)
|
||||||
|
|
||||||
### 1.5.0
|
### 1.5.0
|
||||||
|
|
||||||
- [Added support for notice annotations and more annotation fields](https://github.com/actions/toolkit/pull/855)
|
- [Added support for notice annotations and more annotation fields](https://github.com/actions/toolkit/pull/855)
|
||||||
|
|
||||||
### 1.4.0
|
### 1.4.0
|
||||||
|
|
||||||
- [Added the `getMultilineInput` function](https://github.com/actions/toolkit/pull/829)
|
- [Added the `getMultilineInput` function](https://github.com/actions/toolkit/pull/829)
|
||||||
|
|
||||||
### 1.3.0
|
### 1.3.0
|
||||||
|
|
||||||
- [Added the trimWhitespace option to getInput](https://github.com/actions/toolkit/pull/802)
|
- [Added the trimWhitespace option to getInput](https://github.com/actions/toolkit/pull/802)
|
||||||
- [Added the getBooleanInput function](https://github.com/actions/toolkit/pull/725)
|
- [Added the getBooleanInput function](https://github.com/actions/toolkit/pull/725)
|
||||||
|
|
||||||
### 1.2.7
|
### 1.2.7
|
||||||
|
|
||||||
- [Prepend newline for set-output](https://github.com/actions/toolkit/pull/772)
|
- [Prepend newline for set-output](https://github.com/actions/toolkit/pull/772)
|
||||||
|
|
||||||
### 1.2.6
|
### 1.2.6
|
||||||
|
|
||||||
- [Update `exportVariable` and `addPath` to use environment files](https://github.com/actions/toolkit/pull/571)
|
- [Update `exportVariable` and `addPath` to use environment files](https://github.com/actions/toolkit/pull/571)
|
||||||
|
|
||||||
### 1.2.5
|
### 1.2.5
|
||||||
|
|
||||||
- [Correctly bundle License File with package](https://github.com/actions/toolkit/pull/548)
|
- [Correctly bundle License File with package](https://github.com/actions/toolkit/pull/548)
|
||||||
|
|
||||||
### 1.2.4
|
### 1.2.4
|
||||||
|
|
||||||
- [Be more lenient in accepting non-string command inputs](https://github.com/actions/toolkit/pull/405)
|
- [Be more lenient in accepting non-string command inputs](https://github.com/actions/toolkit/pull/405)
|
||||||
- [Add Echo commands](https://github.com/actions/toolkit/pull/411)
|
- [Add Echo commands](https://github.com/actions/toolkit/pull/411)
|
||||||
|
|
||||||
@@ -85,7 +118,7 @@
|
|||||||
|
|
||||||
- saveState and getState functions for wrapper tasks (on finally entry points that run post job)
|
- saveState and getState functions for wrapper tasks (on finally entry points that run post job)
|
||||||
|
|
||||||
### 1.1.3
|
### 1.1.3
|
||||||
|
|
||||||
- setSecret added to register a secret with the runner to be masked from the logs
|
- setSecret added to register a secret with the runner to be masked from the logs
|
||||||
- exportSecret which was not implemented and never worked was removed after clarification from product.
|
- exportSecret which was not implemented and never worked was removed after clarification from product.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as command from '../src/command'
|
import * as command from '../src/command.js'
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
/* eslint-disable @typescript-eslint/unbound-method */
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as core from '../src/core'
|
import * as core from '../src/core.js'
|
||||||
import {HttpClient} from '@actions/http-client'
|
import {HttpClient} from '@actions/http-client'
|
||||||
import {toCommandProperties} from '../src/utils'
|
import {toCommandProperties} from '../src/utils.js'
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
/* eslint-disable @typescript-eslint/unbound-method */
|
||||||
|
|
||||||
@@ -677,5 +677,8 @@ describe('oidc-client-tests', () => {
|
|||||||
const http = new HttpClient('actions/oidc-client')
|
const http = new HttpClient('actions/oidc-client')
|
||||||
const res = await http.get(getTokenEndPoint())
|
const res = await http.get(getTokenEndPoint())
|
||||||
expect(res.message.statusCode).toBe(200)
|
expect(res.message.statusCode).toBe(200)
|
||||||
|
// Consume the response to close the socket
|
||||||
|
await res.readBody()
|
||||||
|
res.message.destroy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
|
||||||
import {toPlatformPath, toPosixPath, toWin32Path} from '../src/path-utils'
|
import {toPlatformPath, toPosixPath, toWin32Path} from '../src/path-utils.js'
|
||||||
|
|
||||||
describe('#toPosixPath', () => {
|
describe('#toPosixPath', () => {
|
||||||
const cases: {
|
const cases: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import os from 'os'
|
import os from 'os'
|
||||||
import {platform} from '../src/core'
|
import {platform} from '../src/core.js'
|
||||||
|
|
||||||
describe('getInfo', () => {
|
describe('getInfo', () => {
|
||||||
it('returns the platform info', async () => {
|
it('returns the platform info', async () => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import {summary, SUMMARY_ENV_VAR} from '../src/summary'
|
import {summary, SUMMARY_ENV_VAR} from '../src/summary.js'
|
||||||
|
|
||||||
const testDirectoryPath = path.join(__dirname, 'test')
|
const testDirectoryPath = path.join(__dirname, 'test')
|
||||||
const testFilePath = path.join(testDirectoryPath, 'test-summary.md')
|
const testFilePath = path.join(testDirectoryPath, 'test-summary.md')
|
||||||
|
|||||||
Generated
+34
-36
@@ -1,61 +1,55 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/core",
|
"name": "@actions/core",
|
||||||
"version": "2.0.1",
|
"version": "3.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@actions/core",
|
"name": "@actions/core",
|
||||||
"version": "2.0.1",
|
"version": "3.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/http-client": "^3.0.0"
|
"@actions/http-client": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.18.112"
|
"@types/node": "^25.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/exec": {
|
"node_modules/@actions/exec": {
|
||||||
"version": "2.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
|
||||||
"integrity": "sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw==",
|
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/io": "^2.0.0"
|
"@actions/io": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/http-client": {
|
"node_modules/@actions/http-client": {
|
||||||
"version": "3.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
|
||||||
"integrity": "sha512-1s3tXAfVMSz9a4ZEBkXXRQD4QhY3+GAsWSbaYpeknPOKEeyRiU3lH+bHiLMZdo2x/fIeQ/hscL1wCkDLVM2DZQ==",
|
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6",
|
"tunnel": "^0.0.6",
|
||||||
"undici": "^5.28.5"
|
"undici": "^6.23.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/io": {
|
"node_modules/@actions/io": {
|
||||||
"version": "2.0.0",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
|
||||||
"integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==",
|
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==",
|
||||||
"license": "MIT"
|
"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/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "16.18.126",
|
"version": "25.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz",
|
||||||
"integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==",
|
"integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~7.16.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tunnel": {
|
"node_modules/tunnel": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
@@ -67,16 +61,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "5.29.0",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
|
||||||
"@fastify/busboy": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0"
|
"node": ">=18.17"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "7.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||||
|
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/core",
|
"name": "@actions/core",
|
||||||
"version": "2.0.1",
|
"version": "3.0.1",
|
||||||
"description": "Actions core lib",
|
"description": "Actions core lib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"github",
|
"github",
|
||||||
@@ -9,8 +9,15 @@
|
|||||||
],
|
],
|
||||||
"homepage": "https://github.com/actions/toolkit/tree/main/packages/core",
|
"homepage": "https://github.com/actions/toolkit/tree/main/packages/core",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
"main": "lib/core.js",
|
"main": "lib/core.js",
|
||||||
"types": "lib/core.d.ts",
|
"types": "lib/core.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./lib/core.d.ts",
|
||||||
|
"import": "./lib/core.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib",
|
"lib": "lib",
|
||||||
"test": "__tests__"
|
"test": "__tests__"
|
||||||
@@ -36,10 +43,10 @@
|
|||||||
"url": "https://github.com/actions/toolkit/issues"
|
"url": "https://github.com/actions/toolkit/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/http-client": "^3.0.0"
|
"@actions/http-client": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.18.112"
|
"@types/node": "^25.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import {toCommandValue} from './utils'
|
import {toCommandValue} from './utils.js'
|
||||||
|
|
||||||
// For internal use, subject to change.
|
// For internal use, subject to change.
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {issue, issueCommand} from './command'
|
import {issue, issueCommand} from './command.js'
|
||||||
import {issueFileCommand, prepareKeyValueMessage} from './file-command'
|
import {issueFileCommand, prepareKeyValueMessage} from './file-command.js'
|
||||||
import {toCommandProperties, toCommandValue} from './utils'
|
import {toCommandProperties, toCommandValue} from './utils.js'
|
||||||
|
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
|
||||||
import {OidcClient} from './oidc-utils'
|
import {OidcClient} from './oidc-utils.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for getInput options
|
* Interface for getInput options
|
||||||
@@ -400,19 +400,19 @@ export async function getIDToken(aud?: string): Promise<string> {
|
|||||||
/**
|
/**
|
||||||
* Summary exports
|
* Summary exports
|
||||||
*/
|
*/
|
||||||
export {summary} from './summary'
|
export {summary} from './summary.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use core.summary
|
* @deprecated use core.summary
|
||||||
*/
|
*/
|
||||||
export {markdownSummary} from './summary'
|
export {markdownSummary} from './summary.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path exports
|
* Path exports
|
||||||
*/
|
*/
|
||||||
export {toPosixPath, toWin32Path, toPlatformPath} from './path-utils'
|
export {toPosixPath, toWin32Path, toPlatformPath} from './path-utils.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Platform utilities exports
|
* Platform utilities exports
|
||||||
*/
|
*/
|
||||||
export * as platform from './platform'
|
export * as platform from './platform.js'
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import {toCommandValue} from './utils'
|
import {toCommandValue} from './utils.js'
|
||||||
|
|
||||||
export function issueFileCommand(command: string, message: any): void {
|
export function issueFileCommand(command: string, message: any): void {
|
||||||
const filePath = process.env[`GITHUB_${command}`]
|
const filePath = process.env[`GITHUB_${command}`]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as actions_http_client from '@actions/http-client'
|
|||||||
import {RequestOptions} from '@actions/http-client/lib/interfaces'
|
import {RequestOptions} from '@actions/http-client/lib/interfaces'
|
||||||
import {HttpClient} from '@actions/http-client'
|
import {HttpClient} from '@actions/http-client'
|
||||||
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
import {BearerCredentialHandler} from '@actions/http-client/lib/auth'
|
||||||
import {debug, setSecret} from './core'
|
import {debug, setSecret} from './core.js'
|
||||||
interface TokenResponse {
|
interface TokenResponse {
|
||||||
value?: string
|
value?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// We use any as a valid input type
|
// We use any as a valid input type
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
import {AnnotationProperties} from './core'
|
import {AnnotationProperties} from './core.js'
|
||||||
import {CommandProperties} from './command'
|
import {CommandProperties} from './command.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"rootDir": "./src"
|
"rootDir": "./src",
|
||||||
|
"module": "node16",
|
||||||
|
"moduleResolution": "node16"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src"
|
"./src"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user