mirror of
https://github.com/actions/upload-artifact.git
synced 2026-02-26 13:42:35 +00:00
Upgrade the module to ESM and bump dependencies
This commit is contained in:
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"env": { "node": true, "jest": true },
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": { "ecmaVersion": 9, "sourceType": "module" },
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:import/errors",
|
|
||||||
"plugin:import/warnings",
|
|
||||||
"plugin:import/typescript",
|
|
||||||
"plugin:prettier/recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"@typescript-eslint/no-empty-function": "off"
|
|
||||||
},
|
|
||||||
"plugins": ["@typescript-eslint", "jest"]
|
|
||||||
}
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
lib/
|
lib/
|
||||||
__tests__/_temp/
|
__tests__/_temp/
|
||||||
|
.DS_Store
|
||||||
@ -1,8 +1,65 @@
|
|||||||
import * as core from '@actions/core'
|
import {jest, describe, test, expect, beforeEach} from '@jest/globals'
|
||||||
import artifact from '@actions/artifact'
|
|
||||||
import {run} from '../src/merge/merge-artifacts'
|
// Mock @actions/github before importing modules that use it
|
||||||
import {Inputs} from '../src/merge/constants'
|
jest.unstable_mockModule('@actions/github', () => ({
|
||||||
import * as search from '../src/shared/search'
|
context: {
|
||||||
|
repo: {
|
||||||
|
owner: 'actions',
|
||||||
|
repo: 'toolkit'
|
||||||
|
},
|
||||||
|
runId: 123,
|
||||||
|
serverUrl: 'https://github.com'
|
||||||
|
},
|
||||||
|
getOctokit: jest.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Mock @actions/core
|
||||||
|
jest.unstable_mockModule('@actions/core', () => ({
|
||||||
|
getInput: jest.fn(),
|
||||||
|
getBooleanInput: jest.fn(),
|
||||||
|
setOutput: jest.fn(),
|
||||||
|
setFailed: jest.fn(),
|
||||||
|
setSecret: jest.fn(),
|
||||||
|
info: jest.fn(),
|
||||||
|
warning: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
notice: jest.fn(),
|
||||||
|
startGroup: jest.fn(),
|
||||||
|
endGroup: jest.fn(),
|
||||||
|
isDebug: jest.fn(() => false),
|
||||||
|
getState: jest.fn(),
|
||||||
|
saveState: jest.fn(),
|
||||||
|
exportVariable: jest.fn(),
|
||||||
|
addPath: jest.fn(),
|
||||||
|
group: jest.fn((name: string, fn: () => Promise<unknown>) => fn()),
|
||||||
|
toPlatformPath: jest.fn((p: string) => p),
|
||||||
|
toWin32Path: jest.fn((p: string) => p),
|
||||||
|
toPosixPath: jest.fn((p: string) => p)
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Mock fs/promises
|
||||||
|
const actualFsPromises = await import('fs/promises')
|
||||||
|
jest.unstable_mockModule('fs/promises', () => ({
|
||||||
|
...actualFsPromises,
|
||||||
|
mkdtemp:
|
||||||
|
jest.fn<() => Promise<string>>().mockResolvedValue('/tmp/merge-artifact'),
|
||||||
|
rm: jest.fn<() => Promise<void>>().mockResolvedValue(undefined)
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Mock shared search module
|
||||||
|
const mockFindFilesToUpload = jest.fn<
|
||||||
|
() => Promise<{filesToUpload: string[]; rootDirectory: string}>
|
||||||
|
>()
|
||||||
|
jest.unstable_mockModule('../src/shared/search.js', () => ({
|
||||||
|
findFilesToUpload: mockFindFilesToUpload
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Dynamic imports after mocking
|
||||||
|
const core = await import('@actions/core')
|
||||||
|
const artifact = await import('@actions/artifact')
|
||||||
|
const {run} = await import('../src/merge/merge-artifacts.js')
|
||||||
|
const {Inputs} = await import('../src/merge/constants.js')
|
||||||
|
|
||||||
const fixtures = {
|
const fixtures = {
|
||||||
artifactName: 'my-merged-artifact',
|
artifactName: 'my-merged-artifact',
|
||||||
@ -34,27 +91,10 @@ const fixtures = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
jest.mock('@actions/github', () => ({
|
const mockInputs = (
|
||||||
context: {
|
overrides?: Partial<{[K in (typeof Inputs)[keyof typeof Inputs]]?: any}>
|
||||||
repo: {
|
) => {
|
||||||
owner: 'actions',
|
const inputs: Record<string, any> = {
|
||||||
repo: 'toolkit'
|
|
||||||
},
|
|
||||||
runId: 123,
|
|
||||||
serverUrl: 'https://github.com'
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
jest.mock('@actions/core')
|
|
||||||
|
|
||||||
jest.mock('fs/promises', () => ({
|
|
||||||
mkdtemp: jest.fn().mockResolvedValue('/tmp/merge-artifact'),
|
|
||||||
rm: jest.fn().mockResolvedValue(undefined)
|
|
||||||
}))
|
|
||||||
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
|
||||||
const inputs = {
|
|
||||||
[Inputs.Name]: 'my-merged-artifact',
|
[Inputs.Name]: 'my-merged-artifact',
|
||||||
[Inputs.Pattern]: '*',
|
[Inputs.Pattern]: '*',
|
||||||
[Inputs.SeparateDirectories]: false,
|
[Inputs.SeparateDirectories]: false,
|
||||||
@ -64,10 +104,14 @@ const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
|||||||
...overrides
|
...overrides
|
||||||
}
|
}
|
||||||
|
|
||||||
;(core.getInput as jest.Mock).mockImplementation((name: string) => {
|
;(core.getInput as jest.Mock<typeof core.getInput>).mockImplementation(
|
||||||
return inputs[name]
|
(name: string) => {
|
||||||
})
|
return inputs[name]
|
||||||
;(core.getBooleanInput as jest.Mock).mockImplementation((name: string) => {
|
}
|
||||||
|
)
|
||||||
|
;(
|
||||||
|
core.getBooleanInput as jest.Mock<typeof core.getBooleanInput>
|
||||||
|
).mockImplementation((name: string) => {
|
||||||
return inputs[name]
|
return inputs[name]
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -77,44 +121,45 @@ const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
|||||||
describe('merge', () => {
|
describe('merge', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockInputs()
|
mockInputs()
|
||||||
|
jest.clearAllMocks()
|
||||||
|
|
||||||
jest
|
jest
|
||||||
.spyOn(artifact, 'listArtifacts')
|
.spyOn(artifact.default, 'listArtifacts')
|
||||||
.mockResolvedValue({artifacts: fixtures.artifacts})
|
.mockResolvedValue({artifacts: fixtures.artifacts})
|
||||||
|
|
||||||
jest.spyOn(artifact, 'downloadArtifact').mockResolvedValue({
|
jest.spyOn(artifact.default, 'downloadArtifact').mockResolvedValue({
|
||||||
downloadPath: fixtures.tmpDirectory
|
downloadPath: fixtures.tmpDirectory
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
mockFindFilesToUpload.mockResolvedValue({
|
||||||
filesToUpload: fixtures.filesToUpload,
|
filesToUpload: fixtures.filesToUpload,
|
||||||
rootDirectory: fixtures.tmpDirectory
|
rootDirectory: fixtures.tmpDirectory
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(artifact, 'uploadArtifact').mockResolvedValue({
|
jest.spyOn(artifact.default, 'uploadArtifact').mockResolvedValue({
|
||||||
size: 123,
|
size: 123,
|
||||||
id: 1337
|
id: 1337
|
||||||
})
|
})
|
||||||
|
|
||||||
jest
|
jest
|
||||||
.spyOn(artifact, 'deleteArtifact')
|
.spyOn(artifact.default, 'deleteArtifact')
|
||||||
.mockImplementation(async artifactName => {
|
.mockImplementation(async (artifactName: string) => {
|
||||||
const artifact = fixtures.artifacts.find(a => a.name === artifactName)
|
const found = fixtures.artifacts.find(a => a.name === artifactName)
|
||||||
if (!artifact) throw new Error(`Artifact ${artifactName} not found`)
|
if (!found) throw new Error(`Artifact ${artifactName} not found`)
|
||||||
return {id: artifact.id}
|
return {id: found.id}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('merges artifacts', async () => {
|
test('merges artifacts', async () => {
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
for (const a of fixtures.artifacts) {
|
for (const a of fixtures.artifacts) {
|
||||||
expect(artifact.downloadArtifact).toHaveBeenCalledWith(a.id, {
|
expect(artifact.default.downloadArtifact).toHaveBeenCalledWith(a.id, {
|
||||||
path: fixtures.tmpDirectory
|
path: fixtures.tmpDirectory
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.tmpDirectory,
|
fixtures.tmpDirectory,
|
||||||
@ -122,23 +167,23 @@ describe('merge', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('fails if no artifacts found', async () => {
|
test('fails if no artifacts found', async () => {
|
||||||
mockInputs({[Inputs.Pattern]: 'this-does-not-match'})
|
mockInputs({[Inputs.Pattern]: 'this-does-not-match'})
|
||||||
|
|
||||||
expect(run()).rejects.toThrow()
|
await expect(run()).rejects.toThrow()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).not.toBeCalled()
|
expect(artifact.default.uploadArtifact).not.toHaveBeenCalled()
|
||||||
expect(artifact.downloadArtifact).not.toBeCalled()
|
expect(artifact.default.downloadArtifact).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports custom compression level', async () => {
|
test('supports custom compression level', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.CompressionLevel]: 2
|
[Inputs.CompressionLevel]: 2
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.tmpDirectory,
|
fixtures.tmpDirectory,
|
||||||
@ -146,14 +191,14 @@ describe('merge', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports custom retention days', async () => {
|
test('supports custom retention days', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.RetentionDays]: 7
|
[Inputs.RetentionDays]: 7
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.tmpDirectory,
|
fixtures.tmpDirectory,
|
||||||
@ -161,7 +206,7 @@ describe('merge', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports deleting artifacts after merge', async () => {
|
test('supports deleting artifacts after merge', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.DeleteMerged]: true
|
[Inputs.DeleteMerged]: true
|
||||||
})
|
})
|
||||||
@ -169,7 +214,7 @@ describe('merge', () => {
|
|||||||
await run()
|
await run()
|
||||||
|
|
||||||
for (const a of fixtures.artifacts) {
|
for (const a of fixtures.artifacts) {
|
||||||
expect(artifact.deleteArtifact).toHaveBeenCalledWith(a.name)
|
expect(artifact.default.deleteArtifact).toHaveBeenCalledWith(a.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,8 +1,37 @@
|
|||||||
import * as core from '@actions/core'
|
import {jest, describe, test, expect, beforeAll} from '@jest/globals'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as io from '@actions/io'
|
import * as io from '@actions/io'
|
||||||
import {promises as fs} from 'fs'
|
import {promises as fs} from 'fs'
|
||||||
import {findFilesToUpload} from '../src/shared/search'
|
import {fileURLToPath} from 'url'
|
||||||
|
|
||||||
|
// Mock @actions/core to suppress output during tests
|
||||||
|
jest.unstable_mockModule('@actions/core', () => ({
|
||||||
|
getInput: jest.fn(),
|
||||||
|
getBooleanInput: jest.fn(),
|
||||||
|
setOutput: jest.fn(),
|
||||||
|
setFailed: jest.fn(),
|
||||||
|
setSecret: jest.fn(),
|
||||||
|
info: jest.fn(),
|
||||||
|
warning: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
notice: jest.fn(),
|
||||||
|
startGroup: jest.fn(),
|
||||||
|
endGroup: jest.fn(),
|
||||||
|
isDebug: jest.fn(() => false),
|
||||||
|
getState: jest.fn(),
|
||||||
|
saveState: jest.fn(),
|
||||||
|
exportVariable: jest.fn(),
|
||||||
|
addPath: jest.fn(),
|
||||||
|
group: jest.fn((name: string, fn: () => Promise<unknown>) => fn()),
|
||||||
|
toPlatformPath: jest.fn((p: string) => p),
|
||||||
|
toWin32Path: jest.fn((p: string) => p),
|
||||||
|
toPosixPath: jest.fn((p: string) => p)
|
||||||
|
}))
|
||||||
|
|
||||||
|
const {findFilesToUpload} = await import('../src/shared/search.js')
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
const root = path.join(__dirname, '_temp', 'search')
|
const root = path.join(__dirname, '_temp', 'search')
|
||||||
const searchItem1Path = path.join(
|
const searchItem1Path = path.join(
|
||||||
@ -77,11 +106,8 @@ const fileInHiddenFolderInFolderA = path.join(
|
|||||||
|
|
||||||
describe('Search', () => {
|
describe('Search', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
// mock all output so that there is less noise when running tests
|
// mock console.log to reduce noise
|
||||||
jest.spyOn(console, 'log').mockImplementation(() => {})
|
jest.spyOn(console, 'log').mockImplementation(() => {})
|
||||||
jest.spyOn(core, 'debug').mockImplementation(() => {})
|
|
||||||
jest.spyOn(core, 'info').mockImplementation(() => {})
|
|
||||||
jest.spyOn(core, 'warning').mockImplementation(() => {})
|
|
||||||
|
|
||||||
// clear temp directory
|
// clear temp directory
|
||||||
await io.rmRF(root)
|
await io.rmRF(root)
|
||||||
@ -136,43 +162,9 @@ describe('Search', () => {
|
|||||||
await fs.writeFile(hiddenFile, 'hidden file')
|
await fs.writeFile(hiddenFile, 'hidden file')
|
||||||
await fs.writeFile(fileInHiddenFolderPath, 'file in hidden directory')
|
await fs.writeFile(fileInHiddenFolderPath, 'file in hidden directory')
|
||||||
await fs.writeFile(fileInHiddenFolderInFolderA, 'file in hidden directory')
|
await fs.writeFile(fileInHiddenFolderInFolderA, 'file in hidden directory')
|
||||||
/*
|
|
||||||
Directory structure of files that get created:
|
|
||||||
root/
|
|
||||||
.hidden-folder/
|
|
||||||
folder-in-hidden-folder/
|
|
||||||
file.txt
|
|
||||||
folder-a/
|
|
||||||
.hidden-folder-in-folder-a/
|
|
||||||
file.txt
|
|
||||||
folder-b/
|
|
||||||
folder-c/
|
|
||||||
search-item1.txt
|
|
||||||
extraSearch-item1.txt
|
|
||||||
extra-file-in-folder-c.txt
|
|
||||||
folder-e/
|
|
||||||
folder-d/
|
|
||||||
search-item2.txt
|
|
||||||
search-item3.txt
|
|
||||||
search-item4.txt
|
|
||||||
extraSearch-item2.txt
|
|
||||||
folder-f/
|
|
||||||
extraSearch-item3.txt
|
|
||||||
folder-g/
|
|
||||||
folder-h/
|
|
||||||
amazing-item.txt
|
|
||||||
folder-i/
|
|
||||||
extraSearch-item4.txt
|
|
||||||
extraSearch-item5.txt
|
|
||||||
folder-j/
|
|
||||||
folder-k/
|
|
||||||
lonely-file.txt
|
|
||||||
.hidden-file.txt
|
|
||||||
search-item5.txt
|
|
||||||
*/
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Single file search - Absolute Path', async () => {
|
test('Single file search - Absolute Path', async () => {
|
||||||
const searchResult = await findFilesToUpload(extraFileInFolderCPath)
|
const searchResult = await findFilesToUpload(extraFileInFolderCPath)
|
||||||
expect(searchResult.filesToUpload.length).toEqual(1)
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
||||||
expect(searchResult.filesToUpload[0]).toEqual(extraFileInFolderCPath)
|
expect(searchResult.filesToUpload[0]).toEqual(extraFileInFolderCPath)
|
||||||
@ -181,7 +173,7 @@ describe('Search', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Single file search - Relative Path', async () => {
|
test('Single file search - Relative Path', async () => {
|
||||||
const relativePath = path.join(
|
const relativePath = path.join(
|
||||||
'__tests__',
|
'__tests__',
|
||||||
'_temp',
|
'_temp',
|
||||||
@ -200,7 +192,7 @@ describe('Search', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Single file using wildcard', async () => {
|
test('Single file using wildcard', async () => {
|
||||||
const expectedRoot = path.join(root, 'folder-h')
|
const expectedRoot = path.join(root, 'folder-h')
|
||||||
const searchPath = path.join(root, 'folder-h', '**/*lonely*')
|
const searchPath = path.join(root, 'folder-h', '**/*lonely*')
|
||||||
const searchResult = await findFilesToUpload(searchPath)
|
const searchResult = await findFilesToUpload(searchPath)
|
||||||
@ -209,7 +201,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.rootDirectory).toEqual(expectedRoot)
|
expect(searchResult.rootDirectory).toEqual(expectedRoot)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Single file using directory', async () => {
|
test('Single file using directory', async () => {
|
||||||
const searchPath = path.join(root, 'folder-h', 'folder-j')
|
const searchPath = path.join(root, 'folder-h', 'folder-j')
|
||||||
const searchResult = await findFilesToUpload(searchPath)
|
const searchResult = await findFilesToUpload(searchPath)
|
||||||
expect(searchResult.filesToUpload.length).toEqual(1)
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
||||||
@ -217,7 +209,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.rootDirectory).toEqual(searchPath)
|
expect(searchResult.rootDirectory).toEqual(searchPath)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Directory search - Absolute Path', async () => {
|
test('Directory search - Absolute Path', async () => {
|
||||||
const searchPath = path.join(root, 'folder-h')
|
const searchPath = path.join(root, 'folder-h')
|
||||||
const searchResult = await findFilesToUpload(searchPath)
|
const searchResult = await findFilesToUpload(searchPath)
|
||||||
expect(searchResult.filesToUpload.length).toEqual(4)
|
expect(searchResult.filesToUpload.length).toEqual(4)
|
||||||
@ -236,7 +228,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.rootDirectory).toEqual(searchPath)
|
expect(searchResult.rootDirectory).toEqual(searchPath)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Directory search - Relative Path', async () => {
|
test('Directory search - Relative Path', async () => {
|
||||||
const searchPath = path.join('__tests__', '_temp', 'search', 'folder-h')
|
const searchPath = path.join('__tests__', '_temp', 'search', 'folder-h')
|
||||||
const expectedRootDirectory = path.join(root, 'folder-h')
|
const expectedRootDirectory = path.join(root, 'folder-h')
|
||||||
const searchResult = await findFilesToUpload(searchPath)
|
const searchResult = await findFilesToUpload(searchPath)
|
||||||
@ -256,7 +248,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.rootDirectory).toEqual(expectedRootDirectory)
|
expect(searchResult.rootDirectory).toEqual(expectedRootDirectory)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Wildcard search - Absolute Path', async () => {
|
test('Wildcard search - Absolute Path', async () => {
|
||||||
const searchPath = path.join(root, '**/*[Ss]earch*')
|
const searchPath = path.join(root, '**/*[Ss]earch*')
|
||||||
const searchResult = await findFilesToUpload(searchPath)
|
const searchResult = await findFilesToUpload(searchPath)
|
||||||
expect(searchResult.filesToUpload.length).toEqual(10)
|
expect(searchResult.filesToUpload.length).toEqual(10)
|
||||||
@ -285,7 +277,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.rootDirectory).toEqual(root)
|
expect(searchResult.rootDirectory).toEqual(root)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Wildcard search - Relative Path', async () => {
|
test('Wildcard search - Relative Path', async () => {
|
||||||
const searchPath = path.join(
|
const searchPath = path.join(
|
||||||
'__tests__',
|
'__tests__',
|
||||||
'_temp',
|
'_temp',
|
||||||
@ -319,7 +311,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.rootDirectory).toEqual(root)
|
expect(searchResult.rootDirectory).toEqual(root)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Multi path search - root directory', async () => {
|
test('Multi path search - root directory', async () => {
|
||||||
const searchPath1 = path.join(root, 'folder-a')
|
const searchPath1 = path.join(root, 'folder-a')
|
||||||
const searchPath2 = path.join(root, 'folder-d')
|
const searchPath2 = path.join(root, 'folder-d')
|
||||||
|
|
||||||
@ -343,7 +335,7 @@ describe('Search', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Multi path search - with exclude character', async () => {
|
test('Multi path search - with exclude character', async () => {
|
||||||
const searchPath1 = path.join(root, 'folder-a')
|
const searchPath1 = path.join(root, 'folder-a')
|
||||||
const searchPath2 = path.join(root, 'folder-d')
|
const searchPath2 = path.join(root, 'folder-d')
|
||||||
const searchPath3 = path.join(root, 'folder-a', 'folder-b', '**/extra*.txt')
|
const searchPath3 = path.join(root, 'folder-a', 'folder-b', '**/extra*.txt')
|
||||||
@ -363,7 +355,7 @@ describe('Search', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Multi path search - non root directory', async () => {
|
test('Multi path search - non root directory', async () => {
|
||||||
const searchPath1 = path.join(root, 'folder-h', 'folder-i')
|
const searchPath1 = path.join(root, 'folder-h', 'folder-i')
|
||||||
const searchPath2 = path.join(root, 'folder-h', 'folder-j', 'folder-k')
|
const searchPath2 = path.join(root, 'folder-h', 'folder-j', 'folder-k')
|
||||||
const searchPath3 = amazingFileInFolderHPath
|
const searchPath3 = amazingFileInFolderHPath
|
||||||
@ -385,7 +377,7 @@ describe('Search', () => {
|
|||||||
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
|
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Hidden files ignored by default', async () => {
|
test('Hidden files ignored by default', async () => {
|
||||||
const searchPath = path.join(root, '**/*')
|
const searchPath = path.join(root, '**/*')
|
||||||
const searchResult = await findFilesToUpload(searchPath)
|
const searchResult = await findFilesToUpload(searchPath)
|
||||||
|
|
||||||
@ -396,7 +388,7 @@ describe('Search', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Hidden files included', async () => {
|
test('Hidden files included', async () => {
|
||||||
const searchPath = path.join(root, '**/*')
|
const searchPath = path.join(root, '**/*')
|
||||||
const searchResult = await findFilesToUpload(searchPath, true)
|
const searchResult = await findFilesToUpload(searchPath, true)
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,58 @@
|
|||||||
import * as core from '@actions/core'
|
import {jest, describe, test, expect, beforeEach} from '@jest/globals'
|
||||||
import * as github from '@actions/github'
|
|
||||||
import artifact, {ArtifactNotFoundError} from '@actions/artifact'
|
// Mock @actions/github before importing modules that use it
|
||||||
import {run} from '../src/upload/upload-artifact'
|
jest.unstable_mockModule('@actions/github', () => ({
|
||||||
import {Inputs} from '../src/upload/constants'
|
context: {
|
||||||
import * as search from '../src/shared/search'
|
repo: {
|
||||||
|
owner: 'actions',
|
||||||
|
repo: 'toolkit'
|
||||||
|
},
|
||||||
|
runId: 123,
|
||||||
|
serverUrl: 'https://github.com'
|
||||||
|
},
|
||||||
|
getOctokit: jest.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Mock @actions/core
|
||||||
|
jest.unstable_mockModule('@actions/core', () => ({
|
||||||
|
getInput: jest.fn(),
|
||||||
|
getBooleanInput: jest.fn(),
|
||||||
|
setOutput: jest.fn(),
|
||||||
|
setFailed: jest.fn(),
|
||||||
|
setSecret: jest.fn(),
|
||||||
|
info: jest.fn(),
|
||||||
|
warning: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
notice: jest.fn(),
|
||||||
|
startGroup: jest.fn(),
|
||||||
|
endGroup: jest.fn(),
|
||||||
|
isDebug: jest.fn(() => false),
|
||||||
|
getState: jest.fn(),
|
||||||
|
saveState: jest.fn(),
|
||||||
|
exportVariable: jest.fn(),
|
||||||
|
addPath: jest.fn(),
|
||||||
|
group: jest.fn((name: string, fn: () => Promise<unknown>) => fn()),
|
||||||
|
toPlatformPath: jest.fn((p: string) => p),
|
||||||
|
toWin32Path: jest.fn((p: string) => p),
|
||||||
|
toPosixPath: jest.fn((p: string) => p)
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Mock shared search module
|
||||||
|
const mockFindFilesToUpload = jest.fn<
|
||||||
|
() => Promise<{filesToUpload: string[]; rootDirectory: string}>
|
||||||
|
>()
|
||||||
|
jest.unstable_mockModule('../src/shared/search.js', () => ({
|
||||||
|
findFilesToUpload: mockFindFilesToUpload
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Dynamic imports after mocking
|
||||||
|
const core = await import('@actions/core')
|
||||||
|
const github = await import('@actions/github')
|
||||||
|
const artifact = await import('@actions/artifact')
|
||||||
|
const {run} = await import('../src/upload/upload-artifact.js')
|
||||||
|
const {Inputs} = await import('../src/upload/constants.js')
|
||||||
|
const {ArtifactNotFoundError} = artifact
|
||||||
|
|
||||||
const fixtures = {
|
const fixtures = {
|
||||||
artifactName: 'artifact-name',
|
artifactName: 'artifact-name',
|
||||||
@ -14,22 +63,10 @@ const fixtures = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
jest.mock('@actions/github', () => ({
|
const mockInputs = (
|
||||||
context: {
|
overrides?: Partial<{[K in (typeof Inputs)[keyof typeof Inputs]]?: any}>
|
||||||
repo: {
|
) => {
|
||||||
owner: 'actions',
|
const inputs: Record<string, any> = {
|
||||||
repo: 'toolkit'
|
|
||||||
},
|
|
||||||
runId: 123,
|
|
||||||
serverUrl: 'https://github.com'
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
jest.mock('@actions/core')
|
|
||||||
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
|
||||||
const inputs = {
|
|
||||||
[Inputs.Name]: 'artifact-name',
|
[Inputs.Name]: 'artifact-name',
|
||||||
[Inputs.Path]: '/some/artifact/path',
|
[Inputs.Path]: '/some/artifact/path',
|
||||||
[Inputs.IfNoFilesFound]: 'warn',
|
[Inputs.IfNoFilesFound]: 'warn',
|
||||||
@ -39,10 +76,14 @@ const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
|||||||
...overrides
|
...overrides
|
||||||
}
|
}
|
||||||
|
|
||||||
;(core.getInput as jest.Mock).mockImplementation((name: string) => {
|
;(core.getInput as jest.Mock<typeof core.getInput>).mockImplementation(
|
||||||
return inputs[name]
|
(name: string) => {
|
||||||
})
|
return inputs[name]
|
||||||
;(core.getBooleanInput as jest.Mock).mockImplementation((name: string) => {
|
}
|
||||||
|
)
|
||||||
|
;(
|
||||||
|
core.getBooleanInput as jest.Mock<typeof core.getBooleanInput>
|
||||||
|
).mockImplementation((name: string) => {
|
||||||
return inputs[name]
|
return inputs[name]
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -52,28 +93,29 @@ const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
|||||||
describe('upload', () => {
|
describe('upload', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockInputs()
|
mockInputs()
|
||||||
|
jest.clearAllMocks()
|
||||||
|
|
||||||
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
mockFindFilesToUpload.mockResolvedValue({
|
||||||
filesToUpload: fixtures.filesToUpload,
|
filesToUpload: fixtures.filesToUpload,
|
||||||
rootDirectory: fixtures.rootDirectory
|
rootDirectory: fixtures.rootDirectory
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(artifact, 'uploadArtifact').mockResolvedValue({
|
jest.spyOn(artifact.default, 'uploadArtifact').mockResolvedValue({
|
||||||
size: 123,
|
size: 123,
|
||||||
id: 1337,
|
id: 1337,
|
||||||
digest: 'facefeed'
|
digest: 'facefeed'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('uploads a single file', async () => {
|
test('uploads a single file', async () => {
|
||||||
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
mockFindFilesToUpload.mockResolvedValue({
|
||||||
filesToUpload: [fixtures.filesToUpload[0]],
|
filesToUpload: [fixtures.filesToUpload[0]],
|
||||||
rootDirectory: fixtures.rootDirectory
|
rootDirectory: fixtures.rootDirectory
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
[fixtures.filesToUpload[0]],
|
[fixtures.filesToUpload[0]],
|
||||||
fixtures.rootDirectory,
|
fixtures.rootDirectory,
|
||||||
@ -81,10 +123,10 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('uploads multiple files', async () => {
|
test('uploads multiple files', async () => {
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.rootDirectory,
|
fixtures.rootDirectory,
|
||||||
@ -92,27 +134,25 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sets outputs', async () => {
|
test('sets outputs', async () => {
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(core.setOutput).toHaveBeenCalledWith('artifact-id', 1337)
|
expect(core.setOutput).toHaveBeenCalledWith('artifact-id', 1337)
|
||||||
expect(core.setOutput).toHaveBeenCalledWith('artifact-digest', 'facefeed')
|
expect(core.setOutput).toHaveBeenCalledWith('artifact-digest', 'facefeed')
|
||||||
expect(core.setOutput).toHaveBeenCalledWith(
|
expect(core.setOutput).toHaveBeenCalledWith(
|
||||||
'artifact-url',
|
'artifact-url',
|
||||||
`${github.context.serverUrl}/${github.context.repo.owner}/${
|
`${github.context.serverUrl}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}/artifacts/${1337}`
|
||||||
github.context.repo.repo
|
|
||||||
}/actions/runs/${github.context.runId}/artifacts/${1337}`
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports custom compression level', async () => {
|
test('supports custom compression level', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.CompressionLevel]: 2
|
[Inputs.CompressionLevel]: 2
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.rootDirectory,
|
fixtures.rootDirectory,
|
||||||
@ -120,14 +160,14 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports custom retention days', async () => {
|
test('supports custom retention days', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.RetentionDays]: 7
|
[Inputs.RetentionDays]: 7
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.rootDirectory,
|
fixtures.rootDirectory,
|
||||||
@ -135,12 +175,12 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports warn if-no-files-found', async () => {
|
test('supports warn if-no-files-found', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.IfNoFilesFound]: 'warn'
|
[Inputs.IfNoFilesFound]: 'warn'
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
mockFindFilesToUpload.mockResolvedValue({
|
||||||
filesToUpload: [],
|
filesToUpload: [],
|
||||||
rootDirectory: fixtures.rootDirectory
|
rootDirectory: fixtures.rootDirectory
|
||||||
})
|
})
|
||||||
@ -152,12 +192,12 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports error if-no-files-found', async () => {
|
test('supports error if-no-files-found', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.IfNoFilesFound]: 'error'
|
[Inputs.IfNoFilesFound]: 'error'
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
mockFindFilesToUpload.mockResolvedValue({
|
||||||
filesToUpload: [],
|
filesToUpload: [],
|
||||||
rootDirectory: fixtures.rootDirectory
|
rootDirectory: fixtures.rootDirectory
|
||||||
})
|
})
|
||||||
@ -169,12 +209,12 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports ignore if-no-files-found', async () => {
|
test('supports ignore if-no-files-found', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.IfNoFilesFound]: 'ignore'
|
[Inputs.IfNoFilesFound]: 'ignore'
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
mockFindFilesToUpload.mockResolvedValue({
|
||||||
filesToUpload: [],
|
filesToUpload: [],
|
||||||
rootDirectory: fixtures.rootDirectory
|
rootDirectory: fixtures.rootDirectory
|
||||||
})
|
})
|
||||||
@ -186,46 +226,50 @@ describe('upload', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports overwrite', async () => {
|
test('supports overwrite', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.Overwrite]: true
|
[Inputs.Overwrite]: true
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.spyOn(artifact, 'deleteArtifact').mockResolvedValue({
|
jest.spyOn(artifact.default, 'deleteArtifact').mockResolvedValue({
|
||||||
id: 1337
|
id: 1337
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.rootDirectory,
|
fixtures.rootDirectory,
|
||||||
{compressionLevel: 6}
|
{compressionLevel: 6}
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(artifact.deleteArtifact).toHaveBeenCalledWith(fixtures.artifactName)
|
expect(artifact.default.deleteArtifact).toHaveBeenCalledWith(
|
||||||
|
fixtures.artifactName
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('supports overwrite and continues if not found', async () => {
|
test('supports overwrite and continues if not found', async () => {
|
||||||
mockInputs({
|
mockInputs({
|
||||||
[Inputs.Overwrite]: true
|
[Inputs.Overwrite]: true
|
||||||
})
|
})
|
||||||
|
|
||||||
jest
|
jest
|
||||||
.spyOn(artifact, 'deleteArtifact')
|
.spyOn(artifact.default, 'deleteArtifact')
|
||||||
.mockRejectedValue(new ArtifactNotFoundError('not found'))
|
.mockRejectedValue(new ArtifactNotFoundError('not found'))
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
expect(artifact.default.uploadArtifact).toHaveBeenCalledWith(
|
||||||
fixtures.artifactName,
|
fixtures.artifactName,
|
||||||
fixtures.filesToUpload,
|
fixtures.filesToUpload,
|
||||||
fixtures.rootDirectory,
|
fixtures.rootDirectory,
|
||||||
{compressionLevel: 6}
|
{compressionLevel: 6}
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(artifact.deleteArtifact).toHaveBeenCalledWith(fixtures.artifactName)
|
expect(artifact.default.deleteArtifact).toHaveBeenCalledWith(
|
||||||
|
fixtures.artifactName
|
||||||
|
)
|
||||||
expect(core.debug).toHaveBeenCalledWith(
|
expect(core.debug).toHaveBeenCalledWith(
|
||||||
`Skipping deletion of '${fixtures.artifactName}', it does not exist`
|
`Skipping deletion of '${fixtures.artifactName}', it does not exist`
|
||||||
)
|
)
|
||||||
|
|||||||
53
eslint.config.mjs
Normal file
53
eslint.config.mjs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import github from 'eslint-plugin-github'
|
||||||
|
import jest from 'eslint-plugin-jest'
|
||||||
|
import prettier from 'eslint-plugin-prettier/recommended'
|
||||||
|
|
||||||
|
const githubConfigs = github.getFlatConfigs()
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: ['**/node_modules/**', '**/lib/**', '**/dist/**']
|
||||||
|
},
|
||||||
|
githubConfigs.recommended,
|
||||||
|
...githubConfigs.typescript,
|
||||||
|
prettier,
|
||||||
|
{
|
||||||
|
files: ['**/*.ts'],
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
project: './tsconfig.eslint.json'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'prettier/prettier': ['error', {endOfLine: 'auto'}],
|
||||||
|
'eslint-comments/no-use': 'off',
|
||||||
|
'github/no-then': 'off',
|
||||||
|
'github/filenames-match-regex': 'off',
|
||||||
|
'github/array-foreach': 'off',
|
||||||
|
'import/no-namespace': 'off',
|
||||||
|
'import/no-commonjs': 'off',
|
||||||
|
'import/named': 'off',
|
||||||
|
'import/no-unresolved': 'off',
|
||||||
|
'i18n-text/no-en': 'off',
|
||||||
|
'filenames/match-regex': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'no-undef': 'off',
|
||||||
|
camelcase: 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-shadow': 'off',
|
||||||
|
'@typescript-eslint/array-type': 'off',
|
||||||
|
'@typescript-eslint/no-require-imports': 'off'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/__tests__/**/*.ts'],
|
||||||
|
...jest.configs['flat/recommended'],
|
||||||
|
rules: {
|
||||||
|
...jest.configs['flat/recommended'].rules,
|
||||||
|
'jest/expect-expect': 'off',
|
||||||
|
'jest/no-conditional-expect': 'off'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -1,12 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
clearMocks: true,
|
|
||||||
moduleFileExtensions: ['js', 'ts'],
|
|
||||||
roots: ['<rootDir>'],
|
|
||||||
testEnvironment: 'node',
|
|
||||||
testMatch: ['**/*.test.ts'],
|
|
||||||
testRunner: 'jest-circus/runner',
|
|
||||||
transform: {
|
|
||||||
'^.+\\.ts$': 'ts-jest'
|
|
||||||
},
|
|
||||||
verbose: true
|
|
||||||
}
|
|
||||||
24
jest.config.ts
Normal file
24
jest.config.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export default {
|
||||||
|
clearMocks: true,
|
||||||
|
moduleFileExtensions: ['js', 'ts'],
|
||||||
|
roots: ['<rootDir>'],
|
||||||
|
testEnvironment: 'node',
|
||||||
|
testMatch: ['**/*.test.ts'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.ts$': [
|
||||||
|
'ts-jest',
|
||||||
|
{
|
||||||
|
useESM: true,
|
||||||
|
diagnostics: {
|
||||||
|
ignoreCodes: [151002]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
transformIgnorePatterns: ['node_modules/(?!(@actions)/)'],
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^(\\.{1,2}/.*)\\.js$': '$1'
|
||||||
|
},
|
||||||
|
verbose: true
|
||||||
|
}
|
||||||
4426
package-lock.json
generated
4426
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@ -2,6 +2,7 @@
|
|||||||
"name": "upload-artifact",
|
"name": "upload-artifact",
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"description": "Upload an Actions Artifact in a workflow run",
|
"description": "Upload an Actions Artifact in a workflow run",
|
||||||
|
"type": "module",
|
||||||
"main": "dist/upload/index.js",
|
"main": "dist/upload/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
@ -10,7 +11,7 @@
|
|||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --write **/*.ts",
|
||||||
"format-check": "prettier --check **/*.ts",
|
"format-check": "prettier --check **/*.ts",
|
||||||
"lint": "eslint **/*.ts",
|
"lint": "eslint **/*.ts",
|
||||||
"test": "jest --testTimeout 10000"
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testTimeout 10000"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -32,32 +33,29 @@
|
|||||||
"node": ">=24"
|
"node": ">=24"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^5.0.0",
|
"@actions/artifact": "^6.1.0",
|
||||||
"@actions/core": "^2.0.0",
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^9.0.0",
|
||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.6.1",
|
||||||
"@actions/io": "^2.0.0",
|
"@actions/io": "^3.0.2",
|
||||||
"minimatch": "^9.0.3"
|
"minimatch": "^9.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.2.5",
|
"@types/jest": "^30.0.0",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^25.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
||||||
"@typescript-eslint/parser": "^7.18.0",
|
"@typescript-eslint/parser": "^8.54.0",
|
||||||
"@vercel/ncc": "^0.36.0",
|
"@vercel/ncc": "^0.38.4",
|
||||||
"concurrently": "^7.6.0",
|
"concurrently": "^9.2.1",
|
||||||
"eslint": "^8.31.0",
|
"eslint": "^9.39.2",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-plugin-github": "^6.0.0",
|
||||||
"eslint-plugin-github": "^4.6.0",
|
"eslint-plugin-jest": "^29.12.1",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"eslint-plugin-jest": "^28.14.0",
|
"jest": "^30.2.0",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"prettier": "^3.8.1",
|
||||||
"glob": "^8.0.3",
|
"ts-jest": "^29.2.6",
|
||||||
"jest": "^29.3.1",
|
"ts-node": "^10.9.2",
|
||||||
"jest-circus": "^29.3.1",
|
"typescript": "^5.3.3"
|
||||||
"prettier": "^3.7.4",
|
|
||||||
"ts-jest": "^29.0.3",
|
|
||||||
"typescript": "^5.2.2"
|
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"uri-js": "npm:uri-js-replace@^1.0.1"
|
"uri-js": "npm:uri-js-replace@^1.0.1"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {run} from './merge-artifacts'
|
import {run} from './merge-artifacts.js'
|
||||||
|
|
||||||
run().catch(error => {
|
run().catch(error => {
|
||||||
core.setFailed((error as Error).message)
|
core.setFailed((error as Error).message)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Inputs} from './constants'
|
import {Inputs} from './constants.js'
|
||||||
import {MergeInputs} from './merge-inputs'
|
import {MergeInputs} from './merge-inputs.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to get all the inputs for the action
|
* Helper to get all the inputs for the action
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import {mkdtemp, rm} from 'fs/promises'
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Minimatch} from 'minimatch'
|
import {Minimatch} from 'minimatch'
|
||||||
import artifactClient, {UploadArtifactOptions} from '@actions/artifact'
|
import artifactClient, {UploadArtifactOptions} from '@actions/artifact'
|
||||||
import {getInputs} from './input-helper'
|
import {getInputs} from './input-helper.js'
|
||||||
import {uploadArtifact} from '../shared/upload-artifact'
|
import {uploadArtifact} from '../shared/upload-artifact.js'
|
||||||
import {findFilesToUpload} from '../shared/search'
|
import {findFilesToUpload} from '../shared/search.js'
|
||||||
|
|
||||||
const PARALLEL_DOWNLOADS = 5
|
const PARALLEL_DOWNLOADS = 5
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {run} from './upload-artifact'
|
import {run} from './upload-artifact.js'
|
||||||
|
|
||||||
run().catch(error => {
|
run().catch(error => {
|
||||||
core.setFailed((error as Error).message)
|
core.setFailed((error as Error).message)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Inputs, NoFileOptions} from './constants'
|
import {Inputs, NoFileOptions} from './constants.js'
|
||||||
import {UploadInputs} from './upload-inputs'
|
import {UploadInputs} from './upload-inputs.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to get all the inputs for the action
|
* Helper to get all the inputs for the action
|
||||||
|
|||||||
@ -3,10 +3,10 @@ import artifact, {
|
|||||||
UploadArtifactOptions,
|
UploadArtifactOptions,
|
||||||
ArtifactNotFoundError
|
ArtifactNotFoundError
|
||||||
} from '@actions/artifact'
|
} from '@actions/artifact'
|
||||||
import {findFilesToUpload} from '../shared/search'
|
import {findFilesToUpload} from '../shared/search.js'
|
||||||
import {getInputs} from './input-helper'
|
import {getInputs} from './input-helper.js'
|
||||||
import {NoFileOptions} from './constants'
|
import {NoFileOptions} from './constants.js'
|
||||||
import {uploadArtifact} from '../shared/upload-artifact'
|
import {uploadArtifact} from '../shared/upload-artifact.js'
|
||||||
|
|
||||||
async function deleteArtifactIfExists(artifactName: string): Promise<void> {
|
async function deleteArtifactIfExists(artifactName: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import {NoFileOptions} from './constants'
|
import {NoFileOptions} from './constants.js'
|
||||||
|
|
||||||
export interface UploadInputs {
|
export interface UploadInputs {
|
||||||
/**
|
/**
|
||||||
|
|||||||
8
tsconfig.eslint.json
Normal file
8
tsconfig.eslint.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "."
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "__tests__/**/*.ts", "*.ts"],
|
||||||
|
"exclude": ["node_modules", "lib", "dist"]
|
||||||
|
}
|
||||||
@ -1,17 +1,13 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "ES2022",
|
||||||
"module": "commonjs",
|
"module": "NodeNext",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "NodeNext",
|
||||||
"allowSyntheticDefaultImports": true,
|
"esModuleInterop": true
|
||||||
"esModuleInterop": true,
|
},
|
||||||
"declaration": false,
|
"exclude": ["node_modules", "**/*.test.ts", "jest.config.ts", "__tests__"]
|
||||||
"sourceMap": true,
|
}
|
||||||
"lib": ["es6"]
|
|
||||||
},
|
|
||||||
"exclude": ["node_modules", "**/*.test.ts"]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user