name: Runner CD

on:
  workflow_dispatch:
  push:
    paths:
    - releaseVersion
  
jobs:
  check:
    if: startsWith(github.ref, 'refs/heads/releases/') || github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    # Make sure ./releaseVersion match ./src/runnerversion 
    # Query GitHub release ensure version is not used 
    - name: Check version
      uses: actions/github-script@0.3.0
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        script: |
          const core = require('@actions/core')
          const fs = require('fs');
          const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
          const releaseVersion = fs.readFileSync('${{ github.workspace }}/releaseVersion', 'utf8').replace(/\n$/g, '')
          if (runnerVersion != releaseVersion) {
            console.log('Request Release Version: ' + releaseVersion + '\nCurrent Runner Version: ' + runnerVersion)
            core.setFailed('Version mismatch! Make sure ./releaseVersion match ./src/runnerVersion')
            return
          }
          try {
            const release = await github.repos.getReleaseByTag({
              owner: '${{ github.event.repository.owner.name }}',
              repo: '${{ github.event.repository.name }}',
              tag: 'v' + runnerVersion
            })
            core.setFailed('Release with same tag already created: ' + release.data.html_url)
          } catch (e) {
            // We are good to create the release if release with same tag doesn't exists
            if (e.status != 404) {
              throw e
            }
          }
  
  build:
    needs: check
    outputs:
      linux-x64-sha: ${{ steps.sha.outputs.linux-x64-sha256 }}
      linux-arm64-sha: ${{ steps.sha.outputs.linux-arm64-sha256 }}
      linux-arm-sha: ${{ steps.sha.outputs.linux-arm-sha256 }}
      win-x64-sha: ${{ steps.sha.outputs.win-x64-sha256 }}
      osx-x64-sha: ${{ steps.sha.outputs.osx-x64-sha256 }}
    strategy:
      matrix:
        runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
        include:
        - runtime: linux-x64
          os: ubuntu-latest
          devScript: ./dev.sh

        - runtime: linux-arm64
          os: ubuntu-latest
          devScript: ./dev.sh

        - runtime: linux-arm
          os: ubuntu-latest
          devScript: ./dev.sh

        - runtime: osx-x64
          os: macOS-latest
          devScript: ./dev.sh

        - runtime: win-x64
          os: windows-latest
          devScript: ./dev

    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v1

    # Build runner layout
    - name: Build & Layout Release
      run: |
        ${{ matrix.devScript }} layout Release ${{ matrix.runtime }}
      working-directory: src

    # Run tests
    - name: L0
      run: |
        ${{ matrix.devScript }} test
      working-directory: src
      if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm'

    # Create runner package tar.gz/zip
    - name: Package Release
      if: github.event_name != 'pull_request'
      run: |
        ${{ matrix.devScript }} package Release ${{ matrix.runtime }}
      working-directory: src

    # Upload runner package tar.gz/zip as artifact.
    # Since each package name is unique, so we don't need to put ${{matrix}} info into artifact name
    - name: Publish Artifact
      if: github.event_name != 'pull_request'
      uses: actions/upload-artifact@v1
      with:
        name: runner-packages
        path: _package
    # compute shas and set as job outputs to use in release notes
    - run: brew install coreutils #needed for shasum util
      if: ${{ matrix.os == 'macOS-latest' }}
      name: Install Dependencies for SHA Calculation (osx)
    - run: |
        file=$(ls)
        sha=$(sha256sum $file | awk '{ print $1 }')
        echo "Computed sha256: $sha for $file"
        echo "::set-output name=${{matrix.runtime}}-sha256::$sha"
      shell: bash
      id: sha
      name: Compute SHA256
      working-directory: _package
  release:
    needs: build
    runs-on: ubuntu-latest
    steps:

    - uses: actions/checkout@v2

    # Download runner package tar.gz/zip produced by 'build' job
    - name: Download Artifact
      uses: actions/download-artifact@v1
      with:
        name: runner-packages
        path: ./

    # Create ReleaseNote file
    - name: Create ReleaseNote
      id: releaseNote
      uses: actions/github-script@0.3.0
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        script: |
          const core = require('@actions/core')
          const fs = require('fs');
          const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
          var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(/<RUNNER_VERSION>/g, runnerVersion)
          releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-x64-sha}}')
          releaseNote = releaseNote.replace(/<OSX_X64_SHA>/g, '${{needs.build.outputs.osx-x64-sha}}')
          releaseNote = releaseNote.replace(/<LINUX_X64_SHA>/g, '${{needs.build.outputs.linux-x64-sha}}')
          releaseNote = releaseNote.replace(/<LINUX_ARM_SHA>/g, '${{needs.build.outputs.linux-arm-sha}}')
          releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA>/g, '${{needs.build.outputs.linux-arm64-sha}}')
          console.log(releaseNote)
          core.setOutput('version', runnerVersion);
          core.setOutput('note', releaseNote);  
    # Create GitHub release
    - uses: actions/create-release@master
      id: createRelease
      name: Create ${{ steps.releaseNote.outputs.version }} Runner Release
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: "v${{ steps.releaseNote.outputs.version }}"
        release_name: "v${{ steps.releaseNote.outputs.version }}"
        body: |
          ${{ steps.releaseNote.outputs.note }}

    # Upload release assets
    - name: Upload Release Asset (win-x64)
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.createRelease.outputs.upload_url }}
        asset_path: ${{ github.workspace }}/actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip
        asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip
        asset_content_type: application/octet-stream

    - name: Upload Release Asset (linux-x64)
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.createRelease.outputs.upload_url }}
        asset_path: ${{ github.workspace }}/actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_name: actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_content_type: application/octet-stream

    - name: Upload Release Asset (osx-x64)
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.createRelease.outputs.upload_url }}
        asset_path: ${{ github.workspace }}/actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_content_type: application/octet-stream

    - name: Upload Release Asset (linux-arm)
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.createRelease.outputs.upload_url }}
        asset_path: ${{ github.workspace }}/actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_name: actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_content_type: application/octet-stream

    - name: Upload Release Asset (linux-arm64)
      uses: actions/upload-release-asset@v1.0.1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.createRelease.outputs.upload_url }}
        asset_path: ${{ github.workspace }}/actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_name: actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz
        asset_content_type: application/octet-stream
