name: Release

on:
  push:
    branches:
      - master

jobs:
  release:
    name: Release
    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 }}
      proxyd: ${{ steps.packages.outputs.proxyd }}
      hardhat-node: ${{ steps.packages.outputs.hardhat-node }}
      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 }}
      go-builder: ${{ steps.packages.outputs.go-builder }}
      js-builder: ${{ steps.packages.outputs.js-builder }}

    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
        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: Publish To NPM or Create Release Pull Request
        uses: changesets/action@v1
        id: changesets
        with:
          publish: yarn release
        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
        if: steps.changesets.outputs.published == 'true'
        run: |
          node ops/scripts/ci-versions.js ${{ toJSON(steps.changesets.outputs.publishedPackages) }}

  l2geth:
    name: Publish L2Geth Version ${{ needs.release.outputs.l2geth }}
    needs: release
    if: needs.release.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: ./ops/docker/Dockerfile
          push: true
          tags: ethereumoptimism/l2geth:${{ needs.release.outputs.l2geth }},ethereumoptimism/l2geth:latest

  gas-oracle:
    name: Publish Gas Oracle Version ${{ needs.release.outputs.gas-oracle }}
    needs: release
    if: needs.release.outputs.gas-oracle != ''
    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 Gas Oracle
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./gas-oracle/Dockerfile
          push: true
          tags: ethereumoptimism/gas-oracle:${{ needs.release.outputs.gas-oracle }},ethereumoptimism/gas-oracle:latest

  hardhat-node:
    name: Publish Hardhat Node ${{ needs.release.outputs.hardhat-node }}
    needs: release
    if: needs.release.hardhat-node != ''
    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 Hardhat Node
        uses: docker/build-push-action@v2
        with:
          context: ./ops/docker/hardhat
          file: ./Dockerfile
          push: true
          tags: ethereumoptimism/hardhat-node:${{ needs.release.outputs.gas-oracle }},ethereumoptimism/hardhat-node:latest

  go-builder:
    name: Publish go-builder ${{ needs.release.outputs.go-builder }}
    needs: release
    if: needs.release.outputs.go-builder != ''
    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 go-builder
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/go-builder/Dockerfile
          push: true
          tags: ethereumoptimism/go-builder:${{ needs.release.outputs.go-builder }},ethereumoptimism/go-builder:latest

  js-builder:
    name: Publish js-builder ${{ needs.release.outputs.js-builder }}
    needs: release
    if: needs.release.outputs.js-builder != ''
    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 js-builder
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./ops/docker/js-builder/Dockerfile
          push: true
          tags: ethereumoptimism/js-builder:${{ needs.release.outputs.js-builder }},ethereumoptimism/js-builder:latest

  proxyd:
    name: Publish proxyd Version ${{ needs.release.outputs.proxyd }}
    needs: release
    if: needs.release.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.release.outputs.proxyd }},ethereumoptimism/proxyd:latest
          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.release.outputs.l2geth-exporter}}
    needs: release
    if: needs.release.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.release.outputs.l2geth-exporter }},ethereumoptimism/l2geth-exporter:latest
          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.release.outputs.op-exporter}}
    needs: release
    if: needs.release.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.release.outputs.op-exporter }},ethereumoptimism/op-exporter:latest
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}

  message-relayer:
    name: Publish Message Relayer Version ${{ needs.release.outputs.message-relayer }}
    needs: release
    if: needs.release.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: message-relayer
          push: true
          tags: ethereumoptimism/message-relayer:${{ needs.release.outputs.message-relayer }},ethereumoptimism/message-relayer:latest

  fault-detector:
    name: Publish Fault Detector Version ${{ needs.release.outputs.fault-detector }}
    needs: release
    if: needs.release.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: fault-detector
          push: true
          tags: ethereumoptimism/fault-detector:${{ needs.release.outputs.fault-detector }},ethereumoptimism/fault-detector:latest

  data-transport-layer:
    name: Publish Data Transport Layer Version ${{ needs.release.outputs.data-transport-layer }}
    needs: release
    if: needs.release.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.release.outputs.data-transport-layer }},ethereumoptimism/data-transport-layer:latest

  contracts:
    name: Publish Deployer Version ${{ needs.release.outputs.contracts }}
    needs: release
    if: needs.release.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.release.outputs.contracts }},ethereumoptimism/deployer:latest

  integration_tests:
    name: Publish Integration tests ${{ needs.release.outputs.integration-tests }}
    needs: release
    if: needs.release.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.release.outputs.integration-tests }},ethereumoptimism/integration-tests:latest

  replica-healthcheck:
    name: Publish Replica Healthcheck Version ${{ needs.release.outputs.replica-healthcheck }}
    needs: release
    if: needs.release.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.release.outputs.replica-healthcheck }},ethereumoptimism/replica-healthcheck:latest

  batch-submitter-service:
    name: Publish batch-submitter-service Version ${{ needs.release.outputs.batch-submitter-service }}
    needs: release
    if: needs.release.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.release.outputs.batch-submitter-service }},ethereumoptimism/batch-submitter-service:latest

  indexer:
    name: Publish Indexer Version ${{ needs.release.outputs.indexer }}
    needs: release
    if: needs.release.outputs.indexer != ''
    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: 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: Publish Indexer
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./indexer/Dockerfile
          push: true
          tags: ethereumoptimism/indexer:${{ needs.release.outputs.indexer }},ethereumoptimism/indexer:latest
          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.release.outputs.teleportr }}
    needs: release
    if: needs.release.outputs.teleportr != ''
    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: 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: Publish Teleportr
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./teleportr/Dockerfile
          push: true
          tags: ethereumoptimism/teleportr:${{ needs.release.outputs.teleportr }},ethereumoptimism/teleportr:latest
          build-args: |
            GITDATE=${{ steps.build_args.outputs.GITDATE }}
            GITCOMMIT=${{ steps.build_args.outputs.GITCOMMIT }}
            GITVERSION=${{ steps.build_args.outputs.GITVERSION }}
