diff --git a/.github/ghadocs/examples/1_environment-variables.md b/.github/ghadocs/examples/1_environment-variables.md index 9b7bee6..69270e4 100644 --- a/.github/ghadocs/examples/1_environment-variables.md +++ b/.github/ghadocs/examples/1_environment-variables.md @@ -1,4 +1,5 @@ - + + ### Example Using environment variables ```yaml diff --git a/.github/ghadocs/examples/2_services.md b/.github/ghadocs/examples/2_services.md index 02e7113..78a4af2 100644 --- a/.github/ghadocs/examples/2_services.md +++ b/.github/ghadocs/examples/2_services.md @@ -1,4 +1,5 @@ - + + ### Example using `services` Perform `docker compose up` to some given service instead of all of them diff --git a/.github/ghadocs/examples/3_up-flags.md b/.github/ghadocs/examples/3_up-flags.md index 013936c..53ecfa5 100644 --- a/.github/ghadocs/examples/3_up-flags.md +++ b/.github/ghadocs/examples/3_up-flags.md @@ -1,4 +1,5 @@ - + + ### Example using `up-flags` Specify flags to pass to the `docker compose up`. Default is none. Can be used diff --git a/.github/ghadocs/examples/4_down-flags.md b/.github/ghadocs/examples/4_down-flags.md index 0157502..647af9d 100644 --- a/.github/ghadocs/examples/4_down-flags.md +++ b/.github/ghadocs/examples/4_down-flags.md @@ -1,4 +1,5 @@ - + + ### Example using `down-flags` Specify flags to pass to the `docker-compose down` command during cleanup. diff --git a/.github/ghadocs/examples/5_compose-flags.md b/.github/ghadocs/examples/5_compose-flags.md index e708d49..ea91263 100644 --- a/.github/ghadocs/examples/5_compose-flags.md +++ b/.github/ghadocs/examples/5_compose-flags.md @@ -1,4 +1,5 @@ - + + ### Example using `compose-flags` Specify flags to pass to the `docker compose` command. Default is none. A full diff --git a/.github/workflows/__check-action.yml b/.github/workflows/__check-action.yml index 9085e1a..afdec5b 100644 --- a/.github/workflows/__check-action.yml +++ b/.github/workflows/__check-action.yml @@ -269,5 +269,6 @@ jobs: - name: Act uses: ./ with: + docker-flags: "--context test-context" compose-file: "./test/docker-compose.yml" compose-version: "latest" diff --git a/README.md b/README.md index fa5ed28..61c3bcc 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,11 @@ -Release%20by%20tagRelease%20by%20dateCommitOpen%20IssuesDownloads +Release%20by%20tag +Release%20by%20date +Commit +Open%20Issues +Downloads diff --git a/action.yml b/action.yml index 57a7a82..98661ee 100644 --- a/action.yml +++ b/action.yml @@ -6,6 +6,9 @@ branding: color: gray-dark inputs: + docker-flags: + description: "Additional options to pass to `docker` command." + required: false compose-file: description: "Path to compose file(s). It can be a list of files. It can be absolute or relative to the current working directory (cwd)." required: false diff --git a/dist/index.js b/dist/index.js index 122182a..82ce350 100644 --- a/dist/index.js +++ b/dist/index.js @@ -33172,6 +33172,7 @@ async function run() { loggerService.info(`docker compose version: ${installedVersion}`); loggerService.info("Bringing up docker compose service(s)"); await dockerComposeService.up({ + dockerFlags: inputs.dockerFlags, composeFiles: inputs.composeFiles, composeFlags: inputs.composeFlags, cwd: inputs.cwd, @@ -33312,12 +33313,16 @@ class DockerComposeService { output: out, }; } - getCommonOptions({ composeFiles, composeFlags, cwd, }) { + getCommonOptions({ dockerFlags, composeFiles, composeFlags, cwd, }) { return { config: composeFiles, log: true, composeOptions: composeFlags, cwd: cwd, + executable: { + executablePath: "docker", + options: dockerFlags, + }, }; } } @@ -33338,6 +33343,7 @@ const fs_1 = __nccwpck_require__(9896); const path_1 = __nccwpck_require__(6928); var InputNames; (function (InputNames) { + InputNames["DockerFlags"] = "docker-flags"; InputNames["ComposeFile"] = "compose-file"; InputNames["Services"] = "services"; InputNames["ComposeFlags"] = "compose-flags"; @@ -33351,6 +33357,7 @@ exports.COMPOSE_VERSION_LATEST = "latest"; class InputService { getInputs() { return { + dockerFlags: this.getDockerFlags(), composeFiles: this.getComposeFiles(), services: this.getServices(), composeFlags: this.getComposeFlags(), @@ -33361,6 +33368,9 @@ class InputService { githubToken: this.getGithubToken(), }; } + getDockerFlags() { + return this.parseFlags((0, core_1.getInput)(InputNames.DockerFlags)); + } getComposeFiles() { const cwd = this.getCwd(); const composeFiles = (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { diff --git a/dist/post.js b/dist/post.js index d1c2148..1ad6bef 100644 --- a/dist/post.js +++ b/dist/post.js @@ -26335,6 +26335,7 @@ async function run() { const dockerComposeService = new docker_compose_service_1.DockerComposeService(); const inputs = inputService.getInputs(); const { error, output } = await dockerComposeService.logs({ + dockerFlags: inputs.dockerFlags, composeFiles: inputs.composeFiles, composeFlags: inputs.composeFlags, cwd: inputs.cwd, @@ -26345,6 +26346,7 @@ async function run() { } loggerService.debug("docker compose logs:\n" + output); await dockerComposeService.down({ + dockerFlags: inputs.dockerFlags, composeFiles: inputs.composeFiles, composeFlags: inputs.composeFlags, cwd: inputs.cwd, @@ -26399,12 +26401,16 @@ class DockerComposeService { output: out, }; } - getCommonOptions({ composeFiles, composeFlags, cwd, }) { + getCommonOptions({ dockerFlags, composeFiles, composeFlags, cwd, }) { return { config: composeFiles, log: true, composeOptions: composeFlags, cwd: cwd, + executable: { + executablePath: "docker", + options: dockerFlags, + }, }; } } @@ -26425,6 +26431,7 @@ const fs_1 = __nccwpck_require__(9896); const path_1 = __nccwpck_require__(6928); var InputNames; (function (InputNames) { + InputNames["DockerFlags"] = "docker-flags"; InputNames["ComposeFile"] = "compose-file"; InputNames["Services"] = "services"; InputNames["ComposeFlags"] = "compose-flags"; @@ -26438,6 +26445,7 @@ exports.COMPOSE_VERSION_LATEST = "latest"; class InputService { getInputs() { return { + dockerFlags: this.getDockerFlags(), composeFiles: this.getComposeFiles(), services: this.getServices(), composeFlags: this.getComposeFlags(), @@ -26448,6 +26456,9 @@ class InputService { githubToken: this.getGithubToken(), }; } + getDockerFlags() { + return this.parseFlags((0, core_1.getInput)(InputNames.DockerFlags)); + } getComposeFiles() { const cwd = this.getCwd(); const composeFiles = (0, core_1.getMultilineInput)(InputNames.ComposeFile).filter((composeFile) => { diff --git a/src/index-runner.test.ts b/src/index-runner.test.ts index accac2f..0666537 100644 --- a/src/index-runner.test.ts +++ b/src/index-runner.test.ts @@ -28,6 +28,7 @@ describe("run", () => { it("should install docker compose with specified version", async () => { // Arrange getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], @@ -49,7 +50,7 @@ describe("run", () => { expect(infoMock).toHaveBeenCalledWith("Setting up docker compose version 1.29.2"); expect(debugMock).toHaveBeenCalledWith( - 'inputs: {"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir","composeVersion":"1.29.2","githubToken":null}' + 'inputs: {"dockerFlags":[],"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir","composeVersion":"1.29.2","githubToken":null}' ); expect(installMock).toHaveBeenCalledWith({ @@ -59,6 +60,7 @@ describe("run", () => { }); expect(upMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", @@ -72,6 +74,7 @@ describe("run", () => { it("should bring up docker compose services", async () => { // Arrange getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["web"], composeFlags: [], @@ -87,6 +90,7 @@ describe("run", () => { // Assert expect(upMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", @@ -102,6 +106,7 @@ describe("run", () => { upMock.mockRejectedValue(error); getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["web"], composeFlags: [], @@ -125,6 +130,7 @@ describe("run", () => { upMock.mockRejectedValue(error); getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["web"], composeFlags: [], diff --git a/src/index-runner.ts b/src/index-runner.ts index 988adff..04e63af 100644 --- a/src/index-runner.ts +++ b/src/index-runner.ts @@ -36,6 +36,7 @@ export async function run(): Promise { loggerService.info("Bringing up docker compose service(s)"); await dockerComposeService.up({ + dockerFlags: inputs.dockerFlags, composeFiles: inputs.composeFiles, composeFlags: inputs.composeFlags, cwd: inputs.cwd, diff --git a/src/index.test.ts b/src/index.test.ts index 1613dec..3784557 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -25,6 +25,7 @@ describe("index", () => { it("calls run when imported", async () => { getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], @@ -48,12 +49,13 @@ describe("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","composeVersion":null,"githubToken":null}' + 'inputs: {"dockerFlags":[],"composeFiles":["docker-compose.yml"],"services":[],"composeFlags":[],"upFlags":[],"downFlags":[],"cwd":"/current/working/dir","composeVersion":null,"githubToken":null}' ); expect(infoMock).toHaveBeenNthCalledWith(3, "Bringing up docker compose service(s)"); expect(upMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], diff --git a/src/post-runner.test.ts b/src/post-runner.test.ts index 55849d7..3bcf85e 100644 --- a/src/post-runner.test.ts +++ b/src/post-runner.test.ts @@ -27,6 +27,7 @@ describe("run", () => { it("should bring down docker compose service(s) and log output", async () => { // Arrange getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], @@ -46,6 +47,7 @@ describe("run", () => { // Assert expect(logsMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", @@ -53,6 +55,7 @@ describe("run", () => { }); expect(downMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", @@ -69,6 +72,7 @@ describe("run", () => { it("should log docker composer errors if any", async () => { // Arrange getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], @@ -94,6 +98,7 @@ describe("run", () => { composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", + dockerFlags: [], services: [], }); @@ -101,6 +106,7 @@ describe("run", () => { composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", + dockerFlags: [], downFlags: [], }); @@ -129,6 +135,7 @@ describe("run", () => { downMock.mockRejectedValue(error); getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["web"], composeFlags: [], @@ -152,6 +159,7 @@ describe("run", () => { downMock.mockRejectedValue(error); getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["web"], composeFlags: [], diff --git a/src/post-runner.ts b/src/post-runner.ts index 1ce14f0..2789037 100644 --- a/src/post-runner.ts +++ b/src/post-runner.ts @@ -16,6 +16,7 @@ export async function run(): Promise { const inputs = inputService.getInputs(); const { error, output } = await dockerComposeService.logs({ + dockerFlags: inputs.dockerFlags, composeFiles: inputs.composeFiles, composeFlags: inputs.composeFlags, cwd: inputs.cwd, @@ -29,6 +30,7 @@ export async function run(): Promise { loggerService.debug("docker compose logs:\n" + output); await dockerComposeService.down({ + dockerFlags: inputs.dockerFlags, composeFiles: inputs.composeFiles, composeFlags: inputs.composeFlags, cwd: inputs.cwd, diff --git a/src/post.test.ts b/src/post.test.ts index a18c7ba..7235e86 100644 --- a/src/post.test.ts +++ b/src/post.test.ts @@ -24,6 +24,7 @@ describe("post", () => { it("calls run when imported", async () => { getInputsMock.mockImplementation(() => ({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], @@ -42,6 +43,7 @@ describe("post", () => { await new Promise((resolve) => setTimeout(resolve, 0)); expect(logsMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", @@ -49,6 +51,7 @@ describe("post", () => { }); expect(downMock).toHaveBeenCalledWith({ + dockerFlags: [], composeFiles: ["docker-compose.yml"], composeFlags: [], cwd: "/current/working/dir", diff --git a/src/services/docker-compose.service.test.ts b/src/services/docker-compose.service.test.ts index 9c7e665..8d1c702 100644 --- a/src/services/docker-compose.service.test.ts +++ b/src/services/docker-compose.service.test.ts @@ -25,6 +25,7 @@ describe("DockerComposeService", () => { describe("up", () => { it("should call up with correct options", async () => { const upInputs: UpInputs = { + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: [], composeFlags: [], @@ -38,6 +39,35 @@ describe("DockerComposeService", () => { composeOptions: [], commandOptions: [], config: ["docker-compose.yml"], + executable: { + executablePath: "docker", + options: [], + }, + log: true, + cwd: "/current/working/dir", + }); + }); + + it("should call up with specific docker flags", async () => { + const upInputs: UpInputs = { + dockerFlags: ["--context", "dev"], + composeFiles: ["docker-compose.yml"], + services: [], + composeFlags: [], + upFlags: [], + cwd: "/current/working/dir", + }; + + await service.up(upInputs); + + expect(upAllMock).toHaveBeenCalledWith({ + composeOptions: [], + commandOptions: [], + config: ["docker-compose.yml"], + executable: { + executablePath: "docker", + options: ["--context", "dev"], + }, log: true, cwd: "/current/working/dir", }); @@ -45,6 +75,7 @@ describe("DockerComposeService", () => { it("should call up with specific services", async () => { const upInputs: UpInputs = { + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["helloworld2", "helloworld3"], composeFlags: [], @@ -58,8 +89,12 @@ describe("DockerComposeService", () => { composeOptions: [], commandOptions: ["--build"], config: ["docker-compose.yml"], - log: true, cwd: "/current/working/dir", + executable: { + executablePath: "docker", + options: [], + }, + log: true, }); }); }); @@ -67,6 +102,7 @@ describe("DockerComposeService", () => { describe("down", () => { it("should call down with correct options", async () => { const downInputs: DownInputs = { + dockerFlags: [], composeFiles: [], composeFlags: [], downFlags: ["--volumes", "--remove-orphans"], @@ -79,6 +115,10 @@ describe("DockerComposeService", () => { composeOptions: [], commandOptions: ["--volumes", "--remove-orphans"], config: [], + executable: { + executablePath: "docker", + options: [], + }, log: true, cwd: "/current/working/dir", }); @@ -88,6 +128,7 @@ describe("DockerComposeService", () => { describe("logs", () => { it("should call logs with correct options", async () => { const logsInputs: LogsInputs = { + dockerFlags: [], composeFiles: ["docker-compose.yml"], services: ["helloworld2", "helloworld3"], composeFlags: [], @@ -103,6 +144,10 @@ describe("DockerComposeService", () => { config: ["docker-compose.yml"], log: true, cwd: "/current/working/dir", + executable: { + executablePath: "docker", + options: [], + }, follow: false, }); }); diff --git a/src/services/docker-compose.service.ts b/src/services/docker-compose.service.ts index f467ae1..e68e3af 100644 --- a/src/services/docker-compose.service.ts +++ b/src/services/docker-compose.service.ts @@ -9,6 +9,7 @@ import { import { Inputs } from "./input.service"; type OptionsInputs = { + dockerFlags: Inputs["dockerFlags"]; composeFiles: Inputs["composeFiles"]; composeFlags: Inputs["composeFlags"]; cwd: Inputs["cwd"]; @@ -60,6 +61,7 @@ export class DockerComposeService { } private getCommonOptions({ + dockerFlags, composeFiles, composeFlags, cwd, @@ -69,6 +71,10 @@ export class DockerComposeService { log: true, composeOptions: composeFlags, cwd: cwd, + executable: { + executablePath: "docker", + options: dockerFlags, + }, }; } } diff --git a/src/services/input.service.test.ts b/src/services/input.service.test.ts index d46d38c..863af98 100644 --- a/src/services/input.service.test.ts +++ b/src/services/input.service.test.ts @@ -23,6 +23,53 @@ describe("InputService", () => { }); describe("getInputs", () => { + describe("docker-flags", () => { + it("should return given docker-flags input", () => { + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); + + getInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.DockerFlags: + return "docker-flag1 docker-flag2"; + default: + return ""; + } + }); + + existsSyncMock.mockReturnValue(true); + + const inputs = service.getInputs(); + + expect(inputs.dockerFlags).toEqual(["docker-flag1", "docker-flag2"]); + }); + + it("should return empty array when no docker-flags input", () => { + getMultilineInputMock.mockImplementation((inputName) => { + switch (inputName) { + case InputNames.ComposeFile: + return ["file1"]; + default: + return []; + } + }); + + getInputMock.mockReturnValue(""); + + existsSyncMock.mockReturnValue(true); + + const inputs = service.getInputs(); + + expect(inputs.dockerFlags).toEqual([]); + }); + }); + describe("composeFiles", () => { it("should return given composeFiles input", () => { getMultilineInputMock.mockImplementation((inputName) => { diff --git a/src/services/input.service.ts b/src/services/input.service.ts index 1bf4240..2faf383 100644 --- a/src/services/input.service.ts +++ b/src/services/input.service.ts @@ -3,6 +3,7 @@ import { existsSync } from "fs"; import { join } from "path"; export type Inputs = { + dockerFlags: string[]; composeFiles: string[]; services: string[]; composeFlags: string[]; @@ -14,6 +15,7 @@ export type Inputs = { }; export enum InputNames { + DockerFlags = "docker-flags", ComposeFile = "compose-file", Services = "services", ComposeFlags = "compose-flags", @@ -29,6 +31,7 @@ export const COMPOSE_VERSION_LATEST = "latest"; export class InputService { getInputs(): Inputs { return { + dockerFlags: this.getDockerFlags(), composeFiles: this.getComposeFiles(), services: this.getServices(), composeFlags: this.getComposeFlags(), @@ -40,6 +43,10 @@ export class InputService { }; } + private getDockerFlags(): string[] { + return this.parseFlags(getInput(InputNames.DockerFlags)); + } + private getComposeFiles(): string[] { const cwd = this.getCwd(); const composeFiles = getMultilineInput(InputNames.ComposeFile).filter((composeFile: string) => {