Compare commits
75 Commits
Author | SHA1 | Date | |
---|---|---|---|
b72489d629 | |||
1461de7c9d | |||
3061b7bc6e | |||
98ee7d63d3 | |||
066b4398c0 | |||
028e1bbdd5 | |||
8b8594e5e4 | |||
cefb562076 | |||
9eccdd1603 | |||
f429dfef59 | |||
963e38fd7d | |||
f411b5902d | |||
97dd1f3ef4 | |||
3413a77ac7 | |||
206756cd93 | |||
263b5927d1 | |||
a0ad81c6c7 | |||
23846c7f83 | |||
96ac64ddca | |||
a2ed0052e5 | |||
6e7e889e01 | |||
7e18a60b72 | |||
0be4e396cf | |||
b86bbce924 | |||
e1e9dd3f1c | |||
8c2a43987b | |||
c5ff844b40 | |||
1f47cf3861 | |||
bcdc7ae6f9 | |||
91ca84eab5 | |||
875d189c30 | |||
7c3f5f4833 | |||
7a7e797068 | |||
a41f37fc96 | |||
10554ac6c3 | |||
2439726cfe | |||
4f04f4efd9 | |||
32d0abbc7c | |||
ed5b8b1eea | |||
ea241dfc79 | |||
0e70fec054 | |||
5077e8d6bd | |||
901e854f30 | |||
f3b1bd6331 | |||
51ade9f54b | |||
3c86dbf9e6 | |||
b2d426ea4e | |||
fbe0cd3d1a | |||
5f9821866a | |||
ee153ec8cf | |||
e138d84114 | |||
90843d3c39 | |||
90ad96bd01 | |||
f8cc05d28d | |||
fe78afb6d7 | |||
af7dbce93d | |||
2e283eddc6 | |||
3e0a17d097 | |||
7ebddff547 | |||
1397aded03 | |||
40fd4990fc | |||
5784478398 | |||
6e9abd8a8d | |||
ef76e27efb | |||
6be23859c3 | |||
aa09d77c75 | |||
b86b066e8c | |||
7556cef424 | |||
ff7ec1c208 | |||
6f333b4ebc | |||
65682597a6 | |||
fc9f1a6380 | |||
4bb662aed6 | |||
a5c1d5b56d | |||
dc7361b29a |
51
.github/workflows/create-pull-request-multi.yml
vendored
51
.github/workflows/create-pull-request-multi.yml
vendored
@ -1,7 +1,7 @@
|
||||
name: create-pull-request workflow
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [create-pull-request-multi]
|
||||
name: create-pull-request workflow
|
||||
jobs:
|
||||
createPullRequest:
|
||||
name: Testing on ${{ matrix.platform }}
|
||||
@ -10,23 +10,32 @@ jobs:
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Create report file
|
||||
if: matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest'
|
||||
run: touch report.txt
|
||||
- name: Create report file (windows)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: type NUL > report.txt
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@multi-platform-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: Add report file
|
||||
PULL_REQUEST_BODY: This PR is auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request).
|
||||
PULL_REQUEST_TITLE: '[Example] Add report file'
|
||||
PULL_REQUEST_LABELS: report, automated pr
|
||||
PULL_REQUEST_ASSIGNEES: peter-evans
|
||||
PULL_REQUEST_REVIEWERS: peter-evans
|
||||
PULL_REQUEST_MILESTONE: 1
|
||||
PULL_REQUEST_BRANCH: example-patches
|
||||
BRANCH_SUFFIX: 'timestamp'
|
||||
- uses: actions/checkout@v1
|
||||
- name: Create report file
|
||||
if: matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest'
|
||||
run: date +%s > report.txt
|
||||
- name: Create report file (windows)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: echo %DATE% %TIME% > report.txt
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@multi-platform-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: Add report file
|
||||
COMMIT_AUTHOR_EMAIL: peter-evans@users.noreply.github.com
|
||||
COMMIT_AUTHOR_NAME: Peter Evans
|
||||
PULL_REQUEST_TITLE: '[Example] Add report file'
|
||||
PULL_REQUEST_BODY: |
|
||||
New report
|
||||
- Contains *today's* date
|
||||
- Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
PULL_REQUEST_LABELS: report, automated pr
|
||||
PULL_REQUEST_ASSIGNEES: peter-evans
|
||||
PULL_REQUEST_REVIEWERS: peter-evans
|
||||
PULL_REQUEST_MILESTONE: 1
|
||||
PULL_REQUEST_BRANCH: example-patches
|
||||
BRANCH_SUFFIX: 'random'
|
||||
- name: Check output environment variable
|
||||
run: echo "Pull Request Number - ${{ env.PULL_REQUEST_NUMBER }}"
|
||||
|
43
.github/workflows/create-pull-request.yml
vendored
43
.github/workflows/create-pull-request.yml
vendored
@ -1,24 +1,33 @@
|
||||
name: create-pull-request workflow
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [create-pull-request]
|
||||
name: create-pull-request workflow
|
||||
jobs:
|
||||
createPullRequest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Create report file
|
||||
run: touch report.txt
|
||||
- name: Create Pull Request
|
||||
uses: ./
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: Add report file
|
||||
PULL_REQUEST_BODY: This PR is auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request).
|
||||
PULL_REQUEST_TITLE: '[Example] Add report file'
|
||||
PULL_REQUEST_LABELS: report, automated pr
|
||||
PULL_REQUEST_ASSIGNEES: peter-evans
|
||||
PULL_REQUEST_REVIEWERS: peter-evans
|
||||
PULL_REQUEST_MILESTONE: 1
|
||||
PULL_REQUEST_BRANCH: example-patches
|
||||
BRANCH_SUFFIX: short-commit-hash
|
||||
- uses: actions/checkout@v1
|
||||
- name: Create report file
|
||||
run: date +%s > report.txt
|
||||
- name: Create Pull Request
|
||||
uses: ./
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: Add report file
|
||||
COMMIT_AUTHOR_EMAIL: peter-evans@users.noreply.github.com
|
||||
COMMIT_AUTHOR_NAME: Peter Evans
|
||||
PULL_REQUEST_TITLE: '[Example] Add report file'
|
||||
PULL_REQUEST_BODY: |
|
||||
New report
|
||||
- Contains *today's* date
|
||||
- Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
PULL_REQUEST_LABELS: report, automated pr
|
||||
PULL_REQUEST_ASSIGNEES: peter-evans
|
||||
PULL_REQUEST_REVIEWERS: peter-evans
|
||||
PULL_REQUEST_MILESTONE: 1
|
||||
PULL_REQUEST_BRANCH: example-patches
|
||||
BRANCH_SUFFIX: short-commit-hash
|
||||
- name: Check output environment variable
|
||||
run: echo "Pull Request Number - ${{ env.PULL_REQUEST_NUMBER }}"
|
||||
|
16
.github/workflows/dockerhub-description.yml
vendored
Normal file
16
.github/workflows/dockerhub-description.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: Update Docker Hub Description
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
dockerHubDescription:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v2.1.0
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
DOCKERHUB_REPOSITORY: peterevans/create-pull-request
|
@ -1,4 +1,4 @@
|
||||
FROM alpine:3.10.2
|
||||
FROM alpine:3.10.3
|
||||
|
||||
LABEL maintainer="Peter Evans <mail@peterevans.dev>"
|
||||
LABEL repository="https://github.com/peter-evans/create-pull-request"
|
||||
|
156
README.md
156
README.md
@ -1,4 +1,4 @@
|
||||
# Create Pull Request
|
||||
# <img width="24" height="24" src="assets/logo.svg"> Create Pull Request
|
||||
[](https://github.com/marketplace/actions/create-pull-request)
|
||||
|
||||
A GitHub action to create a pull request for changes to your repository in the actions workspace.
|
||||
@ -10,109 +10,129 @@ The changes will be automatically committed to a new branch and a pull request c
|
||||
Create Pull Request action will:
|
||||
|
||||
1. Check for repository changes in the Actions workspace. This includes untracked (new) files as well as modified files.
|
||||
2. Commit all changes to a new branch. The commit will be made using the name and email of the `HEAD` commit author.
|
||||
2. Commit all changes to a new branch, or update an existing pull request branch.
|
||||
3. Create a pull request to merge the new branch into the currently active branch executing the workflow.
|
||||
|
||||
Note: Modifying a repository during workflows is not good practice in general.
|
||||
However, this action opens up some interesting possibilities when used carefully.
|
||||
This action is experimental and may not work well for some use cases.
|
||||
|
||||
## Usage
|
||||
|
||||
See [examples](examples.md) for detailed use cases.
|
||||
|
||||
Linux
|
||||
```yml
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.3.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
Multi platform - Linux, MacOS, Windows (beta)
|
||||
```yml
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.2.1-multi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0-multi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
#### Environment variables
|
||||
**Note**: If you want pull requests created by this action to trigger an `on: pull_request` workflow then you must use a [Personal Access Token](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) instead of the default `GITHUB_TOKEN`.
|
||||
See [this issue](https://github.com/peter-evans/create-pull-request/issues/48) for further details.
|
||||
|
||||
These variables are all optional. If not set, a default value will be used.
|
||||
### Environment variables
|
||||
|
||||
- `COMMIT_MESSAGE` - The message to use when committing changes.
|
||||
- `PULL_REQUEST_TITLE` - The title of the pull request.
|
||||
- `PULL_REQUEST_BODY` - The body of the pull request.
|
||||
- `PULL_REQUEST_LABELS` - A comma separated list of labels.
|
||||
- `PULL_REQUEST_ASSIGNEES` - A comma separated list of assignees (GitHub usernames).
|
||||
- `PULL_REQUEST_REVIEWERS` - A comma separated list of reviewers (GitHub usernames) to request a review from.
|
||||
- `PULL_REQUEST_TEAM_REVIEWERS` - A comma separated list of GitHub teams to request a review from.
|
||||
- `PULL_REQUEST_MILESTONE` - The number of the milestone to associate this pull request with.
|
||||
- `PULL_REQUEST_BRANCH` - The branch name. See **Branch naming** below for details.
|
||||
- `BRANCH_SUFFIX` - The branch suffix type. Valid values are `short-commit-hash` (default) and `timestamp`. See **Branch naming** below for details.
|
||||
These variables are *all optional*. If not set, sensible default values will be used.
|
||||
|
||||
The following parameters are available for debugging and troubleshooting.
|
||||
| Name | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| `COMMIT_MESSAGE` | The message to use when committing changes. | `Auto-committed changes by create-pull-request action` |
|
||||
| `COMMIT_AUTHOR_EMAIL` | The email address of the commit author. | For `push` events, the HEAD commit author. Otherwise, <GITHUB_ACTOR>@users.noreply.github.com, where `GITHUB_ACTOR` is the GitHub user that initiated the event. |
|
||||
| `COMMIT_AUTHOR_NAME` | The name of the commit author. | For `push` events, the HEAD commit author. Otherwise, <GITHUB_ACTOR>, the GitHub user that initiated the event. |
|
||||
| `PULL_REQUEST_TITLE` | The title of the pull request. | `Auto-generated by create-pull-request action` |
|
||||
| `PULL_REQUEST_BODY` | The body of the pull request. | `Auto-generated pull request by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub Action` |
|
||||
| `PULL_REQUEST_LABELS` | A comma separated list of labels. | none |
|
||||
| `PULL_REQUEST_ASSIGNEES` | A comma separated list of assignees (GitHub usernames). | none |
|
||||
| `PULL_REQUEST_REVIEWERS` | A comma separated list of reviewers (GitHub usernames) to request a review from. | none |
|
||||
| `PULL_REQUEST_TEAM_REVIEWERS` | A comma separated list of GitHub teams to request a review from. | none |
|
||||
| `PULL_REQUEST_MILESTONE` | The number of the milestone to associate this pull request with. | none |
|
||||
| `PULL_REQUEST_BRANCH` | The branch name. See **Branch naming** below for details. | `create-pull-request/patch` |
|
||||
| `PULL_REQUEST_BASE` | Overrides the base branch. **Use with caution!** | Defaults to the currently checked out branch. |
|
||||
| `BRANCH_SUFFIX` | The branch suffix type. Valid values are `short-commit-hash`, `timestamp`, `random` and `none`. See **Branch naming** below for details. | `short-commit-hash` |
|
||||
|
||||
**Output environment variables**
|
||||
|
||||
- `PULL_REQUEST_NUMBER` - The number of the pull request created.
|
||||
|
||||
**Debug environment variables**
|
||||
|
||||
The following parameter is available for debugging and troubleshooting.
|
||||
|
||||
- `DEBUG_EVENT` - If present, outputs the event data that triggered the workflow.
|
||||
- `SKIP_IGNORE` - If present, the `ignore_event` function will be skipped.
|
||||
|
||||
#### Branch naming
|
||||
### Branch naming
|
||||
|
||||
The variable `PULL_REQUEST_BRANCH` defaults to `create-pull-request/patch`.
|
||||
Commits will be made to a branch with this name and suffixed with the short SHA1 commit hash.
|
||||
For branch naming there are two strategies. Always create a new branch each time there are changes to be committed, OR, create a fixed-name pull request branch that will be updated with any new commits until it is merged or closed.
|
||||
|
||||
e.g.
|
||||
```
|
||||
create-pull-request/patch-fcdfb59
|
||||
create-pull-request/patch-394710b
|
||||
```
|
||||
#### Strategy A - Always create a new pull request branch (default)
|
||||
|
||||
Alternatively, branches can be suffixed with a timestamp by setting the environment variable `BRANCH_SUFFIX` to the value `timestamp`. This option must be used if multiple pull requests will be created during the execution of a workflow.
|
||||
For this strategy there are three options to suffix the branch name.
|
||||
The branch name is defined by the variable `PULL_REQUEST_BRANCH` and defaults to `create-pull-request/patch`. The following options are values for `BRANCH_SUFFIX`.
|
||||
|
||||
e.g.
|
||||
```
|
||||
create-pull-request/patch-1569322532
|
||||
create-pull-request/patch-1569322552
|
||||
```
|
||||
- `short-commit-hash` (default) - Commits will be made to a branch suffixed with the short SHA1 commit hash. e.g. `create-pull-request/patch-fcdfb59`, `create-pull-request/patch-394710b`
|
||||
|
||||
#### Ignoring files
|
||||
- `timestamp` - Commits will be made to a branch suffixed by a timestamp. e.g. `create-pull-request/patch-1569322532`, `create-pull-request/patch-1569322552`
|
||||
|
||||
- `random` - Commits will be made to a branch suffixed with a random alpha-numeric string. This option should be used if multiple pull requests will be created during the execution of a workflow. e.g. `create-pull-request/patch-6qj97jr`, `create-pull-request/patch-5jrjhvd`
|
||||
|
||||
#### Strategy B - Create and update a pull request branch
|
||||
|
||||
To use this strategy, set `BRANCH_SUFFIX` to the value `none`. The variable `PULL_REQUEST_BRANCH` defaults to `create-pull-request/patch`. Commits will be made to this branch and a pull request created. Any subsequent changes will be committed to the *same* branch and reflected in the existing pull request.
|
||||
|
||||
### Ignoring files
|
||||
|
||||
If there are files or directories you want to ignore you can simply add them to a `.gitignore` file at the root of your repository. The action will respect this file.
|
||||
|
||||
## Example
|
||||
## Reference Example
|
||||
|
||||
Here is an example that sets all the main environment variables.
|
||||
The following workflow is a reference example that sets all the main environment variables.
|
||||
|
||||
See [examples](examples.md) for more realistic use cases.
|
||||
|
||||
```yml
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [create-pull-request]
|
||||
name: create-pull-request workflow
|
||||
name: Create Pull Request
|
||||
on: push
|
||||
jobs:
|
||||
createPullRequest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Create report file
|
||||
run: touch report.txt
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.3.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: Add report file
|
||||
PULL_REQUEST_BODY: This PR is auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request).
|
||||
PULL_REQUEST_TITLE: '[Example] New report'
|
||||
PULL_REQUEST_LABELS: report, automated pr
|
||||
PULL_REQUEST_ASSIGNEES: peter-evans
|
||||
PULL_REQUEST_REVIEWERS: peter-evans
|
||||
PULL_REQUEST_MILESTONE: 1
|
||||
PULL_REQUEST_BRANCH: example-patches
|
||||
BRANCH_SUFFIX: short-commit-hash
|
||||
- uses: actions/checkout@v1
|
||||
- name: Create report file
|
||||
run: date +%s > report.txt
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: Add report file
|
||||
COMMIT_AUTHOR_EMAIL: peter-evans@users.noreply.github.com
|
||||
COMMIT_AUTHOR_NAME: Peter Evans
|
||||
PULL_REQUEST_TITLE: '[Example] Add report file'
|
||||
PULL_REQUEST_BODY: |
|
||||
New report
|
||||
- Contains *today's* date
|
||||
- Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
PULL_REQUEST_LABELS: report, automated pr
|
||||
PULL_REQUEST_ASSIGNEES: peter-evans
|
||||
PULL_REQUEST_REVIEWERS: peter-evans
|
||||
PULL_REQUEST_MILESTONE: 1
|
||||
PULL_REQUEST_BRANCH: example-patches
|
||||
BRANCH_SUFFIX: short-commit-hash
|
||||
- name: Check output environment variable
|
||||
run: echo "Pull Request Number - ${{ env.PULL_REQUEST_NUMBER }}"
|
||||
```
|
||||
|
||||
This configuration will create pull requests that look like this:
|
||||
This reference configuration will create pull requests that look like this:
|
||||
|
||||

|
||||

|
||||
|
||||
## License
|
||||
|
||||
MIT License - see the [LICENSE](LICENSE) file for details
|
||||
[MIT](LICENSE)
|
||||
|
9
action.yml
Normal file
9
action.yml
Normal file
@ -0,0 +1,9 @@
|
||||
name: 'Create Pull Request'
|
||||
author: 'Peter Evans'
|
||||
description: 'Creates a pull request for changes to your repository in the actions workspace'
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'docker://peterevans/create-pull-request:1.6.1'
|
||||
branding:
|
||||
icon: 'git-pull-request'
|
||||
color: 'gray-dark'
|
6
assets/logo.svg
Normal file
6
assets/logo.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="43%" height="43%" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: #000000;"><title>git-pull-request</title>
|
||||
<circle cx="18" cy="18" r="3"></circle>
|
||||
<circle cx="6" cy="6" r="3"></circle>
|
||||
<path d="M13 6h3a2 2 0 0 1 2 2v7"></path>
|
||||
<line x1="6" y1="9" x2="6" y2="21"></line>
|
||||
</svg>
|
After Width: | Height: | Size: 416 B |
BIN
assets/pull-request-example.png
Normal file
BIN
assets/pull-request-example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 441 KiB |
@ -2,9 +2,13 @@
|
||||
''' Create Pull Request '''
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
from git import Repo
|
||||
from github import Github
|
||||
from github import GithubException
|
||||
|
||||
|
||||
def get_github_event(github_event_path):
|
||||
@ -16,32 +20,22 @@ def get_github_event(github_event_path):
|
||||
return github_event
|
||||
|
||||
|
||||
def ignore_event(event_name, event_data):
|
||||
if event_name == "push":
|
||||
# Ignore push events on deleted branches
|
||||
# The event we want to ignore occurs when a PR is created but the repository owner decides
|
||||
# not to commit the changes. They close the PR and delete the branch. This creates a
|
||||
# "push" event that we want to ignore, otherwise it will create another branch and PR on
|
||||
# the same commit.
|
||||
deleted = "{deleted}".format(**event_data)
|
||||
if deleted == "True":
|
||||
print("Ignoring delete branch event.")
|
||||
return True
|
||||
ref = "{ref}".format(**event_data)
|
||||
if not ref.startswith('refs/heads/'):
|
||||
print("Ignoring events for tags and remotes.")
|
||||
return True
|
||||
return False
|
||||
def get_head_short_sha1(repo):
|
||||
return repo.git.rev_parse('--short', 'HEAD')
|
||||
|
||||
|
||||
def pr_branch_exists(repo, branch):
|
||||
def get_random_suffix(size=7, chars=string.ascii_lowercase + string.digits):
|
||||
return ''.join(random.choice(chars) for _ in range(size))
|
||||
|
||||
|
||||
def remote_branch_exists(repo, branch):
|
||||
for ref in repo.remotes.origin.refs:
|
||||
if ref.name == ("origin/%s" % branch):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_head_author(event_name, event_data):
|
||||
def get_author_default(event_name, event_data):
|
||||
if event_name == "push":
|
||||
email = "{head_commit[author][email]}".format(**event_data)
|
||||
name = "{head_commit[author][name]}".format(**event_data)
|
||||
@ -51,24 +45,34 @@ def get_head_author(event_name, event_data):
|
||||
return email, name
|
||||
|
||||
|
||||
def get_head_short_sha1(repo):
|
||||
return repo.git.rev_parse('--short', 'HEAD')
|
||||
|
||||
|
||||
def set_git_config(git, email, name):
|
||||
git.config('--global', 'user.email', '"%s"' % email)
|
||||
git.config('--global', 'user.name', '"%s"' % name)
|
||||
|
||||
|
||||
def set_git_remote_url(git, token, github_repository):
|
||||
git.remote('set-url', 'origin', "https://x-access-token:%s@github.com/%s" % (token, github_repository))
|
||||
git.remote(
|
||||
'set-url', 'origin', "https://x-access-token:%s@github.com/%s" %
|
||||
(token, github_repository))
|
||||
|
||||
|
||||
def commit_changes(git, branch, commit_message):
|
||||
git.checkout('HEAD', b=branch)
|
||||
def checkout_branch(git, remote_exists, branch):
|
||||
if remote_exists:
|
||||
git.stash('--include-untracked')
|
||||
git.checkout(branch)
|
||||
try:
|
||||
git.stash('pop')
|
||||
except BaseException:
|
||||
git.checkout('--theirs', '.')
|
||||
git.reset()
|
||||
else:
|
||||
git.checkout('HEAD', b=branch)
|
||||
|
||||
|
||||
def push_changes(git, branch, commit_message):
|
||||
git.add('-A')
|
||||
git.commit(m=commit_message)
|
||||
return git.push('--set-upstream', 'origin', branch)
|
||||
return git.push('-f', '--set-upstream', 'origin', branch)
|
||||
|
||||
|
||||
def cs_string_to_list(str):
|
||||
@ -78,10 +82,7 @@ def cs_string_to_list(str):
|
||||
return list(filter(None, l))
|
||||
|
||||
|
||||
def process_event(event_name, event_data, repo, branch, base):
|
||||
# Fetch required environment variables
|
||||
github_token = os.environ['GITHUB_TOKEN']
|
||||
github_repository = os.environ['GITHUB_REPOSITORY']
|
||||
def process_event(github_token, github_repository, repo, branch, base):
|
||||
# Fetch optional environment variables with default values
|
||||
commit_message = os.getenv(
|
||||
'COMMIT_MESSAGE',
|
||||
@ -99,27 +100,37 @@ def process_event(event_name, event_data, repo, branch, base):
|
||||
pull_request_reviewers = os.environ.get('PULL_REQUEST_REVIEWERS')
|
||||
pull_request_team_reviewers = os.environ.get('PULL_REQUEST_TEAM_REVIEWERS')
|
||||
|
||||
# Get the HEAD committer's email and name
|
||||
author_email, author_name = get_head_author(event_name, event_data)
|
||||
# Set git configuration
|
||||
set_git_config(repo.git, author_email, author_name)
|
||||
# Update URL for the 'origin' remote
|
||||
set_git_remote_url(repo.git, github_token, github_repository)
|
||||
|
||||
# Commit the repository changes
|
||||
print("Committing changes.")
|
||||
commit_result = commit_changes(repo.git, branch, commit_message)
|
||||
print(commit_result)
|
||||
# Push the local changes to the remote branch
|
||||
print("Pushing changes.")
|
||||
push_result = push_changes(repo.git, branch, commit_message)
|
||||
print(push_result)
|
||||
|
||||
# Create the pull request
|
||||
print("Creating a request to pull %s into %s." % (branch, base))
|
||||
github_repo = Github(github_token).get_repo(github_repository)
|
||||
pull_request = github_repo.create_pull(
|
||||
title=title,
|
||||
body=body,
|
||||
base=base,
|
||||
head=branch)
|
||||
print("Created pull request %d." % pull_request.number)
|
||||
try:
|
||||
pull_request = github_repo.create_pull(
|
||||
title=title,
|
||||
body=body,
|
||||
base=base,
|
||||
head=branch)
|
||||
print("Created pull request #%d (%s => %s)" %
|
||||
(pull_request.number, branch, base))
|
||||
except GithubException as e:
|
||||
if e.status == 422:
|
||||
pull_request = github_repo.get_pulls(
|
||||
state='open',
|
||||
base=base,
|
||||
head=branch)[1]
|
||||
print("Updated pull request #%d (%s => %s)" %
|
||||
(pull_request.number, branch, base))
|
||||
else:
|
||||
print(str(e))
|
||||
sys.exit(1)
|
||||
|
||||
# Set the output variable
|
||||
os.system(
|
||||
'echo ::set-env name=PULL_REQUEST_NUMBER::%d' %
|
||||
pull_request.number)
|
||||
|
||||
# Set labels, assignees and milestone
|
||||
if pull_request_labels is not None:
|
||||
@ -133,52 +144,116 @@ def process_event(event_name, event_data, repo, branch, base):
|
||||
milestone = github_repo.get_milestone(int(pull_request_milestone))
|
||||
pull_request.as_issue().edit(milestone=milestone)
|
||||
|
||||
# Set pull request reviewers and team reviewers
|
||||
# Set pull request reviewers
|
||||
if pull_request_reviewers is not None:
|
||||
print("Requesting reviewers")
|
||||
pull_request.create_review_request(reviewers=cs_string_to_list(pull_request_reviewers))
|
||||
try:
|
||||
pull_request.create_review_request(
|
||||
reviewers=cs_string_to_list(pull_request_reviewers))
|
||||
except GithubException as e:
|
||||
# Likely caused by "Review cannot be requested from pull request author."
|
||||
if e.status == 422:
|
||||
print("Requesting reviewers failed - %s" % e.data["message"])
|
||||
|
||||
# Set pull request team reviewers
|
||||
if pull_request_team_reviewers is not None:
|
||||
print("Requesting team reviewers")
|
||||
pull_request.create_review_request(team_reviewers=cs_string_to_list(pull_request_team_reviewers))
|
||||
pull_request.create_review_request(
|
||||
team_reviewers=cs_string_to_list(pull_request_team_reviewers))
|
||||
|
||||
|
||||
# Get the JSON event data
|
||||
# Fetch environment variables
|
||||
github_token = os.environ['GITHUB_TOKEN']
|
||||
github_repository = os.environ['GITHUB_REPOSITORY']
|
||||
github_ref = os.environ['GITHUB_REF']
|
||||
event_name = os.environ['GITHUB_EVENT_NAME']
|
||||
# Get the JSON event data
|
||||
event_data = get_github_event(os.environ['GITHUB_EVENT_PATH'])
|
||||
# Check if this event should be ignored
|
||||
skip_ignore_event = bool(os.environ.get('SKIP_IGNORE'))
|
||||
if skip_ignore_event or not ignore_event(event_name, event_data):
|
||||
# Set the repo to the working directory
|
||||
repo = Repo(os.getcwd())
|
||||
|
||||
# Fetch/Set the branch name
|
||||
branch = os.getenv('PULL_REQUEST_BRANCH', 'create-pull-request/patch')
|
||||
# Set the current branch as the target base branch
|
||||
base = os.environ['GITHUB_REF'][11:]
|
||||
# Set the repo to the working directory
|
||||
repo = Repo(os.getcwd())
|
||||
# Get the default for author email and name
|
||||
author_email, author_name = get_author_default(event_name, event_data)
|
||||
# Set commit author overrides
|
||||
author_email = os.getenv('COMMIT_AUTHOR_EMAIL', author_email)
|
||||
author_name = os.getenv('COMMIT_AUTHOR_NAME', author_name)
|
||||
# Set git configuration
|
||||
set_git_config(repo.git, author_email, author_name)
|
||||
# Update URL for the 'origin' remote
|
||||
set_git_remote_url(repo.git, github_token, github_repository)
|
||||
|
||||
# Skip if the current branch is a PR branch created by this action
|
||||
if not base.startswith(branch):
|
||||
# Fetch an optional environment variable to determine the branch suffix
|
||||
branch_suffix = os.getenv('BRANCH_SUFFIX', 'short-commit-hash')
|
||||
if branch_suffix == "timestamp":
|
||||
# Suffix with the current timestamp
|
||||
branch = "%s-%s" % (branch, int(time.time()))
|
||||
else:
|
||||
# Suffix with the short SHA1 hash
|
||||
branch = "%s-%s" % (branch, get_head_short_sha1(repo))
|
||||
# Fetch/Set the branch name
|
||||
branch_prefix = os.getenv(
|
||||
'PULL_REQUEST_BRANCH',
|
||||
'create-pull-request/patch')
|
||||
# Fetch an optional base branch override
|
||||
base_override = os.environ.get('PULL_REQUEST_BASE')
|
||||
|
||||
# Check if a PR branch already exists for this HEAD commit
|
||||
if not pr_branch_exists(repo, branch):
|
||||
# Check if there are changes to pull request
|
||||
if repo.is_dirty() or len(repo.untracked_files) > 0:
|
||||
print("Repository has modified or untracked files.")
|
||||
process_event(event_name, event_data, repo, branch, base)
|
||||
else:
|
||||
print("Repository has no modified or untracked files. Skipping.")
|
||||
else:
|
||||
print(
|
||||
"Pull request branch '%s' already exists for this commit. Skipping." %
|
||||
branch)
|
||||
else:
|
||||
# Set the base branch
|
||||
if base_override is not None:
|
||||
base = base_override
|
||||
checkout_branch(repo.git, True, base)
|
||||
elif github_ref.startswith('refs/pull/'):
|
||||
# Switch to the merging branch instead of the merge commit
|
||||
base = os.environ['GITHUB_HEAD_REF']
|
||||
repo.git.checkout(base)
|
||||
else:
|
||||
base = github_ref[11:]
|
||||
|
||||
# Skip if the current branch is a PR branch created by this action.
|
||||
# This may occur when using a PAT instead of GITHUB_TOKEN.
|
||||
if base.startswith(branch_prefix):
|
||||
print("Branch '%s' was created by this action. Skipping." % base)
|
||||
sys.exit()
|
||||
|
||||
# Fetch an optional environment variable to determine the branch suffix
|
||||
branch_suffix = os.getenv('BRANCH_SUFFIX', 'short-commit-hash')
|
||||
if branch_suffix == "short-commit-hash":
|
||||
# Suffix with the short SHA1 hash
|
||||
branch = "%s-%s" % (branch_prefix, get_head_short_sha1(repo))
|
||||
elif branch_suffix == "timestamp":
|
||||
# Suffix with the current timestamp
|
||||
branch = "%s-%s" % (branch_prefix, int(time.time()))
|
||||
elif branch_suffix == "random":
|
||||
# Suffix with the current timestamp
|
||||
branch = "%s-%s" % (branch_prefix, get_random_suffix())
|
||||
elif branch_suffix == "none":
|
||||
# Fixed branch name
|
||||
branch = branch_prefix
|
||||
else:
|
||||
print(
|
||||
"Branch suffix '%s' is not a valid value." %
|
||||
branch_suffix)
|
||||
sys.exit(1)
|
||||
|
||||
# Check if the remote branch exists
|
||||
remote_exists = remote_branch_exists(repo, branch)
|
||||
|
||||
if remote_exists:
|
||||
if branch_suffix == 'short-commit-hash':
|
||||
# A remote branch already exists for the HEAD commit
|
||||
print(
|
||||
"Branch '%s' was created by this action. Skipping." % base)
|
||||
"Pull request branch '%s' already exists for this commit. Skipping." %
|
||||
branch)
|
||||
sys.exit()
|
||||
elif branch_suffix in ['timestamp', 'random']:
|
||||
# Generated branch name clash with an existing branch
|
||||
print(
|
||||
"Pull request branch '%s' already exists. Please re-run." %
|
||||
branch)
|
||||
sys.exit(1)
|
||||
|
||||
# Checkout branch
|
||||
checkout_branch(repo.git, remote_exists, branch)
|
||||
|
||||
# Check if there are changes to pull request
|
||||
if repo.is_dirty() or len(repo.untracked_files) > 0:
|
||||
print("Repository has modified or untracked files.")
|
||||
process_event(
|
||||
github_token,
|
||||
github_repository,
|
||||
repo,
|
||||
branch,
|
||||
base)
|
||||
else:
|
||||
print("Repository has no modified or untracked files. Skipping.")
|
||||
|
219
examples.md
Normal file
219
examples.md
Normal file
@ -0,0 +1,219 @@
|
||||
# Examples
|
||||
|
||||
- [Use case: Create a pull request to update X periodically](#use-case-create-a-pull-request-to-update-x-periodically)
|
||||
- [Update NPM dependencies](#update-npm-dependencies)
|
||||
- [Keep Go up to date](#keep-go-up-to-date)
|
||||
- [Spider and download a website](#spider-and-download-a-website)
|
||||
- [Use case: Create a pull request to modify/fix pull requests](#use-case-create-a-pull-request-to-modifyfix-pull-requests)
|
||||
- [autopep8](#autopep8)
|
||||
- [Misc workflow tips](#misc-workflow-tips)
|
||||
- [Filtering push events](#filtering-push-events)
|
||||
- [Dynamic configuration using variables](#dynamic-configuration-using-variables)
|
||||
|
||||
|
||||
## Use case: Create a pull request to update X periodically
|
||||
|
||||
This pattern will work well for updating any kind of static content from an external source. The workflow executes on a schedule and raises a pull request when there are changes.
|
||||
|
||||
### Update NPM dependencies
|
||||
|
||||
```yml
|
||||
name: Update Dependencies
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * 1'
|
||||
jobs:
|
||||
update-deps:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '10.x'
|
||||
- name: Update dependencies
|
||||
id: vars
|
||||
run: |
|
||||
npm install -g npm-check-updates
|
||||
ncu -u
|
||||
npm install
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: update dependencies
|
||||
PULL_REQUEST_TITLE: Automated Dependency Updates
|
||||
PULL_REQUEST_BODY: This is an auto-generated PR with dependency updates.
|
||||
PULL_REQUEST_BRANCH: dep-updates
|
||||
BRANCH_SUFFIX: none
|
||||
```
|
||||
|
||||
### Keep Go up to date
|
||||
|
||||
Keep Go up to date with [ensure-latest-go](https://github.com/jmhodges/ensure-latest-go) action.
|
||||
|
||||
```yml
|
||||
name: Keeping Go up to date
|
||||
on:
|
||||
schedule:
|
||||
- cron: 47 4 * * *
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
fresh_go:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
ref: master
|
||||
- uses: jmhodges/ensure-latest-go@v1.0.2
|
||||
id: ensure_go
|
||||
- run: echo "##[set-output name=pr_title;]update to latest Go release ${{ steps.ensure_go.outputs.go_version}}"
|
||||
id: pr_title_maker
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
PULL_REQUEST_TITLE: ${{ steps.pr_title_maker.outputs.pr_title }}
|
||||
PULL_REQUEST_BODY: Auto-generated pull request created by the GitHub Actions [create-pull-request](https://github.com/peter-evans/create-pull-request) and [ensure-latest-go](https://github.com/jmhodges/ensure-latest-go).
|
||||
COMMIT_MESSAGE: ${{ steps.pr_title_maker.outputs.pr_title }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BRANCH_SUFFIX: none
|
||||
PULL_REQUEST_BRANCH: ensure-latest-go/patch-${{ steps.ensure_go.outputs.go_version }}
|
||||
```
|
||||
|
||||
### Spider and download a website
|
||||
|
||||
```yml
|
||||
name: Download Website
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *'
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download website
|
||||
run: |
|
||||
wget \
|
||||
--recursive \
|
||||
--level=2 \
|
||||
--wait=1 \
|
||||
--no-clobber \
|
||||
--page-requisites \
|
||||
--html-extension \
|
||||
--convert-links \
|
||||
--domains quotes.toscrape.com \
|
||||
http://quotes.toscrape.com/
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: update local website copy
|
||||
PULL_REQUEST_TITLE: Automated Updates to Local Website Copy
|
||||
PULL_REQUEST_BODY: This is an auto-generated PR with website updates.
|
||||
PULL_REQUEST_BRANCH: website-updates
|
||||
BRANCH_SUFFIX: none
|
||||
```
|
||||
|
||||
## Use case: Create a pull request to modify/fix pull requests
|
||||
|
||||
This is a pattern that works well for any automated code linting and fixing. A pull request can be created to fix or modify something during an `on: pull_request` workflow. The pull request containing the fix will be raised with the original pull request as the base. This can be then be merged to update the original pull request and pass any required tests.
|
||||
|
||||
### autopep8
|
||||
|
||||
The following is an example workflow for a use case where [autopep8 action](https://github.com/peter-evans/autopep8) runs as both a check on pull requests and raises a further pull request to apply code fixes.
|
||||
|
||||
How it works:
|
||||
|
||||
1. When a pull request is raised the workflow executes as a check
|
||||
2. If autopep8 makes any fixes a pull request will be raised for those fixes to be merged into the current pull request branch. The workflow then deliberately causes the check to fail.
|
||||
3. When the pull request containing the fixes is merged the workflow runs again. This time autopep8 makes no changes and the check passes.
|
||||
4. The original pull request can now be merged.
|
||||
|
||||
```yml
|
||||
name: autopep8
|
||||
on: pull_request
|
||||
jobs:
|
||||
autopep8:
|
||||
if: startsWith(github.head_ref, 'autopep8-patches') == false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: autopep8
|
||||
id: autopep8
|
||||
uses: peter-evans/autopep8@v1.1.0
|
||||
with:
|
||||
args: --exit-code --recursive --in-place --aggressive --aggressive .
|
||||
- name: Set autopep8 branch name
|
||||
id: vars
|
||||
run: echo ::set-output name=branch-name::"autopep8-patches/$GITHUB_HEAD_REF"
|
||||
- name: Create Pull Request
|
||||
if: steps.autopep8.outputs.exit-code == 2
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_MESSAGE: autopep8 action fixes
|
||||
PULL_REQUEST_TITLE: Fixes by autopep8 action
|
||||
PULL_REQUEST_BODY: This is an auto-generated PR with fixes by autopep8.
|
||||
PULL_REQUEST_LABELS: autopep8, automated pr
|
||||
PULL_REQUEST_BRANCH: ${{ steps.vars.outputs.branch-name }}
|
||||
BRANCH_SUFFIX: none
|
||||
- name: Fail if autopep8 made changes
|
||||
if: steps.autopep8.outputs.exit-code == 2
|
||||
run: exit 1
|
||||
```
|
||||
|
||||
## Misc workflow tips
|
||||
|
||||
### Filtering push events
|
||||
|
||||
For workflows using `on: push` you may want to ignore push events for tags and remotes.
|
||||
These can be filtered out with the following `if` condition.
|
||||
|
||||
```yml
|
||||
name: Create Pull Request
|
||||
on: push
|
||||
jobs:
|
||||
createPullRequest:
|
||||
if: startsWith(github.ref, 'refs/heads/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
...
|
||||
```
|
||||
|
||||
### Dynamic configuration using variables
|
||||
|
||||
The following examples show how configuration for the action can be dynamically defined in a previous workflow step.
|
||||
|
||||
The recommended method is to use [`set-output`](https://help.github.com/en/github/automating-your-workflow-with-github-actions/development-tools-for-github-actions#set-an-output-parameter-set-output). Note that the step where output variables are defined must have an id.
|
||||
|
||||
```yml
|
||||
- name: Set output variables
|
||||
id: vars
|
||||
run: |
|
||||
echo ::set-output name=pr_title::"[Test] Add report file $(date +%d-%m-%Y)"
|
||||
echo ::set-output name=pr_body::"This PR was auto-generated on $(date +%d-%m-%Y) \
|
||||
by [create-pull-request](https://github.com/peter-evans/create-pull-request)."
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PULL_REQUEST_TITLE: ${{ steps.vars.outputs.pr_title }}
|
||||
PULL_REQUEST_BODY: ${{ steps.vars.outputs.pr_body }}
|
||||
```
|
||||
|
||||
Since the action reads environment variables from the system, it's technically not necessary to explicitly pass them as long as they exist in the environment. So the following method using `set-env` *also* works, but explicitly passing the configuration parameters using the previous method is perferred for its clarity.
|
||||
|
||||
```yml
|
||||
- name: Set environment variables
|
||||
run: |
|
||||
echo ::set-env name=PULL_REQUEST_TITLE::"[Test] Add report file $(date +%d-%m-%Y)"
|
||||
echo ::set-env name=PULL_REQUEST_BODY::"This PR was auto-generated on $(date +%d-%m-%Y) \
|
||||
by [create-pull-request](https://github.com/peter-evans/create-pull-request)."
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.6.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
Binary file not shown.
Before Width: | Height: | Size: 213 KiB |
@ -1,2 +1,2 @@
|
||||
GitPython==3.0.2
|
||||
PyGithub==1.43.8
|
||||
GitPython==3.0.4
|
||||
PyGithub==1.44
|
||||
|
Reference in New Issue
Block a user