From d11f2d1dac6c6280281f79f7f7a0c10ba11717f6 Mon Sep 17 00:00:00 2001 From: Willi Carlsen Date: Mon, 1 Sep 2025 17:05:11 +0200 Subject: [PATCH 1/4] feature: enable loading 1password secrets from file Signed-off-by: Willi Carlsen --- README.md | 2 ++ src/constants.ts | 1 + src/index.ts | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/README.md b/README.md index 51d16e9..f87f8d0 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ jobs: env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} SECRET: op://app-cicd/hello-world/secret + OP_ENV_FILE: "path/to/.env.tpl" - name: Print masked secret run: 'echo "Secret: ${{ steps.load_secrets.outputs.SECRET }}"' @@ -63,6 +64,7 @@ jobs: env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} SECRET: op://app-cicd/hello-world/secret + OP_ENV_FILE: "path/to/.env.tpl" - name: Print masked secret run: 'echo "Secret: $SECRET"' diff --git a/src/constants.ts b/src/constants.ts index 83d7c06..5fead39 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,5 +2,6 @@ export const envConnectHost = "OP_CONNECT_HOST"; export const envConnectToken = "OP_CONNECT_TOKEN"; export const envServiceAccountToken = "OP_SERVICE_ACCOUNT_TOKEN"; export const envManagedVariables = "OP_MANAGED_VARIABLES"; +export const envFilePath = "OP_ENV_FILE"; export const authErr = `Authentication error with environment variables: you must set either 1) ${envServiceAccountToken}, or 2) both ${envConnectHost} and ${envConnectToken}.`; diff --git a/src/index.ts b/src/index.ts index 0bdfaa3..9b32c36 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,9 @@ import * as core from "@actions/core"; import { validateCli } from "@1password/op-js"; import { installCliOnGithubActionRunner } from "op-cli-installer"; import { loadSecrets, unsetPrevious, validateAuth } from "./utils"; +import { + envFilePath, +} from "./constants"; const loadSecretsAction = async () => { try { @@ -20,6 +23,13 @@ const loadSecretsAction = async () => { // Download and install the CLI await installCLI(); + // Set environment variables from OP_ENV_FILE + const file = process.env[envFilePath]; + if (file) { + core.info(`Loading environment variables from file: ${file}`); + process.loadEnvFile(file) + } + // Load secrets await loadSecrets(shouldExportEnv); } catch (error) { From 08a0af8ec3fe7d9a8a15490f3f60d4ac66ebc542 Mon Sep 17 00:00:00 2001 From: Willi Carlsen Date: Wed, 3 Sep 2025 08:45:53 +0200 Subject: [PATCH 2/4] Added OP_ENV_FILE to acceptance test, fixed lint/style error and added example .env.tpl documentation in README Signed-off-by: Willi Carlsen --- .github/workflows/acceptance-test.yml | 6 ++++-- README.md | 4 ++-- src/index.ts | 12 +++++------- tests/.env.tpl | 3 +++ tests/assert-env-set.sh | 17 ++++++++++++----- tests/assert-env-unset.sh | 5 +++++ 6 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 tests/.env.tpl diff --git a/.github/workflows/acceptance-test.yml b/.github/workflows/acceptance-test.yml index b0734d9..f13bac6 100644 --- a/.github/workflows/acceptance-test.yml +++ b/.github/workflows/acceptance-test.yml @@ -36,9 +36,9 @@ jobs: if: | github.event_name != 'repository_dispatch' && ( - github.ref == 'refs/heads/main' || + github.ref == 'refs/heads/main' || ( - github.event_name == 'pull_request' && + github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository ) ) @@ -96,12 +96,14 @@ jobs: SECRET: ${{ inputs.secret }} SECRET_IN_SECTION: ${{ inputs.secret-in-section }} MULTILINE_SECRET: ${{ inputs.multiline-secret }} + OP_ENV_FILE: ./tests/.env.tpl - name: Assert test secret values [step output] if: ${{ !inputs.export-env }} env: SECRET: ${{ steps.load_secrets.outputs.SECRET }} SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }} MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }} + OP_ENV_FILE: ./tests/.env.tpl run: ./tests/assert-env-set.sh - name: Assert test secret values [exported env] if: ${{ inputs.export-env }} diff --git a/README.md b/README.md index f87f8d0..e701481 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ jobs: env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} SECRET: op://app-cicd/hello-world/secret - OP_ENV_FILE: "path/to/.env.tpl" + OP_ENV_FILE: "./path/to/.env.tpl" # see tests/.env.tpl forexample - name: Print masked secret run: 'echo "Secret: ${{ steps.load_secrets.outputs.SECRET }}"' @@ -64,7 +64,7 @@ jobs: env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} SECRET: op://app-cicd/hello-world/secret - OP_ENV_FILE: "path/to/.env.tpl" + OP_ENV_FILE: "./path/to/.env.tpl" # see tests/.env.tpl forexample - name: Print masked secret run: 'echo "Secret: $SECRET"' diff --git a/src/index.ts b/src/index.ts index 9b32c36..c63cf94 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,9 +2,7 @@ import * as core from "@actions/core"; import { validateCli } from "@1password/op-js"; import { installCliOnGithubActionRunner } from "op-cli-installer"; import { loadSecrets, unsetPrevious, validateAuth } from "./utils"; -import { - envFilePath, -} from "./constants"; +import { envFilePath } from "./constants"; const loadSecretsAction = async () => { try { @@ -20,16 +18,16 @@ const loadSecretsAction = async () => { // Validate that a proper authentication configuration is set for the CLI validateAuth(); - // Download and install the CLI - await installCLI(); - // Set environment variables from OP_ENV_FILE const file = process.env[envFilePath]; if (file) { core.info(`Loading environment variables from file: ${file}`); - process.loadEnvFile(file) + process.loadEnvFile(file); } + // Download and install the CLI + await installCLI(); + // Load secrets await loadSecrets(shouldExportEnv); } catch (error) { diff --git a/tests/.env.tpl b/tests/.env.tpl new file mode 100644 index 0000000..15d7272 --- /dev/null +++ b/tests/.env.tpl @@ -0,0 +1,3 @@ +FILE_SECRET=op://acceptance-tests/test-secret/password +FILE_SECRET_IN_SECTION=op://acceptance-tests/test-secret/test-section/password +FILE_MULTILINE_SECRET=op://acceptance-tests/multiline-secret/notesPlain \ No newline at end of file diff --git a/tests/assert-env-set.sh b/tests/assert-env-set.sh index 1871707..7f98855 100755 --- a/tests/assert-env-set.sh +++ b/tests/assert-env-set.sh @@ -9,11 +9,8 @@ assert_env_equals() { fi } -assert_env_equals "SECRET" "RGVhciBzZWN1cml0eSByZXNlYXJjaGVyLCB0aGlzIGlzIGp1c3QgYSBkdW1teSBzZWNyZXQuIFBsZWFzZSBkb24ndCByZXBvcnQgaXQu" - -assert_env_equals "SECRET_IN_SECTION" "RGVhciBzZWN1cml0eSByZXNlYXJjaGVyLCB0aGlzIGlzIGp1c3QgYSBkdW1teSBzZWNyZXQuIFBsZWFzZSBkb24ndCByZXBvcnQgaXQu" - -assert_env_equals "MULTILINE_SECRET" "$(cat << EOF +readonly SECRET="RGVhciBzZWN1cml0eSByZXNlYXJjaGVyLCB0aGlzIGlzIGp1c3QgYSBkdW1teSBzZWNyZXQuIFBsZWFzZSBkb24ndCByZXBvcnQgaXQu" +MULTILINE_SECRET="$(cat << EOF -----BEGIN PRIVATE KEY----- RGVhciBzZWN1cml0eSByZXNlYXJjaGVyLApXaGls ZSB3ZSBkZWVwbHkgYXBwcmVjaWF0ZSB5b3VyIHZp @@ -28,3 +25,13 @@ IApTbyBwbGVhc2UgZG9uJ3QgcmVwb3J0IGl0IQo= -----END PRIVATE KEY----- EOF )" +readonly MULTILINE_SECRET + +assert_env_equals "SECRET" "${SECRET}" +assert_env_equals "FILE_SECRET" "${SECRET}" + +assert_env_equals "SECRET_IN_SECTION" "${SECRET}" +assert_env_equals "FILE_SECRET_IN_SECTION" "${SECRET}" + +assert_env_equals "MULTILINE_SECRET" "${MULTILINE_SECRET}" +assert_env_equals "FILE_MULTILINE_SECRET" "${MULTILINE_SECRET}" \ No newline at end of file diff --git a/tests/assert-env-unset.sh b/tests/assert-env-unset.sh index e4c6448..0565d14 100755 --- a/tests/assert-env-unset.sh +++ b/tests/assert-env-unset.sh @@ -10,5 +10,10 @@ assert_env_unset() { } assert_env_unset "SECRET" +assert_env_unset "FILE_SECRET" + assert_env_unset "SECRET_IN_SECTION" +assert_env_unset "FILE_SECRET_IN_SECTION" + assert_env_unset "MULTILINE_SECRET" +assert_env_unset "FILE_MULTILINE_SECRET" From 1850a6b4876c1ab27e3ed994fd2404e351c41e5a Mon Sep 17 00:00:00 2001 From: Willi Carlsen Date: Wed, 3 Sep 2025 12:45:43 +0200 Subject: [PATCH 3/4] Fixed typo in README Signed-off-by: Willi Carlsen --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e701481..c95ebda 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ jobs: env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} SECRET: op://app-cicd/hello-world/secret - OP_ENV_FILE: "./path/to/.env.tpl" # see tests/.env.tpl forexample + OP_ENV_FILE: "./path/to/.env.tpl" # see tests/.env.tpl for example - name: Print masked secret run: 'echo "Secret: ${{ steps.load_secrets.outputs.SECRET }}"' @@ -64,7 +64,7 @@ jobs: env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} SECRET: op://app-cicd/hello-world/secret - OP_ENV_FILE: "./path/to/.env.tpl" # see tests/.env.tpl forexample + OP_ENV_FILE: "./path/to/.env.tpl" # see tests/.env.tpl for example - name: Print masked secret run: 'echo "Secret: $SECRET"' From 0ff92dd768ca934e09a8b0b66c9c8718f54f37b2 Mon Sep 17 00:00:00 2001 From: Willi Carlsen Date: Sat, 6 Sep 2025 07:37:10 +0200 Subject: [PATCH 4/4] Using dotenv package instead of experimental API process.loadEnvFile Signed-off-by: Willi Carlsen --- package-lock.json | 13 +++++++++++++ package.json | 1 + src/index.ts | 3 ++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 6a1bd95..dabce4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@1password/op-js": "^0.1.11", "@actions/core": "^1.10.1", "@actions/exec": "^1.1.1", + "dotenv": "^17.2.2", "op-cli-installer": "github:1Password/op-cli-installer#e6c1c758bc3339e5fe9b06255728039f688f73fa" }, "devDependencies": { @@ -2766,6 +2767,18 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index f23ff70..74d973d 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@1password/op-js": "^0.1.11", "@actions/core": "^1.10.1", "@actions/exec": "^1.1.1", + "dotenv": "^17.2.2", "op-cli-installer": "github:1Password/op-cli-installer#e6c1c758bc3339e5fe9b06255728039f688f73fa" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index c63cf94..6469bcd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import * as core from "@actions/core"; import { validateCli } from "@1password/op-js"; import { installCliOnGithubActionRunner } from "op-cli-installer"; +import dotenv from "dotenv"; import { loadSecrets, unsetPrevious, validateAuth } from "./utils"; import { envFilePath } from "./constants"; @@ -22,7 +23,7 @@ const loadSecretsAction = async () => { const file = process.env[envFilePath]; if (file) { core.info(`Loading environment variables from file: ${file}`); - process.loadEnvFile(file); + dotenv.config({ path: file }); } // Download and install the CLI