diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..5413f97 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,14 @@ + +name: Check + +on: [push, pull_request] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.x + - run: ./src/check.ts diff --git a/.gitignore b/.gitignore index 3a81145..efdf306 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ services/webhook-handler !/.gitignore !/README.md !/SETUP.md + +!.github diff --git a/src/check.ts b/src/check.ts new file mode 100755 index 0000000..70c0f70 --- /dev/null +++ b/src/check.ts @@ -0,0 +1,58 @@ +#!/usr/bin/env -S COLI_CONC_BASE=. deno run --allow-env --allow-read --allow-sys --ext=ts + +/** + * Checks docker-compose.yml files for issues: + * + * - Duplicate service names + * + * Ideas for other issues to check: + * + * - restart directive + * - Docker networks + * - volume paths + */ + +Deno.env.set("FORCE_COLOR", "2") +import { existsSync } from "https://deno.land/std/fs/mod.ts" + +// Determine available targets by reading docker-compose.yml files in service subfolders +import { parse as parseYaml } from "https://deno.land/std@0.207.0/yaml/mod.ts" +import { getEnv } from "../src/utils.ts" +const { servicePath } = getEnv("") + +const serviceNamesToComposeFiles = {} +let ok = true + +for await (const { name, isDirectory } of Deno.readDir(servicePath)) { + if (!isDirectory) { + continue + } + try { + // Try to read docker-compose.yml + const file = `${servicePath}/${name}/docker-compose.yml` + const fileShort = file.replace(servicePath, "") + const compose = parseYaml(await Deno.readTextFile(file)) + const errors: String[] = [] + for (const service of Object.keys(compose?.services || {})) { + if (serviceNamesToComposeFiles[service]) { + errors.push(`!!! Service "${service}" is already defined in ${serviceNamesToComposeFiles[service]}`) + ok = false + } else { + serviceNamesToComposeFiles[service] = fileShort + } + } + if (errors.length) { + console.error(`%c${fileShort}`, "color: red") + errors.forEach(error => console.error(`%c ${error}`, "color: red")) + } else { + console.log(`%c${fileShort}`, "color: green") + console.log("%c All good.", "color: green") + } + } catch (_) { + // Just ignore errors as we are expecting them + } +} + +if (!ok) { + Deno.exit(1) +}