Skip to content

Commit

Permalink
Fixes #1 Allow for multiple artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
ncipollo committed Sep 3, 2019
1 parent 261c1fc commit a698287
Show file tree
Hide file tree
Showing 24 changed files with 462 additions and 167 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
This action will create a github release and optionally upload an artifact to it.

## Action Inputs
- **artifact**: A path to an optional artifact to upload to the release.
- **artifact**: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
- **artifacts**: 'An optional set of paths representing artifacts to upload to the release. This may be a single path or a comma delimited list of paths (or globs).
- **artifactContentType**: The content type of the artifact. Defaults to raw.
- **body**: An optional body for the release.
- **bodyFile**: An optional body file for the release. This should be the path to the file.
Expand Down Expand Up @@ -32,7 +33,7 @@ jobs:
- uses: actions/checkout@v1
- uses: ncipollo/release-action@v1
with:
artifact: "release.tar.gz"
artifacts: "release.tar.gz,foo/*.txt"
bodyFile: "body.md"
token: ${{ secrets.GITHUB_TOKEN }}

Expand Down
36 changes: 22 additions & 14 deletions __tests__/Action.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Action } from "../src/Action";
import { Artifact } from "../src/Artifact";
import { Inputs } from "../src/Inputs";
import { Releases } from "../src/Releases";
import { ArtifactUploader } from "../src/ArtifactUploader";

const createMock = jest.fn()
const uploadMock = jest.fn()

const artifactPath = 'a/path'
const artifactName = 'path'
const artifactData = Buffer.from('blob','utf-8')
const artifacts = [
new Artifact('a/art1'),
new Artifact('b/art2')
]
const artifactData = Buffer.from('blob', 'utf-8')
const body = 'body'
const commit = 'commit'
const contentType = "raw"
Expand Down Expand Up @@ -44,7 +48,7 @@ describe("Action", () => {
await action.perform()

expect(createMock).toBeCalledWith(tag, body, commit, draft, name)
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactData, 'path')
expect(uploadMock).toBeCalledWith(artifacts, url)
})

it('throws error when create fails', async () => {
Expand Down Expand Up @@ -79,28 +83,25 @@ describe("Action", () => {
}

expect(createMock).toBeCalledWith(tag, body, commit, draft, name)
expect(uploadMock).toBeCalledWith(url, contentLength, contentType, artifactData, 'path')
expect(uploadMock).toBeCalledWith(artifacts, url)
})

function createAction(hasArtifact: boolean): Action {
let artifact: string
let inputArtifact: Artifact[]
if (hasArtifact) {
artifact = artifactPath
inputArtifact = artifacts
} else {
artifact = ''
inputArtifact = []
}
const MockReleases = jest.fn<Releases, any>(() => {
return {
create: createMock,
uploadArtifact: uploadMock
uploadArtifact: jest.fn()
}
})
const MockInputs = jest.fn<Inputs, any>(() => {
return {
artifact: artifact,
artifactName: artifactName,
artifactContentType: contentType,
artifactContentLength: contentLength,
artifacts: inputArtifact,
body: body,
commit: commit,
draft: draft,
Expand All @@ -110,9 +111,16 @@ describe("Action", () => {
readArtifact: () => artifactData
}
})
const MockUploader = jest.fn<ArtifactUploader, any>(() => {
return {
uploadArtifacts: uploadMock
}
})

const inputs = new MockInputs()
const releases = new MockReleases()
const uploader = new MockUploader()

return new Action(inputs, releases)
return new Action(inputs, releases, uploader)
}
})
38 changes: 38 additions & 0 deletions __tests__/Artifact.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Artifact } from "../src/Artifact";

const fileContents = Buffer.from('artful facts', 'utf-8')
const contentLength = 42

jest.mock('fs', () => {
return {
readFileSync: () => fileContents,
statSync: () => { return { size: contentLength } }
};
})

describe("Artifact", () => {
it('defaults contentType to raw', () => {
const artifact = new Artifact('')
expect(artifact.contentType).toBe('raw')
})

it('generates name from path', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.name).toBe('artifact')
})

it('provides contentLength', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.contentLength).toBe(contentLength)
})

it('provides path', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.path).toBe('some/artifact')
})

it('reads artifact', () => {
const artifact = new Artifact('some/artifact')
expect(artifact.readFile()).toBe(fileContents)
})
})
39 changes: 39 additions & 0 deletions __tests__/ArtifactGlobber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
import { Globber } from "../src/Globber";
import { Artifact } from "../src/Artifact";

const contentType = "raw"
const globResults = ["file1", "file2"]

describe("ArtifactGlobber", () => {
it("globs simple path", () => {
const globber = createArtifactGlobber()

const expectedArtifacts =
globResults.map((path) => new Artifact(path, contentType))

expect(globber.globArtifactString('path', 'raw'))
.toEqual(expectedArtifacts)
})

it("splits multiple paths", () => {
const globber = createArtifactGlobber()

const expectedArtifacts =
globResults
.concat(globResults)
.map((path) => new Artifact(path, contentType))

expect(globber.globArtifactString('path1,path2', 'raw'))
.toEqual(expectedArtifacts)
})

function createArtifactGlobber(): FileArtifactGlobber {
const MockGlobber = jest.fn<Globber, any>(() => {
return {
glob: () => globResults
}
})
return new FileArtifactGlobber(new MockGlobber())
}
})
43 changes: 43 additions & 0 deletions __tests__/ArtifactUploader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Artifact } from "../src/Artifact"
import { GithubArtifactUploader } from "../src/ArtifactUploader"
import { Releases } from "../src/Releases";

const artifacts = [
new Artifact('a/art1'),
new Artifact('b/art2')
]
const fileContents = Buffer.from('artful facts', 'utf-8')
const contentLength = 42
const uploadMock = jest.fn()
const url = 'http://api.example.com'

jest.mock('fs', () => {
return {
readFileSync: () => fileContents,
statSync: () => { return { size: contentLength } }
};
})

describe('ArtifactUploader', () => {
it('uploads artifacts', () => {
const uploader = createUploader()

uploader.uploadArtifacts(artifacts, url)

expect(uploadMock).toBeCalledTimes(2)
expect(uploadMock)
.toBeCalledWith(url, contentLength, 'raw', fileContents, 'art1')
expect(uploadMock)
.toBeCalledWith(url, contentLength, 'raw', fileContents, 'art2')
})

function createUploader(): GithubArtifactUploader {
const MockReleases = jest.fn<Releases, any>(() => {
return {
create: jest.fn(),
uploadArtifact: uploadMock
}
})
return new GithubArtifactUploader(new MockReleases())
}
});
Loading

0 comments on commit a698287

Please sign in to comment.