name: 'Buildkit build and push image'
description: 'Build docker image using buildkits buildctl'
inputs:
  path:
    description: 'Root directory'
    required: false
    default: '.'
  context:
    description: 'Folder to use as context during image build'
    required: false
    default: '.'
  dockerfile:
    description: 'Dockerfile path to use for the build'
    required: false
    default: 'Dockerfile'
  platforms:
    description: 'Platform(s) that the image should be build for, multiple platforms can be specified comma separated (linux/amd64,linux/arm64)'
    required: true
    default: 'linux/amd64'
  tags:
    description: 'Tags to build to the image'
    required: true
    default: ''
  labels:
    description: 'Labels for the image'
    required: false
    default: ''
  buildkit-daemon-address:
    description: 'Address of the buildkit daemon to use'
    required: true
    default: 'tcp://buildkit-service.buildkit-service.svc:1234'
  buildkit-cert-ca-file:
    description: 'The ca certificate file to use for the buildkit client'
    required: true
    default: '/buildkit-certs/ca.pem'
  buildkit-cert-file:
    description: 'The certificate file to use for the buildkit client'
    required: true
    default: '/buildkit-certs/cert.pem'
  buildkit-cert-key-file:
    description: 'The certificate key file to use for the buildkit client'
    required: true
    default: '/buildkit-certs/key.pem'
  push:
    description: 'Defines whether the image should be pushed to the registry or not, default is true'
    required: false
    default: "true"
  build-args:
    description: 'Build arguments to be passed to the build'
    required: false
  target:
    description: 'Build stage to build'
    required: false
  secrets:
    description: 'Build secrets to be passed to the build'
    required: false
  registry:
    description: 'The docker registry to push built images'
    required: false
  registry-username:
    description: 'The docker registry user'
    required: false
  registry-password:
    description: 'The docker registry password'
    required: false
runs:
  using: 'composite'
  steps:
    - shell: bash
      env:
        INPUT_PATH: ${{ inputs.path }}
        INPUT_SECRET: ${{ inputs.secrets }}
        INPUT_REGISTRY: ${{ inputs.registry }}
        INPUT_REGISTRY_USERNAME: ${{ inputs.registry-username }}
        INPUT_REGISTRY_PASSWORD: ${{ inputs.registry-password }}
        INPUT_TARGET: ${{ inputs.target }}
        INPUT_BUILDKIT_DAEMON_ADDRESS: ${{ inputs.buildkit-daemon-address }}
        INPUT_BUILDKIT_CERT_CA_FILE: ${{ inputs.buildkit-cert-ca-file }}
        INPUT_BUILDKIT_CERT_FILE: ${{ inputs.buildkit-cert-file }}
        INPUT_BUILDKIT_CERT_KEY_FILE: ${{ inputs.buildkit-cert-key-file }}
        INPUT_CONTEXT: ${{ inputs.context }}
        INPUT_DOCKERFILE: ${{ inputs.dockerfile }}
        INPUT_PLATFORMS: ${{ inputs.platforms }}
        INPUT_LABELS: ${{ inputs.labels }}
        INPUT_BUILD_ARGS: ${{ inputs.build-args }}
        INPUT_TAGS: ${{ inputs.tags }}
        INPUT_PUSH: ${{ inputs.push }}
      run: |
        cd "$INPUT_PATH"

        # hanlde secrets to args
        declare -a secret_args
        while IFS='=' read -r key val; do
          if [[ -n "$key" && -n "$val" ]]; then
            val="${val%\'*}"
            val="${val%\"*}"
            val="${val#\'}"
            val="${val#\"}"
            export SECRET_ENV_${key}="${val}"
            secret_args+=("--secret id=${key},env=SECRET_ENV_${key}")
          fi
        done <<< "$INPUT_SECRETS"

        # login to docker registry
        export DOCKER_CONFIG=~/.docker
        if [ -n "$INPUT_REGISTRY" ]; then
          mkdir -p $DOCKER_CONFIG
          echo "{\"auths\":{\"$INPUT_REGISTRY\":{\"username\":\"$INPUT_REGISTRY_USERNAME\",\"password\":\"$INPUT_REGISTRY_PASSWORD\"}}}" > $DOCKER_CONFIG/config.json
        fi

        target_args=""
        if [ -n "$INPUT_TARGET" ]; then
          target_args="--target=$INPUT_TARGET"
        fi

        # build and push using buildkit
        buildctl \
          --addr $INPUT_BUILDKIT_DAEMON_ADDRESS \
          --tlscacert $INPUT_BUILDKIT_CERT_CA_FILE \
          --tlscert $INPUT_BUILDKIT_CERT_FILE \
          --tlskey $INPUT_BUILDKIT_CERT_KEY_FILE \
          build \
            --frontend dockerfile.v0 \
            --local context=$INPUT_CONTEXT \
            --local dockerfile=$INPUT_CONTEXT \
            --opt platform=$INPUT_PLATFORMS \
            $(echo "$INPUT_BUILD_ARGS" | sed -r '/^\s*$/d' - | sed -r 's/(.*)/--opt build-arg:\1 \\/' -) \
            $(echo "$INPUT_LABELS" | sed -r '/^\s*$/d' - | sed -r 's/(.*)/--opt label:\1 \\/' -) \
            "${secret_args[@]}" \
            "$target_args" \
            --opt filename=./$INPUT_DOCKERFILE \
            --output type=image,\"name=$(echo "$INPUT_TAGS" | paste -sd ',' -)\",push=$INPUT_PUSH
