From 2985889b56fbe0f85ab6a52d529fe5a83ce8ef1b Mon Sep 17 00:00:00 2001 From: ANGkeith Date: Thu, 3 Oct 2024 23:34:36 +0800 Subject: [PATCH] feat: add support for .env format for variables-file --- src/variables-from-files.ts | 17 +++++- tests/test-cases/project-variables-file/.env | 1 + tests/test-cases/project-variables-file/.envs | 23 ++++++++ .../.gitlab-ci-custom.yml | 5 ++ ...integration.project-variables-file.test.ts | 52 +++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/test-cases/project-variables-file/.env create mode 100644 tests/test-cases/project-variables-file/.envs diff --git a/src/variables-from-files.ts b/src/variables-from-files.ts index 418570c3..368760c4 100644 --- a/src/variables-from-files.ts +++ b/src/variables-from-files.ts @@ -6,6 +6,7 @@ import chalk from "chalk"; import {Argv} from "./argv"; import assert from "assert"; import {Utils} from "./utils"; +import dotenv from "dotenv"; export interface CICDVariable { type: "file" | "variable"; @@ -114,8 +115,22 @@ export class VariablesFromFiles { const projectVariablesFile = `${argv.cwd}/${argv.variablesFile}`; if (fs.existsSync(projectVariablesFile)) { - const projectVariablesFileData: any = yaml.load(await fs.readFile(projectVariablesFile, "utf8"), {schema: yaml.FAILSAFE_SCHEMA}) ?? {}; + + const projectVariablesFileRawContent = await fs.readFile(projectVariablesFile, "utf8"); + let projectVariablesFileData; + try { + projectVariablesFileData = yaml.load(projectVariablesFileRawContent, {schema: yaml.FAILSAFE_SCHEMA}) ?? {}; + + if (typeof(projectVariablesFileData) === "string") { + projectVariablesFileData = dotenv.parse(projectVariablesFileRawContent); + } + } catch (e) { + if (e instanceof yaml.YAMLException) { + projectVariablesFileData = dotenv.parse(projectVariablesFileRawContent); + } + } assert(projectVariablesFileData != null, "projectEntries cannot be null/undefined"); + assert(Utils.isObject(projectVariablesFileData), `${argv.cwd}/.gitlab-ci-local-variables.yml must contain an object`); for (const [k, v] of Object.entries(projectVariablesFileData)) { await addToVariables(k, v, 24); diff --git a/tests/test-cases/project-variables-file/.env b/tests/test-cases/project-variables-file/.env new file mode 100644 index 00000000..6879496e --- /dev/null +++ b/tests/test-cases/project-variables-file/.env @@ -0,0 +1 @@ +SECRET="holycow" diff --git a/tests/test-cases/project-variables-file/.envs b/tests/test-cases/project-variables-file/.envs new file mode 100644 index 00000000..692e7894 --- /dev/null +++ b/tests/test-cases/project-variables-file/.envs @@ -0,0 +1,23 @@ +SECRET_APP_DEBUG=true +SECRET_APP_ENV=local +SECRET_APP_KEY= +SECRET_APP_NAME="Laravel" +SECRET_APP_URL=http://localhost +SECRET_BROADCAST_DRIVER=log +SECRET_CACHE_DRIVER=file +SECRET_DB_CONNECTION=mysql +SECRET_DB_DATABASE=laravel +SECRET_DB_HOST=127.0.0.1 +SECRET_DB_PASSWORD= +SECRET_DB_PORT=3306 +# comment and newlines are allowed + +SECRET_DB_USERNAME=root +SECRET_FILESYSTEM_DISK=local +SECRET_LOG_CHANNEL=stack +SECRET_LOG_DEPRECATIONS_CHANNEL=null +SECRET_LOG_LEVEL=debug +SECRET_MEMCACHED_HOST=127.0.0.1 +SECRET_QUEUE_CONNECTION=sync +SECRET_SESSION_DRIVER=file +SECRET_SESSION_LIFETIME=120 diff --git a/tests/test-cases/project-variables-file/.gitlab-ci-custom.yml b/tests/test-cases/project-variables-file/.gitlab-ci-custom.yml index be2cad7c..0d417f31 100644 --- a/tests/test-cases/project-variables-file/.gitlab-ci-custom.yml +++ b/tests/test-cases/project-variables-file/.gitlab-ci-custom.yml @@ -3,3 +3,8 @@ job: image: busybox script: - echo $SECRET + +job2: + image: busybox + script: + - env | grep SECRET diff --git a/tests/test-cases/project-variables-file/integration.project-variables-file.test.ts b/tests/test-cases/project-variables-file/integration.project-variables-file.test.ts index 05030347..28f5b0ff 100644 --- a/tests/test-cases/project-variables-file/integration.project-variables-file.test.ts +++ b/tests/test-cases/project-variables-file/integration.project-variables-file.test.ts @@ -41,6 +41,7 @@ test.concurrent("project-variables-file custom-path", async () => { cwd: "tests/test-cases/project-variables-file", file: ".gitlab-ci-custom.yml", variablesFile: ".custom-local-var-file", + job: ["job"], }, writeStreams); const expected = [ @@ -48,3 +49,54 @@ test.concurrent("project-variables-file custom-path", async () => { ]; expect(writeStreams.stdoutLines).toEqual(expect.arrayContaining(expected)); }); + +test.concurrent("project-variables-file custom-path (.env)", async () => { + const writeStreams = new WriteStreamsMock(); + await handler({ + cwd: "tests/test-cases/project-variables-file", + file: ".gitlab-ci-custom.yml", + variablesFile: ".env", + job: ["job"], + }, writeStreams); + + const expected = [ + chalk`{blueBright job} {greenBright >} holycow`, + ]; + expect(writeStreams.stdoutLines).toEqual(expect.arrayContaining(expected)); +}); + +test.concurrent("project-variables-file custom-path (.envs)", async () => { + const writeStreams = new WriteStreamsMock(); + await handler({ + cwd: "tests/test-cases/project-variables-file", + file: ".gitlab-ci-custom.yml", + job: ["job2"], + variablesFile: ".envs", + }, writeStreams); + + const expected = [ + chalk`{blueBright job2} {greenBright >} SECRET_APP_DEBUG=true`, + chalk`{blueBright job2} {greenBright >} SECRET_APP_ENV=local`, + chalk`{blueBright job2} {greenBright >} SECRET_APP_KEY=`, + chalk`{blueBright job2} {greenBright >} SECRET_APP_NAME=Laravel`, + chalk`{blueBright job2} {greenBright >} SECRET_APP_URL=http://localhost`, + chalk`{blueBright job2} {greenBright >} SECRET_BROADCAST_DRIVER=log`, + chalk`{blueBright job2} {greenBright >} SECRET_CACHE_DRIVER=file`, + chalk`{blueBright job2} {greenBright >} SECRET_DB_CONNECTION=mysql`, + chalk`{blueBright job2} {greenBright >} SECRET_DB_DATABASE=laravel`, + chalk`{blueBright job2} {greenBright >} SECRET_DB_HOST=127.0.0.1`, + chalk`{blueBright job2} {greenBright >} SECRET_DB_PASSWORD=`, + chalk`{blueBright job2} {greenBright >} SECRET_DB_PORT=3306`, + chalk`{blueBright job2} {greenBright >} SECRET_DB_USERNAME=root`, + chalk`{blueBright job2} {greenBright >} SECRET_FILESYSTEM_DISK=local`, + chalk`{blueBright job2} {greenBright >} SECRET_LOG_CHANNEL=stack`, + chalk`{blueBright job2} {greenBright >} SECRET_LOG_DEPRECATIONS_CHANNEL=null`, + chalk`{blueBright job2} {greenBright >} SECRET_LOG_LEVEL=debug`, + chalk`{blueBright job2} {greenBright >} SECRET_MEMCACHED_HOST=127.0.0.1`, + chalk`{blueBright job2} {greenBright >} SECRET_QUEUE_CONNECTION=sync`, + chalk`{blueBright job2} {greenBright >} SECRET_SESSION_DRIVER=file`, + chalk`{blueBright job2} {greenBright >} SECRET_SESSION_LIFETIME=120`, + ]; + + expect(writeStreams.stdoutLines).toEqual(expect.arrayContaining(expected)); +});