2021-04-12 17:13:19 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright ( c ) Red Hat , Inc . All rights reserved .
* Licensed under the MIT License . See LICENSE file in the project root for license information .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2021-02-01 17:54:50 +00:00
import * as core from "@actions/core" ;
import * as io from "@actions/io" ;
import * as path from "path" ;
2021-02-08 16:24:18 +00:00
import { Inputs , Outputs } from "./generated/inputs-outputs" ;
2021-02-01 17:54:50 +00:00
import { BuildahCli , BuildahConfigSettings } from "./buildah" ;
2021-09-14 19:03:38 +00:00
import {
2021-10-14 22:09:15 +00:00
getArch , getPlatform , getContainerfiles , getInputList , splitByNewline ,
2021-10-12 17:21:52 +00:00
isFullImageName , getFullImageName ,
2021-09-14 19:03:38 +00:00
} from "./utils" ;
2020-11-06 17:42:45 +00:00
export async function run ( ) : Promise < void > {
2021-02-01 17:54:50 +00:00
if ( process . env . RUNNER_OS !== "Linux" ) {
throw new Error ( "buildah, and therefore this action, only works on Linux. Please use a Linux runner." ) ;
2020-11-06 17:42:45 +00:00
}
2020-11-19 08:19:57 +00:00
2020-11-06 17:42:45 +00:00
// get buildah cli
2021-02-01 17:54:50 +00:00
const buildahPath = await io . which ( "buildah" , true ) ;
2020-11-19 08:19:57 +00:00
const cli : BuildahCli = new BuildahCli ( buildahPath ) ;
2021-03-23 14:15:56 +00:00
// print buildah version
2021-04-09 14:32:13 +00:00
await cli . execute ( [ "version" ] , { group : true } ) ;
// Check if fuse-overlayfs exists and find the storage driver
await cli . setStorageOptsEnv ( ) ;
2021-03-23 14:15:56 +00:00
2021-02-24 16:13:55 +00:00
const DEFAULT_TAG = "latest" ;
2021-02-01 17:54:50 +00:00
const workspace = process . env . GITHUB_WORKSPACE || process . cwd ( ) ;
2021-09-14 19:03:38 +00:00
const containerFiles = getContainerfiles ( ) ;
2021-10-12 17:21:52 +00:00
const image = core . getInput ( Inputs . IMAGE ) ;
2021-02-24 16:13:55 +00:00
const tags = core . getInput ( Inputs . TAGS ) ;
2021-10-12 17:21:52 +00:00
const tagsList : string [ ] = tags . trim ( ) . split ( /\s+/ ) ;
2021-02-24 16:13:55 +00:00
// info message if user doesn't provides any tag
2021-07-09 15:12:48 +00:00
if ( tagsList . length === 0 ) {
2021-02-24 16:13:55 +00:00
core . info ( ` Input " ${ Inputs . TAGS } " is not provided, using default tag " ${ DEFAULT_TAG } " ` ) ;
tagsList . push ( DEFAULT_TAG ) ;
}
2021-10-12 17:21:52 +00:00
// check if all tags provided are in `image:tag` format
const isFullImageNameTag = isFullImageName ( tagsList [ 0 ] ) ;
if ( tagsList . some ( ( tag ) = > isFullImageName ( tag ) !== isFullImageNameTag ) ) {
2021-10-14 22:39:58 +00:00
throw new Error ( ` Input " ${ Inputs . TAGS } " cannot have a mix of full name and non full name tags. Refer to https://github.com/redhat-actions/buildah-build#image-tag-inputs ` ) ;
2021-10-12 17:21:52 +00:00
}
if ( ! isFullImageNameTag && ! image ) {
2021-10-14 22:39:58 +00:00
throw new Error ( ` Input " ${ Inputs . IMAGE } " must be provided when not using full image name tags. Refer to https://github.com/redhat-actions/buildah-build#image-tag-inputs ` ) ;
2021-10-12 17:21:52 +00:00
}
const newImage = getFullImageName ( image , tagsList [ 0 ] ) ;
2021-02-08 16:24:18 +00:00
const useOCI = core . getInput ( Inputs . OCI ) === "true" ;
2021-07-09 15:12:48 +00:00
const arch = getArch ( ) ;
2021-10-14 22:09:15 +00:00
const platform = getPlatform ( ) ;
if ( arch && platform ) {
throw new Error ( "The --platform option may not be used in combination with the --arch option." ) ;
}
2020-11-26 18:00:17 +00:00
2021-09-14 19:03:38 +00:00
if ( containerFiles . length !== 0 ) {
2021-10-14 22:09:15 +00:00
await doBuildUsingContainerFiles ( cli , newImage , workspace , containerFiles , useOCI , arch , platform ) ;
2021-02-01 17:54:50 +00:00
}
else {
2021-10-14 22:09:15 +00:00
await doBuildFromScratch ( cli , newImage , useOCI , arch , platform ) ;
2020-11-19 18:46:44 +00:00
}
2020-11-23 22:08:21 +00:00
2021-02-01 17:54:50 +00:00
if ( tagsList . length > 1 ) {
await cli . tag ( image , tagsList ) ;
}
2021-02-08 16:24:18 +00:00
core . setOutput ( Outputs . IMAGE , image ) ;
core . setOutput ( Outputs . TAGS , tags ) ;
2021-10-12 17:21:52 +00:00
core . setOutput ( Outputs . IMAGE_WITH_TAG , newImage ) ;
2020-11-19 08:19:57 +00:00
}
2021-09-14 19:03:38 +00:00
async function doBuildUsingContainerFiles (
2021-10-14 22:09:15 +00:00
cli : BuildahCli , newImage : string , workspace : string , containerFiles : string [ ] , useOCI : boolean , arch : string ,
platform : string
2021-02-01 17:54:50 +00:00
) : Promise < void > {
2021-09-14 19:03:38 +00:00
if ( containerFiles . length === 1 ) {
core . info ( ` Performing build from Containerfile ` ) ;
2020-11-23 22:08:21 +00:00
}
else {
2021-09-14 19:03:38 +00:00
core . info ( ` Performing build from ${ containerFiles . length } Containerfiles ` ) ;
2020-11-23 22:08:21 +00:00
}
2021-02-08 16:24:18 +00:00
const context = path . join ( workspace , core . getInput ( Inputs . CONTEXT ) ) ;
const buildArgs = getInputList ( Inputs . BUILD_ARGS ) ;
2021-09-14 19:03:38 +00:00
const containerFileAbsPaths = containerFiles . map ( ( file ) = > path . join ( workspace , file ) ) ;
2021-03-30 12:50:32 +00:00
const layers = core . getInput ( Inputs . LAYERS ) ;
2021-04-12 17:13:19 +00:00
const inputExtraArgsStr = core . getInput ( Inputs . EXTRA_ARGS ) ;
let buildahBudExtraArgs : string [ ] = [ ] ;
if ( inputExtraArgsStr ) {
// transform the array of lines into an array of arguments
// by splitting over lines, then over spaces, then trimming.
const lines = splitByNewline ( inputExtraArgsStr ) ;
buildahBudExtraArgs = lines . flatMap ( ( line ) = > line . split ( " " ) ) . map ( ( arg ) = > arg . trim ( ) ) ;
}
await cli . buildUsingDocker (
2021-10-14 22:09:15 +00:00
newImage , context , containerFileAbsPaths , buildArgs , useOCI , arch , platform , layers , buildahBudExtraArgs
2021-04-12 17:13:19 +00:00
) ;
2020-11-19 08:19:57 +00:00
}
2021-02-01 17:54:50 +00:00
async function doBuildFromScratch (
2021-10-14 22:09:15 +00:00
cli : BuildahCli , newImage : string , useOCI : boolean , arch : string , platform : string
2021-02-01 17:54:50 +00:00
) : Promise < void > {
core . info ( ` Performing build from scratch ` ) ;
2020-11-06 17:42:45 +00:00
2021-02-08 16:24:18 +00:00
const baseImage = core . getInput ( Inputs . BASE_IMAGE , { required : true } ) ;
const content = getInputList ( Inputs . CONTENT ) ;
const entrypoint = getInputList ( Inputs . ENTRYPOINT ) ;
const port = core . getInput ( Inputs . PORT ) ;
const workingDir = core . getInput ( Inputs . WORKDIR ) ;
const envs = getInputList ( Inputs . ENVS ) ;
2020-11-19 18:46:44 +00:00
2020-11-13 11:38:29 +00:00
const container = await cli . from ( baseImage ) ;
2021-02-01 17:54:50 +00:00
const containerId = container . output . replace ( "\n" , "" ) ;
2020-11-06 17:42:45 +00:00
2020-11-13 11:38:29 +00:00
const newImageConfig : BuildahConfigSettings = {
2021-02-01 17:54:50 +00:00
entrypoint ,
port ,
2020-11-13 11:38:29 +00:00
workingdir : workingDir ,
2021-02-01 17:54:50 +00:00
envs ,
2021-07-09 15:12:48 +00:00
arch ,
2021-10-14 22:09:15 +00:00
platform ,
2020-11-13 11:38:29 +00:00
} ;
2020-11-23 22:08:21 +00:00
await cli . config ( containerId , newImageConfig ) ;
2021-09-02 10:55:57 +00:00
await cli . copy ( containerId , content ) ;
2020-11-26 18:00:17 +00:00
await cli . commit ( containerId , newImage , useOCI ) ;
2020-11-06 17:42:45 +00:00
}
2020-11-19 18:46:44 +00:00
run ( ) . catch ( core . setFailed ) ;