mirror of
https://github.com/1Password/load-secrets-action.git
synced 2026-06-21 14:23:48 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f4e59e3d45 | |||
| 3048b822db |
@@ -0,0 +1,118 @@
|
||||
name: Acceptance test
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
secret:
|
||||
required: true
|
||||
type: string
|
||||
secret-in-section:
|
||||
required: true
|
||||
type: string
|
||||
multiline-secret:
|
||||
required: true
|
||||
type: string
|
||||
export-env:
|
||||
required: true
|
||||
type: boolean
|
||||
version:
|
||||
required: false
|
||||
type: string
|
||||
default: "latest"
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
default: "ubuntu-latest"
|
||||
auth:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
acceptance-test:
|
||||
runs-on: ${{ inputs.os }}
|
||||
steps:
|
||||
- name: Base checkout
|
||||
uses: actions/checkout@v4
|
||||
if: |
|
||||
github.event_name != 'repository_dispatch' &&
|
||||
(
|
||||
github.ref == 'refs/heads/main' ||
|
||||
(
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
)
|
||||
)
|
||||
- name: Fork based /ok-to-test checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.client_payload.pull_request.head.sha }}
|
||||
if: |
|
||||
github.event_name == 'repository_dispatch' &&
|
||||
github.event.client_payload.slash_command.args.named.sha != '' &&
|
||||
contains(
|
||||
github.event.client_payload.pull_request.head.sha,
|
||||
github.event.client_payload.slash_command.args.named.sha
|
||||
)
|
||||
- name: Launch 1Password Connect instance
|
||||
if: ${{ inputs.auth == 'connect' }}
|
||||
env:
|
||||
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
|
||||
run: |
|
||||
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
|
||||
docker compose -f tests/fixtures/docker-compose.yml up -d && sleep 10
|
||||
- name: Configure Service account
|
||||
if: ${{ inputs.auth == 'service-account' }}
|
||||
uses: ./configure
|
||||
with:
|
||||
service-account-token: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||
- name: Verify Service Account env var is set
|
||||
if: ${{ inputs.auth == 'service-account' }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -z "${OP_SERVICE_ACCOUNT_TOKEN}" ]; then
|
||||
echo "OP_SERVICE_ACCOUNT_TOKEN environment variable is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
- name: Configure 1Password Connect
|
||||
if: ${{ inputs.auth == 'connect' }}
|
||||
uses: ./configure # 1password/load-secrets-action/configure@<version>
|
||||
with:
|
||||
connect-host: http://localhost:8080
|
||||
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||
- name: Verify Connect env vars are set
|
||||
if: ${{ inputs.auth == 'connect' }}
|
||||
run: |
|
||||
if [ -z "$OP_CONNECT_HOST" ] || [ -z "$OP_CONNECT_TOKEN" ]; then
|
||||
echo "OP_CONNECT_HOST or OP_CONNECT_TOKEN environment variables are not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
- name: Load secrets
|
||||
id: load_secrets
|
||||
uses: ./ # 1password/load-secrets-action@<version>
|
||||
with:
|
||||
version: ${{ inputs.version }}
|
||||
export-env: ${{ inputs.export-env }}
|
||||
env:
|
||||
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 }}
|
||||
run: ./tests/assert-env-set.sh
|
||||
- name: Remove secrets [exported env]
|
||||
if: ${{ inputs.export-env }}
|
||||
uses: ./ # 1password/load-secrets-action@<version>
|
||||
with:
|
||||
unset-previous: true
|
||||
- name: Assert removed secrets [exported env]
|
||||
if: ${{ inputs.export-env }}
|
||||
run: ./tests/assert-env-unset.sh
|
||||
+10
-176
@@ -8,11 +8,6 @@ on:
|
||||
|
||||
# For test.yml to call this workflow
|
||||
workflow_call:
|
||||
inputs:
|
||||
ref:
|
||||
description: "Git ref to checkout"
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
OP_CONNECT_CREDENTIALS:
|
||||
required: true
|
||||
@@ -20,12 +15,6 @@ on:
|
||||
required: true
|
||||
OP_SERVICE_ACCOUNT_TOKEN:
|
||||
required: true
|
||||
OP_WORKLOAD_ID:
|
||||
required: true
|
||||
OP_ENVIRONMENT_ID:
|
||||
required: true
|
||||
OP_INTEGRATION_KEY:
|
||||
required: true
|
||||
VAULT:
|
||||
description: "1Password vault name or UUID"
|
||||
required: true
|
||||
@@ -36,42 +25,23 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
max-parallel: 4
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
version: [latest, 2.30.0]
|
||||
export-env: [true, false]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ inputs.ref }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build actions
|
||||
run: npm run build:all
|
||||
|
||||
- name: Generate .env.tpl
|
||||
shell: bash
|
||||
run: |
|
||||
echo "FILE_SECRET=op://${VAULT}/test-secret/password" > tests/.env.tpl
|
||||
echo "FILE_SECRET_IN_SECTION=op://${VAULT}/test-secret/test-section/password" >> tests/.env.tpl
|
||||
echo "FILE_MULTILINE_SECRET=op://${VAULT}/multiline-secret/notesPlain" >> tests/.env.tpl
|
||||
echo "FILE_WEBSITE=op://${VAULT}/test-secret/website" >> tests/.env.tpl
|
||||
echo "FILE_TEST_SSH_KEY=op://${VAULT}/test-ssh-key/private key" >> tests/.env.tpl
|
||||
echo "FILE_TEST_SSH_KEY_OPENSSH=op://${VAULT}/test-ssh-key/private key?ssh-format=openssh" >> tests/.env.tpl
|
||||
echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
|
||||
echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
|
||||
echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
|
||||
|
||||
env:
|
||||
VAULT: ${{ secrets.VAULT }}
|
||||
- name: Configure Service account
|
||||
uses: ./configure
|
||||
with:
|
||||
@@ -87,52 +57,25 @@ jobs:
|
||||
SECRET: op://${{ secrets.VAULT }}/test-secret/password
|
||||
SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
|
||||
MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
|
||||
WEBSITE: op://${{ secrets.VAULT }}/test-secret/website
|
||||
TEST_SSH_KEY: op://${{ secrets.VAULT }}/test-ssh-key/private key
|
||||
TEST_SSH_KEY_OPENSSH: "op://${{ secrets.VAULT }}/test-ssh-key/private key?ssh-format=openssh"
|
||||
OP_ENV_FILE: ./tests/.env.tpl
|
||||
|
||||
- name: Assert test secret values [step output]
|
||||
if: ${{ !matrix.export-env }}
|
||||
shell: bash
|
||||
env:
|
||||
ASSERT_WEBSITE: "true"
|
||||
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
||||
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
||||
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
||||
FILE_SECRET: ${{ steps.load_secrets.outputs.FILE_SECRET }}
|
||||
FILE_SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.FILE_SECRET_IN_SECTION }}
|
||||
FILE_MULTILINE_SECRET: ${{ steps.load_secrets.outputs.FILE_MULTILINE_SECRET }}
|
||||
WEBSITE: ${{ steps.load_secrets.outputs.WEBSITE }}
|
||||
FILE_WEBSITE: ${{ steps.load_secrets.outputs.FILE_WEBSITE }}
|
||||
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||
run: ./tests/assert-env-set.sh
|
||||
|
||||
- name: Assert SSH key env vars [step output]
|
||||
if: ${{ !matrix.export-env }}
|
||||
shell: bash
|
||||
env:
|
||||
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||
run: ./tests/assert-ssh-keys-set.sh
|
||||
|
||||
- name: Assert test secret values [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
shell: bash
|
||||
env:
|
||||
ASSERT_WEBSITE: "true"
|
||||
run: ./tests/assert-env-set.sh
|
||||
|
||||
- name: Assert SSH key env vars [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
shell: bash
|
||||
run: ./tests/assert-ssh-keys-set.sh
|
||||
|
||||
- name: Remove secrets [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
uses: ./
|
||||
@@ -150,45 +93,28 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
version: [latest, 2.30.0]
|
||||
export-env: [true, false]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ inputs.ref }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build actions
|
||||
run: npm run build:all
|
||||
|
||||
- name: Generate .env.tpl
|
||||
run: |
|
||||
mkdir -p tests
|
||||
echo "FILE_SECRET=op://${VAULT}/test-secret/password" > tests/.env.tpl
|
||||
echo "FILE_SECRET_IN_SECTION=op://${VAULT}/test-secret/test-section/password" >> tests/.env.tpl
|
||||
echo "FILE_MULTILINE_SECRET=op://${VAULT}/multiline-secret/notesPlain" >> tests/.env.tpl
|
||||
echo "FILE_TEST_SSH_KEY=op://${VAULT}/test-ssh-key/private key" >> tests/.env.tpl
|
||||
echo "FILE_TEST_SSH_KEY_OPENSSH=op://${VAULT}/test-ssh-key/private key?ssh-format=openssh" >> tests/.env.tpl
|
||||
echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
|
||||
echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
|
||||
echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
|
||||
|
||||
env:
|
||||
VAULT: ${{ secrets.VAULT }}
|
||||
- name: Launch 1Password Connect instance
|
||||
env:
|
||||
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
|
||||
run: |
|
||||
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
|
||||
docker compose -f tests/fixtures/docker-compose.yml up -d
|
||||
timeout 60 bash -c 'until curl -sf http://localhost:8080/health >/dev/null 2>&1; do sleep 2; done'
|
||||
docker compose -f tests/fixtures/docker-compose.yml up -d && sleep 10
|
||||
|
||||
- name: Configure 1Password Connect
|
||||
uses: ./configure
|
||||
@@ -206,45 +132,23 @@ jobs:
|
||||
SECRET: op://${{ secrets.VAULT }}/test-secret/password
|
||||
SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
|
||||
MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
|
||||
TEST_SSH_KEY: op://${{ secrets.VAULT }}/test-ssh-key/private key
|
||||
TEST_SSH_KEY_OPENSSH: "op://${{ secrets.VAULT }}/test-ssh-key/private key?ssh-format=openssh"
|
||||
OP_ENV_FILE: ./tests/.env.tpl
|
||||
|
||||
- name: Assert test secret values [step output]
|
||||
if: ${{ !matrix.export-env }}
|
||||
env:
|
||||
ASSERT_WEBSITE: "false"
|
||||
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
||||
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
||||
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
||||
FILE_SECRET: ${{ steps.load_secrets.outputs.FILE_SECRET }}
|
||||
FILE_SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.FILE_SECRET_IN_SECTION }}
|
||||
FILE_MULTILINE_SECRET: ${{ steps.load_secrets.outputs.FILE_MULTILINE_SECRET }}
|
||||
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||
run: ./tests/assert-env-set.sh
|
||||
|
||||
- name: Assert SSH key env vars [step output]
|
||||
if: ${{ !matrix.export-env }}
|
||||
env:
|
||||
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||
run: ./tests/assert-ssh-keys-set.sh
|
||||
|
||||
- name: Assert test secret values [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
env:
|
||||
ASSERT_WEBSITE: "false"
|
||||
run: ./tests/assert-env-set.sh
|
||||
|
||||
- name: Assert SSH key env vars [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
run: ./tests/assert-ssh-keys-set.sh
|
||||
|
||||
- name: Remove secrets [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
uses: ./
|
||||
@@ -254,73 +158,3 @@ jobs:
|
||||
- name: Assert removed secrets [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
run: ./tests/assert-env-unset.sh
|
||||
|
||||
test-workload-identity:
|
||||
name: Workload Identity (ubuntu-latest, export-env=${{ matrix.export-env }})
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
export-env: [true, false]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ inputs.ref }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build actions
|
||||
run: npm run build:all
|
||||
|
||||
- name: Load secrets
|
||||
id: load_secrets
|
||||
uses: ./
|
||||
with:
|
||||
export-env: ${{ matrix.export-env }}
|
||||
env:
|
||||
OP_WORKLOAD_ID: ${{ secrets.OP_WORKLOAD_ID }}
|
||||
OP_ENVIRONMENT_ID: ${{ secrets.OP_ENVIRONMENT_ID }}
|
||||
OP_INTEGRATION_KEY: ${{ secrets.OP_INTEGRATION_KEY }}
|
||||
|
||||
- name: Assert test secret values [step output]
|
||||
if: ${{ !matrix.export-env }}
|
||||
shell: bash
|
||||
env:
|
||||
ANOTHER_TEST: ${{ steps.load_secrets.outputs.ANOTHER_TEST }}
|
||||
SUPER_SECRET: ${{ steps.load_secrets.outputs.SUPER_SECRET }}
|
||||
TEST_SECRET: ${{ steps.load_secrets.outputs.TEST_SECRET }}
|
||||
run: ./tests/assert-workload-identity.sh
|
||||
|
||||
- name: Assert test secret values [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
shell: bash
|
||||
run: ./tests/assert-workload-identity.sh
|
||||
|
||||
- name: Remove secrets [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
uses: ./
|
||||
with:
|
||||
unset-previous: true
|
||||
|
||||
- name: Assert removed secrets [exported env]
|
||||
if: ${{ matrix.export-env }}
|
||||
shell: bash
|
||||
run: |
|
||||
for var in ANOTHER_TEST SUPER_SECRET TEST_SECRET; do
|
||||
if [ -n "$(printenv "$var")" ]; then
|
||||
echo "Expected secret $var to be unset"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -9,18 +9,18 @@ jobs:
|
||||
lint-and-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0
|
||||
uses: ludeeus/action-shellcheck@2.0.0
|
||||
with:
|
||||
ignore_paths: >-
|
||||
.husky
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
node-version: 20
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
name: Lint
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@2.0.0
|
||||
with:
|
||||
ignore_paths: >-
|
||||
.husky
|
||||
- name: Setup Node.js
|
||||
id: setup-node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
- name: Install Dependencies
|
||||
id: install
|
||||
run: npm ci
|
||||
- name: Check formatting
|
||||
run: npm run format:check
|
||||
- name: Check lint
|
||||
run: npm run lint
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
steps:
|
||||
- name: Slash Command Dispatch
|
||||
uses: peter-evans/slash-command-dispatch@9bdcd7914ec1b75590b790b844aa3b8eee7c683a # v5
|
||||
uses: peter-evans/slash-command-dispatch@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
reaction-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -10,4 +10,4 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check signed commits in PR
|
||||
uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1
|
||||
uses: 1Password/check-signed-commits-action@v1
|
||||
|
||||
@@ -26,7 +26,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
condition: ${{ steps.check.outputs.condition }}
|
||||
ref: ${{ steps.check.outputs.ref }}
|
||||
steps:
|
||||
- name: Check if PR is from external contributor
|
||||
id: check
|
||||
@@ -46,7 +45,6 @@ jobs:
|
||||
else
|
||||
echo "condition=pr-creation-maintainer" >> $GITHUB_OUTPUT
|
||||
echo "Setting condition=pr-creation-maintainer (internal PR creation)"
|
||||
echo "ref=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
elif [ "${{ github.event_name }}" == "repository_dispatch" ]; then
|
||||
# For repository_dispatch events (ok-to-test), check if sha matches
|
||||
@@ -60,23 +58,19 @@ jobs:
|
||||
if [ -n "$SHA_PARAM" ] && [[ "$PR_HEAD_SHA" == *"$SHA_PARAM"* ]]; then
|
||||
echo "condition=dispatch-event" >> $GITHUB_OUTPUT
|
||||
echo "Setting condition=dispatch-event (sha matches)"
|
||||
echo "ref=$PR_HEAD_SHA" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "condition=skip" >> $GITHUB_OUTPUT
|
||||
echo "Setting condition=skip (sha does not match or empty)"
|
||||
fi
|
||||
elif [ "${{ github.event_name }}" == "push" ] && [ "${REF_NAME}" == "main" ]; then
|
||||
elif [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref_name }}" == "main" ]; then
|
||||
echo "condition=push-to-main" >> $GITHUB_OUTPUT
|
||||
echo "Setting condition=push-to-main (push to main)"
|
||||
echo "ref=${{ github.sha }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
# Unknown event type
|
||||
echo "condition=skip" >> $GITHUB_OUTPUT
|
||||
echo "Setting condition=skip (unknown event type: ${{ github.event_name }})"
|
||||
fi
|
||||
|
||||
env:
|
||||
REF_NAME: ${{ github.ref_name }}
|
||||
e2e:
|
||||
needs: check-external-pr
|
||||
if: |
|
||||
@@ -86,15 +80,10 @@ jobs:
|
||||
||
|
||||
needs.check-external-pr.outputs.condition == 'push-to-main'
|
||||
uses: ./.github/workflows/e2e-tests.yml
|
||||
with:
|
||||
ref: ${{ needs.check-external-pr.outputs.ref }}
|
||||
secrets:
|
||||
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
|
||||
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||
OP_WORKLOAD_ID: ${{ secrets.OP_WORKLOAD_ID }}
|
||||
OP_ENVIRONMENT_ID: ${{ secrets.OP_ENVIRONMENT_ID }}
|
||||
OP_INTEGRATION_KEY: ${{ secrets.OP_INTEGRATION_KEY }}
|
||||
VAULT: ${{ secrets.VAULT }}
|
||||
|
||||
# Post comment on fork PRs after /ok-to-test
|
||||
@@ -110,7 +99,7 @@ jobs:
|
||||
run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create comment on PR
|
||||
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5
|
||||
uses: peter-evans/create-or-update-comment@v5
|
||||
with:
|
||||
issue-number: ${{ github.event.client_payload.pull_request.number }}
|
||||
body: |
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [ok-to-test-command]
|
||||
name: Run acceptance tests [fork]
|
||||
|
||||
jobs:
|
||||
test-with-output-secrets:
|
||||
if: |
|
||||
github.event_name == 'repository_dispatch' &&
|
||||
github.event.client_payload.slash_command.args.named.sha != '' &&
|
||||
contains(
|
||||
github.event.client_payload.pull_request.head.sha,
|
||||
github.event.client_payload.slash_command.args.named.sha
|
||||
)
|
||||
uses: 1password/load-secrets-action/.github/workflows/acceptance-test.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
secret: op://acceptance-tests/test-secret/password
|
||||
secret-in-section: op://acceptance-tests/test-secret/test-section/password
|
||||
multiline-secret: op://acceptance-tests/multiline-secret/notesPlain
|
||||
export-env: false
|
||||
test-with-export-env:
|
||||
if: |
|
||||
github.event_name == 'repository_dispatch' &&
|
||||
github.event.client_payload.slash_command.args.named.sha != '' &&
|
||||
contains(
|
||||
github.event.client_payload.pull_request.head.sha,
|
||||
github.event.client_payload.slash_command.args.named.sha
|
||||
)
|
||||
uses: 1password/load-secrets-action/.github/workflows/acceptance-test.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
secret: op://acceptance-tests/test-secret/password
|
||||
secret-in-section: op://acceptance-tests/test-secret/test-section/password
|
||||
multiline-secret: op://acceptance-tests/multiline-secret/notesPlain
|
||||
export-env: true
|
||||
test-references-with-ids:
|
||||
if: |
|
||||
github.event_name == 'repository_dispatch' &&
|
||||
github.event.client_payload.slash_command.args.named.sha != '' &&
|
||||
contains(
|
||||
github.event.client_payload.pull_request.head.sha,
|
||||
github.event.client_payload.slash_command.args.named.sha
|
||||
)
|
||||
uses: 1password/load-secrets-action/.github/workflows/acceptance-test.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
secret: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
|
||||
secret-in-section: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/Section_tco6nsqycj6jcbyx63h5isxcny/doxu3mhkozcznnk5vjrkpdqayy
|
||||
multiline-secret: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
|
||||
export-env: false
|
||||
update-checks:
|
||||
# required permissions for updating the status of the pull request checks
|
||||
permissions:
|
||||
pull-requests: write
|
||||
checks: write
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ always() }}
|
||||
strategy:
|
||||
matrix:
|
||||
job-name:
|
||||
[
|
||||
test-with-output-secrets,
|
||||
test-with-export-env,
|
||||
test-references-with-ids,
|
||||
]
|
||||
needs:
|
||||
[test-with-output-secrets, test-with-export-env, test-references-with-ids]
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
env:
|
||||
job: ${{ matrix.job-name }}
|
||||
ref: ${{ github.event.client_payload.pull_request.head.sha }}
|
||||
conclusion: ${{ needs[format('{0}', matrix.job-name )].result }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const { data: checks } = await github.rest.checks.listForRef({
|
||||
...context.repo,
|
||||
ref: process.env.ref
|
||||
});
|
||||
|
||||
const check = checks.check_runs.filter(c => c.name === process.env.job);
|
||||
|
||||
const { data: result } = await github.rest.checks.update({
|
||||
...context.repo,
|
||||
check_run_id: check[0].id,
|
||||
status: 'completed',
|
||||
conclusion: process.env.conclusion
|
||||
});
|
||||
|
||||
return result;
|
||||
@@ -0,0 +1,100 @@
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
name: Run acceptance tests
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
|
||||
test-with-output-secrets:
|
||||
if: |
|
||||
github.ref == 'refs/heads/main' ||
|
||||
(
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
)
|
||||
uses: 1password/load-secrets-action/.github/workflows/acceptance-test.yml@main
|
||||
secrets: inherit
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
version: [latest, latest-beta, 2.30.0, 2.30.0-beta.03]
|
||||
auth: [connect, service-account]
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
auth: connect
|
||||
- os: windows-latest
|
||||
auth: connect
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
version: ${{ matrix.version }}
|
||||
auth: ${{ matrix.auth }}
|
||||
secret: op://acceptance-tests/test-secret/password
|
||||
secret-in-section: op://acceptance-tests/test-secret/test-section/password
|
||||
multiline-secret: op://acceptance-tests/multiline-secret/notesPlain
|
||||
export-env: false
|
||||
|
||||
test-with-export-env:
|
||||
if: |
|
||||
github.ref == 'refs/heads/main' ||
|
||||
(
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
)
|
||||
uses: 1password/load-secrets-action/.github/workflows/acceptance-test.yml@main
|
||||
secrets: inherit
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
version: [latest, latest-beta, 2.30.0, 2.30.0-beta.03]
|
||||
auth: [connect, service-account]
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
auth: connect
|
||||
- os: windows-latest
|
||||
auth: connect
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
version: ${{ matrix.version }}
|
||||
auth: ${{ matrix.auth }}
|
||||
secret: op://acceptance-tests/test-secret/password
|
||||
secret-in-section: op://acceptance-tests/test-secret/test-section/password
|
||||
multiline-secret: op://acceptance-tests/multiline-secret/notesPlain
|
||||
export-env: true
|
||||
|
||||
test-references-with-ids:
|
||||
if: |
|
||||
github.ref == 'refs/heads/main' ||
|
||||
(
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
)
|
||||
uses: 1password/load-secrets-action/.github/workflows/acceptance-test.yml@main
|
||||
secrets: inherit
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
version: [latest, latest-beta, 2.30.0, 2.30.0-beta.03]
|
||||
auth: [connect, service-account]
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
auth: connect
|
||||
- os: windows-latest
|
||||
auth: connect
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
version: ${{ matrix.version }}
|
||||
auth: ${{ matrix.auth }}
|
||||
secret: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
|
||||
secret-in-section: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/Section_tco6nsqycj6jcbyx63h5isxcny/doxu3mhkozcznnk5vjrkpdqayy
|
||||
multiline-secret: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
|
||||
export-env: false
|
||||
@@ -17,8 +17,6 @@ Specify in your workflow YAML file which secrets from 1Password should be loaded
|
||||
|
||||
Read more on the [1Password Developer Portal](https://developer.1password.com/docs/ci-cd/github-actions).
|
||||
|
||||
_This project is licensed under [MIT](./LICENSE). Use of the 1Password APIs and services accessed through these tools is governed by the [1Password API Terms of Service](https://1password.com/legal/api-sdk-terms-of-service)._
|
||||
|
||||
## 🪄 See it in action!
|
||||
|
||||
[](https://www.youtube.com/watch?v=kVBl5iQYgSA "Using 1Password Service Accounts with GitHub Actions")
|
||||
@@ -37,7 +35,7 @@ jobs:
|
||||
|
||||
- name: Load secret
|
||||
id: load_secrets
|
||||
uses: 1password/load-secrets-action@v4
|
||||
uses: 1password/load-secrets-action@v3
|
||||
env:
|
||||
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||
SECRET: op://app-cicd/hello-world/secret
|
||||
@@ -59,7 +57,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Load secret
|
||||
uses: 1password/load-secrets-action@v4
|
||||
uses: 1password/load-secrets-action@v3
|
||||
with:
|
||||
# Export loaded secrets as environment variables
|
||||
export-env: true
|
||||
@@ -73,50 +71,6 @@ jobs:
|
||||
# Prints: Secret: ***
|
||||
```
|
||||
|
||||
### 🔑 SSH Key Format
|
||||
|
||||
When loading SSH keys, you can specify the format using the `ssh-format` query parameter. This is useful when you need the private key in a specific format like OpenSSH.
|
||||
|
||||
```yml
|
||||
- name: Load SSH key
|
||||
uses: 1password/load-secrets-action@v4
|
||||
env:
|
||||
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||
# Load SSH private key in OpenSSH format
|
||||
SSH_PRIVATE_KEY: op://vault/item/private key?ssh-format=openssh
|
||||
```
|
||||
|
||||
For more details on secret reference syntax, see the [1Password CLI documentation](https://developer.1password.com/docs/cli/secret-reference-syntax/#ssh-format-parameter).
|
||||
|
||||
## 🧪 Workload Identity (private beta)
|
||||
|
||||
> [!NOTE]
|
||||
> Workload Identity is in **private beta**. It's available to invited participants only. [Contact 1Password](https://developer.1password.com/joinslack) if you're interested in joining the beta.
|
||||
|
||||
Instead of a Service Account token or Connect credentials, you can authenticate using Workload Identity, which exchanges your GitHub Actions OIDC token for short-lived 1Password access. To use it, set all three of the following environment variables (and do not set the Service Account token or the Connect variables):
|
||||
|
||||
```yml
|
||||
on: push
|
||||
jobs:
|
||||
hello-world:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write # required for the action to request a GitHub OIDC token
|
||||
contents: read
|
||||
steps:
|
||||
- name: Load secret
|
||||
id: load_secrets
|
||||
uses: 1password/load-secrets-action@v5beta
|
||||
env:
|
||||
OP_WORKLOAD_ID: ${{ vars.OP_WORKLOAD_ID }}
|
||||
OP_ENVIRONMENT_ID: ${{ vars.OP_ENVIRONMENT_ID }}
|
||||
OP_INTEGRATION_KEY: ${{ secrets.OP_INTEGRATION_KEY }}
|
||||
```
|
||||
|
||||
Unlike the Service Account and Connect flows, you don't select secrets with individual `op://` references. Instead, **all variables defined in the configured 1Password environment are loaded** and each one is exported as an environment variable (or set as a step output). Scope your environment to only the variables you want available to the job.
|
||||
|
||||
If only some of the three variables are set, or if they're combined with another authentication method, the action fails with a configuration error.
|
||||
|
||||
## 💙 Community & Support
|
||||
|
||||
- File an [issue](https://github.com/1Password/load-secrets-action/issues) for bugs and feature requests.
|
||||
|
||||
+1
-1
@@ -15,5 +15,5 @@ inputs:
|
||||
description: Specify which 1Password CLI version to install. Defaults to "latest".
|
||||
default: "latest"
|
||||
runs:
|
||||
using: "node24"
|
||||
using: "node20"
|
||||
main: "dist/index.js"
|
||||
|
||||
@@ -10,12 +10,6 @@ const jestConfig = {
|
||||
rootDir: "../src/",
|
||||
testEnvironment: "node",
|
||||
testRegex: "(/__tests__/.*|(\\.|/)test)\\.ts",
|
||||
moduleNameMapper: {
|
||||
"^@actions/core$": "<rootDir>/__mocks__/actions-core.ts",
|
||||
"^@actions/tool-cache$": "<rootDir>/__mocks__/actions-tool-cache.ts",
|
||||
"^@actions/exec$": "<rootDir>/__mocks__/actions-exec.ts",
|
||||
"^@1password/sdk$": "<rootDir>/__mocks__/1password-sdk.ts",
|
||||
},
|
||||
transform: {
|
||||
".ts": [
|
||||
"ts-jest",
|
||||
@@ -31,4 +25,4 @@ const jestConfig = {
|
||||
verbose: true,
|
||||
};
|
||||
|
||||
module.exports = jestConfig;
|
||||
export default jestConfig;
|
||||
|
||||
@@ -9,5 +9,5 @@ inputs:
|
||||
service-account-token:
|
||||
description: Your 1Password service account token
|
||||
runs:
|
||||
using: "node24"
|
||||
using: "node20"
|
||||
main: "dist/index.js"
|
||||
|
||||
Vendored
+14689
-18123
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
import * as core from "@actions/core";
|
||||
const core = require("@actions/core");
|
||||
|
||||
const configure = () => {
|
||||
const OP_CONNECT_HOST =
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+17185
-22022
File diff suppressed because one or more lines are too long
Generated
+150
-129
@@ -1,19 +1,18 @@
|
||||
{
|
||||
"name": "load-secrets-action",
|
||||
"version": "5.0.0-beta.1",
|
||||
"version": "3.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "load-secrets-action",
|
||||
"version": "5.0.0-beta.1",
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@1password/op-js": "^0.1.11",
|
||||
"@1password/sdk": "0.5.0-beta.1",
|
||||
"@actions/core": "^3.0.0",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/tool-cache": "^4.0.0",
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/tool-cache": "^2.0.2",
|
||||
"dotenv": "^17.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -73,65 +72,59 @@
|
||||
"prettier": "^2.0.0 || ^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@1password/sdk": {
|
||||
"version": "0.5.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/@1password/sdk/-/sdk-0.5.0-beta.1.tgz",
|
||||
"integrity": "sha512-GY1kcn86qkb39jt20AyOftEu5Tw/Kyq4f84GOHXKRjur4TvqvzdhapynBBosRcBL+kBrc+E8cx7Tp7GEfqAomw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@1password/sdk-core": "0.5.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@1password/sdk-core": {
|
||||
"version": "0.5.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/@1password/sdk-core/-/sdk-core-0.5.0-beta.1.tgz",
|
||||
"integrity": "sha512-61Q2n0kKYXBVAbW5ZVFqtbK1KX3lUfFi8wdsv+UjIVtbFd+X1GpFbLFs+nPtPgX+Z7oc2tTN/czK0S9Cz4oF/A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
|
||||
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/http-client": "^4.0.0"
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/exec": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
|
||||
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^3.0.2"
|
||||
"@actions/io": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
|
||||
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^6.23.0"
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
|
||||
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@actions/tool-cache": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-4.0.0.tgz",
|
||||
"integrity": "sha512-L8P9HbXvpvqjZDveb/fdsa55IVC0trfPgQ4ZwGo6r5af6YDVdM9vMGPZ7rgY2fAT9gGj4PSYd6bYlg3p3jD78A==",
|
||||
"license": "MIT",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-2.0.2.tgz",
|
||||
"integrity": "sha512-fBhNNOWxuoLxztQebpOaWu6WeVmuwa77Z+DxIZ1B+OYvGkGQon6kTVg6Z32Cb13WCuw0szqonK+hh03mJV7Z6w==",
|
||||
"dependencies": {
|
||||
"@actions/core": "^3.0.0",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/http-client": "^4.0.0",
|
||||
"@actions/io": "^3.0.0",
|
||||
"semver": "^7.7.3"
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.0.0",
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@actions/io": "^1.1.1",
|
||||
"semver": "^6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/tool-cache/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
@@ -179,6 +172,7 @@
|
||||
"integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
"@babel/code-frame": "^7.26.0",
|
||||
@@ -714,7 +708,6 @@
|
||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
@@ -738,8 +731,7 @@
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true,
|
||||
"license": "Python-2.0",
|
||||
"peer": true
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/js-yaml": {
|
||||
"version": "4.1.1",
|
||||
@@ -747,7 +739,6 @@
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
@@ -761,11 +752,19 @@
|
||||
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
|
||||
@@ -773,7 +772,6 @@
|
||||
"deprecated": "Use @eslint/config-array instead",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^2.0.3",
|
||||
"debug": "^4.3.1",
|
||||
@@ -789,7 +787,6 @@
|
||||
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12.22"
|
||||
},
|
||||
@@ -804,8 +801,7 @@
|
||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||
"deprecated": "Use @eslint/object-schema instead",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"peer": true
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
@@ -1460,6 +1456,7 @@
|
||||
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "6.21.0",
|
||||
"@typescript-eslint/types": "6.21.0",
|
||||
@@ -1572,6 +1569,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
|
||||
@@ -1621,8 +1644,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz",
|
||||
"integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@vercel/ncc": {
|
||||
"version": "0.38.3",
|
||||
@@ -1654,17 +1676,16 @@
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@@ -2105,13 +2126,14 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
@@ -2147,6 +2169,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001688",
|
||||
"electron-to-chromium": "^1.5.73",
|
||||
@@ -2491,6 +2514,13 @@
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
@@ -2634,8 +2664,7 @@
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
@@ -2722,7 +2751,6 @@
|
||||
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esutils": "^2.0.2"
|
||||
},
|
||||
@@ -3381,7 +3409,6 @@
|
||||
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^5.2.0"
|
||||
@@ -3411,8 +3438,7 @@
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true,
|
||||
"license": "Python-2.0",
|
||||
"peer": true
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/eslint/node_modules/find-up": {
|
||||
"version": "5.0.0",
|
||||
@@ -3420,7 +3446,6 @@
|
||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"locate-path": "^6.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
@@ -3438,7 +3463,6 @@
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
@@ -3452,7 +3476,6 @@
|
||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"p-locate": "^5.0.0"
|
||||
},
|
||||
@@ -3469,7 +3492,6 @@
|
||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"p-limit": "^3.0.2"
|
||||
},
|
||||
@@ -3486,7 +3508,6 @@
|
||||
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.9.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
@@ -3532,7 +3553,6 @@
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
@@ -3622,8 +3642,7 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.2",
|
||||
@@ -3667,8 +3686,7 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.17.1",
|
||||
@@ -3696,7 +3714,6 @@
|
||||
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"flat-cache": "^3.0.4"
|
||||
},
|
||||
@@ -3714,6 +3731,29 @@
|
||||
"minimatch": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
@@ -3747,7 +3787,6 @@
|
||||
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"flatted": "^3.2.9",
|
||||
"keyv": "^4.5.3",
|
||||
@@ -3758,11 +3797,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
|
||||
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.3",
|
||||
@@ -3963,7 +4002,6 @@
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
@@ -3977,7 +4015,6 @@
|
||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.20.2"
|
||||
},
|
||||
@@ -4203,7 +4240,6 @@
|
||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"parent-module": "^1.0.0",
|
||||
"resolve-from": "^4.0.0"
|
||||
@@ -4570,7 +4606,6 @@
|
||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -4861,6 +4896,7 @@
|
||||
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/core": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
@@ -5519,8 +5555,7 @@
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
@@ -5534,16 +5569,14 @@
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
@@ -5580,7 +5613,6 @@
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
@@ -5631,7 +5663,6 @@
|
||||
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prelude-ls": "^1.2.1",
|
||||
"type-check": "~0.4.0"
|
||||
@@ -5888,8 +5919,7 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/log-update": {
|
||||
"version": "6.1.0",
|
||||
@@ -6135,19 +6165,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.2"
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
@@ -6347,7 +6374,6 @@
|
||||
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"deep-is": "^0.1.3",
|
||||
"fast-levenshtein": "^2.0.6",
|
||||
@@ -6421,7 +6447,6 @@
|
||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"callsites": "^3.0.0"
|
||||
},
|
||||
@@ -6567,7 +6592,6 @@
|
||||
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
@@ -6656,7 +6680,6 @@
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -6805,7 +6828,6 @@
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -6891,7 +6913,6 @@
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
@@ -6965,9 +6986,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -7514,8 +7535,7 @@
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tmpl": {
|
||||
"version": "1.0.5",
|
||||
@@ -7690,7 +7710,6 @@
|
||||
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prelude-ls": "^1.2.1"
|
||||
},
|
||||
@@ -7714,7 +7733,6 @@
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||
"dev": true,
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -7806,6 +7824,7 @@
|
||||
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -7834,11 +7853,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
@@ -7885,7 +7908,6 @@
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
@@ -8024,7 +8046,6 @@
|
||||
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
||||
+4
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "load-secrets-action",
|
||||
"version": "5.0.0-beta.1",
|
||||
"version": "3.0.0",
|
||||
"description": "Load Secrets from 1Password",
|
||||
"main": "dist/index.js",
|
||||
"directories": {
|
||||
@@ -40,16 +40,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/1Password/load-secrets-action#readme",
|
||||
"dependencies": {
|
||||
"@1password/sdk": "0.5.0-beta.1",
|
||||
"@1password/op-js": "^0.1.11",
|
||||
"@actions/core": "^3.0.0",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/tool-cache": "^4.0.0",
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/tool-cache": "^2.0.2",
|
||||
"dotenv": "^17.2.2"
|
||||
},
|
||||
"overrides": {
|
||||
"minimatch": "^9.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@1password/eslint-config": "^4.3.1",
|
||||
"@1password/prettier-config": "^1.2.0",
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const createClient = jest.fn();
|
||||
@@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
getInput: jest.fn(() => ""),
|
||||
getBooleanInput: jest.fn(() => false),
|
||||
setOutput: jest.fn(),
|
||||
setSecret: jest.fn(),
|
||||
exportVariable: jest.fn(),
|
||||
setFailed: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
error: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
addPath: jest.fn(),
|
||||
isDebug: jest.fn(() => false),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
getIDToken: jest.fn().mockResolvedValue("mock-oidc-token"),
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
getExecOutput: jest.fn(() => ({
|
||||
stdout: "MOCK_SECRET",
|
||||
})),
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
downloadTool: jest.fn(),
|
||||
extractTar: jest.fn(),
|
||||
extractZip: jest.fn(),
|
||||
cacheDir: jest.fn<Promise<string>, [string]>(async (dir) => {
|
||||
await Promise.resolve();
|
||||
return dir;
|
||||
}),
|
||||
find: jest.fn<string, [string, string?, string?]>(() => ""),
|
||||
};
|
||||
@@ -3,8 +3,5 @@ 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 envWorkloadId = "OP_WORKLOAD_ID";
|
||||
export const envEnvironmentId = "OP_ENVIRONMENT_ID";
|
||||
export const envIntegrationKey = "OP_INTEGRATION_KEY";
|
||||
|
||||
export const authErr = `Authentication error with environment variables: you must set either 1) ${envServiceAccountToken}, or 2) both ${envConnectHost} and ${envConnectToken}.`;
|
||||
|
||||
+12
-40
@@ -2,14 +2,7 @@ import dotenv from "dotenv";
|
||||
import * as core from "@actions/core";
|
||||
import { validateCli } from "@1password/op-js";
|
||||
import { installCliOnGithubActionRunner } from "./op-cli-installer";
|
||||
import {
|
||||
getWorkloadIdentityConfig,
|
||||
hasCliAuth,
|
||||
loadSecrets,
|
||||
unsetPrevious,
|
||||
validateAuth,
|
||||
} from "./utils";
|
||||
import { loadSecretsFromSDK } from "./sdk-client";
|
||||
import { loadSecrets, unsetPrevious, validateAuth } from "./utils";
|
||||
import { envFilePath } from "./constants";
|
||||
|
||||
const loadSecretsAction = async () => {
|
||||
@@ -23,42 +16,21 @@ const loadSecretsAction = async () => {
|
||||
unsetPrevious();
|
||||
}
|
||||
|
||||
const workloadConfig = getWorkloadIdentityConfig();
|
||||
// Validate that a proper authentication configuration is set for the CLI
|
||||
validateAuth();
|
||||
|
||||
// `unset-previous` can run with no credentials present: Workload Identity creds
|
||||
// are inline per-step and intentionally not persisted (persisting them would make
|
||||
// every later step re-load all variables). Nothing to auth or load, we're done.
|
||||
if (shouldUnsetPrevious && !workloadConfig && !hasCliAuth()) {
|
||||
core.info(
|
||||
"No authentication configured; unset previously managed variables. No secrets were loaded.",
|
||||
);
|
||||
return;
|
||||
// Set environment variables from OP_ENV_FILE
|
||||
const file = process.env[envFilePath];
|
||||
if (file) {
|
||||
core.info(`Loading environment variables from file: ${file}`);
|
||||
dotenv.config({ path: file });
|
||||
}
|
||||
|
||||
if (workloadConfig) {
|
||||
await loadSecretsFromSDK(
|
||||
workloadConfig.workloadId,
|
||||
workloadConfig.environmentId,
|
||||
workloadConfig.integrationKey,
|
||||
shouldExportEnv,
|
||||
);
|
||||
} else {
|
||||
// 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}`);
|
||||
dotenv.config({ path: file });
|
||||
}
|
||||
|
||||
// Download and install the CLI
|
||||
await installCLI();
|
||||
|
||||
// Load secrets
|
||||
await loadSecrets(shouldExportEnv);
|
||||
}
|
||||
// Load secrets
|
||||
await loadSecrets(shouldExportEnv);
|
||||
} catch (error) {
|
||||
// It's possible for the Error constructor to be modified to be anything
|
||||
// in JavaScript, so the following code accounts for this possibility.
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as tc from "@actions/tool-cache";
|
||||
|
||||
import {
|
||||
archMap,
|
||||
CliInstaller,
|
||||
cliUrlBuilder,
|
||||
type SupportedPlatform,
|
||||
} from "./cli-installer";
|
||||
import { WindowsInstaller } from "./windows";
|
||||
|
||||
jest.mock("fs");
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
@@ -30,7 +25,9 @@ describe("WindowsInstaller", () => {
|
||||
|
||||
it("should call install with correct URL", async () => {
|
||||
const installer = new WindowsInstaller(version);
|
||||
const installMock = jest.spyOn(installer, "install").mockResolvedValue();
|
||||
const installMock = jest
|
||||
.spyOn(CliInstaller.prototype, "install")
|
||||
.mockResolvedValue();
|
||||
|
||||
await installer.installCli();
|
||||
|
||||
@@ -38,23 +35,4 @@ describe("WindowsInstaller", () => {
|
||||
const url = builder(version, installer.arch);
|
||||
expect(installMock).toHaveBeenCalledWith(url);
|
||||
});
|
||||
|
||||
it("should rename downloaded file with .zip extension before extracting", async () => {
|
||||
const downloadPath = "/tmp/abc-123";
|
||||
const extractedPath = "/tmp/extracted";
|
||||
|
||||
(tc.downloadTool as jest.Mock).mockResolvedValue(downloadPath);
|
||||
(tc.extractZip as jest.Mock).mockResolvedValue(extractedPath);
|
||||
|
||||
const installer = new WindowsInstaller(version);
|
||||
await installer.installCli();
|
||||
|
||||
expect(tc.downloadTool).toHaveBeenCalled();
|
||||
expect(fs.renameSync).toHaveBeenCalledWith(
|
||||
downloadPath,
|
||||
`${downloadPath}.zip`,
|
||||
);
|
||||
expect(tc.extractZip).toHaveBeenCalledWith(`${downloadPath}.zip`);
|
||||
expect(core.addPath).toHaveBeenCalledWith(extractedPath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import * as fs from "fs";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as tc from "@actions/tool-cache";
|
||||
|
||||
import {
|
||||
CliInstaller,
|
||||
cliUrlBuilder,
|
||||
@@ -19,19 +14,6 @@ export class WindowsInstaller extends CliInstaller implements Installer {
|
||||
|
||||
public async installCli(): Promise<void> {
|
||||
const urlBuilder = cliUrlBuilder[this.platform];
|
||||
await this.install(urlBuilder(this.version, this.arch));
|
||||
}
|
||||
|
||||
// Windows PowerShell's Expand-Archive requires files to have a .zip extension.
|
||||
// tc.downloadTool saves to a UUID filename with no extension, so we rename it.
|
||||
public override async install(url: string): Promise<void> {
|
||||
console.info(`Downloading 1Password CLI from: ${url}`);
|
||||
const downloadPath = await tc.downloadTool(url);
|
||||
const zipPath = `${downloadPath}.zip`;
|
||||
fs.renameSync(downloadPath, zipPath);
|
||||
console.info("Installing 1Password CLI");
|
||||
const extractedPath = await tc.extractZip(zipPath);
|
||||
core.addPath(extractedPath);
|
||||
core.info("1Password CLI installed");
|
||||
await super.install(urlBuilder(this.version, this.arch));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
import * as core from "@actions/core";
|
||||
import { createClient } from "@1password/sdk";
|
||||
import { envManagedVariables } from "./constants";
|
||||
import { getOIDCToken, loadSecretsFromSDK } from "./sdk-client";
|
||||
|
||||
jest.mock("@1password/sdk");
|
||||
|
||||
const mockGetVariables = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
(createClient as jest.Mock).mockResolvedValue({
|
||||
environments: {
|
||||
getVariables: mockGetVariables,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe("getOIDCToken", () => {
|
||||
it("delegates to core.getIDToken", async () => {
|
||||
(core.getIDToken as jest.Mock).mockResolvedValue("oidc-token");
|
||||
|
||||
await expect(getOIDCToken("test-audience")).resolves.toBe("oidc-token");
|
||||
expect(core.getIDToken).toHaveBeenCalledWith("test-audience");
|
||||
});
|
||||
});
|
||||
|
||||
describe("loadSecretsFromSDK", () => {
|
||||
const workloadId = "workload-uuid";
|
||||
const environmentId = "environment-uuid";
|
||||
const integrationKey = "integration-key";
|
||||
|
||||
const variables = [
|
||||
{ name: "DOCKERHUB_USERNAME", value: "myuser" },
|
||||
{ name: "DOCKERHUB_TOKEN", value: "mypassword" },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
mockGetVariables.mockResolvedValue({ variables });
|
||||
});
|
||||
|
||||
it("sets secrets as step outputs by default", async () => {
|
||||
await loadSecretsFromSDK(workloadId, environmentId, integrationKey, false);
|
||||
|
||||
expect(core.setOutput).toHaveBeenCalledWith("DOCKERHUB_USERNAME", "myuser");
|
||||
expect(core.setOutput).toHaveBeenCalledWith(
|
||||
"DOCKERHUB_TOKEN",
|
||||
"mypassword",
|
||||
);
|
||||
expect(core.exportVariable).not.toHaveBeenCalledWith(
|
||||
"DOCKERHUB_USERNAME",
|
||||
"myuser",
|
||||
);
|
||||
expect(core.setSecret).toHaveBeenCalledWith("myuser");
|
||||
expect(core.setSecret).toHaveBeenCalledWith("mypassword");
|
||||
expect(core.exportVariable).not.toHaveBeenCalledWith(
|
||||
envManagedVariables,
|
||||
expect.any(String),
|
||||
);
|
||||
});
|
||||
|
||||
it("exports secrets as environment variables when shouldExportEnv is true", async () => {
|
||||
await loadSecretsFromSDK(workloadId, environmentId, integrationKey, true);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenCalledWith(
|
||||
"DOCKERHUB_USERNAME",
|
||||
"myuser",
|
||||
);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith(
|
||||
"DOCKERHUB_TOKEN",
|
||||
"mypassword",
|
||||
);
|
||||
expect(core.setOutput).not.toHaveBeenCalled();
|
||||
expect(core.exportVariable).toHaveBeenCalledWith(
|
||||
envManagedVariables,
|
||||
"DOCKERHUB_USERNAME,DOCKERHUB_TOKEN",
|
||||
);
|
||||
});
|
||||
|
||||
describe("when secret value is empty string", () => {
|
||||
beforeEach(() => {
|
||||
mockGetVariables.mockResolvedValue({
|
||||
variables: [{ name: "EMPTY_SECRET", value: "" }],
|
||||
});
|
||||
});
|
||||
|
||||
it("sets empty string as step output", async () => {
|
||||
await loadSecretsFromSDK(
|
||||
workloadId,
|
||||
environmentId,
|
||||
integrationKey,
|
||||
false,
|
||||
);
|
||||
|
||||
expect(core.setOutput).toHaveBeenCalledWith("EMPTY_SECRET", "");
|
||||
expect(core.setSecret).not.toHaveBeenCalledWith("");
|
||||
});
|
||||
|
||||
it("sets empty string as environment variable", async () => {
|
||||
await loadSecretsFromSDK(workloadId, environmentId, integrationKey, true);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenCalledWith("EMPTY_SECRET", "");
|
||||
expect(core.setSecret).not.toHaveBeenCalledWith("");
|
||||
});
|
||||
});
|
||||
|
||||
it("does not export OP_MANAGED_VARIABLES when no variables are returned", async () => {
|
||||
mockGetVariables.mockResolvedValue({ variables: [] });
|
||||
|
||||
await loadSecretsFromSDK(workloadId, environmentId, integrationKey, true);
|
||||
|
||||
expect(core.exportVariable).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
import * as core from "@actions/core";
|
||||
import { createClient } from "@1password/sdk";
|
||||
import { version } from "../package.json";
|
||||
import { envManagedVariables } from "./constants";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export const getOIDCToken = async (audience: string): Promise<string> =>
|
||||
core.getIDToken(audience);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export const loadSecretsFromSDK = async (
|
||||
workloadId: string,
|
||||
environmentId: string,
|
||||
integrationKey: string,
|
||||
shouldExportEnv: boolean,
|
||||
): Promise<void> => {
|
||||
// Temporary fix: strip base64 padding from integrationKey — this will eventually be handled by the SDK core itself
|
||||
const customerManagedSecret = integrationKey.replace(/=+$/, "");
|
||||
core.setSecret(customerManagedSecret);
|
||||
|
||||
const client = await createClient({
|
||||
integrationName: "1Password GitHub Action",
|
||||
integrationVersion: version,
|
||||
oidcFetcher: getOIDCToken,
|
||||
workloadDetails: {
|
||||
customerManagedSecret,
|
||||
workloadUuid: workloadId,
|
||||
},
|
||||
});
|
||||
|
||||
core.info("Authenticated with Workload Identity.");
|
||||
|
||||
const { variables } = await client.environments.getVariables(environmentId);
|
||||
|
||||
const envNames: string[] = [];
|
||||
for (const { name, value } of variables) {
|
||||
core.info(`Populating variable: ${name}`);
|
||||
if (shouldExportEnv) {
|
||||
core.exportVariable(name, value);
|
||||
} else {
|
||||
core.setOutput(name, value);
|
||||
}
|
||||
if (value) {
|
||||
core.setSecret(value);
|
||||
}
|
||||
envNames.push(name);
|
||||
}
|
||||
|
||||
if (shouldExportEnv && envNames.length > 0) {
|
||||
core.exportVariable(envManagedVariables, envNames.join());
|
||||
}
|
||||
};
|
||||
+6
-150
@@ -3,8 +3,6 @@ import * as exec from "@actions/exec";
|
||||
import { read, setClientInfo } from "@1password/op-js";
|
||||
import {
|
||||
extractSecret,
|
||||
getWorkloadIdentityConfig,
|
||||
hasCliAuth,
|
||||
loadSecrets,
|
||||
unsetPrevious,
|
||||
validateAuth,
|
||||
@@ -13,13 +11,16 @@ import {
|
||||
authErr,
|
||||
envConnectHost,
|
||||
envConnectToken,
|
||||
envEnvironmentId,
|
||||
envIntegrationKey,
|
||||
envManagedVariables,
|
||||
envServiceAccountToken,
|
||||
envWorkloadId,
|
||||
} from "./constants";
|
||||
|
||||
jest.mock("@actions/core");
|
||||
jest.mock("@actions/exec", () => ({
|
||||
getExecOutput: jest.fn(() => ({
|
||||
stdout: "MOCK_SECRET",
|
||||
})),
|
||||
}));
|
||||
jest.mock("@1password/op-js");
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -71,96 +72,6 @@ describe("validateAuth", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("getWorkloadIdentityConfig", () => {
|
||||
const testWorkloadId = "workload-id";
|
||||
const testEnvironmentId = "environment-id";
|
||||
const testIntegrationKey = "integration-key";
|
||||
|
||||
beforeEach(() => {
|
||||
process.env[envWorkloadId] = "";
|
||||
process.env[envEnvironmentId] = "";
|
||||
process.env[envIntegrationKey] = "";
|
||||
process.env[envConnectHost] = "";
|
||||
process.env[envConnectToken] = "";
|
||||
process.env[envServiceAccountToken] = "";
|
||||
});
|
||||
|
||||
it("should return null when no variables are set", () => {
|
||||
expect(getWorkloadIdentityConfig()).toBeNull();
|
||||
});
|
||||
|
||||
it("should return the config when all variables are set", () => {
|
||||
process.env[envWorkloadId] = testWorkloadId;
|
||||
process.env[envEnvironmentId] = testEnvironmentId;
|
||||
process.env[envIntegrationKey] = testIntegrationKey;
|
||||
|
||||
expect(getWorkloadIdentityConfig()).toEqual({
|
||||
workloadId: testWorkloadId,
|
||||
environmentId: testEnvironmentId,
|
||||
integrationKey: testIntegrationKey,
|
||||
});
|
||||
});
|
||||
|
||||
it("should throw an error when only some variables are set", () => {
|
||||
process.env[envWorkloadId] = testWorkloadId;
|
||||
|
||||
expect(getWorkloadIdentityConfig).toThrow(
|
||||
/Incomplete Workload Identity configuration/,
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw an error when combined with Connect credentials", () => {
|
||||
process.env[envWorkloadId] = testWorkloadId;
|
||||
process.env[envEnvironmentId] = testEnvironmentId;
|
||||
process.env[envIntegrationKey] = testIntegrationKey;
|
||||
process.env[envConnectHost] = "https://localhost:8000";
|
||||
process.env[envConnectToken] = "token";
|
||||
|
||||
expect(getWorkloadIdentityConfig).toThrow(
|
||||
/Conflicting authentication configuration/,
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw an error when combined with a service account token", () => {
|
||||
process.env[envWorkloadId] = testWorkloadId;
|
||||
process.env[envEnvironmentId] = testEnvironmentId;
|
||||
process.env[envIntegrationKey] = testIntegrationKey;
|
||||
process.env[envServiceAccountToken] = "ops_token";
|
||||
|
||||
expect(getWorkloadIdentityConfig).toThrow(
|
||||
/Conflicting authentication configuration/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("hasCliAuth", () => {
|
||||
beforeEach(() => {
|
||||
process.env[envConnectHost] = "";
|
||||
process.env[envConnectToken] = "";
|
||||
process.env[envServiceAccountToken] = "";
|
||||
});
|
||||
|
||||
it("returns false when no CLI auth is configured", () => {
|
||||
expect(hasCliAuth()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when only the Connect host is set", () => {
|
||||
process.env[envConnectHost] = "https://localhost:8000";
|
||||
expect(hasCliAuth()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true with both Connect host and token", () => {
|
||||
process.env[envConnectHost] = "https://localhost:8000";
|
||||
process.env[envConnectToken] = "token";
|
||||
expect(hasCliAuth()).toBe(true);
|
||||
});
|
||||
|
||||
it("returns true with a service account token", () => {
|
||||
process.env[envServiceAccountToken] = "ops_token";
|
||||
expect(hasCliAuth()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractSecret", () => {
|
||||
const envTestSecretEnv = "TEST_SECRET";
|
||||
const testSecretRef = "op://vault/item/secret";
|
||||
@@ -195,41 +106,6 @@ describe("extractSecret", () => {
|
||||
);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(testSecretValue);
|
||||
});
|
||||
|
||||
describe("when secret value is empty string", () => {
|
||||
const emptySecretValue = "";
|
||||
|
||||
beforeEach(() => {
|
||||
(read.parse as jest.Mock).mockReturnValue(emptySecretValue);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
(read.parse as jest.Mock).mockReturnValue(testSecretValue);
|
||||
});
|
||||
|
||||
it("should set empty string as step output", () => {
|
||||
extractSecret(envTestSecretEnv, false);
|
||||
expect(core.setOutput).toHaveBeenCalledWith(
|
||||
envTestSecretEnv,
|
||||
emptySecretValue,
|
||||
);
|
||||
expect(core.exportVariable).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should set empty string as environment variable", () => {
|
||||
extractSecret(envTestSecretEnv, true);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith(
|
||||
envTestSecretEnv,
|
||||
emptySecretValue,
|
||||
);
|
||||
expect(core.setOutput).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not call setSecret for empty string", () => {
|
||||
extractSecret(envTestSecretEnv, false);
|
||||
expect(core.setSecret).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("loadSecrets", () => {
|
||||
@@ -285,24 +161,4 @@ describe("unsetPrevious", () => {
|
||||
expect(core.info).toHaveBeenCalledWith("Unsetting TEST_SECRET");
|
||||
expect(core.exportVariable).toHaveBeenCalledWith("TEST_SECRET", "");
|
||||
});
|
||||
|
||||
it("should unset every variable listed in OP_MANAGED_VARIABLES", () => {
|
||||
process.env[envManagedVariables] = "TEST_SECRET,ANOTHER_TEST,SUPER_SECRET";
|
||||
|
||||
unsetPrevious();
|
||||
|
||||
expect(core.exportVariable).toHaveBeenCalledWith("TEST_SECRET", "");
|
||||
expect(core.exportVariable).toHaveBeenCalledWith("ANOTHER_TEST", "");
|
||||
expect(core.exportVariable).toHaveBeenCalledWith("SUPER_SECRET", "");
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("should do nothing when no variables are managed", () => {
|
||||
process.env[envManagedVariables] = "";
|
||||
|
||||
unsetPrevious();
|
||||
|
||||
expect(core.exportVariable).not.toHaveBeenCalled();
|
||||
expect(core.info).not.toHaveBeenCalledWith("Unsetting previous values ...");
|
||||
});
|
||||
});
|
||||
|
||||
+4
-62
@@ -8,61 +8,8 @@ import {
|
||||
envConnectToken,
|
||||
envServiceAccountToken,
|
||||
envManagedVariables,
|
||||
envWorkloadId,
|
||||
envEnvironmentId,
|
||||
envIntegrationKey,
|
||||
} from "./constants";
|
||||
|
||||
export interface WorkloadIdentityConfig {
|
||||
workloadId: string;
|
||||
environmentId: string;
|
||||
integrationKey: string;
|
||||
}
|
||||
|
||||
// Returns the Workload Identity configuration when all variables are set,
|
||||
// or null when none are set (so the CLI auth path can be used instead).
|
||||
// Throws if the configuration is only partially set, or if it is combined
|
||||
// with the CLI auth methods (Connect / service account).
|
||||
export const getWorkloadIdentityConfig = (): WorkloadIdentityConfig | null => {
|
||||
const workloadId = process.env[envWorkloadId];
|
||||
const environmentId = process.env[envEnvironmentId];
|
||||
const integrationKey = process.env[envIntegrationKey];
|
||||
|
||||
// None set: fall back to the CLI auth path.
|
||||
if (!workloadId && !environmentId && !integrationKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Some but not all set: configuration is incomplete.
|
||||
if (!workloadId || !environmentId || !integrationKey) {
|
||||
throw new Error(
|
||||
`Incomplete Workload Identity configuration. To use Workload Identity, set all of ${envWorkloadId}, ${envEnvironmentId}, and ${envIntegrationKey}.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Workload Identity is fully configured, so it must not be combined with the
|
||||
// CLI auth methods (Connect / service account), which are mutually exclusive.
|
||||
if (
|
||||
process.env[envConnectHost] ||
|
||||
process.env[envConnectToken] ||
|
||||
process.env[envServiceAccountToken]
|
||||
) {
|
||||
throw new Error(
|
||||
`Conflicting authentication configuration: Workload Identity cannot be combined with Connect (${envConnectHost}/${envConnectToken}) or a service account (${envServiceAccountToken}). Set only one authentication method.`,
|
||||
);
|
||||
}
|
||||
|
||||
return { workloadId, environmentId, integrationKey };
|
||||
};
|
||||
|
||||
// Whether CLI authentication (1Password Connect or a service account) is
|
||||
// configured via environment variables.
|
||||
export const hasCliAuth = (): boolean =>
|
||||
Boolean(
|
||||
(process.env[envConnectHost] && process.env[envConnectToken]) ||
|
||||
process.env[envServiceAccountToken],
|
||||
);
|
||||
|
||||
export const validateAuth = (): void => {
|
||||
const isConnect = process.env[envConnectHost] && process.env[envConnectToken];
|
||||
const isServiceAccount = process.env[envServiceAccountToken];
|
||||
@@ -94,7 +41,7 @@ export const extractSecret = (
|
||||
}
|
||||
|
||||
const secretValue = read.parse(ref);
|
||||
if (secretValue === null || secretValue === undefined) {
|
||||
if (!secretValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,20 +50,15 @@ export const extractSecret = (
|
||||
} else {
|
||||
core.setOutput(envName, secretValue);
|
||||
}
|
||||
// Skip setSecret for empty strings to avoid the warning:
|
||||
// "Can't add secret mask for empty string in ##[add-mask] command."
|
||||
if (secretValue) {
|
||||
core.setSecret(secretValue);
|
||||
}
|
||||
core.setSecret(secretValue);
|
||||
};
|
||||
|
||||
export const loadSecrets = async (shouldExportEnv: boolean): Promise<void> => {
|
||||
// Strip any prerelease suffix; semverToInt only accepts MAJOR.MINOR.PATCH.
|
||||
const [releaseVersion] = version.split("-");
|
||||
// Pass User-Agent Information to the 1Password CLI
|
||||
setClientInfo({
|
||||
name: "1Password GitHub Action",
|
||||
id: "GHA",
|
||||
build: semverToInt(releaseVersion ?? version),
|
||||
build: semverToInt(version),
|
||||
});
|
||||
|
||||
// Load secrets from environment variables using 1Password CLI.
|
||||
|
||||
@@ -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
|
||||
@@ -26,7 +26,6 @@ IApTbyBwbGVhc2UgZG9uJ3QgcmVwb3J0IGl0IQo=
|
||||
EOF
|
||||
)"
|
||||
readonly MULTILINE_SECRET
|
||||
readonly WEBSITE="www.test.com"
|
||||
|
||||
assert_env_equals "SECRET" "${SECRET}"
|
||||
assert_env_equals "FILE_SECRET" "${SECRET}"
|
||||
@@ -36,9 +35,3 @@ assert_env_equals "FILE_SECRET_IN_SECTION" "${SECRET}"
|
||||
|
||||
assert_env_equals "MULTILINE_SECRET" "${MULTILINE_SECRET}"
|
||||
assert_env_equals "FILE_MULTILINE_SECRET" "${MULTILINE_SECRET}"
|
||||
|
||||
# WEBSITE/FILE_WEBSITE: required when ASSERT_WEBSITE=true (Service Account), skipped when false (Connect)
|
||||
if [ "${ASSERT_WEBSITE:-false}" = "true" ]; then
|
||||
assert_env_equals "WEBSITE" "${WEBSITE}"
|
||||
assert_env_equals "FILE_WEBSITE" "${WEBSITE}"
|
||||
fi
|
||||
|
||||
@@ -17,11 +17,3 @@ assert_env_unset "FILE_SECRET_IN_SECTION"
|
||||
|
||||
assert_env_unset "MULTILINE_SECRET"
|
||||
assert_env_unset "FILE_MULTILINE_SECRET"
|
||||
|
||||
assert_env_unset "WEBSITE"
|
||||
assert_env_unset "FILE_WEBSITE"
|
||||
|
||||
assert_env_unset "TEST_SSH_KEY"
|
||||
assert_env_unset "FILE_TEST_SSH_KEY"
|
||||
assert_env_unset "TEST_SSH_KEY_OPENSSH"
|
||||
assert_env_unset "FILE_TEST_SSH_KEY_OPENSSH"
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
assert_ssh_key_set() {
|
||||
local var="$1"
|
||||
local val
|
||||
val="$(printenv "$var" || true)"
|
||||
if [ -z "$val" ]; then
|
||||
echo "Expected $var to be set"
|
||||
exit 1
|
||||
fi
|
||||
[ "$val" = "***" ] && return 0
|
||||
local line
|
||||
line="$(echo "$val" | head -1)"
|
||||
if echo "$var" | grep -q "OPENSSH"; then
|
||||
echo "$line" | grep -q "OPENSSH" || { echo "Expected $var to start with -----BEGIN OPENSSH PRIVATE KEY-----"; exit 1; }
|
||||
else
|
||||
echo "$line" | grep -q "BEGIN.*PRIVATE KEY" || { echo "Expected $var to be a private key"; exit 1; }
|
||||
fi
|
||||
echo "$var OK"
|
||||
}
|
||||
|
||||
assert_ssh_key_set "TEST_SSH_KEY"
|
||||
assert_ssh_key_set "TEST_SSH_KEY_OPENSSH"
|
||||
assert_ssh_key_set "FILE_TEST_SSH_KEY"
|
||||
assert_ssh_key_set "FILE_TEST_SSH_KEY_OPENSSH"
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
# shellcheck disable=SC2086
|
||||
set -e
|
||||
|
||||
# Asserts the secrets loaded via Workload Identity.
|
||||
|
||||
assert_env_equals() {
|
||||
if [ "$(printenv $1)" != "$2" ]; then
|
||||
echo -e "Expected $1 to be set to:\n$2\nBut got:\n$(printenv $1)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_env_equals "ANOTHER_TEST" "anothertest123"
|
||||
assert_env_equals "SUPER_SECRET" "supersecret"
|
||||
assert_env_equals "TEST_SECRET" "thisisatest"
|
||||
Reference in New Issue
Block a user