name: Publish Barretenberg
on:
  workflow_dispatch:
    # Allow pushing a manual nightly release
    inputs:
      tag:
        description: The tag to build from (leave empty to build a nightly release from master)
        required: false
      publish:
        description: Whether to publish the build artifacts
        type: boolean
        default: false
  schedule:
    # Run a nightly release at 2 AM UTC
    - cron: "0 2 * * *"

permissions:
  # Necessary to upload new release artifacts
  contents: write
  issues: write

jobs:
  build-x86_64-linux-gnu:
    name: Build on Linux GNU
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
        with:
          ref: ${{ inputs.tag || env.GITHUB_REF }}

      - name: Install bleeding edge cmake
        run: |
          sudo apt -y remove --purge cmake
          sudo snap install cmake --classic

      - name: Create Build Environment
        run: |
          sudo apt-get update
          sudo apt-get -y install ninja-build

      - name: Install Clang16
        run: |
          wget https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.0/clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
          tar -xvf clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
          sudo cp clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/bin/* /usr/local/bin/
          sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/include/* /usr/local/include/
          sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/lib/* /usr/local/lib/
          sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/share/* /usr/local/share/

      - name: Compile Barretenberg
        run: |
          cd barretenberg/cpp

          cmake --preset default -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_BUILD_TYPE=RelWithAssert -DTARGET_ARCH=westmere
          cmake --build --preset default --target bb

      - name: Tar and GZip bb Binary (Ubuntu)
        working-directory: barretenberg/cpp/build/bin
        run: tar -cvzf barretenberg-x86_64-linux-gnu.tar.gz bb

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: release-linux
          path: |
            ./barretenberg/cpp/build/bin/barretenberg-x86_64-linux-gnu.tar.gz

  build-wasm-ts:
    name: Build WASM and deploy to TS
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
        with:
          ref: ${{ inputs.tag || env.GITHUB_REF }}

      - name: Install bleeding edge cmake
        run: |
          sudo apt -y remove --purge cmake
          sudo snap install cmake --classic

      - name: Create Build Environment
        run: |
          sudo apt-get update
          sudo apt-get -y install ninja-build yarn

      - name: Install Clang16
        run: |
          wget https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.0/clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
          tar -xvf clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
          sudo cp clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/bin/* /usr/local/bin/
          sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/include/* /usr/local/include/
          sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/lib/* /usr/local/lib/
          sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/share/* /usr/local/share/

      - name: Enable Corepack and Install Yarn v4.5.2 # Needed to call 'yarn build' on barretenberg/ts
        run: |
          corepack enable
          corepack prepare yarn@4.5.2 --activate

      - name: Install WASI-SDK
        run: |
          cd barretenberg/cpp

          ./scripts/install-wasi-sdk.sh

      - name: Compile Typescript # Compiles bb.js and wasms
        run: |
          cd barretenberg/ts
          yarn install && yarn && yarn build

      - name: Tar and GZip barretenberg.wasm
        working-directory: barretenberg/cpp/build-wasm/bin
        run: tar -cvzf barretenberg.wasm.tar.gz barretenberg.wasm

      # - name: Setup Node.js
      #   uses: actions/setup-node@v2
      #   with:
      #     node-version: "18"
      #     registry-url: "https://registry.npmjs.org"

      # - name: Deploy Typescript to NPM
      #   if: github.event.inputs.tag != 'nightly' && github.event.inputs.tag != '' # Do not deploy to npm if it is a nightly build
      #   run: |
      #     cd barretenberg/ts
      #     yarn deploy
      #   env:
      #     NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: release-wasm
          path: |
            ./barretenberg/cpp/build-wasm/bin/barretenberg.wasm.tar.gz

  build-mac-intel:
    name: Build on Mac x86_64-apple-darwin
    runs-on: macos-13
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ inputs.tag || env.GITHUB_REF }}

      - name: Create Mac Build Environment
        run: brew install cmake ninja llvm@16

      - name: Compile Barretenberg
        working-directory: barretenberg/cpp
        run: |
          export PATH="/usr/local/opt/llvm@16/bin:$PATH"
          export LDFLAGS="-L/usr/local/opt/llvm@16/lib"
          export CPPFLAGS="-I/usr/local/opt/llvm@16/include"
          cmake -DCMAKE_BUILD_TYPE=RelWithAssert --preset default
          cmake --build --preset default --target bb

      - name: Package barretenberg artifact
        working-directory: barretenberg/cpp/build/bin
        run: |
          mkdir dist
          cp ./bb ./dist/bb
          7z a -ttar -so -an ./dist/* | 7z a -si ./barretenberg-x86_64-apple-darwin.tar.gz

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: barretenberg-x86_64-apple-darwin
          path: ./barretenberg/cpp/build/bin/barretenberg-x86_64-apple-darwin.tar.gz
          retention-days: 3

  build-mac-m1:
    name: Build on Mac aarch64-apple-darwin
    runs-on: macos-14
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ inputs.tag || env.GITHUB_REF }}

      - name: Create Mac Build Environment
        run: brew install cmake ninja

      - name: Compile Barretenberg
        working-directory: barretenberg/cpp
        run: |
          cmake --preset default -DCMAKE_BUILD_TYPE=RelWithAssert
          cmake --build --preset default --target bb

      - name: Package barretenberg artifact
        working-directory: barretenberg/cpp/build/bin
        run: |
          mkdir dist
          cp ./bb ./dist/bb
          7z a -ttar -so -an ./dist/* | 7z a -si ./barretenberg-aarch64-apple-darwin.tar.gz

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: barretenberg-aarch64-apple-darwin
          path: ./barretenberg/cpp/build/bin/barretenberg-aarch64-apple-darwin.tar.gz
          retention-days: 3

  build-check:
    name: Check builds are successful
    needs:
      [build-x86_64-linux-gnu, build-mac-intel, build-mac-m1, build-wasm-ts]
    if: ${{ always() }}
    runs-on: ubuntu-latest
    steps:
      - name: Report overall success
        env:
          FAIL: ${{ contains(needs.*.result, 'failure') }}
        run: |
          if [[ $FAIL == true ]]; then
              echo "At least one job failed, release is unsuccessful."
              exit 1
          else
              echo "All jobs succeeded, uploading artifacts to release."
              exit 0
          fi

      - name: Checkout
        uses: actions/checkout@v3
        if: ${{ failure() }}
        with:
          ref: ${{ inputs.tag || env.GITHUB_REF }}

      # Raise an issue if the release failed
      - name: Alert on dead links
        uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
        if: ${{ failure() }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          WORKFLOW_NAME: ${{ github.workflow }}
          WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
        with:
          update_existing: true
          filename: .github/RELEASE_FAILED.md

  release:
    name: Publish
    needs: [build-check]
    runs-on: ubuntu-latest
    steps:
      - name: Download files from Linux Runner
        uses: actions/download-artifact@v4
        with:
          name: release-linux

      - name: Download files for WASM
        uses: actions/download-artifact@v4
        with:
          name: release-wasm

      - name: Download files from x86_64 Mac Runner
        uses: actions/download-artifact@v4
        with:
          name: barretenberg-x86_64-apple-darwin

      - name: Download files from aarch64 Mac Runner
        uses: actions/download-artifact@v4
        with:
          name: barretenberg-aarch64-apple-darwin

      - name: Publish to GitHub
        uses: softprops/action-gh-release@v1
        if: ${{ inputs.publish || github.event_name == 'schedule' }}
        with:
          tag_name: ${{ inputs.tag || 'nightly' }} # This will fail if `inputs.tag` is not a tag (e.g. testing a branch)
          prerelease: true
          files: |
            barretenberg.wasm.tar.gz
            barretenberg-x86_64-linux-gnu.tar.gz
            barretenberg-x86_64-apple-darwin.tar.gz
            barretenberg-aarch64-apple-darwin.tar.gz