diff --git a/.github/workflows/__check-action.yml b/.github/workflows/__check-action.yml index 6217388..b968eac 100644 --- a/.github/workflows/__check-action.yml +++ b/.github/workflows/__check-action.yml @@ -23,11 +23,11 @@ jobs: - name: "Assert: only expected services are running" run: | - docker-compose -f ./docker/docker-compose.yml ps + docker compose -f ./docker/docker-compose.yml ps - docker-compose -f ./docker/docker-compose.yml ps | grep docker-service-b-1 || (echo "Service service-b is not running" && exit 1) - docker-compose -f ./docker/docker-compose.yml ps | grep docker-service-c-1 || (echo "Service service-c is not running" && exit 1) - (docker-compose -f ./docker/docker-compose.yml ps | grep docker-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true + docker compose -f ./docker/docker-compose.yml ps | grep docker-service-b-1 || (echo "Service service-b is not running" && exit 1) + docker compose -f ./docker/docker-compose.yml ps | grep docker-service-c-1 || (echo "Service service-c is not running" && exit 1) + (docker compose -f ./docker/docker-compose.yml ps | grep docker-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true test-action-with-down-flags: runs-on: ubuntu-latest diff --git a/dist/index.js b/dist/index.js index 18c9eab..b8e5e57 100644 --- a/dist/index.js +++ b/dist/index.js @@ -25937,14 +25937,10 @@ const docker_compose_service_1 = __nccwpck_require__(2911); async function run(callback) { try { const loggerService = new logger_service_1.LoggerService(); - const inputService = new input_service_1.InputService(loggerService); + const inputService = new input_service_1.InputService(); const dockerComposeService = new docker_compose_service_1.DockerComposeService(); const inputs = inputService.getInputs(); loggerService.debug(`inputs: ${JSON.stringify(inputs)}`); - if (!inputs.composeFiles.length) { - loggerService.warn("no compose files found"); - return; - } await callback(inputs, loggerService, dockerComposeService); } catch (error) { @@ -26032,10 +26028,6 @@ var InputNames; InputNames["Cwd"] = "cwd"; })(InputNames || (exports.InputNames = InputNames = {})); class InputService { - logger; - constructor(logger) { - this.logger = logger; - } getInputs() { return { composeFiles: this.getComposeFiles(), @@ -26048,16 +26040,19 @@ class InputService { } getComposeFiles() { const cwd = this.getCwd(); - return (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { + const composeFiles = (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { if (!composeFile.length) { return false; } if (!(0, fs_1.existsSync)((0, path_1.join)(cwd, composeFile))) { - this.logger.warn(`${composeFile} does not exist in ${cwd}`); - return false; + throw new Error(`${composeFile} does not exist in ${cwd}`); } return true; }); + if (!composeFiles.length) { + throw new Error("No compose files found"); + } + return composeFiles; } getServices() { return (0, core_1.getMultilineInput)(InputNames.Services, { required: false }); diff --git a/dist/post.js b/dist/post.js index 70b0ee3..f12ca69 100644 --- a/dist/post.js +++ b/dist/post.js @@ -25937,14 +25937,10 @@ const docker_compose_service_1 = __nccwpck_require__(2911); async function run(callback) { try { const loggerService = new logger_service_1.LoggerService(); - const inputService = new input_service_1.InputService(loggerService); + const inputService = new input_service_1.InputService(); const dockerComposeService = new docker_compose_service_1.DockerComposeService(); const inputs = inputService.getInputs(); loggerService.debug(`inputs: ${JSON.stringify(inputs)}`); - if (!inputs.composeFiles.length) { - loggerService.warn("no compose files found"); - return; - } await callback(inputs, loggerService, dockerComposeService); } catch (error) { @@ -26032,10 +26028,6 @@ var InputNames; InputNames["Cwd"] = "cwd"; })(InputNames || (exports.InputNames = InputNames = {})); class InputService { - logger; - constructor(logger) { - this.logger = logger; - } getInputs() { return { composeFiles: this.getComposeFiles(), @@ -26048,16 +26040,19 @@ class InputService { } getComposeFiles() { const cwd = this.getCwd(); - return (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { + const composeFiles = (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { if (!composeFile.length) { return false; } if (!(0, fs_1.existsSync)((0, path_1.join)(cwd, composeFile))) { - this.logger.warn(`${composeFile} does not exist in ${cwd}`); - return false; + throw new Error(`${composeFile} does not exist in ${cwd}`); } return true; }); + if (!composeFiles.length) { + throw new Error("No compose files found"); + } + return composeFiles; } getServices() { return (0, core_1.getMultilineInput)(InputNames.Services, { required: false }); diff --git a/src/runner.test.ts b/src/runner.test.ts index 9bbfc66..9affad7 100644 --- a/src/runner.test.ts +++ b/src/runner.test.ts @@ -17,7 +17,6 @@ const runMock = jest.spyOn(runner, "run"); // Mock the external libraries and services used by the action let debugMock: jest.SpiedFunction; -let warnMock: jest.SpiedFunction; let setFailedMock: jest.SpiedFunction; let getInputsMock: jest.SpiedFunction; describe("run", () => { @@ -25,14 +24,13 @@ describe("run", () => { jest.clearAllMocks(); debugMock = jest.spyOn(LoggerService.prototype, "debug").mockImplementation(); - warnMock = jest.spyOn(LoggerService.prototype, "warn").mockImplementation(); setFailedMock = jest.spyOn(core, "setFailed").mockImplementation(); getInputsMock = jest.spyOn(InputService.prototype, "getInputs"); }); - it("should return and warns when composeFile is empty", async () => { + it("should call given callback when inputs are valid", async () => { getInputsMock.mockImplementation(() => ({ - composeFiles: [], + composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], upFlags: [], @@ -41,6 +39,7 @@ describe("run", () => { })); const callbackMock = jest.fn(); + callbackMock.mockResolvedValueOnce(null); await runner.run(callbackMock); expect(runMock).toHaveReturned(); @@ -48,10 +47,22 @@ describe("run", () => { // Verify that all of the functions were called correctly expect(debugMock).toHaveBeenNthCalledWith( 1, - 'inputs: {"composeFiles":[],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}' + 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}' ); - expect(warnMock).toHaveBeenNthCalledWith(1, "no compose files found"); - expect(callbackMock).not.toHaveBeenCalled(); + + expect(callbackMock).toHaveBeenCalledWith( + { + composeFiles: ["docker-compose.yml"], + services: [], + composeFlags: [], + upFlags: [], + downFlags: [], + cwd: "/current/working/dir", + }, + expect.any(LoggerService), + expect.any(DockerComposeService) + ); + expect(setFailedMock).not.toHaveBeenCalled(); }); @@ -75,42 +86,4 @@ describe("run", () => { expect(callbackMock).toHaveBeenCalled(); expect(setFailedMock).toHaveBeenNthCalledWith(1, "Error: unkown error"); }); - - it("should call callback when some compose files are provided", async () => { - getInputsMock.mockImplementation(() => ({ - composeFiles: ["docker-compose.yml"], - services: [], - composeFlags: [], - upFlags: [], - downFlags: [], - cwd: "/current/working/dir", - })); - - const callbackMock = jest.fn(); - callbackMock.mockResolvedValueOnce(null); - - await runner.run(callbackMock); - expect(runMock).toHaveReturned(); - - // Verify that all of the functions were called correctly - expect(debugMock).toHaveBeenNthCalledWith( - 1, - 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}' - ); - - expect(callbackMock).toHaveBeenCalledWith( - { - composeFiles: ["docker-compose.yml"], - services: [], - composeFlags: [], - upFlags: [], - downFlags: [], - cwd: "/current/working/dir", - }, - expect.any(LoggerService), - expect.any(DockerComposeService) - ); - - expect(setFailedMock).not.toHaveBeenCalled(); - }); }); diff --git a/src/runner.ts b/src/runner.ts index 8cde39b..1ecfcb4 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -16,17 +16,12 @@ export type RunCallback = ( export async function run(callback: RunCallback): Promise { try { const loggerService = new LoggerService(); - const inputService = new InputService(loggerService); + const inputService = new InputService(); const dockerComposeService = new DockerComposeService(); const inputs = inputService.getInputs(); loggerService.debug(`inputs: ${JSON.stringify(inputs)}`); - if (!inputs.composeFiles.length) { - loggerService.warn("no compose files found"); - return; - } - await callback(inputs, loggerService, dockerComposeService); } catch (error) { setFailed(`${error instanceof Error ? error : JSON.stringify(error)}`); diff --git a/src/services/input.service.test.ts b/src/services/input.service.test.ts index c40842b..9181904 100644 --- a/src/services/input.service.test.ts +++ b/src/services/input.service.test.ts @@ -1,5 +1,4 @@ import { InputService, InputNames } from "./input.service"; -import { LoggerService } from "./logger.service"; import * as core from "@actions/core"; import * as fs from "fs"; @@ -13,14 +12,12 @@ jest.mock("@actions/core"); describe("InputService", () => { let service: InputService; - let logger: LoggerService; let getInputMock: jest.SpiedFunction; let getMultilineInputMock: jest.SpiedFunction; let existsSyncMock: jest.SpiedFunction; beforeEach(() => { - logger = new LoggerService(); - service = new InputService(logger); + service = new InputService(); existsSyncMock = jest.spyOn(fs, "existsSync").mockImplementation(); getInputMock = jest.spyOn(core, "getInput").mockImplementation(); @@ -52,7 +49,7 @@ describe("InputService", () => { expect(inputs.composeFiles).toEqual(["file1", "file2"]); }); - it("should return only existing composeFiles input", () => { + it("should throws an error when a compose file does not exist", () => { getMultilineInputMock.mockImplementation((inputName) => { switch (inputName) { case InputNames.ComposeFile: @@ -62,13 +59,28 @@ describe("InputService", () => { } }); - getInputMock.mockReturnValue(""); + getInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.Cwd: + return "/current/working/directory"; + default: + return ""; + } + }); - existsSyncMock.mockImplementation((file) => file === "file1"); + existsSyncMock.mockImplementation((file) => file === "/current/working/directory/file1"); - const inputs = service.getInputs(); + expect(() => service.getInputs()).toThrow( + "file2 does not exist in /current/working/directory" + ); + }); + + it("should throws an error when no composeFiles input", () => { + getMultilineInputMock.mockReturnValue([]); + + getInputMock.mockReturnValue(""); - expect(inputs.composeFiles).toEqual(["file1"]); + expect(() => service.getInputs()).toThrow("No compose files found"); }); }); @@ -78,12 +90,15 @@ describe("InputService", () => { switch (inputName) { case InputNames.Services: return ["service1", "service2"]; + case InputNames.ComposeFile: + return ["file1"]; default: return []; } }); getInputMock.mockReturnValue(""); + existsSyncMock.mockReturnValue(true); const inputs = service.getInputs(); @@ -93,7 +108,14 @@ describe("InputService", () => { describe("compose-flags", () => { it("should return given compose-flags input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockImplementation((inputName) => { switch (inputName) { @@ -104,15 +126,27 @@ describe("InputService", () => { } }); + existsSyncMock.mockReturnValue(true); + const inputs = service.getInputs(); expect(inputs.composeFlags).toEqual(["compose-flag1", "compose-flag2"]); }); it("should return empty array when no compose-flags input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockReturnValue(""); + + existsSyncMock.mockReturnValue(true); + const inputs = service.getInputs(); expect(inputs.composeFlags).toEqual([]); @@ -121,7 +155,14 @@ describe("InputService", () => { describe("up-flags", () => { it("should return given up-flags input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockImplementation((inputName) => { switch (inputName) { @@ -132,15 +173,27 @@ describe("InputService", () => { } }); + existsSyncMock.mockReturnValue(true); + const inputs = service.getInputs(); expect(inputs.upFlags).toEqual(["up-flag1", "up-flag2"]); }); it("should return empty array when no up-flags input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockReturnValue(""); + + existsSyncMock.mockReturnValue(true); + const inputs = service.getInputs(); expect(inputs.upFlags).toEqual([]); @@ -149,7 +202,14 @@ describe("InputService", () => { describe("down-flags", () => { it("should return given down-flags input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockImplementation((inputName) => { switch (inputName) { @@ -160,15 +220,26 @@ describe("InputService", () => { } }); + existsSyncMock.mockReturnValue(true); + const inputs = service.getInputs(); expect(inputs.downFlags).toEqual(["down-flag1", "down-flag2"]); }); it("should return empty array when no down-flags input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockReturnValue(""); + existsSyncMock.mockReturnValue(true); + const inputs = service.getInputs(); expect(inputs.downFlags).toEqual([]); @@ -177,7 +248,14 @@ describe("InputService", () => { describe("cwd", () => { it("should return given cwd input", () => { - getMultilineInputMock.mockReturnValue([]); + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); getInputMock.mockImplementation((inputName) => { switch (inputName) { case InputNames.Cwd: @@ -186,6 +264,7 @@ describe("InputService", () => { return ""; } }); + existsSyncMock.mockReturnValue(true); const inputs = service.getInputs(); diff --git a/src/services/input.service.ts b/src/services/input.service.ts index 50518a5..ababdb1 100644 --- a/src/services/input.service.ts +++ b/src/services/input.service.ts @@ -1,5 +1,4 @@ import { getInput, getMultilineInput } from "@actions/core"; -import { LoggerService } from "./logger.service"; import { existsSync } from "fs"; import { join } from "path"; @@ -22,8 +21,6 @@ export enum InputNames { } export class InputService { - constructor(private readonly logger: LoggerService) {} - getInputs(): Inputs { return { composeFiles: this.getComposeFiles(), @@ -37,18 +34,23 @@ export class InputService { private getComposeFiles(): string[] { const cwd = this.getCwd(); - return getMultilineInput(InputNames.ComposeFile).filter((composeFile) => { + const composeFiles = getMultilineInput(InputNames.ComposeFile).filter((composeFile) => { if (!composeFile.length) { return false; } if (!existsSync(join(cwd, composeFile))) { - this.logger.warn(`${composeFile} does not exist in ${cwd}`); - return false; + throw new Error(`${composeFile} does not exist in ${cwd}`); } return true; }); + + if (!composeFiles.length) { + throw new Error("No compose files found"); + } + + return composeFiles; } private getServices(): string[] {