Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authenticate the Gigalixir CLI with an API key instead of interactive login #48

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ inputs:
GIGALIXIR_USERNAME:
description: 'Your Gigalixir username'
required: true
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'
required: true
description: 'Your Gigalixir password -- either this option or GIGALIXIR_API_KEY should be used'
required: false
MIGRATIONS:
description: 'Configuration for migrations'
required: true
Expand Down
19 changes: 19 additions & 0 deletions bin/add-gigalixir-api-key
Original file line number Diff line number Diff line change
@@ -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
15 changes: 11 additions & 4 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1093,17 +1093,24 @@ 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)});

await core.group("Installing gigalixir", async () => {
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}`);
Expand Down
15 changes: 11 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,24 @@ 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)});

await core.group("Installing gigalixir", async () => {
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}`);
Expand Down