Treat platforms and allow as a list

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2020-08-17 02:32:27 +02:00
parent 512e4e994b
commit 363c8ed24f
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
8 changed files with 5421 additions and 1749 deletions

32
.github/workflows/test.yml vendored Normal file

@ -0,0 +1,32 @@
name: test
on:
push:
branches:
- master
- v2-working-branch # remove when merged to master
pull_request:
branches:
- master
- v2-working-branch # remove when merged to master
jobs:
test:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2.3.1
-
name: Install
run: yarn install
-
name: Test
run: yarn run test
# -
# name: Upload coverage
# uses: codecov/codecov-action@v1.0.7
# if: success()
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# file: ./coverage/clover.xml

@ -180,22 +180,32 @@ Following inputs can be used as `step.with` keys
| `builder` | String | | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) | | `builder` | String | | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
| `context` | String | `.` | Build's context is the set of files located in the specified `PATH` or `URL` | | `context` | String | `.` | Build's context is the set of files located in the specified `PATH` or `URL` |
| `file` | String | `./Dockerfile` | Path to the Dockerfile. | | `file` | String | `./Dockerfile` | Path to the Dockerfile. |
| `build-args` | List | | Newline-delimited list of build-time variables | | `build-args` | List | | List of build-time variables |
| `labels` | List | | Newline-delimited list of metadata for an image | | `labels` | List | | List of metadata for an image |
| `tags` | List | | Newline-delimited list of tags | | `tags` | List | | List of tags |
| `pull` | Bool | `false` | Always attempt to pull a newer version of the image | | `pull` | Bool | `false` | Always attempt to pull a newer version of the image |
| `target` | String | | Sets the target stage to build | | `target` | String | | Sets the target stage to build |
| `allow` | String | | [Allow](https://github.com/docker/buildx#--allowentitlement) extra privileged entitlement (eg. network.host,security.insecure) | | `allow` | List | | List of [extra privileged entitlement](https://github.com/docker/buildx#--allowentitlement) (eg. `network.host,security.insecure`) |
| `no-cache` | Bool | `false` | Do not use cache when building the image | | `no-cache` | Bool | `false` | Do not use cache when building the image |
| `platforms` | String | | Comma-delimited list of [target platforms](https://github.com/docker/buildx#---platformvaluevalue) for build | | `platforms` | List | | List of [target platforms](https://github.com/docker/buildx#---platformvaluevalue) for build |
| `load` | Bool | `false` | [Load](https://github.com/docker/buildx#--load) is a shorthand for `--output=type=docker` | | `load` | Bool | `false` | [Load](https://github.com/docker/buildx#--load) is a shorthand for `--output=type=docker` |
| `push` | Bool | `false` | [Push](https://github.com/docker/buildx#--push) is a shorthand for `--output=type=registry` | | `push` | Bool | `false` | [Push](https://github.com/docker/buildx#--push) is a shorthand for `--output=type=registry` |
| `outputs` | List | | Newline-delimited list of [output destinations](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) (format: `type=local,dest=path`) | | `outputs` | List | | List of [output destinations](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) (format: `type=local,dest=path`) |
| `cache-from` | List | | Newline-delimited list of [external cache sources](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) (eg. `user/app:cache`, `type=local,src=path/to/dir`) | | `cache-from` | List | | List of [external cache sources](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) (eg. `user/app:cache`, `type=local,src=path/to/dir`) |
| `cache-to` | List | | Newline-delimited list of [cache export destinations](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) (eg. `user/app:cache`, `type=local,dest=path/to/dir`) | | `cache-to` | List | | List of [cache export destinations](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) (eg. `user/app:cache`, `type=local,dest=path/to/dir`) |
| `bake` | Bool | `false` | Use [bake](https://github.com/docker/buildx#buildx-bake-options-target) as the high-level build command | | `bake` | Bool | `false` | Use [bake](https://github.com/docker/buildx#buildx-bake-options-target) as the high-level build command |
| `bake-files` | List | | Newline-delimited list of [bake definition files](https://github.com/docker/buildx#file-definition) | | `bake-files` | List | | List of [bake definition files](https://github.com/docker/buildx#file-definition) |
| `bake-targets` | List | | Newline-delimited list of bake targets | | `bake-targets` | List | | List of bake targets |
> List type can be a comma or newline-delimited string
> ```yaml
> tags: name/app:latest,name/app:1.0.0
> ```
> ```yaml
> tags: |
> name/app:latest
> name/app:1.0.0
> ```
### outputs ### outputs

60
__tests__/context.test.ts Normal file

@ -0,0 +1,60 @@
import * as context from '../src/context';
describe('getInputList', () => {
it('handles single line correctly', async () => {
await setInput('foo', 'bar');
const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar']);
});
it('handles multiple lines correctly', async () => {
setInput('foo', 'bar\nbaz');
const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']);
});
it('handles comma correctly', async () => {
setInput('foo', 'bar,baz');
const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']);
});
it('handles different new lines correctly', async () => {
setInput('foo', 'bar\r\nbaz');
const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']);
});
it('handles different new lines and comma correctly', async () => {
setInput('foo', 'bar\r\nbaz,bat');
const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz', 'bat']);
});
});
describe('asyncForEach', () => {
it('executes async tasks sequentially', async () => {
const testValues = [1, 2, 3, 4, 5];
const results: number[] = [];
await context.asyncForEach(testValues, async value => {
results.push(value);
});
expect(results).toEqual(testValues);
});
});
// See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67
function getInputName(name: string): string {
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
}
function setInput(name: string, value: string): void {
process.env[getInputName(name)] = value;
}

3425
dist/index.js generated vendored

File diff suppressed because it is too large Load Diff

12
jest.config.js Normal file

@ -0,0 +1,12 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
setupFiles: ["dotenv/config"],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: false
}

@ -1,11 +1,12 @@
{ {
"name": "docker-build-push", "name": "docker-build-push",
"description": "GitHub Action to build and push Docker images", "description": "Build and push Docker images",
"main": "lib/main.js", "main": "lib/main.js",
"scripts": { "scripts": {
"build": "tsc && ncc build", "build": "tsc && ncc build",
"format": "prettier --write **/*.ts", "format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts", "format-check": "prettier --check **/*.ts",
"test": "jest --coverage",
"pre-checkin": "yarn run format && yarn run build" "pre-checkin": "yarn run format && yarn run build"
}, },
"repository": { "repository": {
@ -32,9 +33,15 @@
}, },
"devDependencies": { "devDependencies": {
"@types/git-url-parse": "^9.0.0", "@types/git-url-parse": "^9.0.0",
"@types/jest": "^26.0.3",
"@types/node": "^14.0.14", "@types/node": "^14.0.14",
"@zeit/ncc": "^0.22.3", "@zeit/ncc": "^0.22.3",
"dotenv": "^8.2.0",
"jest": "^26.1.0",
"jest-circus": "^26.1.0",
"jest-runtime": "^26.1.0",
"prettier": "^2.0.5", "prettier": "^2.0.5",
"ts-jest": "^26.1.1",
"typescript": "^3.9.5", "typescript": "^3.9.5",
"typescript-formatter": "^7.2.2" "typescript-formatter": "^7.2.2"
} }

@ -9,10 +9,10 @@ export interface Inputs {
tags: string[]; tags: string[];
pull: boolean; pull: boolean;
target: string; target: string;
allow: string; allow: string[];
noCache: boolean; noCache: boolean;
builder: string; builder: string;
platforms: string; platforms: string[];
load: boolean; load: boolean;
push: boolean; push: boolean;
outputs: string[]; outputs: string[];
@ -33,10 +33,10 @@ export async function getInputs(): Promise<Inputs> {
tags: await getInputList('tags'), tags: await getInputList('tags'),
pull: /true/i.test(core.getInput('pull')), pull: /true/i.test(core.getInput('pull')),
target: core.getInput('target'), target: core.getInput('target'),
allow: core.getInput('allow'), allow: await getInputList('allow'),
noCache: /true/i.test(core.getInput('no-cache')), noCache: /true/i.test(core.getInput('no-cache')),
builder: core.getInput('builder'), builder: core.getInput('builder'),
platforms: core.getInput('platforms'), platforms: await getInputList('platforms'),
load: /true/i.test(core.getInput('load')), load: /true/i.test(core.getInput('load')),
push: /true/i.test(core.getInput('push')), push: /true/i.test(core.getInput('push')),
outputs: await getInputList('outputs'), outputs: await getInputList('outputs'),
@ -125,10 +125,10 @@ async function getBuildArgs(inputs: Inputs): Promise<Array<string>> {
args.push('--target', inputs.target); args.push('--target', inputs.target);
} }
if (inputs.allow) { if (inputs.allow) {
args.push('--allow', inputs.allow); args.push('--allow', inputs.allow.join(','));
} }
if (inputs.platforms) { if (inputs.platforms) {
args.push('--platform', inputs.platforms); args.push('--platform', inputs.platforms.join(','));
} }
await asyncForEach(inputs.outputs, async output => { await asyncForEach(inputs.outputs, async output => {
args.push('--output', output); args.push('--output', output);
@ -145,7 +145,7 @@ async function getBuildArgs(inputs: Inputs): Promise<Array<string>> {
return args; return args;
} }
async function getInputList(name: string): Promise<string[]> { export async function getInputList(name: string): Promise<string[]> {
const items = core.getInput(name); const items = core.getInput(name);
if (items == '') { if (items == '') {
return []; return [];
@ -153,7 +153,7 @@ async function getInputList(name: string): Promise<string[]> {
return items.split(/\r?\n/).reduce<string[]>((acc, line) => acc.concat(line.split(',')).map(pat => pat.trim()), []); return items.split(/\r?\n/).reduce<string[]>((acc, line) => acc.concat(line.split(',')).map(pat => pat.trim()), []);
} }
const asyncForEach = async (array, callback) => { export const asyncForEach = async (array, callback) => {
for (let index = 0; index < array.length; index++) { for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array); await callback(array[index], index, array);
} }

3594
yarn.lock

File diff suppressed because it is too large Load Diff