Skip to content
Latchkey

Publish Docker workflow (jorisroovers/gitlint)

The Publish Docker workflow from jorisroovers/gitlint, explained and optimized by Latchkey.

B

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 →
Source: jorisroovers/gitlint.github/workflows/publish-docker.ymlLicense MITView source

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

workflow (.yml)
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_dockerhub

The 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

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:

This workflow runs 2 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow