Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor inputs to support docker/metadata-action #76

Merged
merged 2 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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}`;
}