make Context static
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -18,7 +18,6 @@ import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
|||||||
|
|
||||||
import {BuildKit} from '../../src/buildkit/buildkit';
|
import {BuildKit} from '../../src/buildkit/buildkit';
|
||||||
import {Builder} from '../../src/buildx/builder';
|
import {Builder} from '../../src/buildx/builder';
|
||||||
import {Context} from '../../src/context';
|
|
||||||
|
|
||||||
import {BuilderInfo} from '../../src/types/builder';
|
import {BuilderInfo} from '../../src/types/builder';
|
||||||
|
|
||||||
@@ -47,13 +46,9 @@ jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<Bu
|
|||||||
|
|
||||||
describe('getVersion', () => {
|
describe('getVersion', () => {
|
||||||
it('valid', async () => {
|
it('valid', async () => {
|
||||||
const builder = new Builder({
|
const builder = new Builder();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const builderInfo = await builder.inspect('builder2');
|
const builderInfo = await builder.inspect('builder2');
|
||||||
const buildkit = new BuildKit({
|
const buildkit = new BuildKit();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const version = await buildkit.getVersion(builderInfo.nodes[0]);
|
const version = await buildkit.getVersion(builderInfo.nodes[0]);
|
||||||
expect(version).toBe('v0.11.0');
|
expect(version).toBe('v0.11.0');
|
||||||
});
|
});
|
||||||
@@ -64,9 +59,7 @@ describe('satisfies', () => {
|
|||||||
['builder2', '>=0.10.0', true],
|
['builder2', '>=0.10.0', true],
|
||||||
['builder2', '>0.11.0', false]
|
['builder2', '>0.11.0', false]
|
||||||
])('given %p', async (builderName, range, expected) => {
|
])('given %p', async (builderName, range, expected) => {
|
||||||
const buildkit = new BuildKit({
|
const buildkit = new BuildKit();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected);
|
expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,13 +27,14 @@ const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
|||||||
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildkit-config-jest');
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildkit-config-jest');
|
||||||
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
|
||||||
jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => {
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
if (!fs.existsSync(tmpDir)) {
|
if (!fs.existsSync(tmpDir)) {
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
}
|
}
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
});
|
});
|
||||||
jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => {
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
return tmpName;
|
return tmpName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -60,9 +61,7 @@ describe('resolve', () => {
|
|||||||
]
|
]
|
||||||
])('given %p config', async (val, file, exValue, error: Error) => {
|
])('given %p config', async (val, file, exValue, error: Error) => {
|
||||||
try {
|
try {
|
||||||
const buildkit = new BuildKit({
|
const buildkit = new BuildKit();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
let config: string;
|
let config: string;
|
||||||
if (file) {
|
if (file) {
|
||||||
config = buildkit.config.resolveFromFile(val);
|
config = buildkit.config.resolveFromFile(val);
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import {Builder} from '../../src/buildx/builder';
|
import {Builder} from '../../src/buildx/builder';
|
||||||
import {Context} from '../../src/context';
|
|
||||||
|
|
||||||
import {BuilderInfo} from '../../src/types/builder';
|
import {BuilderInfo} from '../../src/types/builder';
|
||||||
|
|
||||||
@@ -50,9 +49,7 @@ jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<Bu
|
|||||||
|
|
||||||
describe('inspect', () => {
|
describe('inspect', () => {
|
||||||
it('valid', async () => {
|
it('valid', async () => {
|
||||||
const builder = new Builder({
|
const builder = new Builder();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const builderInfo = await builder.inspect('');
|
const builderInfo = await builder.inspect('');
|
||||||
expect(builderInfo).not.toBeUndefined();
|
expect(builderInfo).not.toBeUndefined();
|
||||||
expect(builderInfo.name).not.toEqual('');
|
expect(builderInfo.name).not.toEqual('');
|
||||||
|
|||||||
@@ -30,13 +30,14 @@ import {Cert} from '../../src/types/buildx';
|
|||||||
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest');
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest');
|
||||||
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
|
||||||
jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => {
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
if (!fs.existsSync(tmpDir)) {
|
if (!fs.existsSync(tmpDir)) {
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
}
|
}
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
});
|
});
|
||||||
jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => {
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
return tmpName;
|
return tmpName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -92,7 +93,6 @@ describe('isAvailable', () => {
|
|||||||
it('docker cli', async () => {
|
it('docker cli', async () => {
|
||||||
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx({
|
||||||
context: new Context(),
|
|
||||||
standalone: false
|
standalone: false
|
||||||
});
|
});
|
||||||
await buildx.isAvailable();
|
await buildx.isAvailable();
|
||||||
@@ -105,7 +105,6 @@ describe('isAvailable', () => {
|
|||||||
it('standalone', async () => {
|
it('standalone', async () => {
|
||||||
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx({
|
||||||
context: new Context(),
|
|
||||||
standalone: true
|
standalone: true
|
||||||
});
|
});
|
||||||
await buildx.isAvailable();
|
await buildx.isAvailable();
|
||||||
@@ -121,7 +120,6 @@ describe('printInspect', () => {
|
|||||||
it('prints builder2 instance', async () => {
|
it('prints builder2 instance', async () => {
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
const execSpy = jest.spyOn(exec, 'exec');
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx({
|
||||||
context: new Context(),
|
|
||||||
standalone: true
|
standalone: true
|
||||||
});
|
});
|
||||||
await buildx.printInspect('builder2').catch(() => {
|
await buildx.printInspect('builder2').catch(() => {
|
||||||
@@ -137,7 +135,6 @@ describe('printVersion', () => {
|
|||||||
it('docker cli', async () => {
|
it('docker cli', async () => {
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
const execSpy = jest.spyOn(exec, 'exec');
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx({
|
||||||
context: new Context(),
|
|
||||||
standalone: false
|
standalone: false
|
||||||
});
|
});
|
||||||
await buildx.printVersion();
|
await buildx.printVersion();
|
||||||
@@ -148,7 +145,6 @@ describe('printVersion', () => {
|
|||||||
it('standalone', async () => {
|
it('standalone', async () => {
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
const execSpy = jest.spyOn(exec, 'exec');
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx({
|
||||||
context: new Context(),
|
|
||||||
standalone: true
|
standalone: true
|
||||||
});
|
});
|
||||||
await buildx.printVersion();
|
await buildx.printVersion();
|
||||||
@@ -160,9 +156,7 @@ describe('printVersion', () => {
|
|||||||
|
|
||||||
describe('version', () => {
|
describe('version', () => {
|
||||||
it('valid', async () => {
|
it('valid', async () => {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(semver.valid(await buildx.version)).not.toBeUndefined();
|
expect(semver.valid(await buildx.version)).not.toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -184,9 +178,7 @@ describe('versionSatisfies', () => {
|
|||||||
['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false],
|
['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false],
|
||||||
['f117971', '>0.6.0', true]
|
['f117971', '>0.6.0', true]
|
||||||
])('given %p', async (version, range, expected) => {
|
])('given %p', async (version, range, expected) => {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(await buildx.versionSatisfies(range, version)).toBe(expected);
|
expect(await buildx.versionSatisfies(range, version)).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,13 +32,14 @@ const metadata = `{
|
|||||||
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
|
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => {
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
if (!fs.existsSync(tmpDir)) {
|
if (!fs.existsSync(tmpDir)) {
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
}
|
}
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
});
|
});
|
||||||
jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => {
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
return tmpName;
|
return tmpName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,9 +53,7 @@ afterEach(() => {
|
|||||||
|
|
||||||
describe('resolveBuildImageID', () => {
|
describe('resolveBuildImageID', () => {
|
||||||
it('matches', async () => {
|
it('matches', async () => {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
||||||
const imageIDFile = buildx.inputs.getBuildImageIDFilePath();
|
const imageIDFile = buildx.inputs.getBuildImageIDFilePath();
|
||||||
await fs.writeFileSync(imageIDFile, imageID);
|
await fs.writeFileSync(imageIDFile, imageID);
|
||||||
@@ -65,9 +64,7 @@ describe('resolveBuildImageID', () => {
|
|||||||
|
|
||||||
describe('resolveBuildMetadata', () => {
|
describe('resolveBuildMetadata', () => {
|
||||||
it('matches', async () => {
|
it('matches', async () => {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const metadataFile = buildx.inputs.getBuildMetadataFilePath();
|
const metadataFile = buildx.inputs.getBuildMetadataFilePath();
|
||||||
await fs.writeFileSync(metadataFile, metadata);
|
await fs.writeFileSync(metadataFile, metadata);
|
||||||
const expected = buildx.inputs.resolveBuildMetadata();
|
const expected = buildx.inputs.resolveBuildMetadata();
|
||||||
@@ -77,9 +74,7 @@ describe('resolveBuildMetadata', () => {
|
|||||||
|
|
||||||
describe('resolveDigest', () => {
|
describe('resolveDigest', () => {
|
||||||
it('matches', async () => {
|
it('matches', async () => {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const metadataFile = buildx.inputs.getBuildMetadataFilePath();
|
const metadataFile = buildx.inputs.getBuildMetadataFilePath();
|
||||||
await fs.writeFileSync(metadataFile, metadata);
|
await fs.writeFileSync(metadataFile, metadata);
|
||||||
const expected = buildx.inputs.resolveDigest();
|
const expected = buildx.inputs.resolveDigest();
|
||||||
@@ -129,9 +124,7 @@ describe('getProvenanceInput', () => {
|
|||||||
],
|
],
|
||||||
])('given input %p', async (input: string, expected: string) => {
|
])('given input %p', async (input: string, expected: string) => {
|
||||||
await setInput('provenance', input);
|
await setInput('provenance', input);
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(buildx.inputs.getProvenanceInput('provenance')).toEqual(expected);
|
expect(buildx.inputs.getProvenanceInput('provenance')).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -160,9 +153,7 @@ describe('resolveProvenanceAttrs', () => {
|
|||||||
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
||||||
],
|
],
|
||||||
])('given %p', async (input: string, expected: string) => {
|
])('given %p', async (input: string, expected: string) => {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(buildx.inputs.resolveProvenanceAttrs(input)).toEqual(expected);
|
expect(buildx.inputs.resolveProvenanceAttrs(input)).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -179,9 +170,7 @@ describe('resolveBuildSecret', () => {
|
|||||||
[`notfound=secret`, true, '', '', new Error('secret file secret not found')]
|
[`notfound=secret`, true, '', '', new Error('secret file secret not found')]
|
||||||
])('given %p key and %p secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error) => {
|
])('given %p key and %p secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error) => {
|
||||||
try {
|
try {
|
||||||
const buildx = new Buildx({
|
const buildx = new Buildx();
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
let secret: string;
|
let secret: string;
|
||||||
if (file) {
|
if (file) {
|
||||||
secret = buildx.inputs.resolveBuildSecretFile(kvp);
|
secret = buildx.inputs.resolveBuildSecretFile(kvp);
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ import {Context} from '../src/context';
|
|||||||
const tmpDir = path.join(process.env.TEMP || '/tmp', 'context-jest');
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'context-jest');
|
||||||
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
|
||||||
jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => {
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
if (!fs.existsSync(tmpDir)) {
|
if (!fs.existsSync(tmpDir)) {
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
}
|
}
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
});
|
});
|
||||||
jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => {
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
return tmpName;
|
return tmpName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -43,16 +44,20 @@ afterEach(() => {
|
|||||||
rimraf.sync(tmpDir);
|
rimraf.sync(tmpDir);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('gitRef', () => {
|
||||||
|
it('returns refs/heads/master', async () => {
|
||||||
|
expect(Context.gitRef()).toEqual('refs/heads/master');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('gitContext', () => {
|
describe('gitContext', () => {
|
||||||
it('returns refs/heads/master', async () => {
|
it('returns refs/heads/master', async () => {
|
||||||
const context = new Context();
|
expect(Context.gitContext()).toEqual('https://github.com/docker/actions-toolkit.git#refs/heads/master');
|
||||||
expect(context.buildGitContext).toEqual('https://github.com/docker/actions-toolkit.git#refs/heads/master');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('provenanceBuilderID', () => {
|
describe('provenanceBuilderID', () => {
|
||||||
it('returns 123', async () => {
|
it('returns 123', async () => {
|
||||||
const context = new Context();
|
expect(Context.provenanceBuilderID()).toEqual('https://github.com/docker/actions-toolkit/actions/runs/123');
|
||||||
expect(context.provenanceBuilderID).toEqual('https://github.com/docker/actions-toolkit/actions/runs/123');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import * as core from '@actions/core';
|
|||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
|
|
||||||
import {Context} from '../context';
|
|
||||||
import {Buildx} from '../buildx/buildx';
|
import {Buildx} from '../buildx/buildx';
|
||||||
import {Builder} from '../buildx/builder';
|
import {Builder} from '../buildx/builder';
|
||||||
import {Config} from './config';
|
import {Config} from './config';
|
||||||
@@ -26,24 +25,17 @@ import {Config} from './config';
|
|||||||
import {BuilderInfo, NodeInfo} from '../types/builder';
|
import {BuilderInfo, NodeInfo} from '../types/builder';
|
||||||
|
|
||||||
export interface BuildKitOpts {
|
export interface BuildKitOpts {
|
||||||
context: Context;
|
|
||||||
buildx?: Buildx;
|
buildx?: Buildx;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BuildKit {
|
export class BuildKit {
|
||||||
private readonly context: Context;
|
|
||||||
private readonly buildx: Buildx;
|
private readonly buildx: Buildx;
|
||||||
|
|
||||||
public readonly config: Config;
|
public readonly config: Config;
|
||||||
|
|
||||||
constructor(opts: BuildKitOpts) {
|
constructor(opts?: BuildKitOpts) {
|
||||||
this.context = opts.context;
|
this.config = new Config();
|
||||||
this.config = new Config(this.context);
|
this.buildx = opts?.buildx || new Buildx();
|
||||||
this.buildx =
|
|
||||||
opts?.buildx ||
|
|
||||||
new Buildx({
|
|
||||||
context: this.context
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getVersion(node: NodeInfo): Promise<string | undefined> {
|
public async getVersion(node: NodeInfo): Promise<string | undefined> {
|
||||||
@@ -89,10 +81,7 @@ export class BuildKit {
|
|||||||
|
|
||||||
public async versionSatisfies(builderName: string, range: string, builderInfo?: BuilderInfo): Promise<boolean> {
|
public async versionSatisfies(builderName: string, range: string, builderInfo?: BuilderInfo): Promise<boolean> {
|
||||||
if (!builderInfo) {
|
if (!builderInfo) {
|
||||||
builderInfo = await new Builder({
|
builderInfo = await new Builder({buildx: this.buildx}).inspect(builderName);
|
||||||
context: this.context,
|
|
||||||
buildx: this.buildx
|
|
||||||
}).inspect(builderName);
|
|
||||||
}
|
}
|
||||||
for (const node of builderInfo.nodes) {
|
for (const node of builderInfo.nodes) {
|
||||||
core.debug(`BuildKit.versionSatisfies ${node}: ${range}`);
|
core.debug(`BuildKit.versionSatisfies ${node}: ${range}`);
|
||||||
|
|||||||
@@ -19,12 +19,6 @@ import fs from 'fs';
|
|||||||
import {Context} from '../context';
|
import {Context} from '../context';
|
||||||
|
|
||||||
export class Config {
|
export class Config {
|
||||||
private readonly context: Context;
|
|
||||||
|
|
||||||
constructor(context: Context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public resolveFromString(s: string): string {
|
public resolveFromString(s: string): string {
|
||||||
return this.resolve(s, false);
|
return this.resolve(s, false);
|
||||||
}
|
}
|
||||||
@@ -40,7 +34,7 @@ export class Config {
|
|||||||
}
|
}
|
||||||
s = fs.readFileSync(s, {encoding: 'utf-8'});
|
s = fs.readFileSync(s, {encoding: 'utf-8'});
|
||||||
}
|
}
|
||||||
const configFile = this.context.tmpName({tmpdir: this.context.tmpDir()});
|
const configFile = Context.tmpName({tmpdir: Context.tmpDir()});
|
||||||
fs.writeFileSync(configFile, s);
|
fs.writeFileSync(configFile, s);
|
||||||
return configFile;
|
return configFile;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,26 +17,18 @@
|
|||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
|
|
||||||
import {Buildx} from './buildx';
|
import {Buildx} from './buildx';
|
||||||
import {Context} from '../context';
|
|
||||||
|
|
||||||
import {BuilderInfo, NodeInfo} from '../types/builder';
|
import {BuilderInfo, NodeInfo} from '../types/builder';
|
||||||
|
|
||||||
export interface BuilderOpts {
|
export interface BuilderOpts {
|
||||||
context: Context;
|
|
||||||
buildx?: Buildx;
|
buildx?: Buildx;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Builder {
|
export class Builder {
|
||||||
private readonly context: Context;
|
|
||||||
private readonly buildx: Buildx;
|
private readonly buildx: Buildx;
|
||||||
|
|
||||||
constructor(opts: BuilderOpts) {
|
constructor(opts?: BuilderOpts) {
|
||||||
this.context = opts.context;
|
this.buildx = opts?.buildx || new Buildx();
|
||||||
this.buildx =
|
|
||||||
opts?.buildx ||
|
|
||||||
new Buildx({
|
|
||||||
context: this.context
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async inspect(name: string): Promise<BuilderInfo> {
|
public async inspect(name: string): Promise<BuilderInfo> {
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ import * as exec from '@actions/exec';
|
|||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
|
|
||||||
import {Docker} from '../docker';
|
import {Docker} from '../docker';
|
||||||
import {Context} from '../context';
|
|
||||||
import {Inputs} from './inputs';
|
import {Inputs} from './inputs';
|
||||||
|
|
||||||
import {Cert} from '../types/buildx';
|
import {Cert} from '../types/buildx';
|
||||||
|
|
||||||
export interface BuildxOpts {
|
export interface BuildxOpts {
|
||||||
context: Context;
|
|
||||||
standalone?: boolean;
|
standalone?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,15 +33,13 @@ export class Buildx {
|
|||||||
private _version: string | undefined;
|
private _version: string | undefined;
|
||||||
private readonly _standalone: boolean | undefined;
|
private readonly _standalone: boolean | undefined;
|
||||||
|
|
||||||
private readonly context: Context;
|
|
||||||
public readonly inputs: Inputs;
|
public readonly inputs: Inputs;
|
||||||
|
|
||||||
public static readonly containerNamePrefix = 'buildx_buildkit_';
|
public static readonly containerNamePrefix = 'buildx_buildkit_';
|
||||||
|
|
||||||
constructor(opts: BuildxOpts) {
|
constructor(opts?: BuildxOpts) {
|
||||||
this._standalone = opts?.standalone;
|
this._standalone = opts?.standalone;
|
||||||
this.context = opts.context;
|
this.inputs = new Inputs();
|
||||||
this.inputs = new Inputs(this.context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get configDir(): string {
|
static get configDir(): string {
|
||||||
|
|||||||
@@ -22,18 +22,12 @@ import {parse} from 'csv-parse/sync';
|
|||||||
import {Context} from '../context';
|
import {Context} from '../context';
|
||||||
|
|
||||||
export class Inputs {
|
export class Inputs {
|
||||||
private readonly context: Context;
|
|
||||||
|
|
||||||
constructor(context: Context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getBuildImageIDFilePath(): string {
|
public getBuildImageIDFilePath(): string {
|
||||||
return path.join(this.context.tmpDir(), 'iidfile');
|
return path.join(Context.tmpDir(), 'iidfile');
|
||||||
}
|
}
|
||||||
|
|
||||||
public getBuildMetadataFilePath(): string {
|
public getBuildMetadataFilePath(): string {
|
||||||
return path.join(this.context.tmpDir(), 'metadata-file');
|
return path.join(Context.tmpDir(), 'metadata-file');
|
||||||
}
|
}
|
||||||
|
|
||||||
public resolveBuildImageID(): string | undefined {
|
public resolveBuildImageID(): string | undefined {
|
||||||
@@ -89,7 +83,7 @@ export class Inputs {
|
|||||||
}
|
}
|
||||||
value = fs.readFileSync(value, {encoding: 'utf-8'});
|
value = fs.readFileSync(value, {encoding: 'utf-8'});
|
||||||
}
|
}
|
||||||
const secretFile = this.context.tmpName({tmpdir: this.context.tmpDir()});
|
const secretFile = Context.tmpName({tmpdir: Context.tmpDir()});
|
||||||
fs.writeFileSync(secretFile, value);
|
fs.writeFileSync(secretFile, value);
|
||||||
return `id=${key},src=${secretFile}`;
|
return `id=${key},src=${secretFile}`;
|
||||||
}
|
}
|
||||||
@@ -100,9 +94,8 @@ export class Inputs {
|
|||||||
// if input is not set returns empty string
|
// if input is not set returns empty string
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
const builderID = this.context.provenanceBuilderID;
|
|
||||||
try {
|
try {
|
||||||
return core.getBooleanInput(name) ? `builder-id=${builderID}` : 'false';
|
return core.getBooleanInput(name) ? `builder-id=${Context.provenanceBuilderID()}` : 'false';
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// not a valid boolean, so we assume it's a string
|
// not a valid boolean, so we assume it's a string
|
||||||
return this.resolveProvenanceAttrs(input);
|
return this.resolveProvenanceAttrs(input);
|
||||||
@@ -111,7 +104,7 @@ export class Inputs {
|
|||||||
|
|
||||||
public resolveProvenanceAttrs(input: string): string {
|
public resolveProvenanceAttrs(input: string): string {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
return `builder-id=${this.context.provenanceBuilderID}`;
|
return `builder-id=${Context.provenanceBuilderID()}`;
|
||||||
}
|
}
|
||||||
// parse attributes from input
|
// parse attributes from input
|
||||||
const fields = parse(input, {
|
const fields = parse(input, {
|
||||||
@@ -129,7 +122,7 @@ export class Inputs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if not add builder-id attribute
|
// if not add builder-id attribute
|
||||||
return `${input},builder-id=${this.context.provenanceBuilderID}`;
|
return `${input},builder-id=${Context.provenanceBuilderID()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static hasLocalExporter(exporters: string[]): boolean {
|
public static hasLocalExporter(exporters: string[]): boolean {
|
||||||
|
|||||||
@@ -32,17 +32,13 @@ import {Git} from '../git';
|
|||||||
import {GitHubRelease} from '../types/github';
|
import {GitHubRelease} from '../types/github';
|
||||||
|
|
||||||
export interface InstallOpts {
|
export interface InstallOpts {
|
||||||
context?: Context;
|
|
||||||
standalone?: boolean;
|
standalone?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Install {
|
export class Install {
|
||||||
private readonly _standalone: boolean | undefined;
|
private readonly _standalone: boolean | undefined;
|
||||||
|
|
||||||
private readonly context: Context;
|
|
||||||
|
|
||||||
constructor(opts?: InstallOpts) {
|
constructor(opts?: InstallOpts) {
|
||||||
this.context = opts?.context || new Context();
|
|
||||||
this._standalone = opts?.standalone;
|
this._standalone = opts?.standalone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +80,7 @@ export class Install {
|
|||||||
let toolPath: string;
|
let toolPath: string;
|
||||||
toolPath = tc.find('buildx', vspec);
|
toolPath = tc.find('buildx', vspec);
|
||||||
if (!toolPath) {
|
if (!toolPath) {
|
||||||
const outputDir = path.join(this.context.tmpDir(), 'build-cache');
|
const outputDir = path.join(Context.tmpDir(), 'build-cache');
|
||||||
const buildCmd = await this.buildCommand(gitContext, outputDir);
|
const buildCmd = await this.buildCommand(gitContext, outputDir);
|
||||||
toolPath = await exec
|
toolPath = await exec
|
||||||
.getExecOutput(buildCmd.command, buildCmd.args, {
|
.getExecOutput(buildCmd.command, buildCmd.args, {
|
||||||
@@ -103,7 +99,7 @@ export class Install {
|
|||||||
|
|
||||||
public async installStandalone(toolPath: string, dest?: string): Promise<string> {
|
public async installStandalone(toolPath: string, dest?: string): Promise<string> {
|
||||||
core.info('Standalone mode');
|
core.info('Standalone mode');
|
||||||
dest = dest || this.context.tmpDir();
|
dest = dest || Context.tmpDir();
|
||||||
const toolBinPath = path.join(toolPath, os.platform() == 'win32' ? 'docker-buildx.exe' : 'docker-buildx');
|
const toolBinPath = path.join(toolPath, os.platform() == 'win32' ? 'docker-buildx.exe' : 'docker-buildx');
|
||||||
const binDir = path.join(dest, 'bin');
|
const binDir = path.join(dest, 'bin');
|
||||||
if (!fs.existsSync(binDir)) {
|
if (!fs.existsSync(binDir)) {
|
||||||
@@ -143,8 +139,8 @@ export class Install {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async buildCommand(gitContext: string, outputDir: string): Promise<{args: Array<string>; command: string}> {
|
private async buildCommand(gitContext: string, outputDir: string): Promise<{args: Array<string>; command: string}> {
|
||||||
const buildxStandaloneFound = await new Buildx({context: this.context, standalone: true}).isAvailable();
|
const buildxStandaloneFound = await new Buildx({standalone: true}).isAvailable();
|
||||||
const buildxPluginFound = await new Buildx({context: this.context, standalone: false}).isAvailable();
|
const buildxPluginFound = await new Buildx({standalone: false}).isAvailable();
|
||||||
|
|
||||||
let buildStandalone = false;
|
let buildStandalone = false;
|
||||||
if ((await this.isStandalone()) && buildxStandaloneFound) {
|
if ((await this.isStandalone()) && buildxStandaloneFound) {
|
||||||
@@ -164,7 +160,7 @@ export class Install {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//prettier-ignore
|
//prettier-ignore
|
||||||
return await new Buildx({context: this.context, standalone: buildStandalone}).getCommand([
|
return await new Buildx({standalone: buildStandalone}).getCommand([
|
||||||
'build',
|
'build',
|
||||||
'--target', 'binaries',
|
'--target', 'binaries',
|
||||||
'--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1',
|
'--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1',
|
||||||
|
|||||||
@@ -23,29 +23,32 @@ import * as github from '@actions/github';
|
|||||||
import {GitHub} from './github';
|
import {GitHub} from './github';
|
||||||
|
|
||||||
export class Context {
|
export class Context {
|
||||||
public gitRef: string;
|
private static readonly _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-'));
|
||||||
public buildGitContext: string;
|
|
||||||
public provenanceBuilderID: string;
|
|
||||||
|
|
||||||
private readonly _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-'));
|
public static tmpDir(): string {
|
||||||
|
return Context._tmpDir;
|
||||||
constructor() {
|
|
||||||
this.gitRef = github.context.ref;
|
|
||||||
if (github.context.sha && this.gitRef && !this.gitRef.startsWith('refs/')) {
|
|
||||||
this.gitRef = `refs/heads/${github.context.ref}`;
|
|
||||||
}
|
|
||||||
if (github.context.sha && !this.gitRef.startsWith(`refs/pull/`)) {
|
|
||||||
this.gitRef = github.context.sha;
|
|
||||||
}
|
|
||||||
this.buildGitContext = `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git#${this.gitRef}`;
|
|
||||||
this.provenanceBuilderID = `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public tmpDir(): string {
|
public static tmpName(options?: tmp.TmpNameOptions): string {
|
||||||
return this._tmpDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
public tmpName(options?: tmp.TmpNameOptions): string {
|
|
||||||
return tmp.tmpNameSync(options);
|
return tmp.tmpNameSync(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static gitRef(): string {
|
||||||
|
let gitRef = github.context.ref;
|
||||||
|
if (github.context.sha && gitRef && !gitRef.startsWith('refs/')) {
|
||||||
|
gitRef = `refs/heads/${github.context.ref}`;
|
||||||
|
}
|
||||||
|
if (github.context.sha && !gitRef.startsWith(`refs/pull/`)) {
|
||||||
|
gitRef = github.context.sha;
|
||||||
|
}
|
||||||
|
return gitRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static gitContext(): string {
|
||||||
|
return `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git#${Context.gitRef()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static provenanceBuilderID(): string {
|
||||||
|
return `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Context} from './context';
|
|
||||||
import {Buildx} from './buildx/buildx';
|
import {Buildx} from './buildx/buildx';
|
||||||
import {Install} from './buildx/install';
|
import {Install} from './buildx/install';
|
||||||
import {Builder} from './buildx/builder';
|
import {Builder} from './buildx/builder';
|
||||||
@@ -30,7 +29,6 @@ export interface ToolkitOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Toolkit {
|
export class Toolkit {
|
||||||
public context: Context;
|
|
||||||
public github: GitHub;
|
public github: GitHub;
|
||||||
public buildx: Buildx;
|
public buildx: Buildx;
|
||||||
public buildxInstall: Install;
|
public buildxInstall: Install;
|
||||||
@@ -38,11 +36,10 @@ export class Toolkit {
|
|||||||
public buildkit: BuildKit;
|
public buildkit: BuildKit;
|
||||||
|
|
||||||
constructor(opts: ToolkitOpts = {}) {
|
constructor(opts: ToolkitOpts = {}) {
|
||||||
this.context = new Context();
|
|
||||||
this.github = new GitHub({token: opts.githubToken});
|
this.github = new GitHub({token: opts.githubToken});
|
||||||
this.buildx = new Buildx({context: this.context});
|
this.buildx = new Buildx();
|
||||||
this.buildxInstall = new Install({context: this.context});
|
this.buildxInstall = new Install();
|
||||||
this.builder = new Builder({context: this.context, buildx: this.buildx});
|
this.builder = new Builder({buildx: this.buildx});
|
||||||
this.buildkit = new BuildKit({context: this.context, buildx: this.buildx});
|
this.buildkit = new BuildKit({buildx: this.buildx});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user