bake: support composable attributes
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -22,7 +22,9 @@
|
|||||||
"linux/amd64"
|
"linux/amd64"
|
||||||
],
|
],
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker"
|
{
|
||||||
|
"type": "docker"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,9 @@
|
|||||||
"GO_VERSION": "1.20"
|
"GO_VERSION": "1.20"
|
||||||
},
|
},
|
||||||
"output": [
|
"output": [
|
||||||
"type=cacheonly"
|
{
|
||||||
|
"type": "cacheonly"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"validate-docs": {
|
"validate-docs": {
|
||||||
@@ -36,7 +38,9 @@
|
|||||||
},
|
},
|
||||||
"target": "validate",
|
"target": "validate",
|
||||||
"output": [
|
"output": [
|
||||||
"type=cacheonly"
|
{
|
||||||
|
"type": "cacheonly"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"validate-vendor": {
|
"validate-vendor": {
|
||||||
@@ -48,7 +52,9 @@
|
|||||||
},
|
},
|
||||||
"target": "validate",
|
"target": "validate",
|
||||||
"output": [
|
"output": [
|
||||||
"type=cacheonly"
|
{
|
||||||
|
"type": "cacheonly"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
38
__tests__/.fixtures/bake-03-default.json
Normal file
38
__tests__/.fixtures/bake-03-default.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"default": {
|
||||||
|
"context": ".",
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"cache-from": [
|
||||||
|
{
|
||||||
|
"scope": "build",
|
||||||
|
"type": "gha"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "user/repo:cache",
|
||||||
|
"type": "registry"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cache-to": [
|
||||||
|
{
|
||||||
|
"mode": "max",
|
||||||
|
"scope": "build",
|
||||||
|
"type": "gha"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "inline"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": [
|
||||||
|
{
|
||||||
|
"dest": "./release-out",
|
||||||
|
"type": "local"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "user/app",
|
||||||
|
"type": "registry"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
__tests__/.fixtures/bake-03.hcl
Normal file
28
__tests__/.fixtures/bake-03.hcl
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2024 actions-toolkit authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
target "default" {
|
||||||
|
cache-from = [
|
||||||
|
"type=gha,scope=build",
|
||||||
|
"user/repo:cache",
|
||||||
|
]
|
||||||
|
cache-to = [
|
||||||
|
"type=gha,scope=build,mode=max",
|
||||||
|
"type=inline"
|
||||||
|
]
|
||||||
|
output = [
|
||||||
|
"./release-out",
|
||||||
|
"type=registry,ref=user/app"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -29,7 +29,10 @@
|
|||||||
"windows/arm64"
|
"windows/arm64"
|
||||||
],
|
],
|
||||||
"output": [
|
"output": [
|
||||||
"./bin/build"
|
{
|
||||||
|
"dest": "./bin/build",
|
||||||
|
"type": "local"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,14 @@ describe('getDefinition', () => {
|
|||||||
['*.output=type=docker', '*.platform=linux/amd64'],
|
['*.output=type=docker', '*.platform=linux/amd64'],
|
||||||
undefined,
|
undefined,
|
||||||
path.join(fixturesDir, 'bake-01-overrides.json')
|
path.join(fixturesDir, 'bake-01-overrides.json')
|
||||||
]
|
],
|
||||||
|
[
|
||||||
|
[path.join(fixturesDir, 'bake-03.hcl')],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
undefined,
|
||||||
|
path.join(fixturesDir, 'bake-03-default.json')
|
||||||
|
],
|
||||||
])('given %p', async (files: string[], targets: string[], overrides: string[], execOptions: ExecOptions | undefined, out: string) => {
|
])('given %p', async (files: string[], targets: string[], overrides: string[], execOptions: ExecOptions | undefined, out: string) => {
|
||||||
const bake = new Bake();
|
const bake = new Bake();
|
||||||
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
||||||
@@ -103,7 +110,7 @@ describe('getDefinition', () => {
|
|||||||
targets: targets,
|
targets: targets,
|
||||||
overrides: overrides
|
overrides: overrides
|
||||||
}, execOptions)).toEqual(expectedDef);
|
}, execOptions)).toEqual(expectedDef);
|
||||||
});
|
}, 30 * 60 * 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hasLocalExporter', () => {
|
describe('hasLocalExporter', () => {
|
||||||
@@ -114,7 +121,9 @@ describe('hasLocalExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"build": {
|
"build": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker"
|
{
|
||||||
|
"type": "docker"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -136,7 +145,10 @@ describe('hasLocalExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"local": {
|
"local": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=local,dest=./release-out"
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dest": "./release-out"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -148,19 +160,10 @@ describe('hasLocalExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"tar": {
|
"tar": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=tar,dest=/tmp/image.tar"
|
{
|
||||||
]
|
"type": "tar",
|
||||||
},
|
"dest": "/tmp/image.tar"
|
||||||
}
|
}
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"tar": {
|
|
||||||
"output": [
|
|
||||||
'"type=tar","dest=/tmp/image.tar"',
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -172,19 +175,10 @@ describe('hasLocalExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"local": {
|
"local": {
|
||||||
"output": [
|
"output": [
|
||||||
'" type= local" , dest=./release-out',
|
{
|
||||||
]
|
"type": "local",
|
||||||
},
|
"dest": "."
|
||||||
}
|
}
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"local": {
|
|
||||||
"output": [
|
|
||||||
".",
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -204,7 +198,10 @@ describe('hasTarExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"reg": {
|
"reg": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=registry,ref=user/app"
|
{
|
||||||
|
"type": "registry",
|
||||||
|
"ref": "user/app"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -216,7 +213,9 @@ describe('hasTarExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"build": {
|
"build": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker"
|
{
|
||||||
|
"type": "docker"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -228,7 +227,10 @@ describe('hasTarExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"local": {
|
"local": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=local,dest=./release-out"
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dest": "./release-out"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -240,7 +242,10 @@ describe('hasTarExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"tar": {
|
"tar": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=tar,dest=/tmp/image.tar"
|
{
|
||||||
|
"type": "tar",
|
||||||
|
"dest": "/tmp/image.tar"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -252,20 +257,13 @@ describe('hasTarExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"multi": {
|
"multi": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker",
|
{
|
||||||
"type=tar,dest=/tmp/image.tar"
|
"type": "docker"
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
}
|
"type": "tar",
|
||||||
} as unknown as BakeDefinition,
|
"dest": "/tmp/image.tar"
|
||||||
true
|
}
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"tar": {
|
|
||||||
"output": [
|
|
||||||
'"type=tar","dest=/tmp/image.tar"',
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -277,19 +275,10 @@ describe('hasTarExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"local": {
|
"local": {
|
||||||
"output": [
|
"output": [
|
||||||
'" type= local" , dest=./release-out',
|
{
|
||||||
]
|
"type": "local",
|
||||||
},
|
"dest": "."
|
||||||
}
|
}
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"local": {
|
|
||||||
"output": [
|
|
||||||
".",
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -309,7 +298,10 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"reg": {
|
"reg": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=registry,ref=user/app"
|
{
|
||||||
|
"type": "registry",
|
||||||
|
"ref": "user/app"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -322,7 +314,9 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"build": {
|
"build": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker"
|
{
|
||||||
|
"type": "docker"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -335,8 +329,13 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"multi": {
|
"multi": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker",
|
{
|
||||||
"type=tar,dest=/tmp/image.tar"
|
"type": "docker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tar",
|
||||||
|
"dest": "/tmp/image.tar"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -349,20 +348,10 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"local": {
|
"local": {
|
||||||
"output": [
|
"output": [
|
||||||
'" type= local" , dest=./release-out'
|
{
|
||||||
]
|
"type": "local",
|
||||||
},
|
"dest": "./release-out"
|
||||||
}
|
}
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
false,
|
|
||||||
undefined
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"local": {
|
|
||||||
"output": [
|
|
||||||
"type=local,dest=./release-out"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -375,7 +364,10 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"tar": {
|
"tar": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=tar,dest=/tmp/image.tar"
|
{
|
||||||
|
"type": "tar",
|
||||||
|
"dest": "/tmp/image.tar"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -388,8 +380,13 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"multi": {
|
"multi": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker",
|
{
|
||||||
"type=tar,dest=/tmp/image.tar"
|
"type": "docker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tar",
|
||||||
|
"dest": "/tmp/image.tar"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -397,51 +394,14 @@ describe('hasDockerExporter', () => {
|
|||||||
true,
|
true,
|
||||||
undefined
|
undefined
|
||||||
],
|
],
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"tar": {
|
|
||||||
"output": [
|
|
||||||
'"type=tar","dest=/tmp/image.tar"'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
false,
|
|
||||||
undefined
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"tar": {
|
|
||||||
"output": [
|
|
||||||
'"type=tar","dest=/tmp/image.tar"'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
false,
|
|
||||||
undefined
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"target": {
|
|
||||||
"local": {
|
|
||||||
"output": [
|
|
||||||
'" type= local" , dest=./release-out'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} as unknown as BakeDefinition,
|
|
||||||
false,
|
|
||||||
undefined
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"target": {
|
"target": {
|
||||||
"build": {
|
"build": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker"
|
{
|
||||||
|
"type": "docker"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -454,7 +414,9 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"build": {
|
"build": {
|
||||||
"output": [
|
"output": [
|
||||||
"type=docker"
|
{
|
||||||
|
"type": "docker"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -467,7 +429,10 @@ describe('hasDockerExporter', () => {
|
|||||||
"target": {
|
"target": {
|
||||||
"build": {
|
"build": {
|
||||||
"output": [
|
"output": [
|
||||||
"."
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dest": "."
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,15 @@
|
|||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import {parse} from 'csv-parse/sync';
|
||||||
|
|
||||||
import {Build} from './build';
|
|
||||||
import {Buildx} from './buildx';
|
import {Buildx} from './buildx';
|
||||||
import {Context} from '../context';
|
import {Context} from '../context';
|
||||||
import {Exec} from '../exec';
|
import {Exec} from '../exec';
|
||||||
import {Util} from '../util';
|
import {Util} from '../util';
|
||||||
|
|
||||||
import {ExecOptions} from '@actions/exec';
|
import {ExecOptions} from '@actions/exec';
|
||||||
import {BakeDefinition} from '../types/buildx/bake';
|
import {BakeDefinition, CacheEntry, ExportEntry, SecretEntry, SSHEntry} from '../types/buildx/bake';
|
||||||
import {BuildMetadata} from '../types/buildx/build';
|
import {BuildMetadata} from '../types/buildx/build';
|
||||||
import {VertexWarning} from '../types/buildkit/client';
|
import {VertexWarning} from '../types/buildkit/client';
|
||||||
|
|
||||||
@@ -178,27 +178,197 @@ export class Bake {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static parseDefinition(dt: string): BakeDefinition {
|
public static parseDefinition(dt: string): BakeDefinition {
|
||||||
return <BakeDefinition>JSON.parse(dt);
|
const definition = <BakeDefinition>JSON.parse(dt);
|
||||||
|
|
||||||
|
// convert to composable attributes: https://github.com/docker/buildx/pull/2758
|
||||||
|
for (const name in definition.target) {
|
||||||
|
const target = definition.target[name];
|
||||||
|
if (target['cache-from'] && Array.isArray(target['cache-from'])) {
|
||||||
|
target['cache-from'] = target['cache-from'].map((item: string | CacheEntry): CacheEntry => {
|
||||||
|
return Bake.parseCacheEntry(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target['cache-to'] && Array.isArray(target['cache-to'])) {
|
||||||
|
target['cache-to'] = target['cache-to'].map((item: string | CacheEntry): CacheEntry => {
|
||||||
|
return Bake.parseCacheEntry(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target['output'] && Array.isArray(target['output'])) {
|
||||||
|
target['output'] = target['output'].map((item: string | ExportEntry): ExportEntry => {
|
||||||
|
return Bake.parseExportEntry(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target['secret'] && Array.isArray(target['secret'])) {
|
||||||
|
target['secret'] = target['secret'].map((item: string | SecretEntry): SecretEntry => {
|
||||||
|
return Bake.parseSecretEntry(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target['ssh'] && Array.isArray(target['ssh'])) {
|
||||||
|
target['ssh'] = target['ssh'].map((item: string | SSHEntry): SSHEntry => {
|
||||||
|
return Bake.parseSSHEntry(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseCacheEntry(item: CacheEntry | string): CacheEntry {
|
||||||
|
if (typeof item !== 'string') {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheEntry: CacheEntry = {type: ''};
|
||||||
|
const fields = parse(item, {
|
||||||
|
relaxColumnCount: true,
|
||||||
|
skipEmptyLines: true
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
if (fields.length === 1 && !fields[0].includes('=')) {
|
||||||
|
cacheEntry.type = 'registry';
|
||||||
|
cacheEntry.ref = fields[0];
|
||||||
|
return cacheEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const field of fields) {
|
||||||
|
const [key, value] = field
|
||||||
|
.toString()
|
||||||
|
.split(/(?<=^[^=]+?)=/)
|
||||||
|
.map((item: string) => item.trim());
|
||||||
|
switch (key) {
|
||||||
|
case 'type':
|
||||||
|
cacheEntry.type = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cacheEntry[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cacheEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseExportEntry(item: ExportEntry | string): ExportEntry {
|
||||||
|
if (typeof item !== 'string') {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exportEntry: ExportEntry = {type: ''};
|
||||||
|
const fields = parse(item, {
|
||||||
|
relaxColumnCount: true,
|
||||||
|
skipEmptyLines: true
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
if (fields.length === 1 && fields[0] === item && !item.startsWith('type=')) {
|
||||||
|
if (item !== '-') {
|
||||||
|
exportEntry.type = 'local';
|
||||||
|
exportEntry.dest = item;
|
||||||
|
return exportEntry;
|
||||||
|
}
|
||||||
|
exportEntry.type = 'tar';
|
||||||
|
exportEntry.dest = item;
|
||||||
|
return exportEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const field of fields) {
|
||||||
|
const [key, value] = field
|
||||||
|
.toString()
|
||||||
|
.split(/(?<=^[^=]+?)=/)
|
||||||
|
.map((item: string) => item.trim());
|
||||||
|
switch (key) {
|
||||||
|
case 'type':
|
||||||
|
exportEntry.type = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exportEntry[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exportEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseSecretEntry(item: SecretEntry | string): SecretEntry {
|
||||||
|
if (typeof item !== 'string') {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const secretEntry: SecretEntry = {};
|
||||||
|
const fields = parse(item, {
|
||||||
|
relaxColumnCount: true,
|
||||||
|
skipEmptyLines: true
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
let typ = '';
|
||||||
|
for (const field of fields) {
|
||||||
|
const [key, value] = field
|
||||||
|
.toString()
|
||||||
|
.split(/(?<=^[^=]+?)=/)
|
||||||
|
.map((item: string) => item.trim());
|
||||||
|
switch (key) {
|
||||||
|
case 'type':
|
||||||
|
typ = value;
|
||||||
|
break;
|
||||||
|
case 'id':
|
||||||
|
secretEntry.id = value;
|
||||||
|
break;
|
||||||
|
case 'source':
|
||||||
|
case 'src':
|
||||||
|
secretEntry.src = value;
|
||||||
|
break;
|
||||||
|
case 'env':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typ === 'env' && !secretEntry.env) {
|
||||||
|
secretEntry.env = secretEntry.src;
|
||||||
|
secretEntry.src = undefined;
|
||||||
|
}
|
||||||
|
return secretEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseSSHEntry(item: SSHEntry | string): SSHEntry {
|
||||||
|
if (typeof item !== 'string') {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sshEntry: SSHEntry = {};
|
||||||
|
const [key, value] = item.split('=', 2);
|
||||||
|
sshEntry.id = key;
|
||||||
|
if (value) {
|
||||||
|
sshEntry.paths = value.split(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sshEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static hasLocalExporter(def: BakeDefinition): boolean {
|
public static hasLocalExporter(def: BakeDefinition): boolean {
|
||||||
return Build.hasExporterType('local', Bake.exporters(def));
|
return Bake.hasExporterType('local', Bake.exporters(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static hasTarExporter(def: BakeDefinition): boolean {
|
public static hasTarExporter(def: BakeDefinition): boolean {
|
||||||
return Build.hasExporterType('tar', Bake.exporters(def));
|
return Bake.hasExporterType('tar', Bake.exporters(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static hasDockerExporter(def: BakeDefinition, load?: boolean): boolean {
|
public static hasDockerExporter(def: BakeDefinition, load?: boolean): boolean {
|
||||||
return load || Build.hasExporterType('docker', Bake.exporters(def));
|
return load || Bake.hasExporterType('docker', Bake.exporters(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static exporters(def: BakeDefinition): Array<string> {
|
public static hasExporterType(name: string, exporters: Array<ExportEntry>): boolean {
|
||||||
const exporters = new Array<string>();
|
for (const exporter of exporters) {
|
||||||
|
if (exporter.type == name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static exporters(def: BakeDefinition): Array<ExportEntry> {
|
||||||
|
const exporters = new Array<ExportEntry>();
|
||||||
for (const key in def.target) {
|
for (const key in def.target) {
|
||||||
const target = def.target[key];
|
const target = def.target[key];
|
||||||
if (target.output) {
|
if (target.output) {
|
||||||
exporters.push(...target.output);
|
for (const output of target.output) {
|
||||||
|
exporters.push(Bake.parseExportEntry(output));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return exporters;
|
return exporters;
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ export interface Target {
|
|||||||
description?: string;
|
description?: string;
|
||||||
args?: Record<string, string>;
|
args?: Record<string, string>;
|
||||||
attest?: Array<string>;
|
attest?: Array<string>;
|
||||||
'cache-from'?: Array<string>;
|
'cache-from'?: Array<CacheEntry> | Array<string>;
|
||||||
'cache-to'?: Array<string>;
|
'cache-to'?: Array<CacheEntry> | Array<string>;
|
||||||
call?: string;
|
call?: string;
|
||||||
context: string;
|
context: string;
|
||||||
contexts?: Record<string, string>;
|
contexts?: Record<string, string>;
|
||||||
@@ -39,13 +39,34 @@ export interface Target {
|
|||||||
labels?: Record<string, string>;
|
labels?: Record<string, string>;
|
||||||
'no-cache'?: boolean;
|
'no-cache'?: boolean;
|
||||||
'no-cache-filter'?: Array<string>;
|
'no-cache-filter'?: Array<string>;
|
||||||
output?: Array<string>;
|
output?: Array<ExportEntry> | Array<string>;
|
||||||
platforms?: Array<string>;
|
platforms?: Array<string>;
|
||||||
pull?: boolean;
|
pull?: boolean;
|
||||||
secret?: Array<string>;
|
secret?: Array<SecretEntry> | Array<string>;
|
||||||
'shm-size'?: string;
|
'shm-size'?: string;
|
||||||
ssh?: Array<string>;
|
ssh?: Array<SSHEntry> | Array<string>;
|
||||||
tags?: Array<string>;
|
tags?: Array<string>;
|
||||||
target?: string;
|
target?: string;
|
||||||
ulimits?: Array<string>;
|
ulimits?: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CacheEntry {
|
||||||
|
type: string;
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExportEntry {
|
||||||
|
type: string;
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecretEntry {
|
||||||
|
id?: string;
|
||||||
|
src?: string;
|
||||||
|
env?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SSHEntry {
|
||||||
|
id?: string;
|
||||||
|
paths?: Array<string>;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user