version: 2.1

orbs:
  go: circleci/go@1.5.0
  gcp-cli: circleci/gcp-cli@3.0.1
  slack: circleci/slack@4.10.1
commands:
  gcp-oidc-authenticate:
    description: "Authenticate with GCP using a CircleCI OIDC token."
    parameters:
      project_id:
        type: env_var_name
        default: GCP_PROJECT_ID
      workload_identity_pool_id:
        type: env_var_name
        default: GCP_WIP_ID
      workload_identity_pool_provider_id:
        type: env_var_name
        default: GCP_WIP_PROVIDER_ID
      service_account_email:
        type: env_var_name
        default: GCP_SERVICE_ACCOUNT_EMAIL
      gcp_cred_config_file_path:
        type: string
        default: /home/circleci/gcp_cred_config.json
      oidc_token_file_path:
        type: string
        default: /home/circleci/oidc_token.json
    steps:
      - run:
          name: "Create OIDC credential configuration"
          command: |
            # Store OIDC token in temp file
            echo $CIRCLE_OIDC_TOKEN > << parameters.oidc_token_file_path >>
            # Create a credential configuration for the generated OIDC ID Token
            gcloud iam workload-identity-pools create-cred-config \
                "projects/${<< parameters.project_id >>}/locations/global/workloadIdentityPools/${<< parameters.workload_identity_pool_id >>}/providers/${<< parameters.workload_identity_pool_provider_id >>}"\
                --output-file="<< parameters.gcp_cred_config_file_path >>" \
                --service-account="${<< parameters.service_account_email >>}" \
                --credential-source-file=<< parameters.oidc_token_file_path >>
      - run:
          name: "Authenticate with GCP using OIDC"
          command: |
            # Configure gcloud to leverage the generated credential configuration
            gcloud auth login --brief --cred-file "<< parameters.gcp_cred_config_file_path >>"
            # Configure ADC
            echo "export GOOGLE_APPLICATION_CREDENTIALS='<< parameters.gcp_cred_config_file_path >>'" | tee -a "$BASH_ENV"
  check-changed:
    description: "Conditionally halts a step if certain modules change"
    parameters:
      patterns:
        type: string
        description: "Comma-separated list of dependencies"
    steps:
      - run:
          name: "Check for changes"
          command: |
            cd ops/check-changed
            pip3 install -r requirements.txt
            python3 main.py "<<parameters.patterns>>"
jobs:
  yarn-monorepo:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - check-changed:
          patterns: op-bindings,op-chain-ops,packages/
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - run:
          name: Install dependencies
          command: yarn install && git diff --exit-code
      - save_cache:
          name: Save Yarn Package Cache
          key: yarn-packages-v2-{{ checksum "yarn.lock" }}
          paths:
            - "node_modules"
            - "packages/actor-tests/node_modules"
            - "packages/atst/node_modules"
            - "packages/balance-monitor/node_modules"
            - "packages/chain-mon/node_modules"
            - "packages/common-ts/node_modules"
            - "packages/contracts/node_modules"
            - "packages/contracts-bedrock/node_modules"
            - "packages/contracts-governance/node_modules"
            - "packages/contracts-periphery/node_modules"
            - "packages/core-utils/node_modules"
            - "packages/data-transport-layer/node_modules"
            - "packages/drippie-mon/node_modules"
            - "packages/fault-detector/node_modules"
            - "packages/hardhat-deploy-config/node_modules"
            - "packages/integration-tests-bedrock/node_modules"
            - "packages/message-relayer/node_modules"
            - "packages/migration-data/node_modules"
            - "packages/replica-healthcheck/node_modules"
            - "packages/sdk/node_modules"
      - run:
          name: print forge version
          command: forge --version
      - run:
          name: Build monorepo
          command: yarn build
      - persist_to_workspace:
          root: "."
          paths:
            - "packages/*/dist"
            - "packages/*/artifacts"
            - "packages/contracts/src/contract-artifacts.ts"
            - "packages/contracts/src/contract-deployed-artifacts.ts"
            - "packages/contracts/chugsplash"
            - "packages/contracts/L1"
            - "packages/contracts/L2"
            - "packages/contracts/libraries"
            - "packages/contracts/standards"

  docker-build:
    environment:
      DOCKER_BUILDKIT: 1
    parameters:
      docker_name:
        description: Docker image name
        type: string
      docker_tags:
        description: Docker image tags as csv
        type: string
      docker_file:
        description: Path to Dockerfile
        type: string
      docker_context:
        description: Docker build context
        type: string
      registry:
        description: Docker registry
        type: string
        default: "us-docker.pkg.dev"
      repo:
        description: Docker repo
        type: string
        default: "oplabs-tools-artifacts/images"
    machine:
      image: ubuntu-2204:2022.07.1
      resource_class: medium
    steps:
      - checkout
      - run:
          command: mkdir -p /tmp/docker_images
      - run:
          name: Build
          command: |
            # Check to see if DOCKER_HUB_READ_ONLY_TOKEN is set (i.e. we are in repo) before attempting to use secrets.
            # Building should work without this read only login, but may get rate limited.
            if [[ -v DOCKER_HUB_READ_ONLY_TOKEN ]]; then
              echo "$DOCKER_HUB_READ_ONLY_TOKEN" | docker login -u "$DOCKER_HUB_READ_ONLY_USER" --password-stdin
            fi
            IMAGE_BASE="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>"
            DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
            docker build \
            $(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
            -f <<parameters.docker_file>> \
            <<parameters.docker_context>>
      - run:
          name: Save
          command: |
            IMAGE_BASE="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>"
            DOCKER_LABELS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g")
            echo -ne $DOCKER_LABELS | tr ' ' '\n' | xargs -I {} docker save -o /tmp/docker_images/<<parameters.docker_name>>_{}.tar $IMAGE_BASE:{}
      - persist_to_workspace:
          root: /tmp/docker_images
          paths:
            - "."

  docker-publish:
    environment:
      DOCKER_BUILDKIT: 1
    parameters:
      docker_name:
        description: Docker image name
        type: string
      docker_tags:
        description: Docker image tags as csv
        type: string
      docker_file:
        description: Path to Dockerfile
        type: string
      docker_context:
        description: Docker build context
        type: string
        default: "."
      docker_target:
        description: "target build stage"
        type: string
        default: ""
      registry:
        description: Docker registry
        type: string
        default: "us-docker.pkg.dev"
      repo:
        description: Docker repo
        type: string
        default: "oplabs-tools-artifacts/images"
      platforms:
        description: Platforms to build for
        type: string
        default: "linux/amd64"
    machine:
      image: ubuntu-2204:2022.07.1
      resource_class: medium
    steps:
      - gcp-oidc-authenticate
      # Below is CircleCI recommended way of specifying nameservers on an Ubuntu box:
      # https://support.circleci.com/hc/en-us/articles/7323511028251-How-to-set-custom-DNS-on-Ubuntu-based-images-using-netplan
      - run: sudo sed -i '13 i \ \ \ \ \ \ \ \ \ \ \ \ nameservers:' /etc/netplan/50-cloud-init.yaml
      - run: sudo sed -i '14 i \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ addresses:' /etc/netplan/50-cloud-init.yaml
      - run: sudo sed -i "s/addresses:/ addresses":" [8.8.8.8, 8.8.4.4] /g" /etc/netplan/50-cloud-init.yaml
      - run: cat /etc/netplan/50-cloud-init.yaml
      - run: sudo netplan apply
      - checkout
      - run:
          name: Build & Publish
          command: |
            gcloud auth configure-docker <<parameters.registry>>
            IMAGE_BASE="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>"
            DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
            docker context create buildx-build
            docker buildx create --use buildx-build
            docker buildx build --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
              $(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
              -f <<parameters.docker_file>> \
              <<parameters.docker_context>>

  docker-release:
    environment:
      DOCKER_BUILDKIT: 1
    parameters:
      docker_name:
        description: Docker image name
        type: string
      docker_tags:
        description: Docker image tags as csv
        type: string
      docker_file:
        description: Path to Dockerfile
        type: string
      docker_context:
        description: Docker build context
        type: string
      docker_target:
        description: "target build stage"
        type: string
        default: ""
      registry:
        description: Docker registry
        type: string
        default: "us-docker.pkg.dev"
      repo:
        description: Docker repo
        type: string
        default: "oplabs-tools-artifacts/images"
      platforms:
        description: Platforms to build for
        type: string
        default: "linux/amd64"
    machine:
      image: ubuntu-2204:2022.07.1
      resource_class: medium
    steps:
      - gcp-cli/install
      - gcp-oidc-authenticate
      - checkout
      - run:
          name: Configure Docker
          command: |
            gcloud auth configure-docker <<parameters.registry>>
      - run:
          name: Build & Publish
          command: |
            IMAGE_BASE="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>"
            DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
            docker context create buildx-build
            docker buildx create --use buildx-build
            docker buildx build --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
              $(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
              -f <<parameters.docker_file>> \
              <<parameters.docker_context>>
      - run:
          name: Tag
          command: |
            ./ops/scripts/ci-docker-tag-op-stack-release.sh <<parameters.registry>>/<<parameters.repo>> $CIRCLE_TAG $CIRCLE_SHA1

  contracts-bedrock-coverage:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,hardhat-deploy-config
      - run:
          name: print forge version
          command: forge --version
          working_directory: packages/contracts-bedrock
      - run:
          name: generate coverage report
          command: yarn coverage:lcov
          environment:
            FOUNDRY_PROFILE: ci
          working_directory: packages/contracts-bedrock
      - run:
          name: upload coverage
          command: codecov --verbose --clean --flags contracts-bedrock-tests
          environment:
            FOUNDRY_PROFILE: ci

  contracts-bedrock-tests:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,hardhat-deploy-config
      - run:
          name: print forge version
          command: forge --version
          working_directory: packages/contracts-bedrock
      - run:
          name: run tests
          command: yarn test
          environment:
            FOUNDRY_PROFILE: ci
          working_directory: packages/contracts-bedrock

  contracts-bedrock-checks:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,hardhat-deploy-config
      - run:
          name: lint
          command: |
            yarn lint:check || echo "export LINT_STATUS=1" >> "$BASH_ENV"
          working_directory: packages/contracts-bedrock
      - run:
          name: gas snapshot
          command: |
            forge --version
            yarn gas-snapshot --check || echo "export GAS_SNAPSHOT_STATUS=1" >> "$BASH_ENV"
          environment:
            FOUNDRY_PROFILE: ci
          working_directory: packages/contracts-bedrock
      - run:
          name: validate deploy configs
          command: |
            yarn validate-deploy-configs || echo "export DEPLOY_CONFIG_STATUS=1" >> "$BASH_ENV"
          environment:
            FOUNDRY_PROFILE: ci
          working_directory: packages/contracts-bedrock
      - run:
          name: storage snapshot
          command: |
            yarn storage-snapshot
            git diff --exit-code .storage-layout || echo "export STORAGE_SNAPSHOT_STATUS=1" >> "$BASH_ENV"
          working_directory: packages/contracts-bedrock
      - run:
          name: invariant docs
          command: |
            yarn autogen:invariant-docs
            git diff --exit-code ./invariant-docs/*.md || echo "export INVARIANT_DOCS_STATUS=1" >> "$BASH_ENV"
          working_directory: packages/contracts-bedrock
      - run:
          name: check statuses
          command: |
            if [[ "$LINT_STATUS" -ne 0 ]]; then
              FAILED=1
              echo "Linting failed, see job output for details."
            fi
            if [[ "$GAS_SNAPSHOT_STATUS" -ne 0 ]]; then
              FAILED=1
              echo "Gas snapshot failed, see job output for details."
            fi
            if [[ "$DEPLOY_CONFIG_STATUS" -ne 0 ]]; then
              FAILED=1
              echo "Deploy configs invalid, see job output for details."
            fi
            if [[ "$STORAGE_SNAPSHOT_STATUS" -ne 0 ]]; then
              echo "Storage snapshot failed, see job output for details."
              FAILED=1
            fi
            if [[ "$INVARIANT_DOCS_STATUS" -ne 0 ]]; then
              echo "Invariant docs failed, see job output for details."
              FAILED=1
            fi
            if [[ "$FAILED" -ne 0 ]]; then
              exit 1
            fi

  contracts-bedrock-slither:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,hardhat-deploy-config
      - run:
          name: slither
          command: |
            slither --version
            yarn slither
          working_directory: packages/contracts-bedrock

  contracts-bedrock-validate-spaces:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,hardhat-deploy-config
      - run:
          name: validate spacers
          command: yarn validate-spacers
          working_directory: packages/contracts-bedrock

  bedrock-echidna-build:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - check-changed:
          patterns: contracts-bedrock,contracts
      - run:
          name: Compile with metadata hash
          command: yarn clean && yarn build:with-metadata
          working_directory: packages/contracts-bedrock
      - persist_to_workspace:
          root: .
          paths:
            - "node_modules"
            - packages/contracts-bedrock

  bedrock-echidna-run:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    parameters:
      echidna_target:
        description: Which echidna fuzz contract to run
        type: string
      size:
        description: Custom resource class size for the run
        type: string
        default: large
    resource_class: <<parameters.size>>
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,contracts
      - run:
          name: Echidna Fuzz <<parameters.echidna_target>>
          command: yarn echidna:<<parameters.echidna_target>>
          working_directory: packages/contracts-bedrock
          no_output_timeout: 15m

  op-bindings-build:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: medium
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: contracts-bedrock,op-bindings
      - run:
          name: check go bindings
          command: make && git diff --exit-code
          working_directory: op-bindings

  js-lint-test:
    parameters:
      package_name:
        description: Package name
        type: string
      dependencies:
        description: Regex matching dependent packages
        type: string
        default: this-package-does-not-exist
      coverage_flag:
        description: Coverage flag name
        type: string
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: <<parameters.package_name>>,<<parameters.dependencies>>
      - run:
          name: Lint
          command: yarn lint && git diff --exit-code
          working_directory: packages/<<parameters.package_name>>
      - run:
          name: Test
          command: yarn test:coverage
          working_directory: packages/<<parameters.package_name>>
      - run:
          name: Upload coverage
          command: codecov --verbose --clean --flags <<parameters.coverage_flag>>

  sdk-next-tests:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - check-changed:
          patterns: sdk,contracts-bedrock,contracts
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - run:
          name: anvil-l1
          background: true
          # atm this is goerli but we should use mainnet after bedrock is live
          command: anvil --fork-url $ANVIL_L1_FORK_URL --fork-block-number 9023108
      - run:
          name: anvil-l2
          background: true
          # atm this is goerli but we should use mainnet after bedrock is live
          command: anvil --fork-url $ANVIL_L2_FORK_URL --port 9545 --fork-block-number 9504811
      - run:
          name: build
          command: yarn build
          working_directory: packages/sdk
      - run:
          name: lint
          command: yarn lint:check
          working_directory: packages/sdk
      - run:
          name: make sure anvil l1 is up
          command: npx wait-on tcp:8545 && cast block-number --rpc-url http://localhost:8545
      - run:
          name: make sure anvil l2 is up
          command: npx wait-on tcp:9545 && cast block-number --rpc-url http://localhost:9545
      - run:
          name: test:next
          command: yarn test:next:run
          no_output_timeout: 5m
          working_directory: packages/sdk
          environment:
            # anvil[0] test private key
            VITE_E2E_PRIVATE_KEY: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
            VITE_E2E_RPC_URL_L1: http://localhost:8545
            VITE_E2E_RPC_URL_L2: http://localhost:9545


  bedrock-markdown:
    machine:
      image: ubuntu-2204:2022.07.1
    steps:
      - checkout
      - check-changed:
          patterns: specs/(.*)\.md$
      - run:
          name: yarn dev deps  # todo: what's the best way to pull in the dependencies for linting? yarn install above is using production env without dev dependencies
          command: yarn install --production=false
      - run:
          name: specs toc
          command: yarn lint:specs:toc && git diff --exit-code ./specs
      - run:
          name: markdown lint
          command: yarn lint:specs:check

  bedrock-markdown-links:
    machine:
      image: ubuntu-2204:2022.07.1
    steps:
      - checkout
      - run:
          name: link lint
          command: |
            make bedrock-markdown-links
      - slack/notify:
          channel: C055R639XT9 #notify-link-check
          event: fail
          template: basic_fail_1

  fuzz-op-node:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - check-changed:
          patterns: op-node
      - run:
          name: Fuzz
          command: make fuzz
          working_directory: op-node

  fuzz-op-chain-ops:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - check-changed:
          patterns: op-chain-ops,op-bindings
      - run:
          name: Fuzz
          command: make fuzz
          working_directory: op-chain-ops

  depcheck:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - attach_workspace: { at: "." }
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - check-changed:
          patterns: packages
      # Note: The below needs to be manually configured whenever we
      # add a new package to CI.
      - run:
          name: Check common-ts
          command: npx depcheck
          working_directory: packages/common-ts
      - run:
          name: Check contracts
          command: npx depcheck
          working_directory: packages/contracts
      - run:
          name: Check contracts-periphery
          command: npx depcheck
          working_directory: packages/contracts-periphery
      - run:
          name: Check core-utils
          command: npx depcheck
          working_directory: packages/core-utils
      - run:
          name: Check data-transport-layer
          command: npx depcheck
          working_directory: packages/data-transport-layer
      - run:
          name: Check sdk
          command: npx depcheck
          working_directory: packages/sdk
      - run:
          name: Check integration-tests
          command: npx depcheck
          working_directory: integration-tests

  atst-tests:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: large
    steps:
      - checkout
      - attach_workspace: { at: '.' }
      - check-changed:
          patterns: atst,contracts-periphery
      - restore_cache:
          name: Restore Yarn Package Cache
          keys:
            - yarn-packages-v2-{{ checksum "yarn.lock" }}
      - run:
          name: anvil
          background: true
          command: anvil --fork-url $ANVIL_L2_FORK_URL_MAINNET --fork-block-number 92093723
      - run:
          name: build
          command: yarn build
          working_directory: packages/atst
      - run:
          name: typecheck
          command: yarn typecheck
          working_directory: packages/atst
      - run:
          name: lint
          command: yarn lint:check
          working_directory: packages/atst
      - run:
          name: make sure anvil is up
          command: npx wait-on tcp:8545 && cast block-number --rpc-url http://localhost:8545
      - run:
          name: test
          command: yarn test
          no_output_timeout: 5m
          working_directory: packages/atst
          environment:
            CI: true


  go-lint:
    parameters:
      module:
        description: Go Module Name
        type: string
    docker:
      - image: cimg/go:1.19
    steps:
      - checkout
      - run:
          name: run lint
          command: |
            golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" ./...
          working_directory: <<parameters.module>>

  go-test:
    parameters:
      module:
        description: Go Module Name
        type: string
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest # only used to enable codecov.
    resource_class: xlarge
    steps:
      - checkout
      - run:
          name: prep results dir
          command: mkdir -p /tmp/test-results
      - run:
          name: run tests
          command: |
            gotestsum --format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>.xml \
            -- -parallel=8 -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out ./...
          working_directory: <<parameters.module>>
      - run:
          name: upload coverage
          command: codecov --verbose --clean --flags bedrock-go-tests
      - store_test_results:
          path: /tmp/test-results

  go-e2e-test:
    parameters:
      module:
        description: Go Module Name
        type: string
      use_http:
        description: If the op-e2e package should use HTTP clients
        type: string
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    resource_class: xlarge
    steps:
      - checkout
      - check-changed:
          patterns: op-(.+),contracts-bedrock,contracts
      - run:
          name: prep results dir
          command: mkdir -p /tmp/test-results
      - run:
          name: run tests
          command: |
            # Note: We don't use circle CI test splits because we need to split by test name, not by package. There is an additional
            # constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building.
            # Note: -parallel must be set to match the number of cores in the resource class
            OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=false OP_E2E_USE_HTTP=<<parameters.use_http>>  gotestsum \
            --format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \
            -- -timeout=20m -parallel=8 ./...
          working_directory: <<parameters.module>>
      - store_test_results:
          path: /tmp/test-results

  go-lint-test-build:
    parameters:
      binary_name:
        description: Binary name to build
        type: string
      working_directory:
        description: Working directory
        type: string
      build:
        description: Whether or not to build the binary
        type: boolean
        default: true
      dependencies:
        description: Regex matching dependent packages
        type: string
        default: this-package-does-not-exist
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
      - image: cimg/postgres:14.1
    steps:
      - checkout
      - check-changed:
          patterns: <<parameters.working_directory>>,<<parameters.dependencies>>
      - run:
          name: Lint
          command: golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 2m -e "errors.As" -e "errors.Is" ./...
          working_directory: <<parameters.working_directory>>
      - store_test_results:
          path: /test-results
      - run:
          name: Test
          command: |
            mkdir -p /test-results
            DB_USER=postgres gotestsum --junitfile /test-results/tests.xml
          working_directory: <<parameters.working_directory>>
      - when:
          condition:
            equal: [ true, <<parameters.build>> ]
          steps:
            - run:
                name: Build
                command: make <<parameters.binary_name>>
                working_directory: <<parameters.working_directory>>

  geth-tests:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - check-changed:
          patterns: l2geth
      - run:
          name: Test
          command: make test
          working_directory: l2geth

  devnet:
    machine:
      image: ubuntu-2204:2022.10.2
    parameters:
      deploy:
        description: Deploy contracts
        default: false
        type: boolean
    environment:
      DOCKER_BUILDKIT: 1
    steps:
      - checkout
      - check-changed:
          patterns: op-(.+),packages,integration-tests
      - run:
          name: Install latest golang
          command: |
            wget https://go.dev/dl/go1.19.linux-amd64.tar.gz
            sudo rm -rf /usr/local/go
            sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
            export PATH=$PATH:/usr/local/go/bin
            go version
      - run:
          name: foundryup
          command: |
            curl -L https://foundry.paradigm.xyz | bash
            source $HOME/.bashrc
            foundryup
            echo 'export PATH=$HOME/.foundry/bin:$PATH' >> $BASH_ENV
      - run:
          name: Install and build
          command: |
            yarn install
            yarn build
      - when:
          condition:
            and:
              - equal: [ true, <<parameters.deploy>> ]
          steps:
            - run:
                name: Bring up the stack
                command: |
                  make devnet-up-deploy
            - run:
                name: Check L2 config
                command: npx hardhat check-l2 --network devnetL1 --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
                working_directory: packages/contracts-bedrock
            - run:
                name: Deposit ERC20 through the bridge
                command: timeout 8m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
                working_directory: packages/sdk
            - run:
                name: Deposit ETH through the bridge
                command: timeout 8m npx hardhat deposit-eth --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
                working_directory: packages/sdk
            - run:
                name: Check the status
                command: npx hardhat check-op-node
                working_directory: packages/contracts-bedrock
            - run:
                name: Dump op-node logs
                command: |
                  docker logs ops-bedrock-op-node-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump op-geth logs
                command: |
                  docker logs ops-bedrock-l2-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump l1 logs
                command: |
                  docker logs ops-bedrock-l1-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump op-batcher logs
                command: |
                  docker logs ops-bedrock-op-batcher-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump op-proposer logs
                command: |
                  docker logs ops-bedrock-op-proposer-1 || echo "No logs."
                when: on_fail
      - when:
          condition:
            and:
              - equal: [ false, <<parameters.deploy>> ]
          steps:
            - run:
                name: Bring up the stack
                command: |
                  make devnet-up
            - run:
                name: Check L2 config
                command: |
                  npx hardhat check-l2 \
                    --network devnetL1 \
                    --l2-rpc-url http://localhost:9545 \
                    --l1-rpc-url http://localhost:8545 \
                    --l2-output-oracle-address 0x6900000000000000000000000000000000000000
                working_directory: packages/contracts-bedrock
            - run:
                name: Deposit ERC20 through the bridge
                command: timeout 10m npx hardhat deposit-erc20 --network devnetL1
                working_directory: packages/sdk
            - run:
                name: Deposit ETH through the bridge
                command: timeout 10m npx hardhat deposit-eth --network devnetL1
                working_directory: packages/sdk
            - run:
                name: Check the status
                command: npx hardhat check-op-node
                working_directory: packages/contracts-bedrock
            - run:
                name: Dump op-node logs
                command: |
                  docker logs ops-bedrock-op-node-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump op-geth logs
                command: |
                  docker logs ops-bedrock-l2-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump l1 logs
                command: |
                  docker logs ops-bedrock-l1-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump op-batcher logs
                command: |
                  docker logs ops-bedrock-op-batcher-1 || echo "No logs."
                when: on_fail
            - run:
                name: Dump op-proposer logs
                command: |
                  docker logs ops-bedrock-op-proposer-1 || echo "No logs."
                when: on_fail

  integration-tests:
    machine:
      image: ubuntu-2204:2022.07.1
    environment:
      DOCKER_BUILDKIT: 1
    parallelism: 3
    steps:
      - checkout
      - check-changed:
          patterns: l2geth,common-ts,contracts,core-utils,message-relayer,data-transport-layer,replica-healthcheck,sdk,batch-submitter,gas-oracle,bss-core,integration-tests
      - run:
          name: Bring up the stack
          command: |
            docker-compose build --progress=plain
            docker-compose up -d --scale replica_healthcheck=1
          working_directory: ops
      - run:
          name: Wait for sequencer
          command: bash scripts/wait-for-sequencer.sh
          working_directory: ops
      - run:
          name: Run integration tests
          command: |
            circleci tests glob "../integration-tests/test/*.spec.ts" | circleci tests split | tee splits.txt
            docker-compose run integration_tests $(cat splits.txt)
          working_directory: ops
      - run:
          command: echo "Done."

  semgrep-scan:
    parameters:
      diff_branch:
        type: string
        default: develop
    environment:
      TEMPORARY_BASELINE_REF: << parameters.diff_branch >>
      SEMGREP_REPO_URL: << pipeline.project.git_url >>
      SEMGREP_BRANCH: << pipeline.git.branch >>
      SEMGREP_COMMIT: << pipeline.git.revision >>

      # Change job timeout (default is 1800 seconds; set to 0 to disable)
      SEMGREP_TIMEOUT: 3000

    docker:
      - image: returntocorp/semgrep
    resource_class: medium
    steps:
      - checkout
      - unless:
          condition:
            equal: [ "develop", << pipeline.git.branch >> ]
          steps:
            - run:
                # Scan changed files in PRs, block on new issues only (existing issues ignored)
                # Do a full scan when scanning develop, otherwise do an incremental scan.
                name: "Conditionally set BASELINE env var"
                command: |
                  echo 'export SEMGREP_BASELINE_REF=${TEMPORARY_BASELINE_REF}' >> $BASH_ENV
      - run:
          name: "Set environment variables" # for PR comments and in-app hyperlinks to findings
          command: |
            echo 'export SEMGREP_PR_ID=${CIRCLE_PULL_REQUEST##*/}' >> $BASH_ENV
            echo 'export SEMGREP_JOB_URL=$CIRCLE_BUILD_URL' >> $BASH_ENV
            echo 'export SEMGREP_REPO_NAME=$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV
      - run:
          name: "Semgrep scan"
          command: semgrep ci

  go-mod-tidy:
    docker:
      - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
    steps:
      - checkout
      - run:
          name: "Go mod tidy"
          command: make mod-tidy && git diff --exit-code

  hive-test:
    parameters:
      version:
        type: string
        default: develop
      sim:
        type: string
    machine:
      image: ubuntu-2204:2022.07.1
      docker_layer_caching: true
      resource_class: large
    steps:
      - attach_workspace:
          at: /tmp/docker_images
      - run:
          name: Docker Load
          command: |
            docker load -i /tmp/docker_images/op-batcher_<<parameters.version>>.tar
            docker load -i /tmp/docker_images/op-proposer_<<parameters.version>>.tar
            docker load -i /tmp/docker_images/op-node_<<parameters.version>>.tar
      - run:
          command: git clone https://github.com/ethereum-optimism/hive.git .
      - go/load-cache
      - go/mod-download
      - go/save-cache
      - run: { command: "go build ." }
      - run:
          command: |
            ./hive \
            -sim=<<parameters.sim>> \
            -sim.loglevel=5 \
            -client=go-ethereum_v1.11.6,op-geth_optimism,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>> |& tee /tmp/hive.log || echo "failed."
      - run:
          command: |
            tar -cvf /tmp/workspace.tgz -C /home/circleci/project /home/circleci/project/workspace
          name: "Archive workspace"
      - store_artifacts:
          path: /tmp/workspace.tgz
          destination: hive-workspace.tgz
      - run:
          command: "! grep 'pass.*=false' /tmp/hive.log"

  bedrock-go-tests:
    docker:
      - image: cimg/go:1.19
    resource_class: medium
    steps:
      - run: echo Done

  fpp-verify:
    docker:
      - image: cimg/go:1.19
    steps:
      - checkout
      - run:
          name: verify-goerli
          command: |
            make verify-goerli
          working_directory: op-program
      - slack/notify:
          channel: C03N11M0BBN
          event: fail
          template: basic_fail_1

workflows:
  main:
    jobs:
      - yarn-monorepo
      - js-lint-test:
          name: common-ts-tests
          coverage_flag: common-ts-tests
          package_name: common-ts
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: contracts-tests
          coverage_flag: contracts-tests
          package_name: contracts
          dependencies: hardhat-deploy-config
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: core-utils-tests
          coverage_flag: core-utils-tests
          package_name: core-utils
          requires:
            - yarn-monorepo
      - contracts-bedrock-tests:
          requires:
            - yarn-monorepo
      - contracts-bedrock-coverage:
          requires:
            - yarn-monorepo
      - contracts-bedrock-checks:
          requires:
            - yarn-monorepo
      - contracts-bedrock-slither:
          requires:
            - yarn-monorepo
      - contracts-bedrock-validate-spaces:
          requires:
            - yarn-monorepo
      - op-bindings-build:
          requires:
            - yarn-monorepo
      - atst-tests:
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: actor-tests-tests
          coverage_flag: actor-tests-tests
          package_name: actor-tests
          dependencies: "(core-utils|sdk)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: contracts-periphery-tests
          coverage_flag: contracts-periphery-tests
          package_name: contracts-periphery
          dependencies: "(contracts|contracts-bedrock|core-utils|hardhat-deploy-config)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: dtl-tests
          coverage_flag: dtl-tests
          package_name: data-transport-layer
          dependencies: "(common-ts|contracts|core-utils)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: chain-mon-tests
          coverage_flag: chain-mon-tests
          package_name: chain-mon
          dependencies: "(common-ts|contracts-periphery|core-utils|sdk)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: fault-detector-tests
          coverage_flag: fault-detector-tests
          package_name: fault-detector
          dependencies: "(common-ts|contracts|core-utils|sdk)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: message-relayer-tests
          coverage_flag: message-relayer-tests
          package_name: message-relayer
          dependencies: "(common-ts|core-utils|sdk)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: replica-healthcheck-tests
          coverage_flag: replica-healthcheck-tests
          package_name: replica-healthcheck
          dependencies: "(common-ts|core-utils)"
          requires:
            - yarn-monorepo
      - sdk-next-tests:
          name: sdk-next-tests
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: sdk-tests
          coverage_flag: sdk-tests
          package_name: sdk
          dependencies: "(contracts|core-utils)"
          requires:
            - yarn-monorepo
      - js-lint-test:
          name: balance-monitor-tests
          coverage_flag: balance-monitor-tests
          package_name: balance-monitor
          requires:
            - yarn-monorepo
      - depcheck:
          requires:
            - yarn-monorepo
      - devnet:
          name: devnet (with deployed contracts)
          deploy: true
      - devnet:
          name: devnet (with genesis contracts)
          deploy: false
      - go-lint-test-build:
          name: batch-submitter-tests
          binary_name: batch-submitter
          working_directory: batch-submitter
          dependencies: bss-core
      - go-lint-test-build:
          name: proxyd-tests
          binary_name: proxyd
          working_directory: proxyd
      - go-lint-test-build:
          name: gas-oracle-tests
          binary_name: gas-oracle
          working_directory: gas-oracle
      - go-lint-test-build:
          name: indexer-tests
          binary_name: indexer
          working_directory: indexer
          dependencies: op-bindings
      - go-lint-test-build:
          name: bss-core-tests
          binary_name: bss-core
          working_directory: bss-core
          build: false
      - go-lint-test-build:
          name: op-heartbeat tests
          binary_name: op-heartbeat
          working_directory: op-heartbeat
      - geth-tests
      - integration-tests
      - semgrep-scan
      - go-mod-tidy
      - fuzz-op-node
      - fuzz-op-chain-ops
      - bedrock-markdown
      - go-lint:
          name: op-batcher-lint
          module: op-batcher
      - go-lint:
          name: op-bindings-lint
          module: op-bindings
      - go-lint:
          name: op-chain-ops-lint
          module: op-chain-ops
      - go-lint:
          name: op-e2e-lint
          module: op-e2e
      - go-lint:
          name: op-node-lint
          module: op-node
      - go-lint:
          name: op-proposer-lint
          module: op-proposer
      - go-lint:
          name: op-challenger-lint
          module: op-challenger
      - go-lint:
          name: op-program-lint
          module: op-program
      - go-lint:
          name: op-service-lint
          module: op-service
      - go-lint:
          name: op-wheel-lint
          module: op-wheel
      - go-test:
          name: op-batcher-tests
          module: op-batcher
      - go-test:
          name: op-bindings-tests
          module: op-bindings
      - go-test:
          name: op-chain-ops-tests
          module: op-chain-ops
      - go-test:
          name: op-node-tests
          module: op-node
          # TODO: override resource class
      - go-test:
          name: op-proposer-tests
          module: op-proposer
      - go-test:
          name: op-challenger-tests
          module: op-challenger
      - go-test:
          name: op-program-tests
          module: op-program
      - go-test:
          name: op-service-tests
          module: op-service
      - go-e2e-test:
          name: op-e2e-WS-tests
          module: op-e2e
          use_http: "false"
      - go-e2e-test:
          name: op-e2e-HTTP-tests
          module: op-e2e
          use_http: "true"
      - bedrock-go-tests:
          requires:
            - op-batcher-lint
            - op-bindings-lint
            - op-chain-ops-lint
            - op-e2e-lint
            - op-node-lint
            - op-proposer-lint
            - op-challenger-lint
            - op-program-lint
            - op-service-lint
            - op-batcher-tests
            - op-bindings-tests
            - op-chain-ops-tests
            - op-node-tests
            - op-proposer-tests
            - op-challenger-tests
            - op-program-tests
            - op-service-tests
            - op-e2e-WS-tests
            - op-e2e-HTTP-tests
      - docker-build:
          name: op-node-docker-build
          docker_file: op-node/Dockerfile
          docker_name: op-node
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: op-node-docker-publish
          docker_name: op-node
          docker_file: op-node/Dockerfile
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
          platforms: "linux/amd64,linux/arm64"
      - docker-build:
          name: op-batcher-docker-build
          docker_file: op-batcher/Dockerfile
          docker_name: op-batcher
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: op-batcher-docker-publish
          docker_file: op-batcher/Dockerfile
          docker_name: op-batcher
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
          platforms: "linux/amd64,linux/arm64"
      - docker-build:
          name: op-program-docker-build
          docker_file: op-program/Dockerfile
          docker_name: op-program
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: op-program-docker-publish
          docker_file: op-program/Dockerfile
          docker_name: op-program
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
          platforms: "linux/amd64,linux/arm64"
      - docker-build:
          name: op-proposer-docker-build
          docker_file: op-proposer/Dockerfile
          docker_name: op-proposer
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: op-proposer-docker-publish
          docker_file: op-proposer/Dockerfile
          docker_name: op-proposer
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
          platforms: "linux/amd64,linux/arm64"
      - docker-build:
          name: op-challenger-docker-build
          docker_file: op-challenger/Dockerfile
          docker_name: op-challenger
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: op-challenger-docker-publish
          docker_file: op-challenger/Dockerfile
          docker_name: op-challenger
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
          platforms: "linux/amd64,linux/arm64"
      - docker-build:
          name: op-heartbeat-docker-build
          docker_file: op-heartbeat/Dockerfile
          docker_name: op-heartbeat
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: op-heartbeat-docker-publish
          docker_file: op-heartbeat/Dockerfile
          docker_name: op-heartbeat
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
      - docker-build:
          name: indexer-docker-build
          docker_file: indexer/Dockerfile
          docker_name: indexer
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
      - docker-publish:
          name: indexer-docker-publish
          docker_file: indexer/Dockerfile
          docker_name: indexer
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          context:
            - oplabs-gcr
      - docker-publish:
          name: chain-mon-docker-publish
          docker_file: ./ops/docker/Dockerfile.packages
          docker_name: chain-mon
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_target: wd-mon
          context:
            - oplabs-gcr
      - docker-publish:
          name: fault-detector-docker-publish
          docker_file: ./ops/docker/Dockerfile.packages
          docker_name: fault-detector
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_target: fault-detector
          context:
            - oplabs-gcr
      - hive-test:
          name: hive-test-rpc
          version: <<pipeline.git.revision>>
          sim: optimism/rpc
          requires:
            - op-node-docker-build
            - op-batcher-docker-build
            - op-proposer-docker-build
            - op-challenger-docker-build
      - hive-test:
          name: hive-test-p2p
          version: <<pipeline.git.revision>>
          sim: optimism/p2p
          requires:
            - op-node-docker-build
            - op-batcher-docker-build
            - op-proposer-docker-build
            - op-challenger-docker-build
      - hive-test:
          name: hive-test-l1ops
          version: <<pipeline.git.revision>>
          sim: optimism/l1ops
          requires:
            - op-node-docker-build
            - op-batcher-docker-build
            - op-proposer-docker-build
            - op-challenger-docker-build
  release:
    jobs:
      - hold:
          type: approval
          filters:
            tags:
              only: /^(fault-detector|proxyd|op-[a-z0-9\-]*)\/v.*/
            branches:
              ignore: /.*/
      - docker-release:
          name: op-node-docker-release
          filters:
            tags:
              only: /^op-node\/v.*/
            branches:
              ignore: /.*/
          docker_file: op-node/Dockerfile
          docker_name: op-node
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
          platforms: "linux/amd64,linux/arm64"
          context:
            - oplabs-gcr-release
          requires:
            - hold
      - docker-release:
          name: op-batcher-docker-release
          filters:
            tags:
              only: /^op-batcher\/v.*/
            branches:
              ignore: /.*/
          docker_file: op-batcher/Dockerfile
          docker_name: op-batcher
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
          platforms: "linux/amd64,linux/arm64"
          context:
            - oplabs-gcr-release
          requires:
            - hold
      - docker-release:
          name: op-proposer-docker-release
          filters:
            tags:
              only: /^op-proposer\/v.*/
            branches:
              ignore: /.*/
          docker_file: op-proposer/Dockerfile
          docker_name: op-proposer
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
          platforms: "linux/amd64,linux/arm64"
          context:
            - oplabs-gcr-release
          requires:
            - hold
      - docker-release:
          name: op-challenger-docker-release
          filters:
            tags:
              only: /^op-challenger\/v.*/
            branches:
              ignore: /.*/
          docker_file: op-challenger/Dockerfile
          docker_name: op-challenger
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
          platforms: "linux/amd64,linux/arm64"
          context:
            - oplabs-gcr-release
          requires:
            - hold
      - docker-release:
          name: fault-detector-docker-release
          filters:
            tags:
              only: /^fault-detector\/v.*/
            branches:
              ignore: /.*/
          docker_file: ./ops/docker/Dockerfile.packages
          docker_name: fault-detector
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_target: fault-detector
          docker_context: .
          platforms: "linux/amd64,linux/arm64"
          context:
            - oplabs-gcr-release
          requires:
            - hold
      - docker-build:
          name: op-migrate-docker-release
          filters:
            tags:
              only: /^op-migrate\/v.*/
            branches:
              ignore: /.*/
          docker_file: op-chain-ops/Dockerfile
          docker_name: op-migrate
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
          context:
            - oplabs-gcr-release
          requires:
            - hold
      - docker-release:
          name: proxyd-docker-release
          filters:
            tags:
              only: /^proxyd\/v.*/
            branches:
              ignore: /.*/
          docker_file: proxyd/Dockerfile
          docker_name: proxyd
          docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
          docker_context: .
          context:
            - oplabs-gcr-release
          requires:
            - hold
  release-ci-builder:
    jobs:
      - docker-publish:
          name: ci-builder-docker-publish
          filters:
            tags:
              only: /^ci-builder\/v.*/
            branches:
              ignore: /.*/
          docker_file: ./ops/docker/ci-builder/Dockerfile
          docker_name: ci-builder
          docker_tags: <<pipeline.git.revision>>,latest
          docker_context: ./ops/docker/ci-builder
          context:
            - oplabs-gcr
  scheduled-fpp:
    triggers:
      - schedule:
          # run every 4 hours
          cron: "0 0,6,12,18 * * *"
          filters:
            branches:
              only: [ "develop" ]
    jobs:
      - fpp-verify:
          context:
            - slack
            - oplabs-fpp-nodes

  scheduled-link-check:
    triggers:
      - schedule:
          # Run once a day, only on the develop branch
          cron: "0 0 * * *"
          filters:
            branches:
              only: [ "develop" ]
    jobs:
      - bedrock-markdown-links:
          context: slack
