diff --git a/README.md b/README.md index 99f2c2b..2a973bf 100644 --- a/README.md +++ b/README.md @@ -22,24 +22,71 @@ jobs: runs-on: ubuntu-latest steps: - name: pull-request-action - uses: vsoch/pull-request-action@master + 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 - - **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`) +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. + + ## Example use Case: Update Registry As an example, I created this action to be intended for an diff --git a/examples/push-example.yml b/examples/push-example.yml new file mode 100644 index 0000000..678c3ae --- /dev/null +++ b/examples/push-example.yml @@ -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" diff --git a/examples/release-example.yml b/examples/release-example.yml new file mode 100644 index 0000000..3e9c380 --- /dev/null +++ b/examples/release-example.yml @@ -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!" diff --git a/pull-request.sh b/pull-request.sh index 4a55f93..18146ee 100755 --- a/pull-request.sh +++ b/pull-request.sh @@ -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,10 +35,10 @@ 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"; } @@ -52,9 +52,9 @@ create_pull_request() { # JSON boolean if [[ "${5}" == "true" ]]; then # if PRs are draft - DRAFT="true"; + DRAFT="true"; else - DRAFT="false"; + DRAFT="false"; fi # Check if the branch already has a pull request open @@ -62,17 +62,17 @@ create_pull_request() { 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 # Post the pull request DATA="{\"title\":${TITLE}, \"body\":${BODY}, \"base\":${TARGET}, \"head\":${SOURCE}, \"draft\":${DRAFT}}" - echo "curl --user ${GITHUB_ACTOR} -X POST --data ${DATA} ${PULLS_URL}" + 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 @@ -88,32 +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 - echo "No explicit preference for draft PR: created PRs will be normal PRs." + printf "No explicit preference for draft PR: created PRs will be normal PRs.\n" PULL_REQUEST_DRAFT="false" else - echo "Environment variable PULL_REQUEST_DRAFT set to a value: created PRs will be draft PRs." + printf "Environment variable PULL_REQUEST_DRAFT set to a value: created PRs will be draft PRs.\n" 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" + # 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 # 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 @@ -127,14 +140,14 @@ main () { 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 - echo "Pull request body is ${PULL_REQUEST_BODY}" + printf "Pull request body is ${PULL_REQUEST_BODY}\n" # Pull request title (optional) if [ -z "${PULL_REQUEST_TITLE}" ]; then - echo "No pull request title is set, will use default." + printf "No pull request title is set, will use default.\n" PULL_REQUEST_TITLE="Update container ${BRANCH}" fi - echo "Pull request title is ${PULL_REQUEST_TITLE}" + 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}"