<commit_before>name: Update Docker Images

on:
  schedule:
    - cron:  '0 1 * * *'
  workflow_dispatch:

defaults:
  run:
    shell: bash

env:
  DOCKER_BUILDKIT: 1
  K8S_VERSION: 1.21.1
  K8S_TIMEOUT: 75s

jobs:

  variables:
    name: Get versions of base images
    runs-on: ubuntu-20.04
    outputs:
      kic-tag: ${{ steps.kic.outputs.tag }}
      versions: ${{ steps.versions.outputs.matrix }}
      nginx_version: ${{ steps.versions.outputs.nginx_version }}
      sha_short: ${{ steps.vars.outputs.sha }}
      go_version: ${{ steps.vars.outputs.go_version }}
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Set KIC version
        id: kic
        run: |
          tag=$(git tag --sort=-version:refname | head -n1)
          echo "::set-output name=tag::${tag//v}"
      - name: Checkout Repository at ${{ steps.kic.outputs.tag }}
        run: |
          git checkout v${{ steps.kic.outputs.tag }}
      - name: Set NGINX versions
        id: versions
        run: |
          nginx=library/$(grep -m1 "FROM nginx:" < build/Dockerfile | awk -F" " '{print $2}')
          nginx_alpine=library/nginx:$(grep -m1 "FROM.*nginx.*alpine" < build/Dockerfile | awk -F"[ :]" '{print $3}')
          nginx_ubi=$(grep "FROM redhat" < build/Dockerfile | awk -F" " '{print $2}')
          echo "::set-output name=matrix::[{\"version\": \"${nginx}\", \"distro\": \"debian\"}, {\"version\": \"${nginx_alpine}\", \"distro\": \"alpine\"}, {\"version\": \"${nginx_ubi}\", \"distro\": \"ubi\"}]"
          echo "::set-output name=nginx_version::$(cat build/Dockerfile | grep -m1 "FROM nginx:" | cut -d":" -f2 | cut -d" " -f1)"
      - name: Set other variables
        id: vars
        run: |
          echo "::set-output name=sha::$(echo ${GITHUB_SHA} | cut -c1-7)"
          echo "::set-output name=go_version::$(grep "go 1." go.mod | cut -d " " -f 2)"

  check:
    name: Check if updates are needed
    runs-on: ubuntu-20.04
    needs: variables
    outputs:
      needs-updating-debian: ${{ steps.needs.outputs.debian }}
      needs-updating-alpine: ${{ steps.needs.outputs.alpine }}
      needs-updating-ubi: ${{ steps.needs.outputs.ubi }}
    strategy:
      matrix:
        base_image: ${{ fromJson(needs.variables.outputs.versions) }}
    steps:
      - name: Build KIC tag
        id: dist
        run: |
          if [ ${{ matrix.base_image.distro }} == "debian" ]; then dist=""; else dist="-${{ matrix.base_image.distro }}"; fi
          echo "::set-output name=tag::${{ needs.variables.outputs.kic-tag }}${dist}"
      - name: Check if update available for ${{ matrix.base_image.version }}
        id: update
        uses: lucacome/docker-image-update-checker@v1
        with:
          base-image: ${{ matrix.base_image.version}}
          image: nginx/nginx-ingress:${{ steps.dist.outputs.tag }}
      - id: needs
        run: echo "::set-output name=${{ matrix.base_image.distro }}::${{ steps.update.outputs.needs-updating }}"


  binary:
    if: ${{ needs.check.outputs.needs-updating-debian == 'true' || needs.check.outputs.needs-updating-alpine == 'true' || needs.check.outputs.needs-updating-ubi == 'true' }}
    name: Build binaries
    runs-on: ubuntu-20.04
    needs: [check, variables]
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
          ref: v${{ needs.variables.outputs.kic-tag }}
      - name: Setup Golang Environment
        uses: actions/setup-go@v2
        with:
          go-version: ${{ needs.variables.outputs.go_version }}
      - name: Determine GOPATH
        id: go
        run: echo "::set-output name=go_path::$(go env GOPATH)"
      - name: Build binaries
        uses: goreleaser/goreleaser-action@v2
        with:
          version: latest
          args: build --rm-dist --id kubernetes-ingress
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GOPATH: ${{ steps.go.outputs.go_path }}
      - name: Store Artifacts in Cache
        uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/dist
          key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }}

  release-docker:
    name: Release Images
    runs-on: ubuntu-20.04
    needs: [binary, check, variables]
    strategy:
      matrix:
        include:
          - tags: |
              nginx/nginx-ingress:${{ needs.variables.outputs.kic-tag }}
              nginx/nginx-ingress:latest
            type: debian
            platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x
            needs-updating: ${{ needs.check.outputs.needs-updating-debian }}
          - tags: |
              nginx/nginx-ingress:${{ needs.variables.outputs.kic-tag }}-alpine
              nginx/nginx-ingress:alpine
            type: alpine
            platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x
            needs-updating: ${{ needs.check.outputs.needs-updating-alpine }}
          - tags: |
              nginx/nginx-ingress:${{ needs.variables.outputs.kic-tag }}-ubi
              nginx/nginx-ingress:ubi
            type: ubi
            platforms: linux/arm64,linux/amd64
            needs-updating: ${{ needs.check.outputs.needs-updating-ubi }}
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
        with:
          ref: v${{ needs.variables.outputs.kic-tag }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Fetch Cached Artifacts
        uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/dist
          key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Setup QEMU
        uses: docker/setup-qemu-action@v1
        with:
          platforms: arm,arm64,ppc64le,s390x
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Docker Buildx
        uses: docker/setup-buildx-action@v1
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Build ${{ matrix.type }} Container for tests
        uses: docker/build-push-action@v2
        with:
          file: build/Dockerfile
          context: '.'
          cache-from: type=gha
          cache-to: type=gha,mode=max
          target: goreleaser
          tags: ${{ matrix.type }}:${{ github.sha }}
          load: true
          build-args: |
            BUILD_OS=${{ matrix.type }}
            NGINX_VERSION=${{ needs.variables.outputs.nginx_version }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Build Test-Runner Container
        uses: docker/build-push-action@v2
        with:
          file: tests/docker/Dockerfile
          context: '.'
          cache-from: type=gha
          cache-to: type=gha,mode=max
          tags: test-runner:${{ github.sha }}
          load: true
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Deploy Kubernetes
        id: k8s
        run: |
          kind create cluster --name ${{ github.run_id }} --image=kindest/node:v${{ env.K8S_VERSION }} --config ${{ github.workspace }}/tests/ci-files/ci-kind-config.yaml --kubeconfig kube-${{ github.run_id }} --wait ${{ env.K8S_TIMEOUT }}
          kind load docker-image ${{ matrix.type }}:${{ github.sha }} --name ${{ github.run_id }}
          echo ::set-output name=cluster_ip::$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${{ github.run_id }}-control-plane)
          echo ::set-output name=cluster::$(echo 'nginx-${{ matrix.type }}-vs')
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Setup Kubeconfig
        run: |
          sed -i 's|server:.*|server: https://${{ steps.k8s.outputs.cluster_ip }}:6443|' kube-${{ github.run_id }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Run Smoke Tests
        run: |
          touch tests-${{ steps.k8s.outputs.cluster }}.html
          docker run --rm \
          --name test-runner-${{ github.run_id }} \
          --network=kind \
          -v ${{ github.workspace }}/tests/tests-${{ steps.k8s.outputs.cluster }}.html:/workspace/tests/tests-${{ steps.k8s.outputs.cluster }}.html \
          -v ${{ github.workspace }}/kube-${{ github.run_id }}:/root/.kube/config test-runner:${{ github.sha }} \
          --context=kind-${{ github.run_id }} \
          --image=${{ matrix.type }}:${{ github.sha }} \
          --image-pull-policy=Never \
          --ic-type=nginx-ingress \
          --service=nodeport --node-ip=${{ steps.k8s.outputs.cluster_ip }} \
          --html=tests-${{ steps.k8s.outputs.cluster }}.html \
          --self-contained-html \
          --show-ic-logs=yes --profile \
          -m vs
        working-directory: ./tests
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Upload Test Results
        uses: actions/upload-artifact@v2
        with:
          name: test-results-${{ steps.k8s.outputs.cluster }}
          path: ${{ github.workspace }}/tests/tests-${{ steps.k8s.outputs.cluster }}.html
        if: always()
      - name: DockerHub Login
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Get date
        id: var
        run: |
          echo "::set-output name=date::$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Push to Dockerhub
        id: push
        uses: docker/build-push-action@v2
        with:
          file: build/Dockerfile
          context: '.'
          cache-from: type=gha
          cache-to: type=gha,mode=max
          target: goreleaser
          tags: ${{ matrix.tags }}
          platforms: ${{ matrix.platforms }}
          push: true
          build-args: |
            BUILD_OS=${{ matrix.type }}
            IC_VERSION=v${{ needs.variables.outputs.kic-tag }}-${{ needs.variables.outputs.sha_short }}
            NGINX_VERSION=${{ needs.variables.outputs.nginx_version }}
            DATE=${{ steps.var.outputs.date }}
            GIT_COMMIT=${{ github.sha }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Get variables for Slack
        id: slack
        run: |
          echo "::set-output name=message::$(git log -1 --pretty=%B)"
          echo "::set-output name=date::$(date +%s)"
      - name: Send Notification
        uses: 8398a7/action-slack@v3
        with:
          status: custom
          custom_payload: |
            {
              username: "Docker",
              icon_emoji: ":docker:",
              mention: "here",
              attachments: [{
                title: `New Docker image was pushed to DockerHub for ${process.env.AS_REPO}`,
                color: "good",
                fields: [{
                  title: "Docker Image",
                  value: "<https://hub.docker.com/r/nginx/nginx-ingress/tags?page=1&ordering=last_updated&name=${{ needs.variables.outputs.kic-tag }}|nginx/nginx-ingress:${{ matrix.tag }}>",
                  short: true
                },
                {
                  title: "Image digest",
                  value: "${{ steps.push.outputs.digest }}",
                  short: true
                },
                {
                  title: "Commit Message",
                  value: "${{ steps.slack.outputs.message }}",
                  short: true
                },
                {
                  title: "Commit Hash",
                  value: "${{ needs.variables.outputs.sha_short }}",
                  short: true
                }],
                footer: "Update DockerHub Image",
                footer_icon: "https://raw.githubusercontent.com/docker-library/docs/c350af05d3fac7b5c3f6327ac82fe4d990d8729c/docker/logo.png",
                ts: ${{ steps.slack.outputs.date }}
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
        if: ${{ matrix.needs-updating == 'true' }}
<commit_msg>Update Docker Images workflow for v2.0 (#2027)<commit_after>name: Update Docker Images

on:
  schedule:
    - cron:  '0 1 * * *'
  workflow_dispatch:

defaults:
  run:
    shell: bash

env:
  DOCKER_BUILDKIT: 1
  K8S_TIMEOUT: 75s

jobs:

  variables:
    name: Get versions of base images
    runs-on: ubuntu-20.04
    outputs:
      kic-tag: ${{ steps.kic.outputs.tag }}
      versions: ${{ steps.versions.outputs.matrix }}
      sha_short: ${{ steps.vars.outputs.sha }}
      go_version: ${{ steps.vars.outputs.go_version }}
      k8s_version: ${{ steps.vars.outputs.k8s_version }}
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Set KIC version
        id: kic
        run: |
          tag=$(git tag --sort=-version:refname | head -n1)
          echo "::set-output name=tag::${tag//v}"
      - name: Checkout Repository at ${{ steps.kic.outputs.tag }}
        uses: actions/checkout@v2
        with:
          ref: v${{ steps.kic.outputs.tag }}
      - name: Set NGINX versions
        id: versions
        run: |
          nginx=library/$(grep -m1 "FROM nginx:" < build/Dockerfile | awk -F" " '{print $2}')
          nginx_alpine=library/nginx:$(grep -m1 "FROM.*nginx.*alpine" < build/Dockerfile | awk -F"[ :]" '{print $3}')
          nginx_ubi=$(grep "FROM redhat" < build/Dockerfile | awk -F" " '{print $2}')
          echo "::set-output name=matrix::[{\"version\": \"${nginx}\", \"distro\": \"debian\"}, {\"version\": \"${nginx_alpine}\", \"distro\": \"alpine\"}, {\"version\": \"${nginx_ubi}\", \"distro\": \"ubi\"}]"
      - name: Set other variables
        id: vars
        run: |
          echo "::set-output name=sha::$(echo ${GITHUB_SHA} | cut -c1-7)"
          echo "::set-output name=go_version::$(grep "go 1." go.mod | cut -d " " -f 2)"
          echo "::set-output name=k8s_version::$(grep "K8S_VERSION:" .github/workflows/ci.yml | awk -F" " '{print $2}')"

  check:
    name: Check if updates are needed
    runs-on: ubuntu-20.04
    needs: variables
    outputs:
      needs-updating-debian: ${{ steps.needs.outputs.debian }}
      needs-updating-alpine: ${{ steps.needs.outputs.alpine }}
      needs-updating-ubi: ${{ steps.needs.outputs.ubi }}
    strategy:
      matrix:
        base_image: ${{ fromJson(needs.variables.outputs.versions) }}
    steps:
      - name: Build KIC tag
        id: dist
        run: |
          if [ ${{ matrix.base_image.distro }} == "debian" ]; then dist=""; else dist="-${{ matrix.base_image.distro }}"; fi
          echo "::set-output name=tag::${{ needs.variables.outputs.kic-tag }}${dist}"
      - name: Check if update available for ${{ matrix.base_image.version }}
        id: update
        uses: lucacome/docker-image-update-checker@v1
        with:
          base-image: ${{ matrix.base_image.version}}
          image: nginx/nginx-ingress:${{ steps.dist.outputs.tag }}
      - id: needs
        run: echo "::set-output name=${{ matrix.base_image.distro }}::${{ steps.update.outputs.needs-updating }}"


  binary:
    if: ${{ needs.check.outputs.needs-updating-debian == 'true' || needs.check.outputs.needs-updating-alpine == 'true' || needs.check.outputs.needs-updating-ubi == 'true' }}
    name: Build binaries
    runs-on: ubuntu-20.04
    needs: [check, variables]
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
          ref: v${{ needs.variables.outputs.kic-tag }}
      - name: Setup Golang Environment
        uses: actions/setup-go@v2
        with:
          go-version: ${{ needs.variables.outputs.go_version }}
      - name: Determine GOPATH
        id: go
        run: echo "::set-output name=go_path::$(go env GOPATH)"
      - name: Build binaries
        uses: goreleaser/goreleaser-action@v2
        with:
          version: latest
          args: build --rm-dist --id kubernetes-ingress
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GOPATH: ${{ steps.go.outputs.go_path }}
      - name: Store Artifacts in Cache
        uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/dist
          key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }}

  release-docker:
    name: Release Images
    runs-on: ubuntu-20.04
    needs: [binary, check, variables]
    strategy:
      matrix:
        include:
          - image: debian
            marker: ingresses
            platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x
            needs-updating: ${{ needs.check.outputs.needs-updating-debian }}
          - image: alpine
            marker: vsr
            platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x
            needs-updating: ${{ needs.check.outputs.needs-updating-alpine }}
          - image: opentracing
            marker: vs
            platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x
            needs-updating: ${{ needs.check.outputs.needs-updating-debian }}
          - image: ubi
            marker: ts
            platforms: linux/arm64,linux/amd64
            needs-updating: ${{ needs.check.outputs.needs-updating-ubi }}
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
        with:
          ref: v${{ needs.variables.outputs.kic-tag }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Fetch Cached Artifacts
        uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/dist
          key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Run Smoke Tests
        id: smoke-tests
        uses: ./.github/actions/smoke-tests
        with:
          image: ${{ matrix.image }}
          marker: ${{ matrix.marker }}
          k8s-version: ${{ needs.variables.outputs.k8s_version }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Upload Test Results
        uses: actions/upload-artifact@v2
        with:
          name: ${{ steps.smoke-tests.outputs.test-results-name }}
          path: ${{ github.workspace }}/tests/${{ steps.smoke-tests.outputs.test-results-name }}.html
        if: always()
      - name: Setup QEMU
        uses: docker/setup-qemu-action@v1
        with:
          platforms: arm,arm64,ppc64le,s390x
        if: ${{ matrix.needs-updating == 'true' }}
      - name: DockerHub Login
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Get short tag
        id: tag
        run: |
          version=${{ needs.variables.outputs.kic-tag }}
          short="${version%.*}"
          echo "::set-output name=short::$short"
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v3
        with:
          images: nginx/nginx-ingress
          flavor: |
            latest=true
            suffix=${{ matrix.image != 'debian' && '-' || '' }}${{ matrix.image != 'debian' && matrix.image != 'opentracing' && matrix.image || '' }}${{ matrix.image == 'opentracing' && 'ot' || '' }},onlatest=true
          tags: |
            type=raw,value=${{ needs.variables.outputs.kic-tag }}
            type=raw,value=${{ steps.tag.outputs.short }}
          labels: |
            org.opencontainers.image.description=NGINX Ingress Controller for Kubernetes
            org.opencontainers.image.documentation=https://docs.nginx.com/nginx-ingress-controller
            org.opencontainers.image.vendor=NGINX Inc <<EMAIL>>
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Push to Dockerhub
        id: push
        uses: docker/build-push-action@v2
        with:
          file: build/Dockerfile
          context: '.'
          cache-from: type=gha
          cache-to: type=gha,mode=max
          target: goreleaser
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          platforms: ${{ matrix.platforms }}
          push: true
          build-args: |
            BUILD_OS=${{ matrix.image }}
            IC_VERSION=v${{ needs.variables.outputs.kic-tag }}
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        continue-on-error: true
        with:
          image-ref: nginx/nginx-ingress:${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
          format: 'template'
          template: '@/contrib/sarif.tpl'
          output: 'trivy-results-${{ matrix.image }}.sarif'
          ignore-unfixed: 'true'
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v1
        continue-on-error: true
        with:
          sarif_file: 'trivy-results-${{ matrix.image }}.sarif'
        if: ${{ matrix.needs-updating == 'true' }}
      - name: Upload Scan Results
        uses: actions/upload-artifact@v2
        continue-on-error: true
        with:
          name: 'trivy-results-${{ matrix.image }}.sarif'
          path: 'trivy-results-${{ matrix.image }}.sarif'
        if: always()
      - name: Get variables for Slack
        id: slack
        run: |
          echo "::set-output name=message::$(git log -1 --pretty=%B)"
          echo "::set-output name=date::$(date +%s)"
      - name: Send Notification
        uses: 8398a7/action-slack@v3
        with:
          status: custom
          custom_payload: |
            {
              username: "Docker",
              icon_emoji: ":docker:",
              mention: "here",
              attachments: [{
                title: `New Docker image was pushed to DockerHub for ${process.env.AS_REPO}`,
                color: "good",
                fields: [{
                  title: "Docker Image",
                  value: "<https://hub.docker.com/r/nginx/nginx-ingress/tags?page=1&ordering=last_updated&name=${{ needs.variables.outputs.kic-tag }}|nginx/nginx-ingress:${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}>",
                  short: true
                },
                {
                  title: "Image digest",
                  value: "${{ steps.push.outputs.digest }}",
                  short: true
                },
                {
                  title: "Commit Message",
                  value: "${{ steps.slack.outputs.message }}",
                  short: true
                },
                {
                  title: "Commit Hash",
                  value: "${{ needs.variables.outputs.sha_short }}",
                  short: true
                }],
                footer: "Update DockerHub Image",
                footer_icon: "https://raw.githubusercontent.com/docker-library/docs/c350af05d3fac7b5c3f6327ac82fe4d990d8729c/docker/logo.png",
                ts: ${{ steps.slack.outputs.date }}
              }]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
        if: ${{ matrix.needs-updating == 'true' }}

{'fraction_non_alphanumeric': 0.15416970685437142, 'fraction_numerical': 0.0113309584102322, 'mean_word_length': 1.9176058101677937, 'pattern_counts': {'":': 37, '<': 13, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '357418', 'n_tokens_mistral': 7724, 'n_tokens_neox': 7188, 'n_words': 1437}