Skip to content

Commit

Permalink
Merge pull request #504 from actions/robherley/reorganize
Browse files Browse the repository at this point in the history
Reorganize upload code in prep for merge logic & add more tests
  • Loading branch information
robherley committed Jan 22, 2024
2 parents 694cdab + da58a3f commit 52899c8
Show file tree
Hide file tree
Showing 14 changed files with 593 additions and 256 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/check-dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
run: npm ci

- name: Rebuild the dist/ directory
run: npm run build
run: npm run release

- name: Compare the expected and actual dist/ directories
run: |
Expand Down
2 changes: 1 addition & 1 deletion __tests__/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as core from '@actions/core'
import * as path from 'path'
import * as io from '@actions/io'
import {promises as fs} from 'fs'
import {findFilesToUpload} from '../src/search'
import {findFilesToUpload} from '../src/shared/search'

const root = path.join(__dirname, '_temp', 'search')
const searchItem1Path = path.join(
Expand Down
231 changes: 231 additions & 0 deletions __tests__/upload.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import artifact, {ArtifactNotFoundError} from '@actions/artifact'
import {run} from '../src/upload/upload-artifact'
import {Inputs} from '../src/upload/constants'
import * as search from '../src/shared/search'

const fixtures = {
artifactName: 'artifact-name',
rootDirectory: '/some/artifact/path',
filesToUpload: [
'/some/artifact/path/file1.txt',
'/some/artifact/path/file2.txt'
]
}

jest.mock('@actions/github', () => ({
context: {
repo: {
owner: 'actions',
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.Path]: '/some/artifact/path',
[Inputs.IfNoFilesFound]: 'warn',
[Inputs.RetentionDays]: 0,
[Inputs.CompressionLevel]: 6,
[Inputs.Overwrite]: false,
...overrides
}

;(core.getInput as jest.Mock).mockImplementation((name: string) => {
return inputs[name]
})
;(core.getBooleanInput as jest.Mock).mockImplementation((name: string) => {
return inputs[name]
})

return inputs
}

describe('upload', () => {
beforeEach(async () => {
mockInputs()

jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
filesToUpload: fixtures.filesToUpload,
rootDirectory: fixtures.rootDirectory
})

jest.spyOn(artifact, 'uploadArtifact').mockResolvedValue({
size: 123,
id: 1337
})
})

it('uploads a single file', async () => {
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
filesToUpload: [fixtures.filesToUpload[0]],
rootDirectory: fixtures.rootDirectory
})

await run()

expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
[fixtures.filesToUpload[0]],
fixtures.rootDirectory,
{compressionLevel: 6}
)
})

it('uploads multiple files', async () => {
await run()

expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.rootDirectory,
{compressionLevel: 6}
)
})

it('sets outputs', async () => {
await run()

expect(core.setOutput).toHaveBeenCalledWith('artifact-id', 1337)
expect(core.setOutput).toHaveBeenCalledWith(
'artifact-url',
`${github.context.serverUrl}/${github.context.repo.owner}/${
github.context.repo.repo
}/actions/runs/${github.context.runId}/artifacts/${1337}`
)
})

it('supports custom compression level', async () => {
mockInputs({
[Inputs.CompressionLevel]: 2
})

await run()

expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.rootDirectory,
{compressionLevel: 2}
)
})

it('supports custom retention days', async () => {
mockInputs({
[Inputs.RetentionDays]: 7
})

await run()

expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.rootDirectory,
{retentionDays: 7, compressionLevel: 6}
)
})

it('supports warn if-no-files-found', async () => {
mockInputs({
[Inputs.IfNoFilesFound]: 'warn'
})

jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
filesToUpload: [],
rootDirectory: fixtures.rootDirectory
})

await run()

expect(core.warning).toHaveBeenCalledWith(
`No files were found with the provided path: ${fixtures.rootDirectory}. No artifacts will be uploaded.`
)
})

it('supports error if-no-files-found', async () => {
mockInputs({
[Inputs.IfNoFilesFound]: 'error'
})

jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
filesToUpload: [],
rootDirectory: fixtures.rootDirectory
})

await run()

expect(core.setFailed).toHaveBeenCalledWith(
`No files were found with the provided path: ${fixtures.rootDirectory}. No artifacts will be uploaded.`
)
})

it('supports ignore if-no-files-found', async () => {
mockInputs({
[Inputs.IfNoFilesFound]: 'ignore'
})

jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
filesToUpload: [],
rootDirectory: fixtures.rootDirectory
})

await run()

expect(core.info).toHaveBeenCalledWith(
`No files were found with the provided path: ${fixtures.rootDirectory}. No artifacts will be uploaded.`
)
})

it('supports overwrite', async () => {
mockInputs({
[Inputs.Overwrite]: true
})

jest.spyOn(artifact, 'deleteArtifact').mockResolvedValue({
id: 1337
})

await run()

expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.rootDirectory,
{compressionLevel: 6}
)

expect(artifact.deleteArtifact).toHaveBeenCalledWith(fixtures.artifactName)
})

it('supports overwrite and continues if not found', async () => {
mockInputs({
[Inputs.Overwrite]: true
})

jest
.spyOn(artifact, 'deleteArtifact')
.mockRejectedValue(new ArtifactNotFoundError('not found'))

await run()

expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.rootDirectory,
{compressionLevel: 6}
)

expect(artifact.deleteArtifact).toHaveBeenCalledWith(fixtures.artifactName)
expect(core.debug).toHaveBeenCalledWith(
`Skipping deletion of '${fixtures.artifactName}', it does not exist`
)
})
})
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ outputs:
Common uses cases for such a download URL can be adding download links to artifacts in descriptions or comments on pull requests or issues.
runs:
using: 'node20'
main: 'dist/index.js'
main: 'dist/upload/index.js'

0 comments on commit 52899c8

Please sign in to comment.