Compare commits

..
Author SHA1 Message Date
Ferenc Hammerl c359bfc506 Refactor test to run status codes 1 by 1 2022-12-13 14:20:28 +01:00
John Sudol e6109ecebb fix the audit tool-cache 2022-12-12 16:50:05 +00:00
John Sudol 5e6e2cdba2 Update artifact-tests.yml
remove some logs
2022-12-12 11:36:53 -05:00
John Sudol 2bea83c054 Update artifact-tests.yml
add single quotes to the env variables
2022-12-12 11:33:33 -05:00
John Sudol 942b3c6ec4 Update artifact-tests.yml
Back to Node 16, and bring back the custom fix for windows
2022-12-12 11:19:25 -05:00
John Sudol 31d5189ce1 Update artifact-tests.yml
undo script change
2022-12-10 13:16:41 -05:00
John Sudol e2f44eee2e Update artifact-tests.yml
Try node 18
2022-12-10 13:13:22 -05:00
John Sudol 2e69cc8c9e Update artifact-tests.yml
add some cats
2022-12-09 16:30:13 -05:00
John Sudol 39cdb45e15 Update artifact-tests.yml 2022-12-09 16:24:49 -05:00
John Sudol 0e4c2ef668 Update artifact-tests.yml
add some logging
2022-12-09 16:21:30 -05:00
John Sudol 7eacd46cff Update artifact-tests.yml
actually fix the workflow
2022-12-09 15:53:36 -05:00
John Sudol 2aae61e64a Update artifact-tests.yml
use process.argv[1] instead
2022-12-09 15:49:59 -05:00
John Sudol e1ffeb8e81 Update artifact-tests.yml
flip the single and double quote
2022-12-09 15:22:41 -05:00
John Sudol 4a1742d242 Update artifact-tests.yml
add backticks to the github.workspace
2022-12-09 15:11:09 -05:00
John Sudol 52ebfde634 debug the directory 2022-12-09 20:03:35 +00:00
John Sudol 734c3adc09 bump actions/core in artifact 2022-12-09 17:28:24 +00:00
John Sudol 57ee33c9cd bump test action node version 2022-12-08 16:44:27 +00:00
John Sudol 894df20102 bump to node 16 2022-12-08 16:30:40 +00:00
Ferenc Hammerl bc15eb10af Check npm version 2022-11-04 15:51:17 +00:00
Ferenc Hammerl 640db317cb Try node v14 2022-11-04 15:42:08 +00:00
Ferenc Hammerl 4e3720ed97 Remove npm patching 2022-11-04 11:31:58 +00:00
Ferenc Hammerl 086231c43a Update setup-node to v3 2022-11-04 11:26:42 +00:00
Ferenc Hammerl 92c2d702e5 Use checkout v3 2022-11-04 11:23:24 +00:00
Ferenc Hammerl 8550e77f38 Use node16 2022-11-04 11:23:04 +00:00
Ferenc Hammerl eda924b207 Fix formatting 2022-11-04 11:18:58 +00:00
Ferenc Hammerl dee747db33 Try older node version 2022-11-02 10:37:38 +00:00
Ferenc Hammerl 580da8ec8b Fix actions/cache 2022-11-01 19:29:59 +00:00
Ferenc Hammerl f8d90ef5be Fix glob audit 2022-11-01 17:13:58 +00:00
Ferenc Hammerl c147b96f55 Downgrade Lerna 2022-11-01 17:08:50 +00:00
Ferenc Hammerl a12b7eef44 Bump lerna major version 2022-11-01 17:06:59 +00:00
Ferenc Hammerl d4c6abaad1 Udpate npm versions 2022-11-01 17:01:13 +00:00
Ferenc Hammerl 698f089b86 Bump workflows node versions 2022-11-01 16:51:40 +00:00
245 changed files with 31903 additions and 34235 deletions
-1
View File
@@ -2,4 +2,3 @@ node_modules/
packages/*/node_modules/ packages/*/node_modules/
packages/*/lib/ packages/*/lib/
packages/glob/__tests__/_temp packages/glob/__tests__/_temp
packages/*/src/generated/*/
+7 -44
View File
@@ -1,13 +1,6 @@
{ {
"plugins": [ "plugins": ["jest", "@typescript-eslint"],
"jest", "extends": ["plugin:github/recommended"],
"@typescript-eslint",
"prettier"
],
"extends": [
"plugin:github/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
"ecmaVersion": 9, "ecmaVersion": 9,
@@ -15,33 +8,14 @@
"project": "./tsconfig.eslint.json" "project": "./tsconfig.eslint.json"
}, },
"rules": { "rules": {
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
],
"eslint-comments/no-use": "off", "eslint-comments/no-use": "off",
"no-constant-condition": ["error", { "checkLoops": false }],
"github/no-then": "off", "github/no-then": "off",
"import/no-namespace": "off", "import/no-namespace": "off",
"no-shadow": "off", "no-shadow": "off",
"no-unused-vars": "off", "no-unused-vars": "off",
"i18n-text/no-en": "off",
"filenames/match-regex": "off",
"import/no-commonjs": "off",
"import/named": "off",
"no-sequences": "off",
"import/no-unresolved": "off",
"no-undef": "off", "no-undef": "off",
"no-only-tests/no-only-tests": "off",
"@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-member-accessibility": [ "@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
"error",
{
"accessibility": "no-public"
}
],
"@typescript-eslint/no-require-imports": "error", "@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/array-type": "error", "@typescript-eslint/array-type": "error",
"@typescript-eslint/await-thenable": "error", "@typescript-eslint/await-thenable": "error",
@@ -49,16 +23,8 @@
"camelcase": "off", "camelcase": "off",
"@typescript-eslint/camelcase": "off", "@typescript-eslint/camelcase": "off",
"@typescript-eslint/consistent-type-assertions": "off", "@typescript-eslint/consistent-type-assertions": "off",
"@typescript-eslint/explicit-function-return-type": [ "@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
"error", "@typescript-eslint/func-call-spacing": ["error", "never"],
{
"allowExpressions": true
}
],
"@typescript-eslint/func-call-spacing": [
"error",
"never"
],
"@typescript-eslint/naming-convention": [ "@typescript-eslint/naming-convention": [
"error", "error",
{ {
@@ -90,15 +56,12 @@
"@typescript-eslint/prefer-string-starts-ends-with": "error", "@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/promise-function-async": "error", "@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/require-array-sort-compare": "error", "@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"semi": "off", "semi": "off",
"@typescript-eslint/semi": [ "@typescript-eslint/semi": ["error", "never"],
"error",
"never"
],
"@typescript-eslint/type-annotation-spacing": "error", "@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unbound-method": "error" "@typescript-eslint/unbound-method": "error"
}, },
"ignorePatterns": "packages/glob/__tests__/_temp/**/",
"env": { "env": {
"node": true, "node": true,
"es6": true, "es6": true,
+2 -2
View File
@@ -28,7 +28,7 @@ Note that before a PR will be accepted, you must ensure:
### Useful Scripts ### Useful Scripts
- `npm run bootstrap` This runs `lerna exec -- npm install` which will install dependencies in this repository's packages and cross-link packages where necessary. - `npm run bootstrap` This runs `lerna bootstrap` which will install dependencies in this repository's packages and cross-link packages where necessary.
- `npm run build` This compiles TypeScript code in each package (this is especially important if one package relies on changes in another when you're running tests). This is just an alias for `lerna run tsc`. - `npm run build` This compiles TypeScript code in each package (this is especially important if one package relies on changes in another when you're running tests). This is just an alias for `lerna run tsc`.
- `npm run format` This checks that formatting has been applied with Prettier. - `npm run format` This checks that formatting has been applied with Prettier.
- `npm test` This runs all Jest tests in all packages in this repository. - `npm test` This runs all Jest tests in all packages in this repository.
@@ -43,7 +43,7 @@ Note that before a PR will be accepted, you must ensure:
1. In a new branch, create a new Lerna package: 1. In a new branch, create a new Lerna package:
```console ```console
$ npm run new-package [name] $ npm run create-package new-package
``` ```
This will ask you some questions about the new package. Start with `0.0.0` as the first version (look generally at some of the other packages for how the package.json is structured). This will ask you some questions about the new package. Start with `0.0.0` as the first version (look generally at some of the other packages for how the package.json is structured).
-27
View File
@@ -1,27 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm"
directory: "/packages/artifact"
schedule:
interval: "daily"
groups:
# Group minor and patch updates together but keep major separate
artifact-minor-patch:
update-types:
- "minor"
- "patch"
- package-ecosystem: "npm"
directory: "/packages/cache"
schedule:
interval: "daily"
groups:
# Group minor and patch updates together but keep major separate
cache-minor-patch:
update-types:
- "minor"
- "patch"
+56 -148
View File
@@ -10,8 +10,8 @@ on:
- '**.md' - '**.md'
jobs: jobs:
upload: build:
name: Upload name: Build
strategy: strategy:
matrix: matrix:
@@ -22,12 +22,17 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v3
- name: Set Node.js 24.x - name: Set Node.js 16.x
uses: actions/setup-node@v5 uses: actions/setup-node@v3
with: with:
node-version: 24.x node-version: 16.x
# In order to upload & download artifacts from a shell script, certain env variables need to be set that are only available in the
# node context. This runs a local action that gets and sets the necessary env variables that are needed
- name: Set env variables
uses: ./packages/artifact/__tests__/ci-test-action/
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible # Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
# without these to just compile the artifacts package # without these to just compile the artifacts package
@@ -40,155 +45,58 @@ jobs:
npm run tsc npm run tsc
working-directory: packages/artifact working-directory: packages/artifact
- name: Set artifact file contents
shell: bash
run: |
echo "non-gzip-artifact-content=hello" >> $GITHUB_ENV
echo "gzip-artifact-content=Some large amount of text that has a compression ratio that is greater than 100%. If greater than 100%, gzip is used to upload the file" >> $GITHUB_ENV
echo "empty-artifact-content=_EMPTY_" >> $GITHUB_ENV
- name: Create files that will be uploaded - name: Create files that will be uploaded
run: | run: |
mkdir artifact-path mkdir artifact-path
echo -n 'hello from file 1' > artifact-path/first.txt echo '${{ env.non-gzip-artifact-content }}' > artifact-path/world.txt
echo -n 'hello from file 2' > artifact-path/second.txt echo '${{ env.gzip-artifact-content }}' > artifact-path/gzip.txt
touch artifact-path/empty.txt
- name: Upload Artifacts # We're using node -e to call the functions directly available in the @actions/artifact package
uses: actions/github-script@v8 - name: Upload artifacts using uploadArtifact()
with:
script: |
const {default: artifact} = require('./packages/artifact/lib/artifact')
const artifactName = 'my-artifact-${{ matrix.runs-on }}'
console.log('artifactName: ' + artifactName)
const fileContents = ['artifact-path/first.txt','artifact-path/second.txt']
const uploadResult = await artifact.uploadArtifact(artifactName, fileContents, './')
console.log(uploadResult)
const size = uploadResult.size
const id = uploadResult.id
console.log(`Successfully uploaded artifact ${id}`)
try {
await artifact.uploadArtifact(artifactName, fileContents, './')
throw new Error('should have failed second upload')
} catch (err) {
console.log('Successfully blocked second artifact upload')
}
verify:
name: Verify and Delete
runs-on: ubuntu-latest
needs: [upload]
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 24.x
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
# without these to just compile the artifacts package
- name: Install root npm packages
run: npm ci
- name: Compile artifact package
run: | run: |
npm ci node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-1',['artifact-path/world.txt'], process.argv[1]))" "${{ github.workspace }}"
npm run tsc node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-2',['artifact-path/gzip.txt'], process.argv[1]))" "${{ github.workspace }}"
working-directory: packages/artifact node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().uploadArtifact('my-artifact-3',['artifact-path/empty.txt'], process.argv[1]))" "${{ github.workspace }}"
- name: List and Download Artifacts - name: Download artifacts using downloadArtifact()
uses: actions/github-script@v8 run: |
with: mkdir artifact-1-directory
script: | node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().downloadArtifact('my-artifact-1','artifact-1-directory'))"
const {default: artifactClient} = require('./packages/artifact/lib/artifact') mkdir artifact-2-directory
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().downloadArtifact('my-artifact-2','artifact-2-directory'))"
mkdir artifact-3-directory
node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().downloadArtifact('my-artifact-3','artifact-3-directory'))"
const {readFile} = require('fs/promises') - name: Add additional logging
const path = require('path') shell: bash
run: |
cat ./artifact-1-directory/artifact-path/world.txt
cat ./artifact-2-directory/artifact-path/gzip.txt
cat ./artifact-3-directory/artifact-path/empty.txt
const findBy = { - name: Verify downloadArtifact()
repositoryOwner: process.env.GITHUB_REPOSITORY.split('/')[0], shell: bash
repositoryName: process.env.GITHUB_REPOSITORY.split('/')[1], run: |
token: '${{ secrets.GITHUB_TOKEN }}', packages/artifact/__tests__/test-artifact-file.sh "artifact-1-directory/artifact-path/world.txt" "${{ env.non-gzip-artifact-content }}"
workflowRunId: process.env.GITHUB_RUN_ID packages/artifact/__tests__/test-artifact-file.sh "artifact-2-directory/artifact-path/gzip.txt" "${{ env.gzip-artifact-content }}"
} packages/artifact/__tests__/test-artifact-file.sh "artifact-3-directory/artifact-path/empty.txt" "${{ env.empty-artifact-content }}"
const listResult = await artifactClient.listArtifacts({latest: true, findBy}) - name: Download artifacts using downloadAllArtifacts()
console.log(listResult) run: |
mkdir multi-artifact-directory
const artifacts = listResult.artifacts node -e "Promise.resolve(require('./packages/artifact/lib/artifact-client').create().downloadAllArtifacts('multi-artifact-directory'))"
const expected = [
'my-artifact-ubuntu-latest',
'my-artifact-windows-latest',
'my-artifact-macos-latest'
]
const foundArtifacts = artifacts.filter(artifact =>
expected.includes(artifact.name)
)
if (foundArtifacts.length !== 3) {
console.log('Unexpected length of found artifacts', foundArtifacts)
throw new Error(
`Expected 3 artifacts but found ${foundArtifacts.length} artifacts.`
)
}
console.log('Successfully listed artifacts that were uploaded')
const files = [
{name: 'artifact-path/first.txt', content: 'hello from file 1'},
{name: 'artifact-path/second.txt', content: 'hello from file 2'}
]
for (const artifact of foundArtifacts) {
const {downloadPath} = await artifactClient.downloadArtifact(artifact.id, {
path: artifact.name,
findBy
})
console.log('Downloaded artifact to:', downloadPath)
for (const file of files) {
const filepath = path.join(
process.env.GITHUB_WORKSPACE,
downloadPath,
file.name
)
console.log('Checking file:', filepath)
const content = await readFile(filepath, 'utf8')
if (content.trim() !== file.content.trim()) {
throw new Error(
`Expected file '${file.name}' to contain '${file.content}' but found '${content}'`
)
}
}
}
- name: Delete Artifacts
uses: actions/github-script@v8
with:
script: |
const {default: artifactClient} = require('./packages/artifact/lib/artifact')
const artifactsToDelete = [
'my-artifact-ubuntu-latest',
'my-artifact-windows-latest',
'my-artifact-macos-latest'
]
for (const artifactName of artifactsToDelete) {
const {id} = await artifactClient.deleteArtifact(artifactName)
}
const {artifacts} = await artifactClient.listArtifacts({latest: true})
const foundArtifacts = artifacts.filter(artifact =>
artifactsToDelete.includes(artifact.name)
)
if (foundArtifacts.length !== 0) {
console.log('Unexpected length of found artifacts:', foundArtifacts)
throw new Error(
`Expected 0 artifacts but found ${foundArtifacts.length} artifacts.`
)
}
- name: Verify downloadAllArtifacts()
shell: bash
run: |
packages/artifact/__tests__/test-artifact-file.sh "multi-artifact-directory/my-artifact-1/artifact-path/world.txt" "${{ env.non-gzip-artifact-content }}"
packages/artifact/__tests__/test-artifact-file.sh "multi-artifact-directory/my-artifact-2/artifact-path/gzip.txt" "${{ env.gzip-artifact-content }}"
packages/artifact/__tests__/test-artifact-file.sh "multi-artifact-directory/my-artifact-3/artifact-path/empty.txt" "${{ env.empty-artifact-content }}"
+7 -6
View File
@@ -18,12 +18,12 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v3
- name: Set Node.js 24.x - name: Set Node.js 16.x
uses: actions/setup-node@v5 uses: actions/setup-node@v3
with: with:
node-version: 24.x node-version: 16.x
- name: npm install - name: npm install
run: npm install run: npm install
@@ -31,8 +31,9 @@ jobs:
- name: Bootstrap - name: Bootstrap
run: npm run bootstrap run: npm run bootstrap
- name: audit tools (without allow-list) - name: audit tools
run: npm audit --audit-level=moderate --omit dev # `|| npm audit` to pretty-print the output if vulnerabilies are found after filtering.
run: npm audit --audit-level=moderate --json | scripts/audit-allow-list || npm audit --audit-level=moderate
- name: audit packages - name: audit packages
run: npm run audit-all run: npm run audit-all
+5 -7
View File
@@ -22,12 +22,12 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v3
- name: Set Node.js 24.x - name: Set Node.js 16.x
uses: actions/setup-node@v5 uses: actions/setup-node@v3
with: with:
node-version: 24.x node-version: 16.x
# In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the # In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the
# node context. This runs a local action that gets and sets the necessary env variables that are needed # node context. This runs a local action that gets and sets the necessary env variables that are needed
@@ -39,11 +39,9 @@ jobs:
- name: Install root npm packages - name: Install root npm packages
run: npm ci run: npm ci
# We need to install only runtime dependencies (omit dev dependencies) to verify that what we're shipping is all
# that is needed
- name: Compile cache package - name: Compile cache package
run: | run: |
npm ci --omit=dev npm ci
npm run tsc npm run tsc
working-directory: packages/cache working-directory: packages/cache
-90
View File
@@ -1,90 +0,0 @@
name: cache-windows-bsd-unit-tests
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
name: Build
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- shell: bash
run: |
rm "C:\Program Files\Git\usr\bin\tar.exe"
- name: Set Node.js 24.x
uses: actions/setup-node@v5
with:
node-version: 24.x
# In order to save & restore cache from a shell script, certain env variables need to be set that are only available in the
# node context. This runs a local action that gets and sets the necessary env variables that are needed
- name: Set env variables
uses: ./packages/cache/__tests__/__fixtures__/
# Need root node_modules because certain npm packages like jest are configured for the entire repository and it won't be possible
# without these to just compile the cache package
- name: Install root npm packages
run: npm ci
- name: Compile cache package
run: |
npm ci
npm run tsc
working-directory: packages/cache
- name: Generate files in working directory
shell: bash
run: packages/cache/__tests__/create-cache-files.sh ${{ runner.os }} test-cache
- name: Generate files outside working directory
shell: bash
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()
run: |
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
shell: bash
run: |
rm -rf test-cache
rm -rf ~/test-cache
- name: Restore cache using restoreCache() with http-client
run: |
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
shell: bash
run: |
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} test-cache
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache
- name: Delete cache folders before restoring
shell: bash
run: |
rm -rf test-cache
rm -rf ~/test-cache
- name: Restore cache using restoreCache() with Azure SDK
run: |
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
shell: bash
run: |
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} test-cache
packages/cache/__tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache
+4 -4
View File
@@ -20,18 +20,18 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v1
with: with:
languages: javascript languages: javascript
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v1
+10 -28
View File
@@ -1,42 +1,27 @@
name: Publish NPM name: Publish NPM
run-name: Publish NPM - ${{ github.event.inputs.package }}
on: on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
package: package:
type: choice
required: true required: true
description: 'Which package to release' description: 'core, artifact, cache, exec, github, glob, http-client, io, tool-cache'
options:
- artifact
- attest
- cache
- core
- exec
- github
- glob
- http-client
- io
- tool-cache
jobs: jobs:
test: test:
runs-on: macos-latest-large runs-on: macos-latest
steps: steps:
- name: setup repo - name: setup repo
uses: actions/checkout@v5 uses: actions/checkout@v3
- 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 16.x
uses: actions/setup-node@v5 uses: actions/setup-node@v3
with: with:
node-version: 24.x node-version: 16.x
- name: npm install - name: npm install
run: npm install run: npm install
@@ -55,22 +40,19 @@ jobs:
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@v2
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: macos-latest
needs: test needs: test
environment: npm-publish environment: npm-publish
permissions:
contents: read
id-token: write
steps: steps:
- name: download artifact - name: download artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v2
with: with:
name: ${{ github.event.inputs.package }} name: ${{ github.event.inputs.package }}
@@ -80,7 +62,7 @@ jobs:
NPM_TOKEN: ${{ secrets.TOKEN }} NPM_TOKEN: ${{ secrets.TOKEN }}
- name: publish - name: publish
run: npm publish --provenance *.tgz run: npm publish *.tgz
- name: notify slack on failure - name: notify slack on failure
if: failure() if: failure()
+7 -10
View File
@@ -16,23 +16,20 @@ jobs:
strategy: strategy:
matrix: matrix:
runs-on: [ubuntu-latest, macos-latest-large, windows-latest] runs-on: [ubuntu-latest, macos-latest, windows-latest]
# Node 20 is the currently supported stable Node version for actions - https://docs.github.com/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runsusing-for-javascript-actions
# Node 24 is the new version being added with support in actions runners
node-version: [20.x, 24.x]
fail-fast: false fail-fast: false
runs-on: ${{ matrix.runs-on }} runs-on: ${{ matrix.runs-on }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v3
- name: Set up Node ${{ matrix.node-version }} - name: Set Node.js 16.x
uses: actions/setup-node@v5 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: 16.x
- run: npm -v
- name: npm install - name: npm install
run: npm install run: npm install
@@ -44,7 +41,7 @@ jobs:
run: npm run build run: npm run build
- name: npm test - name: npm test
run: npm test -- --runInBand --forceExit run: npm test
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
+2 -2
View File
@@ -9,7 +9,7 @@ jobs:
if: ${{ github.repository_owner == 'actions' }} if: ${{ github.repository_owner == 'actions' }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v3
- name: Update Octokit - name: Update Octokit
working-directory: packages/github working-directory: packages/github
run: | run: |
@@ -30,7 +30,7 @@ jobs:
fi fi
- name: Create PR - name: Create PR
if: ${{steps.status.outputs.createPR}} if: ${{steps.status.outputs.createPR}}
uses: actions/github-script@v6 uses: actions/github-script@v2
with: with:
github-token: ${{secrets.GITHUB_TOKEN}} github-token: ${{secrets.GITHUB_TOKEN}}
script: | script: |
-2
View File
@@ -1,5 +1,3 @@
node_modules/ node_modules/
packages/*/node_modules/ packages/*/node_modules/
packages/*/lib/ packages/*/lib/
packages/glob/__tests__/_temp/**/
packages/*/src/generated/*/
+1 -2
View File
@@ -7,6 +7,5 @@
"trailingComma": "none", "trailingComma": "none",
"bracketSpacing": false, "bracketSpacing": false,
"arrowParens": "avoid", "arrowParens": "avoid",
"parser": "typescript", "parser": "typescript"
"endOfLine": "auto"
} }
-1
View File
@@ -2,4 +2,3 @@
/packages/artifact/ @actions/artifacts-actions /packages/artifact/ @actions/artifacts-actions
/packages/cache/ @actions/actions-cache /packages/cache/ @actions/actions-cache
/packages/attest/ @actions/package-security
+11 -34
View File
@@ -24,7 +24,7 @@ The GitHub Actions ToolKit provides a set of packages to make creating actions e
Provides functions for inputs, outputs, results, logging, secrets and variables. Read more [here](packages/core) Provides functions for inputs, outputs, results, logging, secrets and variables. Read more [here](packages/core)
```bash ```bash
npm install @actions/core $ npm install @actions/core
``` ```
<br/> <br/>
@@ -33,7 +33,7 @@ npm install @actions/core
Provides functions to exec cli tools and process output. Read more [here](packages/exec) Provides functions to exec cli tools and process output. Read more [here](packages/exec)
```bash ```bash
npm install @actions/exec $ npm install @actions/exec
``` ```
<br/> <br/>
@@ -42,7 +42,7 @@ npm install @actions/exec
Provides functions to search for files matching glob patterns. Read more [here](packages/glob) Provides functions to search for files matching glob patterns. Read more [here](packages/glob)
```bash ```bash
npm install @actions/glob $ npm install @actions/glob
``` ```
<br/> <br/>
@@ -51,7 +51,7 @@ npm install @actions/glob
A lightweight HTTP client optimized for building actions. Read more [here](packages/http-client) A lightweight HTTP client optimized for building actions. Read more [here](packages/http-client)
```bash ```bash
npm install @actions/http-client $ npm install @actions/http-client
``` ```
<br/> <br/>
@@ -60,7 +60,7 @@ npm install @actions/http-client
Provides disk i/o functions like cp, mv, rmRF, which etc. Read more [here](packages/io) Provides disk i/o functions like cp, mv, rmRF, which etc. Read more [here](packages/io)
```bash ```bash
npm install @actions/io $ npm install @actions/io
``` ```
<br/> <br/>
@@ -71,7 +71,7 @@ Provides functions for downloading and caching tools. e.g. setup-* actions. Rea
See @actions/cache for caching workflow dependencies. See @actions/cache for caching workflow dependencies.
```bash ```bash
npm install @actions/tool-cache $ npm install @actions/tool-cache
``` ```
<br/> <br/>
@@ -80,7 +80,7 @@ npm install @actions/tool-cache
Provides an Octokit client hydrated with the context that the current action is being run in. Read more [here](packages/github) Provides an Octokit client hydrated with the context that the current action is being run in. Read more [here](packages/github)
```bash ```bash
npm install @actions/github $ npm install @actions/github
``` ```
<br/> <br/>
@@ -89,7 +89,7 @@ npm install @actions/github
Provides functions to interact with actions artifacts. Read more [here](packages/artifact) Provides functions to interact with actions artifacts. Read more [here](packages/artifact)
```bash ```bash
npm install @actions/artifact $ npm install @actions/artifact
``` ```
<br/> <br/>
@@ -98,16 +98,7 @@ npm install @actions/artifact
Provides functions to cache dependencies and build outputs to improve workflow execution time. Read more [here](packages/cache) Provides functions to cache dependencies and build outputs to improve workflow execution time. Read more [here](packages/cache)
```bash ```bash
npm install @actions/cache $ npm install @actions/cache
```
<br/>
:lock_with_ink_pen: [@actions/attest](packages/attest)
Provides functions to write attestations for workflow artifacts. Read more [here](packages/attest)
```bash
npm install @actions/attest
``` ```
<br/> <br/>
@@ -227,23 +218,9 @@ console.log(`We can even get context data, like the repo: ${context.repo.repo}`)
``` ```
<br/> <br/>
## Note ## Contributing
Thank you for your interest in this GitHub repo, however, right now we are not taking contributions. We welcome contributions. See [how to contribute](.github/CONTRIBUTING.md).
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features were working on and what stage theyre in.
We are taking the following steps to better direct requests related to GitHub Actions, including:
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
3. Security Issues should be handled as per our [security.md](SECURITY.md).
We will still provide security updates for this project and fix major breaking changes during this time.
You are welcome to still raise bugs in this repo.
## Code of Conduct ## Code of Conduct
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
os: [ubuntu-16.04, windows-2019] os: [ubuntu-16.04, windows-2019]
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
actions: actions:
- uses: actions/setup-node@v5 - uses: actions/setup-node@v3
with: with:
version: ${{matrix.node}} version: ${{matrix.node}}
- run: | - run: |
+1 -15
View File
@@ -50,18 +50,7 @@ function setSecret(secret: string): void {}
Now, future logs containing BAR will be masked. E.g. running `echo "Hello FOO BAR World"` will now print `Hello FOO **** World`. Now, future logs containing BAR will be masked. E.g. running `echo "Hello FOO BAR World"` will now print `Hello FOO **** World`.
**WARNING** The add-mask and setSecret commands only support single-line **WARNING** The add-mask and setSecret commands only support single line secrets. To register a multiline secrets you must register each line individually otherwise it will not be masked.
secrets or multi-line secrets that have been escaped. `@actions/core`
`setSecret` will escape the string you provide by default. When an escaped
multi-line string is provided the whole string and each of its lines
individually will be masked. For example you can mask `first\nsecond\r\nthird`
using:
```sh
echo "::add-mask::first%0Asecond%0D%0Athird"
```
This will mask `first%0Asecond%0D%0Athird`, `first`, `second` and `third`.
**WARNING** Do **not** mask short values if you can avoid it, it could render your output unreadable (and future steps' output as well). **WARNING** Do **not** mask short values if you can avoid it, it could render your output unreadable (and future steps' output as well).
For example, if you mask the letter `l`, running `echo "Hello FOO BAR World"` will now print `He*********o FOO BAR Wor****d` For example, if you mask the letter `l`, running `echo "Hello FOO BAR World"` will now print `He*********o FOO BAR Wor****d`
@@ -111,12 +100,9 @@ There are several commands to emit different levels of log output:
| log level | example usage | | log level | example usage |
|---|---| |---|---|
| [debug](action-debugging.md) | `echo "::debug::My debug message"` | | [debug](action-debugging.md) | `echo "::debug::My debug message"` |
| notice | `echo "::notice::My notice message"` |
| warning | `echo "::warning::My warning message"` | | warning | `echo "::warning::My warning message"` |
| error | `echo "::error::My error message"` | | error | `echo "::error::My error message"` |
Additional syntax options are described at [the workflow command documentation](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message).
### Command Echoing ### Command Echoing
By default, the echoing of commands to stdout only occurs if [Step Debugging is enabled](./action-debugging.md#How-to-Access-Step-Debug-Logs) By default, the echoing of commands to stdout only occurs if [Step Debugging is enabled](./action-debugging.md#How-to-Access-Step-Debug-Logs)
+1 -1
View File
@@ -18,7 +18,7 @@ e.g. To use https://github.com/actions/setup-node, users will author:
```yaml ```yaml
steps: steps:
using: actions/setup-node@v5 using: actions/setup-node@v3
``` ```
# Define Metadata # Define Metadata
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"packages": [ "packages": [
"packages/**/*" "packages/*"
], ],
"version": "independent" "version": "independent"
} }
-24
View File
@@ -1,24 +0,0 @@
{
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": []
}
}
},
"affected": {
"defaultBase": "master"
},
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"namedInputs": {
"default": [
"{projectRoot}/**/*",
"sharedGlobals"
],
"sharedGlobals": [],
"production": [
"default"
]
}
}
+23236 -9737
View File
File diff suppressed because it is too large Load Diff
+13 -31
View File
@@ -3,48 +3,30 @@
"private": true, "private": true,
"scripts": { "scripts": {
"audit-all": "lerna run audit-moderate", "audit-all": "lerna run audit-moderate",
"bootstrap": "lerna exec -- npm install", "bootstrap": "lerna bootstrap",
"build": "lerna run tsc", "build": "lerna run tsc",
"clean": "lerna clean",
"repair": "lerna repair",
"check-all": "concurrently \"npm:format-check\" \"npm:lint\" \"npm:test\" \"npm:build -- -- --noEmit\"", "check-all": "concurrently \"npm:format-check\" \"npm:lint\" \"npm:test\" \"npm:build -- -- --noEmit\"",
"format": "prettier --write packages/**/*.ts", "format": "prettier --write packages/**/*.ts",
"format-check": "prettier --check packages/**/*.ts", "format-check": "prettier --check packages/**/*.ts",
"lint": "eslint packages/**/*.ts", "lint": "eslint packages/**/*.ts",
"lint-fix": "eslint packages/**/*.ts --fix", "lint-fix": "eslint packages/**/*.ts --fix",
"new-package": "scripts/create-package", "new-package": "scripts/create-package",
"test": "jest --testTimeout 70000" "test": "jest --testTimeout 10000"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.4", "@types/jest": "^27.0.2",
"@types/node": "^24.1.0", "@types/node": "^12.20.13",
"@types/signale": "^1.4.1", "@types/signale": "^1.4.1",
"@typescript-eslint/parser": "^4.0.0",
"concurrently": "^6.1.0", "concurrently": "^6.1.0",
"eslint": "^8.0.1", "eslint": "^7.23.0",
"eslint-config-prettier": "^8.9.0", "eslint-plugin-github": "^4.1.3",
"eslint-plugin-github": "^4.9.2", "eslint-plugin-jest": "^22.21.0",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-prettier": "^5.0.0",
"flow-bin": "^0.115.0", "flow-bin": "^0.115.0",
"jest": "^29.6.4", "jest": "^27.2.5",
"lerna": "^6.4.1", "lerna": "^5.4.0",
"nx": "16.6.0", "prettier": "^1.19.1",
"prettier": "^3.0.0", "ts-jest": "^27.0.5",
"ts-jest": "^29.1.1", "typescript": "^3.9.9"
"typescript": "^5.2.2"
},
"overrides": {
"semver": "^7.6.0",
"tar": "^6.2.1",
"@octokit/plugin-paginate-rest": "^9.2.2",
"@octokit/request": "^8.4.1",
"@octokit/request-error": "^5.1.1",
"@octokit/core": "^5.0.3",
"tmp": "^0.2.4",
"@types/node": "^24.1.0",
"brace-expansion": "^2.0.2",
"form-data": "^4.0.4",
"uri-js": "npm:uri-js-replace@^1.0.1",
"node-fetch": "^3.3.2"
} }
} }
+12 -26
View File
@@ -1,44 +1,30 @@
# Contributions # Contributions
This package is used internally by the v4 versions of [upload-artifact](https://github.com/actions/upload-artifact) and [download-artifact](https://github.com/actions/download-artifact). This package can also be used by other actions to interact with artifacts. Any changes or updates to this package will propagate updates to these actions so it is important that major changes or updates get properly tested. This package is used internally by the v2+ versions of [upload-artifact](https://github.com/actions/upload-artifact) and [download-artifact](https://github.com/actions/download-artifact). This package can also be used by other actions to interact with artifacts. Any changes or updates to this package will propagate updates to these actions so it is important that major changes or updates get properly tested.
Any issues or feature requests that are related to the artifact actions should be filled in the appropriate repo. Any issues or feature requests that are related to the artifact actions should be filled in the appropriate repo.
A limited range of unit tests run as part of each PR when making changes to the artifact packages. For small contributions and fixes, they should be sufficient. A limited range of unit tests run as part of each PR when making changes to the artifact packages. For small contributions and fixes, they should be sufficient.
If making large changes, there are a few scenarios that should be tested: If making large changes, there are a few scenarios that should be tested.
- Uploading very large artifacts - Uploading very large artifacts (large artifacts get compressed using gzip so compression/decompression must be tested)
- Uploading artifacts with lots of small files - Uploading artifacts with lots of small files (each file is uploaded with its own HTTP call, timeouts and non-success HTTP responses can be expected so they must be properly handled)
- Uploading artifacts using a self-hosted runner (uploads and downloads behave differently due to extra latency) - Uploading artifacts using a self-hosted runner (uploads and downloads behave differently due to extra latency)
- Downloading a single artifact (large and small, if lots of small files are part of an artifact, timeouts and non-success HTTP responses can be expected) - Downloading a single artifact (large and small, if lots of small files are part of an artifact, timeouts and non-success HTTP responses can be expected)
- Downloading all artifacts at once - Downloading all artifacts at once
Large architectural changes can impact upload/download performance so it is important to separately run extra tests. We request that any large contributions/changes have extra detailed testing so we can verify performance and possible regressions. Large architectural changes can impact upload/download performance so it is important to separately run extra tests. We request that any large contributions/changes have extra detailed testing so we can verify performance and possible regressions.
Tests will run for every push/pull_request [via Actions](https://github.com/actions/toolkit/blob/main/.github/workflows/artifact-tests.yml). It is not possible to run end-to-end tests for artifacts as part of a PR in this repo because certain env variables such as `ACTIONS_RUNTIME_URL` are only available from the context of an action as opposed to a shell script. These env variables are needed in order to make the necessary API calls.
# Testing # Testing
## Package tests Any easy way to test changes is to fork the artifact actions and to use `npm link` to test your changes.
To run unit tests for the `@actions/artifact` package: 1. Fork the [upload-artifact](https://github.com/actions/upload-artifact) and [download-artifact](https://github.com/actions/download-artifact) repos
2. Clone the forks locally
1. Clone `actions/toolkit` locally 3. With your local changes to the toolkit repo, type `npm link` after ensuring there are no errors when running `tsc`
2. Install dependencies: `npm bootstrap` 4. In the locally cloned fork, type `npm link @actions/artifact`
3. Change working directory to `packages/artifact` 4. Create a new release for your local fork using `tsc` and `npm run release` (this will create a new `dist/index.js` file using `@vercel/ncc`)
4. Run jest tests: `npm run test` 5. Commit and push your local changes, you will then be able to test your changes with your forked action
## Within upload-artifact or download-artifact actions
Any easy way to test changes for the official upload/download actions is to fork them, compile changes and run them.
1. For your local `actions/toolkit` changes:
1. Change directory to `packages/artifact`
2. Compile the changes: `npm run tsc`
3. Symlink your package change: `npm link`
2. Fork and clone either [upload-artifact](https://github.com/actions/upload-artifact) and [download-artifact](https://github.com/actions/download-artifact)
1. In the locally cloned fork, link to your local toolkit changes: `npm link @actions/artifact`
2. Then, compile your changes with: `npm run release`. The local `dist/index.js` should be updated with your changes.
3. Commit and push to your fork, you can then test with a `uses:` in your workflow pointed at your fork.
4. The format for the above is `<username>/<repository-name>/@<ref>`, i.e. `me/myrepo/@HEAD`
+187 -166
View File
@@ -1,192 +1,213 @@
# `@actions/artifact` # `@actions/artifact`
Interact programmatically with [Actions Artifacts](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts). ## Usage
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. You can use this package to interact with the actions artifacts.
- [Upload an Artifact](#Upload-an-Artifact)
- [Download a Single Artifact](#Download-a-Single-Artifact)
- [Download All Artifacts](#Download-all-Artifacts)
- [Additional Documentation](#Additional-Documentation)
- [Contributions](#Contributions)
Relative paths and absolute paths are both allowed. Relative paths are rooted against the current working directory.
- [`@actions/artifact`](#actionsartifact) ## Upload an Artifact
- [v2 - What's New](#v2---whats-new)
- [Improvements](#improvements)
- [Breaking changes](#breaking-changes)
- [Quick Start](#quick-start)
- [Examples](#examples)
- [Upload and Download](#upload-and-download)
- [Delete an Artifact](#delete-an-artifact)
- [Downloading from other workflow runs or repos](#downloading-from-other-workflow-runs-or-repos)
- [Speeding up large uploads](#speeding-up-large-uploads)
- [Additional Resources](#additional-resources)
## v2 - What's New Method Name: `uploadArtifact`
> [!IMPORTANT] #### Inputs
> @actions/artifact v2+, upload-artifact@v4+, and download-artifact@v4+ are not currently supported on GHES yet. The previous version of this package can be found at [this tag](https://github.com/actions/toolkit/tree/@actions/[email protected]/packages/artifact) and [on npm](https://www.npmjs.com/package/@actions/artifact/v/1.1.2). - `name`
- The name of the artifact that is being uploaded
- Required
- `files`
- A list of file paths that describe what should be uploaded as part of the artifact
- If a path is provided that does not exist, an error will be thrown
- Can be absolute or relative. Internally everything is normalized and resolved
- Required
- `rootDirectory`
- A file path that denotes the root directory of the files being uploaded. This path is used to strip the paths provided in `files` to control how they are uploaded and structured
- If a file specified in `files` is not in the `rootDirectory`, an error will be thrown
- Required
- `options`
- Extra options that allow for the customization of the upload behavior
- Optional
The release of `@actions/artifact@v2` (including `upload-artifact@v4` and `download-artifact@v4`) are major changes to the backend architecture of Artifacts. They have numerous performance and behavioral improvements. #### Available Options
### Improvements - `continueOnError`
- Indicates if the artifact upload should continue in the event a file fails to upload. If there is a error during upload, a partial artifact will always be created and available for download at the end. The `size` reported will be the amount of storage that the user or org will be charged for the partial artifact.
- If set to `false`, and an error is encountered, all other uploads will stop and any files that were queued will not be attempted to be uploaded. The partial artifact available will only include files up until the failure.
- If set to `true` and an error is encountered, the failed file will be skipped and ignored and all other queued files will be attempted to be uploaded. There will be an artifact available for download at the end with everything excluding the file that failed to upload
- Optional, defaults to `true` if not specified
- `retentionDays`
- Duration after which artifact will expire in days
- Minimum value: 1
- Maximum value: 90 unless changed by repository setting
- If this is set to a greater value than the retention settings allowed, the retention on artifacts will be reduced to match the max value allowed on the server, and the upload process will continue. An input of 0 assumes default retention value.
1. All upload and download operations are much quicker, up to 80% faster download times and 96% faster upload times in worst case scenarios. #### Example using Absolute File Paths
2. Once uploaded, an Artifact ID is returned and Artifacts are immediately available in the UI and [REST API](https://docs.github.com/en/rest/actions/artifacts). Previously, you would have to wait for the run to be completed before an ID was available or any APIs could be utilized.
3. Artifacts can now be downloaded and deleted from the UI _before_ the entire workflow run finishes.
4. The contents of an Artifact are uploaded together into an _immutable_ archive. They cannot be altered by subsequent jobs. Both of these factors help reduce the possibility of accidentally corrupting Artifact files. (Digest/integrity hash coming soon in the API!)
5. This library (and `actions/download-artifact`) now support downloading Artifacts from _other_ repositories and runs if a `GITHUB_TOKEN` with sufficient `actions:read` permissions are provided.
### Breaking changes
1. Firewall rules required for self-hosted runners.
If you are using self-hosted runners behind a firewall, you must have flows open to [Actions endpoints](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#communication-between-self-hosted-runners-and-github). If you cannot use wildcard rules for your firewall, see the GitHub [meta endpoint](https://api.github.com/meta) for specific endpoints.
e.g.
```bash
curl https://api.github.com/meta | jq .domains.actions
```
2. Uploading to the same named Artifact multiple times.
Due to how Artifacts are created in this new version, it is no longer possible to upload to the same named Artifact multiple times. You must either split the uploads into multiple Artifacts with different names, or only upload once.
3. Limit of Artifacts for an individual job.
Each job in a workflow run now has a limit of 10 artifacts.
## Quick Start
Install the package:
```bash
npm i @actions/artifact
```
Import the module:
```js ```js
// ES6 module const artifact = require('@actions/artifact');
import {DefaultArtifactClient} from '@actions/artifact' const artifactClient = artifact.create()
const artifactName = 'my-artifact';
// CommonJS const files = [
const {DefaultArtifactClient} = require('@actions/artifact') '/home/user/files/plz-upload/file1.txt',
``` '/home/user/files/plz-upload/file2.txt',
'/home/user/files/plz-upload/dir/file3.txt'
Then instantiate: ]
const rootDirectory = '/home/user/files/plz-upload'
```js const options = {
const artifact = new DefaultArtifactClient() continueOnError: true
```
️ For a comprehensive list of classes, interfaces, functions and more, see the [generated documentation](./docs/generated/README.md).
## Examples
### Upload and Download
The most basic scenario is uploading one or more files to an Artifact, then downloading that Artifact. Downloads are based on the Artifact ID, which can be obtained in the response of `uploadArtifact`, `getArtifact`, `listArtifacts` or via the [REST API](https://docs.github.com/en/rest/actions/artifacts).
```js
const {id, size} = await artifact.uploadArtifact(
// name of the artifact
'my-artifact',
// files to include (supports absolute and relative paths)
['/absolute/path/file1.txt', './relative/file2.txt'],
{
// optional: how long to retain the artifact
// if unspecified, defaults to repository/org retention settings (the limit of this value)
retentionDays: 10
}
)
console.log(`Created artifact with id: ${id} (bytes: ${size}`)
const {downloadPath} = await artifact.downloadArtifact(id, {
// optional: download destination path. otherwise defaults to $GITHUB_WORKSPACE
path: '/tmp/dst/path',
})
console.log(`Downloaded artifact ${id} to: ${downloadPath}`)
```
### Delete an Artifact
To delete an artifact, all you need is the name.
```js
const {id} = await artifact.deleteArtifact(
// name of the artifact
'my-artifact'
)
console.log(`Deleted Artifact ID '${id}'`)
```
It also supports options to delete from other repos/runs given a github token with `actions:write` permissions on the target repository is supplied.
```js
const findBy = {
// must have actions:write permission on target repository
token: process.env['GITHUB_TOKEN'],
workflowRunId: 123,
repositoryOwner: 'actions',
repositoryName: 'toolkit'
} }
const uploadResult = await artifactClient.uploadArtifact(artifactName, files, rootDirectory, options)
const {id} = await artifact.deleteArtifact(
// name of the artifact
'my-artifact',
// options to find by other repo/owner
{ findBy }
)
console.log(`Deleted Artifact ID '${id}' from ${findBy.repositoryOwner}/ ${findBy.repositoryName}`)
``` ```
### Downloading from other workflow runs or repos #### Example using Relative File Paths
```js
// Assuming the current working directory is /home/user/files/plz-upload
const artifact = require('@actions/artifact');
const artifactClient = artifact.create()
const artifactName = 'my-artifact';
const files = [
'file1.txt',
'file2.txt',
'dir/file3.txt'
]
It may be useful to download Artifacts from other workflow runs, or even other repositories. By default, the permissions are scoped so they can only download Artifacts within the current workflow run. To elevate permissions for this scenario, you must specify `options.findBy` to `downloadArtifact`. const rootDirectory = '.' // Also possible to use __dirname
const options = {
```ts continueOnError: false
const findBy = {
// must have actions:read permission on target repository
token: process.env['GITHUB_TOKEN'],
workflowRunId: 123,
repositoryOwner: 'actions',
repositoryName: 'toolkit'
} }
await artifact.downloadArtifact(1337, { const uploadResponse = await artifactClient.uploadArtifact(artifactName, files, rootDirectory, options)
findBy
})
// can also be used in other methods
await artifact.getArtifact('my-artifact', {
findBy
})
await artifact.listArtifacts({
findBy
})
``` ```
### Speeding up large uploads #### Upload Result
If you have large files that need to be uploaded (or file types that don't compress well), you may benefit from changing the compression level of the Artifact archive. NOTE: This is a tradeoff between artifact upload time and stored data size. The returned `UploadResponse` will contain the following information
```ts - `artifactName`
await artifact.uploadArtifact('my-massive-artifact', ['big_file.bin'], { - The name of the artifact that was uploaded
// The level of compression for Zlib to be applied to the artifact archive. - `artifactItems`
// - 0: No compression - A list of all files that describe what is uploaded if there are no errors encountered. Usually this will be equal to the inputted `files` with the exception of empty directories (will not be uploaded)
// - 1: Best speed - `size`
// - 6: Default compression (same as GNU Gzip) - Total size of the artifact that was uploaded in bytes
// - 9: Best compression - `failedItems`
compressionLevel: 0 - A list of items that were not uploaded successfully (this will include queued items that were not uploaded if `continueOnError` is set to false). This is a subset of `artifactItems`
})
## Download a Single Artifact
Method Name: `downloadArtifact`
#### Inputs
- `name`
- The name of the artifact to download
- Required
- `path`
- Path that denotes where the artifact will be downloaded to
- Optional. Defaults to the GitHub workspace directory(`$GITHUB_WORKSPACE`) if not specified
- `options`
- Extra options that allow for the customization of the download behavior
- Optional
#### Available Options
- `createArtifactFolder`
- Specifies if a folder (the artifact name) is created for the artifact that is downloaded (contents downloaded into this folder),
- Optional. Defaults to false if not specified
#### Example
```js
const artifact = require('@actions/artifact');
const artifactClient = artifact.create()
const artifactName = 'my-artifact';
const path = 'some/directory'
const options = {
createArtifactFolder: false
}
const downloadResponse = await artifactClient.downloadArtifact(artifactName, path, options)
// Post download, the directory structure will look like this
/some
/directory
/file1.txt
/file2.txt
/dir
/file3.txt
// If createArtifactFolder is set to true, the directory structure will look like this
/some
/directory
/my-artifact
/file1.txt
/file2.txt
/dir
/file3.txt
``` ```
## Additional Resources #### Download Response
- [Releases](./RELEASES.md) The returned `DownloadResponse` will contain the following information
- [Contribution Guide](./CONTRIBUTIONS.md)
- [Frequently Asked Questions](./docs/faq.md) - `artifactName`
- The name of the artifact that was downloaded
- `downloadPath`
- The full Path to where the artifact was downloaded
## Download All Artifacts
Method Name: `downloadAllArtifacts`
#### Inputs
- `path`
- Path that denotes where the artifact will be downloaded to
- Optional. Defaults to the GitHub workspace directory(`$GITHUB_WORKSPACE`) if not specified
```js
const artifact = require('@actions/artifact');
const artifactClient = artifact.create();
const downloadResponse = await artifactClient.downloadAllArtifacts();
// output result
for (response in downloadResponse) {
console.log(response.artifactName);
console.log(response.downloadPath);
}
```
Because there are multiple artifacts, an extra directory (denoted by the name of the artifact) will be created for each artifact in the path. With 2 artifacts(`my-artifact-1` and `my-artifact-2` for example) and the default path, the directory structure will be as follows:
```js
/GITHUB_WORKSPACE
/my-artifact-1
/ .. contents of `my-artifact-1`
/my-artifact-2
/ .. contents of `my-artifact-2`
```
#### Download Result
An array will be returned that describes the results for downloading all artifacts. The number of items in the array indicates the number of artifacts that were downloaded.
Each artifact will have the same `DownloadResponse` as if it was individually downloaded
- `artifactName`
- The name of the artifact that was downloaded
- `downloadPath`
- The full Path to where the artifact was downloaded