Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
7531167f24 | |||
66a1436815 | |||
1d1fedd99c | |||
823751817d | |||
1edcf07a19 | |||
4c95214a9b | |||
b37c0a038c | |||
d9841567d1 | |||
2cce94bfb0 | |||
d968e8b11b | |||
6c73093f9b | |||
d17c882ef3 | |||
d5f4e48a66 | |||
484d8bd85d | |||
74b6a9337d | |||
2dd62d446e | |||
b6a98c049d | |||
67e8822279 | |||
956a240181 | |||
179aca65d7 | |||
e4c8b68e33 |
@ -36,6 +36,8 @@ jobs:
|
||||
assignees: peter-evans
|
||||
reviewers: peter-evans
|
||||
milestone: 1
|
||||
project: Example Project
|
||||
project-column: To do
|
||||
branch: example-patches
|
||||
branch-suffix: random
|
||||
- name: Check outputs
|
||||
|
2
.github/workflows/create-pull-request.yml
vendored
2
.github/workflows/create-pull-request.yml
vendored
@ -28,6 +28,8 @@ jobs:
|
||||
assignees: peter-evans
|
||||
reviewers: peter-evans
|
||||
milestone: 1
|
||||
project: Example Project
|
||||
project-column: To do
|
||||
branch: example-patches
|
||||
branch-suffix: short-commit-hash
|
||||
- name: Check outputs
|
||||
|
5
.github/workflows/dockerhub-description.yml
vendored
5
.github/workflows/dockerhub-description.yml
vendored
@ -2,7 +2,10 @@ name: Update Docker Hub Description
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- master
|
||||
paths:
|
||||
- README.md
|
||||
- .github/workflows/dockerhub-description.yml
|
||||
jobs:
|
||||
dockerHubDescription:
|
||||
runs-on: ubuntu-latest
|
||||
|
14
README.md
14
README.md
@ -19,11 +19,13 @@ See [examples](examples.md) for detailed use cases.
|
||||
|
||||
```yml
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
You can also pin to a [specific release](https://github.com/peter-evans/create-pull-request/releases) version in the format `@v1.x.x`
|
||||
|
||||
**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.
|
||||
|
||||
@ -43,8 +45,10 @@ These inputs are *all optional*. If not set, sensible default values will be use
|
||||
| `reviewers` | A comma separated list of reviewers (GitHub usernames) to request a review from. | none |
|
||||
| `team-reviewers` | A comma separated list of GitHub teams to request a review from. | none |
|
||||
| `milestone` | The number of the milestone to associate this pull request with. | none |
|
||||
| `project` | The name of the project for which a card should be created. Requires `project-column`. | none |
|
||||
| `project-column` | The name of the project column under which a card should be created. Requires `project`. | none |
|
||||
| `branch` | The branch name. See **Branch naming** below for details. | `create-pull-request/patch` |
|
||||
| `base` | Overrides the base branch. **Use with caution!** | Defaults to the currently checked out branch. |
|
||||
| `base` | Sets the pull request base branch. | Defaults to the currently checked out branch, `GITHUB_REF`. For `pull_request` events, `GITHUB_HEAD_REF` |
|
||||
| `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` |
|
||||
|
||||
**Outputs**
|
||||
@ -55,7 +59,7 @@ Note that in order to read the step output the action step must have an id.
|
||||
```yml
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@v1.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Check outputs
|
||||
@ -105,7 +109,7 @@ jobs:
|
||||
run: date +%s > report.txt
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@v1.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: Add report file
|
||||
@ -122,6 +126,8 @@ jobs:
|
||||
assignees: peter-evans
|
||||
reviewers: peter-evans
|
||||
milestone: 1
|
||||
project: Example Project
|
||||
project-column: To do
|
||||
branch: example-patches
|
||||
branch-suffix: short-commit-hash
|
||||
- name: Check outputs
|
||||
|
@ -24,10 +24,14 @@ inputs:
|
||||
description: 'A comma separated list of GitHub teams to request a review from.'
|
||||
milestone:
|
||||
description: 'The number of the milestone to associate this pull request with.'
|
||||
project:
|
||||
description: 'The name of the project for which a card should be created.'
|
||||
project-column:
|
||||
description: 'The name of the project column under which a card should be created.'
|
||||
branch:
|
||||
description: 'The pull request branch name.'
|
||||
base:
|
||||
description: 'Overrides the base branch.'
|
||||
description: 'Sets the pull request base branch.'
|
||||
branch-suffix:
|
||||
description: 'The branch suffix type.'
|
||||
outputs:
|
||||
|
4
dist/index.js
vendored
4
dist/index.js
vendored
@ -987,6 +987,8 @@ async function run() {
|
||||
reviewers: core.getInput("reviewers"),
|
||||
teamReviewers: core.getInput("team-reviewers"),
|
||||
milestone: core.getInput("milestone"),
|
||||
project: core.getInput("project"),
|
||||
projectColumn: core.getInput("project-column"),
|
||||
branch: core.getInput("branch"),
|
||||
base: core.getInput("base"),
|
||||
branchSuffix: core.getInput("branch-suffix"),
|
||||
@ -1006,6 +1008,8 @@ async function run() {
|
||||
if (inputs.reviewers) process.env.PULL_REQUEST_REVIEWERS = inputs.reviewers;
|
||||
if (inputs.teamReviewers) process.env.PULL_REQUEST_TEAM_REVIEWERS = inputs.teamReviewers;
|
||||
if (inputs.milestone) process.env.PULL_REQUEST_MILESTONE = inputs.milestone;
|
||||
if (inputs.project) process.env.PROJECT_NAME = inputs.project;
|
||||
if (inputs.projectColumn) process.env.PROJECT_COLUMN_NAME = inputs.projectColumn;
|
||||
if (inputs.branch) process.env.PULL_REQUEST_BRANCH = inputs.branch;
|
||||
if (inputs.base) process.env.PULL_REQUEST_BASE = inputs.base;
|
||||
if (inputs.branchSuffix) process.env.BRANCH_SUFFIX = inputs.branchSuffix;
|
||||
|
277
dist/src/create-pull-request.py
vendored
277
dist/src/create-pull-request.py
vendored
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
''' Create Pull Request '''
|
||||
""" Create Pull Request """
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
@ -7,25 +7,24 @@ import string
|
||||
import sys
|
||||
import time
|
||||
from git import Repo
|
||||
from github import Github
|
||||
from github import GithubException
|
||||
from github import Github, GithubException
|
||||
|
||||
|
||||
def get_github_event(github_event_path):
|
||||
with open(github_event_path) as f:
|
||||
github_event = json.load(f)
|
||||
if bool(os.environ.get('DEBUG_EVENT')):
|
||||
print(os.environ['GITHUB_EVENT_NAME'])
|
||||
if bool(os.environ.get("DEBUG_EVENT")):
|
||||
print(os.environ["GITHUB_EVENT_NAME"])
|
||||
print(json.dumps(github_event, sort_keys=True, indent=2))
|
||||
return github_event
|
||||
|
||||
|
||||
def get_head_short_sha1(repo):
|
||||
return repo.git.rev_parse('--short', 'HEAD')
|
||||
return repo.git.rev_parse("--short", "HEAD")
|
||||
|
||||
|
||||
def get_random_suffix(size=7, chars=string.ascii_lowercase + string.digits):
|
||||
return ''.join(random.choice(chars) for _ in range(size))
|
||||
return "".join(random.choice(chars) for _ in range(size))
|
||||
|
||||
|
||||
def remote_branch_exists(repo, branch):
|
||||
@ -40,68 +39,108 @@ def get_author_default(event_name, event_data):
|
||||
email = "{head_commit[author][email]}".format(**event_data)
|
||||
name = "{head_commit[author][name]}".format(**event_data)
|
||||
else:
|
||||
email = os.environ['GITHUB_ACTOR'] + '@users.noreply.github.com'
|
||||
name = os.environ['GITHUB_ACTOR']
|
||||
email = os.environ["GITHUB_ACTOR"] + "@users.noreply.github.com"
|
||||
name = os.environ["GITHUB_ACTOR"]
|
||||
return email, name
|
||||
|
||||
|
||||
def set_git_config(git, email, name):
|
||||
git.config('--global', 'user.email', '"%s"' % email)
|
||||
git.config('--global', 'user.name', '"%s"' % name)
|
||||
print("Configuring git user as '%s <%s>'" % (name, email))
|
||||
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))
|
||||
"set-url",
|
||||
"origin",
|
||||
"https://x-access-token:%s@github.com/%s" % (token, github_repository),
|
||||
)
|
||||
|
||||
|
||||
def checkout_branch(git, remote_exists, branch):
|
||||
if remote_exists:
|
||||
git.stash('--include-untracked')
|
||||
print("Checking out branch '%s'" % branch)
|
||||
git.stash("--include-untracked")
|
||||
git.checkout(branch)
|
||||
try:
|
||||
git.stash('pop')
|
||||
git.stash("pop")
|
||||
except BaseException:
|
||||
git.checkout('--theirs', '.')
|
||||
git.checkout("--theirs", ".")
|
||||
git.reset()
|
||||
else:
|
||||
git.checkout('HEAD', b=branch)
|
||||
print("Creating new branch '%s'" % branch)
|
||||
git.checkout("HEAD", b=branch)
|
||||
|
||||
|
||||
def push_changes(git, branch, commit_message):
|
||||
git.add('-A')
|
||||
git.add("-A")
|
||||
git.commit(m=commit_message)
|
||||
return git.push('-f', '--set-upstream', 'origin', branch)
|
||||
return git.push("-f", "--set-upstream", "origin", branch)
|
||||
|
||||
|
||||
def cs_string_to_list(str):
|
||||
# Split the comma separated string into a list
|
||||
l = [i.strip() for i in str.split(',')]
|
||||
l = [i.strip() for i in str.split(",")]
|
||||
# Remove empty strings
|
||||
return list(filter(None, l))
|
||||
|
||||
|
||||
def create_project_card(github_repo, project_name, project_column_name, pull_request):
|
||||
# Locate the project by name
|
||||
project = None
|
||||
for project_item in github_repo.get_projects("all"):
|
||||
if project_item.name == project_name:
|
||||
project = project_item
|
||||
break
|
||||
|
||||
if not project:
|
||||
print("::warning::Project not found. Unable to create project card.")
|
||||
return
|
||||
|
||||
# Locate the column by name
|
||||
column = None
|
||||
for column_item in project.get_columns():
|
||||
if column_item.name == project_column_name:
|
||||
column = column_item
|
||||
break
|
||||
|
||||
if not column:
|
||||
print("::warning::Project column not found. Unable to create project card.")
|
||||
return
|
||||
|
||||
# Create a project card for the pull request
|
||||
column.create_card(content_id=pull_request.id, content_type="PullRequest")
|
||||
print(
|
||||
"Added pull request #%d to project '%s' under column '%s'"
|
||||
% (pull_request.number, project.name, column.name)
|
||||
)
|
||||
|
||||
|
||||
def process_event(github_token, github_repository, repo, branch, base):
|
||||
# Fetch optional environment variables with default values
|
||||
commit_message = os.getenv(
|
||||
'COMMIT_MESSAGE',
|
||||
"Auto-committed changes by create-pull-request action")
|
||||
"COMMIT_MESSAGE", "Auto-committed changes by create-pull-request action"
|
||||
)
|
||||
title = os.getenv(
|
||||
'PULL_REQUEST_TITLE',
|
||||
"Auto-generated by create-pull-request action")
|
||||
"PULL_REQUEST_TITLE", "Auto-generated by create-pull-request action"
|
||||
)
|
||||
body = os.getenv(
|
||||
'PULL_REQUEST_BODY', "Auto-generated pull request by "
|
||||
"[create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub Action")
|
||||
"PULL_REQUEST_BODY",
|
||||
"Auto-generated pull request by "
|
||||
"[create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub Action",
|
||||
)
|
||||
# Fetch optional environment variables with no default values
|
||||
pull_request_labels = os.environ.get('PULL_REQUEST_LABELS')
|
||||
pull_request_assignees = os.environ.get('PULL_REQUEST_ASSIGNEES')
|
||||
pull_request_milestone = os.environ.get('PULL_REQUEST_MILESTONE')
|
||||
pull_request_reviewers = os.environ.get('PULL_REQUEST_REVIEWERS')
|
||||
pull_request_team_reviewers = os.environ.get('PULL_REQUEST_TEAM_REVIEWERS')
|
||||
pull_request_labels = os.environ.get("PULL_REQUEST_LABELS")
|
||||
pull_request_assignees = os.environ.get("PULL_REQUEST_ASSIGNEES")
|
||||
pull_request_milestone = os.environ.get("PULL_REQUEST_MILESTONE")
|
||||
pull_request_reviewers = os.environ.get("PULL_REQUEST_REVIEWERS")
|
||||
pull_request_team_reviewers = os.environ.get("PULL_REQUEST_TEAM_REVIEWERS")
|
||||
project_name = os.environ.get("PROJECT_NAME")
|
||||
project_column_name = os.environ.get("PROJECT_COLUMN_NAME")
|
||||
|
||||
# Push the local changes to the remote branch
|
||||
print("Pushing changes.")
|
||||
print("Pushing changes to 'origin/%s'" % branch)
|
||||
push_result = push_changes(repo.git, branch, commit_message)
|
||||
print(push_result)
|
||||
|
||||
@ -109,111 +148,145 @@ def process_event(github_token, github_repository, repo, branch, base):
|
||||
github_repo = Github(github_token).get_repo(github_repository)
|
||||
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))
|
||||
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:
|
||||
# Format the branch name
|
||||
head_branch = "%s:%s" % (github_repository.split("/")[0], branch)
|
||||
# Get the pull request
|
||||
pull_request = github_repo.get_pulls(
|
||||
state='open',
|
||||
base=base,
|
||||
head=head_branch)[0]
|
||||
print("Updated pull request #%d (%s => %s)" %
|
||||
(pull_request.number, branch, base))
|
||||
state="open", base=base, head=head_branch
|
||||
)[0]
|
||||
print(
|
||||
"Updated pull request #%d (%s => %s)"
|
||||
% (pull_request.number, branch, base)
|
||||
)
|
||||
else:
|
||||
print(str(e))
|
||||
sys.exit(1)
|
||||
|
||||
# Set the output variables
|
||||
os.system(
|
||||
'echo ::set-env name=PULL_REQUEST_NUMBER::%d' %
|
||||
pull_request.number)
|
||||
os.system(
|
||||
'echo ::set-output name=pr_number::%d' %
|
||||
pull_request.number)
|
||||
os.system("echo ::set-env name=PULL_REQUEST_NUMBER::%d" % pull_request.number)
|
||||
os.system("echo ::set-output name=pr_number::%d" % pull_request.number)
|
||||
|
||||
# Set labels, assignees and milestone
|
||||
if pull_request_labels is not None:
|
||||
print("Applying labels")
|
||||
print("Applying labels '%s'" % pull_request_labels)
|
||||
pull_request.as_issue().edit(labels=cs_string_to_list(pull_request_labels))
|
||||
if pull_request_assignees is not None:
|
||||
print("Applying assignees")
|
||||
pull_request.as_issue().edit(assignees=cs_string_to_list(pull_request_assignees))
|
||||
print("Applying assignees '%s'" % pull_request_assignees)
|
||||
pull_request.as_issue().edit(
|
||||
assignees=cs_string_to_list(pull_request_assignees)
|
||||
)
|
||||
if pull_request_milestone is not None:
|
||||
print("Applying milestone")
|
||||
print("Applying milestone '%s'" % pull_request_milestone)
|
||||
milestone = github_repo.get_milestone(int(pull_request_milestone))
|
||||
pull_request.as_issue().edit(milestone=milestone)
|
||||
|
||||
# Set pull request reviewers
|
||||
if pull_request_reviewers is not None:
|
||||
print("Requesting reviewers")
|
||||
print("Requesting reviewers '%s'" % pull_request_reviewers)
|
||||
try:
|
||||
pull_request.create_review_request(
|
||||
reviewers=cs_string_to_list(pull_request_reviewers))
|
||||
reviewers=cs_string_to_list(pull_request_reviewers)
|
||||
)
|
||||
except GithubException as e:
|
||||
# Likely caused by "Review cannot be requested from pull request author."
|
||||
# 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")
|
||||
print("Requesting team reviewers '%s'" % pull_request_team_reviewers)
|
||||
pull_request.create_review_request(
|
||||
team_reviewers=cs_string_to_list(pull_request_team_reviewers))
|
||||
team_reviewers=cs_string_to_list(pull_request_team_reviewers)
|
||||
)
|
||||
|
||||
# Create a project card for the pull request
|
||||
if project_name is not None and project_column_name is not None:
|
||||
try:
|
||||
create_project_card(
|
||||
github_repo, project_name, project_column_name, pull_request
|
||||
)
|
||||
except GithubException as e:
|
||||
# Likely caused by "Project already has the associated issue."
|
||||
if e.status == 422:
|
||||
print(
|
||||
"Create project card failed - %s" % e.data["errors"][0]["message"]
|
||||
)
|
||||
|
||||
|
||||
# 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']
|
||||
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'])
|
||||
event_data = get_github_event(os.environ["GITHUB_EVENT_PATH"])
|
||||
|
||||
# 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)
|
||||
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)
|
||||
|
||||
# Fetch/Set the branch name
|
||||
branch_prefix = os.getenv(
|
||||
'PULL_REQUEST_BRANCH',
|
||||
'create-pull-request/patch')
|
||||
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')
|
||||
base_override = os.environ.get("PULL_REQUEST_BASE")
|
||||
|
||||
# Set the base branch
|
||||
if base_override is not None:
|
||||
base = base_override
|
||||
print("Overriding the base with branch '%s'" % base)
|
||||
checkout_branch(repo.git, True, base)
|
||||
elif github_ref.startswith('refs/pull/'):
|
||||
elif github_ref.startswith("refs/pull/"):
|
||||
# Check the PR is not raised from a fork of the repository
|
||||
head_repo = "{pull_request[head][repo][full_name]}".format(**event_data)
|
||||
if head_repo != github_repository:
|
||||
print(
|
||||
"::warning::Pull request was raised from a fork of the repository. "
|
||||
+ "Limitations on forked repositories have been imposed by GitHub Actions. "
|
||||
+ "Unable to continue. Exiting."
|
||||
)
|
||||
sys.exit()
|
||||
# Switch to the merging branch instead of the merge commit
|
||||
base = os.environ['GITHUB_HEAD_REF']
|
||||
repo.git.checkout(base)
|
||||
else:
|
||||
base = os.environ["GITHUB_HEAD_REF"]
|
||||
print(
|
||||
"Removing the merge commit by switching to the pull request head branch '%s'"
|
||||
% base
|
||||
)
|
||||
checkout_branch(repo.git, True, base)
|
||||
elif github_ref.startswith("refs/heads/"):
|
||||
base = github_ref[11:]
|
||||
print("Currently checked out base assumed to be branch '%s'" % base)
|
||||
else:
|
||||
print(
|
||||
f"::warning::Currently checked out ref '{github_ref}' is not a valid base for a pull request. "
|
||||
+ "Unable to continue. Exiting."
|
||||
)
|
||||
sys.exit()
|
||||
|
||||
# Skip if the current branch is a PR branch created by this action.
|
||||
# This may occur when using a PAT instead of GITHUB_TOKEN.
|
||||
# This may occur when using a PAT instead of GITHUB_TOKEN because
|
||||
# a PAT allows workflow actions to trigger further events.
|
||||
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')
|
||||
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))
|
||||
@ -227,39 +300,51 @@ elif branch_suffix == "none":
|
||||
# Fixed branch name
|
||||
branch = branch_prefix
|
||||
else:
|
||||
print(
|
||||
"Branch suffix '%s' is not a valid value." %
|
||||
branch_suffix)
|
||||
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)
|
||||
# Output head branch
|
||||
print("Pull request branch to create/update set to '%s'" % branch)
|
||||
|
||||
# Check if the determined head branch exists as a remote
|
||||
remote_exists = remote_branch_exists(repo, branch)
|
||||
if remote_exists:
|
||||
if branch_suffix == 'short-commit-hash':
|
||||
print(
|
||||
"Pull request branch '%s' already exists as remote branch 'origin/%s'"
|
||||
% (branch, branch)
|
||||
)
|
||||
if branch_suffix == "short-commit-hash":
|
||||
# A remote branch already exists for the HEAD commit
|
||||
print(
|
||||
"Pull request branch '%s' already exists for this commit. Skipping." %
|
||||
branch)
|
||||
"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
|
||||
elif branch_suffix in ["timestamp", "random"]:
|
||||
# Generated branch name collision with an existing branch
|
||||
print(
|
||||
"Pull request branch '%s' already exists. Please re-run." %
|
||||
branch)
|
||||
"Pull request branch '%s' collided with a branch of the same name. 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)
|
||||
if remote_exists:
|
||||
print(
|
||||
"Checking for local working copy changes indicating a "
|
||||
+ "diff with existing pull request branch 'origin/%s'" % branch
|
||||
)
|
||||
else:
|
||||
print("Repository has no modified or untracked files. Skipping.")
|
||||
print(
|
||||
"Checking for local working copy changes indicating a "
|
||||
+ "diff with base 'origin/%s'" % base
|
||||
)
|
||||
|
||||
if repo.is_dirty() or len(repo.untracked_files) > 0:
|
||||
print("Modified or untracked files detected.")
|
||||
process_event(github_token, github_repository, repo, branch, base)
|
||||
else:
|
||||
print("No modified or untracked files detected. Skipping.")
|
||||
|
2
dist/src/requirements.txt
vendored
2
dist/src/requirements.txt
vendored
@ -1,2 +1,2 @@
|
||||
GitPython==3.0.4
|
||||
GitPython==3.0.5
|
||||
PyGithub==1.44.1
|
||||
|
112
examples.md
112
examples.md
@ -3,6 +3,7 @@
|
||||
- [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)
|
||||
- [Update SwaggerUI for GitHub Pages](#update-swaggerui-for-github-pages)
|
||||
- [Spider and download a website](#spider-and-download-a-website)
|
||||
- [Use case: Create a pull request to update X by calling the GitHub API](#use-case-create-a-pull-request-to-update-x-by-calling-the-github-api)
|
||||
- [Call the GitHub API from an external service](#call-the-github-api-from-an-external-service)
|
||||
@ -41,7 +42,7 @@ jobs:
|
||||
ncu -u
|
||||
npm install
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: update dependencies
|
||||
@ -75,7 +76,7 @@ jobs:
|
||||
- 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.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
title: ${{ steps.pr_title_maker.outputs.pr_title }}
|
||||
@ -85,8 +86,69 @@ jobs:
|
||||
branch: ensure-latest-go/patch-${{ steps.ensure_go.outputs.go_version }}
|
||||
```
|
||||
|
||||
### Update SwaggerUI for GitHub Pages
|
||||
|
||||
When using [GitHub Pages to host Swagger documentation](https://github.com/peter-evans/swagger-github-pages), this workflow updates the repository with the latest distribution of [SwaggerUI](https://github.com/swagger-api/swagger-ui).
|
||||
|
||||
You must create a file called `swagger-ui.version` at the root of your repository before running.
|
||||
```yml
|
||||
name: Update Swagger UI
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *'
|
||||
jobs:
|
||||
updateSwagger:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get Latest Swagger UI Release
|
||||
id: swagger-ui
|
||||
run: |
|
||||
echo ::set-output name=release_tag::$(curl -sL https://api.github.com/repos/swagger-api/swagger-ui/releases/latest | jq -r ".tag_name")
|
||||
echo ::set-output name=current_tag::$(<swagger-ui.version)
|
||||
- name: Update Swagger UI
|
||||
if: steps.swagger-ui.outputs.current_tag != steps.swagger-ui.outputs.release_tag
|
||||
env:
|
||||
RELEASE_TAG: ${{ steps.swagger-ui.outputs.release_tag }}
|
||||
SWAGGER_YAML: "swagger.yaml"
|
||||
run: |
|
||||
# Delete the dist directory and index.html
|
||||
rm -fr dist index.html
|
||||
# Download the release
|
||||
curl -sL -o $RELEASE_TAG https://api.github.com/repos/swagger-api/swagger-ui/tarball/$RELEASE_TAG
|
||||
# Extract the dist directory
|
||||
tar -xzf $RELEASE_TAG --strip-components=1 $(tar -tzf $RELEASE_TAG | head -1 | cut -f1 -d"/")/dist
|
||||
rm $RELEASE_TAG
|
||||
# Move index.html to the root
|
||||
mv dist/index.html .
|
||||
# Fix references in index.html
|
||||
sed -i "s|https://petstore.swagger.io/v2/swagger.json|$SWAGGER_YAML|g" index.html
|
||||
sed -i "s|href=\"./|href=\"dist/|g" index.html
|
||||
sed -i "s|src=\"./|src=\"dist/|g" index.html
|
||||
# Update current release
|
||||
echo ${{ steps.swagger-ui.outputs.release_tag }} > swagger-ui.version
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: Update swagger-ui to ${{ steps.swagger-ui.outputs.release_tag }}
|
||||
title: Update SwaggerUI to ${{ steps.swagger-ui.outputs.release_tag }}
|
||||
body: |
|
||||
Updates [swagger-ui][1] to ${{ steps.swagger-ui.outputs.release_tag }}
|
||||
|
||||
Auto-generated by [create-pull-request][2]
|
||||
|
||||
[1]: https://github.com/swagger-api/swagger-ui
|
||||
[2]: https://github.com/peter-evans/create-pull-request
|
||||
labels: dependencies, automated pr
|
||||
branch: swagger-ui-updates
|
||||
branch-suffix: none
|
||||
```
|
||||
|
||||
### Spider and download a website
|
||||
|
||||
This workflow spiders a website and downloads the content. Any changes to the website will be raised in a pull request.
|
||||
|
||||
```yml
|
||||
name: Download Website
|
||||
on:
|
||||
@ -110,7 +172,7 @@ jobs:
|
||||
--domains quotes.toscrape.com \
|
||||
http://quotes.toscrape.com/
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v1.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: update local website copy
|
||||
@ -169,7 +231,7 @@ An `on: repository_dispatch` workflow can be triggered from another workflow wit
|
||||
|
||||
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.
|
||||
|
||||
Note that due to [limitations on forked repositories](https://help.github.com/en/github/automating-your-workflow-with-github-actions/virtual-environments-for-github-actions#token-permissions) workflows for this use case do not work for pull requests raised from forks.
|
||||
Note that due to [limitations on forked repositories](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#permissions-for-the-github_token) workflows for this use case do not work for pull requests raised from forks.
|
||||
|
||||
### autopep8
|
||||
|
||||
@ -202,7 +264,7 @@ jobs:
|
||||
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.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: autopep8 action fixes
|
||||
@ -220,11 +282,18 @@ jobs:
|
||||
|
||||
### 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.
|
||||
For workflows using `on: push` you may want to ignore push events for tags and only execute for branches. Specifying `branches` causes only events on branches to trigger the workflow. The `'**'` wildcard will match any branch name.
|
||||
|
||||
```yml
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
```
|
||||
|
||||
If you have a workflow that contains jobs to handle push events on branches as well as tags, you can make sure that the job where you use `create-pull-request` action only executes when `github.ref` is a branch by using an `if` condition as follows.
|
||||
|
||||
```yml
|
||||
name: Create Pull Request
|
||||
on: push
|
||||
jobs:
|
||||
createPullRequest:
|
||||
@ -233,6 +302,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
...
|
||||
|
||||
someOtherJob:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
...
|
||||
```
|
||||
|
||||
### Dynamic configuration using variables
|
||||
@ -249,7 +324,7 @@ The recommended method is to use [`set-output`](https://help.github.com/en/githu
|
||||
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.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
title: ${{ steps.vars.outputs.pr_title }}
|
||||
@ -265,7 +340,7 @@ Alternatively, [`set-env`](https://help.github.com/en/github/automating-your-wor
|
||||
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.7.2
|
||||
uses: peter-evans/create-pull-request@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
title: ${{ env.PULL_REQUEST_TITLE }}
|
||||
@ -274,15 +349,20 @@ Alternatively, [`set-env`](https://help.github.com/en/github/automating-your-wor
|
||||
|
||||
### Debugging GitHub Actions
|
||||
|
||||
**Step Debug Logging** : To enable step debug logging set the secret `ACTIONS_STEP_DEBUG` to `true` in the repository that contains the workflow.
|
||||
#### Runner Diagnostic Logging
|
||||
|
||||
**Output Various Contexts**
|
||||
[Runner diagnostic logging](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/managing-a-workflow-run#enabling-runner-diagnostic-logging) provides additional log files that contain information about how a runner is executing an action.
|
||||
To enable runner diagnostic logging, set the secret `ACTIONS_RUNNER_DEBUG` to `true` in the repository that contains the workflow.
|
||||
|
||||
#### Step Debug Logging
|
||||
|
||||
[Step debug logging](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/managing-a-workflow-run#enabling-step-debug-logging) increases the verbosity of a job's logs during and after a job's execution.
|
||||
To enable step debug logging set the secret `ACTIONS_STEP_DEBUG` to `true` in the repository that contains the workflow.
|
||||
|
||||
#### Output Various Contexts
|
||||
|
||||
```yml
|
||||
- name: Dump event JSON
|
||||
env:
|
||||
EVENT_JSON_FILENAME: ${{ github.event_path }}
|
||||
run: cat "$EVENT_JSON_FILENAME"
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
|
4
index.js
4
index.js
@ -32,6 +32,8 @@ async function run() {
|
||||
reviewers: core.getInput("reviewers"),
|
||||
teamReviewers: core.getInput("team-reviewers"),
|
||||
milestone: core.getInput("milestone"),
|
||||
project: core.getInput("project"),
|
||||
projectColumn: core.getInput("project-column"),
|
||||
branch: core.getInput("branch"),
|
||||
base: core.getInput("base"),
|
||||
branchSuffix: core.getInput("branch-suffix"),
|
||||
@ -51,6 +53,8 @@ async function run() {
|
||||
if (inputs.reviewers) process.env.PULL_REQUEST_REVIEWERS = inputs.reviewers;
|
||||
if (inputs.teamReviewers) process.env.PULL_REQUEST_TEAM_REVIEWERS = inputs.teamReviewers;
|
||||
if (inputs.milestone) process.env.PULL_REQUEST_MILESTONE = inputs.milestone;
|
||||
if (inputs.project) process.env.PROJECT_NAME = inputs.project;
|
||||
if (inputs.projectColumn) process.env.PROJECT_COLUMN_NAME = inputs.projectColumn;
|
||||
if (inputs.branch) process.env.PULL_REQUEST_BRANCH = inputs.branch;
|
||||
if (inputs.base) process.env.PULL_REQUEST_BASE = inputs.base;
|
||||
if (inputs.branchSuffix) process.env.BRANCH_SUFFIX = inputs.branchSuffix;
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "create-pull-request",
|
||||
"version": "1.7.2",
|
||||
"version": "1.8.0",
|
||||
"description": "Creates a pull request for changes to your repository in the actions workspace",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "ncc build index.js -o dist"
|
||||
"package": "ncc build index.js -o dist"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
''' Create Pull Request '''
|
||||
""" Create Pull Request """
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
@ -7,25 +7,24 @@ import string
|
||||
import sys
|
||||
import time
|
||||
from git import Repo
|
||||
from github import Github
|
||||
from github import GithubException
|
||||
from github import Github, GithubException
|
||||
|
||||
|
||||
def get_github_event(github_event_path):
|
||||
with open(github_event_path) as f:
|
||||
github_event = json.load(f)
|
||||
if bool(os.environ.get('DEBUG_EVENT')):
|
||||
print(os.environ['GITHUB_EVENT_NAME'])
|
||||
if bool(os.environ.get("DEBUG_EVENT")):
|
||||
print(os.environ["GITHUB_EVENT_NAME"])
|
||||
print(json.dumps(github_event, sort_keys=True, indent=2))
|
||||
return github_event
|
||||
|
||||
|
||||
def get_head_short_sha1(repo):
|
||||
return repo.git.rev_parse('--short', 'HEAD')
|
||||
return repo.git.rev_parse("--short", "HEAD")
|
||||
|
||||
|
||||
def get_random_suffix(size=7, chars=string.ascii_lowercase + string.digits):
|
||||
return ''.join(random.choice(chars) for _ in range(size))
|
||||
return "".join(random.choice(chars) for _ in range(size))
|
||||
|
||||
|
||||
def remote_branch_exists(repo, branch):
|
||||
@ -40,68 +39,108 @@ def get_author_default(event_name, event_data):
|
||||
email = "{head_commit[author][email]}".format(**event_data)
|
||||
name = "{head_commit[author][name]}".format(**event_data)
|
||||
else:
|
||||
email = os.environ['GITHUB_ACTOR'] + '@users.noreply.github.com'
|
||||
name = os.environ['GITHUB_ACTOR']
|
||||
email = os.environ["GITHUB_ACTOR"] + "@users.noreply.github.com"
|
||||
name = os.environ["GITHUB_ACTOR"]
|
||||
return email, name
|
||||
|
||||
|
||||
def set_git_config(git, email, name):
|
||||
git.config('--global', 'user.email', '"%s"' % email)
|
||||
git.config('--global', 'user.name', '"%s"' % name)
|
||||
print("Configuring git user as '%s <%s>'" % (name, email))
|
||||
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))
|
||||
"set-url",
|
||||
"origin",
|
||||
"https://x-access-token:%s@github.com/%s" % (token, github_repository),
|
||||
)
|
||||
|
||||
|
||||
def checkout_branch(git, remote_exists, branch):
|
||||
if remote_exists:
|
||||
git.stash('--include-untracked')
|
||||
print("Checking out branch '%s'" % branch)
|
||||
git.stash("--include-untracked")
|
||||
git.checkout(branch)
|
||||
try:
|
||||
git.stash('pop')
|
||||
git.stash("pop")
|
||||
except BaseException:
|
||||
git.checkout('--theirs', '.')
|
||||
git.checkout("--theirs", ".")
|
||||
git.reset()
|
||||
else:
|
||||
git.checkout('HEAD', b=branch)
|
||||
print("Creating new branch '%s'" % branch)
|
||||
git.checkout("HEAD", b=branch)
|
||||
|
||||
|
||||
def push_changes(git, branch, commit_message):
|
||||
git.add('-A')
|
||||
git.add("-A")
|
||||
git.commit(m=commit_message)
|
||||
return git.push('-f', '--set-upstream', 'origin', branch)
|
||||
return git.push("-f", "--set-upstream", "origin", branch)
|
||||
|
||||
|
||||
def cs_string_to_list(str):
|
||||
# Split the comma separated string into a list
|
||||
l = [i.strip() for i in str.split(',')]
|
||||
l = [i.strip() for i in str.split(",")]
|
||||
# Remove empty strings
|
||||
return list(filter(None, l))
|
||||
|
||||
|
||||
def create_project_card(github_repo, project_name, project_column_name, pull_request):
|
||||
# Locate the project by name
|
||||
project = None
|
||||
for project_item in github_repo.get_projects("all"):
|
||||
if project_item.name == project_name:
|
||||
project = project_item
|
||||
break
|
||||
|
||||
if not project:
|
||||
print("::warning::Project not found. Unable to create project card.")
|
||||
return
|
||||
|
||||
# Locate the column by name
|
||||
column = None
|
||||
for column_item in project.get_columns():
|
||||
if column_item.name == project_column_name:
|
||||
column = column_item
|
||||
break
|
||||
|
||||
if not column:
|
||||
print("::warning::Project column not found. Unable to create project card.")
|
||||
return
|
||||
|
||||
# Create a project card for the pull request
|
||||
column.create_card(content_id=pull_request.id, content_type="PullRequest")
|
||||
print(
|
||||
"Added pull request #%d to project '%s' under column '%s'"
|
||||
% (pull_request.number, project.name, column.name)
|
||||
)
|
||||
|
||||
|
||||
def process_event(github_token, github_repository, repo, branch, base):
|
||||
# Fetch optional environment variables with default values
|
||||
commit_message = os.getenv(
|
||||
'COMMIT_MESSAGE',
|
||||
"Auto-committed changes by create-pull-request action")
|
||||
"COMMIT_MESSAGE", "Auto-committed changes by create-pull-request action"
|
||||
)
|
||||
title = os.getenv(
|
||||
'PULL_REQUEST_TITLE',
|
||||
"Auto-generated by create-pull-request action")
|
||||
"PULL_REQUEST_TITLE", "Auto-generated by create-pull-request action"
|
||||
)
|
||||
body = os.getenv(
|
||||
'PULL_REQUEST_BODY', "Auto-generated pull request by "
|
||||
"[create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub Action")
|
||||
"PULL_REQUEST_BODY",
|
||||
"Auto-generated pull request by "
|
||||
"[create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub Action",
|
||||
)
|
||||
# Fetch optional environment variables with no default values
|
||||
pull_request_labels = os.environ.get('PULL_REQUEST_LABELS')
|
||||
pull_request_assignees = os.environ.get('PULL_REQUEST_ASSIGNEES')
|
||||
pull_request_milestone = os.environ.get('PULL_REQUEST_MILESTONE')
|
||||
pull_request_reviewers = os.environ.get('PULL_REQUEST_REVIEWERS')
|
||||
pull_request_team_reviewers = os.environ.get('PULL_REQUEST_TEAM_REVIEWERS')
|
||||
pull_request_labels = os.environ.get("PULL_REQUEST_LABELS")
|
||||
pull_request_assignees = os.environ.get("PULL_REQUEST_ASSIGNEES")
|
||||
pull_request_milestone = os.environ.get("PULL_REQUEST_MILESTONE")
|
||||
pull_request_reviewers = os.environ.get("PULL_REQUEST_REVIEWERS")
|
||||
pull_request_team_reviewers = os.environ.get("PULL_REQUEST_TEAM_REVIEWERS")
|
||||
project_name = os.environ.get("PROJECT_NAME")
|
||||
project_column_name = os.environ.get("PROJECT_COLUMN_NAME")
|
||||
|
||||
# Push the local changes to the remote branch
|
||||
print("Pushing changes.")
|
||||
print("Pushing changes to 'origin/%s'" % branch)
|
||||
push_result = push_changes(repo.git, branch, commit_message)
|
||||
print(push_result)
|
||||
|
||||
@ -109,111 +148,145 @@ def process_event(github_token, github_repository, repo, branch, base):
|
||||
github_repo = Github(github_token).get_repo(github_repository)
|
||||
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))
|
||||
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:
|
||||
# Format the branch name
|
||||
head_branch = "%s:%s" % (github_repository.split("/")[0], branch)
|
||||
# Get the pull request
|
||||
pull_request = github_repo.get_pulls(
|
||||
state='open',
|
||||
base=base,
|
||||
head=head_branch)[0]
|
||||
print("Updated pull request #%d (%s => %s)" %
|
||||
(pull_request.number, branch, base))
|
||||
state="open", base=base, head=head_branch
|
||||
)[0]
|
||||
print(
|
||||
"Updated pull request #%d (%s => %s)"
|
||||
% (pull_request.number, branch, base)
|
||||
)
|
||||
else:
|
||||
print(str(e))
|
||||
sys.exit(1)
|
||||
|
||||
# Set the output variables
|
||||
os.system(
|
||||
'echo ::set-env name=PULL_REQUEST_NUMBER::%d' %
|
||||
pull_request.number)
|
||||
os.system(
|
||||
'echo ::set-output name=pr_number::%d' %
|
||||
pull_request.number)
|
||||
os.system("echo ::set-env name=PULL_REQUEST_NUMBER::%d" % pull_request.number)
|
||||
os.system("echo ::set-output name=pr_number::%d" % pull_request.number)
|
||||
|
||||
# Set labels, assignees and milestone
|
||||
if pull_request_labels is not None:
|
||||
print("Applying labels")
|
||||
print("Applying labels '%s'" % pull_request_labels)
|
||||
pull_request.as_issue().edit(labels=cs_string_to_list(pull_request_labels))
|
||||
if pull_request_assignees is not None:
|
||||
print("Applying assignees")
|
||||
pull_request.as_issue().edit(assignees=cs_string_to_list(pull_request_assignees))
|
||||
print("Applying assignees '%s'" % pull_request_assignees)
|
||||
pull_request.as_issue().edit(
|
||||
assignees=cs_string_to_list(pull_request_assignees)
|
||||
)
|
||||
if pull_request_milestone is not None:
|
||||
print("Applying milestone")
|
||||
print("Applying milestone '%s'" % pull_request_milestone)
|
||||
milestone = github_repo.get_milestone(int(pull_request_milestone))
|
||||
pull_request.as_issue().edit(milestone=milestone)
|
||||
|
||||
# Set pull request reviewers
|
||||
if pull_request_reviewers is not None:
|
||||
print("Requesting reviewers")
|
||||
print("Requesting reviewers '%s'" % pull_request_reviewers)
|
||||
try:
|
||||
pull_request.create_review_request(
|
||||
reviewers=cs_string_to_list(pull_request_reviewers))
|
||||
reviewers=cs_string_to_list(pull_request_reviewers)
|
||||
)
|
||||
except GithubException as e:
|
||||
# Likely caused by "Review cannot be requested from pull request author."
|
||||
# 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")
|
||||
print("Requesting team reviewers '%s'" % pull_request_team_reviewers)
|
||||
pull_request.create_review_request(
|
||||
team_reviewers=cs_string_to_list(pull_request_team_reviewers))
|
||||
team_reviewers=cs_string_to_list(pull_request_team_reviewers)
|
||||
)
|
||||
|
||||
# Create a project card for the pull request
|
||||
if project_name is not None and project_column_name is not None:
|
||||
try:
|
||||
create_project_card(
|
||||
github_repo, project_name, project_column_name, pull_request
|
||||
)
|
||||
except GithubException as e:
|
||||
# Likely caused by "Project already has the associated issue."
|
||||
if e.status == 422:
|
||||
print(
|
||||
"Create project card failed - %s" % e.data["errors"][0]["message"]
|
||||
)
|
||||
|
||||
|
||||
# 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']
|
||||
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'])
|
||||
event_data = get_github_event(os.environ["GITHUB_EVENT_PATH"])
|
||||
|
||||
# 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)
|
||||
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)
|
||||
|
||||
# Fetch/Set the branch name
|
||||
branch_prefix = os.getenv(
|
||||
'PULL_REQUEST_BRANCH',
|
||||
'create-pull-request/patch')
|
||||
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')
|
||||
base_override = os.environ.get("PULL_REQUEST_BASE")
|
||||
|
||||
# Set the base branch
|
||||
if base_override is not None:
|
||||
base = base_override
|
||||
print("Overriding the base with branch '%s'" % base)
|
||||
checkout_branch(repo.git, True, base)
|
||||
elif github_ref.startswith('refs/pull/'):
|
||||
elif github_ref.startswith("refs/pull/"):
|
||||
# Check the PR is not raised from a fork of the repository
|
||||
head_repo = "{pull_request[head][repo][full_name]}".format(**event_data)
|
||||
if head_repo != github_repository:
|
||||
print(
|
||||
"::warning::Pull request was raised from a fork of the repository. "
|
||||
+ "Limitations on forked repositories have been imposed by GitHub Actions. "
|
||||
+ "Unable to continue. Exiting."
|
||||
)
|
||||
sys.exit()
|
||||
# Switch to the merging branch instead of the merge commit
|
||||
base = os.environ['GITHUB_HEAD_REF']
|
||||
repo.git.checkout(base)
|
||||
else:
|
||||
base = os.environ["GITHUB_HEAD_REF"]
|
||||
print(
|
||||
"Removing the merge commit by switching to the pull request head branch '%s'"
|
||||
% base
|
||||
)
|
||||
checkout_branch(repo.git, True, base)
|
||||
elif github_ref.startswith("refs/heads/"):
|
||||
base = github_ref[11:]
|
||||
print("Currently checked out base assumed to be branch '%s'" % base)
|
||||
else:
|
||||
print(
|
||||
f"::warning::Currently checked out ref '{github_ref}' is not a valid base for a pull request. "
|
||||
+ "Unable to continue. Exiting."
|
||||
)
|
||||
sys.exit()
|
||||
|
||||
# Skip if the current branch is a PR branch created by this action.
|
||||
# This may occur when using a PAT instead of GITHUB_TOKEN.
|
||||
# This may occur when using a PAT instead of GITHUB_TOKEN because
|
||||
# a PAT allows workflow actions to trigger further events.
|
||||
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')
|
||||
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))
|
||||
@ -227,39 +300,51 @@ elif branch_suffix == "none":
|
||||
# Fixed branch name
|
||||
branch = branch_prefix
|
||||
else:
|
||||
print(
|
||||
"Branch suffix '%s' is not a valid value." %
|
||||
branch_suffix)
|
||||
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)
|
||||
# Output head branch
|
||||
print("Pull request branch to create/update set to '%s'" % branch)
|
||||
|
||||
# Check if the determined head branch exists as a remote
|
||||
remote_exists = remote_branch_exists(repo, branch)
|
||||
if remote_exists:
|
||||
if branch_suffix == 'short-commit-hash':
|
||||
print(
|
||||
"Pull request branch '%s' already exists as remote branch 'origin/%s'"
|
||||
% (branch, branch)
|
||||
)
|
||||
if branch_suffix == "short-commit-hash":
|
||||
# A remote branch already exists for the HEAD commit
|
||||
print(
|
||||
"Pull request branch '%s' already exists for this commit. Skipping." %
|
||||
branch)
|
||||
"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
|
||||
elif branch_suffix in ["timestamp", "random"]:
|
||||
# Generated branch name collision with an existing branch
|
||||
print(
|
||||
"Pull request branch '%s' already exists. Please re-run." %
|
||||
branch)
|
||||
"Pull request branch '%s' collided with a branch of the same name. 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)
|
||||
if remote_exists:
|
||||
print(
|
||||
"Checking for local working copy changes indicating a "
|
||||
+ "diff with existing pull request branch 'origin/%s'" % branch
|
||||
)
|
||||
else:
|
||||
print("Repository has no modified or untracked files. Skipping.")
|
||||
print(
|
||||
"Checking for local working copy changes indicating a "
|
||||
+ "diff with base 'origin/%s'" % base
|
||||
)
|
||||
|
||||
if repo.is_dirty() or len(repo.untracked_files) > 0:
|
||||
print("Modified or untracked files detected.")
|
||||
process_event(github_token, github_repository, repo, branch, base)
|
||||
else:
|
||||
print("No modified or untracked files detected. Skipping.")
|
||||
|
@ -1,2 +1,2 @@
|
||||
GitPython==3.0.4
|
||||
GitPython==3.0.5
|
||||
PyGithub==1.44.1
|
||||
|
Reference in New Issue
Block a user