name: Draft Release

run-name: "Draft Release ${{ inputs.tag }}"

on:
  workflow_dispatch:
    inputs:
      tag:
        required: true

env:
  registry: docker.io
  GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.caching=true"

jobs:
  validate:
    runs-on: ubuntu-22.04
    env:
      RELEASE_VERSION: "${{ inputs.tag }}"
    steps:
      - name: Check default branch
        run: |
          echo "Current Branch: ${{ github.ref_name }}"
          echo "Default Branch: ${{ github.event.repository.default_branch }}"
          if [[ ${{ github.ref_name }} != ${{ github.event.repository.default_branch }} ]]
          then
            echo "This workflow can only be run on default branch. This is not an issue for hot fixes as code is checked out from the tag"
            exit 1
          fi

      - name: Pre-process Release Name
        id: validate_release_version
        run: |
          # strip all whitespace
          RELEASE_VERSION="${RELEASE_VERSION//[[:space:]]/}"
          if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then
            echo "Release name does not conform to a valid besu release format YY.M.v[-suffix], e.g. 24.8.0-RC1."
            exit 1
          fi
          echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT  # Set as output using the new syntax

      # Perform a tag checkout to ensure tag is available
      - name: Verify tag Exist
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ steps.validate_release_version.outputs.release_version }}
          fetch-depth: 1

    outputs:
      release_version: ${{ steps.validate_release_version.outputs.release_version }}

  build:
    runs-on: ubuntu-22.04
    needs: validate
    env:
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}  # Use the output from the pre_process_release job
    outputs:
      tarSha: ${{steps.hashes.outputs.tarSha}}
      zipSha: ${{steps.hashes.outputs.zipSha}}
    steps:
      - name: Checkout tag
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21

      - name: Setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true

      - name: Assemble release
        run:
          ./gradlew -Prelease.releaseVersion=${{env.RELEASE_VERSION}} -Pversion=${{env.RELEASE_VERSION}} assemble

      - name: Hashes
        id: hashes
        run: |
          cd build/distributions
          echo "zipSha=$(shasum -a 256 besu*.zip)"
          echo "tarSha=$(shasum -a 256 besu*.tar.gz)"
          echo "zipSha=$(shasum -a 256 besu*.zip)" >> $GITHUB_OUTPUT
          echo "tarSha=$(shasum -a 256 besu*.tar.gz)" >> $GITHUB_OUTPUT
          shasum -a 256 besu-${{env.RELEASE_VERSION}}.tar.gz > besu-${{env.RELEASE_VERSION}}.tar.gz.sha256
          shasum -a 256 besu-${{env.RELEASE_VERSION}}.zip > besu-${{env.RELEASE_VERSION}}.zip.sha256

      - name: Upload tarball
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.tar.gz'
          name: besu-${{ env.RELEASE_VERSION }}.tar.gz
          compression-level: 0

      - name: upload zipfile
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.zip'
          name: besu-${{ env.RELEASE_VERSION }}.zip
          compression-level: 0

      - name: upload checksum zip
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.zip.sha256'
          name: besu-${{ env.RELEASE_VERSION }}.zip.sha256
          compression-level: 0

      - name: upload checksum tar.gz
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
        with:
          path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.tar.gz.sha256'
          name: besu-${{ env.RELEASE_VERSION }}.tar.gz.sha256
          compression-level: 0

  test-windows:
    runs-on: windows-2022
    needs: ["build"]
    timeout-minutes: 5
    steps:
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21

      - name: Download zip
        uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe
        with:
          pattern: besu-*.zip
          merge-multiple: true

      - name: Test
        run: |
          unzip besu-*.zip -d besu-tmp
          cd besu-tmp
          mv besu-* ../besu
          cd ..
          besu\bin\besu.bat --help
          besu\bin\besu.bat --version

  test-linux:
    runs-on: ubuntu-22.04
    needs: ["build"]
    timeout-minutes: 5
    steps:
      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21

      - name: Download tar.gz
        uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe
        with:
          pattern: besu-*.tar.gz
          merge-multiple: true

      - name: Test
        run: |
          tar zxvf besu-*.tar.gz
          rm -f besu-*.tar.gz
          mv besu-* besu-test
          besu-test/bin/besu --help
          besu-test/bin/besu --version

  docker-lint:
    runs-on: ubuntu-22.04
    needs: [test-linux, test-windows]
    env:
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}  # Use the output from the pre_process_release job
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      - name: hadoLint
        run: docker run --rm -i hadolint/hadolint < docker/Dockerfile

  docker-publish:
    needs: [validate, docker-lint]
    env:
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}  # Use the output from the pre_process_release job
    strategy:
      fail-fast: false
      matrix:
        platform:
          - ubuntu-22.04
          - besu-arm64
    runs-on: ${{ matrix.platform }}
    steps:
      - name: Prepare
        id: prep
        run: |
          platform=${{ matrix.platform }}
          if [ "$platform" = 'ubuntu-22.04' ]; then
            echo "PLATFORM_PAIR=linux-amd64" >> $GITHUB_OUTPUT
            echo "ARCH=amd64" >> $GITHUB_OUTPUT
          else
            echo "PLATFORM_PAIR=linux-arm64" >> $GITHUB_OUTPUT
            echo "ARCH=arm64" >> $GITHUB_OUTPUT
          fi

      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      - name: short sha
        id: shortSha
        run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT

      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21

      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true

      - name: install goss
        run: |
          mkdir -p docker/reports
          curl -L https://github.com/aelsabbahy/goss/releases/download/v0.4.4/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} -o ./docker/tests/goss-${{ steps.prep.outputs.PLATFORM_PAIR }}

      - name: login to ${{ env.registry }}
        uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        with:
          registry: ${{ env.registry }}
          username: ${{ secrets.DOCKER_USER_RW }}
          password: ${{ secrets.DOCKER_PASSWORD_RW }}

      - name: build and test docker
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        env:
          architecture: ${{ steps.prep.outputs.ARCH }}
        with:
          cache-disabled: true
          arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }}

      - name: publish
        env:
          architecture: ${{ steps.prep.outputs.ARCH }}
        run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }}

  docker-manifest:
    needs: [validate, docker-publish]
    runs-on: ubuntu-22.04
    env:
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21

      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true

      - name: login to ${{ env.registry }}
        uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        with:
          registry: ${{ env.registry }}
          username: ${{ secrets.DOCKER_USER_RW }}
          password: ${{ secrets.DOCKER_PASSWORD_RW }}

      - name: multi-arch docker
        run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }}

  docker-verify:
    needs: [validate,docker-manifest]
    env:
      CONTAINER_NAME: besu-check
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}
    runs-on: ${{ matrix.combination.runner }}
    timeout-minutes: 4
    strategy:
      matrix:
        combination:
          - tag: ${{ needs.validate.outputs.release_version }}
            platform: ''
            runner: ubuntu-22.04
          - tag: ${{ needs.validate.outputs.release_version }}-amd64
            platform: 'linux/amd64'
            runner: ubuntu-22.04
          - tag: ${{ needs.validate.outputs.release_version }}-arm64
            platform: ''
            runner: besu-arm64
    steps:
      - name: Checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          sparse-checkout: '.github/workflows/BesuContainerVerify.sh'

      - name: Start container
        run: |
          PLATFORM_OPT=""
          [[ x${{ matrix.combination.platform }} != 'x' ]] && PLATFORM_OPT="--platform ${{ matrix.combination.platform }}"
          docker run -d $PLATFORM_OPT --name ${{ env.CONTAINER_NAME }} ${{ secrets.DOCKER_ORG }}/besu:${{ matrix.combination.tag }}

      - name: Verify besu container
        run: bash .github/workflows/BesuContainerVerify.sh
        env:
          TAG: ${{ matrix.combination.tag }}
          VERSION: ${{ env.RELEASE_VERSION }}
          CHECK_LATEST: false

      - name: Stop container
        run: docker stop ${{ env.CONTAINER_NAME }}

  release-draft:
    runs-on: ubuntu-22.04
    needs: [validate, test-linux, test-windows]
    permissions:
      contents: write
    env:
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}
    steps:
      - name: Checkout Repo
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      - name: Download Besu artifacts
        uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe
        with:
          pattern: besu-${{env.RELEASE_VERSION}}*
          merge-multiple: true

      - name: Draft release notes
        run: |
          echo "## ${{env.RELEASE_VERSION}}" > draft-release-notes.md
          echo "## Upcoming Breaking Changes" >> draft-release-notes.md
          echo "## Breaking Changes" >> draft-release-notes.md
          echo "## Additions and Improvements" >> draft-release-notes.md
          echo "## Bug fixes" >> draft-release-notes.md
          echo "`$(cat besu-${{env.RELEASE_VERSION}}.zip.sha256)`" >> draft-release-notes.md
          echo "`$(cat besu-${{env.RELEASE_VERSION}}.tar.gz.sha256)`" >> draft-release-notes.md
          cat besu-${{env.RELEASE_VERSION}}.zip.sha256 >> draft-release-notes.md
          cat besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 >> draft-release-notes.md

      - name: Draft release
        run: |
          gh release create \
            --draft \
            --title=${{env.RELEASE_VERSION}} \
            --notes-file draft-release-notes.md \
            --verify-tag ${{env.RELEASE_VERSION}} \
            besu-${{env.RELEASE_VERSION}}.tar.gz \
            besu-${{env.RELEASE_VERSION}}.zip \
            besu-${{env.RELEASE_VERSION}}.zip.sha256 \
            besu-${{env.RELEASE_VERSION}}.tar.gz.sha256
        env:
          GH_TOKEN: ${{ github.token }}

  artifactory:
    runs-on: ubuntu-22.04
    needs: [validate, test-linux, test-windows]
    env:
      RELEASE_VERSION: ${{ needs.validate.outputs.release_version }}
    steps:
      - name: checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      - name: Set up Java
        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
        with:
          distribution: temurin
          java-version: 21

      - name: setup gradle
        uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1
        with:
          cache-disabled: true

      - name: Artifactory Publish
        env:
          ARTIFACTORY_USER: ${{ secrets.BESU_ARTIFACTORY_USER }}
          ARTIFACTORY_KEY: ${{ secrets.BESU_ARTIFACTORY_TOKEN }}
        run: ./gradlew -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} -Pversion=${{env.RELEASE_VERSION}} artifactoryPublish

  verify_artifactory:
    runs-on: ubuntu-22.04
    needs: [artifactory, validate, test-linux, test-windows]
    steps:
      - name: checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
        with:
          ref: ${{ env.RELEASE_VERSION }}

      # actions/setup-python@5.3 
      - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
        with:
          python-version: '3.13'

      - name: Install dependencies
        run: pip install requests argparse

      - name: Run the script
        run: python3 .github/workflows/verify_artifacts.py --besu_version="${{ needs.validate.outputs.release_version }}"
