# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: Deploy
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - "*"
jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions/setup-ruby@v1
      - name: Install dependencies
        run: |
          bundle install
      - name: Configure for production
        run: |
          echo "BASE_URL=" >> ../env.sh
          echo "ORIGIN=${{ github.repository }}" >> ../env.sh
          echo "TARGET_BRANCH=asf-site" >> ../env.sh
          echo >> _extra_config.yml
        if: |
          github.event_name == 'push' &&
            github.repository == 'apache/arrow-site'
      - name: Configure for GitHub Pages on master
        run: |
          owner=$(jq --raw-output .repository.owner.login ${GITHUB_EVENT_PATH})
          repository=$(jq --raw-output .repository.name ${GITHUB_EVENT_PATH})
          echo "BASE_URL=/${repository}" >> ../env.sh
          echo "ORIGIN=${owner}/${repository}" >> ../env.sh
          echo "TARGET_BRANCH=gh-pages" >> ../env.sh
          # "url:" is for the opengraph tags, and it can't be relative
          echo "url: https://${owner}.github.io/${repository}" >> _extra_config.yml
        if: |
          github.event_name == 'push' &&
            github.repository != 'apache/arrow-site'
      - name: Configure for GitHub Pages on pull request
        run: |
          owner=$(jq --raw-output .pull_request.head.user.login ${GITHUB_EVENT_PATH})
          repository=$(jq --raw-output .pull_request.head.repo.name ${GITHUB_EVENT_PATH})
          echo "BASE_URL=/${repository}" >> ../env.sh
          echo "ORIGIN=${owner}/${repository}" >> ../env.sh
          echo "TARGET_BRANCH=gh-pages" >> ../env.sh
          # "url:" is for the opengraph tags, and it can't be relative
          echo "url: https://${owner}.github.io/${repository}" >> _extra_config.yml
        if: |
          github.event_name == 'pull_request'
      - name: Build
        run: |
          . ../env.sh
          JEKYLL_ENV=production \
            bundle exec \
              jekyll build \
                --baseurl="${BASE_URL}" \
                --config=_config.yml,_extra_config.yml \
                --destination=../build
      - name: Deploy
        run: |
          . ../env.sh
          git config user.name "$(git log -1 --pretty=format:%an)"
          git config user.email "$(git log -1 --pretty=format:%ae)"
          git remote add deploy \
            https://x-access-token:${GITHUB_TOKEN}@github.com/${ORIGIN}.git
          git fetch deploy
          if ! git checkout --track deploy/${TARGET_BRANCH}; then
            git checkout -b ${TARGET_BRANCH} remotes/origin/asf-site
          fi
          if [ "$ORIGIN" != "apache/arrow-site" ]; then
            # Pull latest asf-site (for docs etc.) if we're not already on it
            git remote add apache https://github.com/apache/arrow-site.git
            git fetch apache
            git reset --hard apache/asf-site
            PUSH_ARGS="-f"
          fi
          rsync \
            -a \
            --delete \
            --exclude '/.git/' \
            --exclude '/docs/' \
            ../build/ \
            ./
          rsync \
            -a \
            ../build/docs/ \
            docs/
          touch .nojekyll
          if [ "$(git status --porcelain)" != "" ]; then
            # There are changes to the built site
            git add --all
            git commit -m "Updating built site (build ${GITHUB_SHA})"
            git push ${PUSH_ARGS} deploy ${TARGET_BRANCH}
          else
            echo "No changes to the built site"
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        if: |
          github.event_name == 'push' ||
            (github.event_name == 'pull_request' &&
              github.repository == github.event.pull_request.head.repo.full_name)
      - name: Comment GitHub Pages URL
        uses: actions/github-script@0.2.0
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const payload = context.payload;
            const base_repo = payload.pull_request.base.repo;
            const head = payload.pull_request.head;
            const head_repo = head.repo;
            const github_pages_url =
              `https://${head_repo.owner.login}.github.io/${head_repo.name}/`;
            const body = `${github_pages_url}\n${head.sha}`;
            github.issues.createComment({
                                          "owner": base_repo.owner.login,
                                          "repo": base_repo.name,
                                          "issue_number": payload.number,
                                          "body": body
                                        });
        if: |
          github.event_name == 'pull_request' &&
            github.repository == github.event.pull_request.head.repo.full_name
