diff --git a/README.md b/README.md index 16dcac0..2669829 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,22 @@ Export GitHub Actions secrets as environment variables. ## Usage -```yml +Set the JSON of secrets to `secrets`. + +```yaml +steps: + - uses: koyashiro/export-secrets-action@v0.1.0 + with: + secrets: ${{ toJSON(secrets) }} +``` + +If you want to downcase secrets starting with `TF_VAR_`, you can use the `downcase-tf-var` option. +For example, a secret like `TF_VAR_EXAMPLE` will be exported as `TF_VAR_example`. + +```yaml steps: - uses: koyashiro/export-secrets-action@v0.1.0 with: secrets: ${{ toJSON(secrets) }} + downcase-tf-var: true ``` diff --git a/action.yml b/action.yml index a9d69be..c29164d 100644 --- a/action.yml +++ b/action.yml @@ -5,6 +5,9 @@ inputs: secrets: description: JSON representation of secrets required: true + downcase-tf-var: + description: Set this option if you want to downcase the secrets starting with `TF_VAR_` + required: false runs: using: node20 main: dist/index.js diff --git a/dist/index.js b/dist/index.js index 01bc7f1..30c15b3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -30847,11 +30847,15 @@ var z = /*#__PURE__*/Object.freeze({ const secretsSchema = z.record(z.string(), z.string()); function exportSecrets(core) { const secretsJson = core.getInput("secrets"); + const downcaseTfVar = core.getInput("downcase-tf-var") === "true"; if (!secretsJson) { throw new Error("secrets is required"); } const secrets = secretsSchema.parse(JSON.parse(secretsJson)); for (const [key, value] of Object.entries(secrets)) { + if (downcaseTfVar && key.startsWith("TF_VAR_")) { + core.exportVariable(`TF_VAR_${key.replace(/^TF_VAR_/, "").toLowerCase()}`, value); + } core.exportVariable(key, value); } } diff --git a/src/lib.test.ts b/src/lib.test.ts index f5b813c..4291acf 100644 --- a/src/lib.test.ts +++ b/src/lib.test.ts @@ -5,11 +5,16 @@ import { exportSecrets } from "./lib"; describe("exportSecrets()", () => { describe("success", () => { const coreMock = { - getInput: vi - .fn() - .mockReturnValue( - '{"KEY_A":"VALUE_A","KEY_B":"VALUE_B","KEY_C":"VALUE_C"}', - ), + getInput: vi.fn().mockImplementation((s: string) => { + switch (s) { + case "secrets": + return '{"KEY_A":"VALUE_A","KEY_B":"VALUE_B","KEY_C":"VALUE_C","TF_VAR_KEY_D":"VALUE_D"}'; + case "downcase-tf-var": + return ""; + default: + return ""; + } + }), exportVariable: vi.fn(), }; @@ -23,7 +28,64 @@ describe("exportSecrets()", () => { expect(coreMock.getInput).toHaveBeenCalledWith("secrets"); }); - it("calls exportVariable() 3 times", () => { + it('calls getInput() with "downcase-tf-var"', () => { + expect(coreMock.getInput).toHaveBeenCalledWith("downcase-tf-var"); + }); + + it("calls exportVariable() 4 times", () => { + expect(coreMock.exportVariable).toHaveBeenNthCalledWith( + 1, + "KEY_A", + "VALUE_A", + ); + expect(coreMock.exportVariable).toHaveBeenNthCalledWith( + 2, + "KEY_B", + "VALUE_B", + ); + expect(coreMock.exportVariable).toHaveBeenNthCalledWith( + 3, + "KEY_C", + "VALUE_C", + ); + expect(coreMock.exportVariable).toHaveBeenNthCalledWith( + 4, + "TF_VAR_KEY_D", + "VALUE_D", + ); + }); + }); + + describe("success_downcase-tf-var", () => { + const coreMock = { + getInput: vi.fn().mockImplementation((s: string) => { + switch (s) { + case "secrets": + return '{"KEY_A":"VALUE_A","KEY_B":"VALUE_B","KEY_C":"VALUE_C","TF_VAR_KEY_D":"VALUE_D"}'; + case "downcase-tf-var": + return "true"; + default: + return ""; + } + }), + exportVariable: vi.fn(), + }; + + it("does not throws an error", () => { + expect(() => { + exportSecrets(coreMock as unknown as typeof core); + }).not.toThrow(); + }); + + it('calls getInput() with "secrets"', () => { + expect(coreMock.getInput).toHaveBeenCalledWith("secrets"); + }); + + it('calls getInput() with "downcase-tf-var"', () => { + expect(coreMock.getInput).toHaveBeenCalledWith("downcase-tf-var"); + }); + + it("calls exportVariable() 4 times", () => { expect(coreMock.exportVariable).toHaveBeenNthCalledWith( 1, "KEY_A", @@ -39,12 +101,26 @@ describe("exportSecrets()", () => { "KEY_C", "VALUE_C", ); + expect(coreMock.exportVariable).toHaveBeenNthCalledWith( + 4, + "TF_VAR_key_d", + "VALUE_D", + ); }); }); describe("secrets is empty", () => { const coreMock = { - getInput: vi.fn().mockReturnValue(""), + getInput: vi.fn().mockImplementation((s: string) => { + switch (s) { + case "secrets": + return "{"; + case "downcase-tf-var": + return ""; + default: + return ""; + } + }), exportVariable: vi.fn(), }; @@ -58,6 +134,10 @@ describe("exportSecrets()", () => { expect(coreMock.getInput).toHaveBeenCalledWith("secrets"); }); + it('calls getInput() with "downcase-tf-var"', () => { + expect(coreMock.getInput).toHaveBeenCalledWith("downcase-tf-var"); + }); + it("does not calls exportVariable()", () => { expect(coreMock.exportVariable).not.toHaveBeenCalled(); }); @@ -65,7 +145,16 @@ describe("exportSecrets()", () => { describe("secret is invalid JSON", () => { const coreMock = { - getInput: vi.fn().mockReturnValue("{"), + getInput: vi.fn().mockImplementation((s: string) => { + switch (s) { + case "secrets": + return "{"; + case "downcase-tf-var": + return ""; + default: + return ""; + } + }), exportVariable: vi.fn(), }; @@ -79,6 +168,10 @@ describe("exportSecrets()", () => { expect(coreMock.getInput).toHaveBeenCalledWith("secrets"); }); + it('calls getInput() with "downcase-tf-var"', () => { + expect(coreMock.getInput).toHaveBeenCalledWith("downcase-tf-var"); + }); + it("does not calls exportVariable()", () => { expect(coreMock.exportVariable).not.toHaveBeenCalled(); }); diff --git a/src/lib.ts b/src/lib.ts index 8eb4997..719d934 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -7,6 +7,7 @@ const secretsSchema = z.record(z.string(), z.string()); export function exportSecrets(core: ActionsCore) { const secretsJson = core.getInput("secrets"); + const downcaseTfVar = core.getInput("downcase-tf-var") === "true"; if (!secretsJson) { throw new Error("secrets is required"); @@ -15,6 +16,12 @@ export function exportSecrets(core: ActionsCore) { const secrets = secretsSchema.parse(JSON.parse(secretsJson)); for (const [key, value] of Object.entries(secrets)) { + if (downcaseTfVar && key.startsWith("TF_VAR_")) { + core.exportVariable( + `TF_VAR_${key.replace(/^TF_VAR_/, "").toLowerCase()}`, + value, + ); + } core.exportVariable(key, value); } }