feat: add docker flags input

Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
This commit is contained in:
Emilien Escalle 2025-01-21 20:05:19 +00:00
parent 49c8cfd612
commit d3ad8ec3be
20 changed files with 172 additions and 11 deletions

View File

@ -1,4 +1,5 @@
<!-- markdownlint-disable-next-line first-line-heading -->
<!-- markdownlint-disable first-line-heading -->
### Example Using environment variables
```yaml

View File

@ -1,4 +1,5 @@
<!-- markdownlint-disable-next-line first-line-heading -->
<!-- markdownlint-disable first-line-heading -->
### Example using `services`
Perform `docker compose up` to some given service instead of all of them

View File

@ -1,4 +1,5 @@
<!-- markdownlint-disable-next-line first-line-heading -->
<!-- markdownlint-disable first-line-heading -->
### Example using `up-flags`
Specify flags to pass to the `docker compose up`. Default is none. Can be used

View File

@ -1,4 +1,5 @@
<!-- markdownlint-disable-next-line first-line-heading -->
<!-- markdownlint-disable first-line-heading -->
### Example using `down-flags`
Specify flags to pass to the `docker-compose down` command during cleanup.

View File

@ -1,4 +1,5 @@
<!-- markdownlint-disable-next-line first-line-heading -->
<!-- markdownlint-disable first-line-heading -->
### Example using `compose-flags`
Specify flags to pass to the `docker compose` command. Default is none. A full

View File

@ -269,5 +269,6 @@ jobs:
- name: Act
uses: ./
with:
docker-flags: "--context test-context"
compose-file: "./test/docker-compose.yml"
compose-version: "latest"

View File

@ -12,7 +12,11 @@
<!-- 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" />
<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 -->

View File

@ -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

12
dist/index.js generated vendored
View File

@ -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) => {

13
dist/post.js generated vendored
View File

@ -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) => {

View File

@ -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: [],

View File

@ -36,6 +36,7 @@ export async function run(): Promise<void> {
loggerService.info("Bringing up docker compose service(s)");
await dockerComposeService.up({
dockerFlags: inputs.dockerFlags,
composeFiles: inputs.composeFiles,
composeFlags: inputs.composeFlags,
cwd: inputs.cwd,

View File

@ -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: [],

View File

@ -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: [],

View File

@ -16,6 +16,7 @@ export async function run(): Promise<void> {
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<void> {
loggerService.debug("docker compose logs:\n" + output);
await dockerComposeService.down({
dockerFlags: inputs.dockerFlags,
composeFiles: inputs.composeFiles,
composeFlags: inputs.composeFlags,
cwd: inputs.cwd,

View File

@ -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",

View File

@ -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,
});
});

View File

@ -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,
},
};
}
}

View File

@ -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) => {

View File

@ -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) => {