Fixes #529 Add zip and tarball urls to output
This commit is contained in:
@@ -49,6 +49,8 @@ This action will create a GitHub release and optionally upload an artifact to it
|
|||||||
| id | The identifier of the created release. |
|
| id | The identifier of the created release. |
|
||||||
| html_url | The HTML URL of the release. |
|
| html_url | The HTML URL of the release. |
|
||||||
| upload_url | The URL for [uploading assets](https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#upload-a-release-asset) to the release. |
|
| upload_url | The URL for [uploading assets](https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#upload-a-release-asset) to the release. |
|
||||||
|
| tarball_url | The URL for downloading the release as a tarball (.tar.gz). |
|
||||||
|
| zipball_url | The URL for downloading the release as a zipball (.zip). |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
This example will create a release when a tag is pushed:
|
This example will create a release when a tag is pushed:
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ import type { Inputs } from "../src/Inputs"
|
|||||||
import type { Outputs } from "../src/Outputs"
|
import type { Outputs } from "../src/Outputs"
|
||||||
import type { Releases } from "../src/Releases"
|
import type { Releases } from "../src/Releases"
|
||||||
|
|
||||||
|
const TEST_URLS = {
|
||||||
|
UPLOAD_URL: "http://api.example.com",
|
||||||
|
HTML_URL: "https://github.com/owner/repo/releases/tag/v1.0.0",
|
||||||
|
TARBALL_URL: "https://api.github.com/repos/owner/repo/tarball/v1.0.0",
|
||||||
|
ZIPBALL_URL: "https://api.github.com/repos/owner/repo/zipball/v1.0.0",
|
||||||
|
} as const
|
||||||
|
|
||||||
const applyReleaseDataMock = jest.fn()
|
const applyReleaseDataMock = jest.fn()
|
||||||
const artifactDestroyMock = jest.fn()
|
const artifactDestroyMock = jest.fn()
|
||||||
const createMock = jest.fn()
|
const createMock = jest.fn()
|
||||||
@@ -38,7 +45,7 @@ const updateDraft = false
|
|||||||
const updateName = "updateName"
|
const updateName = "updateName"
|
||||||
const updatePrerelease = false
|
const updatePrerelease = false
|
||||||
const updateOnlyUnreleased = false
|
const updateOnlyUnreleased = false
|
||||||
const url = "http://api.example.com"
|
const url = TEST_URLS.UPLOAD_URL
|
||||||
const makeLatest = "legacy"
|
const makeLatest = "legacy"
|
||||||
const generatedReleaseBody = "test release notes"
|
const generatedReleaseBody = "test release notes"
|
||||||
|
|
||||||
@@ -421,6 +428,9 @@ describe("Action", () => {
|
|||||||
expect(applyReleaseDataMock).toHaveBeenCalledWith({
|
expect(applyReleaseDataMock).toHaveBeenCalledWith({
|
||||||
id: releaseId,
|
id: releaseId,
|
||||||
upload_url: url,
|
upload_url: url,
|
||||||
|
html_url: TEST_URLS.HTML_URL,
|
||||||
|
tarball_url: TEST_URLS.TARBALL_URL,
|
||||||
|
zipball_url: TEST_URLS.ZIPBALL_URL,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,6 +466,9 @@ describe("Action", () => {
|
|||||||
data: {
|
data: {
|
||||||
id: releaseId,
|
id: releaseId,
|
||||||
upload_url: url,
|
upload_url: url,
|
||||||
|
html_url: TEST_URLS.HTML_URL,
|
||||||
|
tarball_url: TEST_URLS.TARBALL_URL,
|
||||||
|
zipball_url: TEST_URLS.ZIPBALL_URL,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -477,6 +490,9 @@ describe("Action", () => {
|
|||||||
data: {
|
data: {
|
||||||
id: releaseId,
|
id: releaseId,
|
||||||
upload_url: url,
|
upload_url: url,
|
||||||
|
html_url: TEST_URLS.HTML_URL,
|
||||||
|
tarball_url: TEST_URLS.TARBALL_URL,
|
||||||
|
zipball_url: TEST_URLS.ZIPBALL_URL,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
uploadMock.mockResolvedValue({})
|
uploadMock.mockResolvedValue({})
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ describe("ArtifactGlobber", () => {
|
|||||||
const expectedArtifacts = globResults.map((path) => new Artifact(path, contentType))
|
const expectedArtifacts = globResults.map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString("~/path", "raw", false)).toEqual(expectedArtifacts)
|
expect(globber.globArtifactString("~/path", "raw", false)).toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith(untildify("~/path"))
|
expect(globMock).toHaveBeenCalledWith(untildify("~/path"))
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("globs simple path", () => {
|
it("globs simple path", () => {
|
||||||
@@ -49,8 +49,8 @@ describe("ArtifactGlobber", () => {
|
|||||||
const expectedArtifacts = globResults.map((path) => new Artifact(path, contentType))
|
const expectedArtifacts = globResults.map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString("path", "raw", false)).toEqual(expectedArtifacts)
|
expect(globber.globArtifactString("path", "raw", false)).toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith("path")
|
expect(globMock).toHaveBeenCalledWith("path")
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("splits multiple paths with comma separator", () => {
|
it("splits multiple paths with comma separator", () => {
|
||||||
@@ -59,9 +59,9 @@ describe("ArtifactGlobber", () => {
|
|||||||
const expectedArtifacts = globResults.concat(globResults).map((path) => new Artifact(path, contentType))
|
const expectedArtifacts = globResults.concat(globResults).map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString("path1,path2", "raw", false)).toEqual(expectedArtifacts)
|
expect(globber.globArtifactString("path1,path2", "raw", false)).toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith("path1")
|
expect(globMock).toHaveBeenCalledWith("path1")
|
||||||
expect(globMock).toBeCalledWith("path2")
|
expect(globMock).toHaveBeenCalledWith("path2")
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("splits multiple paths with new line separator and trims start", () => {
|
it("splits multiple paths with new line separator and trims start", () => {
|
||||||
@@ -70,16 +70,16 @@ describe("ArtifactGlobber", () => {
|
|||||||
const expectedArtifacts = globResults.concat(globResults).map((path) => new Artifact(path, contentType))
|
const expectedArtifacts = globResults.concat(globResults).map((path) => new Artifact(path, contentType))
|
||||||
|
|
||||||
expect(globber.globArtifactString("path1\n path2", "raw", false)).toEqual(expectedArtifacts)
|
expect(globber.globArtifactString("path1\n path2", "raw", false)).toEqual(expectedArtifacts)
|
||||||
expect(globMock).toBeCalledWith("path1")
|
expect(globMock).toHaveBeenCalledWith("path1")
|
||||||
expect(globMock).toBeCalledWith("path2")
|
expect(globMock).toHaveBeenCalledWith("path2")
|
||||||
expect(warnMock).not.toBeCalled()
|
expect(warnMock).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
||||||
const globber = createArtifactGlobber([])
|
const globber = createArtifactGlobber([])
|
||||||
|
|
||||||
expect(globber.globArtifactString("path", "raw", false)).toEqual([])
|
expect(globber.globArtifactString("path", "raw", false)).toEqual([])
|
||||||
expect(warnMock).toBeCalled()
|
expect(warnMock).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("throws when no glob results are produced and empty results shouild throw", () => {
|
it("throws when no glob results are produced and empty results shouild throw", () => {
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ describe("ArtifactPathValidator", () => {
|
|||||||
const validator = new ArtifactPathValidator(false, paths, pattern)
|
const validator = new ArtifactPathValidator(false, paths, pattern)
|
||||||
|
|
||||||
const result = validator.validate()
|
const result = validator.validate()
|
||||||
expect(warnMock).toBeCalled()
|
expect(warnMock).toHaveBeenCalled()
|
||||||
expect(result).toEqual(["path2"])
|
expect(result).toEqual(["path2"])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
||||||
const validator = new ArtifactPathValidator(false, [], pattern)
|
const validator = new ArtifactPathValidator(false, [], pattern)
|
||||||
const result = validator.validate()
|
const result = validator.validate()
|
||||||
expect(warnMock).toBeCalled()
|
expect(warnMock).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("throws when no glob results are produced and empty results shouild throw", () => {
|
it("throws when no glob results are produced and empty results shouild throw", () => {
|
||||||
|
|||||||
@@ -83,31 +83,31 @@ describe("Inputs", () => {
|
|||||||
mockGetInput.mockReturnValueOnce("art1").mockReturnValueOnce("contentType").mockReturnValueOnce("true")
|
mockGetInput.mockReturnValueOnce("art1").mockReturnValueOnce("contentType").mockReturnValueOnce("true")
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toHaveBeenCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith("art1", "contentType", true)
|
expect(mockGlob).toHaveBeenCalledWith("art1", "contentType", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns empty artifacts", () => {
|
it("returns empty artifacts", () => {
|
||||||
mockGetInput.mockReturnValueOnce("").mockReturnValueOnce("")
|
mockGetInput.mockReturnValueOnce("").mockReturnValueOnce("")
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual([])
|
expect(inputs.artifacts).toEqual([])
|
||||||
expect(mockGlob).toBeCalledTimes(0)
|
expect(mockGlob).toHaveBeenCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns input.artifacts", () => {
|
it("returns input.artifacts", () => {
|
||||||
mockGetInput.mockReturnValueOnce("art1").mockReturnValueOnce("contentType").mockReturnValueOnce("false")
|
mockGetInput.mockReturnValueOnce("art1").mockReturnValueOnce("contentType").mockReturnValueOnce("false")
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toHaveBeenCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith("art1", "contentType", false)
|
expect(mockGlob).toHaveBeenCalledWith("art1", "contentType", false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns input.artifacts with default contentType", () => {
|
it("returns input.artifacts with default contentType", () => {
|
||||||
mockGetInput.mockReturnValueOnce("art1").mockReturnValueOnce("").mockReturnValueOnce("false")
|
mockGetInput.mockReturnValueOnce("art1").mockReturnValueOnce("").mockReturnValueOnce("false")
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toHaveBeenCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith("art1", "raw", false)
|
expect(mockGlob).toHaveBeenCalledWith("art1", "raw", false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns input.artifact", () => {
|
it("returns input.artifact", () => {
|
||||||
@@ -118,8 +118,8 @@ describe("Inputs", () => {
|
|||||||
.mockReturnValueOnce("false")
|
.mockReturnValueOnce("false")
|
||||||
|
|
||||||
expect(inputs.artifacts).toEqual(artifacts)
|
expect(inputs.artifacts).toEqual(artifacts)
|
||||||
expect(mockGlob).toBeCalledTimes(1)
|
expect(mockGlob).toHaveBeenCalledTimes(1)
|
||||||
expect(mockGlob).toBeCalledWith("art2", "contentType", false)
|
expect(mockGlob).toHaveBeenCalledWith("art2", "contentType", false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ jest.mock("@actions/core", () => {
|
|||||||
return { setOutput: mockSetOutput }
|
return { setOutput: mockSetOutput }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const TEST_URLS = {
|
||||||
|
HTML_URL: "https://api.example.com/assets",
|
||||||
|
UPLOAD_URL: "https://api.example.com",
|
||||||
|
TARBALL_URL: "https://api.example.com/tarball",
|
||||||
|
ZIPBALL_URL: "https://api.example.com/zipball",
|
||||||
|
} as const
|
||||||
|
|
||||||
describe("Outputs", () => {
|
describe("Outputs", () => {
|
||||||
let outputs: Outputs
|
let outputs: Outputs
|
||||||
let releaseData: ReleaseData
|
let releaseData: ReleaseData
|
||||||
@@ -15,15 +22,30 @@ describe("Outputs", () => {
|
|||||||
outputs = new CoreOutputs()
|
outputs = new CoreOutputs()
|
||||||
releaseData = {
|
releaseData = {
|
||||||
id: 1,
|
id: 1,
|
||||||
html_url: "https://api.example.com/assets",
|
html_url: TEST_URLS.HTML_URL,
|
||||||
upload_url: "https://api.example.com",
|
upload_url: TEST_URLS.UPLOAD_URL,
|
||||||
|
tarball_url: TEST_URLS.TARBALL_URL,
|
||||||
|
zipball_url: TEST_URLS.ZIPBALL_URL,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Applies the release data to the action output", () => {
|
it("Applies the release data to the action output", () => {
|
||||||
outputs.applyReleaseData(releaseData)
|
outputs.applyReleaseData(releaseData)
|
||||||
expect(mockSetOutput).toBeCalledWith("id", releaseData.id)
|
expect(mockSetOutput).toHaveBeenCalledWith("id", releaseData.id)
|
||||||
expect(mockSetOutput).toBeCalledWith("html_url", releaseData.html_url)
|
expect(mockSetOutput).toHaveBeenCalledWith("html_url", releaseData.html_url)
|
||||||
expect(mockSetOutput).toBeCalledWith("upload_url", releaseData.upload_url)
|
expect(mockSetOutput).toHaveBeenCalledWith("upload_url", releaseData.upload_url)
|
||||||
|
expect(mockSetOutput).toHaveBeenCalledWith("tarball_url", releaseData.tarball_url)
|
||||||
|
expect(mockSetOutput).toHaveBeenCalledWith("zipball_url", releaseData.zipball_url)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Handles null tarball_url and zipball_url", () => {
|
||||||
|
const releaseDataWithNulls = {
|
||||||
|
...releaseData,
|
||||||
|
tarball_url: null,
|
||||||
|
zipball_url: null,
|
||||||
|
}
|
||||||
|
outputs.applyReleaseData(releaseDataWithNulls)
|
||||||
|
expect(mockSetOutput).toHaveBeenCalledWith("tarball_url", "")
|
||||||
|
expect(mockSetOutput).toHaveBeenCalledWith("zipball_url", "")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
1656
dist/index.js
vendored
1656
dist/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/sourcemap-register.js
vendored
2
dist/sourcemap-register.js
vendored
File diff suppressed because one or more lines are too long
@@ -10,5 +10,7 @@ export class CoreOutputs implements Outputs {
|
|||||||
core.setOutput("id", releaseData.id)
|
core.setOutput("id", releaseData.id)
|
||||||
core.setOutput("html_url", releaseData.html_url)
|
core.setOutput("html_url", releaseData.html_url)
|
||||||
core.setOutput("upload_url", releaseData.upload_url)
|
core.setOutput("upload_url", releaseData.upload_url)
|
||||||
|
core.setOutput("tarball_url", releaseData.tarball_url || "")
|
||||||
|
core.setOutput("zipball_url", releaseData.zipball_url || "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export type ReleaseData = {
|
|||||||
id: number
|
id: number
|
||||||
html_url: string
|
html_url: string
|
||||||
upload_url: string
|
upload_url: string
|
||||||
|
tarball_url: string | null
|
||||||
|
zipball_url: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Releases {
|
export interface Releases {
|
||||||
|
|||||||
Reference in New Issue
Block a user