Skip to content

Instantly share code, notes, and snippets.

@jimangel
Created March 27, 2024 19:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimangel/e135b251d801f9bc1440d058dc9a6f98 to your computer and use it in GitHub Desktop.
Save jimangel/e135b251d801f9bc1440d058dc9a6f98 to your computer and use it in GitHub Desktop.
Cool Dockerfile build CI pipeline using GitHub Actions

From: https://github.com/firepress-org/rclone-in-docker/blob/master/.github/workflows/ci_dockerfile_is_master.yml

# The beauty of this CI setup is that it will build any valid DOCKERFILE by setting a few variables.
# See how at https://github.com/firepress-org/rclone-in-docker/blob/master/README-CI.md
# Requires secrets on github: DOCKERHUB_PASSWORD, TOKEN_SLACK
# Update DOCKERFILE_NAME if you are using a special Dockerfile name
# The way we define variables is a hack. See why: https://bit.ly/2ZEAt6u
#
# GNU v3 | Please credit the author if you are re-using some of it :-p
# by Pascal Andy | https://pascalandy.com/blog/now/

name: ci_dockerfile_is_master
on:
  schedule:
    - cron: '0 8 * * *'
  push:
    branches:
      - master
jobs:

  Job1:
    name: Job 1 of 2
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master

      - name: Define variables
        run: |
          # Hard coded variable
          echo "Dockerfile" > DOCKERFILE_NAME
          #
          # Logically defined variable from the Dockerfile
          cat $(cat DOCKERFILE_NAME) | grep DOCKERHUB_USER= | head -n 1 | grep -o '".*"' | sed 's/"//g' > DOCKERHUB_USER
          cat $(cat DOCKERFILE_NAME) | grep APP_NAME= | head -n 1 | grep -o '".*"' | sed 's/"//g' > APP_NAME
          cat $(cat DOCKERFILE_NAME) | grep VERSION= | head -n 1 | grep -o '".*"' | sed 's/"//g' > VERSION
          cat $(cat DOCKERFILE_NAME) | grep GITHUB_ORG= | head -n 1 | grep -o '".*"' | sed 's/"//g' > GITHUB_ORG
          cat $(cat DOCKERFILE_NAME) | grep GITHUB_REGISTRY= | head -n 1 | grep -o '".*"' | sed 's/"//g' > GITHUB_REGISTRY
          echo "$(cat DOCKERHUB_USER)/$(cat APP_NAME)" > DKR_HUB_URL
          echo "docker.pkg.github.com/$(cat GITHUB_ORG)/$(cat GITHUB_REGISTRY)/$(cat APP_NAME)" > GPR_URL
          date -d "-4 hours" "+%Y-%m-%d_%HH%Ms%S" > DATE_TIME
          git rev-parse --short HEAD > SHORT_COMMIT_HASH
          #
          # Four (stable) tags are logically defined
          echo "$(cat DKR_HUB_URL):latest" > TAG_LATEST
          echo "$(cat DKR_HUB_URL):stable" > TAG_STABLE
          echo "$(cat DKR_HUB_URL):$(cat VERSION)" > TAG_VERSION
          echo "$(cat DKR_HUB_URL):$(cat VERSION)_$(cat DATE_TIME)_$(cat SHORT_COMMIT_HASH)" > TAG_BEST_PRACTICE
          # for Github Package Registry (GPR)
          echo "$(cat GPR_URL):latest" > TAG_LATEST_GPR
          echo "$(cat GPR_URL):stable" > TAG_STABLE_GPR
          echo "$(cat GPR_URL):$(cat VERSION)" > TAG_VERSION_GPR
          echo "$(cat GPR_URL):$(cat VERSION)_$(cat DATE_TIME)_$(cat SHORT_COMMIT_HASH)" > TAG_BEST_PRACTICE_GPR

      - name: Build
        run: |
          # UAT is User Acceptance Testing
          echo "$(cat APP_NAME):uat" > TAG_UAT
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_UAT) .
          # for Docker hub
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_BEST_PRACTICE) .
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_VERSION) .
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_STABLE) .
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_LATEST) .
          # for GPR
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_BEST_PRACTICE_GPR) .
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_VERSION_GPR) .
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_STABLE_GPR) .
          docker build --file $(cat DOCKERFILE_NAME) --tag $(cat TAG_LATEST_GPR) .

      - name: Test image with docker-library
        run: |
          git clone --depth 1 https://github.com/docker-library/official-images.git official-images
          # override config.sh. Why: 1) UTC timezone 2) ghost-basic is configure to check the commit between the image of the official docker image of Ghost.
          cp ./test/config.sh official-images/test/config.sh
          official-images/test/run.sh $(cat TAG_UAT)

      - name: Logs / All tags & variables
        run: |
          echo "Check out https://hub.docker.com/r/$(cat DOCKERHUB_USER)/$(cat APP_NAME)/tags"
          echo " "
          echo "$(cat TAG_BEST_PRACTICE) < TAG_BEST_PRACTICE"
          echo "$(cat TAG_VERSION) < TAG_VERSION"
          echo "$(cat TAG_STABLE) < TAG_STABLE"
          echo "$(cat TAG_LATEST) < TAG_LATEST"
          echo " "
          echo "$(cat TAG_BEST_PRACTICE_GPR) < TAG_BEST_PRACTICE_GPR"
          echo "$(cat TAG_VERSION_GPR) < TAG_VERSION_GPR"
          echo "$(cat TAG_STABLE_GPR) < TAG_STABLE_GPR"
          echo "$(cat TAG_LATEST_GPR) < TAG_LATEST_GPR"
          echo " "
          echo "$(cat APP_NAME) < APP_NAME"
          echo "$(cat VERSION) < VERSION"
          echo "$(cat DOCKERFILE_NAME) < DOCKERFILE_NAME"
          echo " "
          echo "$(cat DATE_TIME) < DATE_TIME"
          echo "$(cat SHORT_COMMIT_HASH) < SHORT_COMMIT_HASH"
          echo "$(cat DOCKERHUB_USER) < DOCKERHUB_USER"
          echo "$(cat GITHUB_ORG) < GITHUB_ORG"
          echo "$(cat DKR_HUB_URL) < DKR_HUB_URL"
          echo "$(cat GPR_URL) < GPR_URL"
          echo "$(cat GITHUB_REGISTRY) < GITHUB_REGISTRY"

      - name: Logs / docker (inspect, history, version, info), uname
        run: |
          docker inspect $(cat TAG_UAT)
          docker history $(cat TAG_UAT) --no-trunc
          docker version
          docker info
          uname -a

      - name: Publish on Docker hub
        run: |
          echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login --username $(cat DOCKERHUB_USER) --password-stdin
          docker push $(cat TAG_LATEST)
          docker push $(cat TAG_STABLE)
          docker push $(cat TAG_VERSION)
          docker push $(cat TAG_BEST_PRACTICE)

      - name: Publish to GPR
        if: always()
        # As GPR is in beta, it sometimes does not work as expected
        run: |
          echo ${{ secrets.TOKEN_GPR }} | docker login docker.pkg.github.com --username $(cat GITHUB_ORG) --password-stdin
          docker push $(cat TAG_LATEST_GPR)
          docker push $(cat TAG_STABLE_GPR)
          docker push $(cat TAG_VERSION_GPR)
          docker push $(cat TAG_BEST_PRACTICE_GPR)

  Job2:
    needs: job1
    name: Job 2 of 2
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master

      - name: Define variables
        run: |
          echo "Dockerfile" > DOCKERFILE_NAME
          echo "devmtl/noti:stable" > IMG_NOTI
          cat $(cat DOCKERFILE_NAME) | grep DOCKERHUB_USER= | head -n 1 | grep -o '".*"' | sed 's/"//g' > DOCKERHUB_USER
          cat $(cat DOCKERFILE_NAME) | grep APP_NAME= | head -n 1 | grep -o '".*"' | sed 's/"//g' > APP_NAME
          cat $(cat DOCKERFILE_NAME) | grep VERSION= | head -n 1 | grep -o '".*"' | sed 's/"//g' > VERSION
          git rev-parse --short HEAD > SHORT_COMMIT_HASH
          echo "$(cat APP_NAME):$(cat VERSION) / $(cat SHORT_COMMIT_HASH)" > NOTI_MESSAGE
          # Tags are logically defined (needed by Aquasec microscanner)
          echo "$(cat DOCKERHUB_USER)/$(cat APP_NAME)" > DKR_HUB_URL
          echo "$(cat DKR_HUB_URL):latest" > TAG_LATEST

      - name: Push README to dockerhub description
        run: |
          docker run --rm \
            -v $(pwd)/README.md:/data/README.md \
            -e DOCKERHUB_USERNAME=$(cat DOCKERHUB_USER) \
            -e DOCKERHUB_PASSWORD=${{ secrets.DOCKERHUB_PASSWORD }} \
            -e DOCKERHUB_REPO_PREFIX=$(cat DOCKERHUB_USER) \
            -e DOCKERHUB_REPO_NAME=$(cat APP_NAME) \
            devmtl/readme-to-dockerhub:stable

      - name: Notify on Slack
        run: |
          docker run --rm \
            --name noti \
            -e NOTI_MESSAGE="$(cat NOTI_MESSAGE)" \
            -e SLACK_CHANNEL="github-actions" \
            -e SLACK_TOKEN_CRON="${{ secrets.TOKEN_SLACK }}" \
            $(cat IMG_NOTI) sh -c \
              ' NOTI_SLACK_TOKEN="$SLACK_TOKEN_CRON" \
                NOTI_SLACK_CHANNEL="$SLACK_CHANNEL" \
                noti -k -m "$NOTI_MESSAGE" '

      - name: Test image with Aquasec microscanner
        run: |
          wget --retry-connrefused --waitretry=1 --read-timeout=5 --timeout=5 --tries=10 https://raw.githubusercontent.com/lukebond/microscanner-wrapper/master/scan.sh && chmod +x scan.sh
          #
          docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest \
            --exit-code 0 $(cat TAG_LATEST)

      #- name: Github Actions ideas to implements
      #  run: |
      #    echo "see —> https://gist.github.com/pascalandy/4e499b7c42023836a7d207277923fc09"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment