diff --git a/.github/workflows/__check-action.yml b/.github/workflows/__check-action.yml index 1126983..a0872ad 100644 --- a/.github/workflows/__check-action.yml +++ b/.github/workflows/__check-action.yml @@ -104,3 +104,27 @@ jobs: docker-compose -f ./docker/docker-compose.yml -f ./docker/docker-compose.ci.yml ps | grep docker-helloworld4-1 docker-compose -f ./docker/docker-compose.yml -f ./docker/docker-compose.ci.yml ps | (grep docker-helloworld-1 && echo "Unexpected service is running" && exit 1) || true docker-compose -f ./docker/docker-compose.yml -f ./docker/docker-compose.ci.yml ps | (grep docker-helloworld3-1 && echo "Unexpected service is running" && exit 1) || true + + test-action-with-cwd: + runs-on: ubuntu-latest + name: Test with cwd + steps: + - uses: actions/checkout@v4 + - uses: hoverkraft-tech/ci-github-nodejs/actions/setup-node@0.4.2 + + - name: Act + uses: ./ + with: + compose-file: "docker-compose.yml" + cwd: "./docker" + services: | + helloworld2 + helloworld3 + + - name: "Assert: only expected services are running" + run: | + docker-compose -f ./docker/docker-compose.yml ps + + docker-compose -f ./docker/docker-compose.yml ps | grep docker-helloworld2-1 + docker-compose -f ./docker/docker-compose.yml ps | grep docker-helloworld3-1 + docker-compose -f ./docker/docker-compose.yml ps | (grep docker-helloworld-1 && echo "Unexpected service helloworld is running" && exit 1) || true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..53c37a1 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/action.yml b/action.yml index c79bb94..d596a83 100644 --- a/action.yml +++ b/action.yml @@ -1,31 +1,34 @@ -name: 'Docker Compose Action' -description: - 'This action runs your docker-compose file and clean up before action finished' -author: 'Hoverkraft' +name: "Docker Compose Action" +description: "This action runs your docker-compose file and clean up before action finished" +author: "Hoverkraft" branding: icon: anchor color: gray-dark inputs: compose-file: - description: 'Relative path to compose file(s). It can be a list of files.' + description: "Relative path to compose file(s). It can be a list of files." required: false - default: './docker-compose.yml' + default: "./docker-compose.yml" services: - description: 'Services to perform docker-compose up.' + description: "Services to perform docker-compose up." required: false up-flags: - description: 'Additional options to pass to `docker-compose up` command.' + description: "Additional options to pass to `docker-compose up` command." required: false - default: '' + default: "" down-flags: - description: 'Additional options to pass to `docker-compose down` command.' + description: "Additional options to pass to `docker-compose down` command." required: false - default: '' + default: "" compose-flags: - description: 'Additional options to pass to `docker-compose` command.' + description: "Additional options to pass to `docker-compose` command." required: false - default: '' + default: "" + cwd: + description: "Current working directory" + required: false + default: ${{ github.workspace }} runs: using: node20 main: dist/index.js diff --git a/dist/index.js b/dist/index.js index b5ea5b6..80eddec 100644 --- a/dist/index.js +++ b/dist/index.js @@ -26002,6 +26002,7 @@ class DockerComposeService { config: inputs.composeFiles, log: true, composeOptions: inputs.composeFlags, + cwd: inputs.cwd, }; } } @@ -26019,6 +26020,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.InputService = exports.InputNames = void 0; const core_1 = __nccwpck_require__(2186); const fs_1 = __nccwpck_require__(7147); +const path_1 = __nccwpck_require__(1017); var InputNames; (function (InputNames) { InputNames["ComposeFile"] = "compose-file"; @@ -26026,6 +26028,7 @@ var InputNames; InputNames["ComposeFlags"] = "compose-flags"; InputNames["UpFlags"] = "up-flags"; InputNames["DownFlags"] = "down-flags"; + InputNames["Cwd"] = "cwd"; })(InputNames || (exports.InputNames = InputNames = {})); class InputService { logger; @@ -26039,15 +26042,17 @@ class InputService { composeFlags: this.getComposeFlags(), upFlags: this.getUpFlags(), downFlags: this.getDownFlags(), + cwd: this.getCwd(), }; } getComposeFiles() { + const cwd = this.getCwd(); return (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { if (!composeFile.length) { return false; } - if (!(0, fs_1.existsSync)(composeFile)) { - this.logger.warn(`${composeFile} not exists`); + if (!(0, fs_1.existsSync)((0, path_1.join)(cwd, composeFile))) { + this.logger.warn(`${composeFile} does not exist in ${cwd}`); return false; } return true; @@ -26071,6 +26076,9 @@ class InputService { } return flags.trim().split(" "); } + getCwd() { + return (0, core_1.getInput)(InputNames.Cwd); + } } exports.InputService = InputService; diff --git a/dist/post.js b/dist/post.js index 547d5b0..bd3d320 100644 --- a/dist/post.js +++ b/dist/post.js @@ -26002,6 +26002,7 @@ class DockerComposeService { config: inputs.composeFiles, log: true, composeOptions: inputs.composeFlags, + cwd: inputs.cwd, }; } } @@ -26019,6 +26020,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.InputService = exports.InputNames = void 0; const core_1 = __nccwpck_require__(2186); const fs_1 = __nccwpck_require__(7147); +const path_1 = __nccwpck_require__(1017); var InputNames; (function (InputNames) { InputNames["ComposeFile"] = "compose-file"; @@ -26026,6 +26028,7 @@ var InputNames; InputNames["ComposeFlags"] = "compose-flags"; InputNames["UpFlags"] = "up-flags"; InputNames["DownFlags"] = "down-flags"; + InputNames["Cwd"] = "cwd"; })(InputNames || (exports.InputNames = InputNames = {})); class InputService { logger; @@ -26039,15 +26042,17 @@ class InputService { composeFlags: this.getComposeFlags(), upFlags: this.getUpFlags(), downFlags: this.getDownFlags(), + cwd: this.getCwd(), }; } getComposeFiles() { + const cwd = this.getCwd(); return (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { if (!composeFile.length) { return false; } - if (!(0, fs_1.existsSync)(composeFile)) { - this.logger.warn(`${composeFile} not exists`); + if (!(0, fs_1.existsSync)((0, path_1.join)(cwd, composeFile))) { + this.logger.warn(`${composeFile} does not exist in ${cwd}`); return false; } return true; @@ -26071,6 +26076,9 @@ class InputService { } return flags.trim().split(" "); } + getCwd() { + return (0, core_1.getInput)(InputNames.Cwd); + } } exports.InputService = InputService; diff --git a/src/main.test.ts b/src/main.test.ts index d5299f5..1951c6d 100644 --- a/src/main.test.ts +++ b/src/main.test.ts @@ -44,6 +44,7 @@ describe("run", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", })); await main.run(main.RunAction.UP); @@ -52,7 +53,7 @@ describe("run", () => { // Verify that all of the functions were called correctly expect(debugMock).toHaveBeenNthCalledWith( 1, - 'inputs: {"composeFiles":[],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[]}' + 'inputs: {"composeFiles":[],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}' ); expect(warnMock).toHaveBeenNthCalledWith(1, "no compose files found"); expect(upMock).not.toHaveBeenCalled(); @@ -66,6 +67,7 @@ describe("run", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", })); upMock.mockResolvedValueOnce(); @@ -76,7 +78,7 @@ describe("run", () => { // Verify that all of the functions were called correctly expect(debugMock).toHaveBeenNthCalledWith( 1, - 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[]}' + 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}' ); expect(upMock).toHaveBeenCalledWith({ @@ -85,6 +87,7 @@ describe("run", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", }); expect(setFailedMock).not.toHaveBeenCalled(); @@ -98,6 +101,7 @@ describe("run", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", })); upMock.mockRejectedValueOnce(new Error("unkown error")); @@ -116,6 +120,7 @@ describe("run", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", })); downMock.mockResolvedValueOnce(); @@ -126,7 +131,7 @@ describe("run", () => { // Verify that all of the functions were called correctly expect(debugMock).toHaveBeenNthCalledWith( 1, - 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[]}' + 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir"}' ); expect(downMock).toHaveBeenCalledWith({ @@ -135,6 +140,7 @@ describe("run", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", }); expect(setFailedMock).not.toHaveBeenCalled(); diff --git a/src/services/docker-compose.service.test.ts b/src/services/docker-compose.service.test.ts index 69fe287..7519637 100644 --- a/src/services/docker-compose.service.test.ts +++ b/src/services/docker-compose.service.test.ts @@ -29,6 +29,7 @@ describe("DockerComposeService", () => { composeFlags: [], upFlags: [], downFlags: [], + cwd: "/current/working/dir", }; await service.up(inputs); @@ -38,6 +39,7 @@ describe("DockerComposeService", () => { commandOptions: [], config: ["docker-compose.yml"], log: true, + cwd: "/current/working/dir", }); }); @@ -48,6 +50,7 @@ describe("DockerComposeService", () => { composeFlags: [], upFlags: ["--build"], downFlags: [], + cwd: "/current/working/dir", }; await service.up(inputs); @@ -57,6 +60,7 @@ describe("DockerComposeService", () => { commandOptions: ["--build"], config: ["docker-compose.yml"], log: true, + cwd: "/current/working/dir", }); }); }); @@ -69,6 +73,7 @@ describe("DockerComposeService", () => { composeFlags: [], upFlags: [], downFlags: ["--volumes", "--remove-orphans"], + cwd: "/current/working/dir", }; await service.down(inputs); @@ -78,6 +83,7 @@ describe("DockerComposeService", () => { commandOptions: ["--volumes", "--remove-orphans"], config: [], log: true, + cwd: "/current/working/dir", }); }); }); diff --git a/src/services/docker-compose.service.ts b/src/services/docker-compose.service.ts index 31fe770..4e6739d 100644 --- a/src/services/docker-compose.service.ts +++ b/src/services/docker-compose.service.ts @@ -30,6 +30,7 @@ export class DockerComposeService { config: inputs.composeFiles, log: true, composeOptions: inputs.composeFlags, + cwd: inputs.cwd, }; } } diff --git a/src/services/input.service.test.ts b/src/services/input.service.test.ts index 4c6ffe6..c40842b 100644 --- a/src/services/input.service.test.ts +++ b/src/services/input.service.test.ts @@ -71,6 +71,7 @@ describe("InputService", () => { expect(inputs.composeFiles).toEqual(["file1"]); }); }); + describe("services", () => { it("should return given services input", () => { getMultilineInputMock.mockImplementation((inputName) => { @@ -89,6 +90,7 @@ describe("InputService", () => { expect(inputs.services).toEqual(["service1", "service2"]); }); }); + describe("compose-flags", () => { it("should return given compose-flags input", () => { getMultilineInputMock.mockReturnValue([]); @@ -116,6 +118,7 @@ describe("InputService", () => { expect(inputs.composeFlags).toEqual([]); }); }); + describe("up-flags", () => { it("should return given up-flags input", () => { getMultilineInputMock.mockReturnValue([]); @@ -143,6 +146,7 @@ describe("InputService", () => { expect(inputs.upFlags).toEqual([]); }); }); + describe("down-flags", () => { it("should return given down-flags input", () => { getMultilineInputMock.mockReturnValue([]); @@ -170,5 +174,23 @@ describe("InputService", () => { expect(inputs.downFlags).toEqual([]); }); }); + + describe("cwd", () => { + it("should return given cwd input", () => { + getMultilineInputMock.mockReturnValue([]); + getInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.Cwd: + return "cwd"; + default: + return ""; + } + }); + + const inputs = service.getInputs(); + + expect(inputs.cwd).toEqual("cwd"); + }); + }); }); }); diff --git a/src/services/input.service.ts b/src/services/input.service.ts index 1326838..50518a5 100644 --- a/src/services/input.service.ts +++ b/src/services/input.service.ts @@ -1,6 +1,7 @@ import { getInput, getMultilineInput } from "@actions/core"; import { LoggerService } from "./logger.service"; import { existsSync } from "fs"; +import { join } from "path"; export type Inputs = { composeFiles: string[]; @@ -8,6 +9,7 @@ export type Inputs = { composeFlags: string[]; upFlags: string[]; downFlags: string[]; + cwd: string; }; export enum InputNames { @@ -16,6 +18,7 @@ export enum InputNames { ComposeFlags = "compose-flags", UpFlags = "up-flags", DownFlags = "down-flags", + Cwd = "cwd", } export class InputService { @@ -28,17 +31,19 @@ export class InputService { composeFlags: this.getComposeFlags(), upFlags: this.getUpFlags(), downFlags: this.getDownFlags(), + cwd: this.getCwd(), }; } private getComposeFiles(): string[] { + const cwd = this.getCwd(); return getMultilineInput(InputNames.ComposeFile).filter((composeFile) => { if (!composeFile.length) { return false; } - if (!existsSync(composeFile)) { - this.logger.warn(`${composeFile} not exists`); + if (!existsSync(join(cwd, composeFile))) { + this.logger.warn(`${composeFile} does not exist in ${cwd}`); return false; } @@ -69,4 +74,8 @@ export class InputService { return flags.trim().split(" "); } + + private getCwd(): string { + return getInput(InputNames.Cwd); + } }