name: Publish Packages (canary)

on:
  # enable users to manually trigger with workflow_dispatch
  workflow_dispatch:
    inputs:
      customImageName:
        description: 'Custom Docker Image Tag (keep empty for git hash)'
        required: false
        default: '0.0.0-rc-0'

jobs:
  canary-publish:
    name: Publish Packages (canary)
    runs-on: ubuntu-latest
    # map the step outputs to job outputs
    outputs:
      l2geth: ${{ steps.packages.outputs.l2geth }}
      message-relayer: ${{ steps.packages.outputs.message-relayer }}
      fault-detector: ${{ steps.packages.outputs.fault-detector }}
      data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }}
      contracts: ${{ steps.packages.outputs.contracts }}
      gas-oracle: ${{ steps.packages.outputs.gas-oracle }}
      replica-healthcheck: ${{ steps.packages.outputs.replica-healthcheck }}
      hardhat-node: ${{ steps.packages.outputs.hardhat-node }}
      canary-docker-tag: ${{ steps.docker-image-name.outputs.canary-docker-tag }}
      proxyd: ${{ steps.packages.outputs.proxyd }}
      op-exporter: ${{ steps.packages.outputs.op-exporter }}
      l2geth-exporter: ${{ steps.packages.outputs.l2geth-exporter }}
      batch-submitter-service: ${{ steps.packages.outputs.batch-submitter-service }}
      indexer: ${{ steps.packages.outputs.indexer }}
      teleportr: ${{ steps.packages.outputs.teleportr }}

    steps:
      - name: Check out source code
        uses: actions/checkout@v2
        with:
          # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
          fetch-depth: 0

      - name: Setup Node.js 16.x
        uses: actions/setup-node@master
        with:
          node-version: 16.x

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"

      - uses: actions/cache@v2
        id: yarn-cache
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: Install Dependencies
        run: yarn

      - name: Build
        run: yarn build

      - name: Setup Canary Snapshot
        run: yarn changeset version --snapshot

      - name: Publish To NPM
        uses: changesets/action@v1
        id: changesets
        with:
          publish: yarn changeset publish --tag canary
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

      # Conditional on the release being executed, we unbundle the publishedPackages to specific
      # job outputs
      - name: Get version tags from each published version
        id: packages
        run: |
          node ops/scripts/ci-versions.js ${{ toJSON(steps.changesets.outputs.publishedPackages) }}

      - name: Docker Image Name
        id: docker-image-name
        run: |
          if [ ${CUSTOM_IMAGE_NAME} == '' ]
          then
              echo "::set-output name=canary-docker-tag::${GITHUB_SHA::8}"
          else
              echo "::set-output name=canary-docker-tag::prerelease-${CUSTOM_IMAGE_NAME}"
          fi
        env:
          CUSTOM_IMAGE_NAME: ${{ github.event.inputs.customImageName }}

  l2geth:
    name: Publish L2Geth Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.l2geth != ''
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Publish L2Geth
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./l2geth/Dockerfile
          push: true
          tags: ethereumoptimism/l2geth:${{ needs.canary-publish.outputs.canary-docker-tag }}

  gas-oracle:
    name: Publish Gas Oracle ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.gas-oracle != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./gas-oracle/Dockerfile
          push: true
          tags: ethereumoptimism/gas-oracle:${{ needs.canary-publish.outputs.canary-docker-tag }}

  hardhat-node:
    name: Publish Hardhat Node ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.hardhat-node != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: ./ops/docker/hardhat
          file: ./ops/docker/hardhat/Dockerfile
          push: true
          tags: ethereumoptimism/hardhat-node:${{ needs.canary-publish.outputs.canary-docker-tag }}

  message-relayer:
    name: Publish Message Relayer Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.message-relayer != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/Dockerfile.packages
          target: relayer
          push: true
          tags: ethereumoptimism/message-relayer:${{ needs.canary-publish.outputs.canary-docker-tag }}

  fault-detector:
    name: Publish Fault Detector Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.fault-detector != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/Dockerfile.packages
          target: relayer
          push: true
          tags: ethereumoptimism/fault-detector:${{ needs.canary-publish.outputs.canary-docker-tag }}

  data-transport-layer:
    name: Publish Data Transport Layer Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.data-transport-layer != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/Dockerfile.packages
          target: data-transport-layer
          push: true
          tags: ethereumoptimism/data-transport-layer:${{ needs.canary-publish.outputs.canary-docker-tag }}

  contracts:
    name: Publish Deployer Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.contracts != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/Dockerfile.packages
          target: deployer
          push: true
          tags: ethereumoptimism/deployer:${{ needs.canary-publish.outputs.canary-docker-tag }}

  integration_tests:
    name: Publish Integration tests ${{ needs.canary-publish.outputs.integration-tests }}
    needs: canary-publish
    if: needs.canary-publish.outputs.integration-tests != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/Dockerfile.packages
          target: integration-tests
          push: true
          tags: ethereumoptimism/integration-tests:${{ needs.canary-publish.outputs.canary-docker-tag }}

  replica-healthcheck:
    name: Publish Replica Healthcheck Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.replica-healthcheck != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/Dockerfile.packages
          target: replica-healthcheck
          push: true
          tags: ethereumoptimism/replica-healthcheck:${{ needs.canary-publish.outputs.canary-docker-tag }}

  proxyd:
    name: Publish proxyd Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.proxyd != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Set build args
        id: build_args
        run: |
          echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)"
          echo ::set-output name=GITVERSION::$(jq -r .version ./proxyd/package.json)
          echo ::set-output name=GITCOMMIT::"$GITHUB_SHA"

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./proxyd/Dockerfile
          push: true
          tags: ethereumoptimism/proxyd:${{ needs.canary-publish.outputs.proxyd }}
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}

  op-exporter:
    name: Publish op-exporter Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.op-exporter != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Set build args
        id: build_args
        run: |
          echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)"
          echo ::set-output name=GITVERSION::$(jq -r .version ./op-exporter/package.json)
          echo ::set-output name=GITCOMMIT::"$GITHUB_SHA"

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./op-exporter/Dockerfile=
          push: true
          tags: ethereumoptimism/op-exporter:${{ needs.canary-publish.outputs.op-exporter }}
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}

  l2geth-exporter:
    name: Publish l2geth-exporter Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.l2geth-exporter != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Set build args
        id: build_args
        run: |
          echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)"
          echo ::set-output name=GITVERSION::$(jq -r .version ./l2geth-exporter/package.json)
          echo ::set-output name=GITCOMMIT::"$GITHUB_SHA"

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./l2geth-exporter/Dockerfile
          push: true
          tags: ethereumoptimism/l2geth-exporter:${{ needs.canary-publish.outputs.l2geth-exporter }}
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}

  batch-submitter-service:
    name: Publish batch-submitter-service Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.batch-submitter-service != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./batch-submitter/Dockerfile
          push: true
          tags: ethereumoptimism/batch-submitter-service:${{ needs.canary-publish.outputs.batch-submitter-service }}

  indexer:
    name: Publish indexer Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.indexer != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Set build args
        id: build_args
        run: |
          echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)"
          echo ::set-output name=GITVERSION::$(jq -r .version ./indexer/package.json)
          echo ::set-output name=GITCOMMIT::"$GITHUB_SHA"

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./indexer/Dockerfile
          push: true
          tags: ethereumoptimism/indexer:${{ needs.canary-publish.outputs.indexer }}
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}

  teleportr:
    name: Publish Teleportr Version ${{ needs.canary-publish.outputs.canary-docker-tag }}
    needs: canary-publish
    if: needs.canary-publish.outputs.teleportr != ''
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
          password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}

      - name: Set build args
        id: build_args
        run: |
          echo ::set-output name=GITDATE::"$(date +%d-%m-%Y)"
          echo ::set-output name=GITVERSION::$(jq -r .version ./teleportr/package.json)
          echo ::set-output name=GITCOMMIT::"$GITHUB_SHA"

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./teleportr/Dockerfile
          push: true
          tags: ethereumoptimism/teleportr:${{ needs.canary-publish.outputs.teleportr }}
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}
