summary refs log tree commit diff
path: root/.github/workflows/rebase.yml
blob: 47e8f4e4e42095e26eb7e110298c6ab652cf95de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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 }})