mirror of
https://github.com/peter-evans/create-pull-request.git
synced 2026-10-01 01:47:42 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc7020a609 | ||
|
|
d8700620d6 | ||
|
|
b7064071dc | ||
|
|
339e82d37b | ||
|
|
a319015452 | ||
|
|
df0d07269b |
@@ -1,3 +1,6 @@
|
||||
__pycache__
|
||||
.python-version
|
||||
|
||||
node_modules
|
||||
|
||||
.DS_Store
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# <img width="24" height="24" src="assets/logo.svg"> Create Pull Request
|
||||
# <img width="24" height="24" src="docs/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.
|
||||
@@ -194,7 +194,7 @@ jobs:
|
||||
|
||||
This reference configuration will create pull requests that look like this:
|
||||
|
||||

|
||||

|
||||
|
||||
## License
|
||||
|
||||
|
||||
Vendored
+3
-1
@@ -1018,7 +1018,9 @@ async function run() {
|
||||
await exec.exec("pip", [
|
||||
"install",
|
||||
"--requirement",
|
||||
`${src}/requirements.txt`
|
||||
`${src}/requirements.txt`,
|
||||
"--no-index",
|
||||
`--find-links=${__dirname}/vendor`
|
||||
]);
|
||||
|
||||
// Fetch action inputs
|
||||
|
||||
Vendored
+13
@@ -8,6 +8,19 @@ def get_random_string(length=7, chars=string.ascii_lowercase + string.digits):
|
||||
return "".join(random.choice(chars) for _ in range(length))
|
||||
|
||||
|
||||
def parse_github_repository(url):
|
||||
# Parse the github repository from a URL
|
||||
# e.g. peter-evans/create-pull-request
|
||||
pattern = re.compile(r"^https://github.com/(.+/.+)$")
|
||||
|
||||
# Check we have a match
|
||||
match = pattern.match(url)
|
||||
if match is None:
|
||||
raise ValueError(f"The format of '{url}' is not a valid GitHub repository URL")
|
||||
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def parse_display_name_email(display_name_email):
|
||||
# Parse the name and email address from a string in the following format
|
||||
# Display Name <email@address.com>
|
||||
|
||||
Vendored
+12
-1
@@ -31,6 +31,13 @@ def get_git_config_value(repo, name):
|
||||
return None
|
||||
|
||||
|
||||
def get_github_repository():
|
||||
remote_origin_url = get_git_config_value(repo, "remote.origin.url")
|
||||
if remote_origin_url is None:
|
||||
raise ValueError("Failed to fetch 'remote.origin.url' from git config")
|
||||
return cmn.parse_github_repository(remote_origin_url)
|
||||
|
||||
|
||||
def git_user_config_is_set(repo):
|
||||
name = get_git_config_value(repo, "user.name")
|
||||
email = get_git_config_value(repo, "user.email")
|
||||
@@ -94,7 +101,6 @@ def set_committer_author(repo, committer, author):
|
||||
|
||||
# Get required environment variables
|
||||
github_token = os.environ["GITHUB_TOKEN"]
|
||||
github_repository = os.environ["GITHUB_REPOSITORY"]
|
||||
# Get environment variables with defaults
|
||||
path = os.getenv("CPR_PATH", os.getcwd())
|
||||
branch = os.getenv("CPR_BRANCH", DEFAULT_BRANCH)
|
||||
@@ -107,6 +113,11 @@ base = os.environ.get("CPR_BASE")
|
||||
# Set the repo path
|
||||
repo = Repo(path)
|
||||
|
||||
# Determine the GitHub repository from git config
|
||||
# This will be the target repository for the pull request
|
||||
github_repository = get_github_repository()
|
||||
print(f"Target repository set to {github_repository}")
|
||||
|
||||
# Determine if the checked out ref is a valid base for a pull request
|
||||
# The action needs the checked out HEAD ref to be a branch
|
||||
# This check will fail in the following cases:
|
||||
|
||||
Vendored
+17
@@ -9,6 +9,23 @@ def test_get_random_string():
|
||||
assert len(cmn.get_random_string(length=20)) == 20
|
||||
|
||||
|
||||
def test_parse_github_repository_success():
|
||||
repository = cmn.parse_github_repository(
|
||||
"https://github.com/peter-evans/create-pull-request"
|
||||
)
|
||||
assert repository == "peter-evans/create-pull-request"
|
||||
|
||||
|
||||
def test_parse_github_repository_failure():
|
||||
url = "https://github.com/peter-evans"
|
||||
with pytest.raises(ValueError) as e_info:
|
||||
cmn.parse_github_repository(url)
|
||||
assert (
|
||||
e_info.value.args[0]
|
||||
== f"The format of '{url}' is not a valid GitHub repository URL"
|
||||
)
|
||||
|
||||
|
||||
def test_parse_display_name_email_success():
|
||||
name, email = cmn.parse_display_name_email("abc def <abc@def.com>")
|
||||
assert name == "abc def"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 416 B After Width: | Height: | Size: 416 B |
|
Before Width: | Height: | Size: 414 KiB After Width: | Height: | Size: 414 KiB |
@@ -10,6 +10,7 @@ This document covers terminology, how the action works, and general usage guidel
|
||||
- [Pull request events](#pull-request-events)
|
||||
- [Restrictions on forked repositories](#restrictions-on-forked-repositories)
|
||||
- [Tag push events](#tag-push-events)
|
||||
- [Security](#security)
|
||||
|
||||
## Terminology
|
||||
|
||||
@@ -46,7 +47,7 @@ Workflow steps:
|
||||
|
||||
The following git diagram shows how the action creates and updates a pull request branch.
|
||||
|
||||

|
||||

|
||||
|
||||
## Guidelines
|
||||
|
||||
@@ -171,3 +172,23 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
### Security
|
||||
|
||||
From a security perspective it's good practice to fork third-party actions, review the code, and use your fork of the action in workflows.
|
||||
By using third-party actions directly the risk exists that it could be modified to do something malicious, such as capturing secrets.
|
||||
|
||||
This action uses [ncc](https://github.com/zeit/ncc) to compile the Node.js code and dependencies into a single file.
|
||||
Python dependencies are vendored and committed to the repository [here](https://github.com/peter-evans/create-pull-request/tree/master/dist/vendor).
|
||||
No dependencies are downloaded during the action execution.
|
||||
|
||||
Vendored Python dependencies can be reviewed by rebuilding the [dist](https://github.com/peter-evans/create-pull-request/tree/master/dist) directory and redownloading dependencies.
|
||||
The following commands require Node and Python 3.
|
||||
|
||||
```
|
||||
npm install
|
||||
npm run clean
|
||||
npm run package
|
||||
```
|
||||
|
||||
The `dist` directory should be rebuilt leaving no git diff.
|
||||
|
||||
@@ -16,7 +16,9 @@ async function run() {
|
||||
await exec.exec("pip", [
|
||||
"install",
|
||||
"--requirement",
|
||||
`${src}/requirements.txt`
|
||||
`${src}/requirements.txt`,
|
||||
"--no-index",
|
||||
`--find-links=${__dirname}/vendor`
|
||||
]);
|
||||
|
||||
// Fetch action inputs
|
||||
|
||||
+4
-1
@@ -4,7 +4,10 @@
|
||||
"description": "Creates a pull request for changes to your repository in the actions workspace",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"package": "ncc build index.js -o dist"
|
||||
"clean": "rm -rf dist",
|
||||
"build": "ncc build index.js -o dist",
|
||||
"vendor-deps": "pip download -r src/requirements.txt --no-binary=:all: -d dist/vendor",
|
||||
"package": "npm run build && npm run vendor-deps"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -8,6 +8,19 @@ def get_random_string(length=7, chars=string.ascii_lowercase + string.digits):
|
||||
return "".join(random.choice(chars) for _ in range(length))
|
||||
|
||||
|
||||
def parse_github_repository(url):
|
||||
# Parse the github repository from a URL
|
||||
# e.g. peter-evans/create-pull-request
|
||||
pattern = re.compile(r"^https://github.com/(.+/.+)$")
|
||||
|
||||
# Check we have a match
|
||||
match = pattern.match(url)
|
||||
if match is None:
|
||||
raise ValueError(f"The format of '{url}' is not a valid GitHub repository URL")
|
||||
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def parse_display_name_email(display_name_email):
|
||||
# Parse the name and email address from a string in the following format
|
||||
# Display Name <email@address.com>
|
||||
|
||||
@@ -31,6 +31,13 @@ def get_git_config_value(repo, name):
|
||||
return None
|
||||
|
||||
|
||||
def get_github_repository():
|
||||
remote_origin_url = get_git_config_value(repo, "remote.origin.url")
|
||||
if remote_origin_url is None:
|
||||
raise ValueError("Failed to fetch 'remote.origin.url' from git config")
|
||||
return cmn.parse_github_repository(remote_origin_url)
|
||||
|
||||
|
||||
def git_user_config_is_set(repo):
|
||||
name = get_git_config_value(repo, "user.name")
|
||||
email = get_git_config_value(repo, "user.email")
|
||||
@@ -94,7 +101,6 @@ def set_committer_author(repo, committer, author):
|
||||
|
||||
# Get required environment variables
|
||||
github_token = os.environ["GITHUB_TOKEN"]
|
||||
github_repository = os.environ["GITHUB_REPOSITORY"]
|
||||
# Get environment variables with defaults
|
||||
path = os.getenv("CPR_PATH", os.getcwd())
|
||||
branch = os.getenv("CPR_BRANCH", DEFAULT_BRANCH)
|
||||
@@ -107,6 +113,11 @@ base = os.environ.get("CPR_BASE")
|
||||
# Set the repo path
|
||||
repo = Repo(path)
|
||||
|
||||
# Determine the GitHub repository from git config
|
||||
# This will be the target repository for the pull request
|
||||
github_repository = get_github_repository()
|
||||
print(f"Target repository set to {github_repository}")
|
||||
|
||||
# Determine if the checked out ref is a valid base for a pull request
|
||||
# The action needs the checked out HEAD ref to be a branch
|
||||
# This check will fail in the following cases:
|
||||
|
||||
@@ -9,6 +9,23 @@ def test_get_random_string():
|
||||
assert len(cmn.get_random_string(length=20)) == 20
|
||||
|
||||
|
||||
def test_parse_github_repository_success():
|
||||
repository = cmn.parse_github_repository(
|
||||
"https://github.com/peter-evans/create-pull-request"
|
||||
)
|
||||
assert repository == "peter-evans/create-pull-request"
|
||||
|
||||
|
||||
def test_parse_github_repository_failure():
|
||||
url = "https://github.com/peter-evans"
|
||||
with pytest.raises(ValueError) as e_info:
|
||||
cmn.parse_github_repository(url)
|
||||
assert (
|
||||
e_info.value.args[0]
|
||||
== f"The format of '{url}' is not a valid GitHub repository URL"
|
||||
)
|
||||
|
||||
|
||||
def test_parse_display_name_email_success():
|
||||
name, email = cmn.parse_display_name_email("abc def <abc@def.com>")
|
||||
assert name == "abc def"
|
||||
|
||||
Reference in New Issue
Block a user