name: Image

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
    types: [ labeled, unlabeled, opened, synchronize, reopened ]

env:
  GOLANG_VERSION: '1.18'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  publish:
    if: github.repository == 'argoproj/argo-cd'
    runs-on: ubuntu-latest
    env:
      GOPATH: /home/runner/work/argo-cd/argo-cd
    steps:
      - uses: actions/setup-go@v1
        with:
          go-version: ${{ env.GOLANG_VERSION }}
      - uses: actions/checkout@master
        with:
          path: src/github.com/argoproj/argo-cd

      # get image tag
      - run: echo ::set-output name=tag::$(cat ./VERSION)-${GITHUB_SHA::8}
        working-directory: ./src/github.com/argoproj/argo-cd
        id: image

      # login
      - run: |
          docker login ghcr.io --username $USERNAME --password $PASSWORD
          docker login quay.io --username "${DOCKER_USERNAME}" --password "${DOCKER_TOKEN}"
        if: github.event_name == 'push'
        env:
          USERNAME: ${{ secrets.USERNAME }}
          PASSWORD: ${{ secrets.TOKEN }}
          DOCKER_USERNAME: ${{ secrets.RELEASE_QUAY_USERNAME }}
          DOCKER_TOKEN: ${{ secrets.RELEASE_QUAY_TOKEN }}

      # build
      - uses: docker/setup-qemu-action@v1
      - uses: docker/setup-buildx-action@v1

      - name: Setup cache for argocd-ui docker layer
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-single-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-single-buildx

      - name: Build cache for argocd-ui stage
        uses: docker/build-push-action@v2
        with:
          context: ./src/github.com/argoproj/argo-cd
          target: argocd-ui
          push: false
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
        if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'test-arm-image')

      - name: Run non-container Snyk scans
        if: github.event_name == 'push'
        working-directory: ./src/github.com/argoproj/argo-cd
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        run: |
          npm install -g snyk

          # Run with high threshold to fail build.
          snyk test --org=argoproj --all-projects --exclude=docs,site --severity-threshold=high --policy-path=.snyk
          snyk iac test manifests/install.yaml --org=argoproj --severity-threshold=high --policy-path=.snyk

      - run: |
          IMAGE_PLATFORMS=linux/amd64
          if [[ "${{ github.event_name }}" == "push" || "${{ contains(github.event.pull_request.labels.*.name, 'test-arm-image') }}" == "true" ]]
          then
            IMAGE_PLATFORMS=linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
          fi
          echo "Building image for platforms: $IMAGE_PLATFORMS"
          docker buildx build --platform $IMAGE_PLATFORMS --push="${{ github.event_name == 'push' }}" \
            --cache-from "type=local,src=/tmp/.buildx-cache" \
            -t ghcr.io/argoproj/argocd:${{ steps.image.outputs.tag }} \
            -t quay.io/argoproj/argocd:latest .
        working-directory: ./src/github.com/argoproj/argo-cd

      - name: Run container Snyk scan
        if: github.event_name == 'push'
        working-directory: ./src/github.com/argoproj/argo-cd
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        run: |
          snyk container test quay.io/argoproj/argocd:latest --org=argoproj --file=Dockerfile --severity-threshold=high

        # Temp fix
        # https://github.com/docker/build-push-action/issues/252
        # https://github.com/moby/buildkit/issues/1896
      - name: Clean up build cache
        run: |
          rm -rf /tmp/.buildx-cache
          mv /tmp/.buildx-cache-new /tmp/.buildx-cache
        if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'test-arm-image')

      # deploy
      - run: git clone "https://$TOKEN@github.com/argoproj/argoproj-deployments"
        if: github.event_name == 'push'
        env:
          TOKEN: ${{ secrets.TOKEN }}
      - run: |
          docker run -u $(id -u):$(id -g) -v $(pwd):/src -w /src --rm -t ghcr.io/argoproj/argocd:${{ steps.image.outputs.tag }} kustomize edit set image quay.io/argoproj/argocd=ghcr.io/argoproj/argocd:${{ steps.image.outputs.tag }}
          git config --global user.email 'ci@argoproj.com'
          git config --global user.name 'CI'
          git diff --exit-code && echo 'Already deployed' || (git commit -am 'Upgrade argocd to ${{ steps.image.outputs.tag }}' && git push)
        if: github.event_name == 'push'
        working-directory: argoproj-deployments/argocd
      # TODO: clean up old images once github supports it: https://github.community/t5/How-to-use-Git-and-GitHub/Deleting-images-from-GitHub-Package-Registry/m-p/41202/thread-id/9811
