Mars CD for DockerHub workflow (mars-project/mars)
The Mars CD for DockerHub workflow from mars-project/mars, explained and optimized by Latchkey.
CI health: B - good
Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Mars CD for DockerHub workflow from the mars-project/mars repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Mars CD for DockerHub
on:
schedule:
- cron: '0 18 * * *'
push:
tags:
- '*'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Log in to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Build and push Docker image
shell: bash
env:
DOCKER_ORG: ${{ secrets.DOCKERHUB_USERNAME }}
if: ${{ github.repository == 'mars-project/mars' }}
run: |
source ./ci/reload-env.sh
if [[ -n "$GIT_TAG" ]]; then
BRANCHES="$GIT_TAG"
echo "Will handle tag $BRANCHES"
else
MAINBRANCH=$(git rev-parse --abbrev-ref HEAD)
BRANCHES=$(git branch -r --list 'origin/v*' | sed 's/ *origin\///g')
BRANCHES="$MAINBRANCH $BRANCHES"
echo "Will handle branches:"
for branch in $BRANCHES; do
echo " $branch"
done
fi
if [[ "$DOCKER_ORG" == "marsuploader" ]]; then
export DOCKER_ORG="marsproject"
fi
for branch in $BRANCHES; do
if [[ -n "$GIT_TAG" ]]; then
export IMAGE_TAG="$GIT_TAG"
else
echo ""
git checkout $branch
git log --pretty=format:"%h - %an, %cd : %s" --since=25.hours
# consider schedule delay of Github Actions, some margin needed.
if [[ ! "$(git log --since=25.hours)" ]]; then
echo "No recent commits on branch $branch found, will skip building image."
continue
fi
export IMAGE_TAG="nightly-$branch"
fi
bash bin/kube-image-tool.sh -o "$DOCKER_ORG" -t "$IMAGE_TAG" build
docker push "$DOCKER_ORG/mars:$IMAGE_TAG"
done
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Mars CD for DockerHub on: schedule: - cron: '0 18 * * *' push: tags: - '*' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: timeout-minutes: 30 runs-on: latchkey-small steps: - name: Check out code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Log in to Docker Hub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Build and push Docker image shell: bash env: DOCKER_ORG: ${{ secrets.DOCKERHUB_USERNAME }} if: ${{ github.repository == 'mars-project/mars' }} run: | source ./ci/reload-env.sh if [[ -n "$GIT_TAG" ]]; then BRANCHES="$GIT_TAG" echo "Will handle tag $BRANCHES" else MAINBRANCH=$(git rev-parse --abbrev-ref HEAD) BRANCHES=$(git branch -r --list 'origin/v*' | sed 's/ *origin\///g') BRANCHES="$MAINBRANCH $BRANCHES" echo "Will handle branches:" for branch in $BRANCHES; do echo " $branch" done fi if [[ "$DOCKER_ORG" == "marsuploader" ]]; then export DOCKER_ORG="marsproject" fi for branch in $BRANCHES; do if [[ -n "$GIT_TAG" ]]; then export IMAGE_TAG="$GIT_TAG" else echo "" git checkout $branch git log --pretty=format:"%h - %an, %cd : %s" --since=25.hours # consider schedule delay of Github Actions, some margin needed. if [[ ! "$(git log --since=25.hours)" ]]; then echo "No recent commits on branch $branch found, will skip building image." continue fi export IMAGE_TAG="nightly-$branch" fi bash bin/kube-image-tool.sh -o "$DOCKER_ORG" -t "$IMAGE_TAG" build docker push "$DOCKER_ORG/mars:$IMAGE_TAG" done
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
1 third-party action is referenced by a movable tag. Pin it 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 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.