Skip to content

Commit

Permalink
Refactor inputs to support docker/metadata-action (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
ntkme committed Oct 12, 2021
1 parent f123b1f commit 979e6a6
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 23 deletions.
78 changes: 78 additions & 0 deletions .github/workflows/docker_metadata_action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# This workflow will perform a test whenever there
# is some change in code done to ensure that the changes
# are not buggy and we are getting the desired output.
name: Build with docker/metadata-action@v2
on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # every day at midnight

env:
IMAGE_NAME: "hello-world"

jobs:
build:
name: Build image using Buildah
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
install_latest: [ true, false ]

steps:

# Checkout buildah action github repository
- name: Checkout Buildah action
uses: actions/checkout@v2

- name: Docker Metadata
id: docker-metadata
uses: docker/metadata-action@v3
with:
images: |
${{ env.IMAGE_NAME }}
tags: |
type=edge
type=sha
type=ref,event=branch
type=ref,event=pr
type=schedule
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
- name: Install latest buildah
if: matrix.install_latest
run: |
bash .github/install_latest_buildah.sh
- name: Create Dockerfile
run: |
cat > Containerfile<<EOF
FROM busybox
RUN echo "hello world"
EOF
# Build image using Buildah action
- name: Build Image
id: build_image
uses: ./
with:
layers: false
tags: ${{ steps.docker-metadata.outputs.tags }}
containerfiles: |
./Containerfile
extra-args: |
--pull
- name: Echo Outputs
run: |
echo "Image: ${{ steps.build_image.outputs.image }}"
echo "Tags: ${{ steps.build_image.outputs.tags }}"
echo "Tagged Image: ${{ steps.build_image.outputs.image-with-tag }}"
# Check if image is build
- name: Check images created
run: buildah images | grep '${{ env.IMAGE_NAME }}'
41 changes: 30 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ After building your image, use [push-to-registry](https://github.com/redhat-acti
| arch | Label the image with this architecture, instead of defaulting to the host architecture. Refer to [Multi arch builds](#multi-arch-builds) for more information. | None (host architecture)
| build-args | Build arguments to pass to the Docker build using `--build-arg`, if using a Containerfile that requires ARGs. Use the form `arg_name=arg_value`, and separate arguments with newlines. | None
| context | Path to directory to use as the build context. | `.`
| containerfiles* | The list of Containerfile paths to perform a build using docker instructions. This is a multiline input to allow multiple Containerfiles. | **Must be provided**
| containerfiles\* | The list of Containerfile paths to perform a build using docker instructions. This is a multiline input to allow multiple Containerfiles. | **Must be provided**
| extra-args | Extra args to be passed to buildah bud. Separate arguments by newline. Do not use quotes. | None
| image | Name to give to the output image. | **Must be provided**
| image | Name to give to the output image. | **Must be provided unless tags are provided in `<repository>:<tag>` form**
| layers | Set to true to cache intermediate layers during the build process. | None
| oci | Build the image using the OCI format, instead of the Docker format. By default, this is `false`, because images built using the OCI format have issues when published to Dockerhub. | `false`
| tags | The tags of the image to build. For multiple tags, separate by a space. For example, `latest ${{ github.sha }}` | `latest`
> *The `containerfiles` input was previously `dockerfiles`. Now `dockerfiles` is an alias for `containerfiles`. For details see [the issue](https://github.com/redhat-actions/buildah-build/issues/57).
| tags | The tags of the image to build. For multiple tags, separate by whitespace. For example, `latest ${{ github.sha }}`. For multiple image names, specify tags in `<repository>:<tag>` form. For example, `quay.io/podman/stable:latest quay.io/containers/podman:latest` | `latest`
> \*The `containerfiles` input was previously `dockerfiles`. Now `dockerfiles` is an alias for `containerfiles`. For details see [the issue](https://github.com/redhat-actions/buildah-build/issues/57).
<a id="scratch-build-inputs"></a>

Expand All @@ -47,24 +47,39 @@ After building your image, use [push-to-registry](https://github.com/redhat-acti
| content | Paths to files or directories to copy inside the container to create the file image. This is a multiline input to allow you to copy multiple files/directories.| None
| entrypoint | The entry point to set for the container. This is a multiline input; split arguments across lines. | None
| envs | The environment variables to be set when running the container. This is a multiline input to add multiple environment variables. | None
| image | Name to give to the output image. | **Must be provided**
| image | Name to give to the output image. | **Must be provided unless tags are provided in `<repository>:<tag>` form**
| oci | Build the image using the OCI format, instead of the Docker format. By default, this is `false`, because images built using the OCI format have issues when published to Dockerhub. | `false`
| port | The port to expose when running the container. | None
| tags | The tags of the image to build. For multiple tags, separate by a space. For example, `latest ${{ github.sha }}` | `latest`
| tags | The tags of the image to build. For multiple tags, separate by whitespace. For example, `latest ${{ github.sha }}`. For multiple image names, specify tags in `<repository>:<tag>` form. For example, `quay.io/podman/stable:latest quay.io/containers/podman:latest` | `latest`
| workdir | The working directory to use within the container. | None

**NOTE**: Alternative to provide input `image` and `tags` separately, you can provide input `tags` as `<repository>:<tag>` with repository in fully qualified image name (FQIN) form (e.g. `quay.io/username/myimage:latest`). When FQIN tags are provided, input `image` will be ignored.

<a id="outputs"></a>

## Action Outputs

`image`: The name of the built image.<br>
For example, `spring-image`.

`tags`: A list of the tags that were created, separated by spaces.<br>
For example, `latest ${{ github.sha }}`.

`image-with-tag`: The name of the image tagged with the first tag present.<br>
For example, `spring-image:latest`

For example:

``` yml
image: "spring-image"
tags: "latest ${{ github.sha }}"
image-with-tag: "spring-image:latest"
```

When input `tags` are provided in FQIN form, output `image` will be an empty, and output `tags` and `image-with-tag` will be both in FQIN form.

For example:

``` yml
image: ""
tags: "quay.io/podman/stable:latest quay.io/containers/podman:latest"
image-with-tag: "quay.io/podman/stable:latest"
```

<a id="build-types"></a>

Expand Down Expand Up @@ -176,6 +191,10 @@ There are examples and explanations of the `manifest` command [in this issue](ht

This action does not support the `manifest` command at this time, but there is [an issue open](https://github.com/redhat-actions/buildah-build/issues/61).

## Build with docker/metadata-action

Refer to the [docker/metadata-action example](./.github/workflows/docker_metadata_action.yml).

## Using private images

If your build references a private image, run [**podman-login**](https://github.com/redhat-actions/podman-login) in a step before this action so you can pull the image.
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ branding:
inputs:
image:
description: 'The name (reference) of the image to build'
required: true
required: false
tags:
description: 'The tags of the image to build. For multiple tags, seperate by a space. For example, "latest v1".'
description: 'The tags of the image to build. For multiple tags, seperate by whitespace. For example, "latest v1".'
required: false
default: latest
base-image:
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/buildah.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as core from "@actions/core";
import * as exec from "@actions/exec";
import * as path from "path";
import CommandResult from "./types";
import { isStorageDriverOverlay, findFuseOverlayfsPath } from "./utils";
import { isStorageDriverOverlay, findFuseOverlayfsPath, getFullImageName } from "./utils";

export interface BuildahConfigSettings {
entrypoint?: string[];
Expand Down Expand Up @@ -157,7 +157,7 @@ export class BuildahCli implements Buildah {
async tag(imageName: string, tags: string[]): Promise<CommandResult> {
const args: string[] = [ "tag" ];
for (const tag of tags) {
args.push(`${imageName}:${tag}`);
args.push(getFullImageName(imageName, tag));
}
core.info(`Tagging the built image with tags ${tags.toString()}`);
return this.execute(args);
Expand Down
4 changes: 2 additions & 2 deletions src/generated/inputs-outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export enum Inputs {
EXTRA_ARGS = "extra-args",
/**
* The name (reference) of the image to build
* Required: true
* Required: false
* Default: None.
*/
IMAGE = "image",
Expand All @@ -92,7 +92,7 @@ export enum Inputs {
*/
PORT = "port",
/**
* The tags of the image to build. For multiple tags, seperate by a space. For example, "latest v1".
* The tags of the image to build. For multiple tags, seperate by whitespace. For example, "latest v1".
* Required: false
* Default: "latest"
*/
Expand Down
19 changes: 15 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Inputs, Outputs } from "./generated/inputs-outputs";
import { BuildahCli, BuildahConfigSettings } from "./buildah";
import {
getArch, getContainerfiles, getInputList, splitByNewline,
isFullImageName, getFullImageName,
} from "./utils";

export async function run(): Promise<void> {
Expand All @@ -30,16 +31,26 @@ export async function run(): Promise<void> {
const DEFAULT_TAG = "latest";
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
const containerFiles = getContainerfiles();
const image = core.getInput(Inputs.IMAGE, { required: true });
const image = core.getInput(Inputs.IMAGE);
const tags = core.getInput(Inputs.TAGS);
const tagsList: string[] = tags.split(" ");
const tagsList: string[] = tags.trim().split(/\s+/);

// info message if user doesn't provides any tag
if (tagsList.length === 0) {
core.info(`Input "${Inputs.TAGS}" is not provided, using default tag "${DEFAULT_TAG}"`);
tagsList.push(DEFAULT_TAG);
}
const newImage = `${image}:${tagsList[0]}`;

// check if all tags provided are in `image:tag` format
const isFullImageNameTag = isFullImageName(tagsList[0]);
if (tagsList.some((tag) => isFullImageName(tag) !== isFullImageNameTag)) {
throw new Error(`Input "${Inputs.TAGS}" cannot have a mix of full name and non full name tags`);
}
if (!isFullImageNameTag && !image) {
throw new Error(`Input "${Inputs.IMAGE}" must be provided when using non full name tags`);
}

const newImage = getFullImageName(image, tagsList[0]);
const useOCI = core.getInput(Inputs.OCI) === "true";

const arch = getArch();
Expand All @@ -56,7 +67,7 @@ export async function run(): Promise<void> {
}
core.setOutput(Outputs.IMAGE, image);
core.setOutput(Outputs.TAGS, tags);
core.setOutput(Outputs.IMAGE_WITH_TAG, `${image}:${tagsList[0]}`);
core.setOutput(Outputs.IMAGE_WITH_TAG, newImage);
}

async function doBuildUsingContainerFiles(
Expand Down
11 changes: 11 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ export function getInputList(name: string): string[] {
[],
);
}

export function isFullImageName(image: string): boolean {
return image.indexOf(":") > 0;
}

export function getFullImageName(image: string, tag: string): string {
if (isFullImageName(tag)) {
return tag;
}
return `${image}:${tag}`;
}

0 comments on commit 979e6a6

Please sign in to comment.