name: Release

on:
  push:
    branches:
      - master

# Always wait for previous release to finish before releasing again
concurrency: ${{ github.workflow }}-${{ github.ref }}

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 }}
      balance-mon: ${{ steps.packages.outputs.drippie-mon }}
      drippie-mon: ${{ steps.packages.outputs.drippie-mon }}
      wd-mon: ${{ steps.packages.outputs.wd-mon }}
      data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }}
      contracts: ${{ steps.packages.outputs.contracts }}
      contracts-bedrock: ${{ steps.packages.outputs.contracts-bedrock }}
      balance-monitor: ${{ steps.packages.outputs.balance-monitor }}
      gas-oracle: ${{ steps.packages.outputs.gas-oracle }}
      replica-healthcheck: ${{ steps.packages.outputs.replica-healthcheck }}
      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 }}
      foundry: ${{ steps.packages.outputs.foundry }}
      endpoint-monitor: ${{ steps.packages.outputs.endpoint-monitor }}

    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 --frozen-lockfile

      - name: Install Foundry
        uses: foundry-rs/foundry-toolchain@v1
        with:
          version: nightly

      # Makes a pr to publish the changesets that when
      # merged will publish to npm
      # see https://github.com/changesets/action
      - name: Publish To NPM or Create Release Pull Request
        uses: changesets/action@v1
        id: changesets
        with:
          createGithubReleases: false
          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: ./l2geth/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.outputs.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: ./ops/docker/hardhat/Dockerfile
          push: true
          tags: ethereumoptimism/hardhat-node:${{ needs.release.outputs.hardhat-node }},ethereumoptimism/hardhat-node:latest

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

  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

  wd-mon:
    name: Publish Withdrawal Monitor Version ${{ needs.release.outputs.wd-mon }}
    needs: release
    if: needs.release.outputs.wd-mon != ''
    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: wd-mon
          push: true
          tags: ethereumoptimism/wd-mon:${{ needs.release.outputs.wd-mon }},ethereumoptimism/wd-mon:latest

  balance-mon:
    name: Publish Balance Monitor Version ${{ needs.release.outputs.balance-mon }}
    needs: release
    if: needs.release.outputs.balance-mon != ''
    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: balance-mon
          push: true
          tags: ethereumoptimism/balance-mon:${{ needs.release.outputs.balance-mon }},ethereumoptimism/balance-mon:latest

  drippie-mon:
    name: Publish Drippie Monitor Version ${{ needs.release.outputs.drippie-mon }}
    needs: release
    if: needs.release.outputs.drippie-mon != ''
    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: drippie-mon
          push: true
          tags: ethereumoptimism/drippie-mon:${{ needs.release.outputs.drippie-mon }},ethereumoptimism/drippie-mon: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

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

  balance-monitor:
    name: Publish balance-monitor Version ${{ needs.release.outputs.balance-monitor }}
    needs: release
    if: needs.release.outputs.balance-monitor != ''
    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: balance-monitor
          push: true
          tags: ethereumoptimism/balance-monitor:${{ needs.release.outputs.balance-monitor }},ethereumoptimism/balance-monitor: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

  endpoint-monitor:
    name: Publish endpoint-monitor Version ${{ needs.release.outputs.endpoint-monitor}}
    needs: release
    if: needs.release.outputs.endpoint-monitor != ''
    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 ./endpoint-monitor/package.json)
          echo ::set-output name=GITCOMMIT::"$GITHUB_SHA"

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