feat: add logs debug on post

Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
This commit is contained in:
Emilien Escalle 2024-04-02 15:37:47 +02:00 committed by Emilien Escalle
parent a48c80beab
commit bc90ff6758
13 changed files with 344 additions and 187 deletions

View File

@ -11,9 +11,6 @@
<!-- end title -->
<!-- start badges -->
<a href="https%3A%2F%2Fgithub.com%2Fhoverkraft-tech%2Fcompose-action%2Freleases%2Flatest"><img src="https://img.shields.io/github/v/release/hoverkraft-tech/compose-action?display_name=tag&sort=semver&logo=github&style=flat-square" alt="Release%20by%20tag" /></a><a href="https%3A%2F%2Fgithub.com%2Fhoverkraft-tech%2Fcompose-action%2Freleases%2Flatest"><img src="https://img.shields.io/github/release-date/hoverkraft-tech/compose-action?display_name=tag&sort=semver&logo=github&style=flat-square" alt="Release%20by%20date" /></a><img src="https://img.shields.io/github/last-commit/hoverkraft-tech/compose-action?logo=github&style=flat-square" alt="Commit" /><a href="https%3A%2F%2Fgithub.com%2Fhoverkraft-tech%2Fcompose-action%2Fissues"><img src="https://img.shields.io/github/issues/hoverkraft-tech/compose-action?logo=github&style=flat-square" alt="Open%20Issues" /></a><img src="https://img.shields.io/github/downloads/hoverkraft-tech/compose-action/total?logo=github&style=flat-square" alt="Downloads" />
<!-- end badges -->
</div>
@ -22,8 +19,25 @@
This action runs your docker-compose file and clean up before action finished
<!-- end description -->
<!-- start contents -->
<!-- end contents -->
## Usage
### Action
The action will run `docker-compose up` to start the services defined in the given compose file(s).
The compose file(s) can be specified using the `compose-file` input.
Some extra options can be passed to the `docker-compose up` command using the `up-flags` input.
### Post hook
On post hook, the action will run `docker-compose down` to clean up the services.
In debug mode, the logs of the running services are printed before the cleanup.
Some extra options can be passed to the `docker-compose down` command using the `down-flags` input.
<!-- start usage -->
```yaml

54
dist/index.js generated vendored
View File

@ -25919,50 +25919,36 @@ exports["default"] = _default;
/***/ }),
/***/ 399:
/***/ 3878:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.run = exports.RunAction = void 0;
exports.run = void 0;
const core_1 = __nccwpck_require__(2186);
const docker_compose_service_1 = __nccwpck_require__(2911);
const input_service_1 = __nccwpck_require__(6492);
const logger_service_1 = __nccwpck_require__(6716);
var RunAction;
(function (RunAction) {
RunAction["UP"] = "up";
RunAction["DOWN"] = "down";
})(RunAction || (exports.RunAction = RunAction = {}));
const docker_compose_service_1 = __nccwpck_require__(2911);
/**
* The main function for the action.
* The run function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
async function run(run) {
async function run(callback) {
try {
const loggerService = new logger_service_1.LoggerService();
const dockerComposeService = new docker_compose_service_1.DockerComposeService();
const inputService = new input_service_1.InputService(loggerService);
const dockerComposeService = new docker_compose_service_1.DockerComposeService();
const inputs = inputService.getInputs();
(0, core_1.debug)(`inputs: ${JSON.stringify(inputs)}`);
loggerService.debug(`inputs: ${JSON.stringify(inputs)}`);
if (!inputs.composeFiles.length) {
loggerService.warn("no compose files found");
return;
}
switch (run) {
case RunAction.UP:
await dockerComposeService.up(inputs);
loggerService.info("compose started");
break;
case RunAction.DOWN:
await dockerComposeService.down(inputs);
loggerService.info("compose removed");
break;
}
await callback(inputs, loggerService, dockerComposeService);
}
catch (error) {
(0, core_1.setFailed)(`compose ${run} failed. ${error instanceof Error ? error : JSON.stringify(error)}`);
(0, core_1.setFailed)(`${error instanceof Error ? error : JSON.stringify(error)}`);
}
}
exports.run = run;
@ -25997,6 +25983,17 @@ class DockerComposeService {
};
await docker_compose_1.v2.down(options);
}
async logs(inputs) {
const options = {
...this.getCommonOptions(inputs),
follow: false,
};
const { err, out } = await docker_compose_1.v2.logs(inputs.services, options);
return {
error: err,
output: out,
};
}
getCommonOptions(inputs) {
return {
config: inputs.composeFiles,
@ -26100,6 +26097,9 @@ class LoggerService {
info(message) {
(0, core_1.info)(message);
}
debug(message) {
(0, core_1.debug)(message);
}
}
exports.LoggerService = LoggerService;
@ -36438,9 +36438,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
/**
* The entrypoint for the action.
*/
const main_1 = __nccwpck_require__(399);
const runner_1 = __nccwpck_require__(3878);
const callback = async (inputs, loggerService, dockerComposeService) => {
await dockerComposeService.up(inputs);
loggerService.info("compose started");
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(0, main_1.run)(main_1.RunAction.UP);
(0, runner_1.run)(callback);
})();

59
dist/post.js generated vendored
View File

@ -25919,50 +25919,36 @@ exports["default"] = _default;
/***/ }),
/***/ 399:
/***/ 3878:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.run = exports.RunAction = void 0;
exports.run = void 0;
const core_1 = __nccwpck_require__(2186);
const docker_compose_service_1 = __nccwpck_require__(2911);
const input_service_1 = __nccwpck_require__(6492);
const logger_service_1 = __nccwpck_require__(6716);
var RunAction;
(function (RunAction) {
RunAction["UP"] = "up";
RunAction["DOWN"] = "down";
})(RunAction || (exports.RunAction = RunAction = {}));
const docker_compose_service_1 = __nccwpck_require__(2911);
/**
* The main function for the action.
* The run function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
async function run(run) {
async function run(callback) {
try {
const loggerService = new logger_service_1.LoggerService();
const dockerComposeService = new docker_compose_service_1.DockerComposeService();
const inputService = new input_service_1.InputService(loggerService);
const dockerComposeService = new docker_compose_service_1.DockerComposeService();
const inputs = inputService.getInputs();
(0, core_1.debug)(`inputs: ${JSON.stringify(inputs)}`);
loggerService.debug(`inputs: ${JSON.stringify(inputs)}`);
if (!inputs.composeFiles.length) {
loggerService.warn("no compose files found");
return;
}
switch (run) {
case RunAction.UP:
await dockerComposeService.up(inputs);
loggerService.info("compose started");
break;
case RunAction.DOWN:
await dockerComposeService.down(inputs);
loggerService.info("compose removed");
break;
}
await callback(inputs, loggerService, dockerComposeService);
}
catch (error) {
(0, core_1.setFailed)(`compose ${run} failed. ${error instanceof Error ? error : JSON.stringify(error)}`);
(0, core_1.setFailed)(`${error instanceof Error ? error : JSON.stringify(error)}`);
}
}
exports.run = run;
@ -25997,6 +25983,17 @@ class DockerComposeService {
};
await docker_compose_1.v2.down(options);
}
async logs(inputs) {
const options = {
...this.getCommonOptions(inputs),
follow: false,
};
const { err, out } = await docker_compose_1.v2.logs(inputs.services, options);
return {
error: err,
output: out,
};
}
getCommonOptions(inputs) {
return {
config: inputs.composeFiles,
@ -26100,6 +26097,9 @@ class LoggerService {
info(message) {
(0, core_1.info)(message);
}
debug(message) {
(0, core_1.debug)(message);
}
}
exports.LoggerService = LoggerService;
@ -36438,9 +36438,18 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
/**
* The entrypoint for the post action.
*/
const main_1 = __nccwpck_require__(399);
const runner_1 = __nccwpck_require__(3878);
const callback = async (inputs, loggerService, dockerComposeService) => {
const { error, output } = await dockerComposeService.logs(inputs);
if (error) {
loggerService.debug("compose error:\n" + error);
}
loggerService.debug("compose logs:\n" + output);
await dockerComposeService.down(inputs);
loggerService.info("compose removed");
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(0, main_1.run)(main_1.RunAction.DOWN);
(0, runner_1.run)(callback);
})();

View File

@ -1,17 +1,56 @@
/**
* Unit tests for the action's entrypoint, src/index.ts
*/
import * as core from "@actions/core";
import { DockerComposeService } from "./services/docker-compose.service";
import { InputService } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
import * as main from "./main";
// Mock the action's entrypoint
const runMock = jest.spyOn(main, "run").mockImplementation();
let setFailedMock: jest.SpiedFunction<typeof core.setFailed>;
let getInputsMock: jest.SpiedFunction<typeof InputService.prototype.getInputs>;
let debugMock: jest.SpiedFunction<typeof LoggerService.prototype.debug>;
let infoMock: jest.SpiedFunction<typeof LoggerService.prototype.info>;
let upMock: jest.SpiedFunction<typeof DockerComposeService.prototype.up>;
describe("index", () => {
it("calls run when imported", async () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
require("../src/index");
beforeEach(() => {
jest.clearAllMocks();
expect(runMock).toHaveBeenCalled();
setFailedMock = jest.spyOn(core, "setFailed").mockImplementation();
infoMock = jest.spyOn(LoggerService.prototype, "info").mockImplementation();
debugMock = jest.spyOn(LoggerService.prototype, "debug").mockImplementation();
getInputsMock = jest.spyOn(InputService.prototype, "getInputs");
upMock = jest.spyOn(DockerComposeService.prototype, "up");
});
it("calls run when imported", async () => {
getInputsMock.mockImplementation(() => ({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
}));
upMock.mockResolvedValueOnce();
// eslint-disable-next-line @typescript-eslint/no-require-imports
await require("../src/index");
// 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(upMock).toHaveBeenCalledWith({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
});
expect(setFailedMock).not.toHaveBeenCalled();
expect(infoMock).toHaveBeenCalledWith("compose started");
});
});

View File

@ -1,7 +1,19 @@
/**
* The entrypoint for the action.
*/
import { run, RunAction } from "./main";
import { RunCallback, run } from "./runner";
import { DockerComposeService } from "./services/docker-compose.service";
import { Inputs } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
const callback: RunCallback = async (
inputs: Inputs,
loggerService: LoggerService,
dockerComposeService: DockerComposeService
) => {
await dockerComposeService.up(inputs);
loggerService.info("compose started");
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
run(RunAction.UP);
run(callback);

View File

@ -1,42 +0,0 @@
import { debug, setFailed } from "@actions/core";
import { DockerComposeService } from "./services/docker-compose.service";
import { InputService } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
export enum RunAction {
UP = "up",
DOWN = "down",
}
/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
export async function run(run: RunAction): Promise<void> {
try {
const loggerService = new LoggerService();
const dockerComposeService = new DockerComposeService();
const inputService = new InputService(loggerService);
const inputs = inputService.getInputs();
debug(`inputs: ${JSON.stringify(inputs)}`);
if (!inputs.composeFiles.length) {
loggerService.warn("no compose files found");
return;
}
switch (run) {
case RunAction.UP:
await dockerComposeService.up(inputs);
loggerService.info("compose started");
break;
case RunAction.DOWN:
await dockerComposeService.down(inputs);
loggerService.info("compose removed");
break;
}
} catch (error) {
setFailed(`compose ${run} failed. ${error instanceof Error ? error : JSON.stringify(error)}`);
}
}

View File

@ -1,17 +1,71 @@
/**
* Unit tests for the action's entrypoint, src/index.ts
*/
import * as core from "@actions/core";
import { DockerComposeService } from "./services/docker-compose.service";
import { InputService } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
import * as main from "./main";
// Mock the action's entrypoint
const runMock = jest.spyOn(main, "run").mockImplementation();
let setFailedMock: jest.SpiedFunction<typeof core.setFailed>;
let getInputsMock: jest.SpiedFunction<typeof InputService.prototype.getInputs>;
let debugMock: jest.SpiedFunction<typeof LoggerService.prototype.debug>;
let infoMock: jest.SpiedFunction<typeof LoggerService.prototype.info>;
let downMock: jest.SpiedFunction<typeof DockerComposeService.prototype.down>;
let logsMock: jest.SpiedFunction<typeof DockerComposeService.prototype.logs>;
describe("post", () => {
it("calls run when imported", async () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
require("../src/post");
beforeEach(() => {
jest.clearAllMocks();
expect(runMock).toHaveBeenCalled();
setFailedMock = jest.spyOn(core, "setFailed").mockImplementation();
infoMock = jest.spyOn(LoggerService.prototype, "info").mockImplementation();
debugMock = jest.spyOn(LoggerService.prototype, "debug").mockImplementation();
getInputsMock = jest.spyOn(InputService.prototype, "getInputs");
downMock = jest.spyOn(DockerComposeService.prototype, "down");
logsMock = jest.spyOn(DockerComposeService.prototype, "logs");
});
it("calls run when imported", async () => {
getInputsMock.mockImplementation(() => ({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
}));
logsMock.mockResolvedValueOnce({ error: "", output: "log" });
downMock.mockResolvedValueOnce();
// eslint-disable-next-line @typescript-eslint/no-require-imports
await require("../src/post");
await new Promise((resolve) => setTimeout(resolve, 0));
// 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(logsMock).toHaveBeenCalledWith({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
});
expect(debugMock).toHaveBeenNthCalledWith(2, "compose logs:\nlog");
expect(downMock).toHaveBeenCalledWith({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
});
expect(setFailedMock).not.toHaveBeenCalled();
expect(infoMock).toHaveBeenCalledWith("compose removed");
});
});

View File

@ -1,7 +1,28 @@
/**
* The entrypoint for the post action.
*/
import { run, RunAction } from "./main";
import { RunCallback, run } from "./runner";
import { DockerComposeService } from "./services/docker-compose.service";
import { Inputs } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
const callback: RunCallback = async (
inputs: Inputs,
loggerService: LoggerService,
dockerComposeService: DockerComposeService
) => {
const { error, output } = await dockerComposeService.logs(inputs);
if (error) {
loggerService.debug("compose error:\n" + error);
}
loggerService.debug("compose logs:\n" + output);
await dockerComposeService.down(inputs);
loggerService.info("compose removed");
};
// eslint-disable-next-line @typescript-eslint/no-floating-promises
run(RunAction.DOWN);
run(callback);

View File

@ -10,31 +10,24 @@ import * as core from "@actions/core";
import { DockerComposeService } from "./services/docker-compose.service";
import { InputService } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
import * as main from "./main";
import * as runner from "./runner";
// Mock the action's main function
const runMock = jest.spyOn(main, "run");
const runMock = jest.spyOn(runner, "run");
// Mock the external libraries and services used by the action
let debugMock: jest.SpiedFunction<typeof core.debug>;
let debugMock: jest.SpiedFunction<typeof LoggerService.prototype.debug>;
let warnMock: jest.SpiedFunction<typeof LoggerService.prototype.warn>;
let infoMock: jest.SpiedFunction<typeof LoggerService.prototype.info>;
let setFailedMock: jest.SpiedFunction<typeof core.setFailed>;
let getInputsMock: jest.SpiedFunction<typeof InputService.prototype.getInputs>;
let upMock: jest.SpiedFunction<typeof DockerComposeService.prototype.up>;
let downMock: jest.SpiedFunction<typeof DockerComposeService.prototype.down>;
describe("run", () => {
beforeEach(() => {
jest.clearAllMocks();
debugMock = jest.spyOn(core, "debug").mockImplementation();
debugMock = jest.spyOn(LoggerService.prototype, "debug").mockImplementation();
warnMock = jest.spyOn(LoggerService.prototype, "warn").mockImplementation();
infoMock = jest.spyOn(LoggerService.prototype, "info").mockImplementation();
setFailedMock = jest.spyOn(core, "setFailed").mockImplementation();
getInputsMock = jest.spyOn(InputService.prototype, "getInputs");
upMock = jest.spyOn(DockerComposeService.prototype, "up");
downMock = jest.spyOn(DockerComposeService.prototype, "down");
});
it("should return and warns when composeFile is empty", async () => {
@ -47,7 +40,9 @@ describe("run", () => {
cwd: "/current/working/dir",
}));
await main.run(main.RunAction.UP);
const callbackMock = jest.fn();
await runner.run(callbackMock);
expect(runMock).toHaveReturned();
// Verify that all of the functions were called correctly
@ -56,44 +51,10 @@ describe("run", () => {
'inputs: {"composeFiles":[],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}'
);
expect(warnMock).toHaveBeenNthCalledWith(1, "no compose files found");
expect(upMock).not.toHaveBeenCalled();
expect(callbackMock).not.toHaveBeenCalled();
expect(setFailedMock).not.toHaveBeenCalled();
});
it("should call up when some compose files are provided", async () => {
getInputsMock.mockImplementation(() => ({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
}));
upMock.mockResolvedValueOnce();
await main.run(main.RunAction.UP);
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(upMock).toHaveBeenCalledWith({
composeFiles: ["docker-compose.yml"],
services: [],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
});
expect(setFailedMock).not.toHaveBeenCalled();
expect(infoMock).toHaveBeenCalledWith("compose started");
});
it("sets a failed status", async () => {
getInputsMock.mockImplementation(() => ({
composeFiles: ["docker-compose.yml"],
@ -104,16 +65,18 @@ describe("run", () => {
cwd: "/current/working/dir",
}));
upMock.mockRejectedValueOnce(new Error("unkown error"));
const callbackMock = jest.fn();
callbackMock.mockRejectedValueOnce(new Error("unkown error"));
await main.run(main.RunAction.UP);
await runner.run(callbackMock);
expect(runMock).toHaveReturned();
// Verify that all of the functions were called correctly
expect(setFailedMock).toHaveBeenNthCalledWith(1, "compose up failed. Error: unkown error");
expect(callbackMock).toHaveBeenCalled();
expect(setFailedMock).toHaveBeenNthCalledWith(1, "Error: unkown error");
});
it("should call down when some compose files are provided", async () => {
it("should call callback when some compose files are provided", async () => {
getInputsMock.mockImplementation(() => ({
composeFiles: ["docker-compose.yml"],
services: [],
@ -123,9 +86,10 @@ describe("run", () => {
cwd: "/current/working/dir",
}));
downMock.mockResolvedValueOnce();
const callbackMock = jest.fn();
callbackMock.mockResolvedValueOnce(null);
await main.run(main.RunAction.DOWN);
await runner.run(callbackMock);
expect(runMock).toHaveReturned();
// Verify that all of the functions were called correctly
@ -134,16 +98,19 @@ describe("run", () => {
'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}'
);
expect(downMock).toHaveBeenCalledWith({
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();
expect(infoMock).toHaveBeenCalledWith("compose removed");
});
});

34
src/runner.ts Normal file
View File

@ -0,0 +1,34 @@
import { setFailed } from "@actions/core";
import { InputService, Inputs } from "./services/input.service";
import { LoggerService } from "./services/logger.service";
import { DockerComposeService } from "./services/docker-compose.service";
export type RunCallback = (
inputs: Inputs,
loggerService: LoggerService,
dockerComposeService: DockerComposeService
) => Promise<void>;
/**
* The run function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
export async function run(callback: RunCallback): Promise<void> {
try {
const loggerService = new LoggerService();
const inputService = new InputService(loggerService);
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)}`);
}
}

View File

@ -9,12 +9,14 @@ describe("DockerComposeService", () => {
let upAllMock: jest.SpiedFunction<typeof v2.upAll>;
let upManyMock: jest.SpiedFunction<typeof v2.upMany>;
let downMock: jest.SpiedFunction<typeof v2.down>;
let logsMock: jest.SpiedFunction<typeof v2.logs>;
beforeEach(() => {
service = new DockerComposeService();
upAllMock = jest.spyOn(v2, "upAll").mockImplementation();
upManyMock = jest.spyOn(v2, "upMany").mockImplementation();
downMock = jest.spyOn(v2, "down").mockImplementation();
logsMock = jest.spyOn(v2, "logs").mockImplementation();
});
afterEach(() => {
@ -87,4 +89,29 @@ describe("DockerComposeService", () => {
});
});
});
describe("logs", () => {
it("should call logs with correct options", async () => {
const inputs: Inputs = {
composeFiles: ["docker-compose.yml"],
services: ["helloworld2", "helloworld3"],
composeFlags: [],
upFlags: [],
downFlags: [],
cwd: "/current/working/dir",
};
logsMock.mockResolvedValue({ exitCode: 0, err: "", out: "logs" });
await service.logs(inputs);
expect(v2.logs).toHaveBeenCalledWith(["helloworld2", "helloworld3"], {
composeOptions: [],
config: ["docker-compose.yml"],
log: true,
cwd: "/current/working/dir",
follow: false,
});
});
});
});

View File

@ -1,9 +1,9 @@
import { IDockerComposeOptions, v2 } from "docker-compose";
import { IDockerComposeLogOptions, IDockerComposeOptions, v2 } from "docker-compose";
import { Inputs } from "./input.service";
export class DockerComposeService {
async up(inputs: Inputs): Promise<void> {
const options = {
const options: IDockerComposeOptions = {
...this.getCommonOptions(inputs),
commandOptions: inputs.upFlags,
};
@ -17,7 +17,7 @@ export class DockerComposeService {
}
async down(inputs: Inputs): Promise<void> {
const options = {
const options: IDockerComposeOptions = {
...this.getCommonOptions(inputs),
commandOptions: inputs.downFlags,
};
@ -25,6 +25,20 @@ export class DockerComposeService {
await v2.down(options);
}
async logs(inputs: Inputs): Promise<{ error: string; output: string }> {
const options: IDockerComposeLogOptions = {
...this.getCommonOptions(inputs),
follow: false,
};
const { err, out } = await v2.logs(inputs.services, options);
return {
error: err,
output: out,
};
}
private getCommonOptions(inputs: Inputs): IDockerComposeOptions {
return {
config: inputs.composeFiles,

View File

@ -1,4 +1,4 @@
import { info, warning } from "@actions/core";
import { debug, info, warning } from "@actions/core";
export class LoggerService {
warn(message: string): void {
@ -8,4 +8,8 @@ export class LoggerService {
info(message: string): void {
info(message);
}
debug(message: string) {
debug(message);
}
}