name: 'Build release'
author: 'Forgejo authors'
description: |
  Build release

inputs:
  forgejo:
    description: 'URL of the Forgejo instance where the release is uploaded'
    required: true
  owner:
    description: 'User or organization where the release is uploaded, relative to the Forgejo instance'
    required: true
  repository:
    description: 'Repository where the release is uploaded, relative to the owner'
    required: true
  doer:
    description: 'Name of the user authoring the release'
    required: true
  tag-version:
    description: 'Version of the release derived from the tag withint the leading v'
    required: true
  suffix:
    description: 'Suffix to add to the image tag'
  token:
    description: 'token'
    required: true
  dockerfile:
    description: 'path to the dockerfile'
    default: 'Dockerfile'
  platforms:
    description: 'Coma separated list of platforms'
    default: 'linux/amd64,linux/arm64'
  release-notes:
    description: 'Full text of the release notes'
    default: 'Release notes placeholder'
  binary-name:
    description: 'Name of the binary'
  binary-path:
    description: 'Path of the binary within the container to extract into binary-name'
  verbose:
    description: 'Increase the verbosity level'
    default: 'false'

runs:
  using: "composite"
  steps:
    - run: echo "${{ github.action_path }}" >> $GITHUB_PATH
      shell: bash

    - name: Install dependencies
      run: |
        apt-get install -y -qq xz-utils

    - name: set -x if verbose is required
      id: verbose
      run: |
        if ${{ inputs.verbose }} ; then
          echo "shell=set -x" >> "$GITHUB_OUTPUT"
        fi

    - name: Create the insecure and buildx-config variables for the container registry
      id: registry
      run: |
        ${{ steps.verbose.outputs.shell }}
        url="${{ inputs.forgejo }}"
        hostport=${url##http*://}
        hostport=${hostport%%/}
        echo "host-port=${hostport}" >> "$GITHUB_OUTPUT"
        if ! [[ $url =~ ^http:// ]] ; then
           exit 0
        fi
        cat >> "$GITHUB_OUTPUT" <<EOF
        insecure=true
        buildx-config<<ENDVAR
        [registry."${hostport}"]
          http = true
        ENDVAR
        EOF

    - name: Allow docker pull/push to forgejo
      if: ${{ steps.registry.outputs.insecure }}
      run: |-
        mkdir -p /etc/docker
        cat > /etc/docker/daemon.json <<EOF
          {
            "insecure-registries" : ["${{ steps.registry.outputs.host-port }}"],
            "bip": "172.26.0.1/16"
          }
        EOF

    - name: Install docker
      run: |
        echo deb http://deb.debian.org/debian bullseye-backports main | tee /etc/apt/sources.list.d/backports.list && apt-get -qq update
        DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -qq -y -t bullseye-backports docker.io

    - uses: https://github.com/docker/setup-buildx-action@v2
      with:
        config-inline: |
         ${{ steps.registry.outputs.buildx-config }}

    - name: Login to the container registry
      run: |
        BASE64_AUTH=`echo -n "${{ inputs.doer }}:${{ inputs.token }}" | base64 -w0`
        mkdir -p ~/.docker
        echo "{\"auths\": {\"$CI_REGISTRY\": {\"auth\": \"$BASE64_AUTH\"}}}" > ~/.docker/config.json
      env:
        CI_REGISTRY: "${{ steps.registry.outputs.host-port }}"

    - name: Build the container image for each architecture
      uses: https://github.com/docker/build-push-action@v4
      # workaround until https://github.com/docker/build-push-action/commit/d8823bfaed2a82c6f5d4799a2f8e86173c461aba is in @v4 or @v5 is released
      env:
        ACTIONS_RUNTIME_TOKEN: ''
      with:
        context: .
        push: true
        file: ${{ inputs.dockerfile }}
        platforms: ${{ inputs.platforms }}
        tags: ${{ steps.registry.outputs.host-port }}/${{ inputs.owner }}/${{ inputs.repository }}:${{ inputs.tag-version }}${{ inputs.suffix }}

    - name: Extract the binary from the container images into the release directory
      if: inputs.binary-name != ''
      run: |
        ${{ steps.verbose.outputs.shell }}
        mkdir -p release
        cd release
        for platform in $(echo ${{ inputs.platforms }} | tr ',' ' '); do
          arch=$(echo $platform | sed -e 's|linux/||g' -e 's|arm/v6|arm-6|g')
          docker create --platform $platform --name forgejo-$arch ${{ steps.registry.outputs.host-port }}/${{ inputs.owner }}/${{ inputs.repository }}:${{ inputs.tag-version }}${{ inputs.suffix }}
          binary="${{ inputs.binary-name }}-${{ inputs.tag-version }}-linux"
          docker cp forgejo-$arch:${{ inputs.binary-path }} $binary-$arch
          chmod +x $binary-$arch
          # the displayed version has a + instead of the first -, deal with it
          pattern=$(echo "${{ inputs.tag-version }}" | tr - .)
          if ! ./$binary-$arch --version | grep "$pattern" ; then
            echo "ERROR: expected version pattern $pattern not found in the output of $binary-$arch --version"
            ./$binary-$arch --version
            exit 1
          fi
          xz --keep -9 $binary-$arch
          shasum -a 256 $binary-$arch > $binary-$arch.sha256
          shasum -a 256 $binary-$arch.xz > $binary-$arch.xz.sha256
          docker rm forgejo-$arch
        done

    - name: publish release
      if: inputs.binary-name != ''
      uses: https://code.forgejo.org/actions/forgejo-release@v1
      with:
        direction: upload
        release-dir: release
        release-notes: "${{ inputs.release-notes }}"
        token: ${{ inputs.token }}
        verbose: ${{ steps.verbose.outputs.value }}
