Add support for AWS Elastic Container Registry (ECR)

Add example for Google Container Registry (GCR)
This commit is contained in:
CrazyMax 2020-08-20 15:59:36 +02:00
parent e6dc03b339
commit f37c715508
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
5 changed files with 169 additions and 23 deletions

@ -83,3 +83,29 @@ jobs:
if: always() if: always()
run: | run: |
rm -f ${HOME}/.docker/config.json rm -f ${HOME}/.docker/config.json
ecr:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
logout:
- true
- false
steps:
-
name: Checkout
uses: actions/checkout@v2.3.1
-
name: Login to ECR
uses: ./
with:
registry: ${{ secrets.AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
logout: ${{ matrix.logout }}
-
name: Clear
if: always()
run: |
rm -f ${HOME}/.docker/config.json

@ -18,6 +18,8 @@ ___
* [DockerHub](#dockerhub) * [DockerHub](#dockerhub)
* [GitHub Package Registry](#github-package-registry) * [GitHub Package Registry](#github-package-registry)
* [GitLab](#gitlab) * [GitLab](#gitlab)
* [Google Container Registry (GCR)](#gitlab)
* [AWS Elastic Container Registry (ECR)](#gitlab)
* [Customizing](#customizing) * [Customizing](#customizing)
* [inputs](#inputs) * [inputs](#inputs)
* [Limitation](#limitation) * [Limitation](#limitation)
@ -34,7 +36,6 @@ name: ci
on: on:
push: push:
branches: master branches: master
tags:
jobs: jobs:
login: login:
@ -59,7 +60,6 @@ name: ci
on: on:
push: push:
branches: master branches: master
tags:
jobs: jobs:
login: login:
@ -85,7 +85,6 @@ name: ci
on: on:
push: push:
branches: master branches: master
tags:
jobs: jobs:
login: login:
@ -103,6 +102,67 @@ jobs:
password: ${{ secrets.GITLAB_PASSWORD }} password: ${{ secrets.GITLAB_PASSWORD }}
``` ```
### Google Container Registry (GCR)
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)
called `GCR_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: Checkout
uses: actions/checkout@v2
-
name: Login to GCR
uses: crazy-max/ghaction-docker-login@v1
with:
registry: gcr.io
username: _json_key
password: ${{ secrets.GCR_JSON_KEY }}
```
### 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).
Then create and download access keys and save `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` [as secrets](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository)
in your GitHub repo.
```yaml
name: ci
on:
push:
branches: master
jobs:
login:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Login to ECR
uses: crazy-max/ghaction-docker-login@v1
with:
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
```
> Replace `<aws-account-number>` and `<region>` with their respective values.
## Customizing ## Customizing
### inputs ### inputs

58
dist/index.js generated vendored

@ -953,6 +953,32 @@ class ExecState extends events.EventEmitter {
/***/ }), /***/ }),
/***/ 34:
/***/ (function(__unusedmodule, exports) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRegion = exports.isECR = void 0;
exports.isECR = (registry) => __awaiter(void 0, void 0, void 0, function* () {
return registry.includes('amazonaws');
});
exports.getRegion = (registry) => __awaiter(void 0, void 0, void 0, function* () {
return registry.substring(registry.indexOf('ecr.') + 4, registry.indexOf('.amazonaws'));
});
//# sourceMappingURL=ecr.js.map
/***/ }),
/***/ 87: /***/ 87:
/***/ (function(module) { /***/ (function(module) {
@ -1048,6 +1074,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const os = __importStar(__webpack_require__(87)); const os = __importStar(__webpack_require__(87));
const core = __importStar(__webpack_require__(470)); const core = __importStar(__webpack_require__(470));
const ecr = __importStar(__webpack_require__(34));
const exec = __importStar(__webpack_require__(807)); const exec = __importStar(__webpack_require__(807));
const stateHelper = __importStar(__webpack_require__(153)); const stateHelper = __importStar(__webpack_require__(153));
function run() { function run() {
@ -1062,17 +1089,30 @@ function run() {
stateHelper.setLogout(core.getInput('logout')); stateHelper.setLogout(core.getInput('logout'));
const username = core.getInput('username'); const username = core.getInput('username');
const password = core.getInput('password', { required: true }); const password = core.getInput('password', { required: true });
let loginArgs = ['login', '--password', password]; if (yield ecr.isECR(registry)) {
if (username) { const ecrRegion = yield ecr.getRegion(registry);
loginArgs.push('--username', username); process.env.AWS_ACCESS_KEY_ID = username;
process.env.AWS_SECRET_ACCESS_KEY = password;
yield exec.exec('aws', ['ecr', 'get-login', '--region', ecrRegion, '--no-include-email'], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
core.info('🎉 Login Succeeded!');
});
} }
loginArgs.push(registry); else {
yield exec.exec('docker', loginArgs, true).then(res => { let loginArgs = ['login', '--password', password];
if (res.stderr != '' && !res.success) { if (username) {
throw new Error(res.stderr); loginArgs.push('--username', username);
} }
core.info('🎉 Login Succeeded!'); loginArgs.push(registry);
}); yield exec.exec('docker', loginArgs, true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
core.info('🎉 Login Succeeded!');
});
}
} }
catch (error) { catch (error) {
core.setFailed(error.message); core.setFailed(error.message);

7
src/ecr.ts Normal file

@ -0,0 +1,7 @@
export const isECR = async (registry: string): Promise<boolean> => {
return registry.includes('amazonaws');
};
export const getRegion = async (registry: string): Promise<string> => {
return registry.substring(registry.indexOf('ecr.') + 4, registry.indexOf('.amazonaws'));
};

@ -1,5 +1,6 @@
import * as os from 'os'; import * as os from 'os';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as ecr from './ecr';
import * as exec from './exec'; import * as exec from './exec';
import * as stateHelper from './state-helper'; import * as stateHelper from './state-helper';
@ -17,18 +18,30 @@ async function run(): Promise<void> {
const username: string = core.getInput('username'); const username: string = core.getInput('username');
const password: string = core.getInput('password', {required: true}); const password: string = core.getInput('password', {required: true});
let loginArgs: Array<string> = ['login', '--password', password]; if (await ecr.isECR(registry)) {
if (username) { const ecrRegion = await ecr.getRegion(registry);
loginArgs.push('--username', username); process.env.AWS_ACCESS_KEY_ID = username;
} process.env.AWS_SECRET_ACCESS_KEY = password;
loginArgs.push(registry); await exec.exec('aws', ['ecr', 'get-login', '--region', ecrRegion, '--no-include-email'], true).then(res => {
if (res.stderr != '' && !res.success) {
await exec.exec('docker', loginArgs, true).then(res => { throw new Error(res.stderr);
if (res.stderr != '' && !res.success) { }
throw new Error(res.stderr); core.info('🎉 Login Succeeded!');
});
} else {
let loginArgs: Array<string> = ['login', '--password', password];
if (username) {
loginArgs.push('--username', username);
} }
core.info('🎉 Login Succeeded!'); loginArgs.push(registry);
});
await exec.exec('docker', loginArgs, true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
core.info('🎉 Login Succeeded!');
});
}
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }