mirror of
https://github.com/docker/setup-buildx-action.git
synced 2024-11-22 20:08:43 +00:00
Merge pull request #106 from crazy-max/config-inline
Add `config-inline` input
This commit is contained in:
commit
94ab11c41e
13 changed files with 4751 additions and 16 deletions
12
.github/dependabot.yml
vendored
12
.github/dependabot.yml
vendored
|
@ -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"
|
||||||
|
|
27
.github/workflows/ci.yml
vendored
27
.github/workflows/ci.yml
vendored
|
@ -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:
|
||||||
|
|
70
README.md
70
README.md
|
@ -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');
|
||||||
|
|
3
__tests__/fixtures/buildkitd.toml
Normal file
3
__tests__/fixtures/buildkitd.toml
Normal file
|
@ -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
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"
|
||||||
|
|
Loading…
Reference in a new issue