73 Commits

Author SHA1 Message Date
Vanessasaurus
0969c26295 Merge pull request #100 from vsoch/update-container-base
fix bug with docker build
2023-12-07 19:40:22 -07:00
vsoch
d2ea9c206b fix bug with docker build
the alpine image no longer allows installing to system python
the fix is to target a virtual environment python3.

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2023-12-07 19:35:49 -07:00
Vanessasaurus
81b48d94ab Add LICENSE 2023-09-21 12:20:03 -06:00
Vanessasaurus
f9e7f419d6 Merge pull request #94 from vsoch/check-for-branch
Check for PR branch
2023-01-11 12:39:17 -07:00
Vanessasaurus
dcba08c9c2 Check for PR branch
before using the API so we hopefully save a call.
2023-01-06 20:03:27 -07:00
Yoshihisa Mochihara
c8e84cea4c fix GITHUB_OUTPUT bug (#92)
* fix GITHUB_OUTPUT bug
* Update CHANGELOG.md
2022-11-23 14:02:13 -07:00
Vanessasaurus
50f22f6d14 Update/set output (#90)
* updating set-output to echo to $GITHUB_OUTPUT instead

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2022-10-25 21:00:21 -06:00
Yunqi(Alice)
d703f40f3a Update the list_pull_request 401 case (#89)
* Update the list_pull_request 401 case
Hi, I find this http request is also missing the 401 case.
* Update CHANGELOG.md
2022-09-28 10:03:05 -06:00
Vanessasaurus
415544869c Merge pull request #88 from ohenak/fix/ghe-get-401-error
[Chore] Provide token when getting 401 error
2022-09-22 03:59:00 -06:00
Kane Ho
667293445b [Chore] Provide token when getting 401 error
Issue #87

In GHE, token is necessary when querying the repo API,
When it fails, it returns 401 error. Will need to specify the token in
this case.
2022-09-21 23:44:03 -07:00
Felix Breidenstein
e64deeba68 Fix example in README (#85) 2022-03-18 08:44:13 -06:00
Vanessasaurus
58a078aed9 Update CHANGELOG.md 2022-02-03 06:00:46 -07:00
Sviatoslav Sydorenko
408336c607 Fix emitting LF-separated GHA environment vars (#84)
Fixes #83 (hopefully)
2022-02-03 05:59:59 -07:00
Vanessasaurus
d99aa3ed71 Adding quick option to be able to specify a GitHub enterprise url (#80)
* adding quick option to be able to specify a GitHub enterprise url
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
* Use GITHUB_API_URL instead
Co-authored-by: Tobias <github@tobiasgabriel.de>

* Update README.md
* Update pull-request.py

Co-authored-by: vsoch <vsoch@users.noreply.github.com>
Co-authored-by: Tobias <github@tobiasgabriel.de>
2021-10-02 22:40:48 -06:00
Vanessasaurus
a48b660567 Merge pull request #81 from vsoch/add/open-source-halloween-2021
adding open source halloween!
2021-10-02 18:26:20 -06:00
vsoch
4b09070b0a adding open source halloween!
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2021-10-02 18:25:26 -06:00
Vanessasaurus
29dbfc0acd Merge pull request #75 from Kong/feat/discover-default-branch
Use repo's default branch if no branch specified
2021-06-21 10:10:40 -06:00
Danny Sauer
c0bf76830b Use repo's default branch if no branch specified 2021-06-21 11:04:52 -05:00
Yi Zhang
1cb1956a68 Support to open pull request to another repo (#70)
* support custom token and repo
* print post url if there's error
* update as comments
* Update README.md

Co-authored-by: Vanessasaurus <814322+vsoch@users.noreply.github.com>
2021-04-27 06:04:20 -06:00
vsoch
2ca266185d updating changelog preparing for release
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2021-04-18 19:54:26 -06:00
Max Anderson
e2a437cdbd Prevent unhandled exception when running via schedule (#69)
* Prevent unhandled exception when running via schedule
2021-04-18 19:53:12 -06:00
Vanessasaurus
2d5c80f215 dont use version for examples, stick to master (#67)
* dont use version for examples, stick to master
* add note about it being important to use stable release in README.md

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2021-03-27 19:08:35 -06:00
Vanessasaurus
7f0d383d15 adding back assignees variable (#65)
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2021-02-15 10:51:43 -07:00
Vanessasaurus
6d137cdd42 adding changes to update a PR (#60)
* adding changes to update a pr
including a second envar to set a state, along with refactor
of main body to be multiple functions, and adding docstrings
* fixing missing variable
* Try removing maintainer can modify
* Update pull-request.py

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2021-02-12 17:42:23 -07:00
Vanessasaurus
ebce8e4918 making abort_if_fail more verbose (#57)
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-12-18 04:05:17 -07:00
Vanessasaurus
c761be135f replacing set-env with new environment syntax (#48)
* replacing set-env with new environment syntax
* using direct append to file for set_env instead of os.system
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-11-17 08:33:29 -07:00
Vanessasaurus
c39853dfde Add environment variable to pass if PR exists (#53)
* adding PASS_IF_EXISTS

Signed-off-by: vsoch <vsochat@stanford.edu>

* PASS_IF_EXISTS option, to not error out when a matching PR already is open (#52)

* Pass filters to request for PRs, and move PASS_IF_EXISTS exit in different spot
* Changed a printout to say the params used for a req
* break when looping through branches and find the matching one
Co-authored-by: Vanessasaurus <vsochat@gmail.com>

Co-authored-by: tscizzlebg <54290732+tscizzlebg@users.noreply.github.com>
2020-10-20 12:15:41 -06:00
Vanessasaurus
0d662a3b50 Update/python client (#46)
* testing fixes for original query for pr
* bugfix
* need to loop through
* Adding more verbosity
* adding is_open
* Adding GET request with headers if needed
* Update pull-request.py
2020-09-25 18:31:06 -06:00
Vanessasaurus
727bec37b0 Testing assign request again (#43)
* Update pull-request.sh
* making reviewer failure more verbose
* More debugging
* updating pull request script to be more verbose
* need to pipe curl_wrapper into stderr so it doesnt return
* final tweaks to remove extra printing
* Testing assign request again
* updating to be more verbose
* testing with python entrypoint

Signed-off-by: vsoch <vsochat@stanford.edu>
2020-09-24 11:58:11 -06:00
Vanessasaurus
66d0146c3a Test pr wrapper (#42)
* Update pull-request.sh
* making reviewer failure more verbose
* updating pull request script to be more verbose
* final tweaks to remove extra printing
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-09-21 11:29:57 -06:00
Brandon W Maister
1106c316c1 Tell curl to set an exit code if a request fails (#39)
* Tell curl to set an exit code if the request fails
* Remove the `--user GITHUB_ACTOR` from curl calls
* fixup! Tell curl to set an exit code if the request fails
2020-08-07 13:09:22 -06:00
vsoch
790b81a742 adding example to derive a branch name from the environment (from previous step)
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-06-21 13:56:24 -06:00
vsoch
d347e09c29 adding stale bot, will close stale issues
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-04-21 14:55:37 -06:00
Vanessasaurus
7bc520d458 Merge pull request #33 from vsoch/fix/assignee-reviewer-parsing
Fix bug for parsing list of reviewers/assignees with "-"
2020-04-21 14:50:37 -06:00
vsoch
9388624b4c testing fix to assigning reviewers
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-04-21 14:27:05 -06:00
Vanessasaurus
1e9dfb50ae Merge pull request #28 from vsoch/add/outputs
First test to add outputs
2020-03-25 12:58:06 -06:00
vsoch
443ae6fbfb bumping version in example, setting correct version in example
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-25 10:11:44 -06:00
vsoch
5790dea963 adding outputs example (now tested)
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-25 10:09:34 -06:00
vsoch
aaed200ec8 first test to add outputs
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-25 09:58:27 -06:00
Vanessasaurus
702ab9c078 Merge pull request #26 from vsoch/add/reviewers
Add/reviewers
2020-03-25 09:38:07 -06:00
vsoch
4a1e588164 adding example for reviewers and changelog
This PR will add the ability to specify one or more individual users
or team names to the environment to request for review.

Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-23 13:43:20 -06:00
vsoch
a61c2bcfb7 syntax error
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-23 13:38:49 -06:00
vsoch
1a853b4e3f testing change to add reviewers (team or individual) to a PR
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-23 13:36:27 -06:00
Vanessasaurus
9d567ac1d1 Merge pull request #23 from vsoch/add/assignees
Add/assignees
2020-03-23 11:25:34 -06:00
Vanessasaurus
948483f8ff Merge branch 'master' into add/assignees 2020-03-23 11:24:49 -06:00
Vanessasaurus
96906bfdd9 Merge pull request #24 from fgriberi/patch-1
Fix typo error in README.md file  [minor]
2020-03-19 09:29:13 -06:00
Franco Riberi
35053dc2fc Fix typo error in README.md file [minor]
Fix typo error in README.md file
2020-03-19 11:39:46 -03:00
vsoch
c3a7ec260e update version of example
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 15:51:49 -06:00
vsoch
90f97d7ca1 last change to add example
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 15:35:22 -06:00
vsoch
6795aa743d fix trailing slash
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 15:20:50 -06:00
vsoch
617744b952 fail no matter what
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:52:58 -06:00
vsoch
906c9693bf need to parse assignees
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:43:26 -06:00
vsoch
37a2b85332 trying again
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:38:47 -06:00
vsoch
8638d1b6f1 need to echo response
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:35:59 -06:00
vsoch
09f5606222 update to use .number
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:30:22 -06:00
vsoch
df89c5fb9e update to use .number
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:28:35 -06:00
vsoch
d0166ffab5 updating pull request to use return code to determine to assign folks
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:24:24 -06:00
vsoch
c4372cd524 fixing print of return value and syntax error
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:18:42 -06:00
vsoch
125f29f472 adding ability to assign people to PR
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 14:07:00 -06:00
vsoch
e9cc2a3f41 adding maintainer can modify
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-18 13:47:52 -06:00
Vanessasaurus
d987bc1511 Merge pull request #22 from vsoch/add/support-null-branch
Add/support null branch
2020-03-17 11:37:29 -06:00
vsoch
4ae1c5e25c adding examples for push and release
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-17 11:36:44 -06:00
vsoch
d0c1b9ddb0 adding PR_BRANCH_FROM to support null use case
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-03-17 10:50:25 -06:00
Srdjan Grubor
a3c90d58a7 Fix action branch logic for pull requests
Without this change, `BRANCH` will be `null` for triggers that don't
have an associated branch like `release: [published]`.

Closes #20
2020-03-17 11:27:27 -05:00
vsoch
a3ee64d51c Merge branch 'master' of github.com:vsoch/pull-request-action 2020-02-05 10:09:47 -07:00
vsoch
a46f168cf9 updating link to example
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-02-05 10:09:33 -07:00
Vanessasaurus
02aa792cc8 Merge pull request #16 from vsoch/add/action.yml
adding action.yml to test
2020-02-05 10:08:38 -07:00
vsoch
d7dede2212 adding action.yml to test
Signed-off-by: vsoch <vsochat@stanford.edu>
2020-02-05 10:00:44 -07:00
Carl Sutton
b94f438ea0 Use alpine instead of ubuntu so the build is faster (#14) 2019-12-07 12:19:22 -08:00
Vanessasaurus
ca8460101c fixing up GitHub action to work with yaml syntax (#11)
Signed-off-by: Vanessa Sochat <vsochat@stanford.edu>
2019-10-19 09:36:46 -04:00
Godfrey Chan
e54bcbb815 Quote JSON Strings (#8)
The previous approach causes problems when there are e.g. newlines in the pull
request body. Also, the `draft` parameter was previously passed as a JSON
string (`"draft": "true"` and `"draft": "false"`, as opposed to `"draft": true`
and `"draft": false`), which I suspect is just a bug.
2019-08-23 11:03:18 -04:00
Vanessasaurus
0b6c3279d5 Adding body 2019-05-21 02:06:27 -07:00
Vanessasaurus
4ffa883947 Adding more quotes, debug prints 2019-05-21 01:59:51 -07:00
17 changed files with 899 additions and 155 deletions

17
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

25
CHANGELOG.md Normal file
View File

@@ -0,0 +1,25 @@
# CHANGELOG
This is a manually generated log to track changes to the repository for each release.
Each section should include general headers such as **Implemented enhancements**
and **Merged pull requests**. All closed issued and bug fixes should be
represented by the pull requests that fixed them. Critical items to know are:
- renamed commands
- deprecated / removed commands
- changed defaults
- backward incompatible changes
Versions correspond with GitHub releases that can be referenced with @ using actions.
## [master](https://github.com/vsoch/pull-request-action/tree/master) (master)
- alpine cannot install to system python anymore (1.1.0)
- bugfix of missing output values (1.0.23)
- bugfix of token handling if 401 error received (missing 401 case) (1.0.21)
- bugfix of writing to environment file (missing newline) (1.0.19)
- bugfix of missing from branch with scheduled run (1.0.16)
- forgot to add assignees (1.0.15)
- output and environment variables for PR number and return codes (1.0.5)
- added support for reviewer (individual and team) assignments (1.0.4)
- added support for maintainer can modify and assignees (1.0.3)

View File

@@ -1,4 +1,4 @@
FROM debian:jessie-slim
FROM alpine
# docker build -t vanessa/pull-request-action .
@@ -7,8 +7,11 @@ LABEL "com.github.actions.description"="Create a pull request when a branch is c
LABEL "com.github.actions.icon"="activity"
LABEL "com.github.actions.color"="yellow"
RUN apt-get update && apt-get install -y jq curl wget git
COPY pull-request.sh /pull-request.sh
# Newer alpine we are not allowed to install to system python
RUN apk --no-cache add python3 py3-pip py3-virtualenv git bash && \
python3 -m venv /opt/env && \
/opt/env/bin/pip3 install requests
COPY pull-request.py /pull-request.py
RUN chmod u+x /pull-request.sh
ENTRYPOINT ["/pull-request.sh"]
RUN chmod u+x /pull-request.py
ENTRYPOINT ["/opt/env/bin/python3", "/pull-request.py"]

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-2023 Vanessa Sochat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

112
README.md
View File

@@ -29,16 +29,114 @@ jobs:
PULL_REQUEST_BRANCH: "master"
```
Environment variables include:
**Important**: Make sure to use a stable [release](https://github.com/vsoch/pull-request-action/releases) instead of a branch for your workflow.
- **BRANCH_PREFIX**: the prefix to filter to. If the branch doesn't start with the prefix, it will be ignored
- **PULL_REQUEST_BRANCH**: the branch to issue the pull request to. Defaults to master.
- **PULL_REQUEST_BODY**: the body for the pull request (optional)
- **PULL_REQUEST_TITLE**: the title for the pull request (optional)
- **PULL_REQUEST_DRAFT**: should the pull request be a draft PR? (optional; unset defaults to `false`)
## Environment Variable Inputs
Unlike standard actions, this action just uses variables from the environment.
| Name | Description | Required | Default |
|------|-------------|----------|---------|
| BRANCH_PREFIX | the prefix to filter to. If the branch doesn't start with the prefix, it will be ignored | false | "" |
| PULL_REQUEST_REPOSITORY | Choose another repository instead of default GITHUB_REPOSITORY for the PR | false | |
| PULL_REQUEST_TOKEN | [Personal Access Token(PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) only if you define a different repository with PULL_REQUEST_REPOSITORY | false | |
| PULL_REQUEST_BRANCH | open pull request against this branch | false | master |
| PULL_REQUEST_FROM_BRANCH | if a branch isn't found in your GitHub payload, use this branch | false | |
| PULL_REQUEST_BODY | the body for the pull request | false | |
| PULL_REQUEST_TITLE | the title for the pull request | false | |
| PULL_REQUEST_DRAFT | should this be a draft PR? | false | unset |
| MAINTAINER_CANT_MODIFY | Do not allow the maintainer to modify the PR | false | unset |
| PULL_REQUEST_ASSIGNEES | A list (string with spaces) of users to assign | false | unset |
| PULL_REQUEST_REVIEWERS | A list (string with spaces) of users to assign review | false | unset |
| PULL_REQUEST_TEAM_REVIEWERS | A list (string with spaces) of teams to assign review | false | unset |
| PASS_ON_ERROR | Instead of failing on an error response, pass | false | unset |
| PASS_IF_EXISTS | Instead of failing if the pull request already exists, pass | false | unset |
| PULL_REQUEST_UPDATE | If the pull request already exists, update it | false | unset |
| PULL_REQUEST_STATE | If `PULL_REQUEST_UPDATE` is true, update to this state (open, closed) | false |open |
For `PULL_REQUEST_DRAFT`, `PASS_ON_ERROR`, `PASS_IF_EXISTS`, and `MAINTAINER_CANT_MODIFY`, these are
treated as environment booleans. If they are defined in the environment, they trigger the
"true" condition. E.g.,:
- Define `MAINTAINER_CANT_MODIFY` if you don't want the maintainer to be able to modify the pull request.
- Define `PULL_REQUEST_DRAFT` if you want the PR to be a draft.
- Define `PASS_ON_ERROR` if you want the PR to not exit given any non 200/201 response.
- Define `PASS_IF_EXISTS` if you want the PR to not exit given the pull request is already open.
- Define `PULL_REQUEST_UPDATE` if you want the pull request to be updated if it already exits.
For `PULL_REQUEST_ASSIGNEES`, `PULL_REQUEST_REVIEWERS`, and `PULL_REQUEST_TEAM_REVIEWERS`
you can provide a string of one or more GitHub usernames (or team names) to
assign to the issue. Note that only users with push access can add assigness to
an issue or PR, they are ignored otherwise.
The `GITHUB_TOKEN` secret is required to interact and authenticate with the GitHub API to open
the pull request.
the pull request. The example is [deployed here](https://github.com/vsoch/pull-request-action-example) with an example opened (and merged) [pull request here](https://github.com/vsoch/pull-request-action-example/pull/1) if needed.
If you want to create a pull request to another repository, for example, a pull request to the upstream repository, you need to define PULL_REQUEST_REPOSITORY and PULL_REQUEST_TOKEN. The PULL_REQUEST_TOKEN is one [Personal Access Token(PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token), which can be save in the [encrypted secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository)
## Outputs
The action sets a few useful output and environment variables. An output can
be referenced later as `${{ steps.<stepname>.outputs.<output-name> }}`.
An environment variable of course can be referenced as you usually would.
| Name | Description | Environment |
|------|-------------|-------------|
| pull_request_number |If the pull request is opened, this is the number for it. | PULL_REQUEST_NUMBER |
| pull_request_url |If the pull request is opened, the html url for it. | PULL_REQUEST_URL |
| pull_request_return_code | Return code for the pull request | PULL_REQUEST_RETURN_CODE |
| assignees_return_code | Return code for the assignees request | ASSIGNEES_RETURN_CODE |
| reviewers_return_code | Return code for the reviewers request | REVIEWERS_RETURN_CODE |
See the [examples/outputs-example.yml](examples/outputs-example.yml) for how this works.
In this example, we can reference `${{ steps.pull_request.outputs.pull_request_url }}`
in either another environment variable declaration, or within a run statement to access
our variable `pull_request_url` that was generated in a step with id `pull_request`.
The screenshot below shows the example in action to interact with outputs in several ways.
![img/outputs.png](img/outputs.png)
## Examples
Example workflows are provided in [examples](examples), and please contribute any
examples that you might have to help other users! You can get the same commit hashes
and commented tags if you use the [action-updater](https://github.com/vsoch/action-updater)
also maintained by @vsoch. We will walk through a basic
example here for a niche case. Let's say that we are opening a pull request on the release event. This would mean
that the payload's branch variable would be null. We would need to define `PULL_REQUEST_FROM`. How would
we do that? We can [set environment variables](https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files) for next steps. Here is an example:
```yaml
name: Pull Request on Branch Push
on: [release]
jobs:
pull-request-on-release:
name: PullRequestAction
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Derive from branch name
run: |
# do custom parsing of your code / date to derive a branch from
PR_BRANCH_FROM=release-v$(cat VERSION)
echo "PULL_REQUEST_FROM_BRANCH=${PR_BRANCH_FROM}" >> $GITHUB_ENV
- name: pull-request-action
uses: vsoch/pull-request-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULL_REQUEST_BRANCH: "master"
```
The above workflow is triggered on a release, so the branch will be null in the GItHub
payload. Since we want the release PR to come from a special branch, we derive it
in the second step, and then set the `PULL_REQUEST_FROM_BRANCH` variable in the environment
for the next step. In the Pull Request Action step, the pull request
will be opened from `PULL_REQUEST_FROM_BRANCH` against `PULL_REQUEST_BRANCH`, which is
master. If we do not set this variable, the job will exit in an error,
as it is not clear what action to take.
## Example use Case: Update Registry

20
action.yml Normal file
View File

@@ -0,0 +1,20 @@
name: 'Pull Request Action'
description: 'A GitHub action to open a pull request'
author: 'vsoch'
runs:
using: 'docker'
image: 'Dockerfile'
branding:
icon: 'activity'
color: 'yellow'
outputs:
pull_request_number:
description: 'If the pull request is opened, this is the number for it.'
pull_request_url:
description: 'If the pull request is opened, the html url for it.'
pull_request_return_code:
description: 'The pull request return code.'
assignees_return_code:
description: 'The add assignees post return code.'
reviewers_return_code:
description: 'The add reviewers post return code.'

View File

@@ -0,0 +1,17 @@
name: Pull Request on Branch Push
on:
push:
branches-ignore:
- devel
jobs:
auto-pull-request:
name: PullRequestAction
runs-on: ubuntu-latest
steps:
- name: pull-request-action
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: update/
PULL_REQUEST_BRANCH: master
PULL_REQUEST_ASSIGNEES: vsoch

View File

@@ -0,0 +1,48 @@
name: derive-branch-from-environment
on:
schedule: -
cron: 0 0 * * 0
jobs:
DoSomeUpdate:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Install or Do Something to Change repository
run: |
echo "This is a new file." >> newfile.txt
- name: Checkout New Branch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_AGAINST: master
run: |
printf "GitHub Actor: ${GITHUB_ACTOR}\n"
export BRANCH_FROM="update/newfile-$(date '+%Y-%m-%d')"
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
git branch
git checkout -b "${BRANCH_FROM}" || git checkout "${BRANCH_FROM}"
git branch
git config --global user.name "github-actions"
git config --global user.email "github-actions@users.noreply.github.com"
git add newfile.txt
if git diff-index --quiet HEAD --; then
printf "No changes\n"
else
printf "Changes\n"
git commit -m "Automated deployment to update software database $(date '+%Y-%m-%d')"
git push origin "${BRANCH_FROM}"
fi
# Here is where we are setting the environment variable!
echo "PULL_REQUEST_FROM_BRANCH=${BRANCH_FROM}" >> $GITHUB_ENV
- name: Open Pull Request
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULL_REQUEST_BRANCH: master

View File

@@ -0,0 +1,55 @@
name: Hotfix Branch Pull Request
on:
push:
branches-ignore:
- master
- production
# See https://github.com/vsoch/pull-request-action/issues/47#issuecomment-707109132
jobs:
auto-pull-request:
name: PullRequestAction
runs-on: ubuntu-latest
steps:
- name: Generate branch name
uses: actions/github-script@v6
id: set-branch-name
with:
script: |
const capitalize = (name) => name.charAt(0).toUpperCase() + name.slice(1);
const emoji = context.payload.ref.startsWith("refs/heads/feature")
? "✨ "
: context.payload.ref.startsWith("refs/heads/hotfix")
? "🚑 "
: "";
return `${emoji}${capitalize(
context.payload.ref
.replace("refs/heads/", "")
.replace(/-/g, " ")
.replace("feature ", "")
.replace("hotfix ", "")
)}`;
result-encoding: string
- name: Set branch name
run: echo "PULL_REQUEST_TITLE=${{steps.set-branch-name.outputs.result}}" >> $GITHUB_ENV
- name: Generate PR body
uses: actions/github-script@v6
id: set-pr-body
with:
script: |
return `I'm opening this pull request for this branch, pushed by @${
context.payload.head_commit.author.username
} with ${context.payload.commits.length} commit${
context.payload.commits.length === 1 ? "" : "s"
}.`;
result-encoding: string
- name: Set PR body
run: echo "PULL_REQUEST_BODY=${{steps.set-pr-body.outputs.result}}" >> $GITHUB_ENV
- name: pull-request-action
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: hotfix-
PULL_REQUEST_BRANCH: production
PULL_REQUEST_REVIEWERS: AnandChowdhary

View File

@@ -0,0 +1,28 @@
name: Pull Request on Branch Push
on:
push:
branches-ignore:
- devel
jobs:
auto-pull-request:
name: PullRequestAction
runs-on: ubuntu-latest
steps:
- name: pull-request-action
id: pull_request
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: update/
PULL_REQUEST_BRANCH: master
PULL_REQUEST_REVIEWERS: vsoch
- name: Test outputs
env:
pull_request_number_output: ${{ steps.pull_request.outputs.pull_request_number }}
pull_request_url_output: ${{ steps.pull_request.outputs.pull_request_url }}
run: |
echo "Pull request number from output: ${pull_request_number_output}"
echo "Pull request url from output: ${pull_request_url_output}"
echo "Pull request number from environment: ${PULL_REQUEST_NUMBER}"
echo "Pull request url from environment: ${PULL_REQUEST_URL}"
echo "Another way to specify from output ${{ steps.pull_request.outputs.pull_request_number }}"

18
examples/push-example.yml Normal file
View File

@@ -0,0 +1,18 @@
name: Pull Request on Branch Push
on:
push:
branches-ignore:
- staging
- launchpad
- production
jobs:
auto-pull-request:
name: PullRequestAction
runs-on: ubuntu-latest
steps:
- name: pull-request-action
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: update/
PULL_REQUEST_BRANCH: master

View File

@@ -0,0 +1,44 @@
on:
release:
types:
- published
jobs:
persist-new-suite-yml:
name: Commit Suite Release YML
runs-on: ubuntu-latest
steps:
# Likely other steps go here
- name: Set BRANCH_NAME
run: |
tag_name=${{github.event.release.tag_name}}
echo "Tag: $tag_name"
version=$(echo "$tag_name" | sed 's/^v//')
echo "Version: $version"
echo "suite_version=${version}" >> $GITHUB_OUTPUT
echo "suite_update_branch=suite_${version}" >> $GITHUB_OUTPUT
id: data
- name: Permanently save the new suite release
run: |
mkdir -p releases
new_suite_version_yml="releases/suite_${{ steps.data.outputs.suite_version }}.yml"
echo "Suite target file: $new_suite_version_yml"
cp suite.yml "${new_suite_version_yml}"
git add "${new_suite_version_yml}"
git commit -m "Suite v${{ steps.data.outputs.suite_version }} auto-commit of new release files"
- name: Push files
run: git push --force "https://${{ github.actor }}:${{secrets.GITHUB_TOKEN}}@github.com/${{ github.repository }}.git" "HEAD:${{ steps.data.outputs.suite_update_branch }}"
- name: Open a PR to the default branch
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PULL_REQUEST_FROM_BRANCH: ${{ steps.data.outputs.suite_update_branch }}
PULL_REQUEST_BRANCH: master
PULL_REQUEST_TITLE: 'Action: Update suite release file for v${{ steps.data.outputs.suite_version }}'
PULL_REQUEST_BODY: Auto-generated PR!

View File

@@ -0,0 +1,17 @@
name: Pull Request on Branch Push
on:
push:
branches-ignore:
- devel
jobs:
auto-pull-request:
name: PullRequestAction
runs-on: ubuntu-latest
steps:
- name: pull-request-action
uses: vsoch/pull-request-action@d703f40f3af5ae294f9816395ddf2e3d2d3feafa # 1.0.21
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: update/
PULL_REQUEST_BRANCH: master
PULL_REQUEST_REVIEWERS: vsoch

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
img/outputs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

476
pull-request.py Executable file
View File

@@ -0,0 +1,476 @@
#!/usr/bin/env python3
import sys
import os
import json
import requests
################################################################################
# Helper Functions
################################################################################
def get_envar(name):
"""
Given a name, return the corresponding environment variable. Exit if not
defined, as using this function indicates the envar is required.
Parameters:
name (str): the name of the environment variable
"""
value = os.environ.get(name)
if not value:
sys.exit("%s is required for vsoch/pull-request-action" % name)
return value
def check_events_json():
"""the github events json is required in order to indicate that we are
in an action environment.
"""
events = get_envar("GITHUB_EVENT_PATH")
if not os.path.exists(events):
sys.exit("Cannot find Github events file at ${GITHUB_EVENT_PATH}")
print("Found ${GITHUB_EVENT_PATH} at %s" % events)
return events
def abort_if_fail(response, reason):
"""If PASS_ON_ERROR, don't exit. Otherwise exit with an error and print
the reason.
Parameters:
response (requests.Response) : an unparsed response from requests
reason (str) : a message to print to the user for fail.
"""
message = "%s: %s: %s\n %s" % (
reason,
response.status_code,
response.reason,
response.json(),
)
if os.environ.get("PASS_ON_ERROR"):
print("Error, but PASS_ON_ERROR is set, continuing: %s" % message)
else:
sys.exit(message)
def parse_into_list(values):
"""A list of reviewers or assignees to parse from a string to a list
Parameters:
values (str) : a list of space separated, quoted values to parse to a list
"""
if values:
values = values.replace('"', "").replace("'", "")
if not values:
return []
return [x.strip() for x in values.split(" ")]
def set_env_and_output(name, value):
"""helper function to echo a key/value pair to the environement file
Parameters:
name (str) : the name of the environment variable
value (str) : the value to write to file
"""
for env_var in ("GITHUB_ENV", "GITHUB_OUTPUT"):
environment_file_path = os.environ.get(env_var)
print("Writing %s=%s to %s" % (name, value, env_var))
with open(environment_file_path, "a") as environment_file:
environment_file.write("%s=%s\n" % (name, value))
def open_pull_request(title, body, target, source, is_draft=False, can_modify=True):
"""Open pull request opens a pull request with a given body and content,
and sets output variables. An unparsed response is returned.
Parameters:
title (str) : the title to set for the new pull request
body (str) : the body to set for the new pull request
target (str) : the target branch
source (str) : the source branch
is_draft (bool) : indicate the pull request is a draft
can_modify (bool) : indicate the maintainer can modify
"""
print("No pull request from %s to %s is open, continuing!" % (source, target))
# Post the pull request
data = {
"title": title,
"body": body,
"base": target,
"head": source,
"draft": is_draft,
"maintainer_can_modify": can_modify,
}
print("Data for opening pull request: %s" % data)
response = requests.post(PULLS_URL, json=data, headers=HEADERS)
if response.status_code != 201:
print(f"pull request url is {PULLS_URL}")
abort_if_fail(response, "Unable to create pull request")
return response
def update_pull_request(entry, title, body, target, state=None):
"""Given an existing pull request, update it.
Parameters:
entry (dict) : the pull request metadata
title (str) : the title to set for the new pull request
body (str) : the body to set for the new pull request
target (str) : the target branch
state (bool) : the state of the PR (open, closed)
"""
print("PULL_REQUEST_UPDATE is set, updating existing pull request.")
data = {
"title": title,
"body": body,
"base": target,
"state": state or "open",
}
# PATCH /repos/{owner}/{repo}/pulls/{pull_number}
url = "%s/%s" % (PULLS_URL, entry.get("number"))
print("Data for updating pull request: %s" % data)
response = requests.patch(url, json=data, headers=HEADERS)
if response.status_code != 200:
abort_if_fail(response, "Unable to create pull request")
return response
def set_pull_request_groups(response):
"""Given a response for an open or updated PR, set metadata
Parameters:
response (requests.Response) : a requests response, unparsed
"""
# Expected return codes are 0 for success
pull_request_return_code = (
0 if response.status_code == 201 else response.status_code
)
response = response.json()
print("::group::github response")
print(response)
print("::endgroup::github response")
number = response.get("number")
html_url = response.get("html_url")
print("Number opened for PR is %s" % number)
set_env_and_output("PULL_REQUEST_NUMBER", number)
set_env_and_output("PULL_REQUEST_RETURN_CODE", pull_request_return_code)
set_env_and_output("PULL_REQUEST_URL", html_url)
def list_pull_requests(target, source):
"""Given a target and source, return a list of pull requests that match
(or simply exit given some kind of error code)
Parameters:
target (str) : the target branch
source (str) : the source branch
"""
# Check if the branch already has a pull request open
params = {"base": target, "head": source, "state": "open"}
print("Params for checking if pull request exists: %s" % params)
response = requests.get(PULLS_URL, params=params)
# Case 1: 401, 404 might warrant needing a token
if response.status_code in [401, 404]:
response = requests.get(PULLS_URL, params=params, headers=HEADERS)
if response.status_code != 200:
abort_if_fail(response, "Unable to retrieve information about pull requests")
return response.json()
def add_assignees(entry, assignees):
"""Given a pull request metadata (from create or update) add assignees
Parameters:
entry (dict) : the pull request metadata
assignees (str) : comma separated assignees string set by action
"""
# Remove leading and trailing quotes
assignees = parse_into_list(assignees)
number = entry.get("number")
print(
"Attempting to assign %s to pull request with number %s" % (assignees, number)
)
# POST /repos/:owner/:repo/issues/:issue_number/assignees
data = {"assignees": assignees}
ASSIGNEES_URL = "%s/%s/assignees" % (ISSUE_URL, number)
response = requests.post(ASSIGNEES_URL, json=data, headers=HEADERS)
if response.status_code != 201:
abort_if_fail(response, "Unable to create assignees")
assignees_return_code = 0 if response.status_code == 201 else response.status_code
print("::group::github assignees response")
print(response.json())
print("::endgroup::github assignees response")
set_env_and_output("ASSIGNEES_RETURN_CODE", assignees_return_code)
def find_pull_request(listing, source):
"""Given a listing and a source, find a pull request based on the source
(the branch name).
Parameters:
listing (list) : the list of PR objects (dict) to parse over
source (str) : the source (head) branch to look for
"""
if listing:
for entry in listing:
if entry.get("head", {}).get("ref", "") == source:
print("Pull request from %s is already open!" % source)
return entry
def find_default_branch():
"""Find default branch for a repo (only called if branch not provided)"""
response = requests.get(REPO_URL)
# Case 1: 401, 404 might need a token
if response.status_code in [401, 404]:
response = requests.get(REPO_URL, headers=HEADERS)
if response.status_code != 200:
abort_if_fail(response, "Unable to retrieve default branch")
default_branch = response.json()["default_branch"]
print("Found default branch: %s" % default_branch)
return default_branch
def add_reviewers(entry, reviewers, team_reviewers):
"""Given regular or team reviewers, add them to a PR.
Parameters:
entry (dict) : the pull request metadata
"""
print("Found reviewers: %s and team reviewers: %s" % (reviewers, team_reviewers))
team_reviewers = parse_into_list(team_reviewers)
reviewers = parse_into_list(reviewers)
print("Parsed reviewers: %s and team reviewers: %s" % (reviewers, team_reviewers))
# POST /repos/:owner/:repo/pulls/:pull_number/requested_reviewers
REVIEWERS_URL = "%s/%s/requested_reviewers" % (PULLS_URL, entry.get("number"))
data = {"reviewers": reviewers, "team_reviewers": team_reviewers}
response = requests.post(REVIEWERS_URL, json=data, headers=HEADERS)
if response.status_code != 201:
abort_if_fail(response, "Unable to assign reviewers")
reviewers_return_code = 0 if response.status_code == 201 else response.status_code
print("::group::github reviewers response")
print(response.json())
print("::endgroup::github reviewers response")
set_env_and_output("REVIEWERS_RETURN_CODE", reviewers_return_code)
################################################################################
# Global Variables (we can't use GITHUB_ prefix)
################################################################################
API_VERSION = "v3"
# Allow for a GitHub enterprise URL
BASE = os.environ.get("GITHUB_API_URL") or "https://api.github.com"
PR_TOKEN = os.environ.get("PULL_REQUEST_TOKEN") or get_envar("GITHUB_TOKEN")
PR_REPO = os.environ.get("PULL_REQUEST_REPOSITORY") or get_envar("GITHUB_REPOSITORY")
HEADERS = {
"Authorization": "token %s" % PR_TOKEN,
"Accept": "application/vnd.github.%s+json;application/vnd.github.antiope-preview+json;application/vnd.github.shadow-cat-preview+json"
% API_VERSION,
}
# URLs
REPO_URL = "%s/repos/%s" % (BASE, PR_REPO)
ISSUE_URL = "%s/issues" % REPO_URL
PULLS_URL = "%s/pulls" % REPO_URL
def create_pull_request(
source,
target,
body,
title,
assignees,
reviewers,
team_reviewers,
is_draft=False,
can_modify=True,
state="open",
):
"""Create pull request is the base function that determines if the PR exists,
and then updates or creates it depending on user preferences.
"""
listing = list_pull_requests(target, source)
# Determine if the pull request is already open
entry = find_pull_request(listing, source)
response = None
# Case 1: we found the PR, the user wants to pass
if entry and os.environ.get("PASS_IF_EXISTS"):
print("PASS_IF_EXISTS is set, exiting with success status.")
sys.exit(0)
# Does the user want to update the existing PR?
if entry and os.environ.get("PULL_REQUEST_UPDATE"):
response = update_pull_request(entry, title, body, target, state)
set_pull_request_groups(response)
# If it's not open, we open a new pull request
elif not entry:
response = open_pull_request(title, body, target, source, is_draft, can_modify)
set_pull_request_groups(response)
# If we have a response, parse into json (no longer need retvals)
response = response.json() if response else None
# If we have opened or updated, we can add assignees
if response and assignees:
add_assignees(response, assignees)
if response and (reviewers or team_reviewers):
add_reviewers(response, reviewers, team_reviewers)
def main():
"""main primarily parses environment variables to prepare for creation"""
# path to file that contains the POST response of the event
# Example: https://github.com/actions/bin/tree/master/debug
# Value: /github/workflow/event.json
check_events_json()
branch_prefix = os.environ.get("BRANCH_PREFIX", "")
print("Branch prefix is %s" % branch_prefix)
if not branch_prefix:
print("No branch prefix is set, all branches will be used.")
# Default to project default branch if none provided
pull_request_branch = os.environ.get("PULL_REQUEST_BRANCH")
if not pull_request_branch:
pull_request_branch = find_default_branch()
print("Pull requests will go to %s" % pull_request_branch)
# Pull request draft
pull_request_draft = os.environ.get("PULL_REQUEST_DRAFT")
if not pull_request_draft:
print("No explicit preference for draft PR: created PRs will be normal PRs.")
pull_request_draft = False
else:
print("PULL_REQUEST_DRAFT set to a value: created PRs will be draft PRs.")
pull_request_draft = True
# If an update is true, we can change the state
pull_request_state = os.environ.get("PULL_REQUEST_STATE", "open")
if pull_request_state not in ["open", "closed"]:
sys.exit("State is required to be one of 'open' or 'closed'")
# Maintainer can modify, defaults to CAN, unless user sets MAINTAINER_CANT_MODIFY
maintainer_can_modify = os.environ.get("MAINTAINER_CANT_MODIFY")
if not maintainer_can_modify:
print("No preference for maintainer being able to modify: default is true.")
maintainer_can_modify = True
else:
print(
"MAINTAINER_CANT_MODIFY set to a value: maintainer will not be able to modify."
)
maintainer_can_modify = False
# Assignees
assignees = os.environ.get("PULL_REQUEST_ASSIGNEES")
if not assignees:
print("PULL_REQUEST_ASSIGNEES is not set, no assignees.")
else:
print("PULL_REQUEST_ASSIGNEES is set, %s" % assignees)
# Reviewers (individual and team)
reviewers = os.environ.get("PULL_REQUEST_REVIEWERS")
team_reviewers = os.environ.get("PULL_REQUEST_TEAM_REVIEWERS")
if not reviewers:
print("PULL_REQUEST_REVIEWERS is not set, no reviewers.")
else:
print("PULL_REQUEST_REVIEWERS is set, %s" % reviewers)
if not team_reviewers:
print("PULL_REQUEST_TEAM_REVIEWERS is not set, no team reviewers.")
else:
print("PULL_REQUEST_TEAM_REVIEWERS is set, %s" % team_reviewers)
# The user is allowed to explicitly set the name of the branch
from_branch = os.environ.get("PULL_REQUEST_FROM_BRANCH")
if not from_branch:
print("PULL_REQUEST_FROM_BRANCH is not set, checking branch in payload.")
with open(check_events_json(), "r") as fd:
from_branch = json.loads(fd.read()).get("ref", "")
from_branch = from_branch.replace("refs/heads/", "").strip("/")
else:
print("PULL_REQUEST_FROM_BRANCH is set.")
# At this point, we must have a branch
if from_branch:
print("Found branch %s to open PR from" % from_branch)
else:
sys.exit(
"You are required to define PULL_REQUEST_FROM_BRANCH in the environment."
)
# If it's to the target branch, ignore it
if from_branch == pull_request_branch:
print("Target and current branch are identical (%s), skipping." % from_branch)
sys.exit(0)
# If the prefix for the branch matches
if not branch_prefix or from_branch.startswith(branch_prefix):
# Pull request body (optional)
pull_request_body = os.environ.get(
"PULL_REQUEST_BODY",
"This is an automated pull request to update from branch %s" % from_branch,
)
print("::group::pull request body")
print(pull_request_body)
print("::endgroup::pull request body")
# Pull request title (optional)
pull_request_title = os.environ.get(
"PULL_REQUEST_TITLE", "Update from %s" % from_branch
)
print("::group::pull request title")
print(pull_request_title)
print("::endgroup::pull request title")
# Create the pull request
create_pull_request(
target=pull_request_branch,
source=from_branch,
body=pull_request_body,
title=pull_request_title,
is_draft=pull_request_draft,
can_modify=maintainer_can_modify,
assignees=assignees,
reviewers=reviewers,
team_reviewers=team_reviewers,
state=pull_request_state,
)
if __name__ == "__main__":
print("==========================================================================")
print("START: Running Pull Request on Branch Update Action!")
main()
print("==========================================================================")
print("END: Finished")

View File

@@ -1,143 +0,0 @@
#!/bin/bash
# Suggested by Github actions to be strict
set -e
set -o pipefail
################################################################################
# Global Variables (we can't use GITHUB_ prefix)
################################################################################
API_VERSION=v3
BASE=https://api.github.com
AUTH_HEADER="Authorization: token ${GITHUB_TOKEN}"
HEADER="Accept: application/vnd.github.${API_VERSION}+json"
HEADER="${HEADER}; application/vnd.github.antiope-preview+json; application/vnd.github.shadow-cat-preview+json"
# URLs
REPO_URL="${BASE}/repos/${GITHUB_REPOSITORY}"
PULLS_URL=$REPO_URL/pulls
################################################################################
# Helper Functions
################################################################################
check_credentials() {
if [[ -z "${GITHUB_TOKEN}" ]]; then
echo "You must include the GITHUB_TOKEN as an environment variable."
exit 1
fi
}
check_events_json() {
if [[ ! -f "${GITHUB_EVENT_PATH}" ]]; then
echo "Cannot find Github events file at ${GITHUB_EVENT_PATH}";
exit 1;
fi
echo "Found ${GITHUB_EVENT_PATH}";
}
create_pull_request() {
SOURCE="${1}" # from this branch
TARGET="${2}" # pull request TO this target
BODY="${3}" # this is the content of the message
TITLE="${4}" # pull request title
DRAFT="${5}" # if PRs are draft
# Check if the branch already has a pull request open
DATA="{\"base\":\"${TARGET}\", \"head\":\"${SOURCE}\", \"body\":\"${BODY}\"}"
RESPONSE=$(curl -sSL -H "${AUTH_HEADER}" -H "${HEADER}" --user "${GITHUB_ACTOR}" -X GET --data "${DATA}" ${PULLS_URL})
PR=$(echo "${RESPONSE}" | jq --raw-output '.[] | .head.ref')
echo "Response ref: ${PR}"
# Option 1: The pull request is already open
if [[ "${PR}" == "${SOURCE}" ]]; then
echo "Pull request from ${SOURCE} to ${TARGET} is already open!"
# Option 2: Open a new pull request
else
# Post the pull request
DATA="{\"title\":\"${TITLE}\", \"base\":\"${TARGET}\", \"head\":\"${SOURCE}\", \"draft\":\"${DRAFT}\"}"
echo "curl --user ${GITHUB_ACTOR} -X POST --data ${DATA} ${PULLS_URL}"
curl -sSL -H "${AUTH_HEADER}" -H "${HEADER}" --user "${GITHUB_ACTOR}" -X POST --data "${DATA}" ${PULLS_URL}
echo $?
fi
}
main () {
# path to file that contains the POST response of the event
# Example: https://github.com/actions/bin/tree/master/debug
# Value: /github/workflow/event.json
check_events_json;
# User specified branch to PR to, and check
if [ -z "${BRANCH_PREFIX}" ]; then
echo "No branch prefix is set, all branches will be used."
BRANCH_PREFIX=""
echo "Branch prefix is $BRANCH_PREFIX"
fi
if [ -z "${PULL_REQUEST_BRANCH}" ]; then
PULL_REQUEST_BRANCH=master
fi
echo "Pull requests will go to ${PULL_REQUEST_BRANCH}"
if [ -z "${PULL_REQUEST_DRAFT}" ]; then
echo "No explicit preference for draft PR: created PRs will be normal PRs."
PULL_REQUEST_DRAFT="false"
else
echo "Environment variable PULL_REQUEST_DRAFT set to a value: created PRs will be draft PRs."
PULL_REQUEST_DRAFT="true"
fi
# Get the name of the action that was triggered
BRANCH=$(jq --raw-output .ref "${GITHUB_EVENT_PATH}");
BRANCH=$(echo "${BRANCH/refs\/heads\//}")
echo "Found branch $BRANCH"
# If it's to the target branch, ignore it
if [[ "${BRANCH}" == "${PULL_REQUEST_BRANCH}" ]]; then
echo "Target and current branch are identical (${BRANCH}), skipping."
else
# If the prefix for the branch matches
if [[ $BRANCH == ${BRANCH_PREFIX}* ]]; then
# Ensure we have a GitHub token
check_credentials
# Pull request body (optional)
if [ -z "${PULL_REQUEST_BODY}" ]; then
echo "No pull request body is set, will use default."
PULL_REQUEST_BODY="This is an automated pull request to update the container collection ${BRANCH}"
echo "Pull request body is ${PULL_REQUEST_BODY}"
fi
# Pull request title (optional)
if [ -z "${PULL_REQUEST_TITLE}" ]; then
echo "No pull request title is set, will use default."
PULL_REQUEST_TITLE="Update container ${BRANCH}"
echo "Pull request title is ${PULL_REQUEST_TITLE}"
fi
create_pull_request $BRANCH $PULL_REQUEST_BRANCH $PULL_REQUEST_BODY $PULL_REQUEST_TITLE $PULL_REQUEST_DRAFT
fi
fi
}
echo "==========================================================================
START: Running Pull Request on Branch Update Action!";
main;
echo "==========================================================================
END: Finished";