Reputation: 1338
I'm using GitHub Actions to build a docker image using the build-push-action. I'd like to add tags to the image before pushing it to the docker registry:
latest
I have something along the lines of:
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
push: true
tags:
- user/image:latest
It would be easy to always add more tags, but I want to add it only if there's a git tag. Is there a way to do that?
Upvotes: 17
Views: 43329
Reputation: 1294
I was not able to use the above answers because they are triggered upon adding a tag, whereas I wanted it to be triggered by pushing to master
.
In my case, I would:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0 # Without this, this action won't be able to find any or the correct tags.
- name: 'Get tag'
id: tag
uses: 'WyriHaximus/github-action-get-previous-tag@8a0e045f02c0a3a04e1452df58b90fc7e555e950'
- name: Set correct environment
run: |
TAG=${{ steps.tag.outputs.tag }}
echo "TAG=$TAG" >> "$GITHUB_ENV"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Retrieve metadata
id: metadata
uses: docker/metadata-action@e5622373a38e60fb6d795a4421e56882f2d7a681
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
with:
images: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}
tags: |
type=semver,pattern={{major}}.{{minor}}.{{patch}},value=${{ env.TAG }}
type=semver,pattern={{major}}.{{minor}},value=${{ env.TAG }}
type=semver,pattern={{major}},value=${{ env.TAG }}
- name: Build and push
id: docker
uses: docker/build-push-action@v2
with:
push: true
tags: ${{ steps.metadata.outputs.tags }}
Upvotes: 3
Reputation: 1738
There's a docker/metadata-action
that does this. Make sure to set up the push tags trigger along with whatever other triggers you might need. The action docs have a lot more details about what tags it applies for each event trigger type. See also https://docs.github.com/en/actions/publishing-packages/publishing-docker-images for even more info on the general topic of Docker image publishing.
name: Tag Docker Image with Git
on:
push:
tags: [ v* ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Log into the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for the Docker image
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push the Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Upvotes: 22
Reputation: 4752
Maybe something like this:
- name: Build and push
id: gen_tags
run: |
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
TAGS='["user/image:latest","user/image:'${GITHUB_REF/refs\/tags\//}'"]'
else
TAGS='["user/image:latest"]'
fi
echo '::set-output name=tags::'$TAGS
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
needs: gen_tags
with:
context: .
push: true
tags: ${{ fromJson(steps.gen_tags.outputs.tags) }}
The first step generates the list of tags and the second build/push. if $GITHUB_REF
starts by refs/tags/
it is a tag and as such we generate a json list with both docker tags. Else, we use a list that contains only the latest
tag. Since we can only pass strings around, we have to output the json as a string and then parse it in the second step using fromJson
. I am sorry for the ugly escaping (you might actually have issues there and have to try few different solutions), but it's a bit tricky to do without making the script more complex.
Upvotes: 2
Reputation: 1338
I found a solution using a dedicated action. I create the tags in a separate step and add it afterwards. The relevant parts of the CI config look like this:
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: l7r7/sample
tag-custom: latest
tag-semver: |
{{raw}}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
push: false
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
To be precise, it's not exactly what I was asking for, because it will add a tag containing the branch name as well. But that's ok for me. I can live with that.
A full working example can be found here.
Upvotes: 8