on:
  issue_comment:
    types:
      - created

# This action allows people with write access to the repo to rebase a PRs base branch
# by commenting `/rebase ${branch}` on the PR while avoiding CODEOWNER notifications.

jobs:
  rebase:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'NixOS' && github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
    steps:
      - uses: peter-evans/create-or-update-comment@v1
        with:
          comment-id: ${{ github.event.comment.id }}
          reactions: eyes
      - uses: scherermichael-oss/action-has-permission@1.0.6
        id: check-write-access
        with:
          required-permission: write
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: check permissions
        run: |
          echo "Commenter doesn't have write access to the repo"
          exit 1
        if: "! steps.check-write-access.outputs.has-permission"
      - name: setup
        run: |
          curl "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.issue.number }}" 2>/dev/null >pr.json
          cat <<EOF >>"$GITHUB_ENV"
          CAN_MODIFY=$(jq -r '.maintainer_can_modify' pr.json)
          COMMITS=$(jq -r '.commits' pr.json)
          CURRENT_BASE=$(jq -r '.base.ref' pr.json)
          PR_BRANCH=$(jq -r '.head.ref' pr.json)
          COMMENT_BRANCH=$(echo ${{ github.event.comment.body }} | awk "/^\/rebase / {print \$2}")
          PULL_REQUEST=${{ github.event.issue.number }}
          EOF
          rm pr.json
      - name: check branch
        env:
          PERMANENT_BRANCHES: "haskell-updates|master|nixos|nixpkgs|python-unstable|release|staging"
          VALID_BRANCHES: "haskell-updates|master|python-unstable|release-20.09|release-21.05|staging|staging-20.09|staging-21.05|staging-next|staging-next-21.05"
        run: |
          message() {
            cat <<EOF
          Can't rebase $PR_BRANCH from $CURRENT_BASE onto $COMMENT_BRANCH (PR:$PULL_REQUEST COMMITS:$COMMITS)
          EOF
          }
          if ! [[ "$COMMENT_BRANCH" =~ ^($VALID_BRANCHES)$ ]]; then
            cat <<EOF
          Check that the branch from the comment is valid:

          $(message)

          This action can only rebase onto these branches:

          $VALID_BRANCHES

          \`/rebase \${branch}\` must be at the start of the line
          EOF
            exit 1
          fi
          if [[ "$COMMENT_BRANCH" == "$CURRENT_BASE" ]]; then
            cat <<EOF
          Check that the branch from the comment isn't the current base branch:

          $(message)
          EOF
            exit 1
          fi
          if [[ "$COMMENT_BRANCH" == "$PR_BRANCH" ]]; then
            cat <<EOF
          Check that the branch from the comment isn't the current branch:

          $(message)
          EOF
            exit 1
          fi
          if [[ "$PR_BRANCH" =~ ^($PERMANENT_BRANCHES) ]]; then
            cat <<EOF
          Check that the PR branch isn't a permanent branch:

          $(message)
          EOF
            exit 1
          fi
          if [[ "$CAN_MODIFY" != "true" ]]; then
            cat <<EOF
          Check that maintainers can edit the PR branch:

          $(message)
          EOF
            exit 1
          fi
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: rebase pull request
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config --global user.name "github-actions[bot]"
          git fetch origin
          gh pr checkout "$PULL_REQUEST"
          git rebase \
            --onto="$(git merge-base origin/"$CURRENT_BASE" origin/"$COMMENT_BRANCH")" \
            "HEAD~$COMMITS"
          git push --force
          curl \
            -X POST \
            -H "Accept: application/vnd.github.v3+json" \
            -H "Authorization: token $GITHUB_TOKEN" \
            -d "{ \"base\": \"$COMMENT_BRANCH\" }" \
            "https://api.github.com/repos/${{ github.repository }}/pulls/$PULL_REQUEST"
          curl \
            -X PATCH \
            -H "Accept: application/vnd.github.v3+json" \
            -H "Authorization: token $GITHUB_TOKEN" \
            -d '{ "state": "closed" }' \
            "https://api.github.com/repos/${{ github.repository }}/pulls/$PULL_REQUEST"
      - uses: peter-evans/create-or-update-comment@v1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            Rebased, please reopen the pull request to restart CI
      - uses: peter-evans/create-or-update-comment@v1
        if: failure()
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            [Failed to rebase](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
