Use BuildPulse config

This commit is contained in:
Sid Dange 2025-02-20 10:37:40 -05:00
parent afeb29a6e0
commit 66bd59d4e8
10 changed files with 9110 additions and 2466 deletions

View File

@ -6,7 +6,7 @@
## About ## About
GitHub Action to set up Docker [Buildx](https://github.com/docker/buildx). [BuildPulse](https://buildpulse.io) GitHub Action to set up Docker [Buildx](https://github.com/docker/buildx). See [BuildPulse Runners](#BuildPulse-Runners) below.
This action will create and boot a builder that can be used in the following This action will create and boot a builder that can be used in the following
steps of your workflow if you're using Buildx or the [`build-push` action](https://github.com/docker/build-push-action/). steps of your workflow if you're using Buildx or the [`build-push` action](https://github.com/docker/build-push-action/).
@ -16,6 +16,12 @@ a [BuildKit](https://github.com/moby/buildkit) container.
![Screenshot](.github/setup-buildx-action.png) ![Screenshot](.github/setup-buildx-action.png)
## BuildPulse Runners
This action is modified to be used with [BuildPulse Runners](https://buildpulse.io/products/runners) - cut GitHub Actions cost in half, increase performance 2x.
This action sets up a builder configured to use the in-cluster docker registry for docker build image layer caching. This is useful for re-using cached layers between builds to speed up build times.
This action also enables [BuildPulse Runners] remote docker builders - powerful remote builders that decrease build times by 90%! See the [`buildpulse-builder`](#inputs) action input below.
___ ___
* [Usage](#usage) * [Usage](#usage)
@ -50,7 +56,7 @@ jobs:
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: buildpulse/setup-buildx-action@v3
``` ```
## Configuring your builder ## Configuring your builder
@ -87,6 +93,7 @@ The following inputs can be used as `step.with` keys:
| Name | Type | Default | Description | | Name | Type | Default | Description |
|------------------------------|----------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------|----------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `buildpulse-builder` | String | | BuildPulse Runners remote docker builder runner type ID |
| `version` | String | | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) | | `version` | String | | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) |
| `driver` | String | `docker-container` | Sets the [builder driver](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver) to be used | | `driver` | String | `docker-container` | Sets the [builder driver](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver) to be used |
| `driver-opts` | List | | List of additional [driver-specific options](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver-opt) (eg. `image=moby/buildkit:master`) | | `driver-opts` | List | | List of additional [driver-specific options](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver-opt) (eg. `image=moby/buildkit:master`) |
@ -96,6 +103,7 @@ The following inputs can be used as `step.with` keys:
| `install` | Bool | `false` | Sets up `docker build` command as an alias to `docker buildx` | | `install` | Bool | `false` | Sets up `docker build` command as an alias to `docker buildx` |
| `use` | Bool | `true` | Switch to this builder instance | | `use` | Bool | `true` | Switch to this builder instance |
| `endpoint` | String | | [Optional address for docker socket](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) or context from `docker context ls` | | `endpoint` | String | | [Optional address for docker socket](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) or context from `docker context ls` |
| `name` | String | | Optional override for the [docker builder name](https://docs.docker.com/reference/cli/docker/buildx/create/#name) |
| `platforms` | List/CSV | | Fixed [platforms](https://docs.docker.com/engine/reference/commandline/buildx_create/#platform) for current node. If not empty, values take priority over the detected ones. | | `platforms` | List/CSV | | Fixed [platforms](https://docs.docker.com/engine/reference/commandline/buildx_create/#platform) for current node. If not empty, values take priority over the detected ones. |
| `append` | YAML | | [Append additional nodes](https://docs.docker.com/build/ci/github-actions/configure-builder/#append-additional-nodes-to-the-builder) to the builder | | `append` | YAML | | [Append additional nodes](https://docs.docker.com/build/ci/github-actions/configure-builder/#append-additional-nodes-to-the-builder) to the builder |
| `cache-binary` | Bool | `true` | Cache buildx binary to GitHub Actions cache backend | | `cache-binary` | Bool | `true` | Cache buildx binary to GitHub Actions cache backend |

View File

@ -7,6 +7,12 @@ branding:
color: 'blue' color: 'blue'
inputs: inputs:
buildpulse-builder:
description: "BuildPulse Runners remote docker builder runner-type"
required: false
name:
description: 'Override generated builder name'
required: false
version: version:
description: 'Buildx version. (eg. v0.3.0)' description: 'Buildx version. (eg. v0.3.0)'
required: false required: false

87
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

909
dist/licenses.txt generated vendored

File diff suppressed because it is too large Load Diff

2
dist/sourcemap-register.js generated vendored

File diff suppressed because one or more lines are too long

7253
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
"dependencies": { "dependencies": {
"@actions/core": "^1.11.1", "@actions/core": "^1.11.1",
"@docker/actions-toolkit": "^0.56.0", "@docker/actions-toolkit": "^0.56.0",
"@iarna/toml": "^2.2.5",
"js-yaml": "^4.1.0" "js-yaml": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,16 +1,21 @@
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as TOML from '@iarna/toml';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker'; import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Util} from '@docker/actions-toolkit/lib/util'; import {Util} from '@docker/actions-toolkit/lib/util';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder'; import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder';
import path from 'path';
import * as fs from 'fs';
export const builderNodeEnvPrefix = 'BUILDER_NODE'; export const builderNodeEnvPrefix = 'BUILDER_NODE';
const defaultBuildkitdFlags = '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host'; const defaultBuildkitdFlags = '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host';
export interface Inputs { export interface Inputs {
buildpulseBuilder: string;
version: string; version: string;
name: string; name: string;
driver: string; driver: string;
@ -29,8 +34,9 @@ export interface Inputs {
export async function getInputs(): Promise<Inputs> { export async function getInputs(): Promise<Inputs> {
return { return {
buildpulseBuilder: core.getInput('buildpulse-builder'),
version: core.getInput('version'), version: core.getInput('version'),
name: await getBuilderName(core.getInput('driver') || 'docker-container'), name: core.getInput('name') || (await getBuilderName(core.getInput('driver') || 'docker-container')),
driver: core.getInput('driver') || 'docker-container', driver: core.getInput('driver') || 'docker-container',
driverOpts: Util.getInputList('driver-opts', {ignoreComma: true, quote: false}), driverOpts: Util.getInputList('driver-opts', {ignoreComma: true, quote: false}),
buildkitdFlags: core.getInput('buildkitd-flags'), buildkitdFlags: core.getInput('buildkitd-flags'),
@ -51,11 +57,23 @@ export async function getBuilderName(driver: string): Promise<string> {
} }
export async function getCreateArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> { export async function getCreateArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--driver', inputs.driver]; const remoteBuilderEnabled = inputs.buildpulseBuilder && inputs.buildpulseBuilder.length > 0;
// if remote builder is enabled, use 'kubernetes' driver
const driverInput = remoteBuilderEnabled ? 'kubernetes' : inputs.driver;
const args: Array<string> = ['create', '--name', inputs.name, '--driver', driverInput];
if (await toolkit.buildx.versionSatisfies('>=0.3.0')) { if (await toolkit.buildx.versionSatisfies('>=0.3.0')) {
await Util.asyncForEach(inputs.driverOpts, async (driverOpt: string) => { await Util.asyncForEach(inputs.driverOpts, async (driverOpt: string) => {
args.push('--driver-opt', driverOpt); args.push('--driver-opt', driverOpt);
}); });
// if remote builder is enabled, specify which runner type to use
if (remoteBuilderEnabled) {
const arch = inputs.buildpulseBuilder.includes('arm64') ? 'arm64' : 'x64';
const remoteBuilderDriverOpt = `nodeselector=eks.amazonaws.com/nodegroup=eks-nodegroup-${inputs.buildpulseBuilder},namespace=${inputs.buildpulseBuilder},image=796224758921.dkr.ecr.us-east-1.amazonaws.com/moby/buildkit:buildx-stable-1-${arch}`;
args.push('--driver-opt', remoteBuilderDriverOpt);
}
if (inputs.buildkitdFlags) { if (inputs.buildkitdFlags) {
args.push('--buildkitd-flags', inputs.buildkitdFlags); args.push('--buildkitd-flags', inputs.buildkitdFlags);
} else if (driverSupportsBuildkitdFlags(inputs.driver)) { } else if (driverSupportsBuildkitdFlags(inputs.driver)) {
@ -68,17 +86,53 @@ export async function getCreateArgs(inputs: Inputs, toolkit: Toolkit): Promise<A
if (inputs.use) { if (inputs.use) {
args.push('--use'); args.push('--use');
} }
// modify BuildKit config to include local registry
if (inputs.buildkitdConfig) { if (inputs.buildkitdConfig) {
args.push('--config', toolkit.buildkit.config.resolveFromFile(inputs.buildkitdConfig)); const newBuildkitConfigPath = await addClusterLocalRegistryConfigFile(inputs.buildkitdConfig);
} else if (inputs.buildkitdConfigInline) {
args.push('--config', toolkit.buildkit.config.resolveFromString(inputs.buildkitdConfigInline)); args.push('--config', toolkit.buildkit.config.resolveFromFile(newBuildkitConfigPath));
} else {
const startingConfig = inputs.buildkitdConfigInline || '';
const newBuildKitToml = addClusterLocalRegistryConfig(startingConfig);
args.push('--config', toolkit.buildkit.config.resolveFromString(newBuildKitToml));
} }
if (inputs.endpoint) { if (inputs.endpoint) {
args.push(inputs.endpoint); args.push(inputs.endpoint);
} }
return args; return args;
} }
async function addClusterLocalRegistryConfigFile(buildkitConfigPath: string): Promise<string> {
const configDir = path.dirname(buildkitConfigPath);
const newBuildkitConfigPath = path.join(configDir, 'buildpulse_buildkit.toml');
const buildkitConfigContent = await fs.promises.readFile(buildkitConfigPath, 'utf-8');
const newBuildkitConfigContent = addClusterLocalRegistryConfig(buildkitConfigContent);
await fs.promises.writeFile(newBuildkitConfigPath, newBuildkitConfigContent);
return newBuildkitConfigPath;
}
function addClusterLocalRegistryConfig(buildkitConfig: string): string {
const inlineToml = TOML.parse(buildkitConfig);
if (!inlineToml['registry']) {
inlineToml['registry'] = {};
}
const buildpulseDockerRegistry = process.env.BP_DOCKER_REGISTRY;
if (buildpulseDockerRegistry && buildpulseDockerRegistry.length && !inlineToml['registry'][buildpulseDockerRegistry]) {
inlineToml['registry'][buildpulseDockerRegistry] = {
http: true,
insecure: true
};
}
return TOML.stringify(inlineToml);
}
export async function getAppendArgs(inputs: Inputs, node: Node, toolkit: Toolkit): Promise<Array<string>> { export async function getAppendArgs(inputs: Inputs, node: Node, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--append']; const args: Array<string> = ['create', '--name', inputs.name, '--append'];
if (node.name) { if (node.name) {

3218
yarn.lock

File diff suppressed because it is too large Load Diff