From 9588602d48cbee030f2e80528d51020e26e38dc9 Mon Sep 17 00:00:00 2001 From: Gary Katsevman Date: Wed, 30 Aug 2017 14:22:04 -0400 Subject: [PATCH] docs(COLLABORATOR_GUIDE): how to release Video.js (#4586) --- COLLABORATOR_GUIDE.md | 157 +++++++++++++-- contrib.json | 442 ------------------------------------------ 2 files changed, 142 insertions(+), 457 deletions(-) delete mode 100644 contrib.json diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 00a0534c..9f7a8ed8 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -259,23 +259,16 @@ git reset --hard upstream/master ## video.js releases -Releasing video.js is partially automated through [`conrib.json`](/contrib.json) scripts. To do a release, you need a couple of things: npm access, GitHub personal access token. +Releasing video.js is partially automated through various scripts. +To do a release, you need a couple of things: npm access, GitHub personal access token. -Releases in video.js are done on npm and GitHub and eventually posted on the CDN. These -are the instructions for the npm/GitHub releases. +Releases in video.js are done on npm and GitHub and eventually posted on the CDN. +These are the instructions for the npm/GitHub releases. When we do a release, we release it as a `next` tag on npm first and then at least a week later, we promote this release to `latest` on npm. ### Getting dependencies -#### Install contrib - -You can install it globally - -```sh -npm i -g contrib/contrib -``` - #### npm access To see who currently has access run this: @@ -285,6 +278,7 @@ npm owner ls video.js ``` If you are a core committer, you can request access to npm from one of the current owners. +Access is managed via an [npm organization][npm org] for [Video.js][vjs npm]. #### GitHub personal access token @@ -292,23 +286,146 @@ This is used to make a GitHub release on videojs. You can get a token from the [ After generating one, make sure to keep it safe because GitHub will not show the token for you again. A good place to save it is Lastpass Secure Notes. +### Deciding what type of version release + +Since we follow the [conventional changelog conventions][conventions], +all commits are prepended with a type, most commonly `feat` and `fix`. +If all the commits are fix or other types such as `test` or `chore`, then the release will be a `patch` release. +If there's even one `feat`, the release will be a `minor` release. +If any commit has a `BREAKING CHANGE` footer, then the release will be a `major` release. +Most common releases will be either `patch` or `minor`. + ### Doing a release -To do a release, check out the master branch +It is also recommended you have a clean clone of Video.js for each release line you want to release. +That means having a folder for master/v6 and one for 5.x. +This is because 5.x and 6.x have different versions expecations for release process and have different dependencies. +Plus, during development you could end up with a dirty repo, so, it just usually easier if you have a clean release repo. + +```sh +# for v6 +git clone git@github.com:videojs/video.js.git videojs-6-release +# for v5 +git clone git@github.com:videojs/video.js.git videojs-5-release +``` + +#### Video.js 6 + +Make sure go to the master branch and grab the latest updates. ```sh git checkout master +git pull origin master ``` -Then run the contrib command to do the next release. Don't forget to provide your GitHub token so the GitHub release goes through. +At this point, you should run `npm install` because dependencies may have changed. + +Then, it's mostly a standard npm package release process with running `npm version`, followed by an `npm publish`. ```sh -VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=my-personal-access-token contrib release next patch +npm version {major|minor|patch} ``` -This makes a patch release, you can also do a `minor` and a `major` release. +Depending on the commits that have been merged, you can choose from `major`, `minor`, or `patch` as the versioning values. +See [deciding what type of version release section](#deciding-what-type-of-version-release). + +Optionally, you can run `git show` now to verify that the version update and CHANGELOG automation worked as expected. + +Afterwards, you want to push the commit and the tag to the repo. +It's necessary to do this before running `npm publish` because our GitHub release automation +relies on the commit being available on GitHub. + +```sh +git push --tags origin master +``` + +Finally, run `npm publish` with an appropriate tag. Don't forget to supply your token. + +```sh +VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=my-personal-access-token npm publish --tag next +``` After it's done, verify that the GitHub release has the correct changelog output. +This is to make sure that the CHANGELOG didn't get garbled and isn't missing pieces. + +If the GitHub release did not work correctly, such as if the GitHub token was not provided, +you can run it manually: + +```sh +VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=123 node build/gh-release.js --prelease +``` + +#### Video.js 5 + +Make sure to go to the 5.x branch and grab the latest updates. + +```sh +git checkout 5.x +git pull origin 5.x +``` + +> *Note:* you probably need to delete v6 tags due to the way that the our CHANGELOG lib works. +> +> You can run this to delete them: +> ```sh +> git tag | grep '^v6' | xargs git tag -d +> ``` +> This will find all tags that start with `^v6` and delete them. + +At this point, you should run `npm install` because dependencies may have changed. + +Then, we have a script that automates most of the steps for publishing. It's a little trickier than publishing v6. + +##### Edit git-semver-tags + +You'll need to edit `git-semver-tags` to support our usage of tags that are not part of the branch. +In the file `node_modules/conventional-changelog-cli/node_modules/conventional-changelog/node_modules/conventional-changelog-core/node_modules/git-semver-tags/index.js`, edit the line that says sets the `cmd` to be: +```js +var cmd = 'git log --all --date-order --decorate --no-color'; +``` + +#### And now for the release + +After getting rid of the tags and getting the latest updates, you can just run the release script: + +```sh +VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=123 ./build/bin/release-next.sh +``` + +It will prompt you for a version change type, so, input `patch` or `minor` or `major`. +See [deciding what type of version release section](#deciding-what-type-of-version-release). + +When it's done building everything, it'll show you the commit that's made via the default pager (i.e., less). +At this point you can verify that things look normal rather than, for example, missing all the CSS. + +After exiting the pager, it'll make sure you want to continue with publishing. + +It will automatically release it as a `next-5` tag on npm. + +Then push the local changes up: + +```sh +git push --tags origin 5.x +``` + +Also, you'll need to copy the CHANGELOG for this version and manually edit the GitHub release to include it. +The current release's CHANGELOG could be copied from the [raw CHANGELOG.md file][raw chg] (or locally from the markdown file) +and then pasted into the correct [GitHub release](https://github.com/videojs/video.js/releases). + +### Deploy as a patch to the CDN + +Follow the steps on the [CDN repo][] for the CDN release process. +If it's a `next` or `next-5` release, only publish the patch version to the CDN. + +When the version gets promoted to `latest` or `latest-5`, the corresponding `minor` or `latest` version should be published to the CDN. + +### Announcement + +An announcement should automatically make it's way to #announcements channel on [slack][], it uses IFTTT and might take a while. + +You can also post it to twitter or ask someone (like @gkatsev) to post on your behalf. + +If it's a large enough release, consider writing a blog post as well. ## Doc credit @@ -319,3 +436,13 @@ This collaborator guide was heavily inspired by [node.js's guide](https://github [pr template]: /.github/PULL_REQUEST_TEMPLATE.md [conventions]: https://github.com/videojs/conventional-changelog-videojs/blob/master/convention.md + +[vjs npm]: http://npmjs.com/org/videojs + +[npm org]: https://docs.npmjs.com/misc/orgs + +[slack]: http://slack.videojs.com + +[CDN repo]: https://github.com/videojs/cdn + +[raw chg]: https://raw.githubusercontent.com/videojs/video.js/5.x/CHANGELOG.md diff --git a/contrib.json b/contrib.json deleted file mode 100644 index 682c74ae..00000000 --- a/contrib.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - "meta": { - "org": "videojs", - "name": "video.js", - "requirements": [ - { - "name": "git", - "info": "http://git-scm.com" - }, - { - "name": "node.js", - "info": "http://nodejs.org" - } - ], - "urls": { - "repo_api": "https://api.github.com/repos/videojs/video.js", - "repo_ui": "https://github.com/videojs/video.js" - }, - "branches": { - "development": "master", - "release": "stable" - } - }, - - "install": { - "desc": "Fork, download, and setup the project", - "steps": [ - { "prompt": "confirm", "desc": "You will now be taken to Github where you will choose an account to fork the project under. Remember which account you choose." }, - { "exec": "open https://github.com/{{meta.org}}/{{meta.name}}/fork" }, - { "prompt": "text", "desc": "Which account did you choose? (no '@')", "id": "owner" }, - { "exec": "git clone https://github.com/{{ owner }}/{{ meta.name }}.git" }, - { "exec": "cd {{ meta.name }}", "desc": "Change to the project directory" }, - { "include": "setup" } - ] - }, - - "setup": { - "desc": "Set up version control and install dependencies", - "steps": [ - [ "git fetch origin", "Get all git branches" ], - [ "git checkout -b stable origin/stable", "Create the stable branch for patches" ], - [ "git remote add upstream https://github.com/{{meta.org}}/{{meta.name}}.git", "Add the upstream project as a remote for pulling changes" ], - [ "git fetch upstream", "Get all upstream branches and changes" ], - { "include": "update all" }, - [ "grunt", "Build the library" ] - ] - }, - - "update": { - "all": { - "steps": [ - { "include": "update stable" }, - { "include": "update master" }, - [ "npm install", "Download dependencies"] - ] - }, - "local": { - "master": { - "steps": [ - [ "git checkout master", "Switch to the development branch" ], - [ "git pull upstream master", "Get any changes to master in the main project" ] - ] - }, - "stable": { - "steps": [ - [ "git checkout stable", "Switch to the release branch" ], - [ "git pull upstream stable", "Get any changes to stable in the main project" ] - ] - }, - "patch": { - "steps": [ - [ "git checkout patch", "Switch to the patch branch" ], - [ "git pull upstream patch", "Get any changes to patch in the main project" ] - ] - } - }, - "remote": { - "master": { - "steps": [ - { "include": "update local master" }, - [ "git push origin master", "Push any changes to your copy of the main project" ] - ] - }, - "stable": { - "steps": [ - { "include": "update local stable" }, - [ "git push origin stable", "Push any changes to your copy of the main project" ] - ] - }, - "patch": { - "steps": [ - { "include": "update local patch" }, - [ "git push origin patch", "Push any changes to your copy of the main project" ] - ] - } - }, - - "master": { - "steps": [ - { "include": "update remote master" } - ] - }, - "stable": { - "steps": [ - { "include": "update remote stable" } - ] - }, - "patch": { - "steps": [ - { "include": "update remote patch" } - ] - } - }, - - "test": "grunt test" , - "watch": "grunt watch", - "server": "grunt connect", - - "feature": { - "desc": "Create a new feature or general enhancement", - "baseBranch": "master", - "start": { - "desc": "Start a new feature", - "steps": [ - { "include": "update {{meta.branches.development}}" }, - { "include": "branch start" } - ] - }, - "save": { - "desc": "Save changes to your feature", - "steps": [{ "include": "branch save" }] - }, - "submit": { - "desc": "Submit a pull request for a feature when it's finished", - "steps": [{ "include": "pull_request submit" }] - }, - "delete": { - "desc": "Delete the current feature branch", - "steps": [{ "include": "branch delete" }] - }, - "review": { - "desc": "Review a submitted feature", - "steps": [{ "include": "pull_request review" }] - }, - "modify": { - "desc": "Modify a submitted feature that you are reviewing", - "steps": [{ "include": "pull_request modify" }] - }, - "accept": { - "desc": "Merge a submitted feature", - "steps": [ - { "include": "update {{meta.branches.development}}" }, - { "include": "pull_request accept" } - ] - } - }, - - "patch": { - "desc": "Create an urgent fix for the latest stable version", - "baseBranch": "stable", - "start": { - "desc": "Start a new patch", - "finished": "Make your changes and then run `contrib patch submit`", - "steps": [ - { "include": "update {{meta.branches.release}}" }, - { "include": "branch start" } - ] - }, - "save": { - "desc": "Save changes to your feature", - "steps": [{ "include": "branch save" }] - }, - "submit": { - "desc": "Submit a pull request for a patch when it's finished", - "steps": [{ "include": "pull_request submit" }] - }, - "delete": { - "desc": "Delete the current patch branch", - "steps": [{ "include": "branch delete" }] - }, - "review": { - "desc": "Review a submitted patch", - "steps": [{ "include": "pull_request review" }] - }, - "modify": { - "desc": "Modify a submitted patch that you are reviewing", - "steps": [{ "include": "pull_request modify" }] - }, - "accept": { - "desc": "Merge a submitted patch", - "steps": [ - { "include": "update {{meta.branches.release}}" }, - { "include": "pull_request accept" }, - [ "git checkout master", "Checkout the developmet branch" ], - [ "git merge stable", "Merge the patch changes" ], - [ "git push upstream master", "Push the development changes" ] - ] - } - }, - - "report": { - "desc": "Submit a bug report", - "steps": [ - { "prompt": "text", "desc": "Create a title that is descriptive of the problem", "id": "title" }, - { "prompt": "text", "desc": "What did you do? (steps to reproduce)", "id": "reproduce" }, - { "prompt": "text", "desc": "What did you expect to happen?", "id": "expected" }, - { "prompt": "text", "desc": "What actually happened?", "id": "actual" }, - { "prompt": "text", "desc": "What version of video.js are you using?", "id": "version" }, - { "prompt": "text", "desc": "Are you using any video.js plugins?", "id": "plugins" }, - { "prompt": "text", "desc": "What browsers/platforms did you experience this in (e.g. Win 7, IE10; Android 4, Chrome;)?", "id": "browsers" }, - { "prompt": "text", "desc": "Is there a URL to a live example, or a jsbin (e.g. http://jsbin.com/axedog/9999/edit)?", "id": "example" }, - { "prompt": "text", "desc": "Are there any other details you'd like to provide?", "id": "details" }, - { "open": "{{meta.urls.repo_ui}}/issues/new?title={{title}}&body=**Steps to reproduce:**\n> {{reproduce}}\n\n**What was expected:**\n> {{expected}}\n\n**What Happened:**\n> {{actual}}\n\n**Video.js Version:**\n> {{version}}\n\n**Plugins:**\n> {{plugins}}\n\n**Browsers experienced on:**\n> {{browsers}}\n\n**Example:**\n> {{example}}\n\n**Other details:**\n> {{details}}" } - ], - "finished": "Thanks for submitting a bug report! One of our contributors will address it as soon as possible." - }, - - "request": { - "desc": "Submit a feature/enhancement request", - "steps": [ - { "prompt": "text", "desc": "Create a title that is descriptive of the enhancement", "id": "title" }, - { "prompt": "text", "desc": "Describe the feature/enhancement (be as detailed as possible so it's clear who, why, and how it would be used)", "id": "describe" }, - { "prompt": "text", "desc": "Is there any existing documentation or related specifications?", "id": "docs" }, - { "prompt": "text", "desc": "Are there any existing examples?", "id": "examples" }, - { "prompt": "confirm", "desc": "You will be redirected to Github where you can submit this issue, OK?" }, - { "open": "{{meta.urls.repo_ui}}/issues/new?title={{ title }}&body=**Describe the feature/enhancement:**\n> {{ describe }}\n\n**Existing docs/specs:**\n> {{ docs }}\n\n**Existing examples:**\n> {{ examples }}" } - ], - "finished": "Thanks for submitting a feature request! One of our contributors will address it as soon as possible." - }, - - "release": { - "desc": "Create and publish releases", - - "patch": { - "release_type": "patch", - "description": "Create a patch release from the release branch (stable)", - "steps": [{ "include": "release run" }] - }, - "minor": { - "description": "Create a minor release from the development branch (master)", - "release_type": "minor", - "steps": [ - { "include": "update local master" }, - { "include": "update local stable" }, - [ "git merge master", "Copy the latest development changes to the release branch" ], - { "include": "release run" }, - [ "git checkout master", "Checkout the developmet branch" ], - [ "git merge stable", "Merge package changes into the dev brach" ], - [ "git push upstream master", "Push the dev branch changes to the repo" ] - ] - }, - - "next": { - "patch": { - "description": "Create a patch release and tag it @next on npm", - "release_type": "patch", - "steps": [{ "include": "release run_next" }] - }, - "minor": { - "description": "Create a minor release and tag it @next on npm", - "release_type": "minor", - "steps": [{ "include": "release run_next" }] - }, - "major": { - "description": "Create a major release and tag it @next on npm", - "release_type": "major", - "steps": [{ "include": "release run_next" }] - } - }, - - "prerelease": { - "release_type": "prerelease", - "steps": [{ "include": "release run_next" }] - }, - - "run_next": { - "steps": [ - { "include": "branch check" }, - { "include": "update local master" }, - [ "git checkout -b temp-release-branch master","Create a temporary branch for the dist" ], - [ "grunt version:{{release_type}}", "Bump package versions" ], - [ "./build/bin/version", "Return the current VJS Version from the package.json file", "version" ], - [ "npm run changelog", "Update the changelog with the new release" ], - [ "git commit -am 'v{{version}}'", "Add and commit the package changes" ], - [ "git checkout master", "Checkout the developmet branch" ], - [ "git merge temp-release-branch", "Merge package changes into the dev brach" ], - [ "git push upstream master", "Push the dev branch changes to the repo" ], - [ "git checkout temp-release-branch", "Checkout the temp branch again" ], - [ "grunt dist", "Build the dist" ], - [ "git add es5 dist --force", "Add the (otherwise ignored) release files" ], - [ "git commit -m 'v{{version}} dist'", "Commit the dist changes" ], - [ "git tag -a v{{version}} -m 'v{{version}}'", "Tag the release" ], - [ "git push upstream --tags", "Push the new tag to the repo" ], - [ "grunt github-release:prerelease", "Create a new pre-release on Github" ], - [ "npm publish --tag next", "Publish to npm as 'next'" ], - [ "git checkout master", "Checkout the developmet branch" ], - [ "git branch -D temp-release-branch", "Delete the temp release branch" ] - ] - }, - - "run": { - "steps": [ - { "include": "branch check" }, - { "include": "update local stable" }, - [ "npm install", "Ensure dependency updates have been installed" ], - [ "grunt test", "Run tests" ], - [ "grunt version:{{release_type}}", "Bump package versions" ], - [ "./build/bin/version", "Return the current VJS Version from the package.json file", "version" ], - [ "npm run changelog", "Update the changelog with the new release" ], - [ "git commit -am 'v{{version}}'", "Add and commit the package changes" ], - [ "git push upstream stable", "Push the release branch changes to the repo" ], - [ "git checkout -b temp-release-branch stable","Create a temporary branch for the dist" ], - [ "grunt dist", "Build the dist" ], - [ "git add es5 dist --force", "Add the (otherwise ignored) release files" ], - [ "git commit -m 'v{{version}} dist'", "Commit the dist changes" ], - [ "git tag -a v{{version}} -m 'v{{version}}'", "Tag the release" ], - [ "git push upstream --tags", "Push the new tag to the repo" ], - [ "npm publish", "Publish to npm" ], - [ "grunt github-release:release", "Create a new release on Github" ], - [ "git checkout stable", "Checkout the developmet branch" ], - [ "git branch -D temp-release-branch", "Delete the temp release branch" ] - ] - } - }, - - "branch": { - "private": true, - - "start": { - "steps": [ - { "prompt": "text", "id": "name", "desc": "Name the branch" }, - { "exec": "git checkout -b {{name}} {{baseBranch}}", "desc": "Create the branch" }, - { "exec": "git push -u origin {{name}}", "desc": "Push the branch to your remote copy of the project" } - ] - }, - "save": { - "desc": "Commit and push changes made to files in the project", - "steps": [ - { "include": "branch confirm" }, - { "prompt": "text", "id": "message", "desc": "Briefly describe the changes made" }, - { "exec": "git add .", "desc": "Add the changes" }, - { "exec": "git commit -m '{{message}}'", "desc": "Commit the changes" }, - { "exec": "git push origin {{branch_name}}", "desc": "Push the changes to your remote copy of the project" } - ] - }, - "check": { - "private": true, - "desc": "Check for unsaved changes", - "steps": [ - { "exec": "git diff --exit-code", "desc": "Ensure there's no unadded changes", "fail": "Make sure all changes have been saved (added and committed) or stashed" }, - { "exec": "git diff --cached --exit-code", "desc": "Ensure there's no uncommitted changes", "fail": "Make sure all changes have been saved (added and committed) or stashed" } - ] - }, - "name": { - "private": true, - "steps": [ - { "exec": "git rev-parse --abbrev-ref HEAD", "desc": "Get the current branch", "id": "branch_name" } - ] - }, - "confirm": { - "private": true, - "steps": [ - { "include": "branch name" }, - { "prompt": "confirm", "desc": "Are you sure *{{branch_name}}* is the correct branch?" } - ] - }, - "delete": { - "desc": "Delete the current branch", - "steps": [ - { "include": "branch confirm" }, - { "exec": "git checkout master", "desc": "Exit the branch being deleted" }, - { "exec": "git branch -D {{branch_name}}", "desc": "Delete the local copy of the branch" }, - { "exec": "git push origin :{{branch_name}}", "desc": "Delete the remote copy of the branch" } - ] - } - }, - - "pull_request": { - "private": true, - "desc": "Pull request related commands", - - "prepare": { - "private": true, - "steps": [ - { "include": "branch check" }, - { "include": "branch confirm" }, - { "include": "test" }, - { "prompt": "text", "desc": "Which github user or org are you submitting from?", "id": "user" } - ] - }, - "submit": { - "desc": "Submit a pull request for when the change is finished", - "steps": [ - { "include": "pull_request prepare" }, - { "open": "{{meta.urls.repo_ui}}/compare/videojs:{{baseBranch}}...{{user}}:{{branch_name}}", "desc": "Open the github pull request page" } - ] - }, - "review": { - "steps": [ - { "prompt": "text", "desc": "What is the the pull request number?", "id": "prNum" }, - { "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" }, - [ "git fetch {{pr.head.repo.ssh_url}} {{pr.head.ref}}", "Get the pull request changes but don't merge them" ], - [ "git merge-base master FETCH_HEAD", "Get the common ancestor commit", "base" ], - [ "git checkout -b review-{{pr.user.login}}-{{pr.head.ref}} {{base}}", "Create a new local branch for the pull request that has a base of the common commit" ], - [ "git merge FETCH_HEAD", "Merge in the pull request changes" ], - [ "npm install", "Install any new dependencies" ], - [ "grunt test", "Build and run tests" ] - ] - }, - "modify": { - "desc": "Submit a modification to a pull request that you are currently reviewing", - "steps": [ - { "include": "pull_request prepare" }, - { "prompt": "text", "desc": "What is the the pull request number?", "id": "prNum" }, - { "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" }, - { "exec": "git push -u origin {{branch_name}}", "desc": "Push the changes to the remote repo" }, - { "open": "https://github.com/{{user}}/video.js/compare/{{pr.head.label}}...{{user}}:{{branch_name}}", "desc": "Open the github pull request page" } - ] - }, - "accept": { - "steps": [ - { "prompt": "text", "id": "prNum", "desc": "What is the the pull request number?" }, - { "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" }, - { "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}/commits", "desc": "Get the PR commits to access author info", "id": "prCommits" }, - [ "git checkout -b {{pr.user.login}}/{{pr.head.ref}} {{pr.base.ref}}", "Create a new branch for merging the changes" ], - [ "git fetch {{pr.head.repo.ssh_url}} {{pr.head.ref}}", "Fetch the changes" ], - [ "git merge --no-commit --squash FETCH_HEAD", "Merge the changes in without committing so they can be squashed" ], - [ "grunt test", "Run tests to make sure they still pass" ], - { "prompt": "text", "id": "line", "desc": "Describe this change in one line" }, - [ "grunt chg-add:'{{{line}}} ([view](https\\://github.com/videojs/video.js/pull/{{prNum}}))'", "Add a line to the changelog" ], - [ "git add CHANGELOG.md", "Add the changlelog change to be committed" ], - [ "git commit -a --author='{{prCommits.[0].commit.author.name}} <{{prCommits.[0].commit.author.email}}>' -m '{{line}}. closes #{{prNum}}'", "Commit the changes" ], - { "prompt": "confirm", "desc": "Does everything look ok?" }, - [ "git checkout {{pr.base.ref}}", "Check out the base branch" ], - [ "git merge {{pr.user.login}}/{{pr.head.ref}}", "Merge the changes" ], - [ "git push origin {{pr.base.ref}}", "Push the changes to your remote copy of the project" ], - [ "git push upstream {{pr.base.ref}}", "Push the changes to the main project" ], - [ "git branch -D {{pr.user.login}}/{{pr.head.ref}}", "Delete the local branch used for merging" ] - ] - } - } -}