compose-action/src/services/docker-compose.service.ts
dependabot[bot] 9c11768144
Some checks failed
Internal - Main - Continuous Integration / ci (push) Has been cancelled
Need fix to Issue / main (push) Has been cancelled
Prepare release / release (push) Has been cancelled
Internal - Main - Continuous Integration / prepare-docs (push) Has been cancelled
Internal - Main - Continuous Integration / sync-docs (push) Has been cancelled
Mark stale issues and pull requests / main (push) Has been cancelled
chore(deps): bump the github-actions-dependencies group with 6 updates
Bumps the github-actions-dependencies group with 6 updates:
---
updated-dependencies:
- dependency-name: hoverkraft-tech/ci-github-common/.github/workflows/linter.yml
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: hoverkraft-tech/ci-github-common/.github/workflows/greetings.yml
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: hoverkraft-tech/ci-github-common
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: hoverkraft-tech/ci-github-common/.github/workflows/need-fix-to-issue.yml
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: hoverkraft-tech/ci-github-common/.github/workflows/semantic-pull-request.yml
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
- dependency-name: hoverkraft-tech/ci-github-common/.github/workflows/stale.yml
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
2026-06-04 17:15:41 +02:00

154 lines
3.5 KiB
TypeScript

import {
down,
type IDockerComposeLogOptions,
type IDockerComposeOptions,
type IDockerComposeResult,
logs,
upAll,
upMany,
} from "docker-compose";
import type { Inputs } from "./input.service.js";
type OptionsInputs = {
dockerFlags: Inputs["dockerFlags"];
composeFiles: Inputs["composeFiles"];
composeFlags: Inputs["composeFlags"];
cwd: Inputs["cwd"];
serviceLogger: (message: string) => void;
};
export type UpInputs = OptionsInputs & {
upFlags: Inputs["upFlags"];
services: Inputs["services"];
};
export type DownInputs = OptionsInputs & { downFlags: Inputs["downFlags"] };
export type LogsInputs = OptionsInputs & { services: Inputs["services"] };
export class DockerComposeService {
async up({ upFlags, services, ...optionsInputs }: UpInputs): Promise<void> {
const options: IDockerComposeOptions = {
...this.getCommonOptions(optionsInputs),
commandOptions: upFlags,
};
try {
if (services.length > 0) {
await upMany(services, options);
return;
}
await upAll(options);
} catch (error) {
throw this.formatDockerComposeError(error);
}
}
async down({ downFlags, ...optionsInputs }: DownInputs): Promise<void> {
const options: IDockerComposeOptions = {
...this.getCommonOptions(optionsInputs),
commandOptions: downFlags,
};
try {
await down(options);
} catch (error) {
throw this.formatDockerComposeError(error);
}
}
async logs({ services, ...optionsInputs }: LogsInputs): Promise<{
error: string;
output: string;
}> {
const options: IDockerComposeLogOptions = {
...this.getCommonOptions(optionsInputs),
follow: false,
};
const { err, out } = await logs(services, options);
return {
error: err,
output: out,
};
}
private getCommonOptions({
dockerFlags,
composeFiles,
composeFlags,
cwd,
serviceLogger,
}: OptionsInputs): IDockerComposeOptions {
return {
config: composeFiles,
composeOptions: composeFlags,
cwd: cwd,
callback: (chunk) => serviceLogger(chunk.toString()),
executable: {
executablePath: "docker",
options: dockerFlags,
},
};
}
/**
* Formats docker-compose errors into proper Error objects with readable messages
*/
private formatDockerComposeError(error: unknown): Error {
// If it's already an Error, return it
if (error instanceof Error) {
return error;
}
// Handle docker-compose result objects
if (this.isDockerComposeResult(error)) {
const parts: string[] = [];
// Add exit code information
if (error.exitCode !== null) {
parts.push(
`Docker Compose command failed with exit code ${error.exitCode}`,
);
} else {
parts.push("Docker Compose command failed");
}
// Add error stream output if available
if (error.err?.trim()) {
parts.push("\nError output:");
parts.push(error.err.trim());
}
// Add standard output if available and different from error output
if (error.out?.trim() && error.out !== error.err) {
parts.push("\nStandard output:");
parts.push(error.out.trim());
}
return new Error(parts.join("\n"));
}
// Handle string errors
if (typeof error === "string") {
return new Error(error);
}
// Fallback for unknown error types
return new Error(JSON.stringify(error));
}
/**
* Type guard to check if an object is a docker-compose result
*/
private isDockerComposeResult(error: unknown): error is IDockerComposeResult {
return (
typeof error === "object" &&
error !== null &&
"exitCode" in error &&
"err" in error &&
"out" in error
);
}
}