Publish Docker workflow (jorisroovers/gitlint)
The Publish Docker workflow from jorisroovers/gitlint, explained and optimized by Latchkey.
CI health: B - good
Run this on Latchkey for self-healing, caching, and up to 58% lower cost.
Grade your own workflow free or run it on Latchkey →What it does
This is the Publish Docker workflow from the jorisroovers/gitlint repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Publish Docker
run-name: "Publish Docker (gitlint_version=${{ inputs.gitlint_version }}, docker_image_tag=${{ inputs.docker_image_tag }})"
on:
workflow_call:
inputs:
gitlint_version:
description: "Gitlint version to build docker image for"
required: true
type: string
docker_image_tag:
description: "Docker image tag"
required: true
type: string
push_to_dockerhub:
description: "Push to dockerhub.com"
required: false
type: boolean
default: false
workflow_dispatch:
inputs:
gitlint_version:
description: "Gitlint version to build docker image for"
type: string
docker_image_tag:
description: "Docker image tag"
required: true
type: choice
options:
- "latest_dev"
- "latest"
- "Use $gitlint_version"
default: "Use $gitlint_version"
push_to_dockerhub:
description: "Push to dockerhub.com"
required: false
type: boolean
default: false
jobs:
publish-docker:
runs-on: "ubuntu-latest"
outputs:
docker_image_tag: ${{ steps.set_tag.outputs.docker_image_tag }}
steps:
- name: Determine docker tag
id: set_tag
run: |
if [[ "${{ inputs.docker_image_tag }}" == "Use $gitlint_version" ]]; then
echo "docker_image_tag=${{ inputs.gitlint_version }}" >> $GITHUB_OUTPUT
else
echo "docker_image_tag=${{ inputs.docker_image_tag }}" >> $GITHUB_OUTPUT
fi
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: jorisroovers
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build docker image
uses: docker/build-push-action@v4
with:
build-args: GITLINT_VERSION=${{ inputs.gitlint_version }}
tags: jorisroovers/gitlint:${{ steps.set_tag.outputs.docker_image_tag }}
- name: Test docker image (local)
run: |
gitlint_version=$(docker run --ulimit nofile=1024 -v $(pwd):/repo jorisroovers/gitlint:${{ steps.set_tag.outputs.docker_image_tag }} --version)
echo "$gitlint_version == 'gitlint, version ${{ inputs.gitlint_version }}'"
[ "$gitlint_version" == "gitlint, version ${{ inputs.gitlint_version }}" ]
# This won't actually rebuild the docker image, but just push the previously built and cached image
- name: Push docker image
uses: docker/build-push-action@v4
with:
push: ${{ inputs.push_to_dockerhub }}
build-args: GITLINT_VERSION=${{ inputs.gitlint_version }}
tags: jorisroovers/gitlint:${{ steps.set_tag.outputs.docker_image_tag }}
if: inputs.push_to_dockerhub
# Retest docker image after publishing
test-docker:
needs:
- publish-docker
uses: ./.github/workflows/test-docker.yml
with:
docker_image_tag: ${{ needs.publish-docker.outputs.docker_image_tag }}
gitlint_version: ${{ inputs.gitlint_version }}
if: inputs.push_to_dockerhubThe same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Publish Docker run-name: "Publish Docker (gitlint_version=${{ inputs.gitlint_version }}, docker_image_tag=${{ inputs.docker_image_tag }})" on: workflow_call: inputs: gitlint_version: description: "Gitlint version to build docker image for" required: true type: string docker_image_tag: description: "Docker image tag" required: true type: string push_to_dockerhub: description: "Push to dockerhub.com" required: false type: boolean default: false workflow_dispatch: inputs: gitlint_version: description: "Gitlint version to build docker image for" type: string docker_image_tag: description: "Docker image tag" required: true type: choice options: - "latest_dev" - "latest" - "Use $gitlint_version" default: "Use $gitlint_version" push_to_dockerhub: description: "Push to dockerhub.com" required: false type: boolean default: false jobs: publish-docker: timeout-minutes: 30 runs-on: "ubuntu-latest" outputs: docker_image_tag: ${{ steps.set_tag.outputs.docker_image_tag }} steps: - name: Determine docker tag id: set_tag run: | if [[ "${{ inputs.docker_image_tag }}" == "Use $gitlint_version" ]]; then echo "docker_image_tag=${{ inputs.gitlint_version }}" >> $GITHUB_OUTPUT else echo "docker_image_tag=${{ inputs.docker_image_tag }}" >> $GITHUB_OUTPUT fi - name: Login to Docker Hub uses: docker/login-action@v2 with: username: jorisroovers password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build docker image uses: docker/build-push-action@v4 with: build-args: GITLINT_VERSION=${{ inputs.gitlint_version }} tags: jorisroovers/gitlint:${{ steps.set_tag.outputs.docker_image_tag }} - name: Test docker image (local) run: | gitlint_version=$(docker run --ulimit nofile=1024 -v $(pwd):/repo jorisroovers/gitlint:${{ steps.set_tag.outputs.docker_image_tag }} --version) echo "$gitlint_version == 'gitlint, version ${{ inputs.gitlint_version }}'" [ "$gitlint_version" == "gitlint, version ${{ inputs.gitlint_version }}" ] # This won't actually rebuild the docker image, but just push the previously built and cached image - name: Push docker image uses: docker/build-push-action@v4 with: push: ${{ inputs.push_to_dockerhub }} build-args: GITLINT_VERSION=${{ inputs.gitlint_version }} tags: jorisroovers/gitlint:${{ steps.set_tag.outputs.docker_image_tag }} if: inputs.push_to_dockerhub # Retest docker image after publishing test-docker: timeout-minutes: 30 needs: - publish-docker uses: ./.github/workflows/test-docker.yml with: docker_image_tag: ${{ needs.publish-docker.outputs.docker_image_tag }} gitlint_version: ${{ inputs.gitlint_version }} if: inputs.push_to_dockerhub
What changed
- Add a job timeout so a hung step cannot burn hours of runner time.
2 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Container pulls and builds
This workflow runs 2 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.