mirror of
https://github.com/hoverkraft-tech/compose-action.git
synced 2026-07-03 12:12:50 +08:00
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
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>
154 lines
3.5 KiB
TypeScript
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
|
|
);
|
|
}
|
|
}
|