add support for building images with docker files (#4)

Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
This commit is contained in:
Luca Stocchi 2020-11-17 15:54:29 +01:00
parent 329be0a470
commit 1b1386b77e
No known key found for this signature in database
GPG key ID: 930BB00F3FCF30A4
6 changed files with 82 additions and 26 deletions

View file

@ -5,26 +5,34 @@ branding:
icon: circle
color: red
inputs:
new-image-name:
description: 'Name of the new image that will be created'
image:
description: 'The name (reference) of the image to build'
required: true
base-image:
description: 'Base image to use'
description: 'The base image to use to create a new container'
required: false
dockerfiles:
description: 'The path of one or more Dockerfiles (default: ./Dockerfile)'
required: false
default: './Dockerfile'
context:
description: 'Path to the directory to use as context (default: .)'
required: false
default: '.'
content:
description: 'The content to copy inside the base image'
required: true
required: false
entrypoint:
description: 'Entrypoint'
required: true
description: 'The entry point to set for containers based on image'
required: false
port:
description: 'Port'
required: true
description: 'The port to expose when running containers based on image'
required: false
working-dir:
description: 'Working directory'
description: 'The working directory to use within the container'
required: false
envs:
description: 'envs'
description: 'The environment variables to be set when running containers based on image'
required: false
runs:
using: 'node12'

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View file

@ -3,6 +3,7 @@ import * as exec from "@actions/exec";
import { CommandResult } from "./types";
interface Buildah {
buildUsingDocker(image: string, context: string, dockerFiles: string[]): Promise<CommandResult>;
from(baseImage: string): Promise<CommandResult>;
copy(container: string, contentToCopy: string[]): Promise<CommandResult>;
config(container: string, setting: {}): Promise<CommandResult>;
@ -24,6 +25,18 @@ export class BuildahCli implements Buildah {
this.executable = executable;
}
async buildUsingDocker(image: string, context: string, dockerFiles: string[]): Promise<CommandResult> {
const args: string[] = ['bud'];
dockerFiles.forEach(file => {
args.push('-f');
args.push(file);
});
args.push('t');
args.push(image);
args.push(context);
return await this.execute(args);
}
async from(baseImage: string): Promise<CommandResult> {
return await this.execute(['from', baseImage]);
}

View file

@ -7,23 +7,49 @@ import * as path from 'path';
import { Language } from 'language-recognizer/lib/types';
export async function run(): Promise<void> {
if (process.env.RUNNER_OS !== 'Linux') {
return Promise.reject(new Error('Only linux platform is supported at this time.'));
}
// get buildah cli
const buildahPath = await io.which('buildah', true);
const cli: BuildahCli = new BuildahCli(buildahPath);
const workspace = process.env['GITHUB_WORKSPACE'];
let dockerFiles = getInputList('dockerfiles');
const newImage = core.getInput('image');
dockerFiles = dockerFiles.map(file => path.join(workspace, file));
const dockerBuild = await isDockerBuild(workspace, dockerFiles);
if (dockerBuild) {
doBuildUsingDockerFiles(cli, newImage, workspace, dockerFiles);
} else {
doBuildFromScratch(cli, newImage, workspace);
}
}
async function doBuildUsingDockerFiles(cli: BuildahCli, newImage: string, workspace: string, dockerFiles: string[]): Promise<void> {
const context = path.join(workspace, core.getInput('context'));
const build = await cli.buildUsingDocker(newImage, context, dockerFiles);
if (build.succeeded === false) {
return Promise.reject(new Error('Failed building an image from docker files.'));
}
}
async function doBuildFromScratch(cli: BuildahCli, newImage: string, workspace: string) {
let baseImage = core.getInput('base-image');
const content = getInputList('content');
const newImageName = core.getInput('new-image-name');
const entrypoint = getInputList('entrypoint');
const port = core.getInput('port');
const workingDir = core.getInput('working-dir');
const envs = getInputList('envs');
if (process.env.RUNNER_OS !== 'Linux') {
return Promise.reject(new Error('Only linux platform is supported at this time.'));
}
// get buildah cli
const buildahPath = await io.which('buildah', true);
// if base-image is not specified by the user we need to pick one automatically
if (!baseImage) {
const workspace = process.env['GITHUB_WORKSPACE'];
if (workspace) {
// check language/framework used and pick base-image automatically
const languages = await recognizer.detectLanguages(workspace);
@ -36,8 +62,6 @@ export async function run(): Promise<void> {
}
}
// create the new image
const cli: BuildahCli = new BuildahCli(buildahPath);
const container = await cli.from(baseImage);
if (container.succeeded === false) {
return Promise.reject(new Error(container.reason));
@ -60,12 +84,22 @@ export async function run(): Promise<void> {
return Promise.reject(new Error(configResult.reason));
}
const commit = await cli.commit(containerId, newImageName, ['--squash']);
const commit = await cli.commit(containerId, newImage, ['--squash']);
if (commit.succeeded === false) {
return Promise.reject(new Error(commit.reason));
}
}
async function isDockerBuild(workspace: string, dockerFiles: string[]): Promise<boolean> {
for(const file of dockerFiles) {
const fileExists = (await fs.stat(path.join(workspace, file)).then(() => true).catch(() => false));
if (!fileExists) {
return false;
}
}
return true;
}
function getInputList(name: string): string[] {
const items = core.getInput(name);
if (!items) {

View file

@ -9,6 +9,7 @@
"rootDir": ".",
},
"exclude": [
"node_modules"
"node_modules",
"scripts"
]
}