Add config-inline input

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2021-09-03 22:21:20 +02:00
parent ee7ac3140a
commit 34e94a5fed
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
13 changed files with 4751 additions and 16 deletions

@ -4,19 +4,15 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
time: "06:00"
timezone: "Europe/Paris"
labels: labels:
- ":game_die: dependencies" - "dependencies"
- ":robot: bot" - "bot"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
time: "06:00"
timezone: "Europe/Paris"
allow: allow:
- dependency-type: "production" - dependency-type: "production"
labels: labels:
- ":game_die: dependencies" - "dependencies"
- ":robot: bot" - "bot"

@ -278,6 +278,33 @@ jobs:
with: with:
context: . context: .
config-inline:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Create Dockerfile
run: |
cat > ./Dockerfile <<EOL
FROM alpine
EOL
-
name: Set up Docker Buildx
uses: ./
with:
buildkitd-flags: --debug
config-inline: |
debug = true
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
-
name: Build
uses: docker/build-push-action@v2
with:
context: .
with-qemu: with-qemu:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:

@ -21,6 +21,9 @@ ___
* [Quick start](#quick-start) * [Quick start](#quick-start)
* [With QEMU](#with-qemu) * [With QEMU](#with-qemu)
* [Install by default](#install-by-default) * [Install by default](#install-by-default)
* [BuildKit daemon configuration](#buildkit-daemon-configuration)
* [Registry mirror](#registry-mirror)
* [Max parallelism](#max-parallelism)
* [Customizing](#customizing) * [Customizing](#customizing)
* [inputs](#inputs) * [inputs](#inputs)
* [outputs](#outputs) * [outputs](#outputs)
@ -91,8 +94,6 @@ jobs:
### Install by default ### Install by default
Implemented with https://github.com/docker/buildx#setting-buildx-as-default-builder-in-docker-1903
```yaml ```yaml
name: ci name: ci
@ -117,6 +118,68 @@ jobs:
docker build . # will run buildx docker build . # will run buildx
``` ```
### BuildKit daemon configuration
You can provide a [BuildKit configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md)
to your builder if you're using the [`docker-container` driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver)
(default) with the `config` or `config-inline` inputs:
#### Registry mirror
You can configure a registry mirror using an inline block directly in your
workflow with the `config-inline` input:
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
```
#### Max parallelism
You can limit the parallelism of the BuildKit solver which is particularly
useful for low-powered machines.
You can use the `config-inline` input like the
previous example, or you can use a dedicated BuildKit config file from your
repo if you want with the `config` input:
```toml
# .github/buildkitd.toml
[worker.oci]
max-parallelism = 4
```
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
config: .github/buildkitd.toml
```
## Customizing ## Customizing
### inputs ### inputs
@ -133,6 +196,9 @@ Following inputs can be used as `step.with` keys
| `use` | Bool | Switch to this builder instance (default `true`) | | `use` | Bool | Switch to this builder instance (default `true`) |
| `endpoint` | String | [Optional address for docker socket](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#description) or context from `docker context ls` | | `endpoint` | String | [Optional address for docker socket](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#description) or context from `docker context ls` |
| `config` | String | [BuildKit config file](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#config) | | `config` | String | [BuildKit config file](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#config) |
| `config-inline` | String | Same as `config` but inline |
> `config` and `config-inline` are mutually exclusive.
> `CSV` type must be a newline-delimited string > `CSV` type must be a newline-delimited string
> ```yaml > ```yaml

@ -6,6 +6,8 @@ import * as context from '../src/context';
import * as semver from 'semver'; import * as semver from 'semver';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
const tmpNameSync = path.join('/tmp/.docker-setup-buildx-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
jest.spyOn(context, 'tmpDir').mockImplementation((): string => { jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep); const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep);
if (!fs.existsSync(tmpDir)) { if (!fs.existsSync(tmpDir)) {
@ -14,6 +16,10 @@ jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
return tmpDir; return tmpDir;
}); });
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return tmpNameSync;
});
describe('isAvailable', () => { describe('isAvailable', () => {
const execSpy: jest.SpyInstance = jest.spyOn(exec, 'getExecOutput'); const execSpy: jest.SpyInstance = jest.spyOn(exec, 'getExecOutput');
buildx.isAvailable(); buildx.isAvailable();
@ -119,3 +125,37 @@ describe('install', () => {
expect(fs.existsSync(buildxBin)).toBe(true); expect(fs.existsSync(buildxBin)).toBe(true);
}, 100000); }, 100000);
}); });
describe('getConfig', () => {
test.each([
['debug = true', false, 'debug = true', false],
[`notfound.toml`, true, '', true],
[
`${path.join(__dirname, 'fixtures', 'buildkitd.toml').split(path.sep).join(path.posix.sep)}`,
true,
`debug = true
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
`,
false
]
])('given %p config', async (val, file, exValue, invalid) => {
try {
let config: string;
if (file) {
config = await buildx.getConfigFile(val);
} else {
config = await buildx.getConfigInline(val);
}
expect(true).toBe(!invalid);
console.log(`config: ${config}`);
expect(config).toEqual(`${tmpNameSync}`);
const configValue = await fs.readFileSync(tmpNameSync, 'utf-8');
console.log(`configValue: ${configValue}`);
expect(configValue).toEqual(exValue);
} catch (err) {
console.log(err);
expect(true).toBe(invalid);
}
});
});

@ -11,6 +11,10 @@ jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
return tmpDir; return tmpDir;
}); });
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return path.join('/tmp/.docker-setup-buildx-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
});
describe('getInputList', () => { describe('getInputList', () => {
it('handles single line correctly', async () => { it('handles single line correctly', async () => {
await setInput('foo', 'bar'); await setInput('foo', 'bar');

@ -0,0 +1,3 @@
debug = true
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]

@ -35,6 +35,9 @@ inputs:
config: config:
description: 'BuildKit config file' description: 'BuildKit config file'
required: false required: false
config-inline:
description: 'Inline BuildKit config'
required: false
outputs: outputs:
name: name:

4565
dist/index.js generated vendored

File diff suppressed because it is too large Load Diff

@ -32,6 +32,7 @@
"@actions/http-client": "^1.0.11", "@actions/http-client": "^1.0.11",
"@actions/tool-cache": "^1.7.1", "@actions/tool-cache": "^1.7.1",
"semver": "^7.3.5", "semver": "^7.3.5",
"tmp": "^0.2.1",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"devDependencies": { "devDependencies": {

@ -19,6 +19,28 @@ export type Builder = {
node_platforms?: string; node_platforms?: string;
}; };
export async function getConfigInline(s: string): Promise<string> {
return getConfig(s, false);
}
export async function getConfigFile(s: string): Promise<string> {
return getConfig(s, true);
}
export async function getConfig(s: string, file: boolean): Promise<string> {
if (file) {
if (!fs.existsSync(s)) {
throw new Error(`config file ${s} not found`);
}
s = fs.readFileSync(s, {encoding: 'utf-8'});
}
const configFile = context.tmpNameSync({
tmpdir: context.tmpDir()
});
fs.writeFileSync(configFile, s);
return configFile;
}
export async function isAvailable(): Promise<Boolean> { export async function isAvailable(): Promise<Boolean> {
return await exec return await exec
.getExecOutput('docker', ['buildx'], { .getExecOutput('docker', ['buildx'], {

@ -1,6 +1,7 @@
import fs from 'fs'; import fs from 'fs';
import * as os from 'os'; import * as os from 'os';
import path from 'path'; import path from 'path';
import * as tmp from 'tmp';
import * as core from '@actions/core'; import * as core from '@actions/core';
import {issueCommand} from '@actions/core/lib/command'; import {issueCommand} from '@actions/core/lib/command';
@ -15,6 +16,10 @@ export function tmpDir(): string {
return _tmpDir; return _tmpDir;
} }
export function tmpNameSync(options?: tmp.TmpNameOptions): string {
return tmp.tmpNameSync(options);
}
export interface Inputs { export interface Inputs {
version: string; version: string;
driver: string; driver: string;
@ -24,6 +29,7 @@ export interface Inputs {
use: boolean; use: boolean;
endpoint: string; endpoint: string;
config: string; config: string;
configInline: string;
} }
export async function getInputs(): Promise<Inputs> { export async function getInputs(): Promise<Inputs> {
@ -35,7 +41,8 @@ export async function getInputs(): Promise<Inputs> {
install: core.getBooleanInput('install'), install: core.getBooleanInput('install'),
use: core.getBooleanInput('use'), use: core.getBooleanInput('use'),
endpoint: core.getInput('endpoint'), endpoint: core.getInput('endpoint'),
config: core.getInput('config') config: core.getInput('config'),
configInline: core.getInput('config-inline')
}; };
} }

@ -50,7 +50,9 @@ async function run(): Promise<void> {
createArgs.push(inputs.endpoint); createArgs.push(inputs.endpoint);
} }
if (inputs.config) { if (inputs.config) {
createArgs.push('--config', inputs.config); createArgs.push('--config', await buildx.getConfigFile(inputs.config));
} else if (inputs.configInline) {
createArgs.push('--config', await buildx.getConfigInline(inputs.configInline));
} }
await exec.exec('docker', createArgs); await exec.exec('docker', createArgs);
core.endGroup(); core.endGroup();

@ -3253,6 +3253,13 @@ throat@^5.0.0:
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
tmp@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
dependencies:
rimraf "^3.0.0"
tmpl@1.0.x: tmpl@1.0.x:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"