Skip to content

Commit

Permalink
Merge branch 'master' into login-test
Browse files Browse the repository at this point in the history
  • Loading branch information
CrazyMax authored and GitHub committed Oct 28, 2020
2 parents a5aa81a + ddf06e1 commit 767b2f4
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 47 deletions.
Binary file modified .github/docker-login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ___
* [GitLab](#gitlab)
* [Azure Container Registry (ACR)](#azure-container-registry-acr)
* [Google Container Registry (GCR)](#google-container-registry-gcr)
* [Google Artifact Registry (GAR)](#google-artifact-registry-gar)
* [AWS Elastic Container Registry (ECR)](#aws-elastic-container-registry-ecr)
* [Customizing](#customizing)
* [inputs](#inputs)
Expand Down Expand Up @@ -162,6 +163,11 @@ jobs:

### Google Container Registry (GCR)

> [Google Artifact Registry](#google-artifact-registry-gar) is the evolution of Google Container Registry. As a
> fully-managed service with support for both container images and non-container artifacts. If you currently use
> Google Container Registry, use the information [on this page](https://cloud.google.com/artifact-registry/docs/transition/transition-from-gcr)
> to learn about transitioning to Google Artifact Registry.

Use a service account with the ability to push to GCR and [configure access control](https://cloud.google.com/container-registry/docs/access-control).
Then create and download the JSON key for this service account and save content of `.json` file
[as a secret](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository)
Expand All @@ -187,6 +193,36 @@ jobs:
password: ${{ secrets.GCR_JSON_KEY }}
```

### Google Artifact Registry (GAR)

Use a service account with the ability to push to GAR and [configure access control](https://cloud.google.com/artifact-registry/docs/access-control).
Then create and download the JSON key for this service account and save content of `.json` file
[as a secret](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository)
called `GAR_JSON_KEY` in your GitHub repo. Ensure you set the username to `_json_key`.

```yaml
name: ci
on:
push:
branches: master
jobs:
login:
runs-on: ubuntu-latest
steps:
-
name: Login to GAR
uses: docker/login-action@v1
with:
registry: <location>-docker.pkg.dev
username: _json_key
password: ${{ secrets.GAR_JSON_KEY }}
```

> Replace `<location>` with the regional or multi-regional [location](https://cloud.google.com/artifact-registry/docs/repo-organize#locations)
> of the repository where the image is stored.

### AWS Elastic Container Registry (ECR)

Use an IAM user with the [ability to push to ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html).
Expand All @@ -213,6 +249,34 @@ jobs:
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
```

You can also use the [Configure AWS Credentials](https://github.com/aws-actions/configure-aws-credentials) action in
combination with this action:

```yaml
name: ci
on:
push:
branches: master
jobs:
login:
runs-on: ubuntu-latest
steps:
-
name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: <region>
-
name: Login to ECR
uses: docker/login-action@v1
with:
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
```

> Replace `<aws-account-number>` and `<region>` with their respective values.

## Customizing
Expand Down
15 changes: 1 addition & 14 deletions __tests__/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,7 @@ import osm = require('os');

import {getInputs} from '../src/context';

test('without username getInputs throws errors', async () => {
expect(() => {
getInputs();
}).toThrowError('Input required and not supplied: username');
});

test('without password getInputs throws errors', async () => {
process.env['INPUT_USERNAME'] = 'dbowie';
expect(() => {
getInputs();
}).toThrowError('Input required and not supplied: password');
});

test('with password and username getInputs does not error', async () => {
test('with password and username getInputs does not throw error', async () => {
process.env['INPUT_USERNAME'] = 'dbowie';
process.env['INPUT_PASSWORD'] = 'groundcontrol';
expect(() => {
Expand Down
20 changes: 3 additions & 17 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,15 @@ test('errors when not run on linux platform', async () => {
expect(coreSpy).toHaveBeenCalledWith('Only supported on linux platform');
});

test('errors without username', async () => {
test('errors without username and password', async () => {
const platSpy = jest.spyOn(osm, 'platform');
platSpy.mockImplementation(() => 'linux');

const coreSpy: jest.SpyInstance = jest.spyOn(core, 'setFailed');

await run();

expect(coreSpy).toHaveBeenCalledWith('Input required and not supplied: username');
});

test('errors without password', async () => {
const platSpy = jest.spyOn(osm, 'platform');
platSpy.mockImplementation(() => 'linux');

const coreSpy: jest.SpyInstance = jest.spyOn(core, 'setFailed');

const username: string = 'dbowie';
process.env[`INPUT_USERNAME`] = username;

await run();

expect(coreSpy).toHaveBeenCalledWith('Input required and not supplied: password');
expect(coreSpy).toHaveBeenCalledWith('Username and password required');
});

test('successful with username and password', async () => {
Expand Down Expand Up @@ -79,7 +65,7 @@ test('calls docker login', async () => {
const password: string = 'groundcontrol';
process.env[`INPUT_PASSWORD`] = password;

const registry: string = 'https://ghcr.io';
const registry: string = 'ghcr.io';
process.env[`INPUT_REGISTRY`] = registry;

const logout: string = 'true';
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ inputs:
required: false
username:
description: 'Username used to log against the Docker registry'
required: true
required: false
password:
description: 'Password or personal access token used to log against the Docker registry'
required: true
required: false
logout:
description: 'Log out from the Docker registry at the end of a job'
default: 'true'
Expand Down
15 changes: 8 additions & 7 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export interface Inputs {
export function getInputs(): Inputs {
return {
registry: core.getInput('registry'),
username: core.getInput('username', {required: true}),
password: core.getInput('password', {required: true}),
username: core.getInput('username'),
password: core.getInput('password'),
logout: core.getInput('logout')
};
}
12 changes: 7 additions & 5 deletions src/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ export async function logout(registry: string): Promise<void> {
}

export async function loginStandard(registry: string, username: string, password: string): Promise<void> {
let loginArgs: Array<string> = ['login', '--password-stdin'];
if (username) {
loginArgs.push('--username', username);
if (!username || !password) {
throw new Error('Username and password required');
}

let loginArgs: Array<string> = ['login', '--password-stdin'];
loginArgs.push('--username', username);
loginArgs.push(registry);

if (registry) {
Expand All @@ -44,8 +46,8 @@ export async function loginECR(registry: string, username: string, password: str
const region = await aws.getRegion(registry);
core.info(`💡 AWS ECR detected with ${region} region`);

process.env.AWS_ACCESS_KEY_ID = username;
process.env.AWS_SECRET_ACCESS_KEY = password;
process.env.AWS_ACCESS_KEY_ID = username || process.env.AWS_ACCESS_KEY_ID;
process.env.AWS_SECRET_ACCESS_KEY = password || process.env.AWS_SECRET_ACCESS_KEY;

core.info(`⬇️ Retrieving docker login command through AWS CLI ${cliVersion} (${cliPath})...`);
const loginCmd = await aws.getDockerLoginCmd(cliVersion, registry, region);
Expand Down

0 comments on commit 767b2f4

Please sign in to comment.