Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a7975f916 | ||
|
|
ffba2a6966 | ||
|
|
2ee4979efa | ||
|
|
7903600d82 | ||
|
|
fbf9be8f55 | ||
|
|
5a04ae581c | ||
|
|
747c0b5974 | ||
|
|
c0fbfd88d3 | ||
|
|
3f3d1e45cb | ||
|
|
b73c8a7ca6 | ||
|
|
da6de9b6b3 | ||
|
|
7610c5737f | ||
|
|
30b5930e91 | ||
|
|
c2c5cda6a2 | ||
|
|
351ed34750 | ||
|
|
be04d82018 | ||
|
|
8c15b6c54d | ||
|
|
cb83ae04bf | ||
|
|
e3b137e007 | ||
|
|
30def81a24 | ||
|
|
ed1f9a48af | ||
|
|
b1b82d7384 | ||
|
|
a37c95c8d0 | ||
|
|
aaee1916c6 | ||
|
|
c53c263a7e | ||
|
|
7d858c7ad5 | ||
|
|
ce8b31d0b9 | ||
|
|
2ac8886444 | ||
|
|
641b0d93ec | ||
|
|
c27a045581 | ||
|
|
953b51736f | ||
|
|
2f338e16af | ||
|
|
e9bd76c87a | ||
|
|
d5280efa32 | ||
|
|
8d99fc2a1e | ||
|
|
5c5bbcbaf0 | ||
|
|
e1b37a5b1e | ||
|
|
2a214a29d3 | ||
|
|
2a4f64c09d | ||
|
|
df0b228eb9 | ||
|
|
8052f86fc6 | ||
|
|
34bed60a89 | ||
|
|
ada03a0325 | ||
|
|
c7774c7068 | ||
|
|
1263fc888c | ||
|
|
858b6a838e | ||
|
|
b38b493d73 | ||
|
|
bb28cdf0c6 | ||
|
|
302881bfef | ||
|
|
9fdfd04a6f | ||
|
|
b38d01591f | ||
|
|
d78889ad20 | ||
|
|
6c02b8909f | ||
|
|
cb24269fc9 | ||
|
|
300c776a97 | ||
|
|
2faffa0507 | ||
|
|
d50df7cd6d | ||
|
|
a5debe1b2e | ||
|
|
da5dd0865d | ||
|
|
4af3346b6a | ||
|
|
fae9e58c4f | ||
|
|
000522e32f | ||
|
|
4baca64066 | ||
|
|
ac12d2e3c4 | ||
|
|
e8da10d005 | ||
|
|
5add51bcb8 | ||
|
|
08df44393f | ||
|
|
478705935c | ||
|
|
e64093d691 | ||
|
|
e28960dbbb | ||
|
|
8d95cf6d0d |
151
.github/workflows/test.yml
vendored
151
.github/workflows/test.yml
vendored
@@ -2,7 +2,37 @@ on: push
|
|||||||
name: Run acceptance tests
|
name: Run acceptance tests
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
use-connect-without-export-env:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- 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 && sleep 10
|
||||||
|
- name: Configure 1Password Connect
|
||||||
|
uses: ./configure # 1password/load-secrets-action/configure@<version>
|
||||||
|
with:
|
||||||
|
connect-host: localhost:8080
|
||||||
|
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
|
env:
|
||||||
|
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
|
||||||
|
- name: Assert test secret values
|
||||||
|
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 }}
|
||||||
|
run: ./tests/assert-env-set.sh
|
||||||
|
use-connect-with-export-env:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -18,34 +48,121 @@ jobs:
|
|||||||
connect-host: http://localhost:8080
|
connect-host: http://localhost:8080
|
||||||
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
- name: Load secrets
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
uses: ./ # 1password/load-secrets-action@<version>
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
env:
|
env:
|
||||||
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
|
SECRET: op://acceptance-tests/test-secret/password
|
||||||
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/test-section/password
|
SECRET_IN_SECTION: op://acceptance-tests/test-secret/test-section/password
|
||||||
UNMASKED_VALUE: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/test-section/username
|
MULTILINE_SECRET: op://acceptance-tests/multiline-secret/notesPlain
|
||||||
- name: Load multiline secret
|
|
||||||
uses: ./ # 1password/load-secrets-action@<version>
|
|
||||||
env:
|
|
||||||
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
|
|
||||||
- name: Print environment variables with masked secrets
|
|
||||||
run: printenv
|
|
||||||
- name: Assert test secret values
|
- name: Assert test secret values
|
||||||
run: ./tests/assert-env-set.sh
|
run: ./tests/assert-env-set.sh
|
||||||
- name: Remove secrets
|
- name: Remove secrets
|
||||||
uses: ./ # 1password/load-secrets-action@<version>
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
with:
|
with:
|
||||||
unset-previous: true
|
unset-previous: true
|
||||||
- name: Print environment variables with secrets removed
|
|
||||||
run: printenv
|
|
||||||
- name: Assert removed secrets
|
- name: Assert removed secrets
|
||||||
run: ./tests/assert-env-unset.sh
|
run: ./tests/assert-env-unset.sh
|
||||||
- name: Load secret again
|
use-connect-with-references-with-id:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- 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 && sleep 10
|
||||||
|
- name: Configure 1Password Connect
|
||||||
|
uses: ./configure # 1password/load-secrets-action/configure@<version>
|
||||||
|
with:
|
||||||
|
connect-host: http://localhost:8080
|
||||||
|
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
uses: ./ # 1password/load-secrets-action@<version>
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
env:
|
env:
|
||||||
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
|
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
|
||||||
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/test-section/password
|
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/Section_tco6nsqycj6jcbyx63h5isxcny/doxu3mhkozcznnk5vjrkpdqayy
|
||||||
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
|
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
|
||||||
- name: Print environment variables with masked secrets
|
- name: Assert test secret values
|
||||||
run: printenv
|
env:
|
||||||
- name: Assert test secret values again
|
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
||||||
|
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
||||||
|
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
||||||
|
run: ./tests/assert-env-set.sh
|
||||||
|
use-service-account-without-export-env:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
|
env:
|
||||||
|
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||||
|
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
|
||||||
|
- name: Assert test secret values
|
||||||
|
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 }}
|
||||||
|
run: ./tests/assert-env-set.sh
|
||||||
|
use-service-account-with-export-env:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
|
env:
|
||||||
|
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||||
|
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
|
||||||
|
- name: Assert test secret values
|
||||||
|
run: ./tests/assert-env-set.sh
|
||||||
|
use-service-account-with-references-with-id:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
|
env:
|
||||||
|
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||||
|
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
|
||||||
|
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/Section_tco6nsqycj6jcbyx63h5isxcny/doxu3mhkozcznnk5vjrkpdqayy
|
||||||
|
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
|
||||||
|
- name: Assert test secret values
|
||||||
|
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 }}
|
||||||
|
run: ./tests/assert-env-set.sh
|
||||||
|
run-on-macos-12:
|
||||||
|
runs-on: macos-12
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Load secrets
|
||||||
|
id: load_secrets
|
||||||
|
uses: ./ # 1password/load-secrets-action@<version>
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
|
env:
|
||||||
|
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||||
|
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
|
||||||
|
- name: Assert test secret values
|
||||||
|
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 }}
|
||||||
run: ./tests/assert-env-set.sh
|
run: ./tests/assert-env-set.sh
|
||||||
|
|||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
||||||
167
README.md
167
README.md
@@ -1,11 +1,37 @@
|
|||||||
# Load Secrets from 1Password - GitHub Action
|
# Load Secrets from 1Password - GitHub Action
|
||||||
|
|
||||||
The action to load secrets from [1Password Connect](https://1password.com/secrets/) into GitHub Actions.
|
This action loads secrets from 1Password into GitHub Actions using [1Password Connect](https://1password.com/secrets/).
|
||||||
|
|
||||||
|
Specify in your workflow YAML file which secrets from 1Password should be loaded into your job, and the action will make them available as environment variables for the next steps.
|
||||||
|
|
||||||
|
Read more on the [1Password Developer Portal](https://developer.1password.com/ci-cd/github-actions).
|
||||||
|
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Before you get started, you'll need to:
|
||||||
|
|
||||||
|
- [Deploy 1Password Connect](/docs/connect/get-started#step-2-deploy-1password-connect-server) in your infrastructure.
|
||||||
|
- Set the `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` environment variables to your Connect instance's credentials, so it'll be used to load secrets.
|
||||||
|
|
||||||
|
_Supported runners_: You can run the action on Mac and Linux runners. Windows is currently not supported.
|
||||||
|
|
||||||
Specify right from your workflow YAML which secrets from 1Password should be loaded into your job, and the action will make them available as environment variables for the next steps.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
You can configure the action to use your 1Password Connect instance.
|
||||||
|
|
||||||
|
If you provide `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` variables, the Connect instance will be used to load secrets. Make sure [1Password Connect](https://support.1password.com/secrets-automation/#step-2-deploy-a-1password-connect-server) is deployed in your infrastructure.
|
||||||
|
|
||||||
|
There are two ways that secrets can be loaded:
|
||||||
|
|
||||||
|
- [use the secrets from the action's ouput](#use-secrets-from-the-actions-output)
|
||||||
|
- [export secrets as environment variables](#export-secrets-as-environment-variables)
|
||||||
|
|
||||||
|
### Use secrets from the action's output
|
||||||
|
|
||||||
|
This method allows for you to use the loaded secrets as an output from the step: `steps.step-id.outputs.secret-name`. You will need to set an id for the step that uses this action to be able to access its outputs. For more details, , see [`outputs.<output_id>`](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_id).
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
on: push
|
on: push
|
||||||
jobs:
|
jobs:
|
||||||
@@ -15,16 +41,20 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Load secret
|
- name: Load secret
|
||||||
|
id: op-load-secret
|
||||||
uses: 1password/load-secrets-action@v1
|
uses: 1password/load-secrets-action@v1
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
env:
|
env:
|
||||||
OP_CONNECT_HOST: <Your Connect instance URL>
|
OP_CONNECT_HOST: <Your Connect instance URL>
|
||||||
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
SECRET: op://app-cicd/hello-world/secret
|
SECRET: op://app-cicd/hello-world/secret
|
||||||
|
|
||||||
- name: Print masked secret
|
- name: Print masked secret
|
||||||
run: echo "Secret: $SECRET"
|
run: echo "Secret: ${{ steps.op-load-secret.outputs.SECRET }}"
|
||||||
# Prints: Secret: ***
|
# Prints: Secret: ***
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Longer usage example</b></summary>
|
<summary><b>Longer usage example</b></summary>
|
||||||
|
|
||||||
@@ -41,13 +71,89 @@ jobs:
|
|||||||
- name: Configure 1Password Connect
|
- name: Configure 1Password Connect
|
||||||
uses: 1password/load-secrets-action/configure@v1
|
uses: 1password/load-secrets-action/configure@v1
|
||||||
with:
|
with:
|
||||||
# Persist the 1Password Connect URL for next steps. You can also persist
|
# Persist the 1Password Connect URL for next steps. You can also persist
|
||||||
# the Connect token using input `connect-token`, but keep in mind that
|
# the Connect token using input `connect-token`, but keep in mind that
|
||||||
|
# every single step in the job would then be able to access the token.
|
||||||
|
connect-host: https://1password.acme.com
|
||||||
|
|
||||||
|
- name: Load Docker credentials
|
||||||
|
id: load-docker-credentials
|
||||||
|
uses: 1password/load-secrets-action@v1
|
||||||
|
with:
|
||||||
|
export-env: false
|
||||||
|
env:
|
||||||
|
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
|
DOCKERHUB_USERNAME: op://app-cicd/docker/username
|
||||||
|
DOCKERHUB_TOKEN: op://app-cicd/docker/token
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ steps.load-docker-credentials.outputs.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ steps.load-docker-credentials.outputs.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: acme/app:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Export secrets as environment variables
|
||||||
|
|
||||||
|
This method, allows the action to access the loaded secrets as environment variables. These environment variables are accessible at a job level.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
hello-world:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Load secret
|
||||||
|
uses: 1password/load-secrets-action@v1
|
||||||
|
with:
|
||||||
|
# Export loaded secrets as environment variables
|
||||||
|
export-env: true
|
||||||
|
env:
|
||||||
|
OP_CONNECT_HOST: <Your Connect instance URL>
|
||||||
|
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
|
SECRET: op://app-cicd/hello-world/secret
|
||||||
|
|
||||||
|
- name: Print masked secret
|
||||||
|
run: echo "Secret: $SECRET"
|
||||||
|
# Prints: Secret: ***
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Longer usage example</b></summary>
|
||||||
|
|
||||||
|
```yml
|
||||||
|
on: push
|
||||||
|
name: Deploy app
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Configure 1Password Connect
|
||||||
|
uses: 1password/load-secrets-action/configure@v1
|
||||||
|
with:
|
||||||
|
# Persist the 1Password Connect URL for next steps. You can also persist
|
||||||
|
# the Connect token using input `connect-token`, but keep in mind that
|
||||||
# every single step in the job would then be able to access the token.
|
# every single step in the job would then be able to access the token.
|
||||||
connect-host: https://1password.acme.com
|
connect-host: https://1password.acme.com
|
||||||
|
|
||||||
- name: Load Docker credentials
|
- name: Load Docker credentials
|
||||||
uses: 1password/load-secrets-action@v1
|
uses: 1password/load-secrets-action@v1
|
||||||
|
with:
|
||||||
|
# Export loaded secrets as environment variables
|
||||||
|
export-env: true
|
||||||
env:
|
env:
|
||||||
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
DOCKERHUB_USERNAME: op://app-cicd/docker/username
|
DOCKERHUB_USERNAME: op://app-cicd/docker/username
|
||||||
@@ -71,6 +177,8 @@ jobs:
|
|||||||
- name: Load AWS credentials
|
- name: Load AWS credentials
|
||||||
uses: 1password/load-secrets-action@v1
|
uses: 1password/load-secrets-action@v1
|
||||||
with:
|
with:
|
||||||
|
# Export loaded secrets as environment variables
|
||||||
|
export-env: true
|
||||||
# Remove local copies of the Docker credentials, which are not needed anymore
|
# Remove local copies of the Docker credentials, which are not needed anymore
|
||||||
unset-previous: true
|
unset-previous: true
|
||||||
env:
|
env:
|
||||||
@@ -79,16 +187,18 @@ jobs:
|
|||||||
AWS_SECRET_ACCESS_KEY: op://app-cicd/aws/secret-access-key
|
AWS_SECRET_ACCESS_KEY: op://app-cicd/aws/secret-access-key
|
||||||
|
|
||||||
- name: Deploy app
|
- name: Deploy app
|
||||||
# This script expects AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be set, which was
|
# This script expects AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be set, which was
|
||||||
# done automatically by the step above
|
# done automatically by the step above
|
||||||
run: ./deploy.sh
|
run: ./deploy.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Action Inputs
|
## Action Inputs
|
||||||
|
|
||||||
| Name | Default | Description |
|
| Name | Default | Description |
|
||||||
|---|---|---|
|
| ---------------- | ------- | ---------------------------------------------------------------------------------- |
|
||||||
|
| `export-env` | `true` | Export the loaded secrets as environment variables |
|
||||||
| `unset-previous` | `false` | Whether to unset environment variables populated by 1Password in earlier job steps |
|
| `unset-previous` | `false` | Whether to unset environment variables populated by 1Password in earlier job steps |
|
||||||
|
|
||||||
## Secrets Reference Syntax
|
## Secrets Reference Syntax
|
||||||
@@ -100,23 +210,21 @@ These reference URIs have the following syntax:
|
|||||||
> `op://<vault>/<item>[/<section>]/<field>`
|
> `op://<vault>/<item>[/<section>]/<field>`
|
||||||
|
|
||||||
So for example, the reference URI `op://app-cicd/aws/secret-access-key` would be interpreted as:
|
So for example, the reference URI `op://app-cicd/aws/secret-access-key` would be interpreted as:
|
||||||
* **Vault:** `app-cicd`
|
|
||||||
* **Item:** `aws`
|
- **Vault:** `app-cicd`
|
||||||
* **Section:** default section
|
- **Item:** `aws`
|
||||||
* **Field:** `secret-access-key`
|
- **Section:** default section
|
||||||
|
- **Field:** `secret-access-key`
|
||||||
|
|
||||||
## Masking
|
## Masking
|
||||||
|
|
||||||
Similar to regular GitHub repository secrets, secret fields from 1Password will automatically be masked from the GitHub Actions logs too.
|
Similar to regular GitHub repository secrets, fields from 1Password will automatically be masked from the GitHub Actions logs too.
|
||||||
A 1Password field is considered 'secret' when it's marked as concealed (which shows as `•••••••` in the 1Password GUI) or when it's a secure note.
|
|
||||||
So if one of these values accidentally gets printed, it'll get replaced with `***`.
|
So if one of these values accidentally gets printed, it'll get replaced with `***`.
|
||||||
|
|
||||||
This means that a username or port field for example will not get masked.
|
## 1Password Configuration
|
||||||
|
|
||||||
## 1Password Connect Configuration
|
To use the action with Connect, you need to have a [1Password Connect](https://support.1password.com/secrets-automation/#step-1-set-up-a-secrets-automation-workflow) instance deployed somewhere.
|
||||||
|
To configure the action with your Connect host and token, set the `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` environment variables.
|
||||||
To use the action, you need to have a [1Password Connect](https://support.1password.com/secrets-automation/#step-1-set-up-a-secrets-automation-workflow) instance deployed somewhere.
|
|
||||||
To configure the action with your Connect URL and a Connect token, you can set the `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` variables.
|
|
||||||
|
|
||||||
If you're using the `load-secrets` action more than once in a single job, you can use the `configure` action to avoid duplicate configuration:
|
If you're using the `load-secrets` action more than once in a single job, you can use the `configure` action to avoid duplicate configuration:
|
||||||
|
|
||||||
@@ -133,7 +241,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
connect-host: <Your Connect instance URL>
|
connect-host: <Your Connect instance URL>
|
||||||
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
|
||||||
|
|
||||||
- name: Load secret
|
- name: Load secret
|
||||||
uses: 1password/load-secrets-action@v1
|
uses: 1password/load-secrets-action@v1
|
||||||
env:
|
env:
|
||||||
@@ -142,11 +249,23 @@ jobs:
|
|||||||
|
|
||||||
### `configure` Action Inputs
|
### `configure` Action Inputs
|
||||||
|
|
||||||
| Name | Default | Environment variable | Description |
|
| Name | Default | Environment variable | Description |
|
||||||
|---|---|---|---|
|
| ----------------------- | ------- | -------------------------- | -------------------------------------------------------- |
|
||||||
| `connect-host` | | `OP_CONNECT_HOST` | Your 1Password Connect instance URL |
|
| `connect-host` | | `OP_CONNECT_HOST` | Your 1Password Connect instance URL |
|
||||||
| `connect-token` | | `OP_CONNECT_TOKEN` | Token to authenticate to your 1Password Connect instance |
|
| `connect-token` | | `OP_CONNECT_TOKEN` | Token to authenticate to your 1Password Connect instance |
|
||||||
|
|
||||||
## Supported Runners
|
## Supported Runners
|
||||||
|
|
||||||
You can run the action on Linux and macOS runners. Windows is currently not supported.
|
You can run the action on Linux and macOS runners. Windows is currently not supported.
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
1Password requests you practice responsible disclosure if you discover a vulnerability.
|
||||||
|
|
||||||
|
Please file requests via [**BugCrowd**](https://bugcrowd.com/agilebits).
|
||||||
|
|
||||||
|
For information about security practices, please visit our [Security homepage](https://bugcrowd.com/agilebits).
|
||||||
|
|
||||||
|
## Getting help
|
||||||
|
|
||||||
|
If you find yourself stuck, visit our [**Support Page**](https://support.1password.com/) for help.
|
||||||
|
|||||||
11
action.yml
11
action.yml
@@ -8,10 +8,9 @@ inputs:
|
|||||||
unset-previous:
|
unset-previous:
|
||||||
description: Whether to unset environment variables populated by 1Password in earlier job steps
|
description: Whether to unset environment variables populated by 1Password in earlier job steps
|
||||||
default: false
|
default: false
|
||||||
|
export-env:
|
||||||
|
description: Export the secrets as environment variables
|
||||||
|
default: true
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: 'node16'
|
||||||
steps:
|
main: 'dist/index.js'
|
||||||
- run: |
|
|
||||||
export INPUT_UNSET_PREVIOUS=${{ inputs.unset-previous }}
|
|
||||||
${{ github.action_path }}/entrypoint.sh
|
|
||||||
shell: bash
|
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
name: Configure 1Password Connect
|
name: Configure 1Password Connect and service account
|
||||||
description: Persist 1Password Connect host and token for use in next steps.
|
description: Persist 1Password Connect host, token and service account for use in next steps.
|
||||||
author: 1Password
|
author: 1Password
|
||||||
inputs:
|
inputs:
|
||||||
connect-host:
|
connect-host:
|
||||||
description: Your 1Password Connect instance URL
|
description: Your 1Password Connect instance URL
|
||||||
connect-token:
|
connect-token:
|
||||||
description: Token to authenticate to your 1Password Connect instance
|
description: Token to authenticate to your 1Password Connect instance
|
||||||
|
service-account-token:
|
||||||
|
description: Your 1Password service account token
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
- run: |
|
- shell: bash
|
||||||
export INPUT_CONNECT_HOST=${{ inputs.connect-host }}
|
env:
|
||||||
export INPUT_CONNECT_TOKEN=${{ inputs.connect-token }}
|
INPUT_CONNECT_HOST: ${{ inputs.connect-host }}
|
||||||
|
INPUT_CONNECT_TOKEN: ${{ inputs.connect-token }}
|
||||||
|
INPUT_SERVICE_ACCOUNT_TOKEN: ${{ inputs.service-account-token }}
|
||||||
|
run: |
|
||||||
${{ github.action_path }}/entrypoint.sh
|
${{ github.action_path }}/entrypoint.sh
|
||||||
shell: bash
|
|
||||||
|
|||||||
@@ -14,3 +14,8 @@ OP_CONNECT_TOKEN="${INPUT_CONNECT_TOKEN:-$OP_CONNECT_TOKEN}"
|
|||||||
if [ -n "$OP_CONNECT_TOKEN" ]; then
|
if [ -n "$OP_CONNECT_TOKEN" ]; then
|
||||||
echo "OP_CONNECT_TOKEN=$OP_CONNECT_TOKEN" >> $GITHUB_ENV
|
echo "OP_CONNECT_TOKEN=$OP_CONNECT_TOKEN" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
OP_SERVICE_ACCOUNT_TOKEN="${INPUT_SERVICE_ACCOUNT_TOKEN:-$OP_SERVICE_ACCOUNT_TOKEN}"
|
||||||
|
if [ -n "$OP_SERVICE_ACCOUNT_TOKEN" ]; then
|
||||||
|
echo "OP_SERVICE_ACCOUNT_TOKEN=$OP_SERVICE_ACCOUNT_TOKEN" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|||||||
1954
dist/index.js
vendored
Normal file
1954
dist/index.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
201
entrypoint.sh
201
entrypoint.sh
@@ -2,132 +2,127 @@
|
|||||||
# shellcheck disable=SC2046,SC2001,SC2086
|
# shellcheck disable=SC2046,SC2001,SC2086
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ -z "$OP_CONNECT_TOKEN" ] || [ -z "$OP_CONNECT_HOST" ]; then
|
# Pass User-Agent Inforomation to the 1Password CLI
|
||||||
echo "\$OP_CONNECT_TOKEN and \$OP_CONNECT_HOST must be set"
|
export OP_INTEGRATION_NAME="1Password GitHub Action"
|
||||||
exit 1
|
export OP_INTEGRATION_ID="GHA"
|
||||||
fi
|
export OP_INTEGRATION_BUILDNUMBER="1010001"
|
||||||
|
|
||||||
|
readonly CONNECT="CONNECT"
|
||||||
|
readonly SERVICE_ACCOUNT="SERVICE_ACCOUNT"
|
||||||
|
|
||||||
|
auth_type=$CONNECT
|
||||||
managed_variables_var="OP_MANAGED_VARIABLES"
|
managed_variables_var="OP_MANAGED_VARIABLES"
|
||||||
IFS=',' read -r -a managed_variables <<< "$(printenv $managed_variables_var)"
|
IFS=','
|
||||||
|
|
||||||
|
if [[ "$OP_CONNECT_HOST" != "http://"* ]] && [[ "$OP_CONNECT_HOST" != "https://"* ]]; then
|
||||||
|
export OP_CONNECT_HOST="http://"$OP_CONNECT_HOST
|
||||||
|
fi
|
||||||
|
|
||||||
# Unset all secrets managed by 1Password if `unset-previous` is set.
|
# Unset all secrets managed by 1Password if `unset-previous` is set.
|
||||||
if [ "$INPUT_UNSET_PREVIOUS" == "true" ]; then
|
unset_prev_secrets() {
|
||||||
echo "Unsetting previous values..."
|
if [ "$INPUT_UNSET_PREVIOUS" == "true" ]; then
|
||||||
|
echo "Unsetting previous values..."
|
||||||
|
|
||||||
# Find environment variables that are managed by 1Password.
|
# Find environment variables that are managed by 1Password.
|
||||||
for env_var in "${managed_variables[@]}"; do
|
for env_var in "${managed_variables[@]}"; do
|
||||||
echo "Unsetting $env_var"
|
echo "Unsetting $env_var"
|
||||||
unset $env_var
|
unset $env_var
|
||||||
|
|
||||||
echo "$env_var=" >> $GITHUB_ENV
|
echo "$env_var=" >> $GITHUB_ENV
|
||||||
|
|
||||||
# Keep the masks, just in case.
|
# Keep the masks, just in case.
|
||||||
done
|
done
|
||||||
|
|
||||||
managed_variables=()
|
managed_variables=()
|
||||||
fi
|
|
||||||
|
|
||||||
# Iterate over environment varables to find 1Password references, load the secret values,
|
|
||||||
# and make them available as environment variables in the next steps.
|
|
||||||
IFS=$'\n'
|
|
||||||
for possible_ref in $(printenv | grep "=op://" | grep -v "^#"); do
|
|
||||||
env_var=$(echo "$possible_ref" | cut -d '=' -f1)
|
|
||||||
ref=$(printenv $env_var)
|
|
||||||
|
|
||||||
if [[ ! $ref == "op://"* ]]; then
|
|
||||||
echo "Not really a reference: $ref"
|
|
||||||
continue
|
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
path=$(echo $ref | sed -e "s/^op:\/\///")
|
# Install op-cli
|
||||||
if [ $(echo "$path" | tr -cd '/' | wc -c) -lt 2 ]; then
|
install_op_cli() {
|
||||||
echo "Expected path to be in format op://<vault>/<item>[/<section>]/<field>: $ref"
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||||
continue
|
curl -sSfLo op.zip "https://cache.agilebits.com/dist/1P/op2/pkg/v2.10.0-beta.02/op_linux_amd64_v2.10.0-beta.02.zip"
|
||||||
|
unzip -od /usr/local/bin/ op.zip && rm op.zip
|
||||||
|
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
curl -sSfLo op.pkg "https://cache.agilebits.com/dist/1P/op2/pkg/v2.10.0-beta.02/op_apple_universal_v2.10.0-beta.02.pkg"
|
||||||
|
sudo installer -pkg op.pkg -target /usr/local/bin/ && rm op.pkg
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo "Populating variable: $env_var"
|
populating_secret() {
|
||||||
|
ref=$(printenv $1)
|
||||||
|
|
||||||
vault=""
|
echo "Populating variable: $1"
|
||||||
item=""
|
secret_value=$(op read "$ref")
|
||||||
section=""
|
|
||||||
field=""
|
|
||||||
i=0
|
|
||||||
IFS="/"
|
|
||||||
for component in $path; do
|
|
||||||
((i+=1))
|
|
||||||
case "$i" in
|
|
||||||
1) vault=$component ;;
|
|
||||||
2) item=$component ;;
|
|
||||||
3) section=$component ;;
|
|
||||||
4) field=$component ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
unset IFS
|
|
||||||
|
|
||||||
# If field is not set, it may have wrongfully been interpreted as the section.
|
|
||||||
if [ -z "$field" ]; then
|
|
||||||
field="$section"
|
|
||||||
section=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Loading item $item from vault $vault..."
|
|
||||||
item_json=$(curl -sSf -H "Content-Type: application/json" -H "Authorization: Bearer $OP_CONNECT_TOKEN" "$OP_CONNECT_HOST/v1/vaults/$vault/items/$item")
|
|
||||||
jq_field_selector=".id == \"$field\" or .label == \"$field\""
|
|
||||||
jq_section_selector=".section == null"
|
|
||||||
|
|
||||||
# If the reference contains a section, edit the jq selector to take that into account.
|
|
||||||
if [ -n "$section" ]; then
|
|
||||||
echo "Looking for section: $section"
|
|
||||||
section_id=$(echo "$item_json" | jq -r ".sections[] | select(.id == \"$section\" or .label == \"$section\") | .id")
|
|
||||||
jq_section_selector=".section.id == \"$section_id\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
jq_secret_selector="$jq_section_selector and ($jq_field_selector)"
|
|
||||||
|
|
||||||
echo "Looking for field: $field"
|
|
||||||
secret_field_json=$(echo "$item_json" | jq -r "first(.fields[] | select($jq_secret_selector))")
|
|
||||||
|
|
||||||
field_type=$(echo "$secret_field_json" | jq -r '.type')
|
|
||||||
field_purpose=$(echo "$secret_field_json" | jq -r '.purpose')
|
|
||||||
secret_value=$(echo "$secret_field_json" | jq -r '.value')
|
|
||||||
|
|
||||||
if [ -z "$secret_value" ]; then
|
if [ -z "$secret_value" ]; then
|
||||||
echo "Could not find or access secret $ref"
|
echo "Could not find or access secret $ref"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If the field is marked as concealed or is a note, register a mask
|
# Register a mask for the secret to prevent accidental log exposure.
|
||||||
# for the secret to prevent accidental log exposure.
|
# To support multiline secrets, escape percent signs and add a mask per line.
|
||||||
if [ "$field_type" == "CONCEALED" ] || [ "$field_purpose" == "NOTES" ]; then
|
escaped_mask_value=$(echo "$secret_value" | sed -e 's/%/%25/g')
|
||||||
# To support multiline secrets, escape percent signs and add a mask per line.
|
IFS=$'\n'
|
||||||
escaped_mask_value=$(echo "$secret_value" | sed -e 's/%/%25/g')
|
for line in $escaped_mask_value; do
|
||||||
IFS=$'\n'
|
if [ "${#line}" -lt 3 ]; then
|
||||||
for line in $escaped_mask_value; do
|
# To avoid false positives and unreadable logs, omit mask for lines that are too short.
|
||||||
if [ "${#line}" -lt 3 ]; then
|
continue
|
||||||
# To avoid false positives and unreadable logs, omit mask for lines that are too short.
|
fi
|
||||||
continue
|
echo "::add-mask::$line"
|
||||||
fi
|
done
|
||||||
echo "::add-mask::$line"
|
unset IFS
|
||||||
done
|
|
||||||
unset IFS
|
if [ "$INPUT_EXPORT_ENV" == "true" ]; then
|
||||||
|
# To support multiline secrets, we'll use the heredoc syntax to populate the environment variables.
|
||||||
|
# As the heredoc identifier, we'll use a randomly generated 64-character string,
|
||||||
|
# so that collisions are practically impossible.
|
||||||
|
random_heredoc_identifier=$(openssl rand -hex 32)
|
||||||
|
|
||||||
|
{
|
||||||
|
# Populate env var, using heredoc syntax with generated identifier
|
||||||
|
echo "$env_var<<${random_heredoc_identifier}"
|
||||||
|
echo "$secret_value"
|
||||||
|
echo "${random_heredoc_identifier}"
|
||||||
|
} >> $GITHUB_ENV
|
||||||
|
echo "GITHUB_ENV: $(cat $GITHUB_ENV)"
|
||||||
|
|
||||||
|
else
|
||||||
|
# Prepare the secret_value to be outputed properly (especially multiline secrets)
|
||||||
|
secret_value=$(echo "$secret_value" | awk -v ORS='%0A' '1')
|
||||||
|
|
||||||
|
echo "::set-output name=$env_var::$secret_value"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# To support multiline secrets, we'll use the heredoc syntax to populate the environment variables.
|
|
||||||
# As the heredoc identifier, we'll use a randomly generated 64-character string,
|
|
||||||
# so that collisions are practically impossible.
|
|
||||||
random_heredoc_identifier=$(openssl rand -hex 16)
|
|
||||||
|
|
||||||
{
|
|
||||||
# Populate env var, using heredoc syntax with generated identifier
|
|
||||||
echo "$env_var<<${random_heredoc_identifier}"
|
|
||||||
echo "$secret_value"
|
|
||||||
echo "${random_heredoc_identifier}"
|
|
||||||
} >> $GITHUB_ENV
|
|
||||||
|
|
||||||
managed_variables+=("$env_var")
|
managed_variables+=("$env_var")
|
||||||
done
|
}
|
||||||
unset IFS
|
|
||||||
|
|
||||||
|
# Load environment variables using op cli. Iterate over them to find 1Password references, load the secret values,
|
||||||
|
# and make them available as environment variables in the next steps.
|
||||||
|
extract_secrets() {
|
||||||
|
IFS=$'\n'
|
||||||
|
for env_var in $(op env ls); do
|
||||||
|
populating_secret $env_var
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
read -r -a managed_variables <<< "$(printenv $managed_variables_var)"
|
||||||
|
|
||||||
|
if [ -z "$OP_CONNECT_TOKEN" ] || [ -z "$OP_CONNECT_HOST" ]; then
|
||||||
|
if [ -z "$OP_SERVICE_ACCOUNT_TOKEN" ]; then
|
||||||
|
echo "(\$OP_CONNECT_TOKEN and \$OP_CONNECT_HOST) or \$OP_SERVICE_ACCOUNT_TOKEN must be set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
auth_type=$SERVICE_ACCOUNT
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "Authenticated with %s \n" $auth_type
|
||||||
|
|
||||||
|
unset_prev_secrets
|
||||||
|
install_op_cli
|
||||||
|
extract_secrets
|
||||||
|
|
||||||
|
unset IFS
|
||||||
# Add extra env var that lists which secrets are managed by 1Password so that in a later step
|
# Add extra env var that lists which secrets are managed by 1Password so that in a later step
|
||||||
# these can be unset again.
|
# these can be unset again.
|
||||||
managed_variables_str=$(IFS=','; echo "${managed_variables[*]}")
|
managed_variables_str=$(IFS=','; echo "${managed_variables[*]}")
|
||||||
|
|||||||
156
package-lock.json
generated
Normal file
156
package-lock.json
generated
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
{
|
||||||
|
"name": "load-secrets-action",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "load-secrets-action",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.9.1",
|
||||||
|
"@actions/exec": "^1.1.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^18.7.14",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
|
"typescript": "^4.8.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/core": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/http-client": "^2.0.1",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/exec": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/io": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/http-client": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tunnel": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/io": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-Qi4JoKXjmE0O67wAOH6y0n26QXhMKMFo7GD/4IXNVcrtLjUlGjGuVys6pQgwF3ArfGTQu0XpqaNr0YhED2RaRA=="
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "18.7.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz",
|
||||||
|
"integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@vercel/ncc": {
|
||||||
|
"version": "0.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||||
|
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"ncc": "dist/ncc/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tunnel": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "4.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
|
||||||
|
"integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/core": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
||||||
|
"requires": {
|
||||||
|
"@actions/http-client": "^2.0.1",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@actions/exec": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||||
|
"requires": {
|
||||||
|
"@actions/io": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@actions/http-client": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||||
|
"requires": {
|
||||||
|
"tunnel": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@actions/io": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-Qi4JoKXjmE0O67wAOH6y0n26QXhMKMFo7GD/4IXNVcrtLjUlGjGuVys6pQgwF3ArfGTQu0XpqaNr0YhED2RaRA=="
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "18.7.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz",
|
||||||
|
"integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@vercel/ncc": {
|
||||||
|
"version": "0.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||||
|
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tunnel": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "4.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
|
||||||
|
"integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
package.json
Normal file
37
package.json
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "load-secrets-action",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"description": "Load Secrets from 1Password",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"directories": {
|
||||||
|
"test": "tests"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "ncc build src/index.ts"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/1Password/load-secrets-action.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"actions",
|
||||||
|
"1password",
|
||||||
|
"load secrets",
|
||||||
|
"connect"
|
||||||
|
],
|
||||||
|
"author": "1Password",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/1Password/load-secrets-action/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/1Password/load-secrets-action#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.9.1",
|
||||||
|
"@actions/exec": "^1.1.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^18.7.14",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
|
"typescript": "^4.8.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/index.ts
Normal file
21
src/index.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import * as exec from '@actions/exec';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
async function run(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const parentDir = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
|
// Get action inputs
|
||||||
|
process.env.INPUT_UNSET_PREVIOUS = core.getInput('unset-previous');
|
||||||
|
process.env.INPUT_EXPORT_ENV = core.getInput('export-env');
|
||||||
|
|
||||||
|
// Execute bash script
|
||||||
|
await exec.exec(`sh -c "` + parentDir + `/entrypoint.sh"`);
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
core.setFailed(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
13
tsconfig.json
Normal file
13
tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es6",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user