name: Release and version

on:
  workflow_dispatch:
  push:
    branches:
      - develop

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

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    if: github.repository == 'ethereum-optimism/optimism'
    # map the step outputs to job outputs
    outputs:
      balance-mon: ${{ steps.packages.outputs.balance-mon }}
      drippie-mon: ${{ steps.packages.outputs.drippie-mon }}
      fault-mon: ${{ steps.packages.outputs.fault-mon }}
      multisig-mon: ${{ steps.packages.outputs.multisig-mon }}
      replica-mon: ${{ steps.packages.outputs.replica-mon }}
      wd-mon: ${{ steps.packages.outputs.wd-mon }}
      op-exporter: ${{ steps.packages.outputs.op-exporter }}
      endpoint-monitor: ${{ steps.packages.outputs.endpoint-monitor }}
    # Permissions necessary for Changesets to push a new branch and open PRs
    # (for automated Version Packages PRs), and request the JWT for provenance.
    # More info: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#adding-permissions-settings
    permissions:
      contents: write
      pull-requests: write
      id-token: write
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
        with:
          # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
          fetch-depth: 0
          ref: "develop"

      - name: Setup
        uses: ./.github/actions/setup

      - name: Set deployment token
        run: npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

      # 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: pnpm release:publish
          version: pnpm release:version
        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) }}

  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@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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 }}

  fault-mon:
    name: Publish fault-mon Version ${{ needs.release.outputs.fault-mon }}
    needs: release
    if: needs.release.outputs.fault-mon != ''
    runs-on: ubuntu-latest

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

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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-mon
          push: true
          tags: ethereumoptimism/fault-mon:${{ needs.release.outputs.fault-mon }},ethereumoptimism/fault-mon: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@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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

  multisig-mon:
    name: Publish Multisig Monitor Version ${{ needs.release.outputs.multisig-mon }}
    needs: release
    if: needs.release.outputs.multisig-mon != ''
    runs-on: ubuntu-latest

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

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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: multisig-mon
          push: true
          tags: ethereumoptimism/multisig-mon:${{ needs.release.outputs.multisig-mon }},ethereumoptimism/multisig-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@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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

  replica-mon:
    name: Publish Replica Healthcheck Version ${{ needs.release.outputs.replica-mon }}
    needs: release
    if: needs.release.outputs.replica-mon != ''
    runs-on: ubuntu-latest

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

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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-mon
          push: true
          tags: ethereumoptimism/replica-mon:${{ needs.release.outputs.replica-mon }},ethereumoptimism/replica-mon: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@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        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 }}
