name: gh-pages

on:
  push:
    branches:
      - main
  pull_request:
  release:
    types: [published]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  guide-build:
    runs-on: ubuntu-latest
    outputs:
      tag_name: ${{ steps.prepare_tag.outputs.tag_name }}
    steps:
      - uses: actions/checkout@v2

      - uses: actions-rs/toolchain@v1
        with:
          toolchain: nightly
          profile: minimal

      - name: Setup mdBook
        uses: peaceiris/actions-mdbook@v1
        with:
          mdbook-version: "0.4.10"

      - name: Prepare tag
        id: prepare_tag
        run: |
          TAG_NAME="${GITHUB_REF##*/}"
          echo "::set-output name=tag_name::${TAG_NAME}"

      # Build some internal docs and inject a banner on top of it.
      - name: Build the internal docs
        run: |
          mkdir target
          mkdir -p gh-pages-build/internal
          echo "<div class='internal-banner' style='position:fixed; z-index: 99999; color:red;border:3px solid red;margin-left: auto; margin-right: auto; width: 430px;left:0;right: 0;'><div style='display: flex; align-items: center; justify-content: center;'> ⚠️ Internal Docs ⚠️ Not Public API 👉 <a href='https://pyo3.rs/main/doc/pyo3/index.html' style='color:red;text-decoration:underline;'>Official Docs Here</a></div></div>" > target/banner.html
          cargo xtask doc --internal
          cp -r target/doc gh-pages-build/internal
        env:
          RUSTDOCFLAGS: "--cfg docsrs --Z unstable-options --document-hidden-items --html-before-content target/banner.html"

      - name: Deploy internal docs
        if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'release' }}
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./gh-pages-build/internal
          destination_dir: internal
          full_commit_message: "Upload internal documentation"

      - name: Clear the extra artefacts created earlier
        run: rm -rf target

      # This builds the book in gh-pages-build. See https://github.com/rust-lang-nursery/mdBook/issues/698
      - name: Build the guide
        run: mdbook build -d ../gh-pages-build guide
        env:
          PYO3_VERSION_TAG: ${{ steps.prepare_tag.outputs.tag_name }}

        # This adds the docs to gh-pages-build/doc
      - name: Build the doc
        run: |
          cargo xtask doc
          cp -r target/doc gh-pages-build/doc
          echo "<meta http-equiv=refresh content=0;url=pyo3/index.html>" > gh-pages-build/doc/index.html

      - name: Deploy docs and the guide
        if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'release' }}
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./gh-pages-build/
          destination_dir: ${{ steps.prepare_tag.outputs.tag_name }}
          full_commit_message: "Upload documentation for ${{ steps.prepare_tag.outputs.tag_name }}"

  guide-release:
    needs: guide-build
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'release' }}
    steps:
      - name: Create latest tag redirects
        env:
          TAG_NAME: ${{ needs.build.outputs.tag_name }}
        run: |
          mkdir public
          echo "<meta http-equiv=refresh content=0;url='$TAG_NAME/'>" > public/index.html
          ln -sfT $TAG_NAME public/latest

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public/
          full_commit_message: "Release ${{ needs.build.outputs.tag_name }}"
          keep_files: true

  cargo-benchmark:
    if: ${{ github.ref_name == 'main' }}
    name: Cargo benchmark
    needs: guide-build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: stable
          override: true

      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: cargo-${{ runner.os }}-bench-${{ hashFiles('**/Cargo.toml') }}
        continue-on-error: true

      - name: Run benchmarks
        run: |
          for bench in call dict gil list pyclass pyobject set tuple; do
            cargo bench --features hashbrown --bench "bench_$bench" -- --output-format bencher | tee -a output.txt
          done

      # Download previous benchmark result from cache (if exists)
      - name: Download previous benchmark data
        uses: actions/cache@v1
        with:
          path: ./cache
          key: ${{ runner.os }}-benchmark

      # Run `github-action-benchmark` action
      - name: Store benchmark result
        uses: benchmark-action/github-action-benchmark@v1
        with:
          name: pyo3-bench
          # What benchmark tool the output.txt came from
          tool: "cargo"
          # Where the output from the benchmark tool is stored
          output-file-path: output.txt
          # GitHub API token to make a commit comment
          github-token: ${{ secrets.GITHUB_TOKEN }}
          auto-push: ${{ github.event_name != 'pull_request' }}

  pytest-benchmark:
    if: ${{ github.ref_name == 'main' }}
    name: Pytest benchmark
    needs: cargo-benchmark
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: stable
          override: true

      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: cargo-${{ runner.os }}-pytest-bench-${{ hashFiles('**/Cargo.toml') }}
        continue-on-error: true

      - name: Download previous benchmark data
        uses: actions/cache@v1
        with:
          path: ./cache
          key: ${{ runner.os }}-pytest-benchmark

      - name: Run benchmarks
        run: |
          pip install nox
          nox -f pytests/noxfile.py -s bench -- --benchmark-json $(pwd)/output.json
      - name: Store benchmark result
        uses: benchmark-action/github-action-benchmark@v1
        with:
          name: pytest-bench
          tool: "pytest"
          output-file-path: output.json
          github-token: ${{ secrets.GITHUB_TOKEN }}
          auto-push: ${{ github.event_name != 'pull_request' }}
