name: Docs

# Ensures that only one workflow task will run at a time. Previous deployments, if
# already in process, won't get cancelled. Instead, we let the first to complete
# then queue the latest pending workflow, cancelling any workflows in between
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths:
      # doc source files
      - 'book/**'
      - '**/firebase.json'
      - '**/.firebaserc'
      - 'katex-header.html'
      # rustdoc source files
      - '**/*.rs'
      - '**/Cargo.toml'
      - '**/Cargo.lock'
      # configuration files
      - '.cargo/config.toml'
      - '**/clippy.toml'
      # workflow definitions
      - '.github/workflows/docs.yml'

  pull_request:
    branches:
      - main
    paths:
      # doc source files
      - 'book/**'
      - '**/firebase.json'
      - '**/.firebaserc'
      - 'katex-header.html'
      # rustdoc source files
      - '**/*.rs'
      - '**/Cargo.toml'
      - '**/Cargo.lock'
      # configuration files
      - '.cargo/config.toml'
      - '**/clippy.toml'
      # workflow definitions
      - '.github/workflows/docs.yml'

env:
  RUST_LOG: ${{ vars.RUST_LOG }}
  RUST_BACKTRACE: ${{ vars.RUST_BACKTRACE }}
  RUST_LIB_BACKTRACE: ${{ vars.RUST_LIB_BACKTRACE }}
  COLORBT_SHOW_HIDDEN: ${{ vars.COLORBT_SHOW_HIDDEN }}
  FIREBASE_CHANNEL: ${{ github.event_name == 'pull_request' && 'preview' || 'live' }}
  # cargo doc doesn't support '--  -D warnings', so we have to add it here
  # https://github.com/rust-lang/cargo/issues/8424#issuecomment-774662296
  #
  # The -A and -W settings must be the same as the `rustdocflags` in:
  # https://github.com/ZcashFoundation/zebra/blob/main/.cargo/config.toml#L87
  RUSTDOCFLAGS: --html-in-header katex-header.html -D warnings -A rustdoc::private_intra_doc_links

jobs:
  build-docs-book:
    name: Build and Deploy Zebra Book Docs
    timeout-minutes: 5
    runs-on: ubuntu-latest
    permissions:
      checks: write
      contents: 'read'
      id-token: 'write'
      pull-requests: write
    steps:
      - name: Checkout the source code
        uses: actions/checkout@v4.1.0
        with:
          persist-credentials: false

      - uses: r7kamura/rust-problem-matchers@v1.4.0

      - name: Setup mdBook
        uses: jontze/action-mdbook@v2.2.2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          mdbook-version: '~0.4'
          use-linkcheck: true
          use-mermaid: true

      - name: Build Zebra book
        run: |
          mdbook build book --dest-dir "$(pwd)"/target/book

      # Setup gcloud CLI
      - name: Authenticate to Google Cloud
        id: auth
        uses: google-github-actions/auth@v1.1.1
        with:
          retries: '3'
          workload_identity_provider: '${{ vars.GCP_WIF }}'
          service_account: '${{ vars.GCP_FIREBASE_SA }}'

      # TODO: remove this step after issue https://github.com/FirebaseExtended/action-hosting-deploy/issues/174 is fixed

      - name: Add $GCP_FIREBASE_SA_PATH to env
        run: |
          # shellcheck disable=SC2002
          echo "GCP_FIREBASE_SA_PATH=$(cat ${{ steps.auth.outputs.credentials_file_path }} | tr -d '\n')" >> "$GITHUB_ENV"

      - name: Deploy Zebra book to firebase
        uses: FirebaseExtended/action-hosting-deploy@v0.7.1
        with:
          firebaseServiceAccount: ${{ env.GCP_FIREBASE_SA_PATH }}
          channelId: ${{ env.FIREBASE_CHANNEL }}
          projectId: ${{ vars.GCP_FIREBASE_PROJECT }}
          target: docs-book

  build-docs-external:
    name: Build and Deploy Zebra External Docs
    timeout-minutes: 45
    runs-on: ubuntu-latest
    permissions:
      checks: write
      contents: 'read'
      id-token: 'write'
      pull-requests: write
    steps:
      - name: Checkout the source code
        uses: actions/checkout@v4.1.0
        with:
          persist-credentials: false

      - name: Install last version of Protoc
        uses: arduino/setup-protoc@v2.1.0
        with:
          version: '23.x'
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      # Setup Rust with beta toolchain and default profile (to include rust-docs)
      - name: Setup Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=beta --profile=default

      - uses: Swatinem/rust-cache@v2.7.0

      - name: Build external docs
        run: |
          # Exclude zebra-utils, it is not for library or app users
          cargo doc --no-deps --workspace --all-features --exclude zebra-utils --target-dir "$(pwd)"/target/external

      # Setup gcloud CLI
      - name: Authenticate to Google Cloud
        id: auth
        uses: google-github-actions/auth@v1.1.1
        with:
          retries: '3'
          workload_identity_provider: '${{ vars.GCP_WIF }}'
          service_account: '${{ vars.GCP_FIREBASE_SA }}'

      # TODO: remove this step after issue https://github.com/FirebaseExtended/action-hosting-deploy/issues/174 is fixed
      - name: Add $GCP_FIREBASE_SA_PATH to env
        run: |
          # shellcheck disable=SC2002
          echo "GCP_FIREBASE_SA_PATH=$(cat ${{ steps.auth.outputs.credentials_file_path }} | tr -d '\n')" >> "$GITHUB_ENV"

      - name: Deploy external docs to firebase
        uses: FirebaseExtended/action-hosting-deploy@v0.7.1
        with:
          firebaseServiceAccount: ${{ env.GCP_FIREBASE_SA_PATH }}
          channelId: ${{ env.FIREBASE_CHANNEL }}
          target: docs-external
          projectId: ${{ vars.GCP_FIREBASE_PROJECT }}

  build-docs-internal:
    name: Build and Deploy Zebra Internal Docs
    timeout-minutes: 45
    runs-on: ubuntu-latest
    permissions:
      checks: write
      contents: 'read'
      id-token: 'write'
      pull-requests: write
    steps:
      - name: Checkout the source code
        uses: actions/checkout@v4.1.0
        with:
          persist-credentials: false

      - uses: r7kamura/rust-problem-matchers@v1.4.0

      - name: Install last version of Protoc
        uses: arduino/setup-protoc@v2.1.0
        with:
          version: '23.x'
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      # Setup Rust with beta toolchain and default profile (to include rust-docs)
      - name: Setup Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=beta --profile=default

      - uses: Swatinem/rust-cache@v2.7.0

      - name: Build internal docs
        run: |
          cargo doc --no-deps --workspace --all-features --document-private-items --target-dir "$(pwd)"/target/internal

      # Setup gcloud CLI
      - name: Authenticate to Google Cloud
        id: auth
        uses: google-github-actions/auth@v1.1.1
        with:
          retries: '3'
          workload_identity_provider: '${{ vars.GCP_WIF }}'
          service_account: '${{ vars.GCP_FIREBASE_SA }}'

      # TODO: remove this step after issue https://github.com/FirebaseExtended/action-hosting-deploy/issues/174 is fixed
      - name: Add $GCP_FIREBASE_SA_PATH to env
        run: |
          # shellcheck disable=SC2002
          echo "GCP_FIREBASE_SA_PATH=$(cat ${{ steps.auth.outputs.credentials_file_path }} | tr -d '\n')" >> "$GITHUB_ENV"

      - name: Deploy internal docs to firebase
        uses: FirebaseExtended/action-hosting-deploy@v0.7.1
        with:
          firebaseServiceAccount: ${{ env.GCP_FIREBASE_SA_PATH }}
          channelId: ${{ env.FIREBASE_CHANNEL }}
          target: docs-internal
          projectId: ${{ vars.GCP_FIREBASE_PROJECT }}
