From 44cd162a4e5da97b0192bb6d340579822873434e Mon Sep 17 00:00:00 2001 From: Nick Dichev Date: Wed, 20 Jul 2022 15:10:31 -0700 Subject: [PATCH 1/2] Add support for generating netrc file instead of logging in --- action.yml | 5 ++++- bin/add-gigalixir-api-key | 19 +++++++++++++++++++ dist/index.js | 15 +++++++++++---- index.js | 15 +++++++++++---- 4 files changed, 45 insertions(+), 9 deletions(-) create mode 100755 bin/add-gigalixir-api-key diff --git a/action.yml b/action.yml index 28b9253..c0e7002 100644 --- a/action.yml +++ b/action.yml @@ -14,9 +14,12 @@ inputs: GIGALIXIR_USERNAME: description: 'Your Gigalixir username' required: true + GIGALIXIR_API_KEY: + description: 'Your Gigalixir API key' + required: false GIGALIXIR_PASSWORD: description: 'Your Gigalixir password' - required: true + required: false MIGRATIONS: description: 'Configuration for migrations' required: true diff --git a/bin/add-gigalixir-api-key b/bin/add-gigalixir-api-key new file mode 100755 index 0000000..573999b --- /dev/null +++ b/bin/add-gigalixir-api-key @@ -0,0 +1,19 @@ +#! /usr/bin/env bash + +set -ev + +NETRC="$HOME/.netrc" + +touch $NETRC + +printf "machine api.gigalixir.com\n" >> $NETRC +printf "login %s\n" "$1" >> $NETRC +printf "password %s\n" "$2" >> $NETRC + +printf "\n">> $NETRC + +printf "machine git.gigalixir.com\n" >> $NETRC +printf "login %s\n" "$1" >> $NETRC +printf "password %s\n" "$2" >> $NETRC + +chmod 644 $NETRC diff --git a/dist/index.js b/dist/index.js index 798ca68..8c5fc4f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1093,7 +1093,8 @@ async function run() { const gigalixirApp = core.getInput('GIGALIXIR_APP', {required: true}); const gigalixirClean = core.getInput('GIGALIXIR_CLEAN', {required: false}); const gigalixirUsername = core.getInput('GIGALIXIR_USERNAME', {required: true}); - const gigalixirPassword = core.getInput('GIGALIXIR_PASSWORD', {required: true}); + const gigalixirApiKey = core.getInput('GIGALIXIR_API_KEY', {required: false}); + const gigalixirPassword = core.getInput('GIGALIXIR_PASSWORD', {required: false}); const migrations = core.getInput('MIGRATIONS', {required: true}); const sshPrivateKey = core.getInput('SSH_PRIVATE_KEY', {required: JSON.parse(migrations)}); @@ -1101,9 +1102,15 @@ async function run() { await exec.exec('pip3 install gigalixir') }); - await core.group("Logging in to gigalixir", async () => { - await exec.exec(`gigalixir login -e "${gigalixirUsername}" -y -p "${gigalixirPassword}"`) - }); + if (gigalixirPassword) { + await core.group("Logging in to gigalixir", async () => { + await exec.exec(`gigalixir login -e "${gigalixirUsername}" -y -p "${gigalixirPassword}"`) + }); + } else if (gigalixirApiKey) { + await core.group("Setting up ~/.netrc", async () => { + await exec.exec(path.join(__dirname, "../bin/add-gigalixir-api-key"), [gigalixirUsername, gigalixirApiKey]); + }); + } await core.group("Setting git remote for gigalixir", async () => { await exec.exec(`gigalixir git:remote ${gigalixirApp}`); diff --git a/index.js b/index.js index 7d05eef..6e85557 100644 --- a/index.js +++ b/index.js @@ -85,7 +85,8 @@ async function run() { const gigalixirApp = core.getInput('GIGALIXIR_APP', {required: true}); const gigalixirClean = core.getInput('GIGALIXIR_CLEAN', {required: false}); const gigalixirUsername = core.getInput('GIGALIXIR_USERNAME', {required: true}); - const gigalixirPassword = core.getInput('GIGALIXIR_PASSWORD', {required: true}); + const gigalixirApiKey = core.getInput('GIGALIXIR_API_KEY', {required: false}); + const gigalixirPassword = core.getInput('GIGALIXIR_PASSWORD', {required: false}); const migrations = core.getInput('MIGRATIONS', {required: true}); const sshPrivateKey = core.getInput('SSH_PRIVATE_KEY', {required: JSON.parse(migrations)}); @@ -93,9 +94,15 @@ async function run() { await exec.exec('pip3 install gigalixir') }); - await core.group("Logging in to gigalixir", async () => { - await exec.exec(`gigalixir login -e "${gigalixirUsername}" -y -p "${gigalixirPassword}"`) - }); + if (gigalixirPassword) { + await core.group("Logging in to gigalixir", async () => { + await exec.exec(`gigalixir login -e "${gigalixirUsername}" -y -p "${gigalixirPassword}"`) + }); + } else if (gigalixirApiKey) { + await core.group("Setting up ~/.netrc", async () => { + await exec.exec(path.join(__dirname, "../bin/add-gigalixir-api-key"), [gigalixirUsername, gigalixirApiKey]); + }); + } await core.group("Setting git remote for gigalixir", async () => { await exec.exec(`gigalixir git:remote ${gigalixirApp}`); From 07370bdd90b267b3b6ec2c066cbeb43d429ff4ef Mon Sep 17 00:00:00 2001 From: Nick Dichev Date: Thu, 21 Jul 2022 09:17:44 -0700 Subject: [PATCH 2/2] Update documentation about the difference between password and api key auth --- README.md | 11 ++++++++++- action.yml | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f44b167..9bf8ad2 100644 --- a/README.md +++ b/README.md @@ -32,11 +32,20 @@ deploy: GIGALIXIR_APP: my-gigalixir-app # Feel free to also put this in your secrets GIGALIXIR_CLEAN: true # defaults to false GIGALIXIR_USERNAME: ${{ secrets.GIGALIXIR_USERNAME }} - GIGALIXIR_PASSWORD: ${{ secrets.GIGALIXIR_PASSWORD }} + GIGALIXIR_PASSWORD: ${{ secrets.GIGALIXIR_PASSWORD }} # Use GIGALIXIR_PASSWORD or GIGALIXIR_API_KEY + GIGALIXIR_API_KEY: ${{ secrets.GIGALIXIR_API_KEY }} # Use GIGALIXIR_PASSWORD or GIGALIXIR_API_KEY MIGRATIONS: false # defaults to true SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} ``` +## Gigalixir CLI Authentication + +The default strategy for authenticating the Gigalixir CLI logs in with `GIGALIXIR_USERNAME` and `GIGALIXIR_PASSWORD`. However, if MFA is enabled on the account the login prompt becomes interactive (asking for the MFA token). + +However, the authentication actually shoves an API key into your `~/.netrc` which the [CLI uses](https://gigalixir.readthedocs.io/en/latest/cli.html?highlight=netrc#authentication) when executing commands. You can find your API key on the Gigalixir dashboard under Account > API Key. + +By supplying `GIGALIXIR_API_KEY` instead of `GIGALIXIR_PASSWORD` you can enable MFA on the account associated with deploying the application and still use this action! See the [Gigalixir documentation](https://gigalixir.readthedocs.io/en/latest/account.html?highlight=api%20key#how-to-use-multi-factor-authentication) for the steps to enable MFA. + ## Migrations Currently running migrations is only supported when your app is deployed as a mix release. diff --git a/action.yml b/action.yml index c0e7002..3ba4914 100644 --- a/action.yml +++ b/action.yml @@ -15,10 +15,10 @@ inputs: description: 'Your Gigalixir username' required: true GIGALIXIR_API_KEY: - description: 'Your Gigalixir API key' + description: 'Your Gigalixir API key -- either this option or GIGALIXIR_PASSWORD should be used' required: false GIGALIXIR_PASSWORD: - description: 'Your Gigalixir password' + description: 'Your Gigalixir password -- either this option or GIGALIXIR_API_KEY should be used' required: false MIGRATIONS: description: 'Configuration for migrations'