metadata-action/README.md
2021-02-09 20:54:44 +01:00

17 KiB

GitHub release GitHub marketplace Test workflow Codecov Become a sponsor Paypal Donate

About

GitHub Action to extract metadata (tags, labels) for Docker. This action is particularly useful if used with Docker Build Push action.

If you are interested, check out my other :octocat: GitHub Actions!

Screenshot


Usage

Basic

Event Ref Commit SHA Docker Tags
pull_request refs/pull/2/merge a123b57 pr-2
push refs/heads/master cf20257 master
push refs/heads/my/branch a5df687 my-branch
push tag refs/tags/v1.2.3 ad132f5 v1.2.3, latest
push tag refs/tags/v2.0.8-beta.67 fc89efd v2.0.8-beta.67, latest
name: ci

on:
  push:
    branches:
      - '**'
    tags:
      - 'v*'
  pull_request:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: name/app
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/amd64,linux/arm64,linux/386
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.docker_meta.outputs.tags }}
          labels: ${{ steps.docker_meta.outputs.labels }}

Semver

Event Ref Commit SHA Docker Tags
pull_request refs/pull/2/merge a123b57 pr-2
push refs/heads/master cf20257 master
push refs/heads/my/branch a5df687 my-branch
push tag refs/tags/v1.2.3 ad132f5 1.2.3, 1.2, latest
push tag refs/tags/v2.0.8-beta.67 fc89efd 2.0.8-beta.67
name: ci

on:
  push:
    branches:
      - '**'
    tags:
      - 'v*'
  pull_request:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: name/app
          tag-semver: |
            {{version}}
            {{major}}.{{minor}}            
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/amd64,linux/arm64,linux/386
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.docker_meta.outputs.tags }}
          labels: ${{ steps.docker_meta.outputs.labels }}

Bake definition

This action also handles a bake definition file that can be used with the Docker Bake action. You just have to declare an empty target named ghaction-docker-meta and inherit from it.

// docker-bake.hcl

target "ghaction-docker-meta" {}

target "build" {
  inherits = ["ghaction-docker-meta"]
  context = "./"
  dockerfile = "Dockerfile"
  platforms = ["linux/amd64", "linux/arm/v6", "linux/arm/v7", "linux/arm64", "linux/386", "linux/ppc64le"]
}
name: ci

on:
  push:
    branches:
      - '**'
    tags:
      - 'v*'
  pull_request:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: name/app
          tag-sha: true
          tag-semver: |
            {{version}}
            {{major}}.{{minor}}            
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Build
        uses: docker/bake-action@v1
        with:
          files: |
            ./docker-bake.hcl
            ${{ steps.docker_meta.outputs.bake-file }}            
          targets: |
            build            

Content of ${{ steps.docker_meta.outputs.bake-file }} file will look like this:

{
  "target": {
    "ghaction-docker-meta": {
      "tags": [
        "name/app:1.1.1",
        "name/app:1.1",
        "name/app:latest"
      ],
      "labels": {
        "org.opencontainers.image.title": "Hello-World",
        "org.opencontainers.image.description": "This your first repo!",
        "org.opencontainers.image.url": "https://github.com/octocat/Hello-World",
        "org.opencontainers.image.source": "https://github.com/octocat/Hello-World",
        "org.opencontainers.image.version": "1.1.1",
        "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z",
        "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071",
        "org.opencontainers.image.licenses": "MIT"
      },
      "args": {
        "DOCKER_META_IMAGES": "name/app",
        "DOCKER_META_VERSION": "1.1.1"
      }
    }
  }
}

Customizing

inputs

Following inputs can be used as step.with keys

List type is a newline-delimited string

label-custom: |
  org.opencontainers.image.title=MyCustomTitle
  org.opencontainers.image.description=Another description
  org.opencontainers.image.vendor=MyCompany  

CSV type is a comma-delimited string

images: name/app,ghcr.io/name/app
Name Type Description
images List/CSV List of Docker images to use as base name for tags
tag-sha Bool Add git short commit as Docker tag (default false)
tag-edge Bool Enable edge branch tagging (default false)
tag-edge-branch String Branch that will be tagged as edge (default repo.default_branch)
tag-semver List/CSV Handle Git tag as semver template if possible
tag-match String RegExp to match against a Git tag and use first match as Docker tag
tag-match-group Number Group to get if tag-match matches (default 0)
tag-latest Bool Set latest Docker tag if tag-semver, tag-match or Git tag event occurs (default true)
tag-schedule String Template to apply to schedule tag (default nightly)
tag-custom List/CSV List of custom tags
tag-custom-only Bool Only use tag-custom as Docker tags
label-custom List List of custom labels
sep-tags String Separator to use for tags output (default \n)
sep-labels String Separator to use for labels output (default \n)

tag-semver and tag-match are mutually exclusive

outputs

Following outputs are available

Name Type Description
version String Docker image version
tags String Docker tags
labels String Docker labels
bake-file File Bake definition file path

Notes

Latest tag

Latest Docker tag will be generated by default on push tag event. If for example you push the v1.2.3 Git tag, you will have at the output of this action the Docker tags v1.2.3 and latest. But you can allow the latest tag to be generated only if tag-semver is a valid semver or if Git tag matches a regular expression with the tag-match input. Can be disabled if tag-latest is false.

Handle semver tag

If Git tag is a valid semver you can handle it to output multi Docker tags at once. tag-semver supports multi-line Handlebars template with the following inputs:

Git tag tag-semver Valid Output tags Output version
v1.2.3 {{raw}} v1.2.3, latest v1.2.3
v1.2.3 {{version}} 1.2.3, latest 1.2.3
v1.2.3 {{major}}.{{minor}} 1.2, latest 1.2
v1.2.3 v{{major}} v1, latest v1
v1.2.3 {{minor}} 2, latest 2
v1.2.3 {{patch}} 3, latest 3
v1.2.3 {{major}}.{{minor}}
{{major}}.{{minor}}.{{patch}}
1.2, 1.2.3, latest 1.2*
v2.0.8-beta.67 {{raw}} 2.0.8-beta.67** 2.0.8-beta.67
v2.0.8-beta.67 {{version}} 2.0.8-beta.67 2.0.8-beta.67
v2.0.8-beta.67 {{major}}.{{minor}} 2.0.8-beta.67** 2.0.8-beta.67
release1 {{raw}} release1 release1

*First occurrence of tag-semver will be taken as output.version

**Pre-release (rc, beta, alpha) will only extend {{version}} as tag because they are updated frequently, and contain many breaking changes that are (by the author's design) not yet fit for public consumption.

tag-match examples

Git tag tag-match tag-match-group Match Output tags Output version
v1.2.3 \d{1,3}.\d{1,3}.\d{1,3} 0 1.2.3, latest 1.2.3
v2.0.8-beta.67 v(.*) 1 2.0.8-beta.67, latest 2.0.8-beta.67
v2.0.8-beta.67 v(\d.\d) 1 2.0, latest 2.0
release1 \d{1,3}.\d{1,3} 0 release1 release1
20200110-RC2 \d+ 0 20200110, latest 20200110

Schedule tag

tag-schedule is specially crafted input to support Handlebars template with the following expressions:

Expression Example Description
{{date 'format'}} {{date 'YYYYMMDD'}} > 20200110 Render date by its moment format

You can find more examples in the CI workflow.

Overwrite labels

If some of the OCI Image Format Specification labels generated are not suitable, you can overwrite them like this:

      -
        name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: name/app
          label-custom: |
            maintainer=CrazyMax
            org.opencontainers.image.title=MyCustomTitle
            org.opencontainers.image.description=Another description
            org.opencontainers.image.vendor=MyCompany            

Keep up-to-date with GitHub Dependabot

Since Dependabot has native GitHub Actions support, to enable it on your GitHub repo all you need to do is add the .github/dependabot.yml file:

version: 2
updates:
  # Maintain dependencies for GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"

Contributing

Want to contribute? Awesome! The most basic way to show your support is to star 🌟 the project, or to raise issues 💬. If you want to open a pull request, please read the contributing guidelines.

You can also support this project by becoming a sponsor on GitHub or by making a Paypal donation to ensure this journey continues indefinitely!

Thanks again for your support, it is much appreciated! 🙏

License

MIT. See LICENSE for more details.