Bump to core-3.0.0, move to vitest, support ESM modules (#587)
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { Action } from "../src/Action"
|
||||
import type { ActionSkipper } from "../src/ActionSkipper"
|
||||
import { Artifact } from "../src/Artifact"
|
||||
import type { ArtifactDestroyer } from "../src/ArtifactDestroyer"
|
||||
import type { ArtifactUploader } from "../src/ArtifactUploader"
|
||||
import type { Inputs } from "../src/Inputs"
|
||||
import type { Outputs } from "../src/Outputs"
|
||||
import type { Releases } from "../src/Releases"
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
import { Action } from "../src/Action.js"
|
||||
import type { ActionSkipper } from "../src/ActionSkipper.js"
|
||||
import { Artifact } from "../src/Artifact.js"
|
||||
import type { ArtifactDestroyer } from "../src/ArtifactDestroyer.js"
|
||||
import type { ArtifactUploader } from "../src/ArtifactUploader.js"
|
||||
import type { Inputs } from "../src/Inputs.js"
|
||||
import type { Outputs } from "../src/Outputs.js"
|
||||
import type { Releases } from "../src/Releases.js"
|
||||
|
||||
const TEST_URLS = {
|
||||
UPLOAD_URL: "http://api.example.com",
|
||||
@@ -14,18 +15,18 @@ const TEST_URLS = {
|
||||
ZIPBALL_URL: "https://api.github.com/repos/owner/repo/zipball/v1.0.0",
|
||||
} as const
|
||||
|
||||
const applyReleaseDataMock = jest.fn()
|
||||
const applyAssetUrlsMock = jest.fn()
|
||||
const artifactDestroyMock = jest.fn()
|
||||
const createMock = jest.fn()
|
||||
const deleteMock = jest.fn()
|
||||
const getMock = jest.fn()
|
||||
const listArtifactsMock = jest.fn()
|
||||
const listMock = jest.fn()
|
||||
const shouldSkipMock = jest.fn()
|
||||
const updateMock = jest.fn()
|
||||
const uploadMock = jest.fn()
|
||||
const genReleaseNotesMock = jest.fn()
|
||||
const applyReleaseDataMock = vi.fn()
|
||||
const applyAssetUrlsMock = vi.fn()
|
||||
const artifactDestroyMock = vi.fn()
|
||||
const createMock = vi.fn()
|
||||
const deleteMock = vi.fn()
|
||||
const getMock = vi.fn()
|
||||
const listArtifactsMock = vi.fn()
|
||||
const listMock = vi.fn()
|
||||
const shouldSkipMock = vi.fn()
|
||||
const updateMock = vi.fn()
|
||||
const uploadMock = vi.fn()
|
||||
const genReleaseNotesMock = vi.fn()
|
||||
|
||||
const artifacts = [new Artifact("a/art1"), new Artifact("b/art2")]
|
||||
|
||||
@@ -34,7 +35,7 @@ const createDraft = true
|
||||
const createName = "createName"
|
||||
const commit = "commit"
|
||||
const discussionCategory = "discussionCategory"
|
||||
const generateReleaseNotes = true
|
||||
const _generateReleaseNotes = true
|
||||
const id = 100
|
||||
const createPrerelease = true
|
||||
const releaseId = 101
|
||||
@@ -55,6 +56,7 @@ describe("Action", () => {
|
||||
beforeEach(() => {
|
||||
applyReleaseDataMock.mockClear()
|
||||
applyAssetUrlsMock.mockClear()
|
||||
artifactDestroyMock.mockClear()
|
||||
createMock.mockClear()
|
||||
genReleaseNotesMock.mockClear()
|
||||
getMock.mockClear()
|
||||
@@ -149,7 +151,18 @@ describe("Action", () => {
|
||||
})
|
||||
|
||||
it("creates release with combined body and generated release notes using previous tag", async () => {
|
||||
const action = createAction(false, false, false, true, false, createBody, true, createDraft, updateBody, previousTag)
|
||||
const action = createAction(
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
createBody,
|
||||
true,
|
||||
createDraft,
|
||||
updateBody,
|
||||
previousTag
|
||||
)
|
||||
|
||||
await action.perform()
|
||||
|
||||
@@ -209,8 +222,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -238,8 +251,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -262,8 +275,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -275,8 +288,8 @@ describe("Action", () => {
|
||||
expect(artifactDestroyMock).toHaveBeenCalledWith(releaseId)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -288,8 +301,8 @@ describe("Action", () => {
|
||||
expect(artifactDestroyMock).not.toHaveBeenCalled()
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -456,8 +469,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -488,8 +501,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -513,8 +526,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -578,8 +591,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -610,8 +623,8 @@ describe("Action", () => {
|
||||
expect(uploadMock).toHaveBeenCalledWith(artifacts, releaseId, url)
|
||||
assertOutputApplied()
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -695,8 +708,8 @@ describe("Action", () => {
|
||||
// Should apply the immutable release data instead of the original
|
||||
expect(applyReleaseDataMock).toHaveBeenCalledWith(immutableReleaseResponse.data)
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -705,7 +718,7 @@ describe("Action", () => {
|
||||
const error = { status: 404 }
|
||||
getMock.mockRejectedValue(error)
|
||||
listMock.mockResolvedValue({ data: [] }) // No draft releases found
|
||||
|
||||
|
||||
const immutableReleaseResponse = {
|
||||
data: {
|
||||
id: 888,
|
||||
@@ -749,8 +762,8 @@ describe("Action", () => {
|
||||
// Should apply the immutable release data instead of the original
|
||||
expect(applyReleaseDataMock).toHaveBeenCalledWith(immutableReleaseResponse.data)
|
||||
assertAssetUrlsApplied({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -788,7 +801,7 @@ describe("Action", () => {
|
||||
inputArtifact = []
|
||||
}
|
||||
|
||||
const MockReleases = jest.fn<Releases, any>(() => {
|
||||
const MockReleases = vi.fn<() => Releases>(() => {
|
||||
return {
|
||||
create: createMock,
|
||||
deleteArtifact: deleteMock,
|
||||
@@ -796,7 +809,7 @@ describe("Action", () => {
|
||||
listArtifactsForRelease: listArtifactsMock,
|
||||
listReleases: listMock,
|
||||
update: updateMock,
|
||||
uploadArtifact: jest.fn(),
|
||||
uploadArtifact: vi.fn(),
|
||||
generateReleaseNotes: genReleaseNotesMock,
|
||||
}
|
||||
})
|
||||
@@ -835,11 +848,11 @@ describe("Action", () => {
|
||||
},
|
||||
})
|
||||
uploadMock.mockResolvedValue({
|
||||
"art1": "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/owner/repo/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/owner/repo/releases/download/v1.0.0/art2",
|
||||
})
|
||||
|
||||
const MockInputs = jest.fn<Inputs, any>(() => {
|
||||
const MockInputs = vi.fn<() => Inputs>(() => {
|
||||
return {
|
||||
allowUpdates,
|
||||
artifactErrorsFailBuild: true,
|
||||
@@ -869,35 +882,35 @@ describe("Action", () => {
|
||||
omitBodyDuringUpdate,
|
||||
}
|
||||
})
|
||||
const MockOutputs = jest.fn<Outputs, any>(() => {
|
||||
const MockOutputs = vi.fn<() => Outputs>(() => {
|
||||
return {
|
||||
applyReleaseData: applyReleaseDataMock,
|
||||
applyAssetUrls: applyAssetUrlsMock,
|
||||
}
|
||||
})
|
||||
const MockUploader = jest.fn<ArtifactUploader, any>(() => {
|
||||
const MockUploader = vi.fn<() => ArtifactUploader>(() => {
|
||||
return {
|
||||
uploadArtifacts: uploadMock,
|
||||
}
|
||||
})
|
||||
const MockArtifactDestroyer = jest.fn<ArtifactDestroyer, any>(() => {
|
||||
const MockArtifactDestroyer = vi.fn<() => ArtifactDestroyer>(() => {
|
||||
return {
|
||||
destroyArtifacts: artifactDestroyMock,
|
||||
}
|
||||
})
|
||||
|
||||
const MockActionSkipper = jest.fn<ActionSkipper, any>(() => {
|
||||
const MockActionSkipper = vi.fn<() => ActionSkipper>(() => {
|
||||
return {
|
||||
shouldSkip: shouldSkipMock,
|
||||
}
|
||||
})
|
||||
|
||||
const inputs = new MockInputs()
|
||||
const outputs = new MockOutputs()
|
||||
const releases = new MockReleases()
|
||||
const uploader = new MockUploader()
|
||||
const artifactDestroyer = new MockArtifactDestroyer()
|
||||
const actionSkipper = new MockActionSkipper()
|
||||
const inputs = MockInputs()
|
||||
const outputs = MockOutputs()
|
||||
const releases = MockReleases()
|
||||
const uploader = MockUploader()
|
||||
const artifactDestroyer = MockArtifactDestroyer()
|
||||
const actionSkipper = MockActionSkipper()
|
||||
|
||||
return new Action(inputs, outputs, releases, uploader, artifactDestroyer, actionSkipper)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import { ReleaseActionSkipper } from "../src/ActionSkipper"
|
||||
import type { Releases } from "../src/Releases"
|
||||
import { describe, expect, it, vi } from "vitest"
|
||||
import { ReleaseActionSkipper } from "../src/ActionSkipper.js"
|
||||
import type { Releases } from "../src/Releases.js"
|
||||
|
||||
describe("shouldSkip", () => {
|
||||
const getMock = jest.fn()
|
||||
const getMock = vi.fn()
|
||||
const tag = "tag"
|
||||
const MockReleases = jest.fn<Releases, any>(() => {
|
||||
const MockReleases = vi.fn<() => Releases>(() => {
|
||||
return {
|
||||
create: jest.fn(),
|
||||
deleteArtifact: jest.fn(),
|
||||
create: vi.fn(),
|
||||
deleteArtifact: vi.fn(),
|
||||
getByTag: getMock,
|
||||
listArtifactsForRelease: jest.fn(),
|
||||
listReleases: jest.fn(),
|
||||
update: jest.fn(),
|
||||
uploadArtifact: jest.fn(),
|
||||
generateReleaseNotes: jest.fn(),
|
||||
listArtifactsForRelease: vi.fn(),
|
||||
listReleases: vi.fn(),
|
||||
update: vi.fn(),
|
||||
uploadArtifact: vi.fn(),
|
||||
generateReleaseNotes: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { Artifact } from "../src/Artifact"
|
||||
import * as fs from "node:fs"
|
||||
import { describe, expect, it, vi } from "vitest"
|
||||
import { Artifact } from "../src/Artifact.js"
|
||||
|
||||
vi.mock("fs")
|
||||
|
||||
const contentLength = 42
|
||||
const fakeReadStream = {}
|
||||
|
||||
jest.mock("fs", () => {
|
||||
return {
|
||||
createReadStream: () => fakeReadStream,
|
||||
statSync: () => {
|
||||
return { size: contentLength }
|
||||
},
|
||||
}
|
||||
})
|
||||
const mockCreateReadStream = vi.mocked(fs.createReadStream)
|
||||
const mockStatSync = vi.mocked(fs.statSync)
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Mock object for testing
|
||||
mockCreateReadStream.mockReturnValue(fakeReadStream as any)
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Partial Stats object for testing
|
||||
mockStatSync.mockReturnValue({ size: contentLength } as any)
|
||||
|
||||
describe("Artifact", () => {
|
||||
it("defaults contentType to raw", () => {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { GithubArtifactDestroyer } from "../src/ArtifactDestroyer"
|
||||
import type { Releases } from "../src/Releases"
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
import { GithubArtifactDestroyer } from "../src/ArtifactDestroyer.js"
|
||||
import type { Releases } from "../src/Releases.js"
|
||||
|
||||
const releaseId = 100
|
||||
|
||||
const deleteMock = jest.fn()
|
||||
const listArtifactsMock = jest.fn()
|
||||
const deleteMock = vi.fn()
|
||||
const listArtifactsMock = vi.fn()
|
||||
|
||||
describe("ArtifactDestroyer", () => {
|
||||
beforeEach(() => {
|
||||
@@ -45,26 +46,26 @@ describe("ArtifactDestroyer", () => {
|
||||
})
|
||||
|
||||
function createDestroyer(): GithubArtifactDestroyer {
|
||||
const MockReleases = jest.fn<Releases, any>(() => {
|
||||
const MockReleases = vi.fn<() => Releases>(() => {
|
||||
return {
|
||||
create: jest.fn(),
|
||||
create: vi.fn(),
|
||||
deleteArtifact: deleteMock,
|
||||
getByTag: jest.fn(),
|
||||
getByTag: vi.fn(),
|
||||
listArtifactsForRelease: listArtifactsMock,
|
||||
listReleases: jest.fn(),
|
||||
update: jest.fn(),
|
||||
uploadArtifact: jest.fn(),
|
||||
generateReleaseNotes: jest.fn(),
|
||||
listReleases: vi.fn(),
|
||||
update: vi.fn(),
|
||||
uploadArtifact: vi.fn(),
|
||||
generateReleaseNotes: vi.fn(),
|
||||
}
|
||||
})
|
||||
return new GithubArtifactDestroyer(new MockReleases())
|
||||
return new GithubArtifactDestroyer(MockReleases())
|
||||
}
|
||||
|
||||
function mockDeleteError(): any {
|
||||
function mockDeleteError(): void {
|
||||
deleteMock.mockRejectedValue("error")
|
||||
}
|
||||
|
||||
function mockDeleteSuccess(): any {
|
||||
function mockDeleteSuccess(): void {
|
||||
deleteMock.mockResolvedValue({})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
const warnMock = jest.fn()
|
||||
import * as fs from "node:fs"
|
||||
import * as core from "@actions/core"
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
|
||||
import { Globber } from "../src/Globber"
|
||||
import { Artifact } from "../src/Artifact"
|
||||
import { expandTilde } from "../src/PathExpander"
|
||||
vi.mock("@actions/core")
|
||||
vi.mock("fs")
|
||||
|
||||
import { Artifact } from "../src/Artifact.js"
|
||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber.js"
|
||||
import type { Globber } from "../src/Globber.js"
|
||||
import { expandTilde } from "../src/PathExpander.js"
|
||||
|
||||
const warnMock = vi.mocked(core.warning)
|
||||
const mockStatSync = vi.mocked(fs.statSync)
|
||||
// biome-ignore lint/suspicious/noExplicitAny: fs.realpathSync has overloads that are difficult to type
|
||||
const mockRealpathSync = vi.mocked(fs.realpathSync as any)
|
||||
|
||||
const contentType = "raw"
|
||||
const globMock = jest.fn()
|
||||
const globMock = vi.fn()
|
||||
const globResults = ["file1", "file2"]
|
||||
|
||||
jest.mock("@actions/core", () => {
|
||||
return { warning: warnMock }
|
||||
})
|
||||
mockStatSync.mockReturnValue({
|
||||
isDirectory(): boolean {
|
||||
return false
|
||||
},
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Partial Stats object for testing
|
||||
} as any)
|
||||
|
||||
jest.mock("fs", () => {
|
||||
return {
|
||||
statSync: () => {
|
||||
return {
|
||||
isDirectory(): boolean {
|
||||
return false
|
||||
},
|
||||
}
|
||||
},
|
||||
realpathSync: () => {
|
||||
return false
|
||||
},
|
||||
}
|
||||
})
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Mock return value for testing
|
||||
mockRealpathSync.mockReturnValue(false as any)
|
||||
|
||||
describe("ArtifactGlobber", () => {
|
||||
beforeEach(() => {
|
||||
@@ -90,12 +91,12 @@ describe("ArtifactGlobber", () => {
|
||||
})
|
||||
|
||||
function createArtifactGlobber(results: string[] = globResults): FileArtifactGlobber {
|
||||
const MockGlobber = jest.fn<Globber, any>(() => {
|
||||
const MockGlobber = vi.fn<() => Globber>(() => {
|
||||
return {
|
||||
glob: globMock,
|
||||
}
|
||||
})
|
||||
globMock.mockReturnValue(results)
|
||||
return new FileArtifactGlobber(new MockGlobber())
|
||||
return new FileArtifactGlobber(MockGlobber())
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
const directoryMock = jest.fn()
|
||||
const warnMock = jest.fn()
|
||||
import * as fs from "node:fs"
|
||||
import * as core from "@actions/core"
|
||||
import { describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { ArtifactPathValidator } from "../src/ArtifactPathValidator"
|
||||
vi.mock("@actions/core")
|
||||
vi.mock("fs")
|
||||
|
||||
import { ArtifactPathValidator } from "../src/ArtifactPathValidator.js"
|
||||
|
||||
const warnMock = vi.mocked(core.warning)
|
||||
const mockStatSync = vi.mocked(fs.statSync)
|
||||
const directoryMock = vi.fn()
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Partial Stats object for testing
|
||||
mockStatSync.mockReturnValue({ isDirectory: directoryMock } as any)
|
||||
|
||||
const pattern = "pattern"
|
||||
|
||||
jest.mock("@actions/core", () => {
|
||||
return { warning: warnMock }
|
||||
})
|
||||
|
||||
jest.mock("fs", () => {
|
||||
return {
|
||||
statSync: () => {
|
||||
return { isDirectory: directoryMock }
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
describe("ArtifactPathValidator", () => {
|
||||
beforeEach(() => {
|
||||
warnMock.mockClear()
|
||||
@@ -36,7 +35,7 @@ describe("ArtifactPathValidator", () => {
|
||||
|
||||
it("warns when no glob results are produced and empty results shouldn't throw", () => {
|
||||
const validator = new ArtifactPathValidator(false, [], pattern)
|
||||
const result = validator.validate()
|
||||
const _result = validator.validate()
|
||||
expect(warnMock).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { RequestError } from "@octokit/request-error"
|
||||
import { Artifact } from "../src/Artifact"
|
||||
import { GithubArtifactUploader } from "../src/ArtifactUploader"
|
||||
import type { Releases } from "../src/Releases"
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
import { Artifact } from "../src/Artifact.js"
|
||||
import { GithubArtifactUploader } from "../src/ArtifactUploader.js"
|
||||
import type { Releases } from "../src/Releases.js"
|
||||
|
||||
const artifacts = [new Artifact("a/art1"), new Artifact("b/art2")]
|
||||
const fakeReadStream = {}
|
||||
@@ -9,9 +10,9 @@ const contentLength = 42
|
||||
const releaseId = 100
|
||||
const url = "http://api.example.com"
|
||||
|
||||
const deleteMock = jest.fn()
|
||||
const listArtifactsMock = jest.fn()
|
||||
const uploadMock = jest.fn()
|
||||
const deleteMock = vi.fn()
|
||||
const listArtifactsMock = vi.fn()
|
||||
const uploadMock = vi.fn()
|
||||
|
||||
// Mock response with browser_download_url
|
||||
const mockUploadResponse = (name: string) => ({
|
||||
@@ -19,11 +20,11 @@ const mockUploadResponse = (name: string) => ({
|
||||
browser_download_url: `https://github.com/octocat/Hello-World/releases/download/v1.0.0/${name}`,
|
||||
name: name,
|
||||
id: 1,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
jest.mock("fs", () => {
|
||||
const originalFs = jest.requireActual("fs")
|
||||
vi.mock("fs", async () => {
|
||||
const originalFs = await vi.importActual<typeof import("fs")>("fs")
|
||||
return {
|
||||
...originalFs,
|
||||
promises: {},
|
||||
@@ -49,8 +50,8 @@ describe("ArtifactUploader", () => {
|
||||
const result = await uploader.uploadArtifacts(artifacts, releaseId, url)
|
||||
|
||||
expect(result).toEqual({
|
||||
"art1": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
})
|
||||
expect(uploadMock).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
@@ -117,8 +118,8 @@ describe("ArtifactUploader", () => {
|
||||
const result = await uploader.uploadArtifacts(artifacts, releaseId, url)
|
||||
|
||||
expect(result).toEqual({
|
||||
"art1": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
})
|
||||
expect(uploadMock).toHaveBeenCalledTimes(2)
|
||||
expect(uploadMock).toHaveBeenCalledWith(url, contentLength, "raw", fakeReadStream, "art1", releaseId)
|
||||
@@ -138,8 +139,8 @@ describe("ArtifactUploader", () => {
|
||||
const result = await uploader.uploadArtifacts(artifacts, releaseId, url)
|
||||
|
||||
expect(result).toEqual({
|
||||
"art1": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
})
|
||||
expect(uploadMock).toHaveBeenCalledTimes(2)
|
||||
expect(uploadMock).toHaveBeenCalledWith(url, contentLength, "raw", fakeReadStream, "art1", releaseId)
|
||||
@@ -201,8 +202,8 @@ describe("ArtifactUploader", () => {
|
||||
const result = await uploader.uploadArtifacts(artifacts, releaseId, url)
|
||||
|
||||
expect(result).toEqual({
|
||||
"art1": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
"art2": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
art1: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art1",
|
||||
art2: "https://github.com/octocat/Hello-World/releases/download/v1.0.0/art2",
|
||||
})
|
||||
expect(uploadMock).toHaveBeenCalledTimes(2)
|
||||
expect(uploadMock).toHaveBeenCalledWith(url, contentLength, "raw", fakeReadStream, "art1", releaseId)
|
||||
@@ -212,26 +213,26 @@ describe("ArtifactUploader", () => {
|
||||
})
|
||||
|
||||
function createUploader(replaces: boolean, throws = false): GithubArtifactUploader {
|
||||
const MockReleases = jest.fn<Releases, any>(() => {
|
||||
const MockReleases = vi.fn<() => Releases>(() => {
|
||||
return {
|
||||
create: jest.fn(),
|
||||
create: vi.fn(),
|
||||
deleteArtifact: deleteMock,
|
||||
getByTag: jest.fn(),
|
||||
getByTag: vi.fn(),
|
||||
listArtifactsForRelease: listArtifactsMock,
|
||||
listReleases: jest.fn(),
|
||||
update: jest.fn(),
|
||||
listReleases: vi.fn(),
|
||||
update: vi.fn(),
|
||||
uploadArtifact: uploadMock,
|
||||
generateReleaseNotes: jest.fn(),
|
||||
generateReleaseNotes: vi.fn(),
|
||||
}
|
||||
})
|
||||
return new GithubArtifactUploader(new MockReleases(), replaces, throws)
|
||||
return new GithubArtifactUploader(MockReleases(), replaces, throws)
|
||||
}
|
||||
|
||||
function mockDeleteError(): any {
|
||||
function mockDeleteError(): void {
|
||||
deleteMock.mockRejectedValue("error")
|
||||
}
|
||||
|
||||
function mockDeleteSuccess(): any {
|
||||
function mockDeleteSuccess(): void {
|
||||
deleteMock.mockResolvedValue({})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GithubError } from "../src/GithubError"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { GithubError } from "../src/GithubError.js"
|
||||
|
||||
describe("ErrorMessage", () => {
|
||||
describe("has error with code", () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GithubErrorDetail } from "../src/GithubErrorDetail"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { GithubErrorDetail } from "../src/GithubErrorDetail.js"
|
||||
|
||||
describe("GithubErrorDetail", () => {
|
||||
it("provides error code", () => {
|
||||
|
||||
@@ -1,41 +1,56 @@
|
||||
const mockGetInput = jest.fn()
|
||||
const mockGetBooleanInput = jest.fn()
|
||||
const mockGlob = jest.fn()
|
||||
const mockReadFileSync = jest.fn()
|
||||
const mockStatSync = jest.fn()
|
||||
import * as fs from "node:fs"
|
||||
import * as core from "@actions/core"
|
||||
import type * as github from "@actions/github"
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { Artifact } from "../src/Artifact"
|
||||
import { ArtifactGlobber } from "../src/ArtifactGlobber"
|
||||
import { Context } from "@actions/github/lib/context"
|
||||
import { Inputs, CoreInputs } from "../src/Inputs"
|
||||
vi.mock("@actions/core")
|
||||
vi.mock("fs")
|
||||
|
||||
import { Artifact } from "../src/Artifact.js"
|
||||
import type { ArtifactGlobber } from "../src/ArtifactGlobber.js"
|
||||
import { CoreInputs, type Inputs } from "../src/Inputs.js"
|
||||
|
||||
const mockGetInput = vi.mocked(core.getInput)
|
||||
const mockGetBooleanInput = vi.mocked(core.getBooleanInput)
|
||||
const mockReadFileSync = vi.mocked(fs.readFileSync)
|
||||
const _mockStatSync = vi.mocked(fs.statSync)
|
||||
const mockExistsSync = vi.mocked(fs.existsSync)
|
||||
const mockGlob = vi.fn()
|
||||
|
||||
// existsSync is used by Context's constructor
|
||||
mockExistsSync.mockReturnValue(false)
|
||||
|
||||
const artifacts = [new Artifact("a/art1"), new Artifact("b/art2")]
|
||||
|
||||
jest.mock("@actions/core", () => {
|
||||
return {
|
||||
getInput: mockGetInput,
|
||||
getBooleanInput: mockGetBooleanInput,
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock("fs", () => {
|
||||
// existsSync is used by Context's constructor
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
return {
|
||||
existsSync: () => {
|
||||
return false
|
||||
},
|
||||
readFileSync: mockReadFileSync,
|
||||
statSync: mockStatSync,
|
||||
}
|
||||
})
|
||||
|
||||
describe("Inputs", () => {
|
||||
let context: Context
|
||||
let context: typeof github.context
|
||||
let inputs: Inputs
|
||||
beforeEach(() => {
|
||||
mockGetInput.mockReset()
|
||||
context = new Context()
|
||||
mockGlob.mockClear()
|
||||
context = {
|
||||
payload: {},
|
||||
eventName: "",
|
||||
sha: "",
|
||||
ref: "",
|
||||
workflow: "",
|
||||
action: "",
|
||||
actor: "",
|
||||
job: "",
|
||||
runNumber: 0,
|
||||
runId: 0,
|
||||
runAttempt: 0,
|
||||
apiUrl: "",
|
||||
serverUrl: "",
|
||||
graphqlUrl: "",
|
||||
get repo() {
|
||||
const repo = process.env.GITHUB_REPOSITORY || "/"
|
||||
const [owner, repoName] = repo.split("/")
|
||||
return { owner: owner || "", repo: repoName || "" }
|
||||
},
|
||||
issue: { owner: "", repo: "", number: 0 },
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Partial Context object for testing
|
||||
} as any
|
||||
inputs = new CoreInputs(createGlobber(), context)
|
||||
})
|
||||
|
||||
@@ -189,41 +204,41 @@ describe("Inputs", () => {
|
||||
})
|
||||
|
||||
describe("generateReleaseNotes", () => {
|
||||
it("returns returns true", function () {
|
||||
it("returns returns true", () => {
|
||||
mockGetInput.mockReturnValue("true")
|
||||
expect(inputs.generateReleaseNotes).toBe(true)
|
||||
})
|
||||
|
||||
it("returns false when omitted", function () {
|
||||
it("returns false when omitted", () => {
|
||||
mockGetInput.mockReturnValue("")
|
||||
expect(inputs.generateReleaseNotes).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("generateReleaseNotesPreviousTag", () => {
|
||||
it("returns the previous tag when provided", function () {
|
||||
it("returns the previous tag when provided", () => {
|
||||
mockGetInput.mockReturnValue("v1.0.0")
|
||||
expect(inputs.generateReleaseNotesPreviousTag).toBe("v1.0.0")
|
||||
})
|
||||
|
||||
it("returns undefined when omitted", function () {
|
||||
it("returns undefined when omitted", () => {
|
||||
mockGetInput.mockReturnValue("")
|
||||
expect(inputs.generateReleaseNotesPreviousTag).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe("immutableCreate", () => {
|
||||
it("returns false by default", function () {
|
||||
it("returns false by default", () => {
|
||||
mockGetInput.mockReturnValue("")
|
||||
expect(inputs.immutableCreate).toBe(false)
|
||||
})
|
||||
|
||||
it("returns true when explicitly set", function () {
|
||||
it("returns true when explicitly set", () => {
|
||||
mockGetInput.mockReturnValue("true")
|
||||
expect(inputs.immutableCreate).toBe(true)
|
||||
})
|
||||
|
||||
it("returns false when explicitly disabled", function () {
|
||||
it("returns false when explicitly disabled", () => {
|
||||
mockGetInput.mockReturnValue("false")
|
||||
expect(inputs.immutableCreate).toBe(false)
|
||||
})
|
||||
@@ -252,12 +267,12 @@ describe("Inputs", () => {
|
||||
})
|
||||
|
||||
describe("owner", () => {
|
||||
it("returns owner from context", function () {
|
||||
it("returns owner from context", () => {
|
||||
process.env.GITHUB_REPOSITORY = "owner/repo"
|
||||
mockGetInput.mockReturnValue("")
|
||||
expect(inputs.owner).toBe("owner")
|
||||
})
|
||||
it("returns owner from inputs", function () {
|
||||
it("returns owner from inputs", () => {
|
||||
mockGetInput.mockReturnValue("owner")
|
||||
expect(inputs.owner).toBe("owner")
|
||||
})
|
||||
@@ -297,12 +312,12 @@ describe("Inputs", () => {
|
||||
})
|
||||
|
||||
describe("repo", () => {
|
||||
it("returns repo from context", function () {
|
||||
it("returns repo from context", () => {
|
||||
process.env.GITHUB_REPOSITORY = "owner/repo"
|
||||
mockGetInput.mockReturnValue("")
|
||||
expect(inputs.repo).toBe("repo")
|
||||
})
|
||||
it("returns repo from inputs", function () {
|
||||
it("returns repo from inputs", () => {
|
||||
mockGetInput.mockReturnValue("repo")
|
||||
expect(inputs.repo).toBe("repo")
|
||||
})
|
||||
@@ -330,11 +345,6 @@ describe("Inputs", () => {
|
||||
context.ref = "refs/tags/sha-tag"
|
||||
expect(inputs.tag).toBe("sha-tag")
|
||||
})
|
||||
it("returns context sha when input is null", () => {
|
||||
mockGetInput.mockReturnValue(null)
|
||||
context.ref = "refs/tags/sha-tag"
|
||||
expect(inputs.tag).toBe("sha-tag")
|
||||
})
|
||||
it("throws if no tag", () => {
|
||||
context.ref = ""
|
||||
expect(() => inputs.tag).toThrow()
|
||||
@@ -462,12 +472,12 @@ describe("Inputs", () => {
|
||||
})
|
||||
|
||||
function createGlobber(): ArtifactGlobber {
|
||||
const MockGlobber = jest.fn<ArtifactGlobber, any>(() => {
|
||||
const MockGlobber = vi.fn<() => ArtifactGlobber>(() => {
|
||||
return {
|
||||
globArtifactString: mockGlob,
|
||||
}
|
||||
})
|
||||
mockGlob.mockImplementation(() => artifacts)
|
||||
return new MockGlobber()
|
||||
return MockGlobber()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Action } from "../src/Action"
|
||||
import * as path from "node:path"
|
||||
import * as github from "@actions/github"
|
||||
import { Inputs } from "../src/Inputs"
|
||||
import { GithubReleases, ReleaseData } from "../src/Releases"
|
||||
import { GithubArtifactUploader } from "../src/ArtifactUploader"
|
||||
import * as path from "path"
|
||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber"
|
||||
import { Outputs } from "../src/Outputs"
|
||||
import { GithubArtifactDestroyer } from "../src/ArtifactDestroyer"
|
||||
import { ReleaseActionSkipper } from "../src/ActionSkipper"
|
||||
import { beforeEach, describe, it, vi } from "vitest"
|
||||
import { Action } from "../src/Action.js"
|
||||
import { ReleaseActionSkipper } from "../src/ActionSkipper.js"
|
||||
import { GithubArtifactDestroyer } from "../src/ArtifactDestroyer.js"
|
||||
import { FileArtifactGlobber } from "../src/ArtifactGlobber.js"
|
||||
import { GithubArtifactUploader } from "../src/ArtifactUploader.js"
|
||||
import type { Inputs } from "../src/Inputs.js"
|
||||
import type { Outputs } from "../src/Outputs.js"
|
||||
import { GithubReleases, type ReleaseData } from "../src/Releases.js"
|
||||
|
||||
// This test is currently intended to be manually run during development. To run:
|
||||
// - Make sure you have an environment variable named GITHUB_TOKEN assigned to your token
|
||||
@@ -34,7 +35,7 @@ describe.skip("Integration Test", () => {
|
||||
})
|
||||
|
||||
function getInputs(): Inputs {
|
||||
const MockInputs = jest.fn<Inputs, any>(() => {
|
||||
const MockInputs = vi.fn<() => Inputs>(() => {
|
||||
return {
|
||||
allowUpdates: true,
|
||||
artifactErrorsFailBuild: false,
|
||||
@@ -62,11 +63,11 @@ describe.skip("Integration Test", () => {
|
||||
updateOnlyUnreleased: false,
|
||||
}
|
||||
})
|
||||
return new MockInputs()
|
||||
return MockInputs()
|
||||
}
|
||||
|
||||
function getOutputs(): Outputs {
|
||||
const MockOutputs = jest.fn<Outputs, any>(() => {
|
||||
const MockOutputs = vi.fn<() => Outputs>(() => {
|
||||
return {
|
||||
applyReleaseData(releaseData: ReleaseData) {
|
||||
console.log(`Release Data: ${releaseData}`)
|
||||
@@ -76,7 +77,7 @@ describe.skip("Integration Test", () => {
|
||||
},
|
||||
}
|
||||
})
|
||||
return new MockOutputs()
|
||||
return MockOutputs()
|
||||
}
|
||||
|
||||
function artifacts() {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { CoreOutputs, type Outputs } from "../src/Outputs"
|
||||
import type { ReleaseData } from "../src/Releases"
|
||||
import * as core from "@actions/core"
|
||||
import { describe, expect, it, vi } from "vitest"
|
||||
import { CoreOutputs, type Outputs } from "../src/Outputs.js"
|
||||
import type { ReleaseData } from "../src/Releases.js"
|
||||
|
||||
jest.mock("@actions/core")
|
||||
const { setOutput: mockSetOutput } = jest.mocked(require("@actions/core"))
|
||||
vi.mock("@actions/core")
|
||||
const mockSetOutput = vi.mocked(core.setOutput)
|
||||
|
||||
const TEST_URLS = {
|
||||
HTML_URL: "https://api.example.com/assets",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os from "os"
|
||||
import { expandTilde } from "../src/PathExpander"
|
||||
import os from "node:os"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { expandTilde } from "../src/PathExpander.js"
|
||||
|
||||
describe("PathExpander", () => {
|
||||
describe("expandTilde", () => {
|
||||
@@ -39,4 +40,3 @@ describe("PathExpander", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ReleaseValidator } from "../src/ReleaseValidator"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { ReleaseValidator } from "../src/ReleaseValidator.js"
|
||||
|
||||
describe("validateReleaseUpdate", () => {
|
||||
describe("updateOnlyUnreleased is disabled", () => {
|
||||
|
||||
Reference in New Issue
Block a user