17 Commits
1.0.1 ... 1.0.2

Author SHA1 Message Date
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
Vanessa Sochat
9c31bb936c adding quotes
Signed-off-by: Vanessa Sochat <vsochat@stanford.edu>
2019-05-20 19:18:03 -04:00
Benjamin Cooper
1e2916c992 Add ability to create draft PRs with env var (#5)
* initial effort to add draft PRs

Document how to use draft PR feature

* make PRs draft anytime env var is explicitly declared

* change draft PR env var name

Signed-off-by: Ben Cooper <bencooper222@gmail.com>

* document new draft env var name

* consolidate draft PR logging block

* actually remove draft pr logging
2019-05-17 17:33:39 -07:00
Vanessasaurus
820608e5d2 Merge pull request #3 from vsoch/add/title-body
adding title and body
2019-03-20 08:31:46 -07:00
Vanessa Sochat
6251c0a094 adding title and body 2019-03-20 10:05:38 -04:00
6 changed files with 225 additions and 49 deletions

View File

@@ -1,4 +1,4 @@
FROM debian:jessie-slim
FROM alpine
# docker build -t vanessa/pull-request-action .
@@ -7,7 +7,7 @@ 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
RUN apk --no-cache add curl wget git bash jq
COPY pull-request.sh /pull-request.sh
RUN chmod u+x /pull-request.sh

100
README.md
View File

@@ -5,31 +5,87 @@ whenever a branch with some prefix is pushed to. The idea is that you can
set up some workflow that pushes content to branches of the repostory,
and you would then want this push reviewed for merge to master.
Here is an example of what to put in your `.github/main.workflow` file to
Here is an example of what to put in your `.github/workflows/pull-request.yml` file to
trigger the action.
```
workflow "Create Pull Request" {
on = "push"
resolves = "Create New Pull Request"
}
action "Create New Pull Request" {
uses = "vsoch/pull-request-action@master"
secrets = [
"GITHUB_TOKEN"
]
env = {
BRANCH_PREFIX = "update/"
PULL_REQUEST_BRANCH = "master"
}
}
```yaml
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@1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: "update/"
PULL_REQUEST_BRANCH: "master"
```
Environment variables include:
## Environment Variables
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_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 | false |
All booleans should be lowercase.
The `GITHUB_TOKEN` secret is required to interact and authenticate with the GitHub API to open
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.
## Examples
Example workflows are provided in [examples](examples), and please contribute any
examples that you might have to help other users! 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://help.github.com/en/actions/reference/development-tools-for-github-actions#set-an-environment-variable-set-env) 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)
::set-env name=PULL_REQUEST_FROM_BRANCH::${PR_BRANCH_FROM}
- name: pull-request-action
uses: vsoch/pull-request-action@1.0.2
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.
- **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.
## Example use Case: Update Registry
@@ -42,4 +98,6 @@ registry to update it.
- the container collection metadata is pushed to a new branch on the registry repository, with namespace matching the GitHub repository, meaning that each GitHub repository always has a unique branch for its content.
- pushing this branch that starts with the prefix (update/<namespace>) triggers the GitHub actions to open the pull request.
If the branch is already open for PR, it updates it.
If the branch is already open for PR, it updates it. Take a look at [this example](https://github.com/singularityhub/registry-org/pull/8)
for the pull request opened when we updated the previous GitHub syntax to the new yaml syntax. Although this
doesn't describe the workflow above, it works equivalently in terms of the triggers.

9
action.yml Normal file
View File

@@ -0,0 +1,9 @@
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'

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@add/support-null-branch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_PREFIX: "update/"
PULL_REQUEST_BRANCH: "master"

View File

@@ -0,0 +1,48 @@
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 "::set-output name=suite_version::${version}"
echo "::set-output name=suite_update_branch::suite_${version}"
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@1.0.2
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

@@ -12,7 +12,7 @@ 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"
HEADER="${HEADER}; application/vnd.github.antiope-preview+json; application/vnd.github.shadow-cat-preview+json"
# URLs
REPO_URL="${BASE}/repos/${GITHUB_REPOSITORY}"
@@ -26,7 +26,7 @@ PULLS_URL=$REPO_URL/pulls
check_credentials() {
if [[ -z "${GITHUB_TOKEN}" ]]; then
echo "You must include the GITHUB_TOKEN as an environment variable."
printf "You must include the GITHUB_TOKEN as an environment variable.\n"
exit 1
fi
@@ -35,37 +35,44 @@ check_credentials() {
check_events_json() {
if [[ ! -f "${GITHUB_EVENT_PATH}" ]]; then
echo "Cannot find Github events file at ${GITHUB_EVENT_PATH}";
printf "Cannot find Github events file at ${GITHUB_EVENT_PATH}\n";
exit 1;
fi
echo "Found ${GITHUB_EVENT_PATH}";
printf "Found ${GITHUB_EVENT_PATH}\n";
}
create_pull_request() {
SOURCE=${1} # from this branch
TARGET=${2} # pull request TO this target
# JSON strings
SOURCE="$(echo -n "${1}" | jq --raw-input --slurp ".")" # from this branch
TARGET="$(echo -n "${2}" | jq --raw-input --slurp ".")" # pull request TO this target
BODY="$(echo -n "${3}" | jq --raw-input --slurp ".")" # this is the content of the message
TITLE="$(echo -n "${4}" | jq --raw-input --slurp ".")" # pull request title
# Check if the branch already has a pull request open
# JSON boolean
if [[ "${5}" == "true" ]]; then # if PRs are draft
DRAFT="true";
else
DRAFT="false";
fi
DATA="{\"base\":\"${TARGET}\", \"head\":\"${SOURCE}\"}"
# 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}"
printf "Response ref: ${PR}\n"
# Option 1: The pull request is already open
if [[ "${PR}" == "${SOURCE}" ]]; then
echo "Pull request from ${SOURCE} to ${TARGET} is already open!"
printf "Pull request from ${SOURCE} to ${TARGET} is already open!\n"
# Option 2: Open a new pull request
else
TITLE="Update container ${SOURCE}"
BODY="This is an automated pull request to update the container collection ${SOURCE}"
# Post the pull request
DATA="{\"title\":\"${TITLE}\", \"base\":\"${TARGET}\", \"head\":\"${SOURCE}\"}"
echo "curl --user ${GITHUB_ACTOR} -X POST --data ${DATA} ${PULLS_URL}"
DATA="{\"title\":${TITLE}, \"body\":${BODY}, \"base\":${TARGET}, \"head\":${SOURCE}, \"draft\":${DRAFT}}"
printf "curl --user ${GITHUB_ACTOR} -X POST --data ${DATA} ${PULLS_URL}\n"
curl -sSL -H "${AUTH_HEADER}" -H "${HEADER}" --user "${GITHUB_ACTOR}" -X POST --data "${DATA}" ${PULLS_URL}
echo $?
fi
@@ -81,24 +88,45 @@ main () {
# User specified branch to PR to, and check
if [ -z "${BRANCH_PREFIX}" ]; then
echo "No branch prefix is set, all branches will be used."
printf "No branch prefix is set, all branches will be used.\n"
BRANCH_PREFIX=""
echo "Branch prefix is $BRANCH_PREFIX"
printf "Branch prefix is $BRANCH_PREFIX\n"
fi
if [ -z "${PULL_REQUEST_BRANCH}" ]; then
PULL_REQUEST_BRANCH=master
fi
echo "Pull requests will go to ${PULL_REQUEST_BRANCH}"
printf "Pull requests will go to ${PULL_REQUEST_BRANCH}\n"
if [ -z "${PULL_REQUEST_DRAFT}" ]; then
printf "No explicit preference for draft PR: created PRs will be normal PRs.\n"
PULL_REQUEST_DRAFT="false"
else
printf "Environment variable PULL_REQUEST_DRAFT set to a value: created PRs will be draft PRs.\n"
PULL_REQUEST_DRAFT="true"
fi
# The user is allowed to explicitly set the name of the branch
if [ -z "${PULL_REQUEST_FROM_BRANCH}" ]; then
printf "PULL_REQUEST_FROM_BRANCH is not set, checking branch in payload.\n"
BRANCH=$(jq --raw-output .ref "${GITHUB_EVENT_PATH}");
BRANCH=$(echo "${BRANCH/refs\/heads\//}")
else
printf "PULL_REQUEST_FROM_BRANCH is set.\n"
BRANCH="${PULL_REQUEST_FROM_BRANCH}"
fi
# At this point, we must have a branch
if [[ "$BRANCH" != "null" ]]; then
printf "Found branch $BRANCH to open PR from\n"
else
printf "No branch in payload, you are required to define PULL_REQUEST_FROM_BRANCH in the environment.\n"
exit 1
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."
printf "Target and current branch are identical (${BRANCH}), skipping.\n"
else
# If the prefix for the branch matches
@@ -106,7 +134,22 @@ main () {
# Ensure we have a GitHub token
check_credentials
create_pull_request $BRANCH $PULL_REQUEST_BRANCH
# 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}"
fi
printf "Pull request body is ${PULL_REQUEST_BODY}\n"
# Pull request title (optional)
if [ -z "${PULL_REQUEST_TITLE}" ]; then
printf "No pull request title is set, will use default.\n"
PULL_REQUEST_TITLE="Update container ${BRANCH}"
fi
printf "Pull request title is ${PULL_REQUEST_TITLE}\n"
create_pull_request "${BRANCH}" "${PULL_REQUEST_BRANCH}" "${PULL_REQUEST_BODY}" "${PULL_REQUEST_TITLE}" "${PULL_REQUEST_DRAFT}"
fi