diff --git a/.bowerrc b/.bowerrc
new file mode 100644
index 0000000000..cc48978433
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory": "assets/vendor"
+}
diff --git a/.gitignore b/.gitignore
index 404c6a4fcb..482b02b2a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,22 @@
+# File generated by script/bootstrap
+/.bundle/
+/bin
+/vendor/ruby
+/vendor/gems/
+/vendor/cache/ruby/
+/vendor/bundle/
+/node_modules/
+
+# bower brings in *a lot* of files
+/assets/vendor/lunr.js/*
+!/assets/vendor/lunr.js/lunr.js
+!/assets/vendor/lunr.js/lunr.min.js
+
output
tmp
.DS_Store
.bundle
-bin
crash.log
-/vendor/gems/
-/bin/
-/.bundle/
+npm-debug.log
+build.txt
+json-dump
diff --git a/.rbenv-version b/.rbenv-version
deleted file mode 100644
index 77fee73a8c..0000000000
--- a/.rbenv-version
+++ /dev/null
@@ -1 +0,0 @@
-1.9.3
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 0000000000..585940699b
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+2.2.3
diff --git a/.rvmrc b/.rvmrc
deleted file mode 100644
index 883450f260..0000000000
--- a/.rvmrc
+++ /dev/null
@@ -1 +0,0 @@
-rvm ruby-1.9.3
diff --git a/.travis.yml b/.travis.yml
index 11a115a276..00e5561e87 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,13 @@
language: ruby
rvm:
- - 1.9.3
+ - 2.2.3
+cache:
+ directories:
+ - vendor/bundle
+ - node_modules
+sudo: false
+git:
+ depth: 10
+script:
+ - npm install
+ - script/cibuild
diff --git a/Brewfile b/Brewfile
new file mode 100644
index 0000000000..edee70d70f
--- /dev/null
+++ b/Brewfile
@@ -0,0 +1,12 @@
+# Helpers
+tap "github/bootstrap"
+
+# Ruby
+brew "openssl"
+brew "autoconf"
+brew "rbenv"
+brew "ruby-build"
+
+# Node
+brew "nodenv"
+brew "node-build"
diff --git a/CNAME b/CNAME
deleted file mode 100644
index 82c2e93c12..0000000000
--- a/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-developer.github.com
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..f06489cd3c
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,68 @@
+# Contributing to this repository
+
+Use this repository to:
+
+- Report bugs in the documentation.
+- Propose minor updates to content such as typo fixes or clarifications.
+
+If you have a specific question or issues with the API, please [let us know by contacing GitHub Support](https://github.com/contact).
+
+## API Reference Style Guide
+
+The API reference refers to most of the content under . The format of these pages is consistent:
+
+- Endpoints are introduced with an `h2` that describes the API.
+
+ For example: `## List issues for a repository`
+
+- The endpoint itself is wrapped in a codeblock. Capitalize the HTTP verb followed by the endpoint URL.
+
+ For example: `GET /repos/:owner/:repo/issues`
+
+- Introduce the parameters with an `h3`.
+
+ For example: `### Parameters`.
+
+- Write a table with three columns that describes any parameters. The three column headings are:
+ - `Name`, which identifies the name of the parameter.
+ - `Type`, which identifies the type of the parameter.
+ - `Description`, which describes the parameter. Start the description with the phrase **Required.** if it's required. If it's an optional parameter, end the description by listing the default value, if any.
+- Provide the endpoint's response. Responses are stored in the _lib/responses_ folder.
+
+Optionally, you may choose to include an example. Examples should be introduced with an `h3`, and should occur after the parameters are introduced and before the response.
+
+## Platform Guides
+
+Platform Guides refer to the content under . They are longer form content that solve a specific problem for the reader. Each guide follows a three-section pattern:
+
+- An introduction stating any minimum requirements, such as installed dependencies, as well as a description of the problem to solve.
+- A body that breaks down the solution to the problem with clear guidelines. Include code samples that are preceded with how the sample could be used.
+- A conclusion that summarizes that guide and offers next steps for any advanced topics.
+
+Please submit the full sample code for a guide to .
+
+## Versioning content
+
+Our documentation is single sourced and versioned to also apply to GitHub Enterprise users. We use [Liquid tags](https://help.shopify.com/themes/liquid/basics#tags) to include or exclude content for various builds.
+
+Each GitHub Enterprise release represent a "point in time" for the GitHub.com design and feature set. As a result, the APIs available on GitHub Enterprise are also the same APIs available on GitHub.com at the point when the new version was created. For example, if GitHub Enterprise 2.5 was released on December 15th, the APIs available to users are the same as whatever was available on December 15th. 2.5.x patch releases might introduce bug fixes and updates, but will rarely, if ever, contain brand new API endpoints.
+
+When writing API documentation, we filter sections meant just for GitHub.com using Liquid tags, like this:
+
+```
+{% if page.version == 'dotcom' %}
+
+You need to use an HTTP client which supports...
+
+{% endif %}
+```
+
+Similarly, content for GitHub Enterprise is versioned based on the release number, like this:
+
+```
+{% if page.version != 'dotcom' and page.version >= 2.2 %}
+
+If your GitHub Enterprise appliance has LDAP Sync enabled...
+
+{% endif %}
+```
diff --git a/Gemfile b/Gemfile
index 8c97b1d4b0..82dfa0c806 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,23 +1,34 @@
-source "http://rubygems.org"
+source 'http://rubygems.org'
+ruby '2.2.3'
-ruby '1.9.3'
+gem 'nanoc', '~> 4.0'
+gem 'nanoc-conref-fs', '~> 0.5'
-gem 'builder'
-gem 'coderay'
-gem 'kramdown', '~> 0.13.2'
-gem 'mime-types', '~> 1.16'
-gem 'nanoc', '~> 3.4.3'
-gem 'nokogiri', '~> 1.6.0'
-gem 'pygments.rb'
-gem 'rake', '~> 0.9.2'
-gem 'thin'
-gem 'yajl-ruby', '~> 0.8.2'
+# rendering
+gem 'nanoc-html-pipeline', '0.3.3'
+gem 'gemoji', '2.1.0'
+gem 'github-markdown', '0.6.9'
+gem 'html-pipeline-rouge_filter', '~> 1.0'
+gem 'extended-markdown-filter', '~> 0.4'
+gem 'page-toc-filter', '~> 0.0.1'
+
+# for sitemap
+gem 'builder', '~> 3.2'
group :development do
- gem 'adsf'
- gem 'fssm'
+ gem 'nokogiri', '~> 1.6.0'
+ gem 'rake', '10.3.2'
+ gem 'awesome_print', '1.6.1'
+end
+
+group :staging do
+ gem 'jekyll-auth', '~> 2.0'
end
group :test do
- gem 'html-proofer', '~> 0.6.0'
+ gem 'capybara', '2.4.4'
+ gem 'html-proofer', '~> 3.0'
+ gem 'rspec', '3.1'
+ gem 'selenium-webdriver', '2.45.0'
+ gem 'jsonlint', '0.1.0'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 6aa71bfe6a..03314fa408 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,63 +1,196 @@
GEM
remote: http://rubygems.org/
specs:
- adsf (1.2.0)
- rack (>= 1.0.0)
- blankslate (3.1.2)
+ activesupport (4.2.5.2)
+ i18n (~> 0.7)
+ json (~> 1.7, >= 1.7.7)
+ minitest (~> 5.1)
+ thread_safe (~> 0.3, >= 0.3.4)
+ tzinfo (~> 1.1)
+ addressable (2.3.8)
+ awesome_print (1.6.1)
builder (3.2.2)
- coderay (1.1.0)
+ capybara (2.4.4)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ xpath (~> 2.0)
+ childprocess (0.5.8)
+ ffi (~> 1.0, >= 1.0.11)
+ colorator (0.1)
colored (1.2)
- cri (2.4.1)
- colored (>= 1.2)
- daemons (1.1.9)
- ethon (0.6.2)
+ cri (2.7.0)
+ colored (~> 1.2)
+ diff-lcs (1.2.5)
+ dotenv (2.0.2)
+ ethon (0.8.1)
ffi (>= 1.3.0)
- mime-types (~> 1.18)
- eventmachine (1.0.3)
- ffi (1.9.3)
- fssm (0.2.10)
- html-proofer (0.6.0)
+ extended-markdown-filter (0.4.6)
+ html-pipeline (~> 2.0)
+ nokogiri (~> 1.6.4)
+ faraday (0.9.2)
+ multipart-post (>= 1.2, < 3)
+ ffi (1.9.10)
+ gemoji (2.1.0)
+ github-markdown (0.6.9)
+ html-pipeline (2.2.2)
+ activesupport (>= 2, < 5)
+ nokogiri (>= 1.4)
+ html-pipeline-rouge_filter (1.0.2)
+ activesupport
+ html-pipeline (>= 1.11)
+ rouge (~> 1.8)
+ html-proofer (3.0.3)
+ activesupport (~> 4.2)
+ addressable (~> 2.3)
colored (~> 1.2)
- mercenary (~> 0.2.0)
- nokogiri (~> 1.6.0)
- typhoeus (~> 0.6.7)
- kramdown (0.13.8)
- mercenary (0.2.1)
- mime-types (1.25.1)
- mini_portile (0.5.2)
- nanoc (3.4.3)
- cri (~> 2.2)
- nokogiri (1.6.1)
- mini_portile (~> 0.5.0)
- pygments.rb (0.2.3)
- rubypython (>= 0.5.1)
- rack (1.5.2)
- rake (0.9.6)
- rubypython (0.6.3)
- blankslate (>= 2.1.2.3)
- ffi (>= 1.0.7)
- thin (1.6.1)
- daemons (>= 1.0.9)
- eventmachine (>= 1.0.0)
- rack (>= 1.0.0)
- typhoeus (0.6.7)
- ethon (~> 0.6.2)
- yajl-ruby (0.8.3)
+ mercenary (~> 0.3.2)
+ nokogiri (~> 1.5)
+ parallel (~> 1.3)
+ typhoeus (~> 0.7)
+ yell (~> 2.0)
+ i18n (0.7.0)
+ jekyll (3.0.1)
+ colorator (~> 0.1)
+ jekyll-sass-converter (~> 1.0)
+ jekyll-watch (~> 1.1)
+ kramdown (~> 1.3)
+ liquid (~> 3.0)
+ mercenary (~> 0.3.3)
+ rouge (~> 1.7)
+ safe_yaml (~> 1.0)
+ jekyll-auth (2.0.0)
+ colorator (~> 0.1)
+ dotenv (~> 2.0)
+ jekyll (>= 2.0)
+ mercenary (~> 0.3)
+ rack (~> 1.6)
+ rack-ssl-enforcer (~> 0.2)
+ rake (~> 10.3)
+ safe_yaml (~> 1.0)
+ sinatra-index (~> 0.0)
+ sinatra_auth_github (~> 1.1)
+ jekyll-sass-converter (1.3.0)
+ sass (~> 3.2)
+ jekyll-watch (1.3.0)
+ listen (~> 3.0)
+ json (1.8.3)
+ jsonlint (0.1.0)
+ oj (~> 2)
+ kramdown (1.9.0)
+ liquid (3.0.6)
+ listen (3.0.5)
+ rb-fsevent (>= 0.9.3)
+ rb-inotify (>= 0.9)
+ mercenary (0.3.5)
+ mime-types (3.0)
+ mime-types-data (~> 3.2015)
+ mime-types-data (3.2015.1120)
+ mini_portile2 (2.0.0)
+ minitest (5.8.4)
+ multi_json (1.11.2)
+ multipart-post (2.0.0)
+ nanoc (4.1.2)
+ cri (~> 2.3)
+ nanoc-conref-fs (0.6.5)
+ activesupport (~> 4.2)
+ liquid (~> 3.0)
+ nanoc (~> 4.0)
+ nanoc-html-pipeline (0.3.3)
+ html-pipeline (~> 2.0)
+ nanoc (>= 3.1, < 5.0)
+ nokogiri (1.6.7.2)
+ mini_portile2 (~> 2.0.0.rc2)
+ octokit (4.2.0)
+ sawyer (~> 0.6.0, >= 0.5.3)
+ oj (2.14.1)
+ page-toc-filter (0.0.1)
+ html-pipeline (~> 2.0)
+ nokogiri (~> 1.6.4)
+ parallel (1.6.2)
+ rack (1.6.4)
+ rack-protection (1.5.3)
+ rack
+ rack-ssl-enforcer (0.2.9)
+ rack-test (0.6.3)
+ rack (>= 1.0)
+ rake (10.3.2)
+ rb-fsevent (0.9.6)
+ rb-inotify (0.9.5)
+ ffi (>= 0.5.0)
+ rouge (1.10.1)
+ rspec (3.1.0)
+ rspec-core (~> 3.1.0)
+ rspec-expectations (~> 3.1.0)
+ rspec-mocks (~> 3.1.0)
+ rspec-core (3.1.7)
+ rspec-support (~> 3.1.0)
+ rspec-expectations (3.1.2)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.1.0)
+ rspec-mocks (3.1.3)
+ rspec-support (~> 3.1.0)
+ rspec-support (3.1.2)
+ rubyzip (1.1.7)
+ safe_yaml (1.0.4)
+ sass (3.4.19)
+ sawyer (0.6.0)
+ addressable (~> 2.3.5)
+ faraday (~> 0.8, < 0.10)
+ selenium-webdriver (2.45.0)
+ childprocess (~> 0.5)
+ multi_json (~> 1.0)
+ rubyzip (~> 1.0)
+ websocket (~> 1.0)
+ sinatra (1.4.6)
+ rack (~> 1.4)
+ rack-protection (~> 1.4)
+ tilt (>= 1.3, < 3)
+ sinatra-index (0.0.2)
+ sinatra
+ sinatra_auth_github (1.2.0)
+ sinatra (~> 1.0)
+ warden-github (~> 1.2.0)
+ thread_safe (0.3.5)
+ tilt (2.0.1)
+ typhoeus (0.8.0)
+ ethon (>= 0.8.0)
+ tzinfo (1.2.2)
+ thread_safe (~> 0.1)
+ warden (1.2.3)
+ rack (>= 1.0)
+ warden-github (1.2.0)
+ activesupport (> 3.0)
+ octokit (> 2.1.0)
+ warden (> 1.0)
+ websocket (1.2.2)
+ xpath (2.0.0)
+ nokogiri (~> 1.3)
+ yell (2.0.5)
PLATFORMS
ruby
DEPENDENCIES
- adsf
- builder
- coderay
- fssm
- html-proofer (~> 0.6.0)
- kramdown (~> 0.13.2)
- mime-types (~> 1.16)
- nanoc (~> 3.4.3)
+ awesome_print (= 1.6.1)
+ builder (~> 3.2)
+ capybara (= 2.4.4)
+ extended-markdown-filter (~> 0.4)
+ gemoji (= 2.1.0)
+ github-markdown (= 0.6.9)
+ html-pipeline-rouge_filter (~> 1.0)
+ html-proofer (~> 3.0)
+ jekyll-auth (~> 2.0)
+ jsonlint (= 0.1.0)
+ nanoc (~> 4.0)
+ nanoc-conref-fs (~> 0.5)
+ nanoc-html-pipeline (= 0.3.3)
nokogiri (~> 1.6.0)
- pygments.rb
- rake (~> 0.9.2)
- thin
- yajl-ruby (~> 0.8.2)
+ page-toc-filter (~> 0.0.1)
+ rake (= 10.3.2)
+ rspec (= 3.1)
+ selenium-webdriver (= 2.45.0)
+
+BUNDLED WITH
+ 1.11.2
diff --git a/Guardfile b/Guardfile
new file mode 100644
index 0000000000..b5a2d160f1
--- /dev/null
+++ b/Guardfile
@@ -0,0 +1,8 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard 'nanoc' do
+ watch('nanoc.yaml') # Change this to config.yaml if you use the old config file name
+ watch('Rules')
+ watch(%r{^(content|layouts|lib|static)/.*$})
+end
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000..bef83d2b67
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,524 @@
+The code to generate the site (everything excluding the assets, content,
+and layouts directories) as well as the code samples on the site are
+licensed under CC0-1.0.
+
+Site content (everything in the assets, content, and layouts directories,
+excluding files under open source licenses individually marked) is licensed
+under CC-BY-4.0.
+
+Both licenses are reproduced below.
+
+CC0 1.0 Universal
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator and
+subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for the
+purpose of contributing to a commons of creative, cultural and scientific
+works ("Commons") that the public can reliably and without fear of later
+claims of infringement build upon, modify, incorporate in other works, reuse
+and redistribute as freely as possible in any form whatsoever and for any
+purposes, including without limitation commercial purposes. These owners may
+contribute to the Commons to promote the ideal of a free culture and the
+further production of creative, cultural and scientific works, or to gain
+reputation or greater distribution for their Work in part through the use and
+efforts of others.
+
+For these and/or other purposes and motivations, and without any expectation
+of additional consideration or compensation, the person associating CC0 with a
+Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
+and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
+and publicly distribute the Work under its terms, with knowledge of his or her
+Copyright and Related Rights in the Work and the meaning and intended legal
+effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not limited
+to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
+ and translate a Work;
+
+ ii. moral rights retained by the original author(s) and/or performer(s);
+
+ iii. publicity and privacy rights pertaining to a person's image or likeness
+ depicted in a Work;
+
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+
+ v. rights protecting the extraction, dissemination, use and reuse of data in
+ a Work;
+
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation thereof,
+ including any amended or successor version of such directive); and
+
+ vii. other similar, equivalent or corresponding rights throughout the world
+ based on applicable law or treaty, and any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of,
+applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
+unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
+and Related Rights and associated claims and causes of action, whether now
+known or unknown (including existing as well as future claims and causes of
+action), in the Work (i) in all territories worldwide, (ii) for the maximum
+duration provided by applicable law or treaty (including future time
+extensions), (iii) in any current or future medium and for any number of
+copies, and (iv) for any purpose whatsoever, including without limitation
+commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
+the Waiver for the benefit of each member of the public at large and to the
+detriment of Affirmer's heirs and successors, fully intending that such Waiver
+shall not be subject to revocation, rescission, cancellation, termination, or
+any other legal or equitable action to disrupt the quiet enjoyment of the Work
+by the public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be
+judged legally invalid or ineffective under applicable law, then the Waiver
+shall be preserved to the maximum extent permitted taking into account
+Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
+is so judged Affirmer hereby grants to each affected person a royalty-free,
+non transferable, non sublicensable, non exclusive, irrevocable and
+unconditional license to exercise Affirmer's Copyright and Related Rights in
+the Work (i) in all territories worldwide, (ii) for the maximum duration
+provided by applicable law or treaty (including future time extensions), (iii)
+in any current or future medium and for any number of copies, and (iv) for any
+purpose whatsoever, including without limitation commercial, advertising or
+promotional purposes (the "License"). The License shall be deemed effective as
+of the date CC0 was applied by Affirmer to the Work. Should any part of the
+License for any reason be judged legally invalid or ineffective under
+applicable law, such partial invalidity or ineffectiveness shall not
+invalidate the remainder of the License, and in such case Affirmer hereby
+affirms that he or she will not (i) exercise any of his or her remaining
+Copyright and Related Rights in the Work or (ii) assert any associated claims
+and causes of action with respect to the Work, in either case contrary to
+Affirmer's express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+
+ b. Affirmer offers the Work as-is and makes no representations or warranties
+ of any kind concerning the Work, express, implied, statutory or otherwise,
+ including without limitation warranties of title, merchantability, fitness
+ for a particular purpose, non infringement, or the absence of latent or
+ other defects, accuracy, or the present or absence of errors, whether or not
+ discoverable, all to the greatest extent permissible under applicable law.
+
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without limitation
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
+ disclaims responsibility for obtaining any necessary consents, permissions
+ or other rights required for any use of the Work.
+
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to this
+ CC0 or use of the Work.
+
+For more information, please see
+
+
+CC-BY-4.0
+
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+ Considerations for licensors: Our public licenses are
+ intended for use by those authorized to give the public
+ permission to use material in ways otherwise restricted by
+ copyright and certain other rights. Our licenses are
+ irrevocable. Licensors should read and understand the terms
+ and conditions of the license they choose before applying it.
+ Licensors should also secure all rights necessary before
+ applying our licenses so that the public can reuse the
+ material as expected. Licensors should clearly mark any
+ material not subject to the license. This includes other CC-
+ licensed material, or material used under an exception or
+ limitation to copyright. More considerations for licensors:
+ wiki.creativecommons.org/Considerations_for_licensors
+
+ Considerations for the public: By using one of our public
+ licenses, a licensor grants the public permission to use the
+ licensed material under specified terms and conditions. If
+ the licensor's permission is not necessary for any reason--for
+ example, because of any applicable exception or limitation to
+ copyright--then that use is not regulated by the license. Our
+ licenses grant only permissions under copyright and certain
+ other rights that a licensor has authority to grant. Use of
+ the licensed material may still be restricted for other
+ reasons, including because others have copyright or other
+ rights in the material. A licensor may make special requests,
+ such as asking that all changes be marked or described.
+ Although not required by our licenses, you are encouraged to
+ respect those requests where reasonable. More_considerations
+ for the public:
+ wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+ a. Adapted Material means material subject to Copyright and Similar
+ Rights that is derived from or based upon the Licensed Material
+ and in which the Licensed Material is translated, altered,
+ arranged, transformed, or otherwise modified in a manner requiring
+ permission under the Copyright and Similar Rights held by the
+ Licensor. For purposes of this Public License, where the Licensed
+ Material is a musical work, performance, or sound recording,
+ Adapted Material is always produced where the Licensed Material is
+ synched in timed relation with a moving image.
+
+ b. Adapter's License means the license You apply to Your Copyright
+ and Similar Rights in Your contributions to Adapted Material in
+ accordance with the terms and conditions of this Public License.
+
+ c. Copyright and Similar Rights means copyright and/or similar rights
+ closely related to copyright including, without limitation,
+ performance, broadcast, sound recording, and Sui Generis Database
+ Rights, without regard to how the rights are labeled or
+ categorized. For purposes of this Public License, the rights
+ specified in Section 2(b)(1)-(2) are not Copyright and Similar
+ Rights.
+
+ d. Effective Technological Measures means those measures that, in the
+ absence of proper authority, may not be circumvented under laws
+ fulfilling obligations under Article 11 of the WIPO Copyright
+ Treaty adopted on December 20, 1996, and/or similar international
+ agreements.
+
+ e. Exceptions and Limitations means fair use, fair dealing, and/or
+ any other exception or limitation to Copyright and Similar Rights
+ that applies to Your use of the Licensed Material.
+
+ f. Licensed Material means the artistic or literary work, database,
+ or other material to which the Licensor applied this Public
+ License.
+
+ g. Licensed Rights means the rights granted to You subject to the
+ terms and conditions of this Public License, which are limited to
+ all Copyright and Similar Rights that apply to Your use of the
+ Licensed Material and that the Licensor has authority to license.
+
+ h. Licensor means the individual(s) or entity(ies) granting rights
+ under this Public License.
+
+ i. Share means to provide material to the public by any means or
+ process that requires permission under the Licensed Rights, such
+ as reproduction, public display, public performance, distribution,
+ dissemination, communication, or importation, and to make material
+ available to the public including in ways that members of the
+ public may access the material from a place and at a time
+ individually chosen by them.
+
+ j. Sui Generis Database Rights means rights other than copyright
+ resulting from Directive 96/9/EC of the European Parliament and of
+ the Council of 11 March 1996 on the legal protection of databases,
+ as amended and/or succeeded, as well as other essentially
+ equivalent rights anywhere in the world.
+
+ k. You means the individual or entity exercising the Licensed Rights
+ under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+ a. License grant.
+
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+
+ a. reproduce and Share the Licensed Material, in whole or
+ in part; and
+
+ b. produce, reproduce, and Share Adapted Material.
+
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with
+ its terms and conditions.
+
+ 3. Term. The term of this Public License is specified in Section
+ 6(a).
+
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in
+ all media and formats whether now known or hereafter created,
+ and to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including
+ technical modifications necessary to circumvent Effective
+ Technological Measures. For purposes of this Public License,
+ simply making modifications authorized by this Section 2(a)
+ (4) never produces Adapted Material.
+
+ 5. Downstream recipients.
+
+ a. Offer from the Licensor -- Licensed Material. Every
+ recipient of the Licensed Material automatically
+ receives an offer from the Licensor to exercise the
+ Licensed Rights under the terms and conditions of this
+ Public License.
+
+ b. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section 3(a)(1)(A)(i).
+
+ b. Other rights.
+
+ 1. Moral rights, such as the right of integrity, are not
+ licensed under this Public License, nor are publicity,
+ privacy, and/or other similar personality rights; however, to
+ the extent possible, the Licensor waives and/or agrees not to
+ assert any such rights held by the Licensor to the limited
+ extent necessary to allow You to exercise the Licensed
+ Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this
+ Public License.
+
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society
+ under any voluntary or waivable statutory or compulsory
+ licensing scheme. In all other cases the Licensor expressly
+ reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+ a. Attribution.
+
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+
+ a. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if
+ designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of
+ warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+
+ b. indicate if You modified the Licensed Material and
+ retain an indication of any previous modifications; and
+
+ c. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section 3(a)(1)(A) to the extent
+ reasonably practicable.
+
+ 4. If You Share Adapted Material You produce, the Adapter's
+ License You apply must not prevent recipients of the Adapted
+ Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+ to extract, reuse, reproduce, and Share all or a substantial
+ portion of the contents of the database;
+
+ b. if You include all or a substantial portion of the database
+ contents in a database in which You have Sui Generis Database
+ Rights, then the database in which You have Sui Generis Database
+ Rights (but not its individual contents) is Adapted Material; and
+
+ c. You must comply with the conditions in Section 3(a) if You Share
+ all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+ a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+ EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+ AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+ IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+ WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+ ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+ KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+ ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+ b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+ TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+ NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+ INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+ COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+ USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+ DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+ IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+ c. The disclaimer of warranties and limitation of liability provided
+ above shall be interpreted in a manner that, to the extent
+ possible, most closely approximates an absolute disclaimer and
+ waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+ a. This Public License applies for the term of the Copyright and
+ Similar Rights licensed here. However, if You fail to comply with
+ this Public License, then Your rights under this Public License
+ terminate automatically.
+
+ b. Where Your right to use the Licensed Material has terminated under
+ Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the
+ violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any
+ right the Licensor may have to seek remedies for Your violations
+ of this Public License.
+
+ c. For the avoidance of doubt, the Licensor may also offer the
+ Licensed Material under separate terms or conditions or stop
+ distributing the Licensed Material at any time; however, doing so
+ will not terminate this Public License.
+
+ d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+ License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+ a. The Licensor shall not be bound by any additional or different
+ terms or conditions communicated by You unless expressly agreed.
+
+ b. Any arrangements, understandings, or agreements regarding the
+ Licensed Material not stated herein are separate from and
+ independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+ a. For the avoidance of doubt, this Public License does not, and
+ shall not be interpreted to, reduce, limit, restrict, or impose
+ conditions on any use of the Licensed Material that could lawfully
+ be made without permission under this Public License.
+
+ b. To the extent possible, if any provision of this Public License is
+ deemed unenforceable, it shall be automatically reformed to the
+ minimum extent necessary to make it enforceable. If the provision
+ cannot be reformed, it shall be severed from this Public License
+ without affecting the enforceability of the remaining terms and
+ conditions.
+
+ c. No term or condition of this Public License will be waived and no
+ failure to comply consented to unless expressly agreed to by the
+ Licensor.
+
+ d. Nothing in this Public License constitutes or may be interpreted
+ as a limitation upon, or waiver of, any privileges and immunities
+ that apply to the Licensor or You, including from the legal
+ processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public
+licenses. Notwithstanding, Creative Commons may elect to apply one of
+its public licenses to material it publishes and in those instances
+will be considered the “Licensor.” The text of the Creative Commons
+public licenses is dedicated to the public domain under the CC0 Public
+Domain Dedication. Except for the limited purpose of indicating that
+material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the
+public licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/README.md b/README.md
index a65cc87de4..d73feafde0 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,74 @@
# developer.github.com
-This is a GitHub API resource built with [nanoc][nanoc].
+**NOTE: The developer.github.com website is no longer open-source.**
-All submissions are welcome. To submit a change, fork this repo, commit your changes, and send us a [pull request](http://help.github.com/send-pull-requests/).
+We have moved this repository into [our github-archive organization](https://github.com/github-archive) to signify that we are no longer accepting open-source contributions to this repository. We want to thank the hundreds of contributors for their assistance over the years.
-## Setup
+The decision to close-source the site stems from a variety of reasons:
-Ruby 1.9 is required to build the site.
+1. We actually already _have_ a close-sourced site, which is where we wrote documentation for unreleased features. We designed additional tooling to support this workflow, but updating the documentation is a process we'd like to simplify.
+2. We believe that any open-source project—be it documentation or software—ought to have dedicated maintainers. It became difficult to keep this repository open-source because it was maintained by the best efforts of a small group of people. Closing the site allows us to focus on what's important, without feeling guilty at missing reviews from open-source contributors.
-Get the nanoc gem, plus kramdown for Markdown parsing:
+We think that the tooling we used to build this site is pretty interesting, so we're not getting rid of everything. We hope that what remains can be used as a source of inspiration for your own static site.
-```sh
-$ bundle install
+If you find something that needs to be fixed, you can always [contact our terrific Support team](https://github.com/contact?form%5Bsubject%5D=Moving+developer.github.com+to+github-archive).
+
+Thank you!
+
+* * *
+
+This was the GitHub API documentation, built with [Nanoc][nanoc].
+
+## Development
+
+You can fetch the latest dependencies by opening the command line and running `script/bootstrap`:
+
+``` sh
+$ script/bootstrap
+==> Installing gem dependencies…
+==> Installing npm dependencies…
```
-You can see the available commands with nanoc:
+You'll need Ruby and Node installed on your system. The required versions for each of these languages can be found in the *.ruby-version* and *package.json* files, respectively.
+
+You can run `bundle exec rake build` to generate the site, but it's often more useful
+to simply build the server *and* start the site at the same time.
-```sh
-$ bundle exec nanoc -h
+Nanoc compiles the site into static files living in `output`. It's
+smart enough not to try to compile unchanged files.
+
+You can start the site with `script/server`:
+
+``` sh
+$ script/server
+Loading site data...
+Compiling site...
+ create [0.28s] output/index.html
+ create [1.31s] output/v3/gists/comments/index.html
+ identical [1.92s] output/v3/gists/index.html
+ identical [0.25s] output/v3/issues/comments/index.html
+ update [0.99s] output/v3/issues/labels/index.html
+ update [0.05s] output/v3/index.html
+ …
+
+Site compiled in 5.81s.
```
-Nanoc has [some nice documentation](http://nanoc.ws/docs/tutorial/) to get you started. Though if you're mainly concerned with editing or adding content, you won't need to know much about nanoc.
+The site is hosted at `http://localhost:4000`.
+
+Nanoc has [some nice documentation](http://nanoc.ws/docs/tutorial/) to get you started. Though if you're mainly concerned with editing or adding content, you won't need to know much about Nanoc.
+
+[nanoc]: http://nanoc.ws/
-[nanoc]: http://nanoc.stoneship.org/
+### Enterprise
+
+To generate the `/enterprise` versions, pass in the Enterprise version to `script/server`. For example:
+
+``` sh
+$ script/server 2.6
+```
+
+Note that live reloading is not available for Enterprise documentation.
## Styleguide
@@ -31,7 +77,6 @@ API docs should look like:
# API title
- * TOC
{:toc}
## API endpoint title
@@ -55,7 +100,7 @@ API docs should look like:
<%= headers 200, :pagination => default_pagination_rels, 'X-Custom-Header' => "value" %>
<%= json :resource_name %>
-**Note**: We're using [Kramdown Markdown extensions](http://kramdown.rubyforge.org/syntax.html), such as definition lists.
+**Note**: We're using [Kramdown Markdown extensions](http://kramdown.gettalong.org/syntax.html), such as definition lists.
### JSON Responses
@@ -75,73 +120,57 @@ Some actions return arrays. You can modify the JSON by passing a block:
<%= json(:issue) { |hash| [hash] } %>
```
-### Terminal blocks
-
-You can specify terminal blocks with `pre.terminal` elements. (It'd be
-nice if Markdown could do this more cleanly.)
+There is also a rake task for generating JSON files from the sample responses in the documentation:
-```html
-
-$ curl foobar
-....
-
+``` sh
+$ rake generate_json_from_responses
```
-This is not a `curl` tutorial though. Not every API call needs
-to show how to access it with `curl`.
-
-## Development
+The generated files will end up in *json-dump/*.
-Nanoc compiles the site into static files living in `./output`. It's
-smart enough not to try to compile unchanged files:
+### Terminal blocks
-```sh
-$ bundle exec nanoc compile
-Loading site data...
-Compiling site...
- identical [0.00s] output/css/960.css
- identical [0.00s] output/css/pygments.css
- identical [0.00s] output/css/reset.css
- identical [0.00s] output/css/styles.css
- identical [0.00s] output/css/uv_active4d.css
- update [0.28s] output/index.html
- update [1.31s] output/v3/gists/comments/index.html
- update [1.92s] output/v3/gists/index.html
- update [0.25s] output/v3/issues/comments/index.html
- update [0.99s] output/v3/issues/labels/index.html
- update [0.49s] output/v3/issues/milestones/index.html
- update [0.50s] output/v3/issues/index.html
- update [0.05s] output/v3/index.html
+You can specify terminal blocks by using the `command-line` syntax highlighting.
-Site compiled in 5.81s.
-```
+ ``` command-line
+ $ curl foobar
+ ```
-You can setup whatever you want to view the files. If using the adsf
-gem (as listed in the Gemfile), you can start Webrick:
+You can use certain characters, like `$` and `#`, to emphasize different parts
+of commands.
-```sh
-$ bundle exec nanoc view
-$ open http://localhost:3000
-```
+ ``` command-line
+ # call foobar
+ $ curl foobar
+ ....
+ ```
-Compilation times got you down? Use `autocompile`!
+For more information, see [the reference documentation](https://github.com/gjtorikian/extended-markdown-filter#command-line-highlighting).
-```sh
-$ bundle exec nanoc autocompile
-```
+## Licenses
-This starts a web server too, so there's no need to run `nanoc view`.
-One thing: remember to add trailing slashes to all nanoc links!
+The code to generate the site (everything excluding the assets, content,
+and layouts directories) as well as the code samples on the site are
+licensed under
+[CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode).
+CC0 waives all copyright restrictions but does not grant you any trademark
+permissions.
-## Deploy
+Site content (everything in the assets, content, and layouts directories,
+excluding files under open source licenses individually marked) is licensed
+under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/). CC-BY-4.0
+gives you permission to use content for almost any purpose but does not grant
+you any trademark permissions, so long as you note the license and give credit,
+such as follows:
-```sh
-$ bundle exec rake publish
-```
+> Content based on
+> developer.github.com
+> used under the
+> CC-BY-4.0
+> license.
-## TODO
+This means you can use the code and content in this repository except for
+GitHub trademarks in your own projects.
-* Integrate through a simple hurl.it app for live API calls.
-* Maybe add a nice TOC at the top of each page.
-* Write a task for verifying JSON Resource examples against the actual
- API.
+When you contribute to this repository you are doing so under the above
+licenses.
diff --git a/Rakefile b/Rakefile
index 79ac9dddb6..066f1ab736 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,16 +1,58 @@
-require 'nanoc3/tasks'
-require 'html/proofer'
+require_relative 'lib/resources'
+require 'tmpdir'
+
+Dir.glob('tasks/**/*.rake').each { |r| load r }
task :default => [:test]
-desc "Compile the site"
-task :compile do
- `nanoc compile`
+desc 'Builds the site'
+task :build do
+ if ENV['RACK_ENV'] == 'test'
+ begin
+ sh 'node_modules/gulp/bin/gulp.js build > build.txt'
+ rescue StandardError => e
+ puts 'uh oh'
+ $stderr.puts `cat build.txt`
+ raise e
+ end
+ else
+ sh 'node_modules/gulp/bin/gulp.js build'
+ end
end
desc "Test the output"
-task :test => [:clean, :remove_output_dir, :compile] do
- HTML::Proofer.new("./output").run
+task :test => [:remove_tmp_dir, :remove_output_dir, :build] do
+ Rake::Task['spec'].invoke
+ Rake::Task['run_proofer'].invoke
+end
+
+desc "Run Rspec"
+task :spec do
+ require 'rspec/core/rake_task'
+ RSpec::Core::RakeTask.new(:rspec)
+ Rake::Task['rspec'].invoke
+end
+
+desc "Run the HTML-Proofer"
+task :run_proofer do
+ require 'html-proofer'
+ ignored_links = [%r{www.w3.org}, /api\.github\.com/, /import\.github\.com/]
+ # swap versionless Enterprise articles with versioned paths
+ url_swap = {
+ %r{help.github.com/enterprise/admin/} => "help.github.com/enterprise/#{config[:versions][0]}/admin/",
+ %r{help.github.com/enterprise/user/} => "help.github.com/enterprise/#{config[:versions][0]}/user/"
+ }
+ proofer_opts = {
+ :url_ignore => ignored_links,
+ :url_swap => url_swap,
+ :parallel => { :in_processes => 5 }
+ }
+ HTMLProofer.check_directory("./output", proofer_opts).run
+end
+
+desc "Remove the tmp dir"
+task :remove_tmp_dir do
+ FileUtils.rm_r('tmp') if File.exist?('tmp')
end
desc "Remove the output dir"
@@ -19,43 +61,51 @@ task :remove_output_dir do
end
# Prompt user for a commit message; default: P U B L I S H :emoji:
-def commit_message
+def commit_message(no_commit_msg = false)
publish_emojis = [':boom:', ':rocket:', ':metal:', ':bulb:', ':zap:',
':sailboat:', ':gift:', ':ship:', ':shipit:', ':sparkles:', ':rainbow:']
default_message = "P U B L I S H #{publish_emojis.sample}"
- print "Enter a commit message (default: '#{default_message}'): "
- STDOUT.flush
- mesg = STDIN.gets.chomp.strip
+ unless no_commit_msg
+ print "Enter a commit message (default: '#{default_message}'): "
+ STDOUT.flush
+ mesg = STDIN.gets.chomp.strip
+ end
- mesg = default_message if mesg == ''
+ mesg = default_message if mesg.nil? || mesg == ''
+ mesg << "\nGenerated from #{ENV['BUILD_SHA']}" if ENV['BUILD_SHA']
mesg.gsub(/'/, '') # Allow this to be handed off via -m '#{message}'
end
+namespace :assets do
+ task :precompile => [:build] do
+ sh 'mv output _site/'
+ end
+end
+
desc "Publish to http://developer.github.com"
-task :publish => [:clean, :remove_output_dir] do
- mesg = commit_message
-
- sh "nanoc compile"
-
- ENV['GIT_DIR'] = File.expand_path(`git rev-parse --git-dir`.chomp)
- old_sha = `git rev-parse refs/remotes/origin/gh-pages`.chomp
- Dir.chdir('output') do
- ENV['GIT_INDEX_FILE'] = gif = '/tmp/dev.gh.i'
- ENV['GIT_WORK_TREE'] = Dir.pwd
- File.unlink(gif) if File.file?(gif)
- `git add -A`
- tsha = `git write-tree`.strip
- puts "Created tree #{tsha}"
- if old_sha.size == 40
- csha = `git commit-tree #{tsha} -p #{old_sha} -m '#{mesg}'`.strip
- else
- csha = `git commit-tree #{tsha} -m '#{mesg}'`.strip
- end
- puts "Created commit #{csha}"
- puts `git show #{csha} --stat`
- puts "Updating gh-pages from #{old_sha}"
- `git update-ref refs/heads/gh-pages #{csha}`
- `git push origin gh-pages`
+task :publish, [:no_commit_msg] => [:remove_tmp_dir, :remove_output_dir, :build] do |t, args|
+ message = commit_message(args[:no_commit_msg])
+
+ Dir.mktmpdir do |tmp|
+ system "mv output/* #{tmp}"
+ system "cp .gitignore #{tmp}"
+ system 'git checkout gh-pages'
+ system "rsync -av #{tmp}/ ."
+ system 'git add .'
+ system "git commit -am #{message.shellescape}"
+ system 'git push origin gh-pages --force'
+ system 'git checkout master'
end
end
+
+desc "Generate JSON from the sample responses"
+task :generate_json_from_responses do
+ Dir[File.join(File.dirname(__FILE__), 'lib', 'responses', '*.rb')].each { |file| load file }
+ FileUtils.mkdir_p(File.join(File.dirname(__FILE__), 'json-dump'))
+ GitHub::Resources::Responses.constants.each { |constant|
+ File.open('json-dump/' + constant.to_s + '.json', 'w') { |file|
+ file.write(JSON.pretty_generate(GitHub::Resources::Helpers.get_resource(constant)))
+ }
+ }
+end
diff --git a/Rules b/Rules
index bac778fedc..c04b63886d 100755
--- a/Rules
+++ b/Rules
@@ -4,84 +4,88 @@
#
# * The order of rules is important: for each item, only the first matching
# rule is applied.
-#
-# * Item identifiers start and end with a slash (e.g. “/about/” for the file
-# “content/about.html”). To select all children, grandchildren, … of an
-# item, use the pattern “/about/*/”; “/about/*” will also select the parent,
-# because “*” matches zero or more characters.
-# Reset search-index by deleting it every time
preprocess do
- File.delete("output/search-index.json") if File.exists?("output/search-index.json")
+ add_created_at_attribute
+ add_kind_attribute
+ create_individual_blog_pages
+ generate_redirects(config[:redirects])
+ @items.each do |item|
+ ConrefFS.apply_attributes(@config, item, :default)
+ end
end
-compile '/static/*' do
+passthrough '/CNAME'
+
+compile '/changes.atom' do
+ filter :erb
end
-compile '/CNAME/' do
+compile '/integrations-directory/*' do
+ filter :'conref-fs-filter'
+ filter :erb
+ filter :html_pipeline, @config[:pipeline_config]
+ layout item[:layout] || '/integrations-directory.*'
end
-compile '/feed/' do
+compile '/v3{.*,/**/*}' do
+ filter :'conref-fs-filter'
filter :erb
- filter :kramdown, :toc_levels => [2]
+ filter :html_pipeline, @config[:pipeline_config]
+ layout(item[:layout] ? "/#{item[:layout]}.*" : '/api.*')
end
-compile '/v3/*' do
- filter :search
+compile "/changes/20*" do
+ filter :'conref-fs-filter'
filter :erb
- filter :kramdown, :toc_levels => [2]
- filter :colorize_syntax,
- :colorizers => {:javascript => :pygmentsrb}
- layout item[:layout] || 'api'
+ filter :html_pipeline, @config[:pipeline_config]
+ layout '/changes.*'
+ layout(item[:layout] ? "/#{item[:layout]}.*" : '/blog.*')
end
-%w(v3 */).each do |version|
- compile "/changes/#{version}" do
- filter :erb
- filter :kramdown, :toc_levels => [2]
- filter :colorize_syntax,
- :colorizers => {:javascript => :pygmentsrb}
- layout 'changes' if version[0] == '*'
- layout item[:layout] || 'blog'
- end
+compile '/guides/**/*' do
+ filter :'conref-fs-filter'
+ filter :html_pipeline, @config[:pipeline_config]
+ filter :erb
+ layout(item[:layout] ? "/#{item[:layout]}.*" : '/guides.*')
end
-compile '/guides/*' do
- filter :kramdown, :toc_levels => [2]
+compile '/webhooks/**/*' do
+ filter :'conref-fs-filter'
filter :erb
- filter :colorize_syntax, :default_colorizer => :pygmentsrb
- layout item[:layout] || 'guides'
+ filter :html_pipeline, @config[:pipeline_config]
+ layout(item[:layout] ? "/#{item[:layout]}.*" : '/webhooks.*')
end
-compile '/webhooks/*' do
- filter :kramdown, :toc_levels => [2]
+compile '/search/search-index.json' do
filter :erb
- filter :colorize_syntax, :default_colorizer => :pygmentsrb
- layout item[:layout] || 'webhooks'
end
-compile '*' do
+compile '/**/*' do
+ filter :'conref-fs-filter'
filter :erb
- filter :kramdown, :toc_levels => [2]
- filter :colorize_syntax,
- :colorizers => {:javascript => :pygmentsrb}
- layout item[:layout] || 'default'
+ filter :html_pipeline, @config[:pipeline_config]
+ layout(item[:layout] ? "/#{item[:layout]}.*" : '/default.*')
end
-route '/static/*' do
- item.identifier[7..-2]
+route '/changes.atom' do
+ '/changes.atom'
end
-route '/CNAME/' do
- '/CNAME'
+route '/search/search-index.json' do
+ item.identifier.to_s
end
-route '/feed' do
- '/changes.atom'
+route '/**/index.*' do
+ item.identifier.without_ext + '.html'
+end
+
+route '/404.html' do
+ '/404.html'
end
-route '*' do
- item.identifier + 'index.html'
+route '/**/*' do
+ item.identifier.without_ext + '/index.html'
end
-layout '*', :erb
+layout '/**/*', :erb
diff --git a/favicon.ico b/assets/favicon.ico
similarity index 100%
rename from favicon.ico
rename to assets/favicon.ico
diff --git a/assets/images/add_github_autodeploy_service.png b/assets/images/add_github_autodeploy_service.png
new file mode 100644
index 0000000000..0a09f51f54
Binary files /dev/null and b/assets/images/add_github_autodeploy_service.png differ
diff --git a/assets/images/add_heroku_autodeploy_service.png b/assets/images/add_heroku_autodeploy_service.png
new file mode 100644
index 0000000000..389b3942c6
Binary files /dev/null and b/assets/images/add_heroku_autodeploy_service.png differ
diff --git a/static/shared/images/callout-earth-static.png b/assets/images/callout-earth-static.png
similarity index 100%
rename from static/shared/images/callout-earth-static.png
rename to assets/images/callout-earth-static.png
diff --git a/shared/images/cancel.png b/assets/images/cancel.png
similarity index 100%
rename from shared/images/cancel.png
rename to assets/images/cancel.png
diff --git a/shared/images/cancel@2x.png b/assets/images/cancel@2x.png
similarity index 100%
rename from shared/images/cancel@2x.png
rename to assets/images/cancel@2x.png
diff --git a/assets/images/deploy-keys.png b/assets/images/deploy-keys.png
new file mode 100644
index 0000000000..5208ba9997
Binary files /dev/null and b/assets/images/deploy-keys.png differ
diff --git a/static/shared/images/electrocat.png b/assets/images/electrocat.png
similarity index 100%
rename from static/shared/images/electrocat.png
rename to assets/images/electrocat.png
diff --git a/static/shared/images/electrocat@2x.png b/assets/images/electrocat@2x.png
similarity index 100%
rename from static/shared/images/electrocat@2x.png
rename to assets/images/electrocat@2x.png
diff --git a/shared/images/expand-arrows.png b/assets/images/expand-arrows.png
similarity index 100%
rename from shared/images/expand-arrows.png
rename to assets/images/expand-arrows.png
diff --git a/shared/images/expand-arrows@2x.png b/assets/images/expand-arrows@2x.png
similarity index 100%
rename from shared/images/expand-arrows@2x.png
rename to assets/images/expand-arrows@2x.png
diff --git a/images/feed-icon.png b/assets/images/feed-icon.png
similarity index 100%
rename from images/feed-icon.png
rename to assets/images/feed-icon.png
diff --git a/images/feed-icon@2x.png b/assets/images/feed-icon@2x.png
similarity index 100%
rename from images/feed-icon@2x.png
rename to assets/images/feed-icon@2x.png
diff --git a/static/shared/images/gdp-callout-static.png b/assets/images/gdp-callout-static.png
similarity index 100%
rename from static/shared/images/gdp-callout-static.png
rename to assets/images/gdp-callout-static.png
diff --git a/shared/images/gundamcat.png b/assets/images/gundamcat.png
similarity index 100%
rename from shared/images/gundamcat.png
rename to assets/images/gundamcat.png
diff --git a/shared/images/gundamcat@2x.png b/assets/images/gundamcat@2x.png
similarity index 100%
rename from shared/images/gundamcat@2x.png
rename to assets/images/gundamcat@2x.png
diff --git a/static/shared/images/header-animation-short-loop.gif b/assets/images/header-animation-short-loop.gif
similarity index 100%
rename from static/shared/images/header-animation-short-loop.gif
rename to assets/images/header-animation-short-loop.gif
diff --git a/static/shared/images/header-animation.gif b/assets/images/header-animation.gif
similarity index 100%
rename from static/shared/images/header-animation.gif
rename to assets/images/header-animation.gif
diff --git a/shared/images/header.png b/assets/images/header.png
similarity index 100%
rename from shared/images/header.png
rename to assets/images/header.png
diff --git a/shared/images/header@2x.png b/assets/images/header@2x.png
similarity index 100%
rename from shared/images/header@2x.png
rename to assets/images/header@2x.png
diff --git a/images/logo_developer.png b/assets/images/logo_developer.png
similarity index 100%
rename from images/logo_developer.png
rename to assets/images/logo_developer.png
diff --git a/images/logo_developer@2x.png b/assets/images/logo_developer@2x.png
similarity index 100%
rename from images/logo_developer@2x.png
rename to assets/images/logo_developer@2x.png
diff --git a/assets/images/mark@2x.png b/assets/images/mark@2x.png
new file mode 100644
index 0000000000..ea6ff545a2
Binary files /dev/null and b/assets/images/mark@2x.png differ
diff --git a/assets/images/oauth_prompt.png b/assets/images/oauth_prompt.png
new file mode 100644
index 0000000000..387d022505
Binary files /dev/null and b/assets/images/oauth_prompt.png differ
diff --git a/images/pagination_sample.png b/assets/images/pagination_sample.png
similarity index 100%
rename from images/pagination_sample.png
rename to assets/images/pagination_sample.png
diff --git a/assets/images/payload_request_tab.png b/assets/images/payload_request_tab.png
new file mode 100644
index 0000000000..2fddc6d189
Binary files /dev/null and b/assets/images/payload_request_tab.png differ
diff --git a/assets/images/payload_response_tab.png b/assets/images/payload_response_tab.png
new file mode 100644
index 0000000000..f2507841db
Binary files /dev/null and b/assets/images/payload_response_tab.png differ
diff --git a/assets/images/personal_token.png b/assets/images/personal_token.png
new file mode 100644
index 0000000000..188873d592
Binary files /dev/null and b/assets/images/personal_token.png differ
diff --git a/images/posts/create-repo-init.png b/assets/images/posts/create-repo-init.png
similarity index 100%
rename from images/posts/create-repo-init.png
rename to assets/images/posts/create-repo-init.png
diff --git a/images/posts/default-branch.png b/assets/images/posts/default-branch.png
similarity index 100%
rename from images/posts/default-branch.png
rename to assets/images/posts/default-branch.png
diff --git a/images/posts/submodule-links.png b/assets/images/posts/submodule-links.png
similarity index 100%
rename from images/posts/submodule-links.png
rename to assets/images/posts/submodule-links.png
diff --git a/images/professorcat.png b/assets/images/professorcat.png
similarity index 100%
rename from images/professorcat.png
rename to assets/images/professorcat.png
diff --git a/images/professorcat@2x.png b/assets/images/professorcat@2x.png
similarity index 100%
rename from images/professorcat@2x.png
rename to assets/images/professorcat@2x.png
diff --git a/static/shared/images/rocketship.png b/assets/images/rocketship.png
similarity index 100%
rename from static/shared/images/rocketship.png
rename to assets/images/rocketship.png
diff --git a/static/shared/images/rocketship@2x.png b/assets/images/rocketship@2x.png
similarity index 100%
rename from static/shared/images/rocketship@2x.png
rename to assets/images/rocketship@2x.png
diff --git a/shared/images/search.png b/assets/images/search.png
similarity index 100%
rename from shared/images/search.png
rename to assets/images/search.png
diff --git a/shared/images/search@2x.png b/assets/images/search@2x.png
similarity index 100%
rename from shared/images/search@2x.png
rename to assets/images/search@2x.png
diff --git a/images/status-icon-good.png b/assets/images/status-icon-good.png
similarity index 100%
rename from images/status-icon-good.png
rename to assets/images/status-icon-good.png
diff --git a/images/status-icon-good@2x.png b/assets/images/status-icon-good@2x.png
similarity index 100%
rename from images/status-icon-good@2x.png
rename to assets/images/status-icon-good@2x.png
diff --git a/images/status-icon-major.png b/assets/images/status-icon-major.png
similarity index 100%
rename from images/status-icon-major.png
rename to assets/images/status-icon-major.png
diff --git a/images/status-icon-major@2x.png b/assets/images/status-icon-major@2x.png
similarity index 100%
rename from images/status-icon-major@2x.png
rename to assets/images/status-icon-major@2x.png
diff --git a/images/status-icon-minor.png b/assets/images/status-icon-minor.png
similarity index 100%
rename from images/status-icon-minor.png
rename to assets/images/status-icon-minor.png
diff --git a/images/status-icon-minor@2x.png b/assets/images/status-icon-minor@2x.png
similarity index 100%
rename from images/status-icon-minor@2x.png
rename to assets/images/status-icon-minor@2x.png
diff --git a/images/status-icon-unknown.png b/assets/images/status-icon-unknown.png
similarity index 100%
rename from images/status-icon-unknown.png
rename to assets/images/status-icon-unknown.png
diff --git a/images/status-icon-unknown@2x.png b/assets/images/status-icon-unknown@2x.png
similarity index 100%
rename from images/status-icon-unknown@2x.png
rename to assets/images/status-icon-unknown@2x.png
diff --git a/assets/images/webhook_sample_url.png b/assets/images/webhook_sample_url.png
new file mode 100644
index 0000000000..abf4083d6b
Binary files /dev/null and b/assets/images/webhook_sample_url.png differ
diff --git a/assets/images/webhook_secret_token.png b/assets/images/webhook_secret_token.png
new file mode 100644
index 0000000000..6d2074b6ac
Binary files /dev/null and b/assets/images/webhook_secret_token.png differ
diff --git a/assets/images/webhooks_recent_deliveries.png b/assets/images/webhooks_recent_deliveries.png
new file mode 100644
index 0000000000..3a742bfeae
Binary files /dev/null and b/assets/images/webhooks_recent_deliveries.png differ
diff --git a/assets/javascripts/dev_mode.js b/assets/javascripts/dev_mode.js
new file mode 100644
index 0000000000..1996cb2614
--- /dev/null
+++ b/assets/javascripts/dev_mode.js
@@ -0,0 +1,9 @@
+// Init sidebar
+$(function() {
+ $(window).keydown(function(e){
+ // d
+ if (e.keyCode == 68) {
+ $("body.dev-mode").toggleClass('enterprise')
+ }
+ });
+});
diff --git a/assets/javascripts/documentation.js b/assets/javascripts/documentation.js
new file mode 100644
index 0000000000..d006cd551e
--- /dev/null
+++ b/assets/javascripts/documentation.js
@@ -0,0 +1,96 @@
+// Init sidebar
+$(function() {
+ var activeItem,
+ helpList = $('#js-sidebar .js-topic'),
+ firstOccurance = true,
+ styleTOC = function() {
+ var pathRegEx = /\/\/[^\/]+([A-Za-z0-9-_./]+)/g,
+ docUrl = pathRegEx.exec(window.location.toString())
+ if (docUrl){
+ $('#js-sidebar .js-topic a').each(function(){
+ if ($(this).parent('li').hasClass('disable'))
+ $(this).parent('li').removeClass('disable')
+
+ var url = $(this).attr('href').toString()
+ var cleanDocUrl = docUrl[1]
+ if(url.indexOf(cleanDocUrl) >= 0 && url.length == cleanDocUrl.length){
+ $(this).parent('li').addClass('disable')
+ var parentTopic = $(this).parentsUntil('div.sidebar-module > ul').last()
+ parentTopic.addClass('js-current')
+ parentTopic.find('.js-expand-btn').toggleClass('collapsed expanded')
+ }
+ });
+ }
+ }
+
+ // bind every href with a hash; take a look at v3/search/ for example
+ $('#js-sidebar .js-accordion-list .js-topic a[href*=#]').bind("click", function(e) {
+ if (window.location.toString().indexOf($(e.target).attr('href')) == -1)
+ setTimeout(styleTOC, 0); // trigger the window.location change, then stylize
+ });
+
+ // hide list items at startup
+ if($('body.api') && window.location){
+ styleTOC();
+ }
+
+ $('#js-sidebar .js-topic').each(function(){
+ if(($(this).find('.disable').length == 0 || firstOccurance == false) &&
+ $(this).hasClass('js-current') != true){
+ $(this).find('.js-guides').children().hide()
+ } else {
+ activeItem = $(this).index()
+ firstOccurance = false
+ }
+ })
+
+ // Toggle style list. Expanded items stay
+ // expanded when new items are clicked.
+ $('#js-sidebar .js-toggle-list .js-expand-btn').click(function(){
+ var clickedTopic = $(this).parents('.js-topic'),
+ topicGuides = clickedTopic.find('.js-guides li')
+ $(this).toggleClass('collapsed expanded')
+ topicGuides.slideToggle(100)
+ return false
+ })
+
+ // Accordion style list. Expanded items
+ // collapse when new items are clicked.
+ $('#js-sidebar .js-accordion-list .js-topic h3 a').click(function(){
+ var clickedTopic = $(this).parents('.js-topic'),
+ topicGuides = clickedTopic.find('.js-guides li')
+
+ if(activeItem != clickedTopic.index()){
+ if(helpList.eq(activeItem)){
+ helpList.eq(activeItem).find('.js-guides li').slideToggle(100)
+ }
+ activeItem = clickedTopic.index()
+ topicGuides.slideToggle(100)
+ } else {
+ activeItem = undefined
+ topicGuides.slideToggle(100)
+ }
+
+ return false
+ })
+
+ // Grab API status
+ $.getJSON('https://status.github.com/api/status.json?callback=?', function(data) {
+ if(data) {
+ var link = $("")
+ .attr("href", "https://status.github.com")
+ .addClass(data.status)
+ .attr("title", "API Status: " + data.status + ". Click for details.")
+ .text("API Status: " + data.status);
+ $('.api-status').html(link);
+ }
+ });
+
+ // Earth animation
+ if ($('.dev-program').length) {
+ setTimeout(function() {
+ $('.earth').fadeOut();
+ $('.earth-short-loop').show();
+ }, 19 * 1000); // Let first loop run through 19 seconds
+ }
+});
diff --git a/assets/javascripts/images.js b/assets/javascripts/images.js
new file mode 100644
index 0000000000..d335cfceb6
--- /dev/null
+++ b/assets/javascripts/images.js
@@ -0,0 +1,25 @@
+$(function() {
+ // copy Help's image show/hide functionality in OLs
+ var dismissFullImage;
+
+ $('ol img').each(function(index, elem) {
+ return $(elem).parent().prepend(elem);
+ });
+
+ $(document).on('click', 'ol img', function(event) {
+ var $fullImg, $img;
+ dismissFullImage();
+ $img = $(event.currentTarget).clone();
+ $fullImg = $('
').appendTo("#search-results");
}
-
+
// Select the first alternative
$("#search-results li:first-child").addClass("selected");
}
-
+
// Move the selected list item when hovering
$("#search-results").on("mouseenter", "li", function(e) {
$(this).parent().find(".selected").removeClass("selected").end().end()
.addClass("selected");
});
-
+
function moveSearchSelectionUp() {
$prev = $("#search-results .selected").prev();
if ($prev.length < 1)
return;
-
+
$("#search-results .selected").removeClass("selected");
$prev.addClass("selected");
}
-
+
function moveSearchSelectionDown() {
$next = $("#search-results .selected").next();
if ($next.length < 1)
return;
-
+
$("#search-results .selected").removeClass("selected");
$next.addClass("selected");
}
-
+
function goToSelectedSearchResult() {
var href = $("#search-results .selected a").attr("href");
if (href)
window.location.href = href;
}
-
});
diff --git a/assets/javascripts/search_worker.js b/assets/javascripts/search_worker.js
new file mode 100644
index 0000000000..b1dd459f58
--- /dev/null
+++ b/assets/javascripts/search_worker.js
@@ -0,0 +1,58 @@
+importScripts('lunr.min.js');
+
+// create lunr.js search index specifying that we want to index the title and body fields of documents.
+var lunr_index = lunr(function() {
+ this.field('title', { boost: 10 });
+ this.field('body');
+ this.ref('id');
+ }),
+ entries;
+
+onmessage = function (oEvent) {
+
+ populateIndex = function(data) {
+ // format the raw json into a form that is simpler to work with
+ this.entries = data.map(this.createEntry).filter(function(n){ return n !== undefined });
+ this.entries.forEach(function(entry) {
+ if (entry !== null)
+ this.lunr_index.add(entry);
+ });
+
+ postMessage({type: {indexed: true}});
+ };
+
+ decodeHtmlEntity = function(str) {
+ return str.replace(/(\d+);/g, function(match, dec) {
+ return String.fromCharCode(dec);
+ });
+ };
+
+ createEntry = function(entry, entry_id) {
+ if (entry.title === undefined)
+ return undefined;
+ entry.id = entry_id + 1;
+ entry.title = decodeHtmlEntity(entry.title);
+ return entry;
+ };
+
+ search = function(data) {
+ var entries = this.entries;
+
+ var results = lunr_index
+ .search(data.query)
+ .map(function(result) {
+ return entries.filter(function(entry) { return entry.id === parseInt(result.ref, 10); })[0];
+ })
+ .filter(function (result) {
+ return typeof result !== 'undefined';
+ });
+
+ postMessage({ query: data.query, results: results, type: { search: true } });
+ }
+
+ // if we're asked to index, index! else, search
+ if (oEvent.data.type == "index")
+ populateIndex(oEvent.data);
+ else
+ search(oEvent.data);
+};
diff --git a/static/shared/css/documentation.css b/assets/stylesheets/documentation.css
similarity index 66%
rename from static/shared/css/documentation.css
rename to assets/stylesheets/documentation.css
index cd486db768..6daa3579a8 100644
--- a/static/shared/css/documentation.css
+++ b/assets/stylesheets/documentation.css
@@ -1,21 +1,11 @@
-@import 'octicons.css';
-
/*------------------------------------------------------------------------------
Global Documentation Styles
------------------------------------------------------------------------------*/
-html {
- height:100%;
-}
-
body {
- font: 13px helvetica,arial,freesans,clean,sans-serif;
- line-height: 1.4em;
+ font: 13px/1.4em "Helvetica Neue", arial,freesans,clean,sans-serif;
background-color: #fff;
color: #393939;
- margin: 0px;
- padding: 0px;
- height: 100%;
}
p {
@@ -29,15 +19,29 @@ h1 {
font-weight: normal;
}
+body:not(.enterprise) .enterprise-only {
+ display: none;
+}
+body.dev-mode .enterprise-only {
+ border: 3px solid red;
+}
+body.dev-mode .not-enterprise {
+ border: 3px dashed blue;
+}
+body.dev-mode.enterprise .not-enterprise {
+ display: none;
+}
+
.content h1 {
font-weight: 300;
-webkit-backface-visibility: hidden;
font-size: 36px;
margin: 0em 0 0.5em;
position: relative;
+ line-height: 30px;
}
-.header-anchor {
+.anchor {
position: absolute;
left: -32px;
top: 0;
@@ -52,27 +56,24 @@ h1 {
-webkit-transition: opacity 0.3s ease-in-out 0s;
-moz-transition: opacity 0.3s ease-in-out 0s;
- -ms-transition: opacity 0.3s ease-in-out 0s;
+ transition: opacity 0.3s ease-in-out 0s;
}
-h1 .header-anchor {
+h1 .anchor {
line-height: 55px;
}
-.content h1:hover .header-anchor, .content h2:hover .header-anchor, .content h3:hover .header-anchor, .content h4:hover .header-anchor, .header-anchor:hover {
+.content h1:hover .anchor, .content h2:hover .anchor, .content h3:hover .anchor, .content h4:hover .anchor, .anchor:hover {
opacity: 1;
text-decoration: none;
}
-.header-anchor:before {
- content:'\f05c';
-}
-
h2 {
- font-size: 16px;
+ font-size: 22px;
color: #333;
margin: 2em auto 1em;
position: relative;
+ font-weight: 300;
}
.library-list h1 {
@@ -89,35 +90,24 @@ h2 {
.library-list ul {
margin-bottom: 40px;
+ list-style: none;
}
.library-list ul li {
padding-left: 200px;
padding-right: 200px;
- list-style: none;
font-size: 14px;
}
-body.api .content h2 {
- margin-bottom: 1em;
- margin-top: 2em;
- font-size: 22px;
- font-weight: 300;
-}
-
.change h2, .sidebar-shell h2 {
- font-weight: 300;
- font-size: 22px;
margin: 1.2em 0 1em;
}
-.change h2.title {
- background: none;
+.change > .title {
line-height: 1.4em;
margin: 1.2em 0 0px;
padding-left: 0;
font-size: 30px;
- font-weight: 300;
}
h2 span.step {
@@ -132,6 +122,7 @@ h3 {
}
h4 {
+ margin: 1em 0;
position: relative;
}
@@ -159,12 +150,6 @@ blockquote {
padding: 0px 20px;
}
-ul,
-ol {
- margin: 0px;
- padding: 0px;
-}
-
dt {
font-weight: bold;
}
@@ -178,12 +163,6 @@ dd + dd {
margin-bottom: 0;
}
-span.attention,
-p.attention {
- color: #e98400;
- font-style: italic;
-}
-
a img {
border: 0px;
}
@@ -216,7 +195,7 @@ a img {
.rss-subscribe {
display: block;
padding: 15px 14px 16px 47px;
- background: url(/images/feed-icon.png) 10px center no-repeat;
+ background: url(/assets/images/feed-icon.png) 10px center no-repeat;
color: #444;
font-size: 13px;
text-decoration: none;
@@ -235,7 +214,7 @@ a img {
margin-bottom: 0;
clear: both;
height: 61px;
- background: url(../images/header.png) 0 0 repeat-x;
+ background: url(/assets/images/header.png) 0 0 repeat-x;
}
#header {
@@ -250,7 +229,7 @@ a img {
display: inline-block;
width: 186px;
height: 27px;
- background: url(/images/logo_developer.png) 0 0 no-repeat;
+ background: url(/assets/images/logo_developer.png) 0 0 no-repeat;
text-indent: -999em;
}
@@ -276,7 +255,6 @@ a img {
padding: 20px 11px 19px;
-webkit-transition: color 0.2s ease-in-out 0s;
-moz-transition: color 0.2s ease-in-out 0s;
- -ms-transition: color 0.2s ease-in-out 0s;
transition: color 0.2s ease-in-out 0s;
}
@@ -309,11 +287,10 @@ a img {
margin-top: -4px;
width: 51px;
border-radius: 3px;
- background: url(/shared/images/search.png) 5px center no-repeat #fff;
+ background: url(/assets/images/search.png) 5px center no-repeat #fff;
-webkit-transition: width 0.3s ease-in-out 0s;
-moz-transition: width 0.3s ease-in-out 0s;
- -ms-transition: width 0.3s ease-in-out 0s;
transition: width 0.3s ease-in-out 0s;
}
@@ -345,7 +322,6 @@ a img {
-webkit-transition: opacity 0.3s ease-in-out 0s;
-moz-appearance-transition: opacity 0.3s ease-in-out 0s;
- -ms-transition: opacity 0.3s ease-in-out 0s;
transition: opacity 0.3s ease-in-out 0s;
}
@@ -353,7 +329,7 @@ a img {
position: absolute;
right: 4px;
top: 2px;
- background: url(/shared/images/cancel.png) 0 0 no-repeat;
+ background: url(/assets/images/cancel.png) 0 0 no-repeat;
width: 14px;
height: 14px;
display: none;
@@ -383,7 +359,6 @@ a img {
opacity: 1;
-webkit-transition: opacity 0.3s ease-in-out 0s;
-moz-transition: opacity 0.3s ease-in-out 0s;
- -ms-transition: opacity 0.3s ease-in-out 0s;
transition: opacity 0.3s ease-in-out 0s;
}
@@ -446,7 +421,7 @@ a img {
border-bottom: 1px solid #d8d8d8;
}
-.sub-nav h2, .sub-nav h2 a {
+.sub-nav > h2, .sub-nav > h2 > a {
color: #333;
font-weight: normal;
font-size: 22px;
@@ -455,15 +430,11 @@ a img {
text-decoration: none;
}
-.sub-nav h2 a {
+.sub-nav > h2 > a {
z-index: 10;
position: relative;
}
-.sub-nav li a:hover {
- text-decoration: none;
-}
-
.sub-nav ul {
list-style: none;
position: absolute;
@@ -484,19 +455,20 @@ a img {
padding: 4px 2px 8px;
}
+.sub-nav li a:hover {
+ text-decoration: none;
+ color: #327fc7;
+}
+
.sub-nav li:last-child a {
padding-right: 0;
}
-.sub-nav li a.active {
+.sub-nav li .active {
color: #222;
border-bottom: 2px solid #d8d8d8;
}
-.sub-nav li a:hover {
- color: #327fc7;
-}
-
/*------------------------------------------------------------------------------
Features
------------------------------------------------------------------------------*/
@@ -524,7 +496,6 @@ a img {
}
.feature h1, .library-list .feature h1 {
- border: none;
font-weight: 300;
font-size: 42px;
line-height: 1.2em;
@@ -534,12 +505,14 @@ a img {
text-align: left;
}
-.library-list .feature h1 {
- margin-top: 60px;
+.library-list .feature {
+ overflow: hidden;
+ border-bottom: 1px solid #ddd;
+ padding-bottom: 40px;
}
.feature .intro {
- color: #666666;
+ color: #666;
font-size: 18px;
line-height: 1.5em;
max-width: 400px;
@@ -640,7 +613,6 @@ a img {
.highlights h2 {
margin: 25px 0 15px;
font-size: 30px;
- font-weight: 300;
line-height: 1.2;
-webkit-backface-visibility: hidden;
}
@@ -661,13 +633,12 @@ a .mega-octicon {
position: relative;
float: right;
margin: 20px 0 0;
- width: 280px;
+ width: 290px;
}
.sidebar-module {
border-radius: 4px;
overflow: hidden;
- display: block;
margin-bottom: 20px;
font-size: 12px;
border: 1px solid #ddd;
@@ -684,7 +655,7 @@ a .mega-octicon {
line-height: 1.5em;
}
-.sidebar-module.notice p {
+.notice > p {
padding: 12px;
margin: 0;
}
@@ -701,14 +672,14 @@ a .mega-octicon {
border-top: 1px solid #eee;
}
-.sidebar-module ul h3, .headlines li {
+.sidebar-module ul h3, .headlines > li {
margin: 0px;
color: #666;
border-bottom: 1px solid #eee;
font-size: 14px;
}
-.headlines li a {
+.headlines > li > a {
color: #333;
display: block;
padding: 10px 10px;
@@ -717,35 +688,25 @@ a .mega-octicon {
font-weight: 300;
}
-.headlines a .date {
+.headlines > li > a:hover {
+ color: #327fc7;
+}
+
+.headlines > li > a > .date {
font-weight: normal;
font-size: 12px;
color: #888;
}
-.headlines li a:hover {
- color: #327fc7;
-}
-
.headlines li:hover {
background-color: #fdfdfd;
}
-.sidebar-module h3 a,
-.sidebar-module h3.disable span {
- padding-top: 8px;
- padding-bottom: 8px;
- padding-left: 10px;
+.sidebar-module h3 a {
+ padding: 8px 10px 8px 10px;
color: #555;
text-decoration: none;
-}
-
-.sidebar-module h3.disable span {
- padding-left: 20px;
- background-image: url(../images/active-arrow.png);
- background-position: left center;
- background-repeat: no-repeat;
- cursor: default;
+ display: block;
}
.sidebar-module h3 a:hover {
@@ -754,12 +715,7 @@ a .mega-octicon {
background-color: #fdfdfd;
}
-div.sidebar-module ul ul,
-div.sidebar-module .spacer {
- display: block;
-}
-
-div.sidebar-module ul ul li {
+.sidebar-module ul ul li {
border-bottom: 1px solid #eee;
font-weight: bold;
color: #666;
@@ -770,19 +726,17 @@ div.sidebar-module ul ul li {
border-bottom: none;
}
-div.sidebar-module li.disable a {
+.sidebar-module .disable > a {
color: #333;
border-left: 2px solid #d8d8d8;
padding-left: 29px;
}
-.sidebar-module ul ul li a,
-.sidebar-module ul ul li span {
+.sidebar-module ul ul li a {
padding: 6px 0px 6px 31px;
display: block;
text-decoration: none;
font-weight: normal;
- color: #777;
}
.sidebar-module ul ul li a:hover {
@@ -790,12 +744,6 @@ div.sidebar-module li.disable a {
color: #327fc7;
}
-div.sidebar-module ul ul li span {
- padding-left: 20px;
- cursor: default;
-}
-
-/* @end */
/*****************************************************************************/
/*
@@ -819,19 +767,22 @@ div.sidebar-module ul ul li span {
}
.api-status .unknown {
- background-image: url(/images/status-icon-unknown.png);
+ background-image: url(/assets/images/status-icon-unknown.png);
}
.api-status .good {
- background-image: url(/images/status-icon-good.png);
+ color: #227b41;
+ background-image: url(/assets/images/status-icon-good.png);
}
.api-status .minor {
- background-image: url(/images/status-icon-minor.png);
+ color: #ed8b3f;
+ background-image: url(/assets/images/status-icon-minor.png);
}
.api-status .major {
- background-image: url(/images/status-icon-major.png);
+ color: #ad1a05;
+ background-image: url(/assets/images/status-icon-major.png);
}
.api-status a:hover {
@@ -839,11 +790,6 @@ div.sidebar-module ul ul li span {
color: #327fc7;
}
-.api-status img {
- display: block;
- margin: 6px auto 0;
-}
-
#footer {
position: relative;
bottom:0;
@@ -851,6 +797,7 @@ div.sidebar-module ul ul li span {
color: #636363;
margin: 0 auto;
max-width: 980px;
+ clear: both;
}
#footer a:hover {
@@ -869,7 +816,6 @@ div.sidebar-module ul ul li span {
.lower_footer {
border-top: 1px solid #ddd;
- width: 100%;
padding: 30px 0;
}
@@ -897,7 +843,7 @@ div.sidebar-module ul ul li span {
.footer-cell li {
display: inline;
- margin-right: 20px;
+ margin-right: 9px;
list-style: none;
}
@@ -915,6 +861,7 @@ div.sidebar-module ul ul li span {
.dev-program.feature {
height: 420px;
margin-top: -2px;
+ overflow-x: hidden;
position: relative;
}
@@ -934,11 +881,11 @@ div.sidebar-module ul ul li span {
}
.dev-program.feature .earth {
- margin-top: -187px;
+ margin-top: -150px;
position: absolute;
- right: 5%;
+ right: -55px;
top: 50%;
- z-index: 0;
+ z-index: -1;
}
.dev-program.feature .earth-short-loop {
@@ -950,12 +897,9 @@ div.sidebar-module ul ul li span {
z-index: 1;
}
-.dev-program-callout {
-}
-
.dev-program-callout .wrapper {
padding: 40px 0;
- background: #160625 url(/shared/images/callout-earth-static.png) no-repeat top right / 30%;
+ background: #160625 url(/assets/images/callout-earth-static.png) no-repeat top right / 30%;
}
.dev-program.feature h1,
@@ -969,8 +913,6 @@ div.sidebar-module ul ul li span {
}
.dev-program-callout h2 {
- font-size: 22px;
- font-weight: 300;
margin: 0;
}
@@ -1032,7 +974,7 @@ div.sidebar-module ul ul li span {
}
.content li {
- line-height: 1.7em;
+ margin: 0.5em 0;
}
.content img {
@@ -1040,6 +982,80 @@ div.sidebar-module ul ul li span {
margin: 12px 0;
}
+/* Taken from Help in order to show images in ordered lists inline */
+ol {
+ counter-reset: li;
+ list-style: none;
+ position: relative;
+ padding-bottom: 10px;
+}
+ol > li {
+ padding: 5px 0 5px 55px;
+ position: relative;
+ margin-bottom: 5px;
+}
+ol > li:before {
+ content: counter(li);
+ counter-increment: li;
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 30px;
+ padding: 0 10px 0 0;
+ color: #999;
+ font-size: 22px;
+ font-weight: bold;
+ line-height: 35px;
+ text-align: right;
+ border-right: 1px solid #ddd;
+}
+ol > li > p:first-child {
+ margin-top: 0;
+}
+ol > li:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0;
+}
+.content ol > li img {
+ max-width: 100px;
+ margin: 0 0 0 10px;
+ float: right;
+ border: 1px solid #ddd;
+ cursor: pointer;
+}
+.content ol > li img.expanded {
+ max-width: 400px;
+}
+
+.content .full-image {
+ position: absolute;
+ top: 5px;
+ right: -20px;
+ z-index: 100;
+}
+.content .full-image img {
+ position: absolute;
+ top: 0;
+ right: 20px;
+ margin: 0;
+ max-width: 600px;
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
+}
+.content .full-image:hover .octicon, .full-image:hover .mini-icon {
+ color: #666;
+}
+.content .full-image .octicon, .full-image .octicon-remove-close {
+ position: absolute;
+ top: 0px;
+ right: 0px;
+ color: #999;
+ cursor: pointer;
+}
.content .description {
margin-left: 20px;
@@ -1055,13 +1071,7 @@ div.sidebar-module ul ul li span {
.content dl code,
.content ul code,
p code {
- font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
border-radius: 3px;
- -moz-background-clip: padding;
- -webkit-background-clip: padding-box;
- background-clip: padding-box;
border: 1px solid #ccc;
background-color: #f9f9f9;
padding: 0px 3px;
@@ -1135,6 +1145,7 @@ p code {
#markdown-toc li {
font-size: 14px;
list-style-type: lower-roman;
+ margin: 0.25em 0;
}
#markdown-toc li a {
@@ -1146,16 +1157,14 @@ p code {
color: #327fc7;
}
-body.api .content table {
+.content table {
width: 100%;
overflow: auto;
display: block;
margin: 15px 0;
- border-collapse: collapse;
- border-spacing: 0;
}
-body.api .content thead {
+.content thead {
margin: 0;
padding: 0;
border: 0;
@@ -1164,25 +1173,25 @@ body.api .content thead {
vertical-align: baseline;
}
-body.api .content table th {
+.content table th {
border: 1px solid #ddd;
padding: 6px 13px;
font-weight: bold;
text-align: center;
}
-body.api .content tbody {
+.content tbody {
vertical-align: middle;
border-color: inherit;
}
-body.api .content table tr {
+.content table tr {
border-top: 1px solid #ccc;
background-color: #fff;
vertical-align: inherit;
}
-body.api .content table td {
+.content table td {
border: 1px solid #ddd;
padding: 6px 13px;
}
@@ -1193,21 +1202,20 @@ body.api .content table td {
Pre/Code Styles
------------------------------------------------------------------------------*/
-code {white-space: nowrap;}
+code {
+ white-space: nowrap;
+ font: 12px Consolas, 'Liberation Mono', Courier, monospace;
+}
+
+pre code {white-space: pre;}
pre {
border: 1px solid #cacaca;
- line-height: 1.2em;
- font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
+ font: 12px/1.4em Consolas, 'Liberation Mono', Courier, monospace;
padding: 10px;
overflow:auto;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
border-radius: 3px;
- -moz-background-clip: padding;
- -webkit-background-clip: padding-box;
- background-clip: padding-box;
- background-color: #FAFAFB;
+ background-color: #fafafb;
color: #393939;
margin: 2em 0;
}
@@ -1216,285 +1224,62 @@ ul + pre {
margin-top: 1em;
}
-pre code {white-space: pre;}
-
pre span.comment {color: #aaa;}
-pre.headers {
+.highlight-headers {
margin-bottom: 0;
- border-bottom-width: 0;
- -webkit-border-radius: 3px 3px 0 0;
- -moz-border-radius: 3px 3px 0 0;
- border-radius: 3px 3px 0 0;
- color: #666;
- background-color: #f1f1f1;
- background-image: -moz-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: -ms-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: -o-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e1e1e1));
- background-image: -webkit-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: linear-gradient(top, #f1f1f1, #e1e1e1);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f1f1f1', EndColorStr='#e1e1e1');
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-}
-
-pre.no-response {
- -webkit-border-radius: 3px 3px;
- -moz-border-radius: 3px 3px;
border-radius: 3px 3px;
border-bottom: 1px solid #CACACA;
+ background-color: #f4f4f4;
}
-pre.headers + pre {
- -webkit-border-radius: 0 0 3px 3px;
- -moz-border-radius: 0 0 3px 3px;
+.highlight-headers + pre {
border-radius: 0 0 3px 3px;
margin-top: 0;
+ border-top-color: #ddd;
+}
+
+.highlight-headers + pre.highlight {
+ margin-top: -2px;
}
-pre.terminal {
+.command-line {
background-color: #444;
color: #fff;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
border-radius: 3px;
- -moz-background-clip: padding;
- -webkit-background-clip: padding-box;
- background-clip: padding-box;
border: none;
position: relative;
- padding: 10px;
- text-shadow: none;
- background-image: none;
- filter: none;
}
-pre.terminal em {
+.command-line em {
color: #f9fe64;
}
-span.codeline {
- display: block;
- position: relative;
-}
-
-span.codeline:hover {
- background-color: #292929;
- margin: 0px;
- padding-left: 3px;
- margin-left: -3px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
- color: #666666;
-}
-
-span.codeline span {
- display: inline-block;
- font-size: 10px;
- color: #fff;
- padding: 0 0.3em 0.05em;
- position: absolute;
- right: 0px;
- top: 0px;
- text-indent: -9999px;
- background-image: url(../images/qmark.png);
- background-repeat: no-repeat;
- background-position: 1px 3px;
- max-width: 8px;
- min-width: 8px;
- -moz-user-select: none;
- -khtml-user-select: none;
- user-select: none;
- cursor: default;
-}
-
-span.codeline span:hover {
- display: inline-block;
- text-indent: 0px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
- background: #000;
- border: 1px solid #292929;
- max-width: 1000px;
-}
-
-span.codeline:hover em {
- color: #666666;
-}
-
-pre.bootcamp {
- white-space: normal;
- margin-left: -10px;
- background-image: none;
-}
-
-span.bash-output {
- color: #63e463;
- display: block;
- position: relative;
- -moz-user-select: none;
- -khtml-user-select: none;
- user-select: none;
-}
-
-/* end */
-
-/*------------------------------------------------------------------------------
- More Info Expander
-------------------------------------------------------------------------------*/
-
-.more-info {
- margin: 10px 0;
- position: relative;
-}
-.more-info > h4 {
- background-image: url('../images/dropdown_sprites.jpg');
- background-repeat: no-repeat;
- padding: .25em 0 .25em 25px;
- cursor: pointer;
- color: #4183C4;
- font-weight: normal;
-}
-.more-info h4.compressed {
- background-position: 0 0;
-}
-.more-info:hover h4.compressed {
- background-position: 0 -23px;
-}
-.more-info h4.expanded {
- background-position: 0 -46px;
-}
-.more-info:hover h4.expanded {
- background-position: 0 -69px;
-}
-
-.more-info .more-content {
- display: none;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
- background-color: #FFFFFF;
- border: 3px solid #DDDDDD;
- padding: 1em 2em;
- -webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
- box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
- margin: 15px 0 30px;
-}
-
-.more-info .more-content h4 {
- margin-top: 1em;
-}
-
-.more-info .more-content pre {
- margin-left: 0px;
-}
-
-/****************************/
-/* List Module */
-/****************************/
-
-.list-module h2 {
- border: solid #cacaca;
- border-width: 1px;
- border-radius: 3px 3px 0px 0px;
- -moz-border-radius: 3px 3px 0px 0px;
- -webkit-border-bottom-right-radius: 0px;
- -webkit-border-bottom-left-radius: 0px;
- -moz-background-clip: padding;
- -webkit-background-clip: padding-box;
- background-clip: padding-box;
- padding: 6px 10px;
- background-color: #f1f1f1;
- background-image: -moz-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: -ms-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: -o-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e1e1e1));
- background-image: -webkit-linear-gradient(top, #f1f1f1, #e1e1e1);
- background-image: linear-gradient(top, #f1f1f1, #e1e1e1);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f1f1f1', EndColorStr='#e1e1e1');
- color: #666;
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
- font-size: 16px;
- line-height: 22px;
- margin: 0px;
-}
-
-.list-module .list-body {
- border: solid #cacaca;
- border-width: 0px 1px 1px 1px;
- border-radius: 0px 0px 3px 3px;
- -moz-border-radius: 0px 0px 3px 3px;
- -webkit-border-bottom-right-radius: 3px;
- -webkit-border-bottom-left-radius: 3px;
- -moz-background-clip: padding;
- -webkit-background-clip: padding-box;
- background-clip: padding-box;
- background-color: #fafafb;
- color: #666;
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
-}
-
-.list-module .list-body .icon {
- display: block;
- height: 28px;
- width: 28px;
- position: absolute;
- top: 10px;
- left: 10px;
- background: transparent url(images/popular_guide_sprites.png) 0 0 no-repeat;
-}
-
-.list-module a {
- border-top: 1px solid #fff;
- border-bottom: 1px solid #e9ecee;
- padding: 6px 10px;
- position: relative;
- display: block;
-}
-
-.list-module a:hover {
- border-top: 1px solid #fafafb;
- border-bottom: 1px solid #e5e8ea;
- background-color: #f0f0f3;
- text-decoration: none;
-}
-
-.list-module a h3 {
- color: #4183C4;
-}
-
-.list-module a:hover h3 {
- text-decoration: underline;
+.command-line span.comment {
+ color: #ccc;
}
-.list-module ul {
- list-style-type: none;
- margin: 0px;
+.command-line span.output {
+ color: #63E463;
}
-.list-module h3 {
- margin: 0px;
- font-size: 13px;
+#staging-header {
+ line-height: 34px;
+ color: rgba(255, 255, 255, 0.5);
+ background-color: #222;
}
-.list-module .list-body a p {
- color: #666;
- margin: 0px;
+#staging-header p {
+ color: white;
+ font-size: 12px;
+ padding-left: 20px;
+ margin: 0;
}
-/* @end */
-
/****************************/
/* Expandable List Module */
/****************************/
-.sidebar-module h3 a {
- display: block;
-}
-
.sidebar-module a + a {
padding-left: 27px;
}
@@ -1504,7 +1289,7 @@ span.bash-output {
}
.sidebar-module .arrow-btn {
- background-image: url(/shared/images/expand-arrows.png);
+ background-image: url(/assets/images/expand-arrows.png);
background-repeat: no-repeat;
background-position: -3px -3px;
width: 13px;
@@ -1533,35 +1318,21 @@ span.bash-output {
.alert {
position:relative;
- margin:0 auto;
- padding:15px;
- color:#264c72;
+ padding: 0 15px;
+ color: #264c72;
border: 1px solid #97c1da;
border-radius: 3px;
background-color: #d8ebf8;
}
-.alert *:first-child { margin-top: 0 }
-.alert *:last-child { margin-bottom: 0 }
-
-li.api-status a.good {
- color: #227b41;
-}
-
-li.api-status a.minor {
- color: #ed8b3f;
-}
-
-li.api-status a.major {
- color: #ad1a05;
-}
-
-li.api-status img {
- float: left;
- margin: 0 5px 0 0;
+.warning {
+ position:relative;
+ padding: 0 15px;
+ color: #613A00;
+ border: 1px solid #dca874;
+ border-radius: 3px;
+ background-color: #ffe3c8;
}
-/* @end */
-
/*------------------------------------------------------------------------------
Dev Program
@@ -1595,7 +1366,7 @@ li.api-status img {
position: absolute;
left: 0;
top: 32px;
- color: #4183c4;
+ color: #333;
}
.program-info-column ul {
@@ -1611,52 +1382,52 @@ li.api-status img {
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi) {
#header-wrapper {
- background-image: url(../images/header@2x.png);
+ background-image: url(/assets/images/header@2x.png);
background-size: 8px 61px;
}
#header .logo {
- background-image: url(/images/logo_developer@2x.png);
+ background-image: url(/assets/images/logo_developer@2x.png);
background-size: 186px 27px;
}
#searchfield {
- background-image: url(/shared/images/search@2x.png);
+ background-image: url(/assets/images/search@2x.png);
background-size: 13px 13px;
}
.cancel-search {
- background-image: url(/shared/images/cancel@2x.png);
+ background-image: url(/assets/images/cancel@2x.png);
background-size: 14px 14px;
}
.sidebar-module .arrow-btn {
- background-image: url(/shared/images/expand-arrows@2x.png);
+ background-image: url(/assets/images/expand-arrows@2x.png);
background-size: 73px 80px;
}
.api-status .unknown {
- background-image: url(/images/status-icon-unknown@2x.png);
+ background-image: url(/assets/images/status-icon-unknown@2x.png);
background-size: 32px 32px;
}
.api-status .good {
- background-image: url(/images/status-icon-good@2x.png);
+ background-image: url(/assets/images/status-icon-good@2x.png);
background-size: 32px 32px;
}
.api-status .minor {
- background-image: url(/images/status-icon-minor@2x.png);
+ background-image: url(/assets/images/status-icon-minor@2x.png);
background-size: 32px 32px;
}
.api-status .major {
- background-image: url(/images/status-icon-major@2x.png);
+ background-image: url(/assets/images/status-icon-major@2x.png);
background-size: 32px 32px;
}
.rss-subscribe {
- background-image: url(/images/feed-icon@2x.png);
+ background-image: url(/assets/images/feed-icon@2x.png);
background-size: 28px 28px;
}
diff --git a/assets/stylesheets/pagination.css b/assets/stylesheets/pagination.css
new file mode 100644
index 0000000000..ad1fcd043c
--- /dev/null
+++ b/assets/stylesheets/pagination.css
@@ -0,0 +1,93 @@
+.pagination a,
+.pagination span,
+.pagination em {
+ position: relative;
+ float: left;
+ margin-left: -1px;
+ font-size: 13px;
+ font-weight: bold;
+ font-style: normal;
+ padding: 7px 12px;
+ color: #4078c0;
+ white-space: nowrap;
+ vertical-align: middle;
+ cursor: pointer;
+ background: #fff;
+ border: 1px solid #e5e5e5;
+ user-select: none;
+}
+.pagination a:first-child,
+.pagination span:first-child,
+.pagination em:first-child {
+ margin-left: 0;
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.pagination a:last-child,
+.pagination span:last-child,
+.pagination em:last-child {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+.pagination a:hover, .pagination a:focus,
+.pagination span:hover,
+.pagination span:focus,
+.pagination em:hover,
+.pagination em:focus {
+ z-index: 2;
+ background-color: #e7e7e7;
+ border-color: #e5e5e5;
+ text-decoration: none;
+}
+.pagination .selected {
+ z-index: 3;
+}
+.pagination .current,
+.pagination .current:hover {
+ z-index: 3;
+ color: #fff;
+ background-color: #4078c0;
+ border-color: #4078c0;
+}
+.pagination .gap,
+.pagination .disabled,
+.pagination .gap:hover,
+.pagination .disabled:hover {
+ background-color: #fafafa;
+ cursor: default;
+ color: #d3d3d3;
+}
+
+.ajax_paginate {
+ display: block;
+ margin-top: 20px;
+}
+.ajax_paginate a {
+ float: none;
+ display: block;
+ padding: 6px;
+ text-align: center;
+}
+.ajax_paginate.loading a {
+ text-indent: -3000px;
+ background-color: #eaeaea;
+ background-image: url("/images/spinners/octocat-spinner-16px-EAF2F5.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ border-color: #c5c5c5;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 2), screen and (max--moz-device-pixel-ratio: 2) {
+ .ajax_paginate.loading a {
+ background-image: url("/images/spinners/octocat-spinner-32-EAF2F5.gif");
+ background-size: 16px auto;
+ }
+}
+
+.paginate-container {
+ margin-top: 20px;
+ margin-bottom: 15px;
+ text-align: center;
+}
+.paginate-container .pagination {
+ display: inline-block;
+}
diff --git a/shared/css/pygments.css b/assets/stylesheets/pygments.css
similarity index 100%
rename from shared/css/pygments.css
rename to assets/stylesheets/pygments.css
diff --git a/css/reset.css b/assets/stylesheets/reset.css
similarity index 100%
rename from css/reset.css
rename to assets/stylesheets/reset.css
diff --git a/assets/vendor/lunr.js/lunr.js b/assets/vendor/lunr.js/lunr.js
new file mode 100644
index 0000000000..01bdcb8690
--- /dev/null
+++ b/assets/vendor/lunr.js/lunr.js
@@ -0,0 +1,1968 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.6.0
+ * Copyright (C) 2015 Oliver Nightingale
+ * MIT Licensed
+ * @license
+ */
+
+;(function(){
+
+/**
+ * Convenience function for instantiating a new lunr index and configuring it
+ * with the default pipeline functions and the passed config function.
+ *
+ * When using this convenience function a new index will be created with the
+ * following functions already in the pipeline:
+ *
+ * lunr.StopWordFilter - filters out any stop words before they enter the
+ * index
+ *
+ * lunr.stemmer - stems the tokens before entering the index.
+ *
+ * Example:
+ *
+ * var idx = lunr(function () {
+ * this.field('title', 10)
+ * this.field('tags', 100)
+ * this.field('body')
+ *
+ * this.ref('cid')
+ *
+ * this.pipeline.add(function () {
+ * // some custom pipeline function
+ * })
+ *
+ * })
+ *
+ * @param {Function} config A function that will be called with the new instance
+ * of the lunr.Index as both its context and first parameter. It can be used to
+ * customize the instance of new lunr.Index.
+ * @namespace
+ * @module
+ * @returns {lunr.Index}
+ *
+ */
+var lunr = function (config) {
+ var idx = new lunr.Index
+
+ idx.pipeline.add(
+ lunr.trimmer,
+ lunr.stopWordFilter,
+ lunr.stemmer
+ )
+
+ if (config) config.call(idx, idx)
+
+ return idx
+}
+
+lunr.version = "0.6.0"
+/*!
+ * lunr.utils
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * A namespace containing utils for the rest of the lunr library
+ */
+lunr.utils = {}
+
+/**
+ * Print a warning message to the console.
+ *
+ * @param {String} message The message to be printed.
+ * @memberOf Utils
+ */
+lunr.utils.warn = (function (global) {
+ return function (message) {
+ if (global.console && console.warn) {
+ console.warn(message)
+ }
+ }
+})(this)
+
+/**
+ * Convert an object to a string.
+ *
+ * In the case of `null` and `undefined` the function returns
+ * the empty string, in all other cases the result of calling
+ * `toString` on the passed object is returned.
+ *
+ * @param {Any} obj The object to convert to a string.
+ * @return {String} string representation of the passed object.
+ * @memberOf Utils
+ */
+lunr.utils.asString = function (obj) {
+ if (obj === void 0 || obj === null) {
+ return ""
+ } else {
+ return obj.toString()
+ }
+}
+/*!
+ * lunr.EventEmitter
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers.
+ *
+ * @constructor
+ */
+lunr.EventEmitter = function () {
+ this.events = {}
+}
+
+/**
+ * Binds a handler function to a specific event(s).
+ *
+ * Can bind a single function to many different events in one call.
+ *
+ * @param {String} [eventName] The name(s) of events to bind this function to.
+ * @param {Function} fn The function to call when an event is fired.
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.addListener = function () {
+ var args = Array.prototype.slice.call(arguments),
+ fn = args.pop(),
+ names = args
+
+ if (typeof fn !== "function") throw new TypeError ("last argument must be a function")
+
+ names.forEach(function (name) {
+ if (!this.hasHandler(name)) this.events[name] = []
+ this.events[name].push(fn)
+ }, this)
+}
+
+/**
+ * Removes a handler function from a specific event.
+ *
+ * @param {String} eventName The name of the event to remove this function from.
+ * @param {Function} fn The function to remove from an event.
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.removeListener = function (name, fn) {
+ if (!this.hasHandler(name)) return
+
+ var fnIndex = this.events[name].indexOf(fn)
+ this.events[name].splice(fnIndex, 1)
+
+ if (!this.events[name].length) delete this.events[name]
+}
+
+/**
+ * Calls all functions bound to the given event.
+ *
+ * Additional data can be passed to the event handler as arguments to `emit`
+ * after the event name.
+ *
+ * @param {String} eventName The name of the event to emit.
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.emit = function (name) {
+ if (!this.hasHandler(name)) return
+
+ var args = Array.prototype.slice.call(arguments, 1)
+
+ this.events[name].forEach(function (fn) {
+ fn.apply(undefined, args)
+ })
+}
+
+/**
+ * Checks whether a handler has ever been stored against an event.
+ *
+ * @param {String} eventName The name of the event to check.
+ * @private
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.hasHandler = function (name) {
+ return name in this.events
+}
+
+/*!
+ * lunr.tokenizer
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * A function for splitting a string into tokens ready to be inserted into
+ * the search index. Uses `lunr.tokenizer.seperator` to split strings, change
+ * the value of this property to change how strings are split into tokens.
+ *
+ * @module
+ * @param {String} obj The string to convert into tokens
+ * @see lunr.tokenizer.seperator
+ * @returns {Array}
+ */
+lunr.tokenizer = function (obj) {
+ if (!arguments.length || obj == null || obj == undefined) return []
+ if (Array.isArray(obj)) return obj.map(function (t) { return lunr.utils.asString(t).toLowerCase() })
+
+ return obj.toString().trim().toLowerCase().split(lunr.tokenizer.seperator)
+}
+
+/**
+ * The sperator used to split a string into tokens. Override this property to change the behaviour of
+ * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.
+ *
+ * @static
+ * @see lunr.tokenizer
+ */
+lunr.tokenizer.seperator = /[\s\-]+/
+/*!
+ * lunr.Pipeline
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.Pipelines maintain an ordered list of functions to be applied to all
+ * tokens in documents entering the search index and queries being ran against
+ * the index.
+ *
+ * An instance of lunr.Index created with the lunr shortcut will contain a
+ * pipeline with a stop word filter and an English language stemmer. Extra
+ * functions can be added before or after either of these functions or these
+ * default functions can be removed.
+ *
+ * When run the pipeline will call each function in turn, passing a token, the
+ * index of that token in the original list of all tokens and finally a list of
+ * all the original tokens.
+ *
+ * The output of functions in the pipeline will be passed to the next function
+ * in the pipeline. To exclude a token from entering the index the function
+ * should return undefined, the rest of the pipeline will not be called with
+ * this token.
+ *
+ * For serialisation of pipelines to work, all functions used in an instance of
+ * a pipeline should be registered with lunr.Pipeline. Registered functions can
+ * then be loaded. If trying to load a serialised pipeline that uses functions
+ * that are not registered an error will be thrown.
+ *
+ * If not planning on serialising the pipeline then registering pipeline functions
+ * is not necessary.
+ *
+ * @constructor
+ */
+lunr.Pipeline = function () {
+ this._stack = []
+}
+
+lunr.Pipeline.registeredFunctions = {}
+
+/**
+ * Register a function with the pipeline.
+ *
+ * Functions that are used in the pipeline should be registered if the pipeline
+ * needs to be serialised, or a serialised pipeline needs to be loaded.
+ *
+ * Registering a function does not add it to a pipeline, functions must still be
+ * added to instances of the pipeline for them to be used when running a pipeline.
+ *
+ * @param {Function} fn The function to check for.
+ * @param {String} label The label to register this function with
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.registerFunction = function (fn, label) {
+ if (label in this.registeredFunctions) {
+ lunr.utils.warn('Overwriting existing registered function: ' + label)
+ }
+
+ fn.label = label
+ lunr.Pipeline.registeredFunctions[fn.label] = fn
+}
+
+/**
+ * Warns if the function is not registered as a Pipeline function.
+ *
+ * @param {Function} fn The function to check for.
+ * @private
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {
+ var isRegistered = fn.label && (fn.label in this.registeredFunctions)
+
+ if (!isRegistered) {
+ lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn)
+ }
+}
+
+/**
+ * Loads a previously serialised pipeline.
+ *
+ * All functions to be loaded must already be registered with lunr.Pipeline.
+ * If any function from the serialised data has not been registered then an
+ * error will be thrown.
+ *
+ * @param {Object} serialised The serialised pipeline to load.
+ * @returns {lunr.Pipeline}
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.load = function (serialised) {
+ var pipeline = new lunr.Pipeline
+
+ serialised.forEach(function (fnName) {
+ var fn = lunr.Pipeline.registeredFunctions[fnName]
+
+ if (fn) {
+ pipeline.add(fn)
+ } else {
+ throw new Error('Cannot load un-registered function: ' + fnName)
+ }
+ })
+
+ return pipeline
+}
+
+/**
+ * Adds new functions to the end of the pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {Function} functions Any number of functions to add to the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.add = function () {
+ var fns = Array.prototype.slice.call(arguments)
+
+ fns.forEach(function (fn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(fn)
+ this._stack.push(fn)
+ }, this)
+}
+
+/**
+ * Adds a single function after a function that already exists in the
+ * pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {Function} existingFn A function that already exists in the pipeline.
+ * @param {Function} newFn The new function to add to the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.after = function (existingFn, newFn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
+
+ var pos = this._stack.indexOf(existingFn)
+ if (pos == -1) {
+ throw new Error('Cannot find existingFn')
+ }
+
+ pos = pos + 1
+ this._stack.splice(pos, 0, newFn)
+}
+
+/**
+ * Adds a single function before a function that already exists in the
+ * pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {Function} existingFn A function that already exists in the pipeline.
+ * @param {Function} newFn The new function to add to the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.before = function (existingFn, newFn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
+
+ var pos = this._stack.indexOf(existingFn)
+ if (pos == -1) {
+ throw new Error('Cannot find existingFn')
+ }
+
+ this._stack.splice(pos, 0, newFn)
+}
+
+/**
+ * Removes a function from the pipeline.
+ *
+ * @param {Function} fn The function to remove from the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.remove = function (fn) {
+ var pos = this._stack.indexOf(fn)
+ if (pos == -1) {
+ return
+ }
+
+ this._stack.splice(pos, 1)
+}
+
+/**
+ * Runs the current list of functions that make up the pipeline against the
+ * passed tokens.
+ *
+ * @param {Array} tokens The tokens to run through the pipeline.
+ * @returns {Array}
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.run = function (tokens) {
+ var out = [],
+ tokenLength = tokens.length,
+ stackLength = this._stack.length
+
+ for (var i = 0; i < tokenLength; i++) {
+ var token = tokens[i]
+
+ for (var j = 0; j < stackLength; j++) {
+ token = this._stack[j](token, i, tokens)
+ if (token === void 0 || token === '') break
+ };
+
+ if (token !== void 0 && token !== '') out.push(token)
+ };
+
+ return out
+}
+
+/**
+ * Resets the pipeline by removing any existing processors.
+ *
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.reset = function () {
+ this._stack = []
+}
+
+/**
+ * Returns a representation of the pipeline ready for serialisation.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @returns {Array}
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.toJSON = function () {
+ return this._stack.map(function (fn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(fn)
+
+ return fn.label
+ })
+}
+/*!
+ * lunr.Vector
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.Vectors implement vector related operations for
+ * a series of elements.
+ *
+ * @constructor
+ */
+lunr.Vector = function () {
+ this._magnitude = null
+ this.list = undefined
+ this.length = 0
+}
+
+/**
+ * lunr.Vector.Node is a simple struct for each node
+ * in a lunr.Vector.
+ *
+ * @private
+ * @param {Number} The index of the node in the vector.
+ * @param {Object} The data at this node in the vector.
+ * @param {lunr.Vector.Node} The node directly after this node in the vector.
+ * @constructor
+ * @memberOf Vector
+ */
+lunr.Vector.Node = function (idx, val, next) {
+ this.idx = idx
+ this.val = val
+ this.next = next
+}
+
+/**
+ * Inserts a new value at a position in a vector.
+ *
+ * @param {Number} The index at which to insert a value.
+ * @param {Object} The object to insert in the vector.
+ * @memberOf Vector.
+ */
+lunr.Vector.prototype.insert = function (idx, val) {
+ this._magnitude = undefined;
+ var list = this.list
+
+ if (!list) {
+ this.list = new lunr.Vector.Node (idx, val, list)
+ return this.length++
+ }
+
+ if (idx < list.idx) {
+ this.list = new lunr.Vector.Node (idx, val, list)
+ return this.length++
+ }
+
+ var prev = list,
+ next = list.next
+
+ while (next != undefined) {
+ if (idx < next.idx) {
+ prev.next = new lunr.Vector.Node (idx, val, next)
+ return this.length++
+ }
+
+ prev = next, next = next.next
+ }
+
+ prev.next = new lunr.Vector.Node (idx, val, next)
+ return this.length++
+}
+
+/**
+ * Calculates the magnitude of this vector.
+ *
+ * @returns {Number}
+ * @memberOf Vector
+ */
+lunr.Vector.prototype.magnitude = function () {
+ if (this._magnitude) return this._magnitude
+ var node = this.list,
+ sumOfSquares = 0,
+ val
+
+ while (node) {
+ val = node.val
+ sumOfSquares += val * val
+ node = node.next
+ }
+
+ return this._magnitude = Math.sqrt(sumOfSquares)
+}
+
+/**
+ * Calculates the dot product of this vector and another vector.
+ *
+ * @param {lunr.Vector} otherVector The vector to compute the dot product with.
+ * @returns {Number}
+ * @memberOf Vector
+ */
+lunr.Vector.prototype.dot = function (otherVector) {
+ var node = this.list,
+ otherNode = otherVector.list,
+ dotProduct = 0
+
+ while (node && otherNode) {
+ if (node.idx < otherNode.idx) {
+ node = node.next
+ } else if (node.idx > otherNode.idx) {
+ otherNode = otherNode.next
+ } else {
+ dotProduct += node.val * otherNode.val
+ node = node.next
+ otherNode = otherNode.next
+ }
+ }
+
+ return dotProduct
+}
+
+/**
+ * Calculates the cosine similarity between this vector and another
+ * vector.
+ *
+ * @param {lunr.Vector} otherVector The other vector to calculate the
+ * similarity with.
+ * @returns {Number}
+ * @memberOf Vector
+ */
+lunr.Vector.prototype.similarity = function (otherVector) {
+ return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude())
+}
+/*!
+ * lunr.SortedSet
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.SortedSets are used to maintain an array of uniq values in a sorted
+ * order.
+ *
+ * @constructor
+ */
+lunr.SortedSet = function () {
+ this.length = 0
+ this.elements = []
+}
+
+/**
+ * Loads a previously serialised sorted set.
+ *
+ * @param {Array} serialisedData The serialised set to load.
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.load = function (serialisedData) {
+ var set = new this
+
+ set.elements = serialisedData
+ set.length = serialisedData.length
+
+ return set
+}
+
+/**
+ * Inserts new items into the set in the correct position to maintain the
+ * order.
+ *
+ * @param {Object} The objects to add to this set.
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.add = function () {
+ var i, element
+
+ for (i = 0; i < arguments.length; i++) {
+ element = arguments[i]
+ if (~this.indexOf(element)) continue
+ this.elements.splice(this.locationFor(element), 0, element)
+ }
+
+ this.length = this.elements.length
+}
+
+/**
+ * Converts this sorted set into an array.
+ *
+ * @returns {Array}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.toArray = function () {
+ return this.elements.slice()
+}
+
+/**
+ * Creates a new array with the results of calling a provided function on every
+ * element in this sorted set.
+ *
+ * Delegates to Array.prototype.map and has the same signature.
+ *
+ * @param {Function} fn The function that is called on each element of the
+ * set.
+ * @param {Object} ctx An optional object that can be used as the context
+ * for the function fn.
+ * @returns {Array}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.map = function (fn, ctx) {
+ return this.elements.map(fn, ctx)
+}
+
+/**
+ * Executes a provided function once per sorted set element.
+ *
+ * Delegates to Array.prototype.forEach and has the same signature.
+ *
+ * @param {Function} fn The function that is called on each element of the
+ * set.
+ * @param {Object} ctx An optional object that can be used as the context
+ * @memberOf SortedSet
+ * for the function fn.
+ */
+lunr.SortedSet.prototype.forEach = function (fn, ctx) {
+ return this.elements.forEach(fn, ctx)
+}
+
+/**
+ * Returns the index at which a given element can be found in the
+ * sorted set, or -1 if it is not present.
+ *
+ * @param {Object} elem The object to locate in the sorted set.
+ * @returns {Number}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.indexOf = function (elem) {
+ var start = 0,
+ end = this.elements.length,
+ sectionLength = end - start,
+ pivot = start + Math.floor(sectionLength / 2),
+ pivotElem = this.elements[pivot]
+
+ while (sectionLength > 1) {
+ if (pivotElem === elem) return pivot
+
+ if (pivotElem < elem) start = pivot
+ if (pivotElem > elem) end = pivot
+
+ sectionLength = end - start
+ pivot = start + Math.floor(sectionLength / 2)
+ pivotElem = this.elements[pivot]
+ }
+
+ if (pivotElem === elem) return pivot
+
+ return -1
+}
+
+/**
+ * Returns the position within the sorted set that an element should be
+ * inserted at to maintain the current order of the set.
+ *
+ * This function assumes that the element to search for does not already exist
+ * in the sorted set.
+ *
+ * @param {Object} elem The elem to find the position for in the set
+ * @returns {Number}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.locationFor = function (elem) {
+ var start = 0,
+ end = this.elements.length,
+ sectionLength = end - start,
+ pivot = start + Math.floor(sectionLength / 2),
+ pivotElem = this.elements[pivot]
+
+ while (sectionLength > 1) {
+ if (pivotElem < elem) start = pivot
+ if (pivotElem > elem) end = pivot
+
+ sectionLength = end - start
+ pivot = start + Math.floor(sectionLength / 2)
+ pivotElem = this.elements[pivot]
+ }
+
+ if (pivotElem > elem) return pivot
+ if (pivotElem < elem) return pivot + 1
+}
+
+/**
+ * Creates a new lunr.SortedSet that contains the elements in the intersection
+ * of this set and the passed set.
+ *
+ * @param {lunr.SortedSet} otherSet The set to intersect with this set.
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.intersect = function (otherSet) {
+ var intersectSet = new lunr.SortedSet,
+ i = 0, j = 0,
+ a_len = this.length, b_len = otherSet.length,
+ a = this.elements, b = otherSet.elements
+
+ while (true) {
+ if (i > a_len - 1 || j > b_len - 1) break
+
+ if (a[i] === b[j]) {
+ intersectSet.add(a[i])
+ i++, j++
+ continue
+ }
+
+ if (a[i] < b[j]) {
+ i++
+ continue
+ }
+
+ if (a[i] > b[j]) {
+ j++
+ continue
+ }
+ };
+
+ return intersectSet
+}
+
+/**
+ * Makes a copy of this set
+ *
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.clone = function () {
+ var clone = new lunr.SortedSet
+
+ clone.elements = this.toArray()
+ clone.length = clone.elements.length
+
+ return clone
+}
+
+/**
+ * Creates a new lunr.SortedSet that contains the elements in the union
+ * of this set and the passed set.
+ *
+ * @param {lunr.SortedSet} otherSet The set to union with this set.
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.union = function (otherSet) {
+ var longSet, shortSet, unionSet
+
+ if (this.length >= otherSet.length) {
+ longSet = this, shortSet = otherSet
+ } else {
+ longSet = otherSet, shortSet = this
+ }
+
+ unionSet = longSet.clone()
+
+ unionSet.add.apply(unionSet, shortSet.toArray())
+
+ return unionSet
+}
+
+/**
+ * Returns a representation of the sorted set ready for serialisation.
+ *
+ * @returns {Array}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.toJSON = function () {
+ return this.toArray()
+}
+/*!
+ * lunr.Index
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.Index is object that manages a search index. It contains the indexes
+ * and stores all the tokens and document lookups. It also provides the main
+ * user facing API for the library.
+ *
+ * @constructor
+ */
+lunr.Index = function () {
+ this._fields = []
+ this._ref = 'id'
+ this.pipeline = new lunr.Pipeline
+ this.documentStore = new lunr.Store
+ this.tokenStore = new lunr.TokenStore
+ this.corpusTokens = new lunr.SortedSet
+ this.eventEmitter = new lunr.EventEmitter
+
+ this._idfCache = {}
+
+ this.on('add', 'remove', 'update', (function () {
+ this._idfCache = {}
+ }).bind(this))
+}
+
+/**
+ * Bind a handler to events being emitted by the index.
+ *
+ * The handler can be bound to many events at the same time.
+ *
+ * @param {String} [eventName] The name(s) of events to bind the function to.
+ * @param {Function} fn The serialised set to load.
+ * @memberOf Index
+ */
+lunr.Index.prototype.on = function () {
+ var args = Array.prototype.slice.call(arguments)
+ return this.eventEmitter.addListener.apply(this.eventEmitter, args)
+}
+
+/**
+ * Removes a handler from an event being emitted by the index.
+ *
+ * @param {String} eventName The name of events to remove the function from.
+ * @param {Function} fn The serialised set to load.
+ * @memberOf Index
+ */
+lunr.Index.prototype.off = function (name, fn) {
+ return this.eventEmitter.removeListener(name, fn)
+}
+
+/**
+ * Loads a previously serialised index.
+ *
+ * Issues a warning if the index being imported was serialised
+ * by a different version of lunr.
+ *
+ * @param {Object} serialisedData The serialised set to load.
+ * @returns {lunr.Index}
+ * @memberOf Index
+ */
+lunr.Index.load = function (serialisedData) {
+ if (serialisedData.version !== lunr.version) {
+ lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version)
+ }
+
+ var idx = new this
+
+ idx._fields = serialisedData.fields
+ idx._ref = serialisedData.ref
+
+ idx.documentStore = lunr.Store.load(serialisedData.documentStore)
+ idx.tokenStore = lunr.TokenStore.load(serialisedData.tokenStore)
+ idx.corpusTokens = lunr.SortedSet.load(serialisedData.corpusTokens)
+ idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline)
+
+ return idx
+}
+
+/**
+ * Adds a field to the list of fields that will be searchable within documents
+ * in the index.
+ *
+ * An optional boost param can be passed to affect how much tokens in this field
+ * rank in search results, by default the boost value is 1.
+ *
+ * Fields should be added before any documents are added to the index, fields
+ * that are added after documents are added to the index will only apply to new
+ * documents added to the index.
+ *
+ * @param {String} fieldName The name of the field within the document that
+ * should be indexed
+ * @param {Number} boost An optional boost that can be applied to terms in this
+ * field.
+ * @returns {lunr.Index}
+ * @memberOf Index
+ */
+lunr.Index.prototype.field = function (fieldName, opts) {
+ var opts = opts || {},
+ field = { name: fieldName, boost: opts.boost || 1 }
+
+ this._fields.push(field)
+ return this
+}
+
+/**
+ * Sets the property used to uniquely identify documents added to the index,
+ * by default this property is 'id'.
+ *
+ * This should only be changed before adding documents to the index, changing
+ * the ref property without resetting the index can lead to unexpected results.
+ *
+ * The value of ref can be of any type but it _must_ be stably comparable and
+ * orderable.
+ *
+ * @param {String} refName The property to use to uniquely identify the
+ * documents in the index.
+ * @param {Boolean} emitEvent Whether to emit add events, defaults to true
+ * @returns {lunr.Index}
+ * @memberOf Index
+ */
+lunr.Index.prototype.ref = function (refName) {
+ this._ref = refName
+ return this
+}
+
+/**
+ * Add a document to the index.
+ *
+ * This is the way new documents enter the index, this function will run the
+ * fields from the document through the index's pipeline and then add it to
+ * the index, it will then show up in search results.
+ *
+ * An 'add' event is emitted with the document that has been added and the index
+ * the document has been added to. This event can be silenced by passing false
+ * as the second argument to add.
+ *
+ * @param {Object} doc The document to add to the index.
+ * @param {Boolean} emitEvent Whether or not to emit events, default true.
+ * @memberOf Index
+ */
+lunr.Index.prototype.add = function (doc, emitEvent) {
+ var docTokens = {},
+ allDocumentTokens = new lunr.SortedSet,
+ docRef = doc[this._ref],
+ emitEvent = emitEvent === undefined ? true : emitEvent
+
+ this._fields.forEach(function (field) {
+ var fieldTokens = this.pipeline.run(lunr.tokenizer(doc[field.name]))
+
+ docTokens[field.name] = fieldTokens
+ lunr.SortedSet.prototype.add.apply(allDocumentTokens, fieldTokens)
+ }, this)
+
+ this.documentStore.set(docRef, allDocumentTokens)
+ lunr.SortedSet.prototype.add.apply(this.corpusTokens, allDocumentTokens.toArray())
+
+ for (var i = 0; i < allDocumentTokens.length; i++) {
+ var token = allDocumentTokens.elements[i]
+ var tf = this._fields.reduce(function (memo, field) {
+ var fieldLength = docTokens[field.name].length
+
+ if (!fieldLength) return memo
+
+ var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length
+
+ return memo + (tokenCount / fieldLength * field.boost)
+ }, 0)
+
+ this.tokenStore.add(token, { ref: docRef, tf: tf })
+ };
+
+ if (emitEvent) this.eventEmitter.emit('add', doc, this)
+}
+
+/**
+ * Removes a document from the index.
+ *
+ * To make sure documents no longer show up in search results they can be
+ * removed from the index using this method.
+ *
+ * The document passed only needs to have the same ref property value as the
+ * document that was added to the index, they could be completely different
+ * objects.
+ *
+ * A 'remove' event is emitted with the document that has been removed and the index
+ * the document has been removed from. This event can be silenced by passing false
+ * as the second argument to remove.
+ *
+ * @param {Object} doc The document to remove from the index.
+ * @param {Boolean} emitEvent Whether to emit remove events, defaults to true
+ * @memberOf Index
+ */
+lunr.Index.prototype.remove = function (doc, emitEvent) {
+ var docRef = doc[this._ref],
+ emitEvent = emitEvent === undefined ? true : emitEvent
+
+ if (!this.documentStore.has(docRef)) return
+
+ var docTokens = this.documentStore.get(docRef)
+
+ this.documentStore.remove(docRef)
+
+ docTokens.forEach(function (token) {
+ this.tokenStore.remove(token, docRef)
+ }, this)
+
+ if (emitEvent) this.eventEmitter.emit('remove', doc, this)
+}
+
+/**
+ * Updates a document in the index.
+ *
+ * When a document contained within the index gets updated, fields changed,
+ * added or removed, to make sure it correctly matched against search queries,
+ * it should be updated in the index.
+ *
+ * This method is just a wrapper around `remove` and `add`
+ *
+ * An 'update' event is emitted with the document that has been updated and the index.
+ * This event can be silenced by passing false as the second argument to update. Only
+ * an update event will be fired, the 'add' and 'remove' events of the underlying calls
+ * are silenced.
+ *
+ * @param {Object} doc The document to update in the index.
+ * @param {Boolean} emitEvent Whether to emit update events, defaults to true
+ * @see Index.prototype.remove
+ * @see Index.prototype.add
+ * @memberOf Index
+ */
+lunr.Index.prototype.update = function (doc, emitEvent) {
+ var emitEvent = emitEvent === undefined ? true : emitEvent
+
+ this.remove(doc, false)
+ this.add(doc, false)
+
+ if (emitEvent) this.eventEmitter.emit('update', doc, this)
+}
+
+/**
+ * Calculates the inverse document frequency for a token within the index.
+ *
+ * @param {String} token The token to calculate the idf of.
+ * @see Index.prototype.idf
+ * @private
+ * @memberOf Index
+ */
+lunr.Index.prototype.idf = function (term) {
+ var cacheKey = "@" + term
+ if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey]
+
+ var documentFrequency = this.tokenStore.count(term),
+ idf = 1
+
+ if (documentFrequency > 0) {
+ idf = 1 + Math.log(this.documentStore.length / documentFrequency)
+ }
+
+ return this._idfCache[cacheKey] = idf
+}
+
+/**
+ * Searches the index using the passed query.
+ *
+ * Queries should be a string, multiple words are allowed and will lead to an
+ * AND based query, e.g. `idx.search('foo bar')` will run a search for
+ * documents containing both 'foo' and 'bar'.
+ *
+ * All query tokens are passed through the same pipeline that document tokens
+ * are passed through, so any language processing involved will be run on every
+ * query term.
+ *
+ * Each query term is expanded, so that the term 'he' might be expanded to
+ * 'hello' and 'help' if those terms were already included in the index.
+ *
+ * Matching documents are returned as an array of objects, each object contains
+ * the matching document ref, as set for this index, and the similarity score
+ * for this document against the query.
+ *
+ * @param {String} query The query to search the index with.
+ * @returns {Object}
+ * @see Index.prototype.idf
+ * @see Index.prototype.documentVector
+ * @memberOf Index
+ */
+lunr.Index.prototype.search = function (query) {
+ var queryTokens = this.pipeline.run(lunr.tokenizer(query)),
+ queryVector = new lunr.Vector,
+ documentSets = [],
+ fieldBoosts = this._fields.reduce(function (memo, f) { return memo + f.boost }, 0)
+
+ var hasSomeToken = queryTokens.some(function (token) {
+ return this.tokenStore.has(token)
+ }, this)
+
+ if (!hasSomeToken) return []
+
+ queryTokens
+ .forEach(function (token, i, tokens) {
+ var tf = 1 / tokens.length * this._fields.length * fieldBoosts,
+ self = this
+
+ var set = this.tokenStore.expand(token).reduce(function (memo, key) {
+ var pos = self.corpusTokens.indexOf(key),
+ idf = self.idf(key),
+ similarityBoost = 1,
+ set = new lunr.SortedSet
+
+ // if the expanded key is not an exact match to the token then
+ // penalise the score for this key by how different the key is
+ // to the token.
+ if (key !== token) {
+ var diff = Math.max(3, key.length - token.length)
+ similarityBoost = 1 / Math.log(diff)
+ }
+
+ // calculate the query tf-idf score for this token
+ // applying an similarityBoost to ensure exact matches
+ // these rank higher than expanded terms
+ if (pos > -1) queryVector.insert(pos, tf * idf * similarityBoost)
+
+ // add all the documents that have this key into a set
+ // ensuring that the type of key is preserved
+ var matchingDocuments = self.tokenStore.get(key),
+ refs = Object.keys(matchingDocuments),
+ refsLen = refs.length
+
+ for (var i = 0; i < refsLen; i++) {
+ set.add(matchingDocuments[refs[i]].ref)
+ }
+
+ return memo.union(set)
+ }, new lunr.SortedSet)
+
+ documentSets.push(set)
+ }, this)
+
+ var documentSet = documentSets.reduce(function (memo, set) {
+ return memo.intersect(set)
+ })
+
+ return documentSet
+ .map(function (ref) {
+ return { ref: ref, score: queryVector.similarity(this.documentVector(ref)) }
+ }, this)
+ .sort(function (a, b) {
+ return b.score - a.score
+ })
+}
+
+/**
+ * Generates a vector containing all the tokens in the document matching the
+ * passed documentRef.
+ *
+ * The vector contains the tf-idf score for each token contained in the
+ * document with the passed documentRef. The vector will contain an element
+ * for every token in the indexes corpus, if the document does not contain that
+ * token the element will be 0.
+ *
+ * @param {Object} documentRef The ref to find the document with.
+ * @returns {lunr.Vector}
+ * @private
+ * @memberOf Index
+ */
+lunr.Index.prototype.documentVector = function (documentRef) {
+ var documentTokens = this.documentStore.get(documentRef),
+ documentTokensLength = documentTokens.length,
+ documentVector = new lunr.Vector
+
+ for (var i = 0; i < documentTokensLength; i++) {
+ var token = documentTokens.elements[i],
+ tf = this.tokenStore.get(token)[documentRef].tf,
+ idf = this.idf(token)
+
+ documentVector.insert(this.corpusTokens.indexOf(token), tf * idf)
+ };
+
+ return documentVector
+}
+
+/**
+ * Returns a representation of the index ready for serialisation.
+ *
+ * @returns {Object}
+ * @memberOf Index
+ */
+lunr.Index.prototype.toJSON = function () {
+ return {
+ version: lunr.version,
+ fields: this._fields,
+ ref: this._ref,
+ documentStore: this.documentStore.toJSON(),
+ tokenStore: this.tokenStore.toJSON(),
+ corpusTokens: this.corpusTokens.toJSON(),
+ pipeline: this.pipeline.toJSON()
+ }
+}
+
+/**
+ * Applies a plugin to the current index.
+ *
+ * A plugin is a function that is called with the index as its context.
+ * Plugins can be used to customise or extend the behaviour the index
+ * in some way. A plugin is just a function, that encapsulated the custom
+ * behaviour that should be applied to the index.
+ *
+ * The plugin function will be called with the index as its argument, additional
+ * arguments can also be passed when calling use. The function will be called
+ * with the index as its context.
+ *
+ * Example:
+ *
+ * var myPlugin = function (idx, arg1, arg2) {
+ * // `this` is the index to be extended
+ * // apply any extensions etc here.
+ * }
+ *
+ * var idx = lunr(function () {
+ * this.use(myPlugin, 'arg1', 'arg2')
+ * })
+ *
+ * @param {Function} plugin The plugin to apply.
+ * @memberOf Index
+ */
+lunr.Index.prototype.use = function (plugin) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ args.unshift(this)
+ plugin.apply(this, args)
+}
+/*!
+ * lunr.Store
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.Store is a simple key-value store used for storing sets of tokens for
+ * documents stored in index.
+ *
+ * @constructor
+ * @module
+ */
+lunr.Store = function () {
+ this.store = {}
+ this.length = 0
+}
+
+/**
+ * Loads a previously serialised store
+ *
+ * @param {Object} serialisedData The serialised store to load.
+ * @returns {lunr.Store}
+ * @memberOf Store
+ */
+lunr.Store.load = function (serialisedData) {
+ var store = new this
+
+ store.length = serialisedData.length
+ store.store = Object.keys(serialisedData.store).reduce(function (memo, key) {
+ memo[key] = lunr.SortedSet.load(serialisedData.store[key])
+ return memo
+ }, {})
+
+ return store
+}
+
+/**
+ * Stores the given tokens in the store against the given id.
+ *
+ * @param {Object} id The key used to store the tokens against.
+ * @param {Object} tokens The tokens to store against the key.
+ * @memberOf Store
+ */
+lunr.Store.prototype.set = function (id, tokens) {
+ if (!this.has(id)) this.length++
+ this.store[id] = tokens
+}
+
+/**
+ * Retrieves the tokens from the store for a given key.
+ *
+ * @param {Object} id The key to lookup and retrieve from the store.
+ * @returns {Object}
+ * @memberOf Store
+ */
+lunr.Store.prototype.get = function (id) {
+ return this.store[id]
+}
+
+/**
+ * Checks whether the store contains a key.
+ *
+ * @param {Object} id The id to look up in the store.
+ * @returns {Boolean}
+ * @memberOf Store
+ */
+lunr.Store.prototype.has = function (id) {
+ return id in this.store
+}
+
+/**
+ * Removes the value for a key in the store.
+ *
+ * @param {Object} id The id to remove from the store.
+ * @memberOf Store
+ */
+lunr.Store.prototype.remove = function (id) {
+ if (!this.has(id)) return
+
+ delete this.store[id]
+ this.length--
+}
+
+/**
+ * Returns a representation of the store ready for serialisation.
+ *
+ * @returns {Object}
+ * @memberOf Store
+ */
+lunr.Store.prototype.toJSON = function () {
+ return {
+ store: this.store,
+ length: this.length
+ }
+}
+
+/*!
+ * lunr.stemmer
+ * Copyright (C) 2015 Oliver Nightingale
+ * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
+ */
+
+/**
+ * lunr.stemmer is an english language stemmer, this is a JavaScript
+ * implementation of the PorterStemmer taken from http://tartarus.org/~martin
+ *
+ * @module
+ * @param {String} str The string to stem
+ * @returns {String}
+ * @see lunr.Pipeline
+ */
+lunr.stemmer = (function(){
+ var step2list = {
+ "ational" : "ate",
+ "tional" : "tion",
+ "enci" : "ence",
+ "anci" : "ance",
+ "izer" : "ize",
+ "bli" : "ble",
+ "alli" : "al",
+ "entli" : "ent",
+ "eli" : "e",
+ "ousli" : "ous",
+ "ization" : "ize",
+ "ation" : "ate",
+ "ator" : "ate",
+ "alism" : "al",
+ "iveness" : "ive",
+ "fulness" : "ful",
+ "ousness" : "ous",
+ "aliti" : "al",
+ "iviti" : "ive",
+ "biliti" : "ble",
+ "logi" : "log"
+ },
+
+ step3list = {
+ "icate" : "ic",
+ "ative" : "",
+ "alize" : "al",
+ "iciti" : "ic",
+ "ical" : "ic",
+ "ful" : "",
+ "ness" : ""
+ },
+
+ c = "[^aeiou]", // consonant
+ v = "[aeiouy]", // vowel
+ C = c + "[^aeiouy]*", // consonant sequence
+ V = v + "[aeiou]*", // vowel sequence
+
+ mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0
+ meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1
+ mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1
+ s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ var re_mgr0 = new RegExp(mgr0);
+ var re_mgr1 = new RegExp(mgr1);
+ var re_meq1 = new RegExp(meq1);
+ var re_s_v = new RegExp(s_v);
+
+ var re_1a = /^(.+?)(ss|i)es$/;
+ var re2_1a = /^(.+?)([^s])s$/;
+ var re_1b = /^(.+?)eed$/;
+ var re2_1b = /^(.+?)(ed|ing)$/;
+ var re_1b_2 = /.$/;
+ var re2_1b_2 = /(at|bl|iz)$/;
+ var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$");
+ var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+
+ var re_1c = /^(.+?[^aeiou])y$/;
+ var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+
+ var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+
+ var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ var re2_4 = /^(.+?)(s|t)(ion)$/;
+
+ var re_5 = /^(.+?)e$/;
+ var re_5_1 = /ll$/;
+ var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+
+ var porterStemmer = function porterStemmer(w) {
+ var stem,
+ suffix,
+ firstch,
+ re,
+ re2,
+ re3,
+ re4;
+
+ if (w.length < 3) { return w; }
+
+ firstch = w.substr(0,1);
+ if (firstch == "y") {
+ w = firstch.toUpperCase() + w.substr(1);
+ }
+
+ // Step 1a
+ re = re_1a
+ re2 = re2_1a;
+
+ if (re.test(w)) { w = w.replace(re,"$1$2"); }
+ else if (re2.test(w)) { w = w.replace(re2,"$1$2"); }
+
+ // Step 1b
+ re = re_1b;
+ re2 = re2_1b;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = re_mgr0;
+ if (re.test(fp[1])) {
+ re = re_1b_2;
+ w = w.replace(re,"");
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = re_s_v;
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = re2_1b_2;
+ re3 = re3_1b_2;
+ re4 = re4_1b_2;
+ if (re2.test(w)) { w = w + "e"; }
+ else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); }
+ else if (re4.test(w)) { w = w + "e"; }
+ }
+ }
+
+ // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)
+ re = re_1c;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = re_2;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = re_mgr0;
+ if (re.test(stem)) {
+ w = stem + step2list[suffix];
+ }
+ }
+
+ // Step 3
+ re = re_3;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = re_mgr0;
+ if (re.test(stem)) {
+ w = stem + step3list[suffix];
+ }
+ }
+
+ // Step 4
+ re = re_4;
+ re2 = re2_4;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = re_mgr1;
+ if (re.test(stem)) {
+ w = stem;
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = re_mgr1;
+ if (re2.test(stem)) {
+ w = stem;
+ }
+ }
+
+ // Step 5
+ re = re_5;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = re_mgr1;
+ re2 = re_meq1;
+ re3 = re3_5;
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
+ w = stem;
+ }
+ }
+
+ re = re_5_1;
+ re2 = re_mgr1;
+ if (re.test(w) && re2.test(w)) {
+ re = re_1b_2;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+
+ if (firstch == "y") {
+ w = firstch.toLowerCase() + w.substr(1);
+ }
+
+ return w;
+ };
+
+ return porterStemmer;
+})();
+
+lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')
+/*!
+ * lunr.stopWordFilter
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.generateStopWordFilter builds a stopWordFilter function from the provided
+ * list of stop words.
+ *
+ * The built in lunr.stopWordFilter is built using this generator and can be used
+ * to generate custom stopWordFilters for applications or non English languages.
+ *
+ * @module
+ * @param {Array} token The token to pass through the filter
+ * @returns {Function}
+ * @see lunr.Pipeline
+ * @see lunr.stopWordFilter
+ */
+lunr.generateStopWordFilter = function (stopWords) {
+ var words = stopWords.reduce(function (memo, stopWord) {
+ memo[stopWord] = stopWord
+ return memo
+ }, {})
+
+ return function (token) {
+ if (token && words[token] !== token) return token
+ }
+}
+
+/**
+ * lunr.stopWordFilter is an English language stop word list filter, any words
+ * contained in the list will not be passed through the filter.
+ *
+ * This is intended to be used in the Pipeline. If the token does not pass the
+ * filter then undefined will be returned.
+ *
+ * @module
+ * @param {String} token The token to pass through the filter
+ * @returns {String}
+ * @see lunr.Pipeline
+ */
+lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'all',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'any',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'do',
+ 'does',
+ 'either',
+ 'else',
+ 'ever',
+ 'every',
+ 'for',
+ 'from',
+ 'get',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'in',
+ 'into',
+ 'is',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'let',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'only',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'where',
+ 'which',
+ 'while',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'with',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+])
+
+lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
+/*!
+ * lunr.trimmer
+ * Copyright (C) 2015 Oliver Nightingale
+ */
+
+/**
+ * lunr.trimmer is a pipeline function for trimming non word
+ * characters from the begining and end of tokens before they
+ * enter the index.
+ *
+ * This implementation may not work correctly for non latin
+ * characters and should either be removed or adapted for use
+ * with languages with non-latin characters.
+ *
+ * @module
+ * @param {String} token The token to pass through the filter
+ * @returns {String}
+ * @see lunr.Pipeline
+ */
+lunr.trimmer = function (token) {
+ return token.replace(/^\W+/, '').replace(/\W+$/, '')
+}
+
+lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')
+/*!
+ * lunr.stemmer
+ * Copyright (C) 2015 Oliver Nightingale
+ * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
+ */
+
+/**
+ * lunr.TokenStore is used for efficient storing and lookup of the reverse
+ * index of token to document ref.
+ *
+ * @constructor
+ */
+lunr.TokenStore = function () {
+ this.root = { docs: {} }
+ this.length = 0
+}
+
+/**
+ * Loads a previously serialised token store
+ *
+ * @param {Object} serialisedData The serialised token store to load.
+ * @returns {lunr.TokenStore}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.load = function (serialisedData) {
+ var store = new this
+
+ store.root = serialisedData.root
+ store.length = serialisedData.length
+
+ return store
+}
+
+/**
+ * Adds a new token doc pair to the store.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to store the doc under
+ * @param {Object} doc The doc to store against the token
+ * @param {Object} root An optional node at which to start looking for the
+ * correct place to enter the doc, by default the root of this lunr.TokenStore
+ * is used.
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.add = function (token, doc, root) {
+ var root = root || this.root,
+ key = token.charAt(0),
+ rest = token.slice(1)
+
+ if (!(key in root)) root[key] = {docs: {}}
+
+ if (rest.length === 0) {
+ root[key].docs[doc.ref] = doc
+ this.length += 1
+ return
+ } else {
+ return this.add(rest, doc, root[key])
+ }
+}
+
+/**
+ * Checks whether this key is contained within this lunr.TokenStore.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to check for
+ * @param {Object} root An optional node at which to start
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.has = function (token) {
+ if (!token) return false
+
+ var node = this.root
+
+ for (var i = 0; i < token.length; i++) {
+ if (!node[token.charAt(i)]) return false
+
+ node = node[token.charAt(i)]
+ }
+
+ return true
+}
+
+/**
+ * Retrieve a node from the token store for a given token.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to get the node for.
+ * @param {Object} root An optional node at which to start.
+ * @returns {Object}
+ * @see TokenStore.prototype.get
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.getNode = function (token) {
+ if (!token) return {}
+
+ var node = this.root
+
+ for (var i = 0; i < token.length; i++) {
+ if (!node[token.charAt(i)]) return {}
+
+ node = node[token.charAt(i)]
+ }
+
+ return node
+}
+
+/**
+ * Retrieve the documents for a node for the given token.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to get the documents for.
+ * @param {Object} root An optional node at which to start.
+ * @returns {Object}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.get = function (token, root) {
+ return this.getNode(token, root).docs || {}
+}
+
+lunr.TokenStore.prototype.count = function (token, root) {
+ return Object.keys(this.get(token, root)).length
+}
+
+/**
+ * Remove the document identified by ref from the token in the store.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to get the documents for.
+ * @param {String} ref The ref of the document to remove from this token.
+ * @param {Object} root An optional node at which to start.
+ * @returns {Object}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.remove = function (token, ref) {
+ if (!token) return
+ var node = this.root
+
+ for (var i = 0; i < token.length; i++) {
+ if (!(token.charAt(i) in node)) return
+ node = node[token.charAt(i)]
+ }
+
+ delete node.docs[ref]
+}
+
+/**
+ * Find all the possible suffixes of the passed token using tokens
+ * currently in the store.
+ *
+ * @param {String} token The token to expand.
+ * @returns {Array}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.expand = function (token, memo) {
+ var root = this.getNode(token),
+ docs = root.docs || {},
+ memo = memo || []
+
+ if (Object.keys(docs).length) memo.push(token)
+
+ Object.keys(root)
+ .forEach(function (key) {
+ if (key === 'docs') return
+
+ memo.concat(this.expand(token + key, memo))
+ }, this)
+
+ return memo
+}
+
+/**
+ * Returns a representation of the token store ready for serialisation.
+ *
+ * @returns {Object}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.toJSON = function () {
+ return {
+ root: this.root,
+ length: this.length
+ }
+}
+
+ /**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+ ;(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like enviroments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ root.lunr = factory()
+ }
+ }(this, function () {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return lunr
+ }))
+})();
diff --git a/assets/vendor/lunr.js/lunr.min.js b/assets/vendor/lunr.js/lunr.min.js
new file mode 100644
index 0000000000..f008e8b881
--- /dev/null
+++ b/assets/vendor/lunr.js/lunr.min.js
@@ -0,0 +1,7 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.6.0
+ * Copyright (C) 2015 Oliver Nightingale
+ * MIT Licensed
+ * @license
+ */
+!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.6.0",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return t.utils.asString(e).toLowerCase()}):e.toString().trim().toLowerCase().split(t.tokenizer.seperator):[]},t.tokenizer.seperator=/[\s\-]+/,t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},r=new t.SortedSet,o=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=o,t.SortedSet.prototype.add.apply(r,o)},this),this.documentStore.set(o,r),t.SortedSet.prototype.add.apply(this.corpusTokens,r.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),p=Object.keys(f),d=p.length,v=0;d>v;v++)l.add(f[p[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),p=new RegExp(u),d=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,m=/^(.+?)eed$/,g=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+r+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=d,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=m,a=g,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=p,a.test(i)&&(n=i,a=S,h=w,u=x,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n"
+ ],
+ "main": [
+ "octicons/sprockets-octicons.scss",
+ "octicons/octicons.eot",
+ "octicons/octicons.svg",
+ "octicons/octicons.ttf",
+ "octicons/octicons.woff"
+ ],
+ "keywords": [
+ "GitHub",
+ "icons",
+ "font",
+ "web font",
+ "icon font"
+ ],
+ "ignore": [
+ "**/.*",
+ "bower_components"
+ ],
+ "version": "3.0.1",
+ "_release": "3.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v3.0.1",
+ "commit": "15b128d80c226874339f9873916cd05f2df639ae"
+ },
+ "_source": "git://github.com/github/octicons.git",
+ "_target": "3.0.1",
+ "_originalSource": "octicons"
+}
\ No newline at end of file
diff --git a/assets/vendor/octicons/CHANGELOG.md b/assets/vendor/octicons/CHANGELOG.md
new file mode 100644
index 0000000000..f104b996cb
--- /dev/null
+++ b/assets/vendor/octicons/CHANGELOG.md
@@ -0,0 +1,162 @@
+### 3.0.0
+
+Removes
+
+- `microscope`
+- `beer`
+- `split`
+- `puzzle`
+- `steps`
+- `podium`
+- `timer`
+- all `alignment` icons
+- all `move` icons
+- all `playback` icons
+- all `jump` icons
+
+Adds
+
+- `beaker`
+- `bell`
+- `desktop-download`
+- `watch`
+
+Line-weight changes, sizing normalization, and new drawings
+
+- `circle-slash`
+- `lock`
+- `cloud-upload`
+- `cloud-download`
+- `plus`
+- `✕`
+- `broadcast`
+- `lock`
+- all `repo` icons
+- organization
+- person
+- all `chevrons` & `triangles`
+- all `diff` icons
+- `clippy`
+- all `issue` and circular icons
+- `rss`
+- `ruby`
+- `cancel`
+- `settings`
+- `mirror`
+- `external-link`
+- `history`
+- `gear`
+- `settings`
+- `info`
+- `history`
+- `package`
+- `gist-secret`
+- `rocket`
+- `law`
+- `telescope`
+- `search`
+- `tag`
+- `normal-screen`
+- `iphone`
+- `no-new-line`
+- `desktop`
+- all `git` icons
+- `circuit-board`
+- `heart`
+- `home`
+- `briefcase`
+- `wiki`
+- `bookmark`
+- `briefcase`
+- `calendar`
+- `color-mode`
+- `comment`
+- `discussions`
+- `credit-card`
+- `dashboard`
+- `camera`
+- `video`
+- `bug`
+- `desktop`
+- `ellipses`
+- `eye`
+- all `files` & `folders`
+- `fold`
+- `unfold`
+- `gift`
+- `graph`
+- `hubot`
+- `inbox`
+- `jersey`
+- `keyboard`
+- `light-bulb`
+- `link`
+- `location`
+- `mail`
+- `mail-read`
+- `marker`
+- `plug`
+- `mute`
+- `pencil`
+- `push-pin`
+- `fullscreen`
+- `unfullscreen`
+- `server`
+- `sign-in`
+- `sign-out`
+- `tag`
+- `terminal`
+- `thumbs-up`
+- `thumbs-down`
+- `trash`
+- `unmute`
+- `versions`
+- `gist`
+- `key`
+- `megaphone`
+- `checklist`
+
+## 2.4.1 (June 2, 2015)
+
+- Add the scss file I forgot to include
+
+## 2.4.0 (June 2, 2015)
+
+- Add `octicons.scss`
+- Revert path changes to `sprockets-octicons.scss`, as they broke octicons in sprockets.
+
+## 2.3.0 (May 28, 2015)
+
+- Add a path variable to `sprockets-octicons.scss` to be consistent with octicons.less`
+
+## 2.2.3 (May 21, 2015)
+
+- Use SPDX license identifiers in package.json
+
+## 2.2.2 (April 1, 2015)
+
+Fixes file icons for
+
+- `file-binary`
+- `file-code`
+- `file-media`
+- `file-pdf`
+- `file-symlink-file`
+- `file-text`
+- `file-zip`
+
+## 2.2.1 (March 30, 2015)
+
+- Fix vector artifact and smooth curves in `mark-github`
+
+## 2.2.0 (Feb 18, 2015)
+
+- Add two new icons: `thumbsup` and `thumbsdown`
+
+## 2.0.1 (June 16, 2014)
+
+- Add mention of github.com/logos to the license
+
+## 2.0.0 (June 16, 2014)
+
+- Hello world
diff --git a/assets/vendor/octicons/CONTRIBUTING.md b/assets/vendor/octicons/CONTRIBUTING.md
new file mode 100644
index 0000000000..57694316f0
--- /dev/null
+++ b/assets/vendor/octicons/CONTRIBUTING.md
@@ -0,0 +1,3 @@
+The contents of */octicons* */svg* are generated by an automated process. Changes to these files may be accepted, but may also be overwritten.
+
+Octicons is GitHub's icon font. At this time, new icons will only add icons when they are needed for GitHub products.
diff --git a/assets/vendor/octicons/LICENSE.txt b/assets/vendor/octicons/LICENSE.txt
new file mode 100644
index 0000000000..69aa0d5426
--- /dev/null
+++ b/assets/vendor/octicons/LICENSE.txt
@@ -0,0 +1,9 @@
+(c) 2012-2015 GitHub
+
+When using the GitHub logos, be sure to follow the GitHub logo guidelines (https://github.com/logos)
+
+Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL)
+Applies to all font files
+
+Code License: MIT (http://choosealicense.com/licenses/mit/)
+Applies to all other files
diff --git a/assets/vendor/octicons/README.md b/assets/vendor/octicons/README.md
new file mode 100644
index 0000000000..b462e68318
--- /dev/null
+++ b/assets/vendor/octicons/README.md
@@ -0,0 +1,127 @@
+# Octicons!
+
+This is the [Bower][bower] package for [GitHub Octicons][octicons].
+
+## Add Octicons to your project
+
+1. Create a new file called *bower.json* (if you don't have one already).
+
+2. Add a new line for the Octicon dependency, pointing to the correct repository:
+
+ ``` json
+ {
+ "name": "my_great_project",
+ "dependencies": {
+ "octicons": "*"
+ }
+ }
+ ```
+
+3. Run `bower install`. The Octicons styles will be downloaded to *bower_components/octicons*.
+
+4. Link to the `octicons.css` stylesheet in the `` of your `` page:
+
+ ``` html
+
+ ```
+
+4. Simply use an icon in your HTML page:
+
+ ``` html
+
+ ```
+
+### Rails' asset pipeline
+
+Octicons includes a stylesheet specifically for [Rails 4/Sprockets][sprockets].
+
+1. Create a new file called *vendor/assets/bower.json* (if you don't have one already).
+
+2. Add a new line for the Octicon dependency, pointing to the correct repository:
+
+ ``` json
+ {
+ "name": "my_great_project",
+ "dependencies": {
+ "octicons": "*"
+ }
+ }
+ ```
+
+3. `cd` into `vendor/assets` and run `bower install`. The Octicons styles will be downloaded to *vendor/assets/bower_components/octicons*.
+
+4. Open your config/application.rb, and add this line inside your Application:
+
+ ``` ruby
+ config.assets.precompile += %w(*.svg *.eot *.woff *.ttf)
+ ```
+
+5. In your application stylesheet, require `sprockets-octicons`:
+
+ ``` css
+ /*
+ = require sprockets-octicons
+ */
+ ```
+
+6. Simply use an icon in your HTML page:
+
+ ``` html
+
+ ```
+
+7. If you want a view helper, add something like this to *app/helpers/application_helper.rb*:
+
+ ``` ruby
+ def octicon(code)
+ content_tag :span, '', :class => "octicon octicon-#{code.to_s.dasherize}"
+ end
+ ```
+
+## Best practices
+
+- Octicons look best in sizes that are multiples of 16px. You can update the size using the `font-size` CSS property. For example:
+
+ ``` css
+ .octicon {
+ font-size: 32px;
+ }
+ ```
+
+- Octicons are not monospaced. This lets them work well next to type, but it means they won’t stack nicely by default. If you intend to stack octicons, such as in navigation, you will want to add some CSS to make them the same width, and centered. For example:
+
+ ``` css
+ .navigation .octicon {
+ width: 16px;
+ text-align: center;
+ }
+ ```
+
+### Resources
+
+- [octicons.github.com](http://octicons.github.com/) - the Octicons website
+- Read why [icon fonts are awesome](http://css-tricks.com/examples/IconFont/)
+- How to compose your [HTML for icon font usage](http://css-tricks.com/html-for-icon-font-usage/)
+
+## Why can't I see the characters in Font Book??
+
+Give this a try, you should be all set:
+
+
+
+## FAQ
+
+Check out [issues with the FAQ label](https://github.com/github/octicons/issues?q=is%3Aclosed+is%3Aissue+label%3AFAQ).
+
+## Versions
+
+Octicons operates similarly to [Semver](http://semver.org/) with the following version convention:
+
+- Major: Breaking changes — removed icons, markup changes, unicode switches, css renames, icon redesigns
+- Minor: Non-breaking changes — new icons, new aliases, minor icon changes
+- Patch: Unnoticeable tweaks — slight visual changes, package updates
+
+
+[octicons]: http://octicons.github.com
+[bower]: http://bower.io/
+[sprockets]: http://guides.rubyonrails.org/asset_pipeline.html
diff --git a/assets/vendor/octicons/bower.json b/assets/vendor/octicons/bower.json
new file mode 100644
index 0000000000..5b9fc4f8c3
--- /dev/null
+++ b/assets/vendor/octicons/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "octicons",
+ "description": "GitHub's icon font",
+ "license": [
+ "OFL-1.1",
+ "MIT"
+ ],
+ "homepage": "https://octicons.github.com",
+ "authors": [
+ "GitHub "
+ ],
+ "main": [
+ "octicons/sprockets-octicons.scss",
+ "octicons/octicons.eot",
+ "octicons/octicons.svg",
+ "octicons/octicons.ttf",
+ "octicons/octicons.woff"
+ ],
+ "keywords": [
+ "GitHub",
+ "icons",
+ "font",
+ "web font",
+ "icon font"
+ ],
+ "ignore": [
+ "**/.*",
+ "bower_components"
+ ]
+}
diff --git a/assets/vendor/octicons/octicons/README.md b/assets/vendor/octicons/octicons/README.md
new file mode 100644
index 0000000000..1007073350
--- /dev/null
+++ b/assets/vendor/octicons/octicons/README.md
@@ -0,0 +1 @@
+If you intend to install Octicons locally, install `octicons-local.ttf`. It should appear as “github-octicons” in your font list. It is specially designed not to conflict with GitHub's web fonts.
diff --git a/assets/vendor/octicons/octicons/octicons-local.ttf b/assets/vendor/octicons/octicons/octicons-local.ttf
new file mode 100644
index 0000000000..9e2fb2a8ee
Binary files /dev/null and b/assets/vendor/octicons/octicons/octicons-local.ttf differ
diff --git a/static/shared/css/octicons.css b/assets/vendor/octicons/octicons/octicons.css
similarity index 71%
rename from static/shared/css/octicons.css
rename to assets/vendor/octicons/octicons/octicons.css
index d3d1be255b..72f32b9889 100644
--- a/static/shared/css/octicons.css
+++ b/assets/vendor/octicons/octicons/octicons.css
@@ -1,7 +1,6 @@
@font-face {
font-family: 'octicons';
- src: url('octicons.eot');
- src: url('octicons.eot#iefix') format('embedded-opentype'),
+ src: url('octicons.eot?#iefix') format('embedded-opentype'),
url('octicons.woff') format('woff'),
url('octicons.ttf') format('truetype'),
url('octicons.svg#octicons') format('svg');
@@ -15,25 +14,21 @@
.mega-octicon is optimized for 32px but can be used larger.
*/
-.octicon {
- font: normal normal 16px octicons;
- line-height: 1;
- display: inline-block;
- text-decoration: none;
- -webkit-font-smoothing: antialiased;
-}
-.mega-octicon {
- font: normal normal 32px octicons;
- line-height: 1;
+.octicon, .mega-octicon {
+ font: normal normal normal 16px/1 octicons;
display: inline-block;
text-decoration: none;
+ text-rendering: auto;
-webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
+.mega-octicon { font-size: 32px; }
.octicon-alert:before { content: '\f02d'} /* */
-.octicon-alignment-align:before { content: '\f08a'} /* */
-.octicon-alignment-aligned-to:before { content: '\f08e'} /* */
-.octicon-alignment-unalign:before { content: '\f08b'} /* */
.octicon-arrow-down:before { content: '\f03f'} /* */
.octicon-arrow-left:before { content: '\f040'} /* */
.octicon-arrow-right:before { content: '\f03e'} /* */
@@ -42,7 +37,9 @@
.octicon-arrow-small-right:before { content: '\f071'} /* */
.octicon-arrow-small-up:before { content: '\f09f'} /* */
.octicon-arrow-up:before { content: '\f03d'} /* */
-.octicon-beer:before { content: '\f069'} /* */
+.octicon-microscope:before,
+.octicon-beaker:before { content: '\f0dd'} /* */
+.octicon-bell:before { content: '\f0de'} /* */
.octicon-book:before { content: '\f007'} /* */
.octicon-bookmark:before { content: '\f07b'} /* */
.octicon-briefcase:before { content: '\f0d3'} /* */
@@ -57,19 +54,22 @@
.octicon-chevron-right:before { content: '\f078'} /* */
.octicon-chevron-up:before { content: '\f0a2'} /* */
.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
.octicon-clippy:before { content: '\f035'} /* */
.octicon-clock:before { content: '\f046'} /* */
.octicon-cloud-download:before { content: '\f00b'} /* */
.octicon-cloud-upload:before { content: '\f00c'} /* */
.octicon-code:before { content: '\f05f'} /* */
.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
.octicon-comment:before { content: '\f02b'} /* */
-.octicon-comment-add:before { content: '\f06f'} /* */
.octicon-comment-discussion:before { content: '\f04f'} /* */
.octicon-credit-card:before { content: '\f045'} /* */
.octicon-dash:before { content: '\f0ca'} /* */
.octicon-dashboard:before { content: '\f07d'} /* */
.octicon-database:before { content: '\f096'} /* */
+.octicon-clone:before,
+.octicon-desktop-download:before { content: '\f0dc'} /* */
.octicon-device-camera:before { content: '\f056'} /* */
.octicon-device-camera-video:before { content: '\f057'} /* */
.octicon-device-desktop:before { content: '\f27c'} /* */
@@ -81,14 +81,12 @@
.octicon-diff-removed:before { content: '\f06c'} /* */
.octicon-diff-renamed:before { content: '\f06e'} /* */
.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
.octicon-eye:before { content: '\f04e'} /* */
-.octicon-eye-unwatch:before { content: '\f01e'} /* */
-.octicon-eye-watch:before { content: '\f01d'} /* */
-.octicon-file-add:before { content: '\f086'} /* */
.octicon-file-binary:before { content: '\f094'} /* */
.octicon-file-code:before { content: '\f010'} /* */
.octicon-file-directory:before { content: '\f016'} /* */
-.octicon-file-directory-create:before { content: '\f095'} /* */
.octicon-file-media:before { content: '\f012'} /* */
.octicon-file-pdf:before { content: '\f014'} /* */
.octicon-file-submodule:before { content: '\f017'} /* */
@@ -101,26 +99,21 @@
.octicon-gear:before { content: '\f02f'} /* */
.octicon-gift:before { content: '\f042'} /* */
.octicon-gist:before { content: '\f00e'} /* */
-.octicon-gist-fork:before { content: '\f079'} /* */
-.octicon-gist-new:before { content: '\f07a'} /* */
-.octicon-gist-private:before { content: '\f00f'} /* */
.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
.octicon-git-branch:before { content: '\f020'} /* */
-.octicon-git-branch-create:before { content: '\f098'} /* */
-.octicon-git-branch-delete:before { content: '\f09b'} /* */
.octicon-git-commit:before { content: '\f01f'} /* */
.octicon-git-compare:before { content: '\f0ac'} /* */
-.octicon-git-fork-private:before { content: '\f021'} /* */
.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
.octicon-git-pull-request:before { content: '\f009'} /* */
-.octicon-git-pull-request-abandoned:before { content: '\f090'} /* */
.octicon-globe:before { content: '\f0b6'} /* */
.octicon-graph:before { content: '\f043'} /* */
.octicon-heart:before { content: '\2665'} /* ♥ */
.octicon-history:before { content: '\f07e'} /* */
.octicon-home:before { content: '\f08d'} /* */
.octicon-horizontal-rule:before { content: '\f070'} /* */
-.octicon-hourglass:before { content: '\f09e'} /* */
.octicon-hubot:before { content: '\f09d'} /* */
.octicon-inbox:before { content: '\f0cf'} /* */
.octicon-info:before { content: '\f059'} /* */
@@ -128,100 +121,90 @@
.octicon-issue-opened:before { content: '\f026'} /* */
.octicon-issue-reopened:before { content: '\f027'} /* */
.octicon-jersey:before { content: '\f019'} /* */
-.octicon-jump-down:before { content: '\f072'} /* */
-.octicon-jump-left:before { content: '\f0a5'} /* */
-.octicon-jump-right:before { content: '\f0a6'} /* */
-.octicon-jump-up:before { content: '\f073'} /* */
.octicon-key:before { content: '\f049'} /* */
.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
.octicon-light-bulb:before { content: '\f000'} /* */
.octicon-link:before { content: '\f05c'} /* */
.octicon-link-external:before { content: '\f07f'} /* */
.octicon-list-ordered:before { content: '\f062'} /* */
.octicon-list-unordered:before { content: '\f061'} /* */
.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
.octicon-lock:before { content: '\f06a'} /* */
-.octicon-log-in:before { content: '\f036'} /* */
-.octicon-log-out:before { content: '\f032'} /* */
.octicon-logo-github:before { content: '\f092'} /* */
.octicon-mail:before { content: '\f03b'} /* */
.octicon-mail-read:before { content: '\f03c'} /* */
.octicon-mail-reply:before { content: '\f051'} /* */
-.octicon-mark-facebook:before { content: '\f0ce'} /* */
.octicon-mark-github:before { content: '\f00a'} /* */
-.octicon-mark-google:before { content: '\f0cd'} /* */
-.octicon-mark-twitter:before { content: '\f0ae'} /* */
.octicon-markdown:before { content: '\f0c9'} /* */
.octicon-megaphone:before { content: '\f077'} /* */
.octicon-mention:before { content: '\f0be'} /* */
-.octicon-microscope:before { content: '\f089'} /* */
.octicon-milestone:before { content: '\f075'} /* */
-.octicon-mirror-private:before { content: '\f025'} /* */
-.octicon-mirror-public:before { content: '\f024'} /* */
-.octicon-move-down:before { content: '\f0a8'} /* */
-.octicon-move-left:before { content: '\f074'} /* */
-.octicon-move-right:before { content: '\f0a9'} /* */
-.octicon-move-up:before { content: '\f0a7'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
.octicon-mute:before { content: '\f080'} /* */
-.octicon-mute-video:before { content: '\f0b8'} /* */
.octicon-no-newline:before { content: '\f09c'} /* */
.octicon-octoface:before { content: '\f008'} /* */
.octicon-organization:before { content: '\f037'} /* */
.octicon-package:before { content: '\f0c4'} /* */
.octicon-paintcan:before { content: '\f0d1'} /* */
.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
.octicon-person:before { content: '\f018'} /* */
-.octicon-person-add:before { content: '\f01a'} /* */
-.octicon-person-follow:before { content: '\f01c'} /* */
-.octicon-person-remove:before { content: '\f01b'} /* */
.octicon-pin:before { content: '\f041'} /* */
-.octicon-playback-fast-forward:before { content: '\f0bd'} /* */
-.octicon-playback-pause:before { content: '\f0bb'} /* */
-.octicon-playback-play:before { content: '\f0bf'} /* */
-.octicon-playback-rewind:before { content: '\f0bc'} /* */
.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
.octicon-plus:before { content: '\f05d'} /* */
-.octicon-podium:before { content: '\f0af'} /* */
.octicon-primitive-dot:before { content: '\f052'} /* */
.octicon-primitive-square:before { content: '\f053'} /* */
.octicon-pulse:before { content: '\f085'} /* */
-.octicon-puzzle:before { content: '\f0c0'} /* */
.octicon-question:before { content: '\f02c'} /* */
.octicon-quote:before { content: '\f063'} /* */
.octicon-radio-tower:before { content: '\f030'} /* */
-.octicon-remove-close:before { content: '\f050'} /* */
+.octicon-repo-delete:before,
.octicon-repo:before { content: '\f001'} /* */
.octicon-repo-clone:before { content: '\f04c'} /* */
-.octicon-repo-create:before { content: '\f003'} /* */
-.octicon-repo-delete:before { content: '\f004'} /* */
.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
.octicon-repo-forked:before { content: '\f002'} /* */
.octicon-repo-pull:before { content: '\f006'} /* */
.octicon-repo-push:before { content: '\f005'} /* */
-.octicon-repo-sync:before { content: '\f04b'} /* */
.octicon-rocket:before { content: '\f033'} /* */
.octicon-rss:before { content: '\f034'} /* */
.octicon-ruby:before { content: '\f047'} /* */
.octicon-screen-full:before { content: '\f066'} /* */
.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
.octicon-search:before { content: '\f02e'} /* */
-.octicon-search-save:before { content: '\f0cb'} /* */
.octicon-server:before { content: '\f097'} /* */
.octicon-settings:before { content: '\f07c'} /* */
-.octicon-split:before { content: '\f0c6'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
.octicon-star:before { content: '\f02a'} /* */
-.octicon-star-add:before { content: '\f082'} /* */
-.octicon-star-delete:before { content: '\f083'} /* */
-.octicon-steps:before { content: '\f0c7'} /* */
.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
.octicon-tag:before { content: '\f015'} /* */
-.octicon-tag-add:before { content: '\f054'} /* */
-.octicon-tag-remove:before { content: '\f055'} /* */
.octicon-telescope:before { content: '\f088'} /* */
.octicon-terminal:before { content: '\f0c8'} /* */
.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-thumbsdown:before { content: '\f0db'} /* */
+.octicon-thumbsup:before { content: '\f0da'} /* */
.octicon-tools:before { content: '\f031'} /* */
.octicon-trashcan:before { content: '\f0d0'} /* */
.octicon-triangle-down:before { content: '\f05b'} /* */
@@ -230,8 +213,8 @@
.octicon-triangle-up:before { content: '\f0aa'} /* */
.octicon-unfold:before { content: '\f039'} /* */
.octicon-unmute:before { content: '\f0ba'} /* */
-.octicon-unmute-video:before { content: '\f0b9'} /* */
.octicon-versions:before { content: '\f064'} /* */
+.octicon-watch:before { content: '\f0e0'} /* */
+.octicon-remove-close:before,
.octicon-x:before { content: '\f081'} /* */
.octicon-zap:before { content: '\26A1'} /* ⚡ */
-
diff --git a/assets/vendor/octicons/octicons/octicons.eot b/assets/vendor/octicons/octicons/octicons.eot
new file mode 100644
index 0000000000..62fbf26c78
Binary files /dev/null and b/assets/vendor/octicons/octicons/octicons.eot differ
diff --git a/assets/vendor/octicons/octicons/octicons.less b/assets/vendor/octicons/octicons/octicons.less
new file mode 100644
index 0000000000..4c50b750ce
--- /dev/null
+++ b/assets/vendor/octicons/octicons/octicons.less
@@ -0,0 +1,219 @@
+@octicons-font-path: ".";
+@octicons-version: "b01a7f596657e53ed8582fa87efeaef4e51709c2";
+
+@font-face {
+ font-family: 'octicons';
+ src: ~"url('@{octicons-font-path}/octicons.eot?#iefix&v=@{octicons-version}') format('embedded-opentype')",
+ ~"url('@{octicons-font-path}/octicons.woff?v=@{octicons-version}') format('woff')",
+ ~"url('@{octicons-font-path}/octicons.ttf?v=@{octicons-version}') format('truetype')",
+ ~"url('@{octicons-font-path}/octicons.svg?v=@{octicons-version}#octicons') format('svg')";
+ font-weight: normal;
+ font-style: normal;
+}
+
+// .octicon is optimized for 16px.
+// .mega-octicon is optimized for 32px but can be used larger.
+.octicon, .mega-octicon {
+ font: normal normal normal 16px/1 octicons;
+ display: inline-block;
+ text-decoration: none;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.mega-octicon { font-size: 32px; }
+
+.octicon-alert:before { content: '\f02d'} /* */
+.octicon-arrow-down:before { content: '\f03f'} /* */
+.octicon-arrow-left:before { content: '\f040'} /* */
+.octicon-arrow-right:before { content: '\f03e'} /* */
+.octicon-arrow-small-down:before { content: '\f0a0'} /* */
+.octicon-arrow-small-left:before { content: '\f0a1'} /* */
+.octicon-arrow-small-right:before { content: '\f071'} /* */
+.octicon-arrow-small-up:before { content: '\f09f'} /* */
+.octicon-arrow-up:before { content: '\f03d'} /* */
+.octicon-microscope:before,
+.octicon-beaker:before { content: '\f0dd'} /* */
+.octicon-bell:before { content: '\f0de'} /* */
+.octicon-book:before { content: '\f007'} /* */
+.octicon-bookmark:before { content: '\f07b'} /* */
+.octicon-briefcase:before { content: '\f0d3'} /* */
+.octicon-broadcast:before { content: '\f048'} /* */
+.octicon-browser:before { content: '\f0c5'} /* */
+.octicon-bug:before { content: '\f091'} /* */
+.octicon-calendar:before { content: '\f068'} /* */
+.octicon-check:before { content: '\f03a'} /* */
+.octicon-checklist:before { content: '\f076'} /* */
+.octicon-chevron-down:before { content: '\f0a3'} /* */
+.octicon-chevron-left:before { content: '\f0a4'} /* */
+.octicon-chevron-right:before { content: '\f078'} /* */
+.octicon-chevron-up:before { content: '\f0a2'} /* */
+.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
+.octicon-clippy:before { content: '\f035'} /* */
+.octicon-clock:before { content: '\f046'} /* */
+.octicon-cloud-download:before { content: '\f00b'} /* */
+.octicon-cloud-upload:before { content: '\f00c'} /* */
+.octicon-code:before { content: '\f05f'} /* */
+.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
+.octicon-comment:before { content: '\f02b'} /* */
+.octicon-comment-discussion:before { content: '\f04f'} /* */
+.octicon-credit-card:before { content: '\f045'} /* */
+.octicon-dash:before { content: '\f0ca'} /* */
+.octicon-dashboard:before { content: '\f07d'} /* */
+.octicon-database:before { content: '\f096'} /* */
+.octicon-clone:before,
+.octicon-desktop-download:before { content: '\f0dc'} /* */
+.octicon-device-camera:before { content: '\f056'} /* */
+.octicon-device-camera-video:before { content: '\f057'} /* */
+.octicon-device-desktop:before { content: '\f27c'} /* */
+.octicon-device-mobile:before { content: '\f038'} /* */
+.octicon-diff:before { content: '\f04d'} /* */
+.octicon-diff-added:before { content: '\f06b'} /* */
+.octicon-diff-ignored:before { content: '\f099'} /* */
+.octicon-diff-modified:before { content: '\f06d'} /* */
+.octicon-diff-removed:before { content: '\f06c'} /* */
+.octicon-diff-renamed:before { content: '\f06e'} /* */
+.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
+.octicon-eye:before { content: '\f04e'} /* */
+.octicon-file-binary:before { content: '\f094'} /* */
+.octicon-file-code:before { content: '\f010'} /* */
+.octicon-file-directory:before { content: '\f016'} /* */
+.octicon-file-media:before { content: '\f012'} /* */
+.octicon-file-pdf:before { content: '\f014'} /* */
+.octicon-file-submodule:before { content: '\f017'} /* */
+.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
+.octicon-file-symlink-file:before { content: '\f0b0'} /* */
+.octicon-file-text:before { content: '\f011'} /* */
+.octicon-file-zip:before { content: '\f013'} /* */
+.octicon-flame:before { content: '\f0d2'} /* */
+.octicon-fold:before { content: '\f0cc'} /* */
+.octicon-gear:before { content: '\f02f'} /* */
+.octicon-gift:before { content: '\f042'} /* */
+.octicon-gist:before { content: '\f00e'} /* */
+.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
+.octicon-git-branch:before { content: '\f020'} /* */
+.octicon-git-commit:before { content: '\f01f'} /* */
+.octicon-git-compare:before { content: '\f0ac'} /* */
+.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
+.octicon-git-pull-request:before { content: '\f009'} /* */
+.octicon-globe:before { content: '\f0b6'} /* */
+.octicon-graph:before { content: '\f043'} /* */
+.octicon-heart:before { content: '\2665'} /* ♥ */
+.octicon-history:before { content: '\f07e'} /* */
+.octicon-home:before { content: '\f08d'} /* */
+.octicon-horizontal-rule:before { content: '\f070'} /* */
+.octicon-hubot:before { content: '\f09d'} /* */
+.octicon-inbox:before { content: '\f0cf'} /* */
+.octicon-info:before { content: '\f059'} /* */
+.octicon-issue-closed:before { content: '\f028'} /* */
+.octicon-issue-opened:before { content: '\f026'} /* */
+.octicon-issue-reopened:before { content: '\f027'} /* */
+.octicon-jersey:before { content: '\f019'} /* */
+.octicon-key:before { content: '\f049'} /* */
+.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
+.octicon-light-bulb:before { content: '\f000'} /* */
+.octicon-link:before { content: '\f05c'} /* */
+.octicon-link-external:before { content: '\f07f'} /* */
+.octicon-list-ordered:before { content: '\f062'} /* */
+.octicon-list-unordered:before { content: '\f061'} /* */
+.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
+.octicon-lock:before { content: '\f06a'} /* */
+.octicon-logo-github:before { content: '\f092'} /* */
+.octicon-mail:before { content: '\f03b'} /* */
+.octicon-mail-read:before { content: '\f03c'} /* */
+.octicon-mail-reply:before { content: '\f051'} /* */
+.octicon-mark-github:before { content: '\f00a'} /* */
+.octicon-markdown:before { content: '\f0c9'} /* */
+.octicon-megaphone:before { content: '\f077'} /* */
+.octicon-mention:before { content: '\f0be'} /* */
+.octicon-milestone:before { content: '\f075'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
+.octicon-mute:before { content: '\f080'} /* */
+.octicon-no-newline:before { content: '\f09c'} /* */
+.octicon-octoface:before { content: '\f008'} /* */
+.octicon-organization:before { content: '\f037'} /* */
+.octicon-package:before { content: '\f0c4'} /* */
+.octicon-paintcan:before { content: '\f0d1'} /* */
+.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
+.octicon-person:before { content: '\f018'} /* */
+.octicon-pin:before { content: '\f041'} /* */
+.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
+.octicon-plus:before { content: '\f05d'} /* */
+.octicon-primitive-dot:before { content: '\f052'} /* */
+.octicon-primitive-square:before { content: '\f053'} /* */
+.octicon-pulse:before { content: '\f085'} /* */
+.octicon-question:before { content: '\f02c'} /* */
+.octicon-quote:before { content: '\f063'} /* */
+.octicon-radio-tower:before { content: '\f030'} /* */
+.octicon-repo-delete:before,
+.octicon-repo:before { content: '\f001'} /* */
+.octicon-repo-clone:before { content: '\f04c'} /* */
+.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
+.octicon-repo-forked:before { content: '\f002'} /* */
+.octicon-repo-pull:before { content: '\f006'} /* */
+.octicon-repo-push:before { content: '\f005'} /* */
+.octicon-rocket:before { content: '\f033'} /* */
+.octicon-rss:before { content: '\f034'} /* */
+.octicon-ruby:before { content: '\f047'} /* */
+.octicon-screen-full:before { content: '\f066'} /* */
+.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
+.octicon-search:before { content: '\f02e'} /* */
+.octicon-server:before { content: '\f097'} /* */
+.octicon-settings:before { content: '\f07c'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
+.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
+.octicon-star:before { content: '\f02a'} /* */
+.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
+.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
+.octicon-tag:before { content: '\f015'} /* */
+.octicon-telescope:before { content: '\f088'} /* */
+.octicon-terminal:before { content: '\f0c8'} /* */
+.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-thumbsdown:before { content: '\f0db'} /* */
+.octicon-thumbsup:before { content: '\f0da'} /* */
+.octicon-tools:before { content: '\f031'} /* */
+.octicon-trashcan:before { content: '\f0d0'} /* */
+.octicon-triangle-down:before { content: '\f05b'} /* */
+.octicon-triangle-left:before { content: '\f044'} /* */
+.octicon-triangle-right:before { content: '\f05a'} /* */
+.octicon-triangle-up:before { content: '\f0aa'} /* */
+.octicon-unfold:before { content: '\f039'} /* */
+.octicon-unmute:before { content: '\f0ba'} /* */
+.octicon-versions:before { content: '\f064'} /* */
+.octicon-watch:before { content: '\f0e0'} /* */
+.octicon-remove-close:before,
+.octicon-x:before { content: '\f081'} /* */
+.octicon-zap:before { content: '\26A1'} /* ⚡ */
diff --git a/assets/vendor/octicons/octicons/octicons.scss b/assets/vendor/octicons/octicons/octicons.scss
new file mode 100644
index 0000000000..e216eebeb3
--- /dev/null
+++ b/assets/vendor/octicons/octicons/octicons.scss
@@ -0,0 +1,219 @@
+$octicons-font-path: "." !default;
+$octicons-version: "b01a7f596657e53ed8582fa87efeaef4e51709c2";
+
+@font-face {
+ font-family: 'octicons';
+ src: url('#{$octicons-font-path}/octicons.eot?#iefix&v=#{$octicons-version}') format('embedded-opentype'),
+ url('#{$octicons-font-path}/octicons.woff?v=#{$octicons-version}') format('woff'),
+ url('#{$octicons-font-path}/octicons.ttf?v=#{$octicons-version}') format('truetype'),
+ url('#{$octicons-font-path}/octicons.svg?v=#{$octicons-version}#octicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+// .octicon is optimized for 16px.
+// .mega-octicon is optimized for 32px but can be used larger.
+.octicon, .mega-octicon {
+ font: normal normal normal 16px/1 octicons;
+ display: inline-block;
+ text-decoration: none;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.mega-octicon { font-size: 32px; }
+
+.octicon-alert:before { content: '\f02d'} /* */
+.octicon-arrow-down:before { content: '\f03f'} /* */
+.octicon-arrow-left:before { content: '\f040'} /* */
+.octicon-arrow-right:before { content: '\f03e'} /* */
+.octicon-arrow-small-down:before { content: '\f0a0'} /* */
+.octicon-arrow-small-left:before { content: '\f0a1'} /* */
+.octicon-arrow-small-right:before { content: '\f071'} /* */
+.octicon-arrow-small-up:before { content: '\f09f'} /* */
+.octicon-arrow-up:before { content: '\f03d'} /* */
+.octicon-microscope:before,
+.octicon-beaker:before { content: '\f0dd'} /* */
+.octicon-bell:before { content: '\f0de'} /* */
+.octicon-book:before { content: '\f007'} /* */
+.octicon-bookmark:before { content: '\f07b'} /* */
+.octicon-briefcase:before { content: '\f0d3'} /* */
+.octicon-broadcast:before { content: '\f048'} /* */
+.octicon-browser:before { content: '\f0c5'} /* */
+.octicon-bug:before { content: '\f091'} /* */
+.octicon-calendar:before { content: '\f068'} /* */
+.octicon-check:before { content: '\f03a'} /* */
+.octicon-checklist:before { content: '\f076'} /* */
+.octicon-chevron-down:before { content: '\f0a3'} /* */
+.octicon-chevron-left:before { content: '\f0a4'} /* */
+.octicon-chevron-right:before { content: '\f078'} /* */
+.octicon-chevron-up:before { content: '\f0a2'} /* */
+.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
+.octicon-clippy:before { content: '\f035'} /* */
+.octicon-clock:before { content: '\f046'} /* */
+.octicon-cloud-download:before { content: '\f00b'} /* */
+.octicon-cloud-upload:before { content: '\f00c'} /* */
+.octicon-code:before { content: '\f05f'} /* */
+.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
+.octicon-comment:before { content: '\f02b'} /* */
+.octicon-comment-discussion:before { content: '\f04f'} /* */
+.octicon-credit-card:before { content: '\f045'} /* */
+.octicon-dash:before { content: '\f0ca'} /* */
+.octicon-dashboard:before { content: '\f07d'} /* */
+.octicon-database:before { content: '\f096'} /* */
+.octicon-clone:before,
+.octicon-desktop-download:before { content: '\f0dc'} /* */
+.octicon-device-camera:before { content: '\f056'} /* */
+.octicon-device-camera-video:before { content: '\f057'} /* */
+.octicon-device-desktop:before { content: '\f27c'} /* */
+.octicon-device-mobile:before { content: '\f038'} /* */
+.octicon-diff:before { content: '\f04d'} /* */
+.octicon-diff-added:before { content: '\f06b'} /* */
+.octicon-diff-ignored:before { content: '\f099'} /* */
+.octicon-diff-modified:before { content: '\f06d'} /* */
+.octicon-diff-removed:before { content: '\f06c'} /* */
+.octicon-diff-renamed:before { content: '\f06e'} /* */
+.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
+.octicon-eye:before { content: '\f04e'} /* */
+.octicon-file-binary:before { content: '\f094'} /* */
+.octicon-file-code:before { content: '\f010'} /* */
+.octicon-file-directory:before { content: '\f016'} /* */
+.octicon-file-media:before { content: '\f012'} /* */
+.octicon-file-pdf:before { content: '\f014'} /* */
+.octicon-file-submodule:before { content: '\f017'} /* */
+.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
+.octicon-file-symlink-file:before { content: '\f0b0'} /* */
+.octicon-file-text:before { content: '\f011'} /* */
+.octicon-file-zip:before { content: '\f013'} /* */
+.octicon-flame:before { content: '\f0d2'} /* */
+.octicon-fold:before { content: '\f0cc'} /* */
+.octicon-gear:before { content: '\f02f'} /* */
+.octicon-gift:before { content: '\f042'} /* */
+.octicon-gist:before { content: '\f00e'} /* */
+.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
+.octicon-git-branch:before { content: '\f020'} /* */
+.octicon-git-commit:before { content: '\f01f'} /* */
+.octicon-git-compare:before { content: '\f0ac'} /* */
+.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
+.octicon-git-pull-request:before { content: '\f009'} /* */
+.octicon-globe:before { content: '\f0b6'} /* */
+.octicon-graph:before { content: '\f043'} /* */
+.octicon-heart:before { content: '\2665'} /* ♥ */
+.octicon-history:before { content: '\f07e'} /* */
+.octicon-home:before { content: '\f08d'} /* */
+.octicon-horizontal-rule:before { content: '\f070'} /* */
+.octicon-hubot:before { content: '\f09d'} /* */
+.octicon-inbox:before { content: '\f0cf'} /* */
+.octicon-info:before { content: '\f059'} /* */
+.octicon-issue-closed:before { content: '\f028'} /* */
+.octicon-issue-opened:before { content: '\f026'} /* */
+.octicon-issue-reopened:before { content: '\f027'} /* */
+.octicon-jersey:before { content: '\f019'} /* */
+.octicon-key:before { content: '\f049'} /* */
+.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
+.octicon-light-bulb:before { content: '\f000'} /* */
+.octicon-link:before { content: '\f05c'} /* */
+.octicon-link-external:before { content: '\f07f'} /* */
+.octicon-list-ordered:before { content: '\f062'} /* */
+.octicon-list-unordered:before { content: '\f061'} /* */
+.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
+.octicon-lock:before { content: '\f06a'} /* */
+.octicon-logo-github:before { content: '\f092'} /* */
+.octicon-mail:before { content: '\f03b'} /* */
+.octicon-mail-read:before { content: '\f03c'} /* */
+.octicon-mail-reply:before { content: '\f051'} /* */
+.octicon-mark-github:before { content: '\f00a'} /* */
+.octicon-markdown:before { content: '\f0c9'} /* */
+.octicon-megaphone:before { content: '\f077'} /* */
+.octicon-mention:before { content: '\f0be'} /* */
+.octicon-milestone:before { content: '\f075'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
+.octicon-mute:before { content: '\f080'} /* */
+.octicon-no-newline:before { content: '\f09c'} /* */
+.octicon-octoface:before { content: '\f008'} /* */
+.octicon-organization:before { content: '\f037'} /* */
+.octicon-package:before { content: '\f0c4'} /* */
+.octicon-paintcan:before { content: '\f0d1'} /* */
+.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
+.octicon-person:before { content: '\f018'} /* */
+.octicon-pin:before { content: '\f041'} /* */
+.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
+.octicon-plus:before { content: '\f05d'} /* */
+.octicon-primitive-dot:before { content: '\f052'} /* */
+.octicon-primitive-square:before { content: '\f053'} /* */
+.octicon-pulse:before { content: '\f085'} /* */
+.octicon-question:before { content: '\f02c'} /* */
+.octicon-quote:before { content: '\f063'} /* */
+.octicon-radio-tower:before { content: '\f030'} /* */
+.octicon-repo-delete:before,
+.octicon-repo:before { content: '\f001'} /* */
+.octicon-repo-clone:before { content: '\f04c'} /* */
+.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
+.octicon-repo-forked:before { content: '\f002'} /* */
+.octicon-repo-pull:before { content: '\f006'} /* */
+.octicon-repo-push:before { content: '\f005'} /* */
+.octicon-rocket:before { content: '\f033'} /* */
+.octicon-rss:before { content: '\f034'} /* */
+.octicon-ruby:before { content: '\f047'} /* */
+.octicon-screen-full:before { content: '\f066'} /* */
+.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
+.octicon-search:before { content: '\f02e'} /* */
+.octicon-server:before { content: '\f097'} /* */
+.octicon-settings:before { content: '\f07c'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
+.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
+.octicon-star:before { content: '\f02a'} /* */
+.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
+.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
+.octicon-tag:before { content: '\f015'} /* */
+.octicon-telescope:before { content: '\f088'} /* */
+.octicon-terminal:before { content: '\f0c8'} /* */
+.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-thumbsdown:before { content: '\f0db'} /* */
+.octicon-thumbsup:before { content: '\f0da'} /* */
+.octicon-tools:before { content: '\f031'} /* */
+.octicon-trashcan:before { content: '\f0d0'} /* */
+.octicon-triangle-down:before { content: '\f05b'} /* */
+.octicon-triangle-left:before { content: '\f044'} /* */
+.octicon-triangle-right:before { content: '\f05a'} /* */
+.octicon-triangle-up:before { content: '\f0aa'} /* */
+.octicon-unfold:before { content: '\f039'} /* */
+.octicon-unmute:before { content: '\f0ba'} /* */
+.octicon-versions:before { content: '\f064'} /* */
+.octicon-watch:before { content: '\f0e0'} /* */
+.octicon-remove-close:before,
+.octicon-x:before { content: '\f081'} /* */
+.octicon-zap:before { content: '\26A1'} /* ⚡ */
diff --git a/assets/vendor/octicons/octicons/octicons.svg b/assets/vendor/octicons/octicons/octicons.svg
new file mode 100644
index 0000000000..58757eee8f
--- /dev/null
+++ b/assets/vendor/octicons/octicons/octicons.svg
@@ -0,0 +1,182 @@
+
+
+
diff --git a/assets/vendor/octicons/octicons/octicons.ttf b/assets/vendor/octicons/octicons/octicons.ttf
new file mode 100644
index 0000000000..21c8635b7f
Binary files /dev/null and b/assets/vendor/octicons/octicons/octicons.ttf differ
diff --git a/assets/vendor/octicons/octicons/octicons.woff b/assets/vendor/octicons/octicons/octicons.woff
new file mode 100644
index 0000000000..ad9d753771
Binary files /dev/null and b/assets/vendor/octicons/octicons/octicons.woff differ
diff --git a/assets/vendor/octicons/octicons/sprockets-octicons.scss b/assets/vendor/octicons/octicons/sprockets-octicons.scss
new file mode 100644
index 0000000000..269110e8b4
--- /dev/null
+++ b/assets/vendor/octicons/octicons/sprockets-octicons.scss
@@ -0,0 +1,216 @@
+@font-face {
+ font-family: 'octicons';
+ src: font-url('octicons.eot?#iefix') format('embedded-opentype'),
+ font-url('octicons.woff') format('woff'),
+ font-url('octicons.ttf') format('truetype'),
+ font-url('octicons.svg#octicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+// .octicon is optimized for 16px.
+// .mega-octicon is optimized for 32px but can be used larger.
+.octicon, .mega-octicon {
+ font: normal normal normal 16px/1 octicons;
+ display: inline-block;
+ text-decoration: none;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.mega-octicon { font-size: 32px; }
+
+.octicon-alert:before { content: '\f02d'} /* */
+.octicon-arrow-down:before { content: '\f03f'} /* */
+.octicon-arrow-left:before { content: '\f040'} /* */
+.octicon-arrow-right:before { content: '\f03e'} /* */
+.octicon-arrow-small-down:before { content: '\f0a0'} /* */
+.octicon-arrow-small-left:before { content: '\f0a1'} /* */
+.octicon-arrow-small-right:before { content: '\f071'} /* */
+.octicon-arrow-small-up:before { content: '\f09f'} /* */
+.octicon-arrow-up:before { content: '\f03d'} /* */
+.octicon-microscope:before,
+.octicon-beaker:before { content: '\f0dd'} /* */
+.octicon-bell:before { content: '\f0de'} /* */
+.octicon-book:before { content: '\f007'} /* */
+.octicon-bookmark:before { content: '\f07b'} /* */
+.octicon-briefcase:before { content: '\f0d3'} /* */
+.octicon-broadcast:before { content: '\f048'} /* */
+.octicon-browser:before { content: '\f0c5'} /* */
+.octicon-bug:before { content: '\f091'} /* */
+.octicon-calendar:before { content: '\f068'} /* */
+.octicon-check:before { content: '\f03a'} /* */
+.octicon-checklist:before { content: '\f076'} /* */
+.octicon-chevron-down:before { content: '\f0a3'} /* */
+.octicon-chevron-left:before { content: '\f0a4'} /* */
+.octicon-chevron-right:before { content: '\f078'} /* */
+.octicon-chevron-up:before { content: '\f0a2'} /* */
+.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
+.octicon-clippy:before { content: '\f035'} /* */
+.octicon-clock:before { content: '\f046'} /* */
+.octicon-cloud-download:before { content: '\f00b'} /* */
+.octicon-cloud-upload:before { content: '\f00c'} /* */
+.octicon-code:before { content: '\f05f'} /* */
+.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
+.octicon-comment:before { content: '\f02b'} /* */
+.octicon-comment-discussion:before { content: '\f04f'} /* */
+.octicon-credit-card:before { content: '\f045'} /* */
+.octicon-dash:before { content: '\f0ca'} /* */
+.octicon-dashboard:before { content: '\f07d'} /* */
+.octicon-database:before { content: '\f096'} /* */
+.octicon-clone:before,
+.octicon-desktop-download:before { content: '\f0dc'} /* */
+.octicon-device-camera:before { content: '\f056'} /* */
+.octicon-device-camera-video:before { content: '\f057'} /* */
+.octicon-device-desktop:before { content: '\f27c'} /* */
+.octicon-device-mobile:before { content: '\f038'} /* */
+.octicon-diff:before { content: '\f04d'} /* */
+.octicon-diff-added:before { content: '\f06b'} /* */
+.octicon-diff-ignored:before { content: '\f099'} /* */
+.octicon-diff-modified:before { content: '\f06d'} /* */
+.octicon-diff-removed:before { content: '\f06c'} /* */
+.octicon-diff-renamed:before { content: '\f06e'} /* */
+.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
+.octicon-eye:before { content: '\f04e'} /* */
+.octicon-file-binary:before { content: '\f094'} /* */
+.octicon-file-code:before { content: '\f010'} /* */
+.octicon-file-directory:before { content: '\f016'} /* */
+.octicon-file-media:before { content: '\f012'} /* */
+.octicon-file-pdf:before { content: '\f014'} /* */
+.octicon-file-submodule:before { content: '\f017'} /* */
+.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
+.octicon-file-symlink-file:before { content: '\f0b0'} /* */
+.octicon-file-text:before { content: '\f011'} /* */
+.octicon-file-zip:before { content: '\f013'} /* */
+.octicon-flame:before { content: '\f0d2'} /* */
+.octicon-fold:before { content: '\f0cc'} /* */
+.octicon-gear:before { content: '\f02f'} /* */
+.octicon-gift:before { content: '\f042'} /* */
+.octicon-gist:before { content: '\f00e'} /* */
+.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
+.octicon-git-branch:before { content: '\f020'} /* */
+.octicon-git-commit:before { content: '\f01f'} /* */
+.octicon-git-compare:before { content: '\f0ac'} /* */
+.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
+.octicon-git-pull-request:before { content: '\f009'} /* */
+.octicon-globe:before { content: '\f0b6'} /* */
+.octicon-graph:before { content: '\f043'} /* */
+.octicon-heart:before { content: '\2665'} /* ♥ */
+.octicon-history:before { content: '\f07e'} /* */
+.octicon-home:before { content: '\f08d'} /* */
+.octicon-horizontal-rule:before { content: '\f070'} /* */
+.octicon-hubot:before { content: '\f09d'} /* */
+.octicon-inbox:before { content: '\f0cf'} /* */
+.octicon-info:before { content: '\f059'} /* */
+.octicon-issue-closed:before { content: '\f028'} /* */
+.octicon-issue-opened:before { content: '\f026'} /* */
+.octicon-issue-reopened:before { content: '\f027'} /* */
+.octicon-jersey:before { content: '\f019'} /* */
+.octicon-key:before { content: '\f049'} /* */
+.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
+.octicon-light-bulb:before { content: '\f000'} /* */
+.octicon-link:before { content: '\f05c'} /* */
+.octicon-link-external:before { content: '\f07f'} /* */
+.octicon-list-ordered:before { content: '\f062'} /* */
+.octicon-list-unordered:before { content: '\f061'} /* */
+.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
+.octicon-lock:before { content: '\f06a'} /* */
+.octicon-logo-github:before { content: '\f092'} /* */
+.octicon-mail:before { content: '\f03b'} /* */
+.octicon-mail-read:before { content: '\f03c'} /* */
+.octicon-mail-reply:before { content: '\f051'} /* */
+.octicon-mark-github:before { content: '\f00a'} /* */
+.octicon-markdown:before { content: '\f0c9'} /* */
+.octicon-megaphone:before { content: '\f077'} /* */
+.octicon-mention:before { content: '\f0be'} /* */
+.octicon-milestone:before { content: '\f075'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
+.octicon-mute:before { content: '\f080'} /* */
+.octicon-no-newline:before { content: '\f09c'} /* */
+.octicon-octoface:before { content: '\f008'} /* */
+.octicon-organization:before { content: '\f037'} /* */
+.octicon-package:before { content: '\f0c4'} /* */
+.octicon-paintcan:before { content: '\f0d1'} /* */
+.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
+.octicon-person:before { content: '\f018'} /* */
+.octicon-pin:before { content: '\f041'} /* */
+.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
+.octicon-plus:before { content: '\f05d'} /* */
+.octicon-primitive-dot:before { content: '\f052'} /* */
+.octicon-primitive-square:before { content: '\f053'} /* */
+.octicon-pulse:before { content: '\f085'} /* */
+.octicon-question:before { content: '\f02c'} /* */
+.octicon-quote:before { content: '\f063'} /* */
+.octicon-radio-tower:before { content: '\f030'} /* */
+.octicon-repo-delete:before,
+.octicon-repo:before { content: '\f001'} /* */
+.octicon-repo-clone:before { content: '\f04c'} /* */
+.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
+.octicon-repo-forked:before { content: '\f002'} /* */
+.octicon-repo-pull:before { content: '\f006'} /* */
+.octicon-repo-push:before { content: '\f005'} /* */
+.octicon-rocket:before { content: '\f033'} /* */
+.octicon-rss:before { content: '\f034'} /* */
+.octicon-ruby:before { content: '\f047'} /* */
+.octicon-screen-full:before { content: '\f066'} /* */
+.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
+.octicon-search:before { content: '\f02e'} /* */
+.octicon-server:before { content: '\f097'} /* */
+.octicon-settings:before { content: '\f07c'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
+.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
+.octicon-star:before { content: '\f02a'} /* */
+.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
+.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
+.octicon-tag:before { content: '\f015'} /* */
+.octicon-telescope:before { content: '\f088'} /* */
+.octicon-terminal:before { content: '\f0c8'} /* */
+.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-thumbsdown:before { content: '\f0db'} /* */
+.octicon-thumbsup:before { content: '\f0da'} /* */
+.octicon-tools:before { content: '\f031'} /* */
+.octicon-trashcan:before { content: '\f0d0'} /* */
+.octicon-triangle-down:before { content: '\f05b'} /* */
+.octicon-triangle-left:before { content: '\f044'} /* */
+.octicon-triangle-right:before { content: '\f05a'} /* */
+.octicon-triangle-up:before { content: '\f0aa'} /* */
+.octicon-unfold:before { content: '\f039'} /* */
+.octicon-unmute:before { content: '\f0ba'} /* */
+.octicon-versions:before { content: '\f064'} /* */
+.octicon-watch:before { content: '\f0e0'} /* */
+.octicon-remove-close:before,
+.octicon-x:before { content: '\f081'} /* */
+.octicon-zap:before { content: '\26A1'} /* ⚡ */
diff --git a/assets/vendor/octicons/package.json b/assets/vendor/octicons/package.json
new file mode 100644
index 0000000000..2cb472cc2b
--- /dev/null
+++ b/assets/vendor/octicons/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "octicons",
+ "version": "3.0.1",
+ "description": "GitHub's icon font",
+ "main": "README.md",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/github/octicons.git"
+ },
+ "keywords": [
+ "GitHub",
+ "icons",
+ "font",
+ "web font",
+ "icon font"
+ ],
+ "author": "GitHub ",
+ "license": "SIL OFL 1.1, MIT",
+ "bugs": {
+ "url": "https://github.com/github/octicons/issues"
+ },
+ "homepage": "https://octicons.github.com"
+}
diff --git a/assets/vendor/octicons/svg/alert.svg b/assets/vendor/octicons/svg/alert.svg
new file mode 100644
index 0000000000..ba04d1c67f
--- /dev/null
+++ b/assets/vendor/octicons/svg/alert.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-down.svg b/assets/vendor/octicons/svg/arrow-down.svg
new file mode 100644
index 0000000000..67f3e8118c
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-down.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-left.svg b/assets/vendor/octicons/svg/arrow-left.svg
new file mode 100644
index 0000000000..acbcee4d7c
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-left.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-right.svg b/assets/vendor/octicons/svg/arrow-right.svg
new file mode 100644
index 0000000000..848b4d82e9
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-small-down.svg b/assets/vendor/octicons/svg/arrow-small-down.svg
new file mode 100644
index 0000000000..f38f60229f
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-small-down.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-small-left.svg b/assets/vendor/octicons/svg/arrow-small-left.svg
new file mode 100644
index 0000000000..2c6ebc1cd1
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-small-left.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-small-right.svg b/assets/vendor/octicons/svg/arrow-small-right.svg
new file mode 100644
index 0000000000..805ff36335
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-small-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-small-up.svg b/assets/vendor/octicons/svg/arrow-small-up.svg
new file mode 100644
index 0000000000..3604cd9824
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-small-up.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/arrow-up.svg b/assets/vendor/octicons/svg/arrow-up.svg
new file mode 100644
index 0000000000..5cca743313
--- /dev/null
+++ b/assets/vendor/octicons/svg/arrow-up.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/beaker.svg b/assets/vendor/octicons/svg/beaker.svg
new file mode 100644
index 0000000000..971f3e72ec
--- /dev/null
+++ b/assets/vendor/octicons/svg/beaker.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/bell.svg b/assets/vendor/octicons/svg/bell.svg
new file mode 100644
index 0000000000..b2ed4349cc
--- /dev/null
+++ b/assets/vendor/octicons/svg/bell.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/book.svg b/assets/vendor/octicons/svg/book.svg
new file mode 100644
index 0000000000..0b2f32f2fb
--- /dev/null
+++ b/assets/vendor/octicons/svg/book.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/bookmark.svg b/assets/vendor/octicons/svg/bookmark.svg
new file mode 100644
index 0000000000..45002b3e71
--- /dev/null
+++ b/assets/vendor/octicons/svg/bookmark.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/briefcase.svg b/assets/vendor/octicons/svg/briefcase.svg
new file mode 100644
index 0000000000..b9307c088f
--- /dev/null
+++ b/assets/vendor/octicons/svg/briefcase.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/broadcast.svg b/assets/vendor/octicons/svg/broadcast.svg
new file mode 100644
index 0000000000..de728458f2
--- /dev/null
+++ b/assets/vendor/octicons/svg/broadcast.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/browser.svg b/assets/vendor/octicons/svg/browser.svg
new file mode 100644
index 0000000000..c21a4cb2bb
--- /dev/null
+++ b/assets/vendor/octicons/svg/browser.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/bug.svg b/assets/vendor/octicons/svg/bug.svg
new file mode 100644
index 0000000000..b80342e1c8
--- /dev/null
+++ b/assets/vendor/octicons/svg/bug.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/calendar.svg b/assets/vendor/octicons/svg/calendar.svg
new file mode 100644
index 0000000000..8ce32744fe
--- /dev/null
+++ b/assets/vendor/octicons/svg/calendar.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/check.svg b/assets/vendor/octicons/svg/check.svg
new file mode 100644
index 0000000000..d53f27766c
--- /dev/null
+++ b/assets/vendor/octicons/svg/check.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/checklist.svg b/assets/vendor/octicons/svg/checklist.svg
new file mode 100644
index 0000000000..9db365c50e
--- /dev/null
+++ b/assets/vendor/octicons/svg/checklist.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/chevron-down.svg b/assets/vendor/octicons/svg/chevron-down.svg
new file mode 100644
index 0000000000..7ef0951e1e
--- /dev/null
+++ b/assets/vendor/octicons/svg/chevron-down.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/chevron-left.svg b/assets/vendor/octicons/svg/chevron-left.svg
new file mode 100644
index 0000000000..e314bec637
--- /dev/null
+++ b/assets/vendor/octicons/svg/chevron-left.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/chevron-right.svg b/assets/vendor/octicons/svg/chevron-right.svg
new file mode 100644
index 0000000000..289154df79
--- /dev/null
+++ b/assets/vendor/octicons/svg/chevron-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/chevron-up.svg b/assets/vendor/octicons/svg/chevron-up.svg
new file mode 100644
index 0000000000..797a850467
--- /dev/null
+++ b/assets/vendor/octicons/svg/chevron-up.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/circle-slash.svg b/assets/vendor/octicons/svg/circle-slash.svg
new file mode 100644
index 0000000000..f83336408a
--- /dev/null
+++ b/assets/vendor/octicons/svg/circle-slash.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/circuit-board.svg b/assets/vendor/octicons/svg/circuit-board.svg
new file mode 100644
index 0000000000..4e9265b5f8
--- /dev/null
+++ b/assets/vendor/octicons/svg/circuit-board.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/clippy.svg b/assets/vendor/octicons/svg/clippy.svg
new file mode 100644
index 0000000000..e1b1703590
--- /dev/null
+++ b/assets/vendor/octicons/svg/clippy.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/clock.svg b/assets/vendor/octicons/svg/clock.svg
new file mode 100644
index 0000000000..709d1ac690
--- /dev/null
+++ b/assets/vendor/octicons/svg/clock.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/cloud-download.svg b/assets/vendor/octicons/svg/cloud-download.svg
new file mode 100644
index 0000000000..59c6d92c9c
--- /dev/null
+++ b/assets/vendor/octicons/svg/cloud-download.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/cloud-upload.svg b/assets/vendor/octicons/svg/cloud-upload.svg
new file mode 100644
index 0000000000..4a9379c089
--- /dev/null
+++ b/assets/vendor/octicons/svg/cloud-upload.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/code.svg b/assets/vendor/octicons/svg/code.svg
new file mode 100644
index 0000000000..e5d4ac69e0
--- /dev/null
+++ b/assets/vendor/octicons/svg/code.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/color-mode.svg b/assets/vendor/octicons/svg/color-mode.svg
new file mode 100644
index 0000000000..5fbd20ed0d
--- /dev/null
+++ b/assets/vendor/octicons/svg/color-mode.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/comment-discussion.svg b/assets/vendor/octicons/svg/comment-discussion.svg
new file mode 100644
index 0000000000..ca00b02a67
--- /dev/null
+++ b/assets/vendor/octicons/svg/comment-discussion.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/comment.svg b/assets/vendor/octicons/svg/comment.svg
new file mode 100644
index 0000000000..9ac8330f6f
--- /dev/null
+++ b/assets/vendor/octicons/svg/comment.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/credit-card.svg b/assets/vendor/octicons/svg/credit-card.svg
new file mode 100644
index 0000000000..c20775b7b5
--- /dev/null
+++ b/assets/vendor/octicons/svg/credit-card.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/dash.svg b/assets/vendor/octicons/svg/dash.svg
new file mode 100644
index 0000000000..f32e98bbd7
--- /dev/null
+++ b/assets/vendor/octicons/svg/dash.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/dashboard.svg b/assets/vendor/octicons/svg/dashboard.svg
new file mode 100644
index 0000000000..92b1fa1742
--- /dev/null
+++ b/assets/vendor/octicons/svg/dashboard.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/database.svg b/assets/vendor/octicons/svg/database.svg
new file mode 100644
index 0000000000..050e97227e
--- /dev/null
+++ b/assets/vendor/octicons/svg/database.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/desktop-download.svg b/assets/vendor/octicons/svg/desktop-download.svg
new file mode 100644
index 0000000000..ce5c8a461b
--- /dev/null
+++ b/assets/vendor/octicons/svg/desktop-download.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/device-camera-video.svg b/assets/vendor/octicons/svg/device-camera-video.svg
new file mode 100644
index 0000000000..db064b2f3d
--- /dev/null
+++ b/assets/vendor/octicons/svg/device-camera-video.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/device-camera.svg b/assets/vendor/octicons/svg/device-camera.svg
new file mode 100644
index 0000000000..84a46036d8
--- /dev/null
+++ b/assets/vendor/octicons/svg/device-camera.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/device-desktop.svg b/assets/vendor/octicons/svg/device-desktop.svg
new file mode 100644
index 0000000000..358d72a88b
--- /dev/null
+++ b/assets/vendor/octicons/svg/device-desktop.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/device-mobile.svg b/assets/vendor/octicons/svg/device-mobile.svg
new file mode 100644
index 0000000000..a7536f3c72
--- /dev/null
+++ b/assets/vendor/octicons/svg/device-mobile.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/diff-added.svg b/assets/vendor/octicons/svg/diff-added.svg
new file mode 100644
index 0000000000..ff11fcc4ae
--- /dev/null
+++ b/assets/vendor/octicons/svg/diff-added.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/diff-ignored.svg b/assets/vendor/octicons/svg/diff-ignored.svg
new file mode 100644
index 0000000000..bf24b0c025
--- /dev/null
+++ b/assets/vendor/octicons/svg/diff-ignored.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/diff-modified.svg b/assets/vendor/octicons/svg/diff-modified.svg
new file mode 100644
index 0000000000..60d8adc393
--- /dev/null
+++ b/assets/vendor/octicons/svg/diff-modified.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/diff-removed.svg b/assets/vendor/octicons/svg/diff-removed.svg
new file mode 100644
index 0000000000..bdabbaf45a
--- /dev/null
+++ b/assets/vendor/octicons/svg/diff-removed.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/diff-renamed.svg b/assets/vendor/octicons/svg/diff-renamed.svg
new file mode 100644
index 0000000000..a50bbd9032
--- /dev/null
+++ b/assets/vendor/octicons/svg/diff-renamed.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/diff.svg b/assets/vendor/octicons/svg/diff.svg
new file mode 100644
index 0000000000..5e4e850e71
--- /dev/null
+++ b/assets/vendor/octicons/svg/diff.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/ellipsis.svg b/assets/vendor/octicons/svg/ellipsis.svg
new file mode 100644
index 0000000000..ffc2598894
--- /dev/null
+++ b/assets/vendor/octicons/svg/ellipsis.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/eye.svg b/assets/vendor/octicons/svg/eye.svg
new file mode 100644
index 0000000000..067bfcb576
--- /dev/null
+++ b/assets/vendor/octicons/svg/eye.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-binary.svg b/assets/vendor/octicons/svg/file-binary.svg
new file mode 100644
index 0000000000..cc5b349cdd
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-binary.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-code.svg b/assets/vendor/octicons/svg/file-code.svg
new file mode 100644
index 0000000000..0a59390029
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-code.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-directory.svg b/assets/vendor/octicons/svg/file-directory.svg
new file mode 100644
index 0000000000..7a1d4c22e3
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-directory.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-media.svg b/assets/vendor/octicons/svg/file-media.svg
new file mode 100644
index 0000000000..2973f89845
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-media.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-pdf.svg b/assets/vendor/octicons/svg/file-pdf.svg
new file mode 100644
index 0000000000..448d4c49b4
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-pdf.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-submodule.svg b/assets/vendor/octicons/svg/file-submodule.svg
new file mode 100644
index 0000000000..3481b89b29
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-submodule.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-symlink-directory.svg b/assets/vendor/octicons/svg/file-symlink-directory.svg
new file mode 100644
index 0000000000..f3820b2b6c
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-symlink-directory.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-symlink-file.svg b/assets/vendor/octicons/svg/file-symlink-file.svg
new file mode 100644
index 0000000000..2d958c518f
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-symlink-file.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-text.svg b/assets/vendor/octicons/svg/file-text.svg
new file mode 100644
index 0000000000..9962aeecd9
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-text.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/file-zip.svg b/assets/vendor/octicons/svg/file-zip.svg
new file mode 100644
index 0000000000..713691b93e
--- /dev/null
+++ b/assets/vendor/octicons/svg/file-zip.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/flame.svg b/assets/vendor/octicons/svg/flame.svg
new file mode 100644
index 0000000000..f22a2307a0
--- /dev/null
+++ b/assets/vendor/octicons/svg/flame.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/fold.svg b/assets/vendor/octicons/svg/fold.svg
new file mode 100644
index 0000000000..c4426ccd19
--- /dev/null
+++ b/assets/vendor/octicons/svg/fold.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/gear.svg b/assets/vendor/octicons/svg/gear.svg
new file mode 100644
index 0000000000..1ebb26ae62
--- /dev/null
+++ b/assets/vendor/octicons/svg/gear.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/gift.svg b/assets/vendor/octicons/svg/gift.svg
new file mode 100644
index 0000000000..7b864d011d
--- /dev/null
+++ b/assets/vendor/octicons/svg/gift.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/gist-secret.svg b/assets/vendor/octicons/svg/gist-secret.svg
new file mode 100644
index 0000000000..03de44d5e3
--- /dev/null
+++ b/assets/vendor/octicons/svg/gist-secret.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/gist.svg b/assets/vendor/octicons/svg/gist.svg
new file mode 100644
index 0000000000..e9e4f8e9ba
--- /dev/null
+++ b/assets/vendor/octicons/svg/gist.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/git-branch.svg b/assets/vendor/octicons/svg/git-branch.svg
new file mode 100644
index 0000000000..f4319e9608
--- /dev/null
+++ b/assets/vendor/octicons/svg/git-branch.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/git-commit.svg b/assets/vendor/octicons/svg/git-commit.svg
new file mode 100644
index 0000000000..bb6080f5f8
--- /dev/null
+++ b/assets/vendor/octicons/svg/git-commit.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/git-compare.svg b/assets/vendor/octicons/svg/git-compare.svg
new file mode 100644
index 0000000000..2a479feff4
--- /dev/null
+++ b/assets/vendor/octicons/svg/git-compare.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/git-merge.svg b/assets/vendor/octicons/svg/git-merge.svg
new file mode 100644
index 0000000000..5ff0daae16
--- /dev/null
+++ b/assets/vendor/octicons/svg/git-merge.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/git-pull-request.svg b/assets/vendor/octicons/svg/git-pull-request.svg
new file mode 100644
index 0000000000..93951bf22d
--- /dev/null
+++ b/assets/vendor/octicons/svg/git-pull-request.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/globe.svg b/assets/vendor/octicons/svg/globe.svg
new file mode 100644
index 0000000000..5108ca0e3d
--- /dev/null
+++ b/assets/vendor/octicons/svg/globe.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/graph.svg b/assets/vendor/octicons/svg/graph.svg
new file mode 100644
index 0000000000..1b58564c6f
--- /dev/null
+++ b/assets/vendor/octicons/svg/graph.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/heart.svg b/assets/vendor/octicons/svg/heart.svg
new file mode 100644
index 0000000000..58f422eb33
--- /dev/null
+++ b/assets/vendor/octicons/svg/heart.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/history.svg b/assets/vendor/octicons/svg/history.svg
new file mode 100644
index 0000000000..fe092ed9a0
--- /dev/null
+++ b/assets/vendor/octicons/svg/history.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/home.svg b/assets/vendor/octicons/svg/home.svg
new file mode 100644
index 0000000000..417f225f1d
--- /dev/null
+++ b/assets/vendor/octicons/svg/home.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/horizontal-rule.svg b/assets/vendor/octicons/svg/horizontal-rule.svg
new file mode 100644
index 0000000000..38e5975654
--- /dev/null
+++ b/assets/vendor/octicons/svg/horizontal-rule.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/hubot.svg b/assets/vendor/octicons/svg/hubot.svg
new file mode 100644
index 0000000000..1876d5e9fb
--- /dev/null
+++ b/assets/vendor/octicons/svg/hubot.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/inbox.svg b/assets/vendor/octicons/svg/inbox.svg
new file mode 100644
index 0000000000..ba0a8b2959
--- /dev/null
+++ b/assets/vendor/octicons/svg/inbox.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/info.svg b/assets/vendor/octicons/svg/info.svg
new file mode 100644
index 0000000000..da80363e6c
--- /dev/null
+++ b/assets/vendor/octicons/svg/info.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/issue-closed.svg b/assets/vendor/octicons/svg/issue-closed.svg
new file mode 100644
index 0000000000..8d69210f49
--- /dev/null
+++ b/assets/vendor/octicons/svg/issue-closed.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/issue-opened.svg b/assets/vendor/octicons/svg/issue-opened.svg
new file mode 100644
index 0000000000..e08652ec79
--- /dev/null
+++ b/assets/vendor/octicons/svg/issue-opened.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/issue-reopened.svg b/assets/vendor/octicons/svg/issue-reopened.svg
new file mode 100644
index 0000000000..cbce0149dd
--- /dev/null
+++ b/assets/vendor/octicons/svg/issue-reopened.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/jersey.svg b/assets/vendor/octicons/svg/jersey.svg
new file mode 100644
index 0000000000..be4f2e5197
--- /dev/null
+++ b/assets/vendor/octicons/svg/jersey.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/key.svg b/assets/vendor/octicons/svg/key.svg
new file mode 100644
index 0000000000..daef6b9230
--- /dev/null
+++ b/assets/vendor/octicons/svg/key.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/keyboard.svg b/assets/vendor/octicons/svg/keyboard.svg
new file mode 100644
index 0000000000..c1356b920a
--- /dev/null
+++ b/assets/vendor/octicons/svg/keyboard.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/law.svg b/assets/vendor/octicons/svg/law.svg
new file mode 100644
index 0000000000..35f99b8192
--- /dev/null
+++ b/assets/vendor/octicons/svg/law.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/light-bulb.svg b/assets/vendor/octicons/svg/light-bulb.svg
new file mode 100644
index 0000000000..8363d65785
--- /dev/null
+++ b/assets/vendor/octicons/svg/light-bulb.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/link-external.svg b/assets/vendor/octicons/svg/link-external.svg
new file mode 100644
index 0000000000..aa440c56f8
--- /dev/null
+++ b/assets/vendor/octicons/svg/link-external.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/link.svg b/assets/vendor/octicons/svg/link.svg
new file mode 100644
index 0000000000..5a56a88259
--- /dev/null
+++ b/assets/vendor/octicons/svg/link.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/list-ordered.svg b/assets/vendor/octicons/svg/list-ordered.svg
new file mode 100644
index 0000000000..5ffadb6de4
--- /dev/null
+++ b/assets/vendor/octicons/svg/list-ordered.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/list-unordered.svg b/assets/vendor/octicons/svg/list-unordered.svg
new file mode 100644
index 0000000000..dc3ab72d27
--- /dev/null
+++ b/assets/vendor/octicons/svg/list-unordered.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/location.svg b/assets/vendor/octicons/svg/location.svg
new file mode 100644
index 0000000000..2ded703b29
--- /dev/null
+++ b/assets/vendor/octicons/svg/location.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/lock.svg b/assets/vendor/octicons/svg/lock.svg
new file mode 100644
index 0000000000..42a6bcac5b
--- /dev/null
+++ b/assets/vendor/octicons/svg/lock.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/logo-github.svg b/assets/vendor/octicons/svg/logo-github.svg
new file mode 100644
index 0000000000..136ed38609
--- /dev/null
+++ b/assets/vendor/octicons/svg/logo-github.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mail-read.svg b/assets/vendor/octicons/svg/mail-read.svg
new file mode 100644
index 0000000000..57ab3807a4
--- /dev/null
+++ b/assets/vendor/octicons/svg/mail-read.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mail-reply.svg b/assets/vendor/octicons/svg/mail-reply.svg
new file mode 100644
index 0000000000..a96d77873f
--- /dev/null
+++ b/assets/vendor/octicons/svg/mail-reply.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mail.svg b/assets/vendor/octicons/svg/mail.svg
new file mode 100644
index 0000000000..f2fb607840
--- /dev/null
+++ b/assets/vendor/octicons/svg/mail.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mark-github.svg b/assets/vendor/octicons/svg/mark-github.svg
new file mode 100644
index 0000000000..e6a247f96a
--- /dev/null
+++ b/assets/vendor/octicons/svg/mark-github.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/markdown.svg b/assets/vendor/octicons/svg/markdown.svg
new file mode 100644
index 0000000000..3a3bddb148
--- /dev/null
+++ b/assets/vendor/octicons/svg/markdown.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/megaphone.svg b/assets/vendor/octicons/svg/megaphone.svg
new file mode 100644
index 0000000000..63e77f0fa1
--- /dev/null
+++ b/assets/vendor/octicons/svg/megaphone.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mention.svg b/assets/vendor/octicons/svg/mention.svg
new file mode 100644
index 0000000000..877568a5ff
--- /dev/null
+++ b/assets/vendor/octicons/svg/mention.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/milestone.svg b/assets/vendor/octicons/svg/milestone.svg
new file mode 100644
index 0000000000..e94563f7aa
--- /dev/null
+++ b/assets/vendor/octicons/svg/milestone.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mirror.svg b/assets/vendor/octicons/svg/mirror.svg
new file mode 100644
index 0000000000..b74d2ee3af
--- /dev/null
+++ b/assets/vendor/octicons/svg/mirror.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mortar-board.svg b/assets/vendor/octicons/svg/mortar-board.svg
new file mode 100644
index 0000000000..48d46d2dcd
--- /dev/null
+++ b/assets/vendor/octicons/svg/mortar-board.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/mute.svg b/assets/vendor/octicons/svg/mute.svg
new file mode 100644
index 0000000000..595faef529
--- /dev/null
+++ b/assets/vendor/octicons/svg/mute.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/no-newline.svg b/assets/vendor/octicons/svg/no-newline.svg
new file mode 100644
index 0000000000..59d685a245
--- /dev/null
+++ b/assets/vendor/octicons/svg/no-newline.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/octoface.svg b/assets/vendor/octicons/svg/octoface.svg
new file mode 100644
index 0000000000..de191e8e6d
--- /dev/null
+++ b/assets/vendor/octicons/svg/octoface.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/organization.svg b/assets/vendor/octicons/svg/organization.svg
new file mode 100644
index 0000000000..b8e580e070
--- /dev/null
+++ b/assets/vendor/octicons/svg/organization.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/package.svg b/assets/vendor/octicons/svg/package.svg
new file mode 100644
index 0000000000..e62235a883
--- /dev/null
+++ b/assets/vendor/octicons/svg/package.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/paintcan.svg b/assets/vendor/octicons/svg/paintcan.svg
new file mode 100644
index 0000000000..d62f91e934
--- /dev/null
+++ b/assets/vendor/octicons/svg/paintcan.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/pencil.svg b/assets/vendor/octicons/svg/pencil.svg
new file mode 100644
index 0000000000..e947458f46
--- /dev/null
+++ b/assets/vendor/octicons/svg/pencil.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/person.svg b/assets/vendor/octicons/svg/person.svg
new file mode 100644
index 0000000000..b28fbab92e
--- /dev/null
+++ b/assets/vendor/octicons/svg/person.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/pin.svg b/assets/vendor/octicons/svg/pin.svg
new file mode 100644
index 0000000000..6412d6295b
--- /dev/null
+++ b/assets/vendor/octicons/svg/pin.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/plug.svg b/assets/vendor/octicons/svg/plug.svg
new file mode 100644
index 0000000000..200314bcaf
--- /dev/null
+++ b/assets/vendor/octicons/svg/plug.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/plus.svg b/assets/vendor/octicons/svg/plus.svg
new file mode 100644
index 0000000000..3b9746f9af
--- /dev/null
+++ b/assets/vendor/octicons/svg/plus.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/primitive-dot.svg b/assets/vendor/octicons/svg/primitive-dot.svg
new file mode 100644
index 0000000000..9e1a80bce7
--- /dev/null
+++ b/assets/vendor/octicons/svg/primitive-dot.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/primitive-square.svg b/assets/vendor/octicons/svg/primitive-square.svg
new file mode 100644
index 0000000000..84b06a9472
--- /dev/null
+++ b/assets/vendor/octicons/svg/primitive-square.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/pulse.svg b/assets/vendor/octicons/svg/pulse.svg
new file mode 100644
index 0000000000..4c91e1835e
--- /dev/null
+++ b/assets/vendor/octicons/svg/pulse.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/question.svg b/assets/vendor/octicons/svg/question.svg
new file mode 100644
index 0000000000..f164aa6dc5
--- /dev/null
+++ b/assets/vendor/octicons/svg/question.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/quote.svg b/assets/vendor/octicons/svg/quote.svg
new file mode 100644
index 0000000000..6648dc0ba0
--- /dev/null
+++ b/assets/vendor/octicons/svg/quote.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/radio-tower.svg b/assets/vendor/octicons/svg/radio-tower.svg
new file mode 100644
index 0000000000..bcbf90636e
--- /dev/null
+++ b/assets/vendor/octicons/svg/radio-tower.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/repo-clone.svg b/assets/vendor/octicons/svg/repo-clone.svg
new file mode 100644
index 0000000000..364852d33b
--- /dev/null
+++ b/assets/vendor/octicons/svg/repo-clone.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/repo-force-push.svg b/assets/vendor/octicons/svg/repo-force-push.svg
new file mode 100644
index 0000000000..ee7f26551b
--- /dev/null
+++ b/assets/vendor/octicons/svg/repo-force-push.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/repo-forked.svg b/assets/vendor/octicons/svg/repo-forked.svg
new file mode 100644
index 0000000000..8ace05e2f4
--- /dev/null
+++ b/assets/vendor/octicons/svg/repo-forked.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/repo-pull.svg b/assets/vendor/octicons/svg/repo-pull.svg
new file mode 100644
index 0000000000..e9e189f8c9
--- /dev/null
+++ b/assets/vendor/octicons/svg/repo-pull.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/repo-push.svg b/assets/vendor/octicons/svg/repo-push.svg
new file mode 100644
index 0000000000..e7fa9e9d25
--- /dev/null
+++ b/assets/vendor/octicons/svg/repo-push.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/repo.svg b/assets/vendor/octicons/svg/repo.svg
new file mode 100644
index 0000000000..9cca77274f
--- /dev/null
+++ b/assets/vendor/octicons/svg/repo.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/rocket.svg b/assets/vendor/octicons/svg/rocket.svg
new file mode 100644
index 0000000000..10f69efc35
--- /dev/null
+++ b/assets/vendor/octicons/svg/rocket.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/rss.svg b/assets/vendor/octicons/svg/rss.svg
new file mode 100644
index 0000000000..e93daabdd7
--- /dev/null
+++ b/assets/vendor/octicons/svg/rss.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/ruby.svg b/assets/vendor/octicons/svg/ruby.svg
new file mode 100644
index 0000000000..a32a4c3e42
--- /dev/null
+++ b/assets/vendor/octicons/svg/ruby.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/screen-full.svg b/assets/vendor/octicons/svg/screen-full.svg
new file mode 100644
index 0000000000..c19e8712c2
--- /dev/null
+++ b/assets/vendor/octicons/svg/screen-full.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/screen-normal.svg b/assets/vendor/octicons/svg/screen-normal.svg
new file mode 100644
index 0000000000..ee5d8c8deb
--- /dev/null
+++ b/assets/vendor/octicons/svg/screen-normal.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/search.svg b/assets/vendor/octicons/svg/search.svg
new file mode 100644
index 0000000000..e6a92c13e4
--- /dev/null
+++ b/assets/vendor/octicons/svg/search.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/server.svg b/assets/vendor/octicons/svg/server.svg
new file mode 100644
index 0000000000..1e511b0547
--- /dev/null
+++ b/assets/vendor/octicons/svg/server.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/settings.svg b/assets/vendor/octicons/svg/settings.svg
new file mode 100644
index 0000000000..0c030ee062
--- /dev/null
+++ b/assets/vendor/octicons/svg/settings.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/sign-in.svg b/assets/vendor/octicons/svg/sign-in.svg
new file mode 100644
index 0000000000..a4679493e7
--- /dev/null
+++ b/assets/vendor/octicons/svg/sign-in.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/sign-out.svg b/assets/vendor/octicons/svg/sign-out.svg
new file mode 100644
index 0000000000..0b0da8fcfe
--- /dev/null
+++ b/assets/vendor/octicons/svg/sign-out.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/squirrel.svg b/assets/vendor/octicons/svg/squirrel.svg
new file mode 100644
index 0000000000..4a80ab7812
--- /dev/null
+++ b/assets/vendor/octicons/svg/squirrel.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/star.svg b/assets/vendor/octicons/svg/star.svg
new file mode 100644
index 0000000000..6c51448765
--- /dev/null
+++ b/assets/vendor/octicons/svg/star.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/stop.svg b/assets/vendor/octicons/svg/stop.svg
new file mode 100644
index 0000000000..203682e180
--- /dev/null
+++ b/assets/vendor/octicons/svg/stop.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/sync.svg b/assets/vendor/octicons/svg/sync.svg
new file mode 100644
index 0000000000..ad9b161cdc
--- /dev/null
+++ b/assets/vendor/octicons/svg/sync.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/tag.svg b/assets/vendor/octicons/svg/tag.svg
new file mode 100644
index 0000000000..7946ddc12f
--- /dev/null
+++ b/assets/vendor/octicons/svg/tag.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/telescope.svg b/assets/vendor/octicons/svg/telescope.svg
new file mode 100644
index 0000000000..fe774259a7
--- /dev/null
+++ b/assets/vendor/octicons/svg/telescope.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/terminal.svg b/assets/vendor/octicons/svg/terminal.svg
new file mode 100644
index 0000000000..bee2f81d16
--- /dev/null
+++ b/assets/vendor/octicons/svg/terminal.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/three-bars.svg b/assets/vendor/octicons/svg/three-bars.svg
new file mode 100644
index 0000000000..e01a2fae06
--- /dev/null
+++ b/assets/vendor/octicons/svg/three-bars.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/thumbsdown.svg b/assets/vendor/octicons/svg/thumbsdown.svg
new file mode 100644
index 0000000000..f9d1a6e7a9
--- /dev/null
+++ b/assets/vendor/octicons/svg/thumbsdown.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/thumbsup.svg b/assets/vendor/octicons/svg/thumbsup.svg
new file mode 100644
index 0000000000..d5462db850
--- /dev/null
+++ b/assets/vendor/octicons/svg/thumbsup.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/tools.svg b/assets/vendor/octicons/svg/tools.svg
new file mode 100644
index 0000000000..658a3bf515
--- /dev/null
+++ b/assets/vendor/octicons/svg/tools.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/trashcan.svg b/assets/vendor/octicons/svg/trashcan.svg
new file mode 100644
index 0000000000..f99e8bdd76
--- /dev/null
+++ b/assets/vendor/octicons/svg/trashcan.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/triangle-down.svg b/assets/vendor/octicons/svg/triangle-down.svg
new file mode 100644
index 0000000000..ce87663087
--- /dev/null
+++ b/assets/vendor/octicons/svg/triangle-down.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/triangle-left.svg b/assets/vendor/octicons/svg/triangle-left.svg
new file mode 100644
index 0000000000..5d13d84205
--- /dev/null
+++ b/assets/vendor/octicons/svg/triangle-left.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/triangle-right.svg b/assets/vendor/octicons/svg/triangle-right.svg
new file mode 100644
index 0000000000..b05f3ae288
--- /dev/null
+++ b/assets/vendor/octicons/svg/triangle-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/triangle-up.svg b/assets/vendor/octicons/svg/triangle-up.svg
new file mode 100644
index 0000000000..915f95158b
--- /dev/null
+++ b/assets/vendor/octicons/svg/triangle-up.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/unfold.svg b/assets/vendor/octicons/svg/unfold.svg
new file mode 100644
index 0000000000..1d391af1fa
--- /dev/null
+++ b/assets/vendor/octicons/svg/unfold.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/unmute.svg b/assets/vendor/octicons/svg/unmute.svg
new file mode 100644
index 0000000000..2f6cb82bd0
--- /dev/null
+++ b/assets/vendor/octicons/svg/unmute.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/versions.svg b/assets/vendor/octicons/svg/versions.svg
new file mode 100644
index 0000000000..7ce801df5e
--- /dev/null
+++ b/assets/vendor/octicons/svg/versions.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/watch.svg b/assets/vendor/octicons/svg/watch.svg
new file mode 100644
index 0000000000..91c03d3d3c
--- /dev/null
+++ b/assets/vendor/octicons/svg/watch.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/x.svg b/assets/vendor/octicons/svg/x.svg
new file mode 100644
index 0000000000..7ab1ba2e04
--- /dev/null
+++ b/assets/vendor/octicons/svg/x.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/octicons/svg/zap.svg b/assets/vendor/octicons/svg/zap.svg
new file mode 100644
index 0000000000..c330af6a19
--- /dev/null
+++ b/assets/vendor/octicons/svg/zap.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/vendor/retinajs/.bower.json b/assets/vendor/retinajs/.bower.json
new file mode 100644
index 0000000000..11f03609f6
--- /dev/null
+++ b/assets/vendor/retinajs/.bower.json
@@ -0,0 +1,14 @@
+{
+ "name": "retinajs",
+ "homepage": "https://github.com/imulus/retinajs",
+ "version": "1.1.0",
+ "_release": "1.1.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.1.0",
+ "commit": "160ce0abfcd602bbcddcf5f3255b9f8efd504f4d"
+ },
+ "_source": "git://github.com/imulus/retinajs.git",
+ "_target": "1.1.0",
+ "_originalSource": "retinajs"
+}
\ No newline at end of file
diff --git a/assets/vendor/retinajs/.gitignore b/assets/vendor/retinajs/.gitignore
new file mode 100644
index 0000000000..d7f2d30835
--- /dev/null
+++ b/assets/vendor/retinajs/.gitignore
@@ -0,0 +1,7 @@
+build
+pkg
+tmp
+.DS_Store
+test/functional/retina.*
+test/functional/public/retina.*
+node_modules
diff --git a/assets/vendor/retinajs/.travis.yml b/assets/vendor/retinajs/.travis.yml
new file mode 100644
index 0000000000..9d76248797
--- /dev/null
+++ b/assets/vendor/retinajs/.travis.yml
@@ -0,0 +1,7 @@
+language: node_js
+node_js:
+ - 0.8
+ - 0.6
+notifications:
+ recipients:
+ - ci@imulus.com
diff --git a/assets/vendor/retinajs/LICENSE b/assets/vendor/retinajs/LICENSE
new file mode 100644
index 0000000000..3abbf5bc18
--- /dev/null
+++ b/assets/vendor/retinajs/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Imulus, LLC, Ben Atkin, and other contributors
+
+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.
diff --git a/assets/vendor/retinajs/Makefile b/assets/vendor/retinajs/Makefile
new file mode 100644
index 0000000000..94a6f938db
--- /dev/null
+++ b/assets/vendor/retinajs/Makefile
@@ -0,0 +1,32 @@
+VERSION=$(shell grep 'version' package.json | cut -d '"' -f 4)
+YEAR=$(shell date "+%Y")
+BANNER= "/*!\n \
+ * Retina.js v$(VERSION)\n \
+ *\n \
+ * Copyright $(YEAR) Imulus, LLC\n \
+ * Released under the MIT license\n \
+ *\n \
+ * Retina.js is an open source script that makes it easy to serve\n \
+ * high-resolution images to devices with retina displays.\n \
+ */"
+
+all: clean test build package
+
+clean:
+ rm -rf build
+
+test:
+ npm test
+
+build:
+ mkdir -p build/js build/less
+ cp README.md build/README.md
+ cp src/retina.less build/less/retina-$(VERSION).less
+ echo $(BANNER) > build/js/retina-$(VERSION).js
+ cat src/retina.js >> build/js/retina-$(VERSION).js
+ echo $(BANNER) > build/js/retina-$(VERSION).min.js
+ uglifyjs src/retina.js >> build/js/retina-$(VERSION).min.js
+
+package:
+ mkdir -p pkg
+ cd build && zip -r ../pkg/retina-$(VERSION).zip .
diff --git a/assets/vendor/retinajs/README.md b/assets/vendor/retinajs/README.md
new file mode 100644
index 0000000000..a05f20b519
--- /dev/null
+++ b/assets/vendor/retinajs/README.md
@@ -0,0 +1,130 @@
+# retina.js [](http://travis-ci.org/imulus/retinajs)
+
+JavaScript and LESS helpers for rendering high-resolution image variants. retina.js makes it easy to serve high-resolution images to devices with retina displays.
+
+## How it works
+
+When your users load a page, retina.js checks each image on the page to see if there is a high-resolution version of that image on your server. If a high-resolution variant exists, the script will swap in that image in-place.
+
+The script assumes you use Apple's prescribed high-resolution modifier (@2x) to denote high-resolution image variants on your server. It is also possible to override this by manually specifying the URL for the @2x images using `data-at2x` attributes.
+
+For example, if you have an image on your page that looks like this:
+
+```html
+
+```
+
+The script will check your server to see if an alternative image exists at `/images/my_image@2x.png`
+
+However, if you have:
+
+```html
+
+```
+
+The script will use `http://example.com/my_image@2x.png` as the high-resolution image. No checks to the server will be performed.
+
+## How to use
+
+### JavaScript
+
+The JavaScript helper script automatically replaces images on your page with high-resolution variants (if they exist). To use it, download the script and include it at the bottom of your page.
+
+1. Place the retina.js file on your server
+2. Include the script on your page (put it at the bottom of your template, before your closing \ tag)
+
+``` html
+
+```
+
+### LESS
+
+The LESS CSS mixin is a helper for applying high-resolution background images in your stylesheet. You provide it with an image path and the dimensions of the original-resolution image. The mixin creates a media query specifically for Retina displays, changes the background image for the selector elements to use the high-resolution (@2x) variant and applies a background-size of the original image in order to maintain proper dimensions. To use it, download the mixin, import or include it in your LESS stylesheet, and apply it to elements of your choice.
+
+*Syntax:*
+
+``` less
+.at2x(@path, [optional] @width: auto, [optional] @height: auto);
+```
+
+*Steps:*
+
+1. Add the .at2x() mixin from retina.less to your LESS stylesheet (or reference it in an @import statement)
+2. In your stylesheet, call the .at2x() mixin anywhere instead of using background-image
+
+This:
+
+``` less
+.logo {
+ .at2x('/images/my_image.png', 200px, 100px);
+}
+```
+
+Will compile to:
+
+``` less
+.logo {
+ background-image: url('/images/my_image.png');
+}
+
+@media all and (-webkit-min-device-pixel-ratio: 1.5) {
+ .logo {
+ background-image: url('/images/my_image@2x.png');
+ background-size: 200px 100px;
+ }
+}
+```
+
+### Ruby on Rails 3.x
+
+...or any framework that embeds some digest/hash to the asset URLs based on the contents, e.g. `/images/image-{hash1}.jpg`.
+
+The problem with this is that the high-resolution version would have a different hash, and would not conform the usual pattern, i.e. `/images/image@2x-{hash2}.jpg`. So automatic detection would fail because retina.js would check the existence of `/images/image-{hash1}@2x.jpg`.
+
+There's no way for retina.js to know beforehand what the high-resolution image's hash would be without some sort of help from the server side. So in this case, the suggested method is to supply the high-resolution URLs using the `data-at2x` attributes as previously described in the How It Works section.
+
+In Rails, one way to automate this is using a helper, e.g.:
+
+```ruby
+# in app/helpers/some_helper.rb or app/helpers/application_helper.rb
+def image_tag_with_at2x(name_at_1x, options={})
+ name_at_2x = name_at_1x.gsub(%r{\.\w+$}, '@2x\0')
+ image_tag(name_at_1x, options.merge("data-at2x" => asset_path(name_at_2x)))
+end
+```
+
+And then in your views (templates), instead of using image_tag, you would use image_tag_with_at2x, e.g. for ERB:
+
+```erb
+<%= image_tag_with_at2x "logo.png" %>
+```
+
+It would generate something like:
+
+```html
+
+```
+
+## How to test
+
+We use [mocha](http://visionmedia.github.com/mocha/) for unit testing with [should](https://github.com/visionmedia/should.js) assertions. Install mocha and should by running `npm install`.
+
+To run the test suite:
+
+``` bash
+$ npm test
+```
+
+Use [http-server](https://github.com/nodeapps/http-server) for node.js to test it. To install, run `npm install -g http-server`.
+
+If you've updated `retina.js` be sure to copy it from `src/retina.js` to `test/functional/public/retina.js`.
+
+To start the server, run:
+
+``` bash
+$ cd test/functional && http-server
+```
+
+Then navigate your browser to [http://localhost:8080](http://localhost:8080)
+
+After that, open up `test/functional/public/index.html` in your editor, and try commenting out the line that spoofs retina support, and reloading it.
diff --git a/assets/vendor/retinajs/package.json b/assets/vendor/retinajs/package.json
new file mode 100644
index 0000000000..f35dc1796f
--- /dev/null
+++ b/assets/vendor/retinajs/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "retina.js",
+ "version": "1.1.0",
+ "devDependencies": {
+ "mocha": "*",
+ "should": "*",
+ "less": "*"
+ },
+ "main": "./src/retina",
+ "scripts": {
+ "test": "mocha"
+ }
+}
diff --git a/assets/vendor/retinajs/src/retina.js b/assets/vendor/retinajs/src/retina.js
new file mode 100644
index 0000000000..c948b7f4f0
--- /dev/null
+++ b/assets/vendor/retinajs/src/retina.js
@@ -0,0 +1,143 @@
+(function() {
+
+ var root = (typeof exports == 'undefined' ? window : exports);
+
+ var config = {
+ // Ensure Content-Type is an image before trying to load @2x image
+ // https://github.com/imulus/retinajs/pull/45)
+ check_mime_type: true
+ };
+
+
+
+ root.Retina = Retina;
+
+ function Retina() {}
+
+ Retina.configure = function(options) {
+ if (options == null) options = {};
+ for (var prop in options) config[prop] = options[prop];
+ };
+
+ Retina.init = function(context) {
+ if (context == null) context = root;
+
+ var existing_onload = context.onload || new Function;
+
+ context.onload = function() {
+ var images = document.getElementsByTagName("img"), retinaImages = [], i, image;
+ for (i = 0; i < images.length; i++) {
+ image = images[i];
+ retinaImages.push(new RetinaImage(image));
+ }
+ existing_onload();
+ }
+ };
+
+ Retina.isRetina = function(){
+ var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
+ (min--moz-device-pixel-ratio: 1.5),\
+ (-o-min-device-pixel-ratio: 3/2),\
+ (min-resolution: 1.5dppx)";
+
+ if (root.devicePixelRatio > 1)
+ return true;
+
+ if (root.matchMedia && root.matchMedia(mediaQuery).matches)
+ return true;
+
+ return false;
+ };
+
+
+ root.RetinaImagePath = RetinaImagePath;
+
+ function RetinaImagePath(path, at_2x_path) {
+ this.path = path;
+ if (typeof at_2x_path !== "undefined" && at_2x_path !== null) {
+ this.at_2x_path = at_2x_path;
+ this.perform_check = false;
+ } else {
+ this.at_2x_path = path.replace(/\.\w+$/, function(match) { return "@2x" + match; });
+ this.perform_check = true;
+ }
+ }
+
+ RetinaImagePath.confirmed_paths = [];
+
+ RetinaImagePath.prototype.is_external = function() {
+ return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) )
+ }
+
+ RetinaImagePath.prototype.check_2x_variant = function(callback) {
+ var http, that = this;
+ if (this.is_external()) {
+ return callback(false);
+ } else if (!this.perform_check && typeof this.at_2x_path !== "undefined" && this.at_2x_path !== null) {
+ return callback(true);
+ } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) {
+ return callback(true);
+ } else {
+ http = new XMLHttpRequest;
+ http.open('HEAD', this.at_2x_path);
+ http.onreadystatechange = function() {
+ if (http.readyState != 4) {
+ return callback(false);
+ }
+
+ if (http.status >= 200 && http.status <= 399) {
+ if (config.check_mime_type) {
+ var type = http.getResponseHeader('Content-Type');
+ if (type == null || !type.match(/^image/i)) {
+ return callback(false);
+ }
+ }
+
+ RetinaImagePath.confirmed_paths.push(that.at_2x_path);
+ return callback(true);
+ } else {
+ return callback(false);
+ }
+ }
+ http.send();
+ }
+ }
+
+
+
+ function RetinaImage(el) {
+ this.el = el;
+ this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x'));
+ var that = this;
+ this.path.check_2x_variant(function(hasVariant) {
+ if (hasVariant) that.swap();
+ });
+ }
+
+ root.RetinaImage = RetinaImage;
+
+ RetinaImage.prototype.swap = function(path) {
+ if (typeof path == 'undefined') path = this.path.at_2x_path;
+
+ var that = this;
+ function load() {
+ if (! that.el.complete) {
+ setTimeout(load, 5);
+ } else {
+ that.el.setAttribute('width', that.el.offsetWidth);
+ that.el.setAttribute('height', that.el.offsetHeight);
+ that.el.setAttribute('src', path);
+ }
+ }
+ load();
+ }
+
+
+
+
+ if (Retina.isRetina()) {
+ Retina.init(root);
+ }
+
+})();
+
diff --git a/assets/vendor/retinajs/src/retina.less b/assets/vendor/retinajs/src/retina.less
new file mode 100644
index 0000000000..3b96a416cd
--- /dev/null
+++ b/assets/vendor/retinajs/src/retina.less
@@ -0,0 +1,14 @@
+// retina.less
+// A helper mixin for applying high-resolution background images (http://www.retinajs.com)
+
+@highdpi: ~"(-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 1.5dppx)";
+
+.at2x(@path, @w: auto, @h: auto) {
+ background-image: url(@path);
+ @at2x_path: ~`@{path}.replace(/\.\w+$/, function(match) { return "@2x" + match; })`;
+
+ @media @highdpi {
+ background-image: url("@{at2x_path}");
+ background-size: @w @h;
+ }
+}
diff --git a/assets/vendor/retinajs/test/fixtures/desired_output.css b/assets/vendor/retinajs/test/fixtures/desired_output.css
new file mode 100644
index 0000000000..493c281363
--- /dev/null
+++ b/assets/vendor/retinajs/test/fixtures/desired_output.css
@@ -0,0 +1,18 @@
+body {
+ background-image: url('/path/to/image.png');
+}
+@media (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 1.5dppx) {
+ body {
+ background-image: url("/path/to/image@2x.png");
+ background-size: 200px 100px;
+ }
+}
+header {
+ background-image: url("/path/to/header.png");
+}
+@media (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 1.5dppx) {
+ header {
+ background-image: url("/path/to/header@2x.png");
+ background-size: 600px 50px;
+ }
+}
diff --git a/assets/vendor/retinajs/test/fixtures/image.js b/assets/vendor/retinajs/test/fixtures/image.js
new file mode 100644
index 0000000000..976b56be8f
--- /dev/null
+++ b/assets/vendor/retinajs/test/fixtures/image.js
@@ -0,0 +1,19 @@
+function Image() {
+ this.complete = true;
+ this.attributes = {
+ src : "/images/some_image.png",
+ offsetWidth : 500,
+ offsetHeight : 400
+ };
+}
+
+Image.prototype.setAttribute = function(name, value) {
+ this.attributes[name] = value;
+}
+
+Image.prototype.getAttribute = function(name) {
+ return this.attributes[name];
+}
+
+var root = (exports || window);
+root.Image = Image;
diff --git a/assets/vendor/retinajs/test/fixtures/test.less b/assets/vendor/retinajs/test/fixtures/test.less
new file mode 100644
index 0000000000..47e13f7533
--- /dev/null
+++ b/assets/vendor/retinajs/test/fixtures/test.less
@@ -0,0 +1,10 @@
+@import 'src/retina';
+
+// Single quoted
+body {
+ .at2x('/path/to/image.png', 200px, 100px);
+}
+// Double quoted
+header {
+ .at2x("/path/to/header.png", 600px, 50px);
+}
diff --git a/assets/vendor/retinajs/test/fixtures/xml_http_request.js b/assets/vendor/retinajs/test/fixtures/xml_http_request.js
new file mode 100644
index 0000000000..7c26b1cab7
--- /dev/null
+++ b/assets/vendor/retinajs/test/fixtures/xml_http_request.js
@@ -0,0 +1,24 @@
+function XMLHttpRequest() {
+ this.status = XMLHttpRequest.status;
+ this.contentType = XMLHttpRequest.contentType;
+ this.readyState = 4;
+ this.onreadystatechange = function() {}
+}
+
+XMLHttpRequest.status = 200;
+XMLHttpRequest.contentType = 'image/png';
+
+XMLHttpRequest.prototype.open = function() {
+ return true;
+}
+
+XMLHttpRequest.prototype.send = function() {
+ this.onreadystatechange();
+}
+
+XMLHttpRequest.prototype.getResponseHeader = function(contentType) {
+ return this.contentType;
+}
+
+var root = (exports || window);
+root.XMLHttpRequest = XMLHttpRequest;
diff --git a/assets/vendor/retinajs/test/functional/public/google.png b/assets/vendor/retinajs/test/functional/public/google.png
new file mode 100644
index 0000000000..533d2b2737
Binary files /dev/null and b/assets/vendor/retinajs/test/functional/public/google.png differ
diff --git a/assets/vendor/retinajs/test/functional/public/google@1x.png b/assets/vendor/retinajs/test/functional/public/google@1x.png
new file mode 100644
index 0000000000..533d2b2737
Binary files /dev/null and b/assets/vendor/retinajs/test/functional/public/google@1x.png differ
diff --git a/assets/vendor/retinajs/test/functional/public/google@2x.png b/assets/vendor/retinajs/test/functional/public/google@2x.png
new file mode 100644
index 0000000000..99b37d55bf
Binary files /dev/null and b/assets/vendor/retinajs/test/functional/public/google@2x.png differ
diff --git a/assets/vendor/retinajs/test/functional/public/index.html b/assets/vendor/retinajs/test/functional/public/index.html
new file mode 100644
index 0000000000..8dc85f57fd
--- /dev/null
+++ b/assets/vendor/retinajs/test/functional/public/index.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/vendor/retinajs/test/functional/public/ipad_hero.jpeg b/assets/vendor/retinajs/test/functional/public/ipad_hero.jpeg
new file mode 100644
index 0000000000..40943cb679
Binary files /dev/null and b/assets/vendor/retinajs/test/functional/public/ipad_hero.jpeg differ
diff --git a/assets/vendor/retinajs/test/functional/public/ipad_hero@1x.jpeg b/assets/vendor/retinajs/test/functional/public/ipad_hero@1x.jpeg
new file mode 100644
index 0000000000..40943cb679
Binary files /dev/null and b/assets/vendor/retinajs/test/functional/public/ipad_hero@1x.jpeg differ
diff --git a/assets/vendor/retinajs/test/functional/public/ipad_hero@2x.jpeg b/assets/vendor/retinajs/test/functional/public/ipad_hero@2x.jpeg
new file mode 100644
index 0000000000..da7a1709d4
Binary files /dev/null and b/assets/vendor/retinajs/test/functional/public/ipad_hero@2x.jpeg differ
diff --git a/assets/vendor/retinajs/test/mocha.opts b/assets/vendor/retinajs/test/mocha.opts
new file mode 100644
index 0000000000..24d45f5902
--- /dev/null
+++ b/assets/vendor/retinajs/test/mocha.opts
@@ -0,0 +1,3 @@
+--require should
+--slow 20
+--growl
diff --git a/assets/vendor/retinajs/test/retina.test.js b/assets/vendor/retinajs/test/retina.test.js
new file mode 100644
index 0000000000..6dc3ad4934
--- /dev/null
+++ b/assets/vendor/retinajs/test/retina.test.js
@@ -0,0 +1,36 @@
+// Create a document object because we don't have one
+// in our Node test environment
+delete global.document;
+global.document = {};
+
+var Retina = require('../').Retina;
+
+describe('Retina', function() {
+
+ before(function(){
+ // stub out the getElementsByTagName method
+ global.document = {
+ getElementsByTagName : function(){
+ return [];
+ }
+ }
+ });
+
+ describe('init', function(){
+ it('stashes the existing onload and executes it later', function(){
+ var existingOnloadExecutions = 0;
+ var window = {
+ matchMedia : function() {
+ return { matches: false }
+ },
+ onload : function() {
+ existingOnloadExecutions++;
+ }
+ };
+ Retina.init(window);
+ window.onload();
+ existingOnloadExecutions.should.equal(1);
+ });
+ });
+
+});
diff --git a/assets/vendor/retinajs/test/retina_image_path.test.js b/assets/vendor/retinajs/test/retina_image_path.test.js
new file mode 100644
index 0000000000..439d711b4a
--- /dev/null
+++ b/assets/vendor/retinajs/test/retina_image_path.test.js
@@ -0,0 +1,195 @@
+// Create a document object because we don't have one
+// in our Node test environment
+delete global.document;
+global.document = {};
+global.Image = require('./fixtures/image').Image;
+global.XMLHttpRequest = require('./fixtures/xml_http_request').XMLHttpRequest;
+
+global.exports = {
+ devicePixelRatio : 0.9,
+ matchMedia : function() {
+ return {
+ matches : false
+ }
+ }
+}
+
+var Retina = require('../').Retina;
+var RetinaImage = require('../').RetinaImage;
+var RetinaImagePath = require('../').RetinaImagePath;
+
+describe('RetinaImagePath', function() {
+ var path = null;
+
+ before(function(){
+ global.document = {domain: null};
+ });
+
+ describe('@at_2x_path', function(){
+ it('adds "@2x" before the extension', function(){
+ path = new RetinaImagePath("/path/to/image.png");
+ path.at_2x_path.should.equal("/path/to/image@2x.png");
+ });
+
+ it('uses data-@2x when supplied', function(){
+ path = new RetinaImagePath("/path/to/image-hash1.png", "/path/to/image@2x-hash2.png");
+ path.at_2x_path.should.equal("/path/to/image@2x-hash2.png");
+ });
+ });
+
+ describe('#is_external()', function() {
+ it('should return true when image path references a remote domain with www', function() {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("http://www.google.com/images/some_image.png");
+ path.is_external().should.equal(true);
+ });
+
+ it('should return true when image path references a remote domain without www', function() {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("http://google.com/images/some_image.png");
+ path.is_external().should.equal(true);
+ });
+
+ it('should return true when image path references a remote domain with https', function() {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("https://google.com/images/some_image.png");
+ path.is_external().should.equal(true);
+ });
+
+ it('should return true when image path is a remote domain with www and domain is localhost', function() {
+ document.domain = "localhost";
+ path = new RetinaImagePath("http://www.google.com/images/some_image.png");
+ path.is_external().should.equal(true);
+ });
+
+ it('should return true when image path is a remote domain without www and domain is localhost', function() {
+ document.domain = "localhost"
+ path = new RetinaImagePath("http://google.com/images/some_image.png")
+ path.is_external().should.equal(true);
+ });
+
+ it('should return true when image path has www and domain does not', function() {
+ document.domain = "apple.com";
+ path = new RetinaImagePath("http://www.apple.com/images/some_image.png");
+ path.is_external().should.equal(true);
+ });
+
+ it('should return true when image path does not have www and domain does', function() {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("http://apple.com/images/some_image.png");
+ path.is_external().should.equal(true);
+ });
+
+ it('should return false when image path is relative with www', function() {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("/images/some_image.png");
+ path.is_external().should.equal(false);
+ });
+
+ it('should return false when image path is relative without www', function() {
+ document.domain = "apple.com";
+ path = new RetinaImagePath("/images/some_image.png");
+ path.is_external().should.equal(false);
+ });
+
+ it('should return false when image path is relative to localhost', function() {
+ document.domain = "localhost";
+ path = new RetinaImagePath("/images/some_image.png");
+ path.is_external().should.equal(false);
+ });
+
+ it('should return false when image path has same domain as current site with www', function() {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("http://www.apple.com/images/some_image.png");
+ path.is_external().should.equal(false);
+ });
+ });
+
+ describe('#check_2x_variant()', function() {
+ it('should callback with false when #is_external() is true', function(done) {
+ document.domain = "www.apple.com";
+ path = new RetinaImagePath("http://google.com/images/some_image.png");
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(false);
+ done();
+ });
+ });
+
+ it('should callback with true when at2x is supplied', function(done) {
+ path = new RetinaImagePath("/images/some_image.png", "/images/some_image@100x.png");
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(true);
+ done();
+ });
+ });
+
+ it('should callback with false when remote at2x image does not exist', function(done) {
+ XMLHttpRequest.status = 404; // simulate a failing request
+ XMLHttpRequest.contentType = 'image/png'; // simulate a proper content type
+ path = new RetinaImagePath("/images/some_image.png");
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(false);
+ done();
+ });
+ });
+
+ it('should callback with false when content-type is not an image type', function(done) {
+ XMLHttpRequest.status = 200; // simulate a an image request that comes back OK
+ XMLHttpRequest.contentType = 'text/html'; // but is actually an improperly coded 404 page
+ path = new RetinaImagePath("/images/some_image.png");
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(false);
+ done();
+ });
+ });
+
+ it('should callback with true when content-type is wrong, but check_mime_type is false', function(done) {
+ XMLHttpRequest.status = 200; // simulate a proper request
+ XMLHttpRequest.contentType = 'text/html'; // but with an incorrect content type
+
+ Retina.configure({
+ check_mime_type: false // but ignore it
+ });
+
+ path = new RetinaImagePath("/images/some_image.png");
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(true);
+
+ Retina.configure({
+ check_mime_type: true
+ });
+
+ done();
+ });
+ });
+
+ it('should callback with true when remote at2x image exists', function(done) {
+ XMLHttpRequest.status = 200; // simulate a proper request
+ XMLHttpRequest.contentType = 'image/png'; // simulate a proper content type
+ path = new RetinaImagePath("/images/some_image.png");
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(true);
+ done();
+ });
+ });
+
+ it('should add path to cache when at2x image exists', function(done) {
+ XMLHttpRequest.status = 200; // simulate a proper request
+ XMLHttpRequest.contentType = 'image/png'; // simulate a proper content type
+ path = new RetinaImagePath("/images/some_image.png");
+ path.check_2x_variant(function(hasVariant) {
+ RetinaImagePath.confirmed_paths.should.include(path.at_2x_path);
+ done();
+ });
+ });
+
+ it('should return true when the at2x image path has already been checked and confirmed', function(done) {
+ RetinaImagePath.confirmed_paths = ['/images/some_image@2x.png']
+ path = new RetinaImagePath("/images/some_image.png")
+ path.check_2x_variant(function(hasVariant) {
+ hasVariant.should.equal(true);
+ done();
+ });
+ });
+ });
+});
diff --git a/assets/vendor/retinajs/test/retina_less.test.js b/assets/vendor/retinajs/test/retina_less.test.js
new file mode 100644
index 0000000000..7268ab14e4
--- /dev/null
+++ b/assets/vendor/retinajs/test/retina_less.test.js
@@ -0,0 +1,17 @@
+var fs = require('fs');
+var less = require('less');
+
+describe('retina.less', function() {
+
+ describe('.at2x()', function(){
+ it('compiles correctly', function(done){
+ var desired_output = fs.readFileSync('test/fixtures/desired_output.css', 'utf8');
+ var input = fs.readFileSync('test/fixtures/test.less', 'utf8');
+ less.render(input, function (e, actual_output) {
+ actual_output.should.equal(desired_output);
+ done();
+ });
+ });
+ });
+
+});
diff --git a/bower.json b/bower.json
new file mode 100644
index 0000000000..d2ddf6b081
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,8 @@
+{
+ "name": "developer.github.com",
+ "dependencies": {
+ "lunr.js": "0.6.0",
+ "octicons": "3.0.1",
+ "retinajs": "1.1.0"
+ }
+}
diff --git a/changes.atom b/changes.atom
deleted file mode 100644
index 502617e422..0000000000
--- a/changes.atom
+++ /dev/null
@@ -1,1201 +0,0 @@
-
-
- http://developer.github.com/
- GitHub API Changes
- 2014-01-29T05:00:00Z
-
-
-
- technoweenie
- https://github.com/technoweenie
-
-
- tag:developer.github.com,2014-01-29:/changes/2014-01-29-audit-org-members-for-2fa/
- Audit organization members for two-factor authentication
- 2014-01-29T05:00:00Z
- 2014-01-29T05:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>We’ve added a <a href="/v3/orgs/members/#audit-two-factor-auth">new filter</a> for listing members of an organization without
-<a href="https://github.com/blog/1614-two-factor-authentication">two-factor authentication</a> enabled:</p>
-
-<pre class="terminal">
-$ curl -H "Authorization: token [yours]" \
- https://api.github.com/orgs/octokit/members\?filter\=2fa_disabled
-</pre>
-
-<p>The new filter is available for owners of organizations with private
-repositories. Happy auditing and <a href="https://github.com/contact?form%5Bsubject%5D=API+2FA+filter">send us your feedback or questions</a>.</p>
-
-
-
-
- tag:developer.github.com,2014-01-09:/changes/2014-01-09-preview-the-new-deployments-api/
- Preview the New Deployments API
- 2014-01-09T05:00:00Z
- 2014-01-09T05:00:00Z
-
- atmos
- https://github.com/technoweenie
-
-
- <p>Today we’re excited to announce a <a href="/v3/repos/deployments/">Deployments API</a>. We ship a lot of
-software at GitHub: web, mobile, and native. For the last few years, we’ve been
-driving our deployments from our <a href="https://speakerdeck.com/jnewland/chatops">ChatOps tooling</a> and we’ve learned a
-lot. The Deployments API is a generalization of the approach that we’ve been
-taking, and we’re really excited to see what our users and integrations start
-building around it.</p>
-
-<p>Deployments are a new model in the GitHub ecosystem. We don’t have any UI
-components currently, and deployments are intended to be used exclusively by
-tooling. If you’re familiar with the Status API, you know that it allows
-various tools to report on the status of a commit (e.g., the progress of an
-attempt to perform a build at a particular commit). The Status API doesn’t
-perform the build; it just reports the results. Much like the Status API, we
-won’t be doing actual deployments for you. Instead, the API provides a way for
-you to track the status of your deployments. We’re hoping to provide
-consistency across the various type of release processes, regardless of the
-underlying steps involved with getting your code built or shipped to your
-servers.</p>
-
-<h2 id="highlights">Highlights</h2>
-
-<h3 id="automatic-merging">Automatic Merging</h3>
-
-<p>The system can auto-merge the default branch for the repository if the
-requested deployment ref is behind the default branch. On active projects it’s
-easy to fall behind, so let automation watch your back.</p>
-
-<h3 id="commit-status-integration">Commit Status Integration</h3>
-
-<p>By default, the system rejects deployment requests for repositories that have
-commit statuses but don’t have a green build for the deployment ref. This can
-be bypassed, but is useful in cases where continuous integration is being used.</p>
-
-<h3 id="force-deployments">Force Deployments</h3>
-
-<p>Sometimes the world crashes down on you, and you need to just get the code out
-the door. Forced deployments bypass any commit status checks or ahead/behind
-checks in the repository.</p>
-
-<h3 id="deployment-statuses">Deployment Statuses</h3>
-
-<p>Different deployment systems can update the status of a deployment to be
-<code>pending</code>, <code>success</code>, <code>failure</code>, or <code>error</code>. There’s also a field for linking
-to deployment output.</p>
-
-<h3 id="events">Events</h3>
-
-<p>Both Deployments and Deployment Statuses trigger events on GitHub. 3rd party
-integrations can listen for these events via <a href="/v3/repos/hooks/">webhooks</a> and choose
-whether or not to actually deploy the repository that the event was created for.</p>
-
-<h2 id="preview-period">Preview Period</h2>
-
-<p>We’re making this new API available today for developers to
-<a href="/v3/repos/deployments/#preview-mode">preview</a>. We think developers and existing integrations are
-going to love it, but we want to <a href="https://github.com/contact?form%5Bsubject%5D=Deployments+API">get your feedback</a> before we declare
-the Deployments API “final” and “unchangeable.” We expect the preview period to
-last for roughly 60-90 days.</p>
-
-<p>As we discover opportunities to improve the API during the preview period, we
-may ship changes that break clients using the preview version of the API. We
-want to iterate quickly. To do so, we will announce any changes here (on the
-developer blog), but we will not provide any advance notice.</p>
-
-<p>At the end of preview period, the Deployments API will become an official
-component of GitHub API v3. At that point, the new Deployments API will be
-stable and suitable for production use.</p>
-
-<p>We hope you’ll take it for a spin and <a href="https://github.com/contact?form%5Bsubject%5D=Deployments+API">send us your feedback</a>.</p>
-
-<p><img src="http://shipitsquirrel.github.io/images/ship%20it%20squirrel.png" alt=""></p>
-
-
-
-
- tag:developer.github.com,2014-01-07:/changes/2014-01-07-upcoming-change-to-default-media-type/
- Upcoming Change to Default Media Type
- 2014-01-07T05:00:00Z
- 2014-01-07T05:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>On April 15, 2014<a href="#cutover-test">*</a>, the GitHub API will start serving the v3 media type by default. The information below will help you determine whether your applications will be affected by this change. For affected applications, you’ll find tips below to help you smoothly navigate this change.</p>
-
-<h2 id="whats-changing">What’s changing?</h2>
-
-<h3 id="a-new-default-version">A new default version</h3>
-
-<p>There are <a href="/v3/versions">two versions</a> of the GitHub API: <strong>beta</strong> and <strong>v3</strong>. Today, requests receive the beta version by default. On April 15<a href="#cutover-test">*</a>, requests will begin receiving the v3 version by default.</p>
-
-<p>For the most part, beta and v3 are remarkably similar. There are <a href="/v3/versions/#differences-from-beta-version">just a few differences</a> to keep in mind.</p>
-
-<h3 id="a-new-default-media-type">A new default media type</h3>
-
-<p>The version is one part of the <a href="/v3/media">media type</a>. By default, the API provides the beta media type:</p>
-
-<pre><code>application/vnd.github.beta+json
-</code></pre>
-
-<p>On April 15<a href="#cutover-test">*</a>, requests will begin responding with the v3 media type by default:</p>
-
-<pre><code>application/vnd.github.v3+json
-</code></pre>
-
-<h2 id="who-is-affected">Who is affected?</h2>
-
-<p>Since 2012, we have encouraged developers to explicitly <a href="/v3/media/#beta-v3-and-the-future">request a specific media type via the <code>Accept</code> header</a>. If you are requesting either beta or v3 via the <code>Accept</code> header, then you are <em>not</em> affected by this change. The API will continue to respond with the requested media type.</p>
-
-<p>If you are not requesting beta or v3 via the <code>Accept</code> header, then the API is currently responding with the beta media type. On April 15<a href="#cutover-test">*</a>, the API will begin responding with the v3 media type. If your application relies on <a href="/v3/versions/#differences-from-beta-version">functionality that differs between beta and v3</a>, then you are affected by this change. You will need to take steps to prepare for the change.</p>
-
-<h2 id="what-should-you-do">What should you do?</h2>
-
-<p>If you are affected by this change, we recommend that you:</p>
-
-<ol>
- <li>Update your applications to depend on the v3 functionality instead of the beta functionality. (If you use one of the popular <a href="/libraries/">client libraries</a>, there’s a good chance that they’ve already done the work for you. In that case, you can just update to the latest version of that library.)</li>
- <li>Request the v3 media type via the <code>Accept</code> header.</li>
-</ol>
-
-<p>If you cannot update your application to depend on the v3 functionality by April 15<a href="#cutover-test">*</a>, you can just request the beta media type via the <code>Accept</code> header. Doing so will insulate you from this change.</p>
-
-<h2 id="cutover-test">Cutover test on March 12, 2014</h2>
-
-<p>To help you understand the impact of this change before it becomes permanent, we will temporarily implement this change for a single day on March 12. From approximately 12:01am UTC to 11:59pm UTC on March 12, the API will respond with the v3 media type by default.</p>
-
-<p>Follow <a href="https://twitter.com/GitHubAPI">@GitHubAPI</a> to receive updates before and after the test.</p>
-
-<h2 id="stay-informed">Stay informed</h2>
-
-<p>Depending on the results of the cutover test, we may schedule additional tests before the final cutover on April 15. If so, we’ll to announce them in advance. Be sure to stay tuned to the <a href="/changes">blog</a> or follow <a href="https://twitter.com/GitHubAPI">@GitHubAPI</a> for updates.</p>
-
-<p>If you have any questions, please <a href="https://github.com/contact?form%5Bsubject%5D=Upcoming+change+to+default+API+media+type">get in touch</a>. We’ll be happy to help.</p>
-
-
-
-
- tag:developer.github.com,2013-12-13:/changes/2013-12-13-paginating-org-members/
- Paginated results for organization members
- 2013-12-13T05:00:00Z
- 2013-12-13T05:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>The <a href="http://developer.github.com/v3/orgs/members/#members-list">organization members</a> and <a href="http://developer.github.com/v3/orgs/members/#public-members-list">organization public members</a> methods will soon return paginated results by default. Beginning
-today, these methods will paginate if you include <code>page</code> or <code>per_page</code> query
-parameters. Starting January 15th, 2014, these methods will <em>always</em> return paginated
-results.</p>
-
-<p>As always, be sure and follow those <a href="http://developer.github.com/v3/#pagination">Link headers</a> to get
-subsequent results. If you have any questions or run into trouble, feel free to
-<a href="https://github.com/contact?form%5Bsubject%5D=API+v3:+Paginating+org+members">get in touch</a>.</p>
-
-<p>Happy paginating.</p>
-
-
-
-
- tag:developer.github.com,2013-11-04:/changes/2013-11-04-releases-api-is-official/
- Releases API is Official
- 2013-11-04T05:00:00Z
- 2013-11-04T05:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>Hot on the heels of the <a href="http://developer.github.com/changes/2013-10-29-search-api-becomes-an-official-part-of-github-api-v3/">Search API</a>, the <a href="/v3/repos/releases/">Releases API</a>
-is now officially part of GitHub API v3. We now consider it stable for
-production use. </p>
-
-<h3 id="preview-media-type-no-longer-needed">Preview Media Type No Longer Needed</h3>
-
-<p>If you used the Releases API during the preview period, you needed to provide a custom media type in the <code>Accept</code> header:</p>
-
-<pre><code>application/vnd.github.manifold-preview+json
-</code></pre>
-
-<p>Now that the preview period has ended, you no longer need to pass this custom media type.</p>
-
-<p>Instead, we <a href="/v3/media">recommend</a> that you specify <code>v3</code> as the version in the <code>Accept</code> header:</p>
-
-<pre><code>application/vnd.github.v3+json
-</code></pre>
-
-<h3 id="onward">Onward!</h3>
-
-<p>Thanks again to everyone that tried out the Releases API during the preview period.
-We got some great feedback, and we are already discussing additions to the API.</p>
-
-<p>We can’t wait to see what you ship!</p>
-
-
-
-
- tag:developer.github.com,2013-10-29:/changes/2013-10-29-search-api-becomes-an-official-part-of-github-api-v3/
- Search API Becomes an Official Part of API v3
- 2013-10-29T04:00:00Z
- 2013-10-29T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>We’re excited to announce that the <a href="/v3/search">new Search API</a> has graduated from <a href="/changes/2013-07-19-preview-the-new-search-api/#preview-period">preview mode</a>.
-As of today, the Search API is an official part of <a href="/v3">GitHub API v3</a>.
-As such, the Search API is now stable and suitable for production use.</p>
-
-<h3 id="preview-media-type-no-longer-needed">Preview Media Type No Longer Needed</h3>
-
-<p>If you used the Search API during the preview period, you needed to provide a custom media type in the <code>Accept</code> header:</p>
-
-<pre><code>application/vnd.github.preview+json
-</code></pre>
-
-<p>Now that the preview period has ended, you no longer need to pass this custom media type.</p>
-
-<p>Instead, we <a href="/v3/media">recommend</a> that you specify <code>v3</code> as the version in the <code>Accept</code> header:</p>
-
-<pre><code>application/vnd.github.v3+json
-</code></pre>
-
-<h3 id="onward">Onward!</h3>
-
-<p>Thanks again to everyone that tried out the Search API during the preview period.</p>
-
-<p>We can’t wait to see what you build!</p>
-
-
-
-
- tag:developer.github.com,2013-10-18:/changes/2013-10-18-new-code-search-requirements/
- New Validation Rule for Beta Code Search API
- 2013-10-18T04:00:00Z
- 2013-10-18T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>As we <a href="/changes/2013-09-28-an-update-on-the-new-search-api/">prepare to end the preview period</a> for the new search API,
-we’re making sure that it’s ready to handle the traffic from all the apps you’ll build on top of it.</p>
-
-<h2 id="new-validation-rule">New Validation Rule</h2>
-
-<p>In order to support the expected volume of requests, we’re applying a new validation rule to the <a href="/v3/search/#search-code">Code Search API</a>.
-Starting today, you will need to scope your code queries to a specific set of users, organizations, or repositories.</p>
-
-<p>As usual, you specify the query via the <code>q</code> parameter.
-The value must include <a href="https://help.github.com/articles/searching-code#users-organizations-and-repositories">at least one user, organization, or repository</a>.</p>
-
-<p>For example, with this query, we’re searching for code from <a href="https://github.com/twitter">@twitter</a> or <a href="https://github.com/facebook">@facebook</a> that uses an MIT License:</p>
-
-<pre><code>MIT License user:twitter user:facebook
-</code></pre>
-
-<p>And here, we’re looking for uses of the underscore library in <a href="https://github.com/mozilla/BrowserQuest">@mozilla’s BrowserQuest</a> repository:</p>
-
-<pre><code>underscore language:js repo:mozilla/BrowserQuest
-</code></pre>
-
-<p>To perform these queries via the API, we would use the following URLs (respectively):</p>
-
-<pre><code>https://api.github.com/search/code?q=MIT+License+user%3Atwitter+user%3Afacebook
-
-https://api.github.com/search/code?q=underscore+language%3Ajs+repo%3Amozilla%2FBrowserQuest
-</code></pre>
-
-<p>All the various <a href="https://help.github.com/articles/searching-code">code search qualifiers</a> are still available to you.
-A <a href="https://help.github.com/articles/searching-code#users-organizations-and-repositories">user, organization, or repository qualifier</a> is now required.
-The other search qualifiers are still optional.</p>
-
-<h2 id="other-search-types-not-affected">Other Search Types Not Affected</h2>
-
-<p>This new validation only applies to the <a href="/v3/search/#search-code">Code Search API</a>.
-It does not apply to the Search API for <a href="/v3/search/#search-issues">issues</a>, <a href="/v3/search/#search-users">users</a>, or <a href="/v3/search/#search-repositories">repositories</a>.</p>
-
-<p>This validation does not affect searches performed on <a href="https://github.com/search">github.com/search</a>.</p>
-
-<p>By ensuring that code queries are more targeted in nature, the API will be ready to meet the expected demand from all your apps.
-As we continue to tune the Search API, we hope to relax this validation in the future.
-There’s no ETA, but we’d like to relax it as soon as it’s feasible.</p>
-
-<p>As always, if you have any questions or feedback, please <a href="https://github.com/contact?form%5Bsubject%5D=New+Validation+Rule+for+Code+Search+API">get in touch</a>.</p>
-
-
-
-
- tag:developer.github.com,2013-10-08:/changes/2013-10-08-list-all-user-teams/
- List all teams for the authenticated user
- 2013-10-08T04:00:00Z
- 2013-10-08T04:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>We just added a <a href="/v3/orgs/teams/#list-user-teams">new API method</a> to list all
-the teams for the authenticated user across all organizations:</p>
-
-<pre class="terminal">
-$ curl -H "Authorization: token [yours]" https://api.github.com/user/teams
-
-[
- {
- "name": "Testing",
- "id": 396018,
- "slug": "testing",
- "permission": "pull",
- "url": "https://api.github.com/teams/396018",
- "members_url": "https://api.github.com/teams/396018/members{/member}",
- "repositories_url": "https://api.github.com/teams/396018/repos",
- "members_count": 1,
- "repos_count": 0,
- "organization": {
- "login": "dotfiles",
- "id": 1593590,
- "url": "https://api.github.com/orgs/dotfiles",
- "repos_url": "https://api.github.com/orgs/dotfiles/repos",
- "events_url": "https://api.github.com/orgs/dotfiles/events",
- "members_url": "https://api.github.com/orgs/dotfiles/members{/member}",
- "public_members_url": "https://api.github.com/orgs/dotfiles/public_members{/member}",
- "avatar_url": "https://0.gravatar.com/avatar/67d30facf213f62853c119fc2a05e246?d=https%3A%2F%2Fidenticons.github.com%2Fc90a68e6ab739e81c642f0e93f88c722.png"
- }
- },
- ...
-]
-</pre>
-
-<p>As always, if you have any questions or feedback, please <a href="https://github.com/contact?form%5Bsubject%5D=API+-+Listing+Teams+for+User">drop us a line</a>.</p>
-
-
-
-
- tag:developer.github.com,2013-10-04:/changes/2013-10-04-oauth-changes-coming/
- OAuth changes coming
- 2013-10-04T04:00:00Z
- 2013-10-04T04:00:00Z
-
- tclem
- https://github.com/technoweenie
-
-
- <p>Starting today, we are returning granted scopes as part of the
-<a href="/v3/oauth/#github-redirects-back-to-your-site">access_token response</a>.
-For example, if you are making a POST with the <code>application/json</code>
-mime-type you’ll see an additional field for the granted scopes.</p>
-
-<pre><code class="language-javascript"><span class="p">{</span>
- <span class="s2">"access_token"</span><span class="o">:</span><span class="s2">"e72e16c7e42f292c6912e7710c838347ae178b4a"</span><span class="p">,</span>
- <span class="s2">"scope"</span><span class="o">:</span><span class="s2">"repo,gist"</span><span class="p">,</span>
- <span class="s2">"token_type"</span><span class="o">:</span><span class="s2">"bearer"</span>
-<span class="p">}</span></code></pre>
-
-<p>Right now, these scopes will be identical to what you requested, but we
-are moving towards a feature set that will allow GitHub users to edit
-their scopes, effectively granting your application less access than you
-originally requested. You should be aware of this possibility and adjust
-your application behavior accordingly.</p>
-
-<p>Some things to watch out for and keep in mind:</p>
-
-<ul>
- <li>
- <p>Most third party applications using GitHub OAuth to identify users have
-the best success in adoption by starting out with a request for the
-minimum access that the application can possibly get away with.
-Something like no scopes or just <code>user:email</code> is very sane.</p>
- </li>
- <li>
- <p>It is important to handle the error cases where a user chooses to
-grant you less access than you originally requested. Now that we are
-surfacing the granted scopes on the access_token response, applications
-can warn or otherwise communicate with their users that they will see
-reduced functionality or be unable to perform some actions.</p>
- </li>
- <li>
- <p>Applications can always send users back through the flow again to get
-additional permission, but don’t forget that users can always say no.</p>
- </li>
-</ul>
-
-
-
- tag:developer.github.com,2013-09-28:/changes/2013-09-28-an-update-on-the-new-search-api/
- An Update on the New Search API
- 2013-09-28T04:00:00Z
- 2013-09-28T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>We owe a big “Thank You!” to everyone that has taken the time to try out the <a href="/changes/2013-07-19-preview-the-new-search-api">new Search API</a>.
-We <code>:heart:</code> every one of you.
-Just as we hoped,
-the <a href="/changes/2013-07-19-preview-the-new-search-api/#preview-period">preview period</a> has allowed us to see how you want to use the new API,
-and it has given us a chance to improve the API before finalizing it.</p>
-
-<p>In order to incorporate everything that we’ve learned,
-we’re going to keep the Search API in <a href="/changes/2013-07-19-preview-the-new-search-api/#preview-period">preview mode</a> for a little while longer.
-We have a few bugs to squash and a couple performance kinks to iron out.
-We’re hard at work on those improvements now,
-and we expect to have more news in the coming weeks.</p>
-
-<p>In the mean time, <a href="https://github.com/contact?form%5Bsubject%5D=New+Search+API">keep the suggestions coming</a>!</p>
-
-
-
-
- tag:developer.github.com,2013-09-25:/changes/2013-09-25-releases-api/
- Releases API
- 2013-09-25T04:00:00Z
- 2013-09-25T04:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>This summer we made it easier to <a href="https://github.com/blog/1547-release-your-software">release your software</a>. Today, you can fully automate those releases via the
-<a href="http://developer.github.com/v3/repos/releases/">Releases API Preview</a>.</p>
-
-<p>This API is a little different due to the binary assets. We use the <code>Accept</code> header for content negotiation when requesting
-a release asset. Pass a standard API media type to get the API representation:</p>
-
-<pre class="terminal">
-$ curl -i -H "Authorization: token TOKEN" \
- -H "Accept: application/vnd.github.manifold-preview" \
- "https://uploads.github.com/repos/hubot/singularity/releases/assets/123"
-
-HTTP/1.1 200 OK
-
-{
- "id": 123,
- ...
-}
-</pre>
-
-<p>Pass “application/octet-stream” to download the binary content.</p>
-
-<pre class="terminal">
-$ curl -i -H "Authorization: token TOKEN" \
- -H "Accept: application/octet-stream" \
- "https://uploads.github.com/repos/hubot/singularity/releases/assets/123"
-
-HTTP/1.1 302 Found
-</pre>
-
-<p>Uploads are handled by a single request to a companion “uploads.github.com” service.</p>
-
-<pre class="terminal">
-$ curl -H "Authorization: token TOKEN" \
- -H "Accept: application/vnd.github.manifold-preview" \
- -H "Content-Type: application/zip" \
- --data-binary @build/mac/package.zip \
- "https://uploads.github.com/repos/hubot/singularity/releases/123/assets?name=1.0.0-mac.zip"
-</pre>
-
-<h2 id="preview-mode">Preview mode</h2>
-
-<p>The new API is available as a <a href="http://developer.github.com/v3/repos/releases/#preview-mode">preview</a>. This gives developers a chance to <a href="https://github.com/contact?form%5Bsubject%5D=New+Releases+API">provide feedback</a> on the direction of
-the API before we freeze changes. We expect to lift the preview status in 30 days.</p>
-
-<p>As with <a href="http://developer.github.com/changes/2013-07-19-preview-the-new-search-api/">the Search API</a>, we’ll take this opportunity to iterate quickly. Breaking changes will be announced
-on this developer blog without any advance warning. Once the preview period is over, we’ll consider the Releases API unchangeable.
-At that point, it will be stable and suitable for production use.</p>
-
-<p>The preview media type is “application/vnd.github.manifold-preview”. <a href="http://en.wikipedia.org/wiki/Eden_Fesi">Manifold</a> is
-a member of the Avengers, with the ability to teleport through time and space. He’s the one in the middle holding the spear.</p>
-
-<p><img src="https://f.cloud.github.com/assets/21/1210628/ae8556fa-25fc-11e3-986d-0ab522271d43.png" alt="Manifold teleporting the Avengers to a terraformed Mars surface"></p>
-
-
-
-
- tag:developer.github.com,2013-09-03:/changes/2013-09-03-two-factor-authentication/
- Two-Factor Authentication and the API
- 2013-09-03T04:00:00Z
- 2013-09-03T04:00:00Z
-
- mastahyeti
- https://github.com/technoweenie
-
-
- <p>As <a href="https://github.com/blog/1614-two-factor-authentication">announced earlier today</a>, GitHub.com now supports two-factor
-authentication (2FA) for increased security. For users with this feature
-enabled, GitHub.com will prompt for a 2FA code in addition to a username and
-password during authentication. We’ve also rolled out some improvements to the
-API to ensure that 2FA requirements in the API are consistent with GitHub.com.</p>
-
-<h2 id="authenticating-with-the-api">Authenticating with the API</h2>
-
-<p>For users without 2FA enabled, and for applications using the <a href="/v3/oauth/#web-application-flow">OAuth web
-flow</a> for authentication, everything is
-business as usual. You’ll continue to authenticate with the API just as you
-always have. (That was easy.)</p>
-
-<p>If you enable 2FA <em>and</em> use Basic Authentication to access the API, we’re
-providing multiple options to make the flow simple and easy.</p>
-
-<h2 id="basic-authentication-and-2fa">Basic Authentication and 2FA</h2>
-
-<h3 id="personal-access-tokens">Personal Access Tokens</h3>
-
-<p>Personal access tokens provide the simplest option for using 2FA with Basic
-Authentication. You can create these tokens via the <a href="https://github.com/settings/applications">application settings page
-on GitHub.com</a>, and you can revoke
-them at any time. For more information about authenticating to the API with
-personal access tokens, be sure to check out our <a href="https://help.github.com/articles/creating-an-access-token-for-command-line-use">help article on the
-topic</a>.</p>
-
-<h3 id="tightly-integrated-2fa">Tightly-integrated 2FA</h3>
-
-<p>For developers wishing to integrate GitHub 2FA directly into their application,
-the API’s Basic Authentication now supports the <a href="/v3/auth/#working-with-two-factor-authentication">ability to send the user’s 2FA
-code</a>, in addition to the username and password.</p>
-
-<h2 id="were-here-to-help">We’re here to help</h2>
-
-<p>We think GitHub users are going to love the additional security provided by
-two-factor authentication. As always, if you have any questions or feedback,
-<a href="https://github.com/contact?form%5Bsubject%5D=2FA+and+the+API">let us know</a>. We’re here to help!</p>
-
-
-
-
- tag:developer.github.com,2013-08-20:/changes/2013-08-20-search-api-improvements/
- Improvements to the Search API
- 2013-08-20T04:00:00Z
- 2013-08-20T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>Today we’re shipping two improvements to the <a href="/changes/2013-07-19-preview-the-new-search-api/">new Search API</a>.</p>
-
-<h2 id="more-text-match-metadata">More Text Match Metadata</h2>
-
-<p>When searching for code, the API previously provided <a href="/v3/search/#text-match-metadata">text match metadata</a> (i.e., “highlights”) for file content.
-Now, you can also <a href="/v3/search/#highlighting-code-search-results">get this metadata</a> for matches that occur within the file path.</p>
-
-<p>For example, when <a href="https://github.com/search?q=%40octokit%2Foctokit.rb+in%3Apath+client&type=Code">searching for files that have “client” in their path</a>, the results include this match for <code>lib/octokit/client/commits.rb</code>:</p>
-
-<pre class="json">
-{
- "name": "commits.rb",
- "path": "lib/octokit/client/commits.rb",
- "text_matches": [
- {
- "object_url": "https://api.github.com/repositories/417862/contents/lib/octokit/client/commits.rb?ref=8d487ab06ccef463aa9f5412a56f1a2f1fa4dc88",
- "object_type": "FileContent",
- "property": "path",
- "fragment": "lib/octokit/client/commits.rb",
- "matches": [
- {
- "text": "client",
- "indices": [ 12, 18 ]
- }
- ]
- }
- ]
- // ...
-}
-</pre>
-
-<h2 id="better-text-match-metadata">Better Text Match Metadata</h2>
-
-<p>Before today, the API applied HTML entity encoding to all <code>fragment</code> data.
-For example, imagine your search returns an issue like <a href="https://github.com/rails/rails/issues/11889">rails/rails#11889</a>:</p>
-
-<p><img src="https://f.cloud.github.com/assets/2988/994632/a84f2888-09af-11e3-9417-4bd92f1f1ed6.png" alt="Example Issue Title"></p>
-
-<p>The response would include a <code>text_matches</code> array with the following object:</p>
-
-<pre class="json">
-{
- "fragment": "undefined method `except' for #&lt;Array:XXX&gt;",
- // ...
-}
-</pre>
-
-<p>Inside the <code>fragment</code> value, we see HTML-encoded entities (e.g., <code>&lt;</code>).
-Since we’re returning JSON (not HTML), API clients might not expect any HTML-encoded text.
-As of today, the API returns these fragments <em>without</em> this extraneous encoding.</p>
-
-<pre class="json">
-{
- "fragment": "undefined method `except' for #<Array:XXX>",
- // ...
-}
-</pre>
-
-<h2 id="preview-period">Preview Period</h2>
-
-<p>We’re about halfway through the <a href="/changes/2013-07-19-preview-the-new-search-api/#preview-period">preview period</a> for the new Search API.
-We appreciate everyone that has provided feedback so far. Please <a href="https://github.com/contact?form%5Bsubject%5D=New+Search+API">keep it coming</a>!</p>
-
-
-
-
- tag:developer.github.com,2013-07-19:/changes/2013-07-19-preview-the-new-search-api/
- Preview the New Search API
- 2013-07-19T04:00:00Z
- 2013-07-19T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>Today we’re excited to announce a <a href="/v3/search/">brand new Search API</a>. Whether you’re
-searching for <a href="/v3/search/#search-code">code</a>, <a href="/v3/search/#search-repositories">repositories</a>,
-<a href="/v3/search/#search-issues">issues</a>, or <a href="/v3/search/#search-users">users</a>, all the query abilities of
-github.com are now available via the API as well.</p>
-
-<p>Maybe you want to find <a href="/v3/search/#repository-search-example">popular Tetris implementations written in Assembly</a>.
-We’ve got you covered.
-Or perhaps you’re looking for <a href="/v3/search/#code-search-example">new gems that are using Octokit.rb</a>.
-No problem.
-The possibilities are endless.</p>
-
-<h2 id="highlights">Highlights</h2>
-
-<p>On github.com, we enjoy the context provided by code snippets and highlights in
-search results.</p>
-
-<p><a href="https://github.com/search?q=faraday+builder+repo%3Aoctokit%2Foctokit.rb&type=Code"><img src="https://f.cloud.github.com/assets/865/819651/959a4826-efb5-11e2-8af8-46c4a3857cdf.png" alt="code-snippet-highlighting"></a></p>
-
-<p>We want API consumers to have access to that information as well. So, API
-requests can opt to receive those
-<a href="/v3/search#text-match-metadata">text fragments in the response</a>. Each fragment is accompanied by
-numeric offsets identifying the exact location of each matching search term.</p>
-
-<h2 id="preview-period">Preview period</h2>
-
-<p>We’re making this new API available today for developers to
-<a href="/v3/search/#preview-mode">preview</a>. We think developers are going to love it, but we want
-to get your feedback before we declare the Search API “final” and
-“unchangeable.” We expect the preview period to last for roughly 60 days.</p>
-
-<p>As we discover opportunities to improve this new API during the preview period,
-we may ship changes that break clients using the preview version of the API. We
-want to iterate quickly. To do so, we will announce any changes here (on the
-developer blog), but we will not provide any advance notice.</p>
-
-<p>At the end of preview period, the Search API will become an official component
-of GitHub API v3. At that point, the new Search API will be stable and suitable
-for production use.</p>
-
-<h2 id="what-about-the-old-search-api">What about the old search API?</h2>
-
-<p>The <a href="/v3/search/legacy/">legacy search API</a> is still available. Many existing clients
-depend on it, and it is not changing in any way. While the new API offers much
-more functionality, the legacy search endpoints remain an official part of
-GitHub API v3.</p>
-
-<h2 id="take-it-for-a-spin">Take it for a spin</h2>
-
-<p>We hope you’ll kick the tires and <a href="https://github.com/contact?form%5Bsubject%5D=New+Search+API">send us your feedback</a>. Happy
-<del>searching</del> finding!</p>
-
-
-
-
- tag:developer.github.com,2013-07-02:/changes/2013-07-02-rate-limit-reset/
- When Does My Rate Limit Reset?
- 2013-07-02T04:00:00Z
- 2013-07-02T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>Have you ever wondered when your <a href="/v3/#rate-limiting">rate limit</a> will reset back to its maximum value?
-That information is now available in the new <code>X-RateLimit-Reset</code> response header.</p>
-
-<pre class="terminal">
-$ curl -I https://api.github.com/orgs/octokit
-
-HTTP/1.1 200 OK
-Status: 200 OK
-X-RateLimit-Limit: 60
-X-RateLimit-Remaining: 42
-X-RateLimit-Reset: 1372700873
-...
-</pre>
-
-<p>The <code>X-RateLimit-Reset</code> header provides a <a href="http://en.wikipedia.org/wiki/Unix_time">Unix UTC timestamp</a>, letting you know the exact time that your fresh new rate limit kicks in.</p>
-
-<p>The reset timestamp is also available as part of the <code>/rate_limit</code> resource.</p>
-
-<pre class="terminal">
-$ curl https://api.github.com/rate_limit
-
-{
- "rate": {
- "limit": 60,
- "remaining": 42,
- "reset": 1372700873
- }
-}
-</pre>
-
-<p>For more information on rate limits, be sure to check out the <a href="/v3/#rate-limiting">docs</a>.</p>
-
-<p>If you have any questions or feedback, please <a href="https://github.com/contact?form%5Bsubject%5D=X-RateLimit-Reset">drop us a line</a>.</p>
-
-
-
-
- tag:developer.github.com,2013-07-01:/changes/2013-07-01-feeds-api/
- Feeds API
- 2013-07-01T04:00:00Z
- 2013-07-01T04:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>Today we’re releasing a new <a href="/v3/activity/feeds/">Feeds API</a>, an easy way to list all the Atom
-resources available to the authenticated user.</p>
-
-<pre class="terminal">
-
-curl -u defunkt https://api.github.com/feeds
-
-{
- "timeline_url": "https://github.com/timeline",
- "user_url": "https://github.com/{user}",
- "current_user_public_url": "https://github.com/defunkt",
- "current_user_url": "https://github.com/defunkt.private?token=abc123",
- "current_user_actor_url": "https://github.com/defunkt.private.actor?token=abc123",
- "current_user_organization_url": "https://github.com/organizations/{org}/defunkt.private.atom?token=abc123",
- "_links": {
- "timeline": {
- "href": "https://github.com/timeline",
- "type": "application/atom+xml"
- },
- "user": {
- "href": "https://github.com/{user}",
- "type": "application/atom+xml"
- },
- "current_user_public": {
- "href": "https://github.com/defunkt",
- "type": "application/atom+xml"
- },
- "current_user": {
- "href": "https://github.com/defunkt.private?token=abc123",
- "type": "application/atom+xml"
- },
- "current_user_actor": {
- "href": "https://github.com/defunkt.private.actor?token=abc123",
- "type": "application/atom+xml"
- },
- "current_user_organization": {
- "href": "https://github.com/organizations/{org}/defunkt.private.atom?token=abc123",
- "type": "application/atom+xml"
- }
- }
-}
-
-</pre>
-
-<p>If you have any questions or feedback, <a href="https://github.com/contact?form%5Bsubject%5D=Feeds%20API">please drop us a line</a>.</p>
-
-
-
-
- tag:developer.github.com,2013-05-06:/changes/2013-05-06-create-update-delete-individual-files/
- Create, update, and delete individual files
- 2013-05-06T04:00:00Z
- 2013-05-06T04:00:00Z
-
- ymendel
- https://github.com/technoweenie
-
-
- <p>We’re following in the footsteps of GitHub.com’s ability to <a href="https://github.com/blog/143-inline-file-editing">edit</a> and
-<a href="https://github.com/blog/1327-creating-files-on-github">create</a> files in your web browser. Starting today, the
-<a href="/v3/repos/contents/">Repository Contents API</a> will let you easily <a href="/v3/repos/contents/#create-a-file">create</a>, <a href="/v3/repos/contents/#update-a-file">update</a>, and even
-<a href="/v3/repos/contents/#delete-a-file">delete</a> individual files.</p>
-
-<p>Happy editing!</p>
-
-
-
-
- tag:developer.github.com,2013-05-06:/changes/2013-05-06-repository-stats/
- Repository Statistics
- 2013-05-06T04:00:00Z
- 2013-05-06T04:00:00Z
-
- Caged
- https://github.com/technoweenie
-
-
- <p>Today we’re happy to open our <a href="/v3/repos/statistics">Repository Statistics API</a> to everyone. We’re using
-repository statistics to power <a href="https://github.com/github/linguist/graphs">our graphs</a>,
-but we can’t wait to see what others can do with this information.</p>
-
-<p>Starting today, these resources are available to you:</p>
-
-<ul>
- <li><strong><a href="/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts">Contributors</a></strong></li>
- <li><strong><a href="/v3/repos/statistics/#get-the-last-year-of-commit-activity-data">Commit Activity</a></strong></li>
- <li><strong><a href="/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week">Code Frequency</a></strong></li>
- <li><strong><a href="/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repo-owner-and-everyone-else">Participation</a></strong></li>
- <li><strong><a href="/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day">Punch Card</a></strong></li>
-</ul>
-
-<p>Enjoy!</p>
-
-
-
- tag:developer.github.com,2013-04-30:/changes/2013-04-30-improved-submodule-support-in-repository-contents-api/
- Improved Support for Submodules in the Repository Contents API
- 2013-04-30T04:00:00Z
- 2013-04-30T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>When you view a repository with a submodule on github.com, you get useful links and information for the submodule.</p>
-
-<p><a href="/images/posts/submodule-links.png"><img src="/images/posts/submodule-links.png" alt="Repository Contents with Submodule"></a></p>
-
-<p>Today we’re making that data available in the <a href="/v3/repos/contents/#get-contents">Repository Contents API</a>.</p>
-
-<pre class="terminal">
-curl https://api.github.com/repos/jquery/jquery/contents/test/qunit
-
-{
- "name": "qunit",
- "path": "test/qunit",
- "type": "submodule",
- "submodule_git_url": "git://github.com/jquery/qunit.git",
- "sha": "6ca3721222109997540bd6d9ccd396902e0ad2f9",
- "size": 0,
- "url": "https://api.github.com/repos/jquery/jquery/contents/test/qunit?ref=master",
- "git_url": "https://api.github.com/repos/jquery/qunit/git/trees/6ca3721222109997540bd6d9ccd396902e0ad2f9",
- "html_url": "https://github.com/jquery/qunit/tree/6ca3721222109997540bd6d9ccd396902e0ad2f9",
- "_links": {
- "self": "https://api.github.com/repos/jquery/jquery/contents/test/qunit?ref=master",
- "git": "https://api.github.com/repos/jquery/qunit/git/trees/6ca3721222109997540bd6d9ccd396902e0ad2f9",
- "html": "https://github.com/jquery/qunit/tree/6ca3721222109997540bd6d9ccd396902e0ad2f9"
- }
-}
-</pre>
-
-<p>If you have any questions or feedback, please drop us a line at
-<a href="mailto:support@github.com?subject=Submodules%20in%20Repository%20Contents%20API">support@github.com</a>.</p>
-
-
-
-
- tag:developer.github.com,2013-04-30:/changes/2013-04-30-statuses-for-branches-and-tags/
- Commit Statuses Now Available for Branches and Tags
- 2013-04-30T04:00:00Z
- 2013-04-30T04:00:00Z
-
- foca
- https://github.com/technoweenie
-
-
- <p>Last week we announced <a href="https://github.com/blog/1484-check-the-status-of-your-branches">support for build statuses in the branches page</a>.
-Now we are extending this to the API. The <a href="http://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref">API endpoint for commit statuses</a>
-has been extended to allow branch and tag names, as well as commit SHAs.</p>
-
-<pre class="terminal">
-curl https://api.github.com/repos/rails/rails/statuses/3-2-stable
-</pre>
-
-<p>Enjoy.</p>
-
-
-
-
- tag:developer.github.com,2013-04-25:/changes/2013-04-25-deprecating-merge-commit-sha/
- Deprecating a Confusing Attribute in the Pull Request API
- 2013-04-25T04:00:00Z
- 2013-04-25T04:00:00Z
-
- jasonrudolph
- https://github.com/technoweenie
-
-
- <p>When you get the details for a Pull Request from the API, the
-<a href="/v3/pulls/#get-a-single-pull-request">response</a> provides everything there is to
-know about that Pull Request. In addition to the useful information provided in
-the API response, the JSON also includes the <code>merge_commit_sha</code> attribute. This
-attribute is a frequent source of misunderstanding, and we aim to remove the
-confusion.</p>
-
-<p>To help current API consumers, we’ve <a href="/v3/pulls/#mergability">documented the
-attribute</a> for improved understanding.</p>
-
-<p>To protect future API consumers from this confusion, we have
-<a href="/v3/versions/#v3-deprecations">deprecated</a> the <code>merge_commit_sha</code> attribute, and we will
-remove it in the next major version of the API.</p>
-
-<p>As always, if you have any questions or feedback, please drop us a line at
-<a href="mailto:support@github.com?subject=Deprecating%20merge_commit_sha">support@github.com</a>.</p>
-
-
-
- tag:developer.github.com,2013-04-24:/changes/2013-04-24-user-agent-required/
- User Agent now mandatory
- 2013-04-24T04:00:00Z
- 2013-04-24T04:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>After an almost six week grace period, we’re now enforcing the <a href="/v3/#user-agent-required">User Agent
-header</a> for all API requests. Most HTTP libraries (including cURL)
-set this header by default. If you’re experiencing an increase in <code>403</code>
-responses, be sure and check your code.</p>
-
-<p>If you have any questions or feedback, please drop us a line at
-<a href="mailto:support@github.com?subject=User%20Agent%20Requirement">support@github.com</a>.</p>
-
-
-
- tag:developer.github.com,2013-03-01:/changes/2013-3-1-new-hookshot-coming/
- New Hookshot Changes
- 2013-03-01T05:00:00Z
- 2013-03-01T05:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>We are experimenting with changes to the “Hookshot” backend that powers service
-hooks. There were some significant networking changes with the new cluster,
-so there are some new IP whitelist rules for hooks:</p>
-
-<ul>
- <li>204.232.175.64/27</li>
- <li>192.30.252.0/22</li>
-</ul>
-
-<p>These are in CIDR notation. They represent a significant range of GitHub
-addresses, meaning this should be the last IP change for a while. Once this
-cluster is activated and we shut the other cluster down, we will be removing
-the other entries.</p>
-
-<p>We are currently testing the new backend with all repositories in the GitHub
-organization only, and expect to start testing it with user data next week.</p>
-
-<p>This also means we should be able to start accepting <a href="https://github.com/github/github-services/pulls">GitHub Services pull
-requests</a> very soon :)</p>
-
-
-
- tag:developer.github.com,2013-02-14:/changes/2013-2-13-sortable-stars/
- Sortable Stars in Repository Starring API
- 2013-02-14T05:00:00Z
- 2013-02-14T05:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>As we <a href="https://github.com/blog/1410-sortable-stars">announced on the GitHub blog</a>, Stars now support sorting. The
-Repository Starring API now supports <a href="/v3/activity/starring/#list-repositories-being-starred">two new parameters</a> when listing
-Stars: <code>sort</code> and <code>direction</code>.</p>
-
-<pre class="terminal">
-curl https://api.github.com/users/defunkt/starred?sort=created&direction=asc
-</pre>
-
-<p>Enjoy.</p>
-
-
-
-
- tag:developer.github.com,2013-02-13:/changes/2013-2-13-hookshot-load-balancer/
- Hookshot Load balancer
- 2013-02-13T12:00:00Z
- 2013-02-13T12:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>We had an issue with the Hookshot load balancer this morning, causing the
-majority of hooks to flow to a single node only. This lead to massive queue
-times. While fixing this, we’re putting the old Services backend in use.</p>
-
-<p>This means the old IPs are back in use. Use this <a href="https://help.github.com/articles/what-ip-addresses-does-github-use-that-i-should-whitelist">Help guide</a>
-if you already removed them from your firewall.</p>
-
-
-
- tag:developer.github.com,2013-02-13:/changes/2013-2-13-hookshot-issues/
- Some Hookshot Issues
- 2013-02-13T11:00:00Z
- 2013-02-13T11:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>We turned Hookshot (our new GitHub Services backend) on yesterday. Things have
-been pretty smooth, with one issue: Hooks going to other EC2 nodes come from
-the private IP addresses of our nodes in the 10.<em>.</em>.* range.</p>
-
-<p>If your web hook servers are on EC2 and are missing hooks from GitHub due to
-an IP restriction, we recommend the following:</p>
-
-<ol>
- <li>Remove the IP white list.</li>
- <li>Fall back to HTTPS and Basic Auth to restrict pushes to authorized senders only.</li>
-</ol>
-
-<p>We’re currently working on solving this problem. Hit up <a href="mailto:support@github.com">support@github.com</a>
-if you have any questions.</p>
-
-
-
- tag:developer.github.com,2013-02-05:/changes/2013-2-5-changes-to-services/
- Upcoming Changes to GitHub Services
- 2013-02-05T05:00:00Z
- 2013-02-05T05:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>We are finishing up a new GitHub Services backend, dubbed “Hookshot”, to
-increase the speed and reliability of our delivered payloads. We are doing
-what we can to make this a seamless transition for everyone. However, there
-are a few notable changes.</p>
-
-<ul>
- <li>
- <p>There is a new <a href="http://developer.github.com/v3/meta/">Meta API endpoint</a>
-listing the current public IPs that hooks originate from.</p>
- </li>
- <li>
- <p>We’re removing the AMQP service from GitHub. It hasn’t worked in quite some
-time, and the code it uses doesn’t work in our background workers.</p>
- </li>
- <li>
- <p>We’re also instituting a new guideline to improve the reliability and
-maintainability of services in the future. As of today, all new services must
-accept an unmodified payload over HTTP. Any service that does not will be
-rejected. To see an example of an acceptable service, check out <a href="https://github.com/github/github-services/blob/master/lib/services/codeclimate.rb">Code Climate</a>.
-Notice their service simply accepts HTTP POST from GitHub unmodified. For an
-example of a service that won’t be accepted after today, check out <a href="https://github.com/github/github-services/blob/master/lib/services/campfire.rb">Campfire</a>. It
-uses other Ruby gems and contains custom logic to transform the GitHub payload
-to Campfire messages. Existing hooks will keep working (don’t worry 37signals, we
-:heart: Campfire).</p>
- </li>
-</ul>
-
-<p>We’re making these changes because we want to focus on the reliability of the
-core Services backend for everyone. Maintaining custom logic and libraries for
-over 100 services is taking too much of this focus away.</p>
-
-
-
-
- tag:developer.github.com,2013-01-31:/changes/2013-01-31-user-agent-will-soon-be-mandatory/
- User Agent mandatory from March 4th 2013
- 2013-01-31T05:00:00Z
- 2013-01-31T05:00:00Z
-
- agh
- https://github.com/technoweenie
-
-
- <p>Following on from our <a href="http://developer.github.com/changes/2012-10-14-rate-limit-changes/">previous post</a>
-about requiring requests to include a valid <a href="http://en.wikipedia.org/wiki/User_agent">User Agent header</a>
-we will soon be changing our API servers to return HTTP 403
-to any clients not providing a valid User Agent header.</p>
-
-<p>We will be making this change on Monday, March 4th 2013.</p>
-
-<p>Setting this helps us identify requests from you, and get in touch with people who are using
-the API in a way which causes disruption to GitHub. Most HTTP libraries and tools like cURL
-already provide a valid header for you, and allow you to customize it, so this will not require
-many of our users to make any changes whatsoever.</p>
-
-<p>If you have any questions or feedback, please drop us a line at
-<a href="mailto:support@github.com?subject=User%20Agent%20Requirement">support@github.com</a>.</p>
-
-
-
- tag:developer.github.com,2013-01-08:/changes/2013-01-08-new-user-scopes/
- New User scopes
- 2013-01-08T05:00:00Z
- 2013-01-08T05:00:00Z
-
- technoweenie
- https://github.com/technoweenie
-
-
- <p>We’ve added a <a href="http://developer.github.com/v3/oauth/#scopes">few new user scopes</a> for 3rd party applications that want very
-specific user functionality. The <code>user:email</code> scope gives apps read-only access
-to a user’s private email addresses. The <code>user:follow</code> scope lets a user
-follow and unfollow other users.</p>
-
-<p>This should help keep applications from requiring the <code>user</code> scope, which
-can be potentially dangerous.</p>
-
-<p>We also added a read-only endpoint to get a user’s public SSH keys.</p>
-
-<pre><code>GET https://api.github.com/users/technoweenie/keys
-</code></pre>
-
-
-
-
- tag:developer.github.com,2012-12-10:/changes/2012-12-10-Diff-and-patch-media-types/
- Diff and patch media types
- 2012-12-10T05:00:00Z
- 2012-12-10T05:00:00Z
-
- pengwynn
- https://github.com/technoweenie
-
-
- <p>Starting today, you can get <code>.diff</code> and <code>.patch</code> content directly from the API for the following resources:</p>
-
-<ul>
- <li><a href="/v3/repos/commits/#get-a-single-commit">Commits</a></li>
- <li><a href="/v3/repos/commits/#compare-two-commits">Commit comparisons</a></li>
- <li><a href="/v3/pulls/#get-a-single-pull-request">Pull request</a></li>
-</ul>
-
-<p>Simply use the same resource URL and send either <code>application/vnd.github.diff</code> or <code>application/vnd.github.patch</code> in the <code>Accept</code> header:</p>
-
-<pre><code>curl -H "Accept: application/vnd.github.diff" https://api.github.com/repos/pengwynn/dotfiles/commits/aee60a4cd56fb4c6a50e60f17096fc40c0d4d72c
-
-diff --git a/tmux/tmux.conf.symlink b/tmux/tmux.conf.symlink
-index 1f599cb..abaf625 100755
---- a/tmux/tmux.conf.symlink
-+++ b/tmux/tmux.conf.symlink
-@@ -111,6 +111,7 @@ set-option -g base-index 1
- ## enable mouse
- set-option -g mouse-select-pane on
- set-option -g mouse-select-window on
-+set-option -g mouse-resize-pane on
- set-window-option -g mode-keys vi
- set-window-option -g mode-mouse on
- # set-window-option -g monitor-activity off
-</code></pre>
-
-
-
-
diff --git a/changes/2012-10-14-rate-limit-changes/index.html b/changes/2012-10-14-rate-limit-changes/index.html
deleted file mode 100644
index ef02719559..0000000000
--- a/changes/2012-10-14-rate-limit-changes/index.html
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
-
-
-
- Rate limit changes for unauthenticated requests
-
-
-
-
-
-
-
-
-
-
-
-
To ensure a high quality of service for all API consumers, we’ve reduced the
-default rate limit for unauthenticated requests. To enjoy the default rate
-limit of 5,000 requests per hour, you’ll need to
-authenticate via Basic Auth
-or OAuth. Unauthenticated requests will be limited to 60 per hour unless you
-include your OAuth client and
-secret.
-
-
We’ll soon require all requests to include a valid User Agent
-header. Setting a
-unique value for this header helps us identify requests and get in touch with
-developers who are abusing the API. Most HTTP libraries, wrapper libraries, and
-even cURL provide a valid header for you already and allow you to change it to
-something unique to your application.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
Requesting the member list of an
-organization of which you are not a member now redirects to the public members
-list. Similarly, requests to
-membership check resources of
-an organization of which you are not a member are redirected to the equivalent
-public membership check.
-One exception to the latter case is that if you are checking about your own
-membership the request is not redirected. You are always allowed to know what
-organizations you belong to.
-
-
The changes where made to clarify the purpose of these various resources. The
-/orgs/:org/members resources are intended for use by members of the
-organization in question. The /orgs/:org/public_members resources are for
-acquiring information about the public membership of organizations. If you are
-not a member you are not allowed to see private membership information so you
-should be using the public membership resources.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
Now that the dust has settled around Notifications and Stars,
-we’ve unleashed all that :sparkles: in a brand new API. You can now
-view and mark notifications as read.
-
-
Endpoint
-
-
The core notifications functionality is under the /notifications endpoint.
-You can look for unread notifications:
-
-
-$ curl https://api.github.com/notifications
-
-
-
You can filter these notifications to a single Repository:
-# all notifications
-$ curl https://api.github.com/notifications \
- -X PUT -d '{"read": true}'
-
-# notifications for a single repository
-$ curl https://api.github.com/repos/technoweenie/faraday/notifications \
- -X PUT -d '{"read": true}'
-
-
-
You can also modify subscriptions for a Repository or a single thread.
-
-
-# subscription details for the thread (either an Issue or Commit)
-$ curl https://api.github.com/notifications/threads/1/subscription
-
-# subscription details for a whole Repository.
-$ curl https://api.github.com/repos/technoweenie/faraday/subscription
-
-
-
Polling
-
-
The Notifications API is optimized for polling by the last modified time:
-
-
-# Add authentication to your requests
-$ curl -I https://api.github.com/notifications
-HTTP/1.1 200 OK
-Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
-X-Poll-Interval: 60
-
-# Pass the Last-Modified header exactly
-$ curl -I https://api.github.com/notifications
- -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
-HTTP/1.1 304 Not Modified
-X-Poll-Interval: 60
-
The URIs of all gist comments are changing immediately. The new URI pattern for gist comments is /gists/{gist-id}/comments/{id}. (See gist comments section of the docs for more details.) This change is necessary because the auto-incremented ids of gist comments are easy to guess. This predictability allows anyone to view comments on private Gists with relative ease. Obviously, comments on private gists should be just as private as the gist itself.
-
-
Adding the gist id to the URI of comments makes it impossible, in practical terms, to guess that URI because the id of private gists are very large random numbers. This is, unfortunately, a breaking change but one that cannot be avoided because of the security implications of the current URIs. We apologize for the inconvenience.
-
-
We have also added a comments_url member to the Gist documents. The comments_url link provides access to the comments of a Gist in a way that will insulate clients from changes in the URI patterns used by the GitHub API. We are increasing our use of links in order to make changes such as this one less damaging to clients. We strongly encourage using url and *_url properties, where possible, rather than constructing URIs using the patterns published on this site. Doing so will result in clients that break less often.
We made a slight change to the way you fork a repository. By default, you
-can fork my repository through an HTTP POST to the repository’s fork resource.
-
-
$ curl -X POST https://api.github.com/repos/technoweenie/faraday/forks
-
-
-
This repository forks to your personal account. However, there are cases when
-you want to fork to one of your organizations instead. The previous method
-required a ?org query parameter:
-
-
$ curl -X POST /repos/technoweenie/faraday/forks?org=mycompany
-
-
-
Query parameters on POST requests are unusual in APIs, and definitely
-inconsistent with the rest of the GitHub API. You should be able to post a
-JSON body like every other POST endpoint. Now, you can! Only, now we’re
-calling the field organization.
We recently made it easy to initialize a repository when you create
-it via the API. One of the options you can pass when creating a
-repository is gitignore_template. This value is the name of one of the
-templates from the the public GitHub .gitignore repository.
You’ve always been able to grab all the commit comments for an entire
-repository via the API, but to get Issue comments and Pull Request Review
-Comments, you could only fetch the comments for a single Issue or Pull Request.
-
-
Today, we’re introducing two new methods to grab all Issue Comments and Review
-Comments for a repository.
-
-
# Grab all Issue Comments
-curl https://api.github.com/repos/mathiasbynens/dotfiles/issues/comments
-
-# Grab all Review Comments
-curl https://api.github.com/repos/mathiasbynens/dotfiles/pulls/comments
-
-
-
Check out the docs for sorting and filtering options:
The Authorizations API is an easy way to create an OAuth
-authorization using Basic Auth. Just POST your desired scopes and optional
-note and you get a token back:
This call creates a token for the authenticating user tied to a special “API”
-OAuth application.
-
-
We now support creating tokens for your own OAuth application by passing your
-twenty character client_id and forty character client_secret as found in
-the settings page for your OAuth application.
We’ve made a couple of changes today to the Organization repositories
-listing to bring it a bit closer to the functionality of the GitHub.com
-Organization repositories tab. We now let you retrieve repositories
-which are forks of another repository, as well as those repositories which
-are sources (not forks).
-
-
# Grab all fork Repositories for an Organization
-curl "https://api.github.com/orgs/:org/repos?type=forks"
-
-# Grab all source Repositories for an Organization
-curl "https://api.github.com/orgs/:org/repos?type=sources"
-
-
-
Check out the docs for sorting and filtering options:
Improvements continue to the Organizations Repository listing endpoint.
-Today we’re improving pagination so that it works as documented. Now
-you can expect Link headers to navigate through the results space,
-regardless of what you send in the type parameter.
-
-
The docs for Organization Repositories queries are still here:
Today we’ve made it easier to add commits to a repository via the GitHub API.
-Until now, you could create a repository, but you would
-need to initialize it locally via your Git client before adding any commits via
-the API.
-
-
Now you can optionally init a repository when it’s created by sending true
-for the auto_init parameter:
We recently changed the Watcher behavior on GitHub. What
-used to be known as “Watching” is now “Starring”. Starring is basically a way
-to bookmark interesting repositories. Watching is a way to indicate that you
-want to receive email or web notifications on a Repository.
-
-
This works well on GitHub.com, but poses a problem for the GitHub API. How do
-we change this in a way that developers can gracefully upgrade their
-applications? We’re currently looking at rolling out the changes in three
-phases over an extended period of time.
-/repos/:owner/:repo/watchers - A list of users starring the repository.
-
-/users/:user/watched - A list of repositories that a user has starred.
-
-/user/watched - A list of repositories the current user has starred.
-
-
-
Phase 1: Add Watchers as Subscriptions
-
-
This phase exposes Watchers as “Subscriptions”. This is to
-keep from clashing with the legacy endpoints. This phase will happen
-automatically and will not break your application until Phase 3 starts.
-(UPDATE: API v3 will continue to support this functionality indefinitely.)
-
-
-
-/repos/:owner/:repo/subscribers - A list of users watching the repository.
-
-/users/:user/subscriptions - A list of repositories that a user is watching.
-
-/user/subscriptions - A list of repositories the current user is watching.
-
-
-
We’ll also add a copy of the legacy Watchers API in the new endpoint:
-
-
-
-/repos/:owner/:repo/stargazers - A list of users starring the repository.
-
-/users/:user/starred - A list of repositories that a user has starred.
-
-/user/starred - A list of repositories the current user has starred.
-
-
-
This is in place now with the current media type for the API:
-
-
application/vnd.github.beta+json
-
-
-
If you care about your application not breaking, make sure all outgoing API
-requests pass that value for the “Accept” header. You should do this now. This
-can be verified by checking the X-GitHub-Media-Type header on all API
-responses.
-This Phase will be broken once Phase 3 starts. Phase 3 removes all support for
-the "beta" media type, and makes the "v3" media type the implicit default
-for API requests.
-
-
UPDATE - November 6, 2013
-
-
-
- API v3 will continue to officially support the functionality described in
- Phase 1 above. This functionality will remain intact for the lifetime of
- API v3.
-
-
- API v3 will not include Phases 2 and 3 (below). Those phases will
- likely be part of the next major version of the API. (We have not announced
- a timeline for the next major version of the API.)
-
-
-
-
Phase 2: Switch /watchers API Endpoint
-
-The "watch" endpoints will now be a copy of the "subscription" endpoints. You
-will have to use /user/starred to get a user's starred repositories, not
-/user/watched.
-
-This requires a new media type value:
-
-
application/vnd.github.v3+json
-
-This is a breaking change from Phase 1. We will release this change in an
-experimental mode first, letting developers gracefully upgrade their
-applications by specifying the new media value for the Accept header.
-
-
-
-
-This phase involves disabling the subscription endpoints completely. At this
-point, you should be using the starring endpoints for starred repositories, and
-the watch endpoints for watched repositories. No date has been set yet, but we
-expect this to be 3-6 months after Phase 2 is in place. This should give
-developers enough time for a smooth upgrade path. If they use popular API
-wrappers, the work will likely mostly be done for them.
-
-Keep on passing the "v3" media type in your application, until the API has
-another breaking change to make. If you can't make the deadline for Phase 3,
-just set the "beta" media type until we shut that down completely. It's likely
-that we will keep the old "beta" media type active for another month, like
-the last time we terminated
-old API functionality.
-
-
We’ve added a few new user scopes for 3rd party applications that want very
-specific user functionality. The user:email scope gives apps read-only access
-to a user’s private email addresses. The user:follow scope lets a user
-follow and unfollow other users.
-
-
This should help keep applications from requiring the user scope, which
-can be potentially dangerous.
-
-
We also added a read-only endpoint to get a user’s public SSH keys.
-
-
GET https://api.github.com/users/technoweenie/keys
-
Following on from our previous post
-about requiring requests to include a valid User Agent header
-we will soon be changing our API servers to return HTTP 403
-to any clients not providing a valid User Agent header.
-
-
We will be making this change on Monday, March 4th 2013.
-
-
Setting this helps us identify requests from you, and get in touch with people who are using
-the API in a way which causes disruption to GitHub. Most HTTP libraries and tools like cURL
-already provide a valid header for you, and allow you to customize it, so this will not require
-many of our users to make any changes whatsoever.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
After an almost six week grace period, we’re now enforcing the User Agent
-header for all API requests. Most HTTP libraries (including cURL)
-set this header by default. If you’re experiencing an increase in 403
-responses, be sure and check your code.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
When you get the details for a Pull Request from the API, the
-response provides everything there is to
-know about that Pull Request. In addition to the useful information provided in
-the API response, the JSON also includes the merge_commit_sha attribute. This
-attribute is a frequent source of misunderstanding, and we aim to remove the
-confusion.
To protect future API consumers from this confusion, we have
-deprecated the merge_commit_sha attribute, and we will
-remove it in the next major version of the API.
-
-
As always, if you have any questions or feedback, please drop us a line at
-support@github.com.
We’re following in the footsteps of GitHub.com’s ability to edit and
-create files in your web browser. Starting today, the
-Repository Contents API will let you easily create, update, and even
-delete individual files.
Today we’re happy to open our Repository Statistics API to everyone. We’re using
-repository statistics to power our graphs,
-but we can’t wait to see what others can do with this information.
-
-
Starting today, these resources are available to you:
Have you ever wondered when your rate limit will reset back to its maximum value?
-That information is now available in the new X-RateLimit-Reset response header.
-
-
-$ curl -I https://api.github.com/orgs/octokit
-
-HTTP/1.1 200 OK
-Status: 200 OK
-X-RateLimit-Limit: 60
-X-RateLimit-Remaining: 42
-X-RateLimit-Reset: 1372700873
-...
-
-
-
The X-RateLimit-Reset header provides a Unix UTC timestamp, letting you know the exact time that your fresh new rate limit kicks in.
-
-
The reset timestamp is also available as part of the /rate_limit resource.
Today we’re excited to announce a brand new Search API. Whether you’re
-searching for code, repositories,
-issues, or users, all the query abilities of
-github.com are now available via the API as well.
On github.com, we enjoy the context provided by code snippets and highlights in
-search results.
-
-
-
-
We want API consumers to have access to that information as well. So, API
-requests can opt to receive those
-text fragments in the response. Each fragment is accompanied by
-numeric offsets identifying the exact location of each matching search term.
-
-
Preview period
-
-
We’re making this new API available today for developers to
-preview. We think developers are going to love it, but we want
-to get your feedback before we declare the Search API “final” and
-“unchangeable.” We expect the preview period to last for roughly 60 days.
-
-
As we discover opportunities to improve this new API during the preview period,
-we may ship changes that break clients using the preview version of the API. We
-want to iterate quickly. To do so, we will announce any changes here (on the
-developer blog), but we will not provide any advance notice.
-
-
At the end of preview period, the Search API will become an official component
-of GitHub API v3. At that point, the new Search API will be stable and suitable
-for production use.
-
-
What about the old search API?
-
-
The legacy search API is still available. Many existing clients
-depend on it, and it is not changing in any way. While the new API offers much
-more functionality, the legacy search endpoints remain an official part of
-GitHub API v3.
Today we’re shipping two improvements to the new Search API.
-
-
More Text Match Metadata
-
-
When searching for code, the API previously provided text match metadata (i.e., “highlights”) for file content.
-Now, you can also get this metadata for matches that occur within the file path.
Inside the fragment value, we see HTML-encoded entities (e.g., <).
-Since we’re returning JSON (not HTML), API clients might not expect any HTML-encoded text.
-As of today, the API returns these fragments without this extraneous encoding.
We’re about halfway through the preview period for the new Search API.
-We appreciate everyone that has provided feedback so far. Please keep it coming!
As announced earlier today, GitHub.com now supports two-factor
-authentication (2FA) for increased security. For users with this feature
-enabled, GitHub.com will prompt for a 2FA code in addition to a username and
-password during authentication. We’ve also rolled out some improvements to the
-API to ensure that 2FA requirements in the API are consistent with GitHub.com.
-
-
Authenticating with the API
-
-
For users without 2FA enabled, and for applications using the OAuth web
-flow for authentication, everything is
-business as usual. You’ll continue to authenticate with the API just as you
-always have. (That was easy.)
-
-
If you enable 2FA and use Basic Authentication to access the API, we’re
-providing multiple options to make the flow simple and easy.
-
-
Basic Authentication and 2FA
-
-
Personal Access Tokens
-
-
Personal access tokens provide the simplest option for using 2FA with Basic
-Authentication. You can create these tokens via the application settings page
-on GitHub.com, and you can revoke
-them at any time. For more information about authenticating to the API with
-personal access tokens, be sure to check out our help article on the
-topic.
-
-
Tightly-integrated 2FA
-
-
For developers wishing to integrate GitHub 2FA directly into their application,
-the API’s Basic Authentication now supports the ability to send the user’s 2FA
-code, in addition to the username and password.
-
-
We’re here to help
-
-
We think GitHub users are going to love the additional security provided by
-two-factor authentication. As always, if you have any questions or feedback,
-let us know. We’re here to help!
This API is a little different due to the binary assets. We use the Accept header for content negotiation when requesting
-a release asset. Pass a standard API media type to get the API representation:
The new API is available as a preview. This gives developers a chance to provide feedback on the direction of
-the API before we freeze changes. We expect to lift the preview status in 30 days.
-
-
As with the Search API, we’ll take this opportunity to iterate quickly. Breaking changes will be announced
-on this developer blog without any advance warning. Once the preview period is over, we’ll consider the Releases API unchangeable.
-At that point, it will be stable and suitable for production use.
-
-
The preview media type is “application/vnd.github.manifold-preview”. Manifold is
-a member of the Avengers, with the ability to teleport through time and space. He’s the one in the middle holding the spear.
We owe a big “Thank You!” to everyone that has taken the time to try out the new Search API.
-We :heart: every one of you.
-Just as we hoped,
-the preview period has allowed us to see how you want to use the new API,
-and it has given us a chance to improve the API before finalizing it.
-
-
In order to incorporate everything that we’ve learned,
-we’re going to keep the Search API in preview mode for a little while longer.
-We have a few bugs to squash and a couple performance kinks to iron out.
-We’re hard at work on those improvements now,
-and we expect to have more news in the coming weeks.
Starting today, we are returning granted scopes as part of the
-access_token response.
-For example, if you are making a POST with the application/json
-mime-type you’ll see an additional field for the granted scopes.
Right now, these scopes will be identical to what you requested, but we
-are moving towards a feature set that will allow GitHub users to edit
-their scopes, effectively granting your application less access than you
-originally requested. You should be aware of this possibility and adjust
-your application behavior accordingly.
-
-
Some things to watch out for and keep in mind:
-
-
-
-
Most third party applications using GitHub OAuth to identify users have
-the best success in adoption by starting out with a request for the
-minimum access that the application can possibly get away with.
-Something like no scopes or just user:email is very sane.
-
-
-
It is important to handle the error cases where a user chooses to
-grant you less access than you originally requested. Now that we are
-surfacing the granted scopes on the access_token response, applications
-can warn or otherwise communicate with their users that they will see
-reduced functionality or be unable to perform some actions.
-
-
-
Applications can always send users back through the flow again to get
-additional permission, but don’t forget that users can always say no.
As we prepare to end the preview period for the new search API,
-we’re making sure that it’s ready to handle the traffic from all the apps you’ll build on top of it.
-
-
New Validation Rule
-
-
In order to support the expected volume of requests, we’re applying a new validation rule to the Code Search API.
-Starting today, you will need to scope your code queries to a specific set of users, organizations, or repositories.
This validation does not affect searches performed on github.com/search.
-
-
By ensuring that code queries are more targeted in nature, the API will be ready to meet the expected demand from all your apps.
-As we continue to tune the Search API, we hope to relax this validation in the future.
-There’s no ETA, but we’d like to relax it as soon as it’s feasible.
-
-
As always, if you have any questions or feedback, please get in touch.
We’re excited to announce that the new Search API has graduated from preview mode.
-As of today, the Search API is an official part of GitHub API v3.
-As such, the Search API is now stable and suitable for production use.
-
-
Preview Media Type No Longer Needed
-
-
If you used the Search API during the preview period, you needed to provide a custom media type in the Accept header:
-
-
application/vnd.github.preview+json
-
-
-
Now that the preview period has ended, you no longer need to pass this custom media type.
-
-
Instead, we recommend that you specify v3 as the version in the Accept header:
-
-
application/vnd.github.v3+json
-
-
-
Onward!
-
-
Thanks again to everyone that tried out the Search API during the preview period.
Hot on the heels of the Search API, the Releases API
-is now officially part of GitHub API v3. We now consider it stable for
-production use.
-
-
Preview Media Type No Longer Needed
-
-
If you used the Releases API during the preview period, you needed to provide a custom media type in the Accept header:
-
-
application/vnd.github.manifold-preview+json
-
-
-
Now that the preview period has ended, you no longer need to pass this custom media type.
-
-
Instead, we recommend that you specify v3 as the version in the Accept header:
-
-
application/vnd.github.v3+json
-
-
-
Onward!
-
-
Thanks again to everyone that tried out the Releases API during the preview period.
-We got some great feedback, and we are already discussing additions to the API.
The organization members and organization public members methods will soon return paginated results by default. Beginning
-today, these methods will paginate if you include page or per_page query
-parameters. Starting January 15th, 2014, these methods will always return paginated
-results.
-
-
As always, be sure and follow those Link headers to get
-subsequent results. If you have any questions or run into trouble, feel free to
-get in touch.
We turned Hookshot (our new GitHub Services backend) on yesterday. Things have
-been pretty smooth, with one issue: Hooks going to other EC2 nodes come from
-the private IP addresses of our nodes in the 10...* range.
-
-
If your web hook servers are on EC2 and are missing hooks from GitHub due to
-an IP restriction, we recommend the following:
-
-
-
Remove the IP white list.
-
Fall back to HTTPS and Basic Auth to restrict pushes to authorized senders only.
-
-
-
We’re currently working on solving this problem. Hit up support@github.com
-if you have any questions.
We had an issue with the Hookshot load balancer this morning, causing the
-majority of hooks to flow to a single node only. This lead to massive queue
-times. While fixing this, we’re putting the old Services backend in use.
-
-
This means the old IPs are back in use. Use this Help guide
-if you already removed them from your firewall.
We are finishing up a new GitHub Services backend, dubbed “Hookshot”, to
-increase the speed and reliability of our delivered payloads. We are doing
-what we can to make this a seamless transition for everyone. However, there
-are a few notable changes.
-
-
-
-
There is a new Meta API endpoint
-listing the current public IPs that hooks originate from.
-
-
-
We’re removing the AMQP service from GitHub. It hasn’t worked in quite some
-time, and the code it uses doesn’t work in our background workers.
-
-
-
We’re also instituting a new guideline to improve the reliability and
-maintainability of services in the future. As of today, all new services must
-accept an unmodified payload over HTTP. Any service that does not will be
-rejected. To see an example of an acceptable service, check out Code Climate.
-Notice their service simply accepts HTTP POST from GitHub unmodified. For an
-example of a service that won’t be accepted after today, check out Campfire. It
-uses other Ruby gems and contains custom logic to transform the GitHub payload
-to Campfire messages. Existing hooks will keep working (don’t worry 37signals, we
-:heart: Campfire).
-
-
-
-
We’re making these changes because we want to focus on the reliability of the
-core Services backend for everyone. Maintaining custom logic and libraries for
-over 100 services is taking too much of this focus away.
We are experimenting with changes to the “Hookshot” backend that powers service
-hooks. There were some significant networking changes with the new cluster,
-so there are some new IP whitelist rules for hooks:
-
-
-
204.232.175.64/27
-
192.30.252.0/22
-
-
-
These are in CIDR notation. They represent a significant range of GitHub
-addresses, meaning this should be the last IP change for a while. Once this
-cluster is activated and we shut the other cluster down, we will be removing
-the other entries.
-
-
We are currently testing the new backend with all repositories in the GitHub
-organization only, and expect to start testing it with user data next week.
On April 15, 2014*, the GitHub API will start serving the v3 media type by default. The information below will help you determine whether your applications will be affected by this change. For affected applications, you’ll find tips below to help you smoothly navigate this change.
-
-
What’s changing?
-
-
A new default version
-
-
There are two versions of the GitHub API: beta and v3. Today, requests receive the beta version by default. On April 15*, requests will begin receiving the v3 version by default.
-
-
For the most part, beta and v3 are remarkably similar. There are just a few differences to keep in mind.
-
-
A new default media type
-
-
The version is one part of the media type. By default, the API provides the beta media type:
-
-
application/vnd.github.beta+json
-
-
-
On April 15*, requests will begin responding with the v3 media type by default:
-
-
application/vnd.github.v3+json
-
-
-
Who is affected?
-
-
Since 2012, we have encouraged developers to explicitly request a specific media type via the Accept header. If you are requesting either beta or v3 via the Accept header, then you are not affected by this change. The API will continue to respond with the requested media type.
-
-
If you are not requesting beta or v3 via the Accept header, then the API is currently responding with the beta media type. On April 15*, the API will begin responding with the v3 media type. If your application relies on functionality that differs between beta and v3, then you are affected by this change. You will need to take steps to prepare for the change.
-
-
What should you do?
-
-
If you are affected by this change, we recommend that you:
-
-
-
Update your applications to depend on the v3 functionality instead of the beta functionality. (If you use one of the popular client libraries, there’s a good chance that they’ve already done the work for you. In that case, you can just update to the latest version of that library.)
-
Request the v3 media type via the Accept header.
-
-
-
If you cannot update your application to depend on the v3 functionality by April 15*, you can just request the beta media type via the Accept header. Doing so will insulate you from this change.
-
-
Cutover test on March 12, 2014
-
-
To help you understand the impact of this change before it becomes permanent, we will temporarily implement this change for a single day on March 12. From approximately 12:01am UTC to 11:59pm UTC on March 12, the API will respond with the v3 media type by default.
-
-
Follow @GitHubAPI to receive updates before and after the test.
-
-
Stay informed
-
-
Depending on the results of the cutover test, we may schedule additional tests before the final cutover on April 15. If so, we’ll to announce them in advance. Be sure to stay tuned to the blog or follow @GitHubAPI for updates.
-
-
If you have any questions, please get in touch. We’ll be happy to help.
Today we’re excited to announce a Deployments API. We ship a lot of
-software at GitHub: web, mobile, and native. For the last few years, we’ve been
-driving our deployments from our ChatOps tooling and we’ve learned a
-lot. The Deployments API is a generalization of the approach that we’ve been
-taking, and we’re really excited to see what our users and integrations start
-building around it.
-
-
Deployments are a new model in the GitHub ecosystem. We don’t have any UI
-components currently, and deployments are intended to be used exclusively by
-tooling. If you’re familiar with the Status API, you know that it allows
-various tools to report on the status of a commit (e.g., the progress of an
-attempt to perform a build at a particular commit). The Status API doesn’t
-perform the build; it just reports the results. Much like the Status API, we
-won’t be doing actual deployments for you. Instead, the API provides a way for
-you to track the status of your deployments. We’re hoping to provide
-consistency across the various type of release processes, regardless of the
-underlying steps involved with getting your code built or shipped to your
-servers.
-
-
Highlights
-
-
Automatic Merging
-
-
The system can auto-merge the default branch for the repository if the
-requested deployment ref is behind the default branch. On active projects it’s
-easy to fall behind, so let automation watch your back.
-
-
Commit Status Integration
-
-
By default, the system rejects deployment requests for repositories that have
-commit statuses but don’t have a green build for the deployment ref. This can
-be bypassed, but is useful in cases where continuous integration is being used.
-
-
Force Deployments
-
-
Sometimes the world crashes down on you, and you need to just get the code out
-the door. Forced deployments bypass any commit status checks or ahead/behind
-checks in the repository.
-
-
Deployment Statuses
-
-
Different deployment systems can update the status of a deployment to be
-pending, success, failure, or error. There’s also a field for linking
-to deployment output.
-
-
Events
-
-
Both Deployments and Deployment Statuses trigger events on GitHub. 3rd party
-integrations can listen for these events via webhooks and choose
-whether or not to actually deploy the repository that the event was created for.
-
-
Preview Period
-
-
We’re making this new API available today for developers to
-preview. We think developers and existing integrations are
-going to love it, but we want to get your feedback before we declare
-the Deployments API “final” and “unchangeable.” We expect the preview period to
-last for roughly 60-90 days.
-
-
As we discover opportunities to improve the API during the preview period, we
-may ship changes that break clients using the preview version of the API. We
-want to iterate quickly. To do so, we will announce any changes here (on the
-developer blog), but we will not provide any advance notice.
-
-
At the end of preview period, the Deployments API will become an official
-component of GitHub API v3. At that point, the new Deployments API will be
-stable and suitable for production use.
Today we’re excited to announce a Deployments API. We ship a lot of
-software at GitHub: web, mobile, and native. For the last few years, we’ve been
-driving our deployments from our ChatOps tooling and we’ve learned a
-lot. The Deployments API is a generalization of the approach that we’ve been
-taking, and we’re really excited to see what our users and integrations start
-building around it.
-
-
Deployments are a new model in the GitHub ecosystem. We don’t have any UI
-components currently, and deployments are intended to be used exclusively by
-tooling. If you’re familiar with the Status API, you know that it allows
-various tools to report on the status of a commit (e.g., the progress of an
-attempt to perform a build at a particular commit). The Status API doesn’t
-perform the build; it just reports the results. Much like the Status API, we
-won’t be doing actual deployments for you. Instead, the API provides a way for
-you to track the status of your deployments. We’re hoping to provide
-consistency across the various type of release processes, regardless of the
-underlying steps involved with getting your code built or shipped to your
-servers.
-
-
Highlights
-
-
Automatic Merging
-
-
The system can auto-merge the default branch for the repository if the
-requested deployment ref is behind the default branch. On active projects it’s
-easy to fall behind, so let automation watch your back.
-
-
Commit Status Integration
-
-
By default, the system rejects deployment requests for repositories that have
-commit statuses but don’t have a green build for the deployment ref. This can
-be bypassed, but is useful in cases where continuous integration is being used.
-
-
Force Deployments
-
-
Sometimes the world crashes down on you, and you need to just get the code out
-the door. Forced deployments bypass any commit status checks or ahead/behind
-checks in the repository.
-
-
Deployment Statuses
-
-
Different deployment systems can update the status of a deployment to be
-pending, success, failure, or error. There’s also a field for linking
-to deployment output.
-
-
Events
-
-
Both Deployments and Deployment Statuses trigger events on GitHub. 3rd party
-integrations can listen for these events via webhooks and choose
-whether or not to actually deploy the repository that the event was created for.
-
-
Preview Period
-
-
We’re making this new API available today for developers to
-preview. We think developers and existing integrations are
-going to love it, but we want to get your feedback before we declare
-the Deployments API “final” and “unchangeable.” We expect the preview period to
-last for roughly 60-90 days.
-
-
As we discover opportunities to improve the API during the preview period, we
-may ship changes that break clients using the preview version of the API. We
-want to iterate quickly. To do so, we will announce any changes here (on the
-developer blog), but we will not provide any advance notice.
-
-
At the end of preview period, the Deployments API will become an official
-component of GitHub API v3. At that point, the new Deployments API will be
-stable and suitable for production use.
On April 15, 2014*, the GitHub API will start serving the v3 media type by default. The information below will help you determine whether your applications will be affected by this change. For affected applications, you’ll find tips below to help you smoothly navigate this change.
-
-
What’s changing?
-
-
A new default version
-
-
There are two versions of the GitHub API: beta and v3. Today, requests receive the beta version by default. On April 15*, requests will begin receiving the v3 version by default.
-
-
For the most part, beta and v3 are remarkably similar. There are just a few differences to keep in mind.
-
-
A new default media type
-
-
The version is one part of the media type. By default, the API provides the beta media type:
-
-
application/vnd.github.beta+json
-
-
-
On April 15*, requests will begin responding with the v3 media type by default:
-
-
application/vnd.github.v3+json
-
-
-
Who is affected?
-
-
Since 2012, we have encouraged developers to explicitly request a specific media type via the Accept header. If you are requesting either beta or v3 via the Accept header, then you are not affected by this change. The API will continue to respond with the requested media type.
-
-
If you are not requesting beta or v3 via the Accept header, then the API is currently responding with the beta media type. On April 15*, the API will begin responding with the v3 media type. If your application relies on functionality that differs between beta and v3, then you are affected by this change. You will need to take steps to prepare for the change.
-
-
What should you do?
-
-
If you are affected by this change, we recommend that you:
-
-
-
Update your applications to depend on the v3 functionality instead of the beta functionality. (If you use one of the popular client libraries, there’s a good chance that they’ve already done the work for you. In that case, you can just update to the latest version of that library.)
-
Request the v3 media type via the Accept header.
-
-
-
If you cannot update your application to depend on the v3 functionality by April 15*, you can just request the beta media type via the Accept header. Doing so will insulate you from this change.
-
-
Cutover test on March 12, 2014
-
-
To help you understand the impact of this change before it becomes permanent, we will temporarily implement this change for a single day on March 12. From approximately 12:01am UTC to 11:59pm UTC on March 12, the API will respond with the v3 media type by default.
-
-
Follow @GitHubAPI to receive updates before and after the test.
-
-
Stay informed
-
-
Depending on the results of the cutover test, we may schedule additional tests before the final cutover on April 15. If so, we’ll to announce them in advance. Be sure to stay tuned to the blog or follow @GitHubAPI for updates.
-
-
If you have any questions, please get in touch. We’ll be happy to help.
The organization members and organization public members methods will soon return paginated results by default. Beginning
-today, these methods will paginate if you include page or per_page query
-parameters. Starting January 15th, 2014, these methods will always return paginated
-results.
-
-
As always, be sure and follow those Link headers to get
-subsequent results. If you have any questions or run into trouble, feel free to
-get in touch.
Hot on the heels of the Search API, the Releases API
-is now officially part of GitHub API v3. We now consider it stable for
-production use.
-
-
Preview Media Type No Longer Needed
-
-
If you used the Releases API during the preview period, you needed to provide a custom media type in the Accept header:
-
-
application/vnd.github.manifold-preview+json
-
-
-
Now that the preview period has ended, you no longer need to pass this custom media type.
-
-
Instead, we recommend that you specify v3 as the version in the Accept header:
-
-
application/vnd.github.v3+json
-
-
-
Onward!
-
-
Thanks again to everyone that tried out the Releases API during the preview period.
-We got some great feedback, and we are already discussing additions to the API.
We’re excited to announce that the new Search API has graduated from preview mode.
-As of today, the Search API is an official part of GitHub API v3.
-As such, the Search API is now stable and suitable for production use.
-
-
Preview Media Type No Longer Needed
-
-
If you used the Search API during the preview period, you needed to provide a custom media type in the Accept header:
-
-
application/vnd.github.preview+json
-
-
-
Now that the preview period has ended, you no longer need to pass this custom media type.
-
-
Instead, we recommend that you specify v3 as the version in the Accept header:
-
-
application/vnd.github.v3+json
-
-
-
Onward!
-
-
Thanks again to everyone that tried out the Search API during the preview period.
As we prepare to end the preview period for the new search API,
-we’re making sure that it’s ready to handle the traffic from all the apps you’ll build on top of it.
-
-
New Validation Rule
-
-
In order to support the expected volume of requests, we’re applying a new validation rule to the Code Search API.
-Starting today, you will need to scope your code queries to a specific set of users, organizations, or repositories.
This validation does not affect searches performed on github.com/search.
-
-
By ensuring that code queries are more targeted in nature, the API will be ready to meet the expected demand from all your apps.
-As we continue to tune the Search API, we hope to relax this validation in the future.
-There’s no ETA, but we’d like to relax it as soon as it’s feasible.
-
-
As always, if you have any questions or feedback, please get in touch.
Starting today, we are returning granted scopes as part of the
-access_token response.
-For example, if you are making a POST with the application/json
-mime-type you’ll see an additional field for the granted scopes.
Right now, these scopes will be identical to what you requested, but we
-are moving towards a feature set that will allow GitHub users to edit
-their scopes, effectively granting your application less access than you
-originally requested. You should be aware of this possibility and adjust
-your application behavior accordingly.
-
-
Some things to watch out for and keep in mind:
-
-
-
-
Most third party applications using GitHub OAuth to identify users have
-the best success in adoption by starting out with a request for the
-minimum access that the application can possibly get away with.
-Something like no scopes or just user:email is very sane.
-
-
-
It is important to handle the error cases where a user chooses to
-grant you less access than you originally requested. Now that we are
-surfacing the granted scopes on the access_token response, applications
-can warn or otherwise communicate with their users that they will see
-reduced functionality or be unable to perform some actions.
-
-
-
Applications can always send users back through the flow again to get
-additional permission, but don’t forget that users can always say no.
We owe a big “Thank You!” to everyone that has taken the time to try out the new Search API.
-We :heart: every one of you.
-Just as we hoped,
-the preview period has allowed us to see how you want to use the new API,
-and it has given us a chance to improve the API before finalizing it.
-
-
In order to incorporate everything that we’ve learned,
-we’re going to keep the Search API in preview mode for a little while longer.
-We have a few bugs to squash and a couple performance kinks to iron out.
-We’re hard at work on those improvements now,
-and we expect to have more news in the coming weeks.
This API is a little different due to the binary assets. We use the Accept header for content negotiation when requesting
-a release asset. Pass a standard API media type to get the API representation:
The new API is available as a preview. This gives developers a chance to provide feedback on the direction of
-the API before we freeze changes. We expect to lift the preview status in 30 days.
-
-
As with the Search API, we’ll take this opportunity to iterate quickly. Breaking changes will be announced
-on this developer blog without any advance warning. Once the preview period is over, we’ll consider the Releases API unchangeable.
-At that point, it will be stable and suitable for production use.
-
-
The preview media type is “application/vnd.github.manifold-preview”. Manifold is
-a member of the Avengers, with the ability to teleport through time and space. He’s the one in the middle holding the spear.
As announced earlier today, GitHub.com now supports two-factor
-authentication (2FA) for increased security. For users with this feature
-enabled, GitHub.com will prompt for a 2FA code in addition to a username and
-password during authentication. We’ve also rolled out some improvements to the
-API to ensure that 2FA requirements in the API are consistent with GitHub.com.
-
-
Authenticating with the API
-
-
For users without 2FA enabled, and for applications using the OAuth web
-flow for authentication, everything is
-business as usual. You’ll continue to authenticate with the API just as you
-always have. (That was easy.)
-
-
If you enable 2FA and use Basic Authentication to access the API, we’re
-providing multiple options to make the flow simple and easy.
-
-
Basic Authentication and 2FA
-
-
Personal Access Tokens
-
-
Personal access tokens provide the simplest option for using 2FA with Basic
-Authentication. You can create these tokens via the application settings page
-on GitHub.com, and you can revoke
-them at any time. For more information about authenticating to the API with
-personal access tokens, be sure to check out our help article on the
-topic.
-
-
Tightly-integrated 2FA
-
-
For developers wishing to integrate GitHub 2FA directly into their application,
-the API’s Basic Authentication now supports the ability to send the user’s 2FA
-code, in addition to the username and password.
-
-
We’re here to help
-
-
We think GitHub users are going to love the additional security provided by
-two-factor authentication. As always, if you have any questions or feedback,
-let us know. We’re here to help!
Today we’re shipping two improvements to the new Search API.
-
-
More Text Match Metadata
-
-
When searching for code, the API previously provided text match metadata (i.e., “highlights”) for file content.
-Now, you can also get this metadata for matches that occur within the file path.
Inside the fragment value, we see HTML-encoded entities (e.g., <).
-Since we’re returning JSON (not HTML), API clients might not expect any HTML-encoded text.
-As of today, the API returns these fragments without this extraneous encoding.
We’re about halfway through the preview period for the new Search API.
-We appreciate everyone that has provided feedback so far. Please keep it coming!
Today we’re excited to announce a brand new Search API. Whether you’re
-searching for code, repositories,
-issues, or users, all the query abilities of
-github.com are now available via the API as well.
On github.com, we enjoy the context provided by code snippets and highlights in
-search results.
-
-
-
-
We want API consumers to have access to that information as well. So, API
-requests can opt to receive those
-text fragments in the response. Each fragment is accompanied by
-numeric offsets identifying the exact location of each matching search term.
-
-
Preview period
-
-
We’re making this new API available today for developers to
-preview. We think developers are going to love it, but we want
-to get your feedback before we declare the Search API “final” and
-“unchangeable.” We expect the preview period to last for roughly 60 days.
-
-
As we discover opportunities to improve this new API during the preview period,
-we may ship changes that break clients using the preview version of the API. We
-want to iterate quickly. To do so, we will announce any changes here (on the
-developer blog), but we will not provide any advance notice.
-
-
At the end of preview period, the Search API will become an official component
-of GitHub API v3. At that point, the new Search API will be stable and suitable
-for production use.
-
-
What about the old search API?
-
-
The legacy search API is still available. Many existing clients
-depend on it, and it is not changing in any way. While the new API offers much
-more functionality, the legacy search endpoints remain an official part of
-GitHub API v3.
Have you ever wondered when your rate limit will reset back to its maximum value?
-That information is now available in the new X-RateLimit-Reset response header.
-
-
-$ curl -I https://api.github.com/orgs/octokit
-
-HTTP/1.1 200 OK
-Status: 200 OK
-X-RateLimit-Limit: 60
-X-RateLimit-Remaining: 42
-X-RateLimit-Reset: 1372700873
-...
-
-
-
The X-RateLimit-Reset header provides a Unix UTC timestamp, letting you know the exact time that your fresh new rate limit kicks in.
-
-
The reset timestamp is also available as part of the /rate_limit resource.
We’re following in the footsteps of GitHub.com’s ability to edit and
-create files in your web browser. Starting today, the
-Repository Contents API will let you easily create, update, and even
-delete individual files.
Today we’re happy to open our Repository Statistics API to everyone. We’re using
-repository statistics to power our graphs,
-but we can’t wait to see what others can do with this information.
-
-
Starting today, these resources are available to you:
When you get the details for a Pull Request from the API, the
-response provides everything there is to
-know about that Pull Request. In addition to the useful information provided in
-the API response, the JSON also includes the merge_commit_sha attribute. This
-attribute is a frequent source of misunderstanding, and we aim to remove the
-confusion.
To protect future API consumers from this confusion, we have
-deprecated the merge_commit_sha attribute, and we will
-remove it in the next major version of the API.
-
-
As always, if you have any questions or feedback, please drop us a line at
-support@github.com.
After an almost six week grace period, we’re now enforcing the User Agent
-header for all API requests. Most HTTP libraries (including cURL)
-set this header by default. If you’re experiencing an increase in 403
-responses, be sure and check your code.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
We are experimenting with changes to the “Hookshot” backend that powers service
-hooks. There were some significant networking changes with the new cluster,
-so there are some new IP whitelist rules for hooks:
-
-
-
204.232.175.64/27
-
192.30.252.0/22
-
-
-
These are in CIDR notation. They represent a significant range of GitHub
-addresses, meaning this should be the last IP change for a while. Once this
-cluster is activated and we shut the other cluster down, we will be removing
-the other entries.
-
-
We are currently testing the new backend with all repositories in the GitHub
-organization only, and expect to start testing it with user data next week.
We had an issue with the Hookshot load balancer this morning, causing the
-majority of hooks to flow to a single node only. This lead to massive queue
-times. While fixing this, we’re putting the old Services backend in use.
-
-
This means the old IPs are back in use. Use this Help guide
-if you already removed them from your firewall.
We turned Hookshot (our new GitHub Services backend) on yesterday. Things have
-been pretty smooth, with one issue: Hooks going to other EC2 nodes come from
-the private IP addresses of our nodes in the 10...* range.
-
-
If your web hook servers are on EC2 and are missing hooks from GitHub due to
-an IP restriction, we recommend the following:
-
-
-
Remove the IP white list.
-
Fall back to HTTPS and Basic Auth to restrict pushes to authorized senders only.
-
-
-
We’re currently working on solving this problem. Hit up support@github.com
-if you have any questions.
We are finishing up a new GitHub Services backend, dubbed “Hookshot”, to
-increase the speed and reliability of our delivered payloads. We are doing
-what we can to make this a seamless transition for everyone. However, there
-are a few notable changes.
-
-
-
-
There is a new Meta API endpoint
-listing the current public IPs that hooks originate from.
-
-
-
We’re removing the AMQP service from GitHub. It hasn’t worked in quite some
-time, and the code it uses doesn’t work in our background workers.
-
-
-
We’re also instituting a new guideline to improve the reliability and
-maintainability of services in the future. As of today, all new services must
-accept an unmodified payload over HTTP. Any service that does not will be
-rejected. To see an example of an acceptable service, check out Code Climate.
-Notice their service simply accepts HTTP POST from GitHub unmodified. For an
-example of a service that won’t be accepted after today, check out Campfire. It
-uses other Ruby gems and contains custom logic to transform the GitHub payload
-to Campfire messages. Existing hooks will keep working (don’t worry 37signals, we
-:heart: Campfire).
-
-
-
-
We’re making these changes because we want to focus on the reliability of the
-core Services backend for everyone. Maintaining custom logic and libraries for
-over 100 services is taking too much of this focus away.
Following on from our previous post
-about requiring requests to include a valid User Agent header
-we will soon be changing our API servers to return HTTP 403
-to any clients not providing a valid User Agent header.
-
-
We will be making this change on Monday, March 4th 2013.
-
-
Setting this helps us identify requests from you, and get in touch with people who are using
-the API in a way which causes disruption to GitHub. Most HTTP libraries and tools like cURL
-already provide a valid header for you, and allow you to customize it, so this will not require
-many of our users to make any changes whatsoever.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
We’ve added a few new user scopes for 3rd party applications that want very
-specific user functionality. The user:email scope gives apps read-only access
-to a user’s private email addresses. The user:follow scope lets a user
-follow and unfollow other users.
-
-
This should help keep applications from requiring the user scope, which
-can be potentially dangerous.
-
-
We also added a read-only endpoint to get a user’s public SSH keys.
-
-
GET https://api.github.com/users/technoweenie/keys
-
Improvements continue to the Organizations Repository listing endpoint.
-Today we’re improving pagination so that it works as documented. Now
-you can expect Link headers to navigate through the results space,
-regardless of what you send in the type parameter.
-
-
The docs for Organization Repositories queries are still here:
We’ve made a couple of changes today to the Organization repositories
-listing to bring it a bit closer to the functionality of the GitHub.com
-Organization repositories tab. We now let you retrieve repositories
-which are forks of another repository, as well as those repositories which
-are sources (not forks).
-
-
# Grab all fork Repositories for an Organization
-curl "https://api.github.com/orgs/:org/repos?type=forks"
-
-# Grab all source Repositories for an Organization
-curl "https://api.github.com/orgs/:org/repos?type=sources"
-
-
-
Check out the docs for sorting and filtering options:
The Authorizations API is an easy way to create an OAuth
-authorization using Basic Auth. Just POST your desired scopes and optional
-note and you get a token back:
This call creates a token for the authenticating user tied to a special “API”
-OAuth application.
-
-
We now support creating tokens for your own OAuth application by passing your
-twenty character client_id and forty character client_secret as found in
-the settings page for your OAuth application.
You’ve always been able to grab all the commit comments for an entire
-repository via the API, but to get Issue comments and Pull Request Review
-Comments, you could only fetch the comments for a single Issue or Pull Request.
-
-
Today, we’re introducing two new methods to grab all Issue Comments and Review
-Comments for a repository.
-
-
# Grab all Issue Comments
-curl https://api.github.com/repos/mathiasbynens/dotfiles/issues/comments
-
-# Grab all Review Comments
-curl https://api.github.com/repos/mathiasbynens/dotfiles/pulls/comments
-
-
-
Check out the docs for sorting and filtering options:
We recently made it easy to initialize a repository when you create
-it via the API. One of the options you can pass when creating a
-repository is gitignore_template. This value is the name of one of the
-templates from the the public GitHub .gitignore repository.
We made a slight change to the way you fork a repository. By default, you
-can fork my repository through an HTTP POST to the repository’s fork resource.
-
-
$ curl -X POST https://api.github.com/repos/technoweenie/faraday/forks
-
-
-
This repository forks to your personal account. However, there are cases when
-you want to fork to one of your organizations instead. The previous method
-required a ?org query parameter:
-
-
$ curl -X POST /repos/technoweenie/faraday/forks?org=mycompany
-
-
-
Query parameters on POST requests are unusual in APIs, and definitely
-inconsistent with the rest of the GitHub API. You should be able to post a
-JSON body like every other POST endpoint. Now, you can! Only, now we’re
-calling the field organization.
The URIs of all gist comments are changing immediately. The new URI pattern for gist comments is /gists/{gist-id}/comments/{id}. (See gist comments section of the docs for more details.) This change is necessary because the auto-incremented ids of gist comments are easy to guess. This predictability allows anyone to view comments on private Gists with relative ease. Obviously, comments on private gists should be just as private as the gist itself.
-
-
Adding the gist id to the URI of comments makes it impossible, in practical terms, to guess that URI because the id of private gists are very large random numbers. This is, unfortunately, a breaking change but one that cannot be avoided because of the security implications of the current URIs. We apologize for the inconvenience.
-
-
We have also added a comments_url member to the Gist documents. The comments_url link provides access to the comments of a Gist in a way that will insulate clients from changes in the URI patterns used by the GitHub API. We are increasing our use of links in order to make changes such as this one less damaging to clients. We strongly encourage using url and *_url properties, where possible, rather than constructing URIs using the patterns published on this site. Doing so will result in clients that break less often.
Now that the dust has settled around Notifications and Stars,
-we’ve unleashed all that :sparkles: in a brand new API. You can now
-view and mark notifications as read.
-
-
Endpoint
-
-
The core notifications functionality is under the /notifications endpoint.
-You can look for unread notifications:
-
-
-$ curl https://api.github.com/notifications
-
-
-
You can filter these notifications to a single Repository:
-# all notifications
-$ curl https://api.github.com/notifications \
- -X PUT -d '{"read": true}'
-
-# notifications for a single repository
-$ curl https://api.github.com/repos/technoweenie/faraday/notifications \
- -X PUT -d '{"read": true}'
-
-
-
You can also modify subscriptions for a Repository or a single thread.
-
-
-# subscription details for the thread (either an Issue or Commit)
-$ curl https://api.github.com/notifications/threads/1/subscription
-
-# subscription details for a whole Repository.
-$ curl https://api.github.com/repos/technoweenie/faraday/subscription
-
-
-
Polling
-
-
The Notifications API is optimized for polling by the last modified time:
-
-
-# Add authentication to your requests
-$ curl -I https://api.github.com/notifications
-HTTP/1.1 200 OK
-Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
-X-Poll-Interval: 60
-
-# Pass the Last-Modified header exactly
-$ curl -I https://api.github.com/notifications
- -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
-HTTP/1.1 304 Not Modified
-X-Poll-Interval: 60
-
Requesting the member list of an
-organization of which you are not a member now redirects to the public members
-list. Similarly, requests to
-membership check resources of
-an organization of which you are not a member are redirected to the equivalent
-public membership check.
-One exception to the latter case is that if you are checking about your own
-membership the request is not redirected. You are always allowed to know what
-organizations you belong to.
-
-
The changes where made to clarify the purpose of these various resources. The
-/orgs/:org/members resources are intended for use by members of the
-organization in question. The /orgs/:org/public_members resources are for
-acquiring information about the public membership of organizations. If you are
-not a member you are not allowed to see private membership information so you
-should be using the public membership resources.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
To ensure a high quality of service for all API consumers, we’ve reduced the
-default rate limit for unauthenticated requests. To enjoy the default rate
-limit of 5,000 requests per hour, you’ll need to
-authenticate via Basic Auth
-or OAuth. Unauthenticated requests will be limited to 60 per hour unless you
-include your OAuth client and
-secret.
-
-
We’ll soon require all requests to include a valid User Agent
-header. Setting a
-unique value for this header helps us identify requests and get in touch with
-developers who are abusing the API. Most HTTP libraries, wrapper libraries, and
-even cURL provide a valid header for you already and allow you to change it to
-something unique to your application.
-
-
If you have any questions or feedback, please drop us a line at
-support@github.com.
Today we’ve made it easier to add commits to a repository via the GitHub API.
-Until now, you could create a repository, but you would
-need to initialize it locally via your Git client before adding any commits via
-the API.
-
-
Now you can optionally init a repository when it’s created by sending true
-for the auto_init parameter:
We recently changed the Watcher behavior on GitHub. What
-used to be known as “Watching” is now “Starring”. Starring is basically a way
-to bookmark interesting repositories. Watching is a way to indicate that you
-want to receive email or web notifications on a Repository.
-
-
This works well on GitHub.com, but poses a problem for the GitHub API. How do
-we change this in a way that developers can gracefully upgrade their
-applications? We’re currently looking at rolling out the changes in three
-phases over an extended period of time.
-/repos/:owner/:repo/watchers - A list of users starring the repository.
-
-/users/:user/watched - A list of repositories that a user has starred.
-
-/user/watched - A list of repositories the current user has starred.
-
-
-
Phase 1: Add Watchers as Subscriptions
-
-
This phase exposes Watchers as “Subscriptions”. This is to
-keep from clashing with the legacy endpoints. This phase will happen
-automatically and will not break your application until Phase 3 starts.
-(UPDATE: API v3 will continue to support this functionality indefinitely.)
-
-
-
-/repos/:owner/:repo/subscribers - A list of users watching the repository.
-
-/users/:user/subscriptions - A list of repositories that a user is watching.
-
-/user/subscriptions - A list of repositories the current user is watching.
-
-
-
We’ll also add a copy of the legacy Watchers API in the new endpoint:
-
-
-
-/repos/:owner/:repo/stargazers - A list of users starring the repository.
-
-/users/:user/starred - A list of repositories that a user has starred.
-
-/user/starred - A list of repositories the current user has starred.
-
-
-
This is in place now with the current media type for the API:
-
-
application/vnd.github.beta+json
-
-
-
If you care about your application not breaking, make sure all outgoing API
-requests pass that value for the “Accept” header. You should do this now. This
-can be verified by checking the X-GitHub-Media-Type header on all API
-responses.
-This Phase will be broken once Phase 3 starts. Phase 3 removes all support for
-the "beta" media type, and makes the "v3" media type the implicit default
-for API requests.
-
-
UPDATE - November 6, 2013
-
-
-
- API v3 will continue to officially support the functionality described in
- Phase 1 above. This functionality will remain intact for the lifetime of
- API v3.
-
-
- API v3 will not include Phases 2 and 3 (below). Those phases will
- likely be part of the next major version of the API. (We have not announced
- a timeline for the next major version of the API.)
-
-
-
-
Phase 2: Switch /watchers API Endpoint
-
-The "watch" endpoints will now be a copy of the "subscription" endpoints. You
-will have to use /user/starred to get a user's starred repositories, not
-/user/watched.
-
-This requires a new media type value:
-
-
application/vnd.github.v3+json
-
-This is a breaking change from Phase 1. We will release this change in an
-experimental mode first, letting developers gracefully upgrade their
-applications by specifying the new media value for the Accept header.
-
-
-
-
-This phase involves disabling the subscription endpoints completely. At this
-point, you should be using the starring endpoints for starred repositories, and
-the watch endpoints for watched repositories. No date has been set yet, but we
-expect this to be 3-6 months after Phase 2 is in place. This should give
-developers enough time for a smooth upgrade path. If they use popular API
-wrappers, the work will likely mostly be done for them.
-
-Keep on passing the "v3" media type in your application, until the API has
-another breaking change to make. If you can't make the deadline for Phase 3,
-just set the "beta" media type until we shut that down completely. It's likely
-that we will keep the old "beta" media type active for another month, like
-the last time we terminated
-old API functionality.
-
-
-
-
-
-
-
-
-
-
diff --git a/config.ru b/config.ru
new file mode 100644
index 0000000000..6763c19b6b
--- /dev/null
+++ b/config.ru
@@ -0,0 +1,5 @@
+# This file is auto-generated by Jekyll Auth
+# It tells Heroku how to launch our site
+
+require "jekyll-auth"
+run JekyllAuth.site
diff --git a/config.yaml b/config.yaml
deleted file mode 100644
index b2a6c6213a..0000000000
--- a/config.yaml
+++ /dev/null
@@ -1,56 +0,0 @@
-# A list of file extensions that nanoc will consider to be textual rather than
-# binary. If an item with an extension not in this list is found, the file
-# will be considered as binary.
-text_extensions: [ 'css', 'erb', 'haml', 'htm', 'html', 'js', 'less', 'markdown', 'md', 'php', 'rb', 'sass', 'scss', 'txt', 'xhtml', 'xml', 'atom' ]
-
-# The path to the directory where all generated files will be written to. This
-# can be an absolute path starting with a slash, but it can also be path
-# relative to the site directory.
-output_dir: output
-
-# A list of index filenames, i.e. names of files that will be served by a web
-# server when a directory is requested. Usually, index files are named
-# “index.hml”, but depending on the web server, this may be something else,
-# such as “default.htm”. This list is used by nanoc to generate pretty URLs.
-index_filenames: [ 'index.html' ]
-
-# Whether or not to generate a diff of the compiled content when compiling a
-# site. The diff will contain the differences between the compiled content
-# before and after the last site compilation.
-enable_output_diff: false
-
-# The data sources where nanoc loads its data from. This is an array of
-# hashes; each array element represents a single data source. By default,
-# there is only a single data source that reads data from the “content/” and
-# “layout/” directories in the site directory.
-data_sources:
- -
- # The type is the identifier of the data source. By default, this will be
- # `filesystem_unified`.
- type: filesystem_unified
-
- # The path where items should be mounted (comparable to mount points in
- # Unix-like systems). This is “/” by default, meaning that items will have
- # “/” prefixed to their identifiers. If the items root were “/en/”
- # instead, an item at content/about.html would have an identifier of
- # “/en/about/” instead of just “/about/”.
- items_root: /
-
- # The path where layouts should be mounted. The layouts root behaves the
- # same as the items root, but applies to layouts rather than items.
- layouts_root: /
-
- -
- type: static
- items_root: /static
-
-# For the atom feed.
-base_url: http://developer.github.com
-
-# Array of [version, released_at] Array tuples.
-api_versions:
- -
- - beta
- - 2011-4-27
- -
- - v3
diff --git a/content/404.html b/content/404.html
new file mode 100644
index 0000000000..77bc3992f1
--- /dev/null
+++ b/content/404.html
@@ -0,0 +1,7 @@
+---
+title: GitHub Help • Article not found!
+exclude_from_search: true
+---
+
+
Whoops, looks like that page doesn't exist.
+
diff --git a/content/feed.atom b/content/changes.atom
similarity index 99%
rename from content/feed.atom
rename to content/changes.atom
index d04f5aae55..e80eaefb66 100644
--- a/content/feed.atom
+++ b/content/changes.atom
@@ -5,5 +5,4 @@ author_name: technoweenie
author_uri: https://github.com/technoweenie
layout: false
---
-
<%= atom_feed :limit => 30, :articles => api_changes %>
diff --git a/content/changes/2012-9-5-watcher-api.html b/content/changes/2012-09-05-watcher-api.html
similarity index 96%
rename from content/changes/2012-9-5-watcher-api.html
rename to content/changes/2012-09-05-watcher-api.html
index c64f114109..fd151bdc3c 100644
--- a/content/changes/2012-9-5-watcher-api.html
+++ b/content/changes/2012-09-05-watcher-api.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Upcoming Changes to Watcher and Star APIs
-created_at: 2012-9-5
author_name: technoweenie
---
@@ -53,9 +51,11 @@
can be verified by checking the `X-GitHub-Media-Type` header on all API
responses.
- # Accesses a user's starred repositories.
- curl https://api.github.com/user/watched \
- -H "Accept: application/vnd.github.beta+json"
+``` command-line
+# Accesses a user's starred repositories.
+$ curl https://api.github.com/user/watched \
+$ -H "Accept: application/vnd.github.beta+json"
+```
-This Phase will be broken once Phase 3 starts. Phase 3 removes all support for
the "beta" media type, and makes the "v3" media type the implicit default
diff --git a/content/changes/2012-9-28-auto-init-for-repositories.html b/content/changes/2012-09-28-auto-init-for-repositories.html
similarity index 71%
rename from content/changes/2012-9-28-auto-init-for-repositories.html
rename to content/changes/2012-09-28-auto-init-for-repositories.html
index bca3d142b6..cf650e9291 100644
--- a/content/changes/2012-9-28-auto-init-for-repositories.html
+++ b/content/changes/2012-09-28-auto-init-for-repositories.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Initialize a repository when creating
-created_at: 2012-9-28
author_name: pengwynn
---
@@ -13,15 +11,15 @@
Now you can optionally init a repository when it's created by sending `true`
for the `auto_init` parameter:
-
+``` command-line
+$ curl -i -u pengwynn \
+$ -d '{"name": "create-repo-test", "auto_init": true}' \
+$ https://api.github.com/user/repos
+```
The resulting repository will have a README stub and an initial commit.
-
+
### .gitignore templates
@@ -29,13 +27,12 @@
the basename of any template in the [GitHub gitignore templates
project](https://github.com/github/gitignore).
-
-
+``` command-line
+$ curl -i -u pengwynn \
+$ -d '{"name": "create-repo-test", "auto_init": true, \
+$ "gitignore_template": "Haskell"}' \
+$ https://api.github.com/user/repos
+```
As the [docs point out](/v3/repos/#create), the `gitignore_template` parameter
is ignored if `auto_init` is not present and `true`.
@@ -47,4 +44,3 @@
[twitter]: https://twitter.com/githubapi
[email]: mailto:support@github.com
[c]: https://github.com/c
-
diff --git a/content/changes/2012-10-14-rate-limit-changes.html b/content/changes/2012-10-14-rate-limit-changes.html
index b33e2cf9bc..60aa94f4fa 100644
--- a/content/changes/2012-10-14-rate-limit-changes.html
+++ b/content/changes/2012-10-14-rate-limit-changes.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Rate limit changes for unauthenticated requests
-created_at: 2012-10-14
author_name: pengwynn
---
@@ -11,7 +9,7 @@
[authenticate](http://developer.github.com/v3/#authentication) via Basic Auth
or OAuth. Unauthenticated requests will be limited to 60 per hour unless you
[include your OAuth client and
-secret](http://developer.github.com/v3/#unauthenticated-rate-limited-requests).
+secret](http://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications).
We'll soon require all requests to include a valid [User Agent
header](http://en.wikipedia.org/wiki/User_agent). Setting a
diff --git a/content/changes/2012-10-17-org-members-redirection.md b/content/changes/2012-10-17-org-members-redirection.md
index 6b8a3f54da..ace24c0173 100644
--- a/content/changes/2012-10-17-org-members-redirection.md
+++ b/content/changes/2012-10-17-org-members-redirection.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Organization Members Resource Changes
-created_at: 2012-10-17
author_name: pezra
---
diff --git a/content/changes/2012-10-24-set-default-branch.html b/content/changes/2012-10-24-set-default-branch.html
index 05bb456161..ac9800b41b 100644
--- a/content/changes/2012-10-24-set-default-branch.html
+++ b/content/changes/2012-10-24-set-default-branch.html
@@ -1,21 +1,19 @@
---
-kind: change
title: Set the default branch for a repository
-created_at: 2012-10-24
author_name: pengwynn
---
You can set the default branch for a repository to something other than 'master' from the GitHub repository admin screen:
-
+
Now, you can update this setting via the API. We've added a `default_branch` parameter to the [Edit Repository method][edit-repo]:
-
+``` command-line
+$ curl -u pengwynn \
+$ -d '{"name": "octokit", "default_branch":"development"}' \
+$ https://api.github.com/repos/octokit/octokit.rb
+```
If you provide a branch name that hasn't been pushed to GitHub, we'll gracefully fall back to `'master'` or the first branch.
diff --git a/content/changes/2012-10-26-notifications-api.md b/content/changes/2012-10-26-notifications-api.md
index 6d1e6bd3e4..db08698377 100644
--- a/content/changes/2012-10-26-notifications-api.md
+++ b/content/changes/2012-10-26-notifications-api.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Notifications API
-created_at: 2012-10-26
author_name: technoweenie
---
@@ -17,56 +15,54 @@ view and mark notifications as read.
The core notifications functionality is under the `/notifications` endpoint.
You can look for unread notifications:
-
+``` command-line
# all notifications
$ curl https://api.github.com/notifications \
- -X PUT -d '{"read": true}'
+$ -X PUT -d '{"read": true}'
# notifications for a single repository
$ curl https://api.github.com/repos/technoweenie/faraday/notifications \
- -X PUT -d '{"read": true}'
-
+$ -X PUT -d '{"read": true}'
+```
You can also modify subscriptions for a Repository or a single thread.
-
+``` command-line
# subscription details for the thread (either an Issue or Commit)
$ curl https://api.github.com/notifications/threads/1/subscription
# subscription details for a whole Repository.
$ curl https://api.github.com/repos/technoweenie/faraday/subscription
-
+```
## Polling
The Notifications API is optimized for polling by the last modified time:
-
+``` command-line
# Add authentication to your requests
$ curl -I https://api.github.com/notifications
-HTTP/1.1 200 OK
-Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
-X-Poll-Interval: 60
+> HTTP/1.1 200 OK
+> Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
+> X-Poll-Interval: 60
# Pass the Last-Modified header exactly
$ curl -I https://api.github.com/notifications
- -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
-HTTP/1.1 304 Not Modified
-X-Poll-Interval: 60
-
+$ -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
+> HTTP/1.1 304 Not Modified
+> X-Poll-Interval: 60
+```
You can read about the API details in depth in the [Notifications documentation][api].
-
-
diff --git a/content/changes/2012-10-31-gist-comment-uris.md b/content/changes/2012-10-31-gist-comment-uris.md
index 09c112586c..a6f3d9e4f4 100644
--- a/content/changes/2012-10-31-gist-comment-uris.md
+++ b/content/changes/2012-10-31-gist-comment-uris.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Gist comment URIs
-created_at: 2012-10-31
author_name: pezra
---
diff --git a/content/changes/2012-11-27-forking-to-organizations.html b/content/changes/2012-11-27-forking-to-organizations.html
index 7e4530985a..90282f045a 100644
--- a/content/changes/2012-11-27-forking-to-organizations.html
+++ b/content/changes/2012-11-27-forking-to-organizations.html
@@ -1,29 +1,32 @@
---
-kind: change
title: Forking to Organizations
-created_at: 2012-11-27
author_name: technoweenie
---
We made a slight change to the way you fork a repository. By default, you
can fork my repository through an HTTP POST to the repository's fork resource.
- $ curl -X POST https://api.github.com/repos/technoweenie/faraday/forks
+``` command-line
+$ curl -X POST https://api.github.com/repos/technoweenie/faraday/forks
+```
This repository forks to your personal account. However, there are cases when
you want to fork to one of your organizations instead. The previous method
required a `?org` query parameter:
- $ curl -X POST /repos/technoweenie/faraday/forks?org=mycompany
+``` command-line
+$ curl -X POST /repos/technoweenie/faraday/forks?org=mycompany
+```
Query parameters on POST requests are unusual in APIs, and definitely
inconsistent with the rest of the GitHub API. You should be able to post a
JSON body like every other POST endpoint. Now, you can! Only, now we're
calling the field `organization`.
- $ curl /repos/technoweenie/faraday/forks?org=mycompany \
- -d '{"organization": "mycompany"}'
+``` command-line
+$ curl /repos/technoweenie/faraday/forks?org=mycompany \
+$ -d '{"organization": "mycompany"}'
+```
Don't worry, we are committed to maintaining the legacy behavior until the next
major change of the GitHub API.
-
diff --git a/content/changes/2012-11-29-gitignore-templates.html b/content/changes/2012-11-29-gitignore-templates.html
index 931e12b060..d88d39b88f 100644
--- a/content/changes/2012-11-29-gitignore-templates.html
+++ b/content/changes/2012-11-29-gitignore-templates.html
@@ -1,58 +1,60 @@
---
-kind: change
title: Gitignore Templates API
-created_at: 2012-11-29
author_name: pengwynn
---
We recently [made it easy][init-post] to initialize a repository when you create
it [via the API][repo-create]. One of the options you can pass when creating a
repository is `gitignore_template`. This value is the name of one of the
-templates from the the public [GitHub .gitignore repository][templates-repo].
+templates from the public [GitHub .gitignore repository][templates-repo].
The [Gitignore Templates API][new-api] makes it easy to list those templates:
- curl https://api.github.com/gitignore/templates
+``` command-line
+$ curl https://api.github.com/gitignore/templates
- HTTP/1.1 200 OK
+> HTTP/1.1 200 OK
- [
- "Actionscript",
- "Android",
- "AppceleratorTitanium",
- "Autotools",
- "Bancha",
- "C",
- "C++",
- ...
+> [
+> "Actionscript",
+> "Android",
+> "AppceleratorTitanium",
+> "Autotools",
+> "Bancha",
+> "C",
+> "C++",
+> ...
+```
If you'd like to view the source, you can also fetch a single template.
- curl -H 'Accept: application/vnd.github.raw' \
- https://api.github.com/gitignore/templates/Objective-C
-
- HTTP/1.1 200 OK
-
- # Xcode
- .DS_Store
- build/
- *.pbxuser
- !default.pbxuser
- *.mode1v3
- !default.mode1v3
- *.mode2v3
- !default.mode2v3
- *.perspectivev3
- !default.perspectivev3
- *.xcworkspace
- !default.xcworkspace
- xcuserdata
- profile
- *.moved-aside
- DerivedData
- .idea/
-
-[init-post]: /changes/2012-9-28-auto-init-for-repositories/
+``` command-line
+$ curl -H 'Accept: application/vnd.github.raw' \
+$ https://api.github.com/gitignore/templates/Objective-C
+
+> HTTP/1.1 200 OK
+
+# Xcode
+> .DS_Store
+> build/
+> *.pbxuser
+> !default.pbxuser
+> *.mode1v3
+> !default.mode1v3
+> *.mode2v3
+> !default.mode2v3
+> *.perspectivev3
+> !default.perspectivev3
+> *.xcworkspace
+> !default.xcworkspace
+> xcuserdata
+> profile
+> *.moved-aside
+> DerivedData
+> .idea/
+```
+
+[init-post]: /changes/2012-09-28-auto-init-for-repositories/
[repo-create]: /v3/repos/#create
[templates-repo]: https://github.com/github/gitignore
[new-api]: /v3/gitignore/
diff --git a/content/changes/2012-12-04-List-comments-for-repo.html b/content/changes/2012-12-04-List-comments-for-repo.html
index 228bdc849b..7511737cdc 100644
--- a/content/changes/2012-12-04-List-comments-for-repo.html
+++ b/content/changes/2012-12-04-List-comments-for-repo.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Per-repository Review and Issue Comment listing
-created_at: 2012-12-04
author_name: pengwynn
---
@@ -12,15 +10,15 @@
Today, we're introducing two new methods to grab all Issue Comments and Review
Comments for a repository.
- # Grab all Issue Comments
- curl https://api.github.com/repos/mathiasbynens/dotfiles/issues/comments
+``` command-line
+# Grab all Issue Comments
+> curl https://api.github.com/repos/mathiasbynens/dotfiles/issues/comments
- # Grab all Review Comments
- curl https://api.github.com/repos/mathiasbynens/dotfiles/pulls/comments
+# Grab all Review Comments
+> curl https://api.github.com/repos/mathiasbynens/dotfiles/pulls/comments
+```
Check out the docs for sorting and filtering options:
* [Issue comments](/v3/issues/comments/#list-comments-in-a-repository)
* [Review comments](/v3/pulls/comments/#list-comments-in-a-repository)
-
-
diff --git a/content/changes/2012-12-06-create-authorization-for-app.html b/content/changes/2012-12-06-create-authorization-for-app.html
index d03a97a817..a1de9eb1b0 100644
--- a/content/changes/2012-12-06-create-authorization-for-app.html
+++ b/content/changes/2012-12-06-create-authorization-for-app.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Create an OAuth authorization for an app
-created_at: 2012-12-06
author_name: pengwynn
---
@@ -9,12 +7,12 @@
authorization using Basic Auth. Just POST your desired scopes and optional
note and you get a token back:
-
+``` command-line
+$ curl -u pengwynn -d '{"scopes": ["user", "gist"]}' \
+$ https://api.github.com/authorizations
+```
-This call creates a token for the authenticating user tied to a special "API"
+This call creates a token for the authenticated user tied to a special "API"
OAuth application.
We now support creating tokens for _your own OAuth application_ by passing your
@@ -22,14 +20,14 @@
the settings page for your OAuth application.
-
+``` command-line
+$ curl -u pengwynn -d '{ \
+$ "scopes": ["user", "gist"], \
+$ "client_id": "abcdeabcdeabcdeabcdeabcde" \
+$ "client_secret": "abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde" \
+$ }' \ '
+$ https://api.github.com/authorizations
+```
No more implementing the [web flow][web-flow] just to get a token tied to your
app's rate limit.
diff --git a/content/changes/2012-12-08-finding-source-and-fork-repos-for-organizations.html b/content/changes/2012-12-08-finding-source-and-fork-repos-for-organizations.html
index d7bf6aec6c..bd9f91bedf 100644
--- a/content/changes/2012-12-08-finding-source-and-fork-repos-for-organizations.html
+++ b/content/changes/2012-12-08-finding-source-and-fork-repos-for-organizations.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Finding sources and fork repositories for organizations
-created_at: 2012-12-08
author_name: rick
---
@@ -11,13 +9,14 @@
which are forks of another repository, as well as those repositories which
are sources (not forks).
- # Grab all fork Repositories for an Organization
- curl "https://api.github.com/orgs/:org/repos?type=forks"
+``` command-line
+# Grab all fork Repositories for an Organization
+$ curl "https://api.github.com/orgs/:org/repos?type=forks"
- # Grab all source Repositories for an Organization
- curl "https://api.github.com/orgs/:org/repos?type=sources"
+# Grab all source Repositories for an Organization
+$ curl "https://api.github.com/orgs/:org/repos?type=sources"
+```
Check out the docs for sorting and filtering options:
* [Organization Repositories](/v3/repos/#list-organization-repositories)
-
diff --git a/content/changes/2012-12-09-organization-repositories-results-now-paginate.html b/content/changes/2012-12-09-organization-repositories-results-now-paginate.html
index d58a557520..530d13e2ef 100644
--- a/content/changes/2012-12-09-organization-repositories-results-now-paginate.html
+++ b/content/changes/2012-12-09-organization-repositories-results-now-paginate.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Pagination for Organization Repository lists now paginates properly
-created_at: 2012-12-09
author_name: rick
---
diff --git a/content/changes/2012-12-10-Diff-and-patch-media-types.html b/content/changes/2012-12-10-Diff-and-patch-media-types.html
index 5345c9466f..96eb82a02a 100644
--- a/content/changes/2012-12-10-Diff-and-patch-media-types.html
+++ b/content/changes/2012-12-10-Diff-and-patch-media-types.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Diff and patch media types
-created_at: 2012-12-10
author_name: pengwynn
---
@@ -13,22 +11,23 @@
Simply use the same resource URL and send either `application/vnd.github.diff` or `application/vnd.github.patch` in the `Accept` header:
- curl -H "Accept: application/vnd.github.diff" https://api.github.com/repos/pengwynn/dotfiles/commits/aee60a4cd56fb4c6a50e60f17096fc40c0d4d72c
+``` command-line
+$ curl -H "Accept: application/vnd.github.diff" $ https://api.github.com/repos/pengwynn/dotfiles/commits/aee60a4cd56fb4c6a50e60f17096fc40c0d4d72c
- diff --git a/tmux/tmux.conf.symlink b/tmux/tmux.conf.symlink
- index 1f599cb..abaf625 100755
- --- a/tmux/tmux.conf.symlink
- +++ b/tmux/tmux.conf.symlink
- @@ -111,6 +111,7 @@ set-option -g base-index 1
- ## enable mouse
- set-option -g mouse-select-pane on
- set-option -g mouse-select-window on
- +set-option -g mouse-resize-pane on
- set-window-option -g mode-keys vi
- set-window-option -g mode-mouse on
- # set-window-option -g monitor-activity off
+> diff --git a/tmux/tmux.conf.symlink b/tmux/tmux.conf.symlink
+> index 1f599cb..abaf625 100755
+> --- a/tmux/tmux.conf.symlink
+> +++ b/tmux/tmux.conf.symlink
+> @@ -111,6 +111,7 @@ set-option -g base-index 1
+> ## enable mouse
+> set-option -g mouse-select-pane on
+> set-option -g mouse-select-window on
+> +set-option -g mouse-resize-pane on
+> set-window-option -g mode-keys vi
+> set-window-option -g mode-mouse on
+> # set-window-option -g monitor-activity off
+```
[commits-get]: /v3/repos/commits/#get-a-single-commit
[commits-compare]: /v3/repos/commits/#compare-two-commits
[pulls]: /v3/pulls/#get-a-single-pull-request
-
diff --git a/content/changes/2013-01-08-new-user-scopes.html b/content/changes/2013-01-08-new-user-scopes.html
index c0e3aeae7f..ecd48a14db 100644
--- a/content/changes/2013-01-08-new-user-scopes.html
+++ b/content/changes/2013-01-08-new-user-scopes.html
@@ -1,7 +1,5 @@
---
-kind: change
title: New User scopes
-created_at: 2013-01-08
author_name: technoweenie
---
diff --git a/content/changes/2013-01-31-user-agent-will-soon-be-mandatory.html b/content/changes/2013-01-31-user-agent-will-soon-be-mandatory.html
index 2407d3a97d..3c06f81381 100644
--- a/content/changes/2013-01-31-user-agent-will-soon-be-mandatory.html
+++ b/content/changes/2013-01-31-user-agent-will-soon-be-mandatory.html
@@ -1,13 +1,11 @@
---
-kind: change
title: User Agent mandatory from March 4th 2013
-created_at: 2013-01-31
author_name: agh
---
Following on from our [previous post](http://developer.github.com/changes/2012-10-14-rate-limit-changes/)
about requiring requests to include a valid [User Agent header](http://en.wikipedia.org/wiki/User_agent)
-we will soon be changing our API servers to return HTTP 403
+we will soon be changing our API servers to return HTTP 403
to any clients not providing a valid User Agent header.
We will be making this change on Monday, March 4th 2013.
diff --git a/content/changes/2013-2-5-changes-to-services.html b/content/changes/2013-02-05-changes-to-services.html
similarity index 85%
rename from content/changes/2013-2-5-changes-to-services.html
rename to content/changes/2013-02-05-changes-to-services.html
index ba86cb0243..4ff6d6e8cd 100644
--- a/content/changes/2013-2-5-changes-to-services.html
+++ b/content/changes/2013-02-05-changes-to-services.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Upcoming Changes to GitHub Services
-created_at: 2013-2-5
author_name: technoweenie
---
@@ -30,5 +28,5 @@
core Services backend for everyone. Maintaining custom logic and libraries for
over 100 services is taking too much of this focus away.
-[codeclimate]: https://github.com/github/github-services/blob/master/lib/services/codeclimate.rb
-[cf]: https://github.com/github/github-services/blob/master/lib/services/campfire.rb
+[codeclimate]: https://github.com/github/github-services/blob/fbc0db24b8b7685b2058462181d928a5f2a0a448/lib/services/codeclimate.rb
+[cf]: https://github.com/github/github-services/blob/fbc0db24b8b7685b2058462181d928a5f2a0a448/lib/services/campfire.rb
diff --git a/content/changes/2013-2-13-hookshot-issues.html b/content/changes/2013-02-13-hookshot-issues.html
similarity index 93%
rename from content/changes/2013-2-13-hookshot-issues.html
rename to content/changes/2013-02-13-hookshot-issues.html
index 6141df4757..7e69bc2ada 100644
--- a/content/changes/2013-2-13-hookshot-issues.html
+++ b/content/changes/2013-02-13-hookshot-issues.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Some Hookshot Issues
-created_at: 2013-2-13T11:00:00
author_name: technoweenie
---
@@ -17,4 +15,3 @@
We're currently working on solving this problem. Hit up [support@github.com](mailto:support@github.com)
if you have any questions.
-
diff --git a/content/changes/2013-2-13-hookshot-load-balancer.html b/content/changes/2013-02-13-hookshot-load-balancer.html
similarity index 91%
rename from content/changes/2013-2-13-hookshot-load-balancer.html
rename to content/changes/2013-02-13-hookshot-load-balancer.html
index 6e605af7e4..fd6b3114cd 100644
--- a/content/changes/2013-2-13-hookshot-load-balancer.html
+++ b/content/changes/2013-02-13-hookshot-load-balancer.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Hookshot Load balancer
-created_at: 2013-2-13T12:00:00
author_name: technoweenie
---
diff --git a/content/changes/2013-2-13-sortable-stars.html b/content/changes/2013-02-14-sortable-stars.html
similarity index 73%
rename from content/changes/2013-2-13-sortable-stars.html
rename to content/changes/2013-02-14-sortable-stars.html
index fbaf50dab0..d7b253b919 100644
--- a/content/changes/2013-2-13-sortable-stars.html
+++ b/content/changes/2013-02-14-sortable-stars.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Sortable Stars in Repository Starring API
-created_at: 2013-2-14
author_name: pengwynn
---
@@ -9,9 +7,9 @@
Repository Starring API now supports [two new parameters][params] when listing
Stars: `sort` and `direction`.
-
+``` command-line
+$ curl https://api.github.com/users/defunkt/starred?sort=created&direction=asc
+```
Enjoy.
diff --git a/content/changes/2013-3-1-new-hookshot-coming.html b/content/changes/2013-03-01-new-hookshot-coming.html
similarity index 96%
rename from content/changes/2013-3-1-new-hookshot-coming.html
rename to content/changes/2013-03-01-new-hookshot-coming.html
index b0ede13721..c109a40653 100644
--- a/content/changes/2013-3-1-new-hookshot-coming.html
+++ b/content/changes/2013-03-01-new-hookshot-coming.html
@@ -1,7 +1,5 @@
---
-kind: change
title: New Hookshot Changes
-created_at: 2013-3-1
author_name: technoweenie
---
@@ -22,4 +20,3 @@
This also means we should be able to start accepting [GitHub Services pull
requests](https://github.com/github/github-services/pulls) very soon :)
-
diff --git a/content/changes/2013-04-24-user-agent-required.html b/content/changes/2013-04-24-user-agent-required.html
index 292d14c5a1..b1fae21ff0 100644
--- a/content/changes/2013-04-24-user-agent-required.html
+++ b/content/changes/2013-04-24-user-agent-required.html
@@ -1,7 +1,5 @@
---
-kind: change
title: User Agent now mandatory
-created_at: 2013-04-24
author_name: pengwynn
---
diff --git a/content/changes/2013-04-25-deprecating-merge-commit-sha.html b/content/changes/2013-04-25-deprecating-merge-commit-sha.html
index 54a024593b..8bff84e414 100644
--- a/content/changes/2013-04-25-deprecating-merge-commit-sha.html
+++ b/content/changes/2013-04-25-deprecating-merge-commit-sha.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Deprecating a Confusing Attribute in the Pull Request API
-created_at: 2013-04-25
author_name: jasonrudolph
---
@@ -13,7 +11,7 @@
confusion.
To help current API consumers, we've [documented the
-attribute](/v3/pulls/#mergability) for improved understanding.
+attribute](/v3/pulls/#get-a-single-pull-request) for improved understanding.
To protect future API consumers from this confusion, we have
[deprecated](/v3/versions/#v3-deprecations) the `merge_commit_sha` attribute, and we will
diff --git a/content/changes/2013-04-30-improved-submodule-support-in-repository-contents-api.md b/content/changes/2013-04-30-improved-submodule-support-in-repository-contents-api.md
index fcd99765f1..8b7598e783 100644
--- a/content/changes/2013-04-30-improved-submodule-support-in-repository-contents-api.md
+++ b/content/changes/2013-04-30-improved-submodule-support-in-repository-contents-api.md
@@ -1,39 +1,37 @@
---
-kind: change
title: Improved Support for Submodules in the Repository Contents API
-created_at: 2013-04-30
author_name: jasonrudolph
---
When you view a repository with a submodule on github.com, you get useful links and information for the submodule.
-[][screenshot]
+[][screenshot]
Today we're making that data available in the [Repository Contents API][docs].
-
+> {
+> "name": "qunit",
+> "path": "test/qunit",
+> "type": "submodule",
+> "submodule_git_url": "git://github.com/jquery/qunit.git",
+> "sha": "6ca3721222109997540bd6d9ccd396902e0ad2f9",
+> "size": 0,
+> "url": "https://api.github.com/repos/jquery/jquery/contents/test/qunit?ref=master",
+> "git_url": "https://api.github.com/repos/jquery/qunit/git/trees/6ca3721222109997540bd6d9ccd396902e0ad2f9",
+> "html_url": "https://github.com/jquery/qunit/tree/6ca3721222109997540bd6d9ccd396902e0ad2f9",
+> "_links": {
+> "self": "https://api.github.com/repos/jquery/jquery/contents/test/qunit?ref=master",
+> "git": "https://api.github.com/repos/jquery/qunit/git/trees/6ca3721222109997540bd6d9ccd396902e0ad2f9",
+> "html": "https://github.com/jquery/qunit/tree/6ca3721222109997540bd6d9ccd396902e0ad2f9"
+> }
+> }
+```
If you have any questions or feedback, please drop us a line at
[support@github.com](mailto:support@github.com?subject=Submodules in Repository Contents API).
[docs]: /v3/repos/contents/#get-contents
-[screenshot]: /images/posts/submodule-links.png
+[screenshot]: /assets/images/posts/submodule-links.png
diff --git a/content/changes/2013-04-30-statuses-for-branches-and-tags.md b/content/changes/2013-04-30-statuses-for-branches-and-tags.md
index d35724dcd6..b42aafdb81 100644
--- a/content/changes/2013-04-30-statuses-for-branches-and-tags.md
+++ b/content/changes/2013-04-30-statuses-for-branches-and-tags.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Commit Statuses Now Available for Branches and Tags
-created_at: 2013-04-30
author_name: foca
---
@@ -9,9 +7,9 @@ Last week we announced [support for build statuses in the branches page][blog].
Now we are extending this to the API. The [API endpoint for commit statuses][doc]
has been extended to allow branch and tag names, as well as commit SHAs.
-
+``` command-line
+$ curl -u defunkt https://api.github.com/feeds
+
+> {
+> "timeline_url": "https://github.com/timeline",
+> "user_url": "https://github.com/{user}",
+> "current_user_public_url": "https://github.com/defunkt",
+> "current_user_url": "https://github.com/defunkt.private?token=abc123",
+> "current_user_actor_url": "https://github.com/defunkt.private.actor?token=abc123",
+> "current_user_organization_url": "https://github.com/organizations/{org}/defunkt.private.atom?token=abc123",
+> "_links": {
+> "timeline": {
+> "href": "https://github.com/timeline",
+> "type": "application/atom+xml"
+> },
+> "user": {
+> "href": "https://github.com/{user}",
+> "type": "application/atom+xml"
+> },
+> "current_user_public": {
+> "href": "https://github.com/defunkt",
+> "type": "application/atom+xml"
+> },
+> "current_user": {
+> "href": "https://github.com/defunkt.private?token=abc123",
+> "type": "application/atom+xml"
+> },
+> "current_user_actor": {
+> "href": "https://github.com/defunkt.private.actor?token=abc123",
+> "type": "application/atom+xml"
+> },
+> "current_user_organization": {
+> "href": "https://github.com/organizations/{org}/defunkt.private.atom?token=abc123",
+> "type": "application/atom+xml"
+> }
+> }
+> }
+```
If you have any questions or feedback, [please drop us a line][contact].
diff --git a/content/changes/2013-07-02-rate-limit-reset.md b/content/changes/2013-07-02-rate-limit-reset.md
index ab19eed93e..5106f7412b 100644
--- a/content/changes/2013-07-02-rate-limit-reset.md
+++ b/content/changes/2013-07-02-rate-limit-reset.md
@@ -1,39 +1,37 @@
---
-kind: change
title: When Does My Rate Limit Reset?
-created_at: 2013-07-02
author_name: jasonrudolph
---
Have you ever wondered when your [rate limit][rate-limit-docs] will reset back to its maximum value?
That information is now available in the new `X-RateLimit-Reset` response header.
-
+``` command-line
$ curl -I https://api.github.com/orgs/octokit
-HTTP/1.1 200 OK
-Status: 200 OK
-X-RateLimit-Limit: 60
-X-RateLimit-Remaining: 42
-X-RateLimit-Reset: 1372700873
-...
-
+> HTTP/1.1 200 OK
+> Status: 200 OK
+> X-RateLimit-Limit: 60
+> X-RateLimit-Remaining: 42
+> X-RateLimit-Reset: 1372700873
+> ...
+```
The `X-RateLimit-Reset` header provides a [Unix UTC timestamp][unix-time], letting you know the exact time that your fresh new rate limit kicks in.
The reset timestamp is also available as part of the `/rate_limit` resource.
-
+> {
+> "rate": {
+> "limit": 60,
+> "remaining": 42,
+> "reset": 1372700873
+> }
+> }
+```
For more information on rate limits, be sure to check out the [docs][rate-limit-docs].
diff --git a/content/changes/2013-07-19-preview-the-new-search-api.md b/content/changes/2013-07-19-preview-the-new-search-api.md
index 736b4a28b6..370a1440c2 100644
--- a/content/changes/2013-07-19-preview-the-new-search-api.md
+++ b/content/changes/2013-07-19-preview-the-new-search-api.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Preview the New Search API
-created_at: 2013-07-19
author_name: jasonrudolph
---
diff --git a/content/changes/2013-08-20-search-api-improvements.md b/content/changes/2013-08-20-search-api-improvements.md
index 230de12678..1ab04d2b9e 100644
--- a/content/changes/2013-08-20-search-api-improvements.md
+++ b/content/changes/2013-08-20-search-api-improvements.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Improvements to the Search API
-created_at: 2013-08-20
author_name: jasonrudolph
---
@@ -14,54 +12,51 @@ Now, you can also [get this metadata][code-text-matches] for matches that occur
For example, when [searching for files that have "client" in their path][example-path-search], the results include this match for `lib/octokit/client/commits.rb`:
-
## Better Text Match Metadata
Before today, the API applied HTML entity encoding to all `fragment` data.
-For example, imagine your search returns an issue like [rails/rails#11889][example-issue]:
+For example, imagine your search returns an issue like rails/rails#11889:

The response would include a `text_matches` array with the following object:
-
+{:.json}
+ {
+ "fragment": "undefined method 'except' for #<Array:XXX>",
+ // ...
+ }
Inside the `fragment` value, we see HTML-encoded entities (e.g., `<`).
Since we're returning JSON (not HTML), API clients might not expect any HTML-encoded text.
As of today, the API returns these fragments _without_ this extraneous encoding.
-
+{:.json}
+ {
+ "fragment": "undefined method 'except' for #",
+ // ...
+ }
## Preview Period
@@ -70,7 +65,6 @@ We appreciate everyone that has provided feedback so far. Please [keep it coming
[contact]: https://github.com/contact?form[subject]=New+Search+API
[code-text-matches]: /v3/search/#highlighting-code-search-results
-[example-issue]: https://github.com/rails/rails/issues/11889
[example-path-search]: https://github.com/search?q=%40octokit%2Foctokit.rb+in%3Apath+client&type=Code
[original-search-api-announcement]: /changes/2013-07-19-preview-the-new-search-api/
[preview-period]: /changes/2013-07-19-preview-the-new-search-api/#preview-period
diff --git a/content/changes/2013-09-03-two-factor-authentication.md b/content/changes/2013-09-03-two-factor-authentication.md
index 4c5fc5d364..0b999da9a9 100644
--- a/content/changes/2013-09-03-two-factor-authentication.md
+++ b/content/changes/2013-09-03-two-factor-authentication.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Two-Factor Authentication and the API
-created_at: 2013-09-03
author_name: mastahyeti
---
@@ -26,8 +24,8 @@ providing multiple options to make the flow simple and easy.
### Personal Access Tokens
Personal access tokens provide the simplest option for using 2FA with Basic
-Authentication. You can create these tokens via the [application settings page
-on GitHub.com](https://github.com/settings/applications), and you can revoke
+Authentication. You can create these tokens via the [tokens settings page
+on GitHub.com](https://github.com/settings/tokens), and you can revoke
them at any time. For more information about authenticating to the API with
personal access tokens, be sure to check out our [help article on the
topic][personal-access-tokens].
diff --git a/content/changes/2013-09-25-releases-api.md b/content/changes/2013-09-25-releases-api.md
index e7a1ab9067..7185d32cb5 100644
--- a/content/changes/2013-09-25-releases-api.md
+++ b/content/changes/2013-09-25-releases-api.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Releases API
-created_at: 2013-09-25
author_name: technoweenie
---
@@ -11,38 +9,38 @@ This summer we made it easier to [release your software][blawg]. Today, you can
This API is a little different due to the binary assets. We use the `Accept` header for content negotiation when requesting
a release asset. Pass a standard API media type to get the API representation:
-
+```
## Preview mode
diff --git a/content/changes/2013-09-28-an-update-on-the-new-search-api.md b/content/changes/2013-09-28-an-update-on-the-new-search-api.md
index 2212fdff16..fbdf1623d8 100644
--- a/content/changes/2013-09-28-an-update-on-the-new-search-api.md
+++ b/content/changes/2013-09-28-an-update-on-the-new-search-api.md
@@ -1,7 +1,5 @@
---
-kind: change
title: An Update on the New Search API
-created_at: 2013-09-28
author_name: jasonrudolph
---
diff --git a/content/changes/2013-10-04-oauth-changes-coming.html b/content/changes/2013-10-04-oauth-changes-coming.html
index 842175a2d7..a81fbc7c99 100644
--- a/content/changes/2013-10-04-oauth-changes-coming.html
+++ b/content/changes/2013-10-04-oauth-changes-coming.html
@@ -1,22 +1,20 @@
---
-kind: change
title: OAuth changes coming
-created_at: 2013-10-04
author_name: tclem
---
Starting today, we are returning granted scopes as part of the
-[access_token response](/v3/oauth/#github-redirects-back-to-your-site).
+[access_token response](/v3/oauth/#2-github-redirects-back-to-your-site).
For example, if you are making a POST with the `application/json`
mime-type you'll see an additional field for the granted scopes.
-
+```
Right now, these scopes will be identical to what you requested, but we
are moving towards a feature set that will allow GitHub users to edit
diff --git a/content/changes/2013-10-08-list-all-user-teams.html b/content/changes/2013-10-08-list-all-user-teams.html
index e604a6eeee..1989d9ea81 100644
--- a/content/changes/2013-10-08-list-all-user-teams.html
+++ b/content/changes/2013-10-08-list-all-user-teams.html
@@ -1,41 +1,39 @@
---
-kind: change
title: List all teams for the authenticated user
-created_at: 2013-10-08
author_name: pengwynn
---
We just added a [new API method](/v3/orgs/teams/#list-user-teams) to list all
the teams for the authenticated user across all organizations:
-
+```
Happy querying. If you have any questions or feedback [get in touch][contact].
diff --git a/content/changes/2014-03-03-deployments-api-updates.md b/content/changes/2014-03-03-deployments-api-updates.md
index 7946aa1d7f..bf6198beb4 100644
--- a/content/changes/2014-03-03-deployments-api-updates.md
+++ b/content/changes/2014-03-03-deployments-api-updates.md
@@ -1,11 +1,9 @@
---
-kind: change
title: New Payload Format for Deployments
-created_at: 2014-03-03
author_name: atmos
---
-As we [iterate on the preview][january-deployment-api-post] for the new Deployment API, we're making sure that it's friendly to work with for the apps built on top of it.
+As we [iterate on the preview][january-deployment-api-post] for the new Deployments API, we're making sure that it's friendly to work with for the apps built on top of it.
## Deserialize Deployment Payloads
diff --git a/content/changes/2014-03-04-timezone-handling-changes.html b/content/changes/2014-03-04-timezone-handling-changes.html
index 8642f0c46c..2f8e862653 100644
--- a/content/changes/2014-03-04-timezone-handling-changes.html
+++ b/content/changes/2014-03-04-timezone-handling-changes.html
@@ -1,7 +1,5 @@
---
-kind: change
title: Improved timezone handling in the API
-created_at: 2014-03-04
author_name: dbussink
---
@@ -30,7 +28,9 @@
It is possible to supply a `Time-Zone` header which defines a timezone according
to the [list of names from the Olson database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- $ curl -H "Time-Zone: Europe/Amsterdam" -X POST https://api.github.com/repos/github/linguist/contents/new_file.md
+``` command-line
+$ curl -H "Time-Zone: Europe/Amsterdam" -X POST https://api.github.com/repos/github/linguist/contents/new_file.md
+```
This means that we generate a timestamp for the moment your API call is made in
the timezone this header defines. For example, the [Contents API](/v3/repos/contents/)
diff --git a/content/changes/2014-03-05-reminder-about-upcoming-cutover-test.md b/content/changes/2014-03-05-reminder-about-upcoming-cutover-test.md
index e19dd70b96..3a6aabfff0 100644
--- a/content/changes/2014-03-05-reminder-about-upcoming-cutover-test.md
+++ b/content/changes/2014-03-05-reminder-about-upcoming-cutover-test.md
@@ -1,7 +1,5 @@
---
-kind: change
title: "Reminder: March 12 Cutover Test for Default Media Type"
-created_at: 2014-03-05
author_name: jasonrudolph
---
diff --git a/content/changes/2014-03-12-page-build-event-for-webhooks.md b/content/changes/2014-03-12-page-build-event-for-webhooks.md
index bdc50b2a1c..64e19a83c8 100644
--- a/content/changes/2014-03-12-page-build-event-for-webhooks.md
+++ b/content/changes/2014-03-12-page-build-event-for-webhooks.md
@@ -1,7 +1,5 @@
---
-kind: change
title: Page Build Event for Webhooks
-created_at: 2014-3-12
author_name: benbalter
---
diff --git a/content/changes/2014-03-18-paginating-method-changes.md b/content/changes/2014-03-18-paginating-method-changes.md
new file mode 100644
index 0000000000..9cba74b8db
--- /dev/null
+++ b/content/changes/2014-03-18-paginating-method-changes.md
@@ -0,0 +1,128 @@
+---
+title: Pagination changes for some resource lists
+author_name: pengwynn
+---
+
+In an effort to keep the API fast for everyone, we're enabling
+[pagination][paginating] on some API methods that previously did not support it.
+Beginning today, the methods below will paginate if you include `page` or
+`per_page` query parameters. Starting April 17th, 2014, these methods will
+_always_ return [paginated results][paginating]. If you have any questions or
+run into trouble, feel free to [get in touch][contact].
+
+Here's the complete list of updated methods:
+
+#### [Gist comments][]
+
+ GET /gists/:gist_id/comments
+
+#### [Gist commits][]
+
+ GET /gists/:gist_id/commits
+
+#### [Gist forks][]
+
+ GET /gists/:gist_id/forks
+
+#### [Git refs][]
+
+ GET /repos/:owner/:repo/git/refs
+
+#### [Issue labels][]
+
+ GET /repos/:owner/:repo/issues/:number/labels
+
+#### [Milestone labels][]
+
+ GET /repos/:owner/:repo/milestones/:id/labels
+
+#### [Organization teams][]
+
+ GET /orgs/:org/teams
+
+#### [Pull Request commits][]
+
+ GET /repos/:owner/:repo/pulls/:number/commits
+
+#### [Pull Request files][]
+
+ GET /repos/:owner/:repo/pulls/:number/files
+
+#### [Release assets][]
+
+ GET /repos/:owner/:repo/releases/:id/assets
+
+#### [Repository collaborators][]
+
+ GET /repos/:owner/:repo/collaborators
+
+#### [Repository contributors][]
+
+ GET /repos/:owner/:repo/contributors
+
+#### [Repository branches][]
+
+ GET /repos/:owner/:repo/branches
+
+#### [Repository downloads][]
+
+ GET /repos/:owner/:repo/downloads
+
+#### [Repository keys][]
+
+ GET /repos/:owner/:repo/keys
+
+#### [Repository labels][]
+
+ GET /repos/:owner/:repo/labels
+
+#### [Repository tags][]
+
+ GET /repos/:owner/:repo/tags
+
+#### [Repository teams][]
+
+ GET /repos/:owner/:repo/teams
+
+#### [Team members][]
+
+ GET /teams/:id/members
+
+#### [Team repositories][]
+
+ GET /teams/:id/repos
+
+#### [User emails][] (v3 media type only)
+
+ GET /user/emails
+
+#### [User keys][]
+
+ GET /users/:user/keys
+ GET /user/keys
+
+[Gist comments]: /v3/gists/comments/#list-comments-on-a-gist
+[Gist commits]: /v3/gists/#list-gist-commits
+[Gist forks]: /v3/gists/#list-gist-forks
+[Git refs]: /v3/git/refs/#get-all-references
+[Repository collaborators]: /v3/repos/collaborators/#list-collaborators
+[Repository downloads]: /v3/repos/downloads/#list-downloads-for-a-repository
+[Repository keys]: /v3/repos/keys/#list-deploy-keys
+[Repository labels]: /v3/issues/labels/#list-all-labels-for-this-repository
+[Team repositories]: /v3/orgs/teams/#list-team-repos
+[User emails]: /v3/users/emails/#list-email-addresses-for-a-user
+[User keys]: /v3/users/keys/#list-public-keys-for-a-user
+[Issue labels]:/v3/issues/labels/#list-labels-on-an-issue
+[Milestone labels]: /v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
+[Organization teams]: /v3/orgs/teams/#list-teams
+[Pull Request commits]: /v3/pulls/#list-commits-on-a-pull-request
+[Pull Request files]: /v3/pulls/#list-pull-requests-files
+[Release assets]: /v3/repos/releases/#list-assets-for-a-release
+[Repository contributors]: /v3/repos/#list-contributors
+[Repository branches]: /v3/repos/branches/#list-branches
+[Repository tags]: /v3/repos/#list-tags
+[Repository teams]: /v3/repos/#list-teams
+[Team members]: /v3/orgs/teams/#list-team-members
+
+[paginating]: /v3/#pagination
+[contact]: https://github.com/contact?form[subject]=API+v3:+Pagination+changes
diff --git a/content/changes/2014-03-27-combined-status-api.md b/content/changes/2014-03-27-combined-status-api.md
new file mode 100644
index 0000000000..2edc34295a
--- /dev/null
+++ b/content/changes/2014-03-27-combined-status-api.md
@@ -0,0 +1,54 @@
+---
+title: Preview the New Combined Status API
+author_name: bhuga
+---
+
+What does it mean for a branch to be "green?" The [Status API][status-api] helps
+thousands of teams answer that question. Developers use it to record the status
+of continuous integration builds, contributor license agreements, code coverage
+analysis, automated security testing, dependency management, and more.
+
+For many teams, a branch is considered "green" only when _all_ of their various
+status checks are successful. With the new [Combined Status
+API][combined-status-api], developers can easily fetch this single, consolidated
+status for any branch, commit, or tag.
+
+### Status context
+
+To help multiple service providers use the Status API simultaneously, statuses
+now support a `context` field. This field allows a provider to distinguish its
+statuses from another provider's statuses. For example, your [Jenkins][] builds
+might use a context of `ci/jenkins`, while your [Brakeman][] checks might adopt a
+context of `security/brakeman`.
+
+The new [Combined Status endpoint][combined-status-api] returns a single,
+combined state, as well as the latest status from each context. Systems that
+consume status updates can now get all the information they need in one place.
+
+### Opt-in
+
+The existing [Status API][list-statuses] continues to work as it always has. The
+`context` field is entirely optional, and the [color of the merge button on pull
+requests](https://github.com/blog/1227-commit-status-api) does not currently
+take context into account.
+
+### Preview period
+
+We're making this new API available today for developers to
+[preview][status-api]. During this period, we may change aspects of the Combined
+Status API from time to time. We will announce any changes here (on the
+developer blog), but we will not provide any advance notice.
+
+We expect the preview period to last 30-60 days. At the end of preview period,
+the Combined Status API will become an official component of GitHub API v3. At
+that point, this new API will be stable and suitable for production use.
+
+We hope you'll [try it out][status-api] and [send us your feedback][contact]!
+
+[status-api]: /v3/repos/statuses/
+[contact]: https://github.com/contact?form[subject]=Combined+Status+API
+[combined-status-api]: /v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
+[create-a-status]: /v3/repos/statuses/#create-a-status
+[brakeman]: http://brakemanscanner.org/
+[jenkins]: http://jenkins-ci.org/
+[list-statuses]: /v3/repos/statuses/#list-statuses-for-a-specific-ref
diff --git a/content/changes/2014-04-04-create-public-repo-without-repo-scope.md b/content/changes/2014-04-04-create-public-repo-without-repo-scope.md
new file mode 100644
index 0000000000..1231f241a4
--- /dev/null
+++ b/content/changes/2014-04-04-create-public-repo-without-repo-scope.md
@@ -0,0 +1,15 @@
+---
+title: Grant access to create public repositories without granting access to private repositories
+author_name: pengwynn
+---
+
+The [Create Repository method][api] now allows creating public repositories via
+OAuth with `public_repo` [scope][]. This means you can safely grant third
+party applications the ability to create public repositories on your behalf
+without granting access to your private repositories.
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=API+create+repositories+with+public_repo+scope
+[api]: /v3/repos/#create
+[scope]: /v3/oauth/#scopes
diff --git a/content/changes/2014-04-07-understanding-search-results-and-potential-timeouts.md b/content/changes/2014-04-07-understanding-search-results-and-potential-timeouts.md
new file mode 100644
index 0000000000..07090d55c5
--- /dev/null
+++ b/content/changes/2014-04-07-understanding-search-results-and-potential-timeouts.md
@@ -0,0 +1,23 @@
+---
+title: Understanding search results and potential timeouts
+author_name: izuzak
+---
+
+Some queries are computationally expensive for our search infrastructure to
+execute. To keep the [Search API](/v3/search) fast for everyone, we limit how
+long any individual query can run. In rare situations when a query exceeds the
+time limit, the API returns all matches that were found prior to the timeout.
+
+Starting today, the Search API also now [informs you when such a timeout
+happens](/v3/search/#timeouts-and-incomplete-results). Reaching a timeout does
+not necessarily mean that search results are incomplete. It just means that the
+query was discontinued before it searched through all possible data. More
+results might have been found, but also might not.
+
+In some cases, if you know that your search results are potentially incomplete,
+you might think about the data differently. By exposing timeouts when they
+happen, the API helps you better understand how to interpret the results.
+
+We hope this is useful as you integrate with the Search API. In the meantime,
+we're working on improving search so that these timeouts occur as rarely as
+possible. If you have any questions, [let us know](https://github.com/contact?form%5Bsubject%5D=Search+API).
diff --git a/content/changes/2014-04-08-reset-api-tokens.md b/content/changes/2014-04-08-reset-api-tokens.md
new file mode 100644
index 0000000000..ed07db685f
--- /dev/null
+++ b/content/changes/2014-04-08-reset-api-tokens.md
@@ -0,0 +1,33 @@
+---
+title: "Recommendation: Reset OAuth authorizations"
+author_name: pengwynn
+---
+
+As [announced earlier today][heartbleed-blog-post], we are actively responding
+to the recently-disclosed [Heartbleed security
+vulnerability][heartbleed-blog-post] in OpenSSL. While at this time GitHub has
+no indication that the attack has been used beyond testing the vulnerability, we
+recommend that integrators [reset the API authorizations][api] for their OAuth
+applications.
+
+We've added a [new API method][api] for this exact purpose. Calling this method
+will invalidate the old token and return a new token for applications to store
+and use in its place. This new method provides a safe way to reset user
+authorizations without requiring users to re-authorize the application on the
+web.
+
+Integrators can also use the existing revocation methods to ~~revoke all
+tokens~~ or [revoke a single token][] for their applications.
+
+{{#tip}}
+
+**UPDATE (2016-01-25):** API v3 no longer provides a method to revoke all of an application's tokens as previously referenced above. If you need to revoke all tokens for your application, you can do so via the settings page for your application.
+
+{{/tip}}
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=API+resetting+tokens
+[api]: /v3/oauth_authorizations/#reset-an-authorization
+[revoke a single token]: /v3/oauth_authorizations/#revoke-an-authorization-for-an-application
+[heartbleed-blog-post]: https://github.com/blog/1818-security-heartbleed-vulnerability
diff --git a/content/changes/2014-04-09-reminder-about-default-media-type-change.md b/content/changes/2014-04-09-reminder-about-default-media-type-change.md
new file mode 100644
index 0000000000..ba70ed5456
--- /dev/null
+++ b/content/changes/2014-04-09-reminder-about-default-media-type-change.md
@@ -0,0 +1,14 @@
+---
+title: "Reminder: Default media type will change on April 15"
+author_name: jasonrudolph
+---
+
+Just a friendly reminder: On April 15, 2014, the GitHub API will start serving the v3 media type by default. Please see the [original announcement][2014-01-announcement] for full details about [this change][what's-changing], [who it affects][who-it-affects], and [how to ensure that you are prepared][prepare].
+
+If you have any questions, please [get in touch][contact].
+
+[2014-01-announcement]: /changes/2014-01-07-upcoming-change-to-default-media-type/
+[contact]: https://github.com/contact?form[subject]=Upcoming+change+to+default+API+media+type
+[what's-changing]: /changes/2014-01-07-upcoming-change-to-default-media-type/#whats-changing
+[who-it-affects]: /changes/2014-01-07-upcoming-change-to-default-media-type/#who-is-affected
+[prepare]: /changes/2014-01-07-upcoming-change-to-default-media-type/#what-should-you-do
diff --git a/content/changes/2014-04-10-deployment-api-preview-extension.md b/content/changes/2014-04-10-deployment-api-preview-extension.md
new file mode 100644
index 0000000000..2087c59656
--- /dev/null
+++ b/content/changes/2014-04-10-deployment-api-preview-extension.md
@@ -0,0 +1,13 @@
+---
+title: Extending the preview period for the Deployments API
+author_name: atmos
+---
+
+The preview period for the new [Deployments API][2014-01-deployments-api-post] continues to yield valuable feedback from developers. In early March, we used that feedback to [improve the payload format][payload-update] that integrations can use to customize deployments. A few weeks later, we began integrating with the new [Combined Status API][combined-statuses] to help ensure that only verified code gets deployed, even if you have multiple systems verifying different aspects of your software.
+
+To give developers time to explore these recent refinements to the Deployments API, we're extending the preview period for a little while longer. As always, if you have any questions or feedback, please [get in touch][contact].
+
+[2014-01-deployments-api-post]: /changes/2014-01-09-preview-the-new-deployments-api/
+[payload-update]: /changes/2014-03-03-deployments-api-updates/
+[combined-statuses]: /changes/2014-03-27-combined-status-api/
+[contact]: https://github.com/contact?form[subject]=Deployments+API
diff --git a/content/changes/2014-04-22-deprecating-beta-media-type.md b/content/changes/2014-04-22-deprecating-beta-media-type.md
new file mode 100644
index 0000000000..e212e5ae0e
--- /dev/null
+++ b/content/changes/2014-04-22-deprecating-beta-media-type.md
@@ -0,0 +1,15 @@
+---
+title: Deprecating the beta media type
+author_name: jasonrudolph
+---
+
+Now that the GitHub API is [serving the v3 media type by default][v3-default], we are deprecating the legacy [beta media type][beta].
+
+We will eventually remove support for the beta media type, but we have no official retirement date to announce at the moment. When the time comes, rest assured that we'll announce the retirement with plenty of notice. In the meantime, existing API clients that rely on the beta media type should start making plans to migrate to v3. The beta media type differs from v3 in [just a few places][differences]. In most cases, migrating an application from the beta media type to the v3 media type is smooth and painless.
+
+As always, if you have any questions, please [get in touch][contact].
+
+[v3-default]: /changes/2014-01-07-upcoming-change-to-default-media-type/
+[beta]: /v3/versions/#beta
+[differences]: /v3/versions/#differences-from-beta-version
+[contact]: https://github.com/contact?form[subject]=API:+Deprecating+the+beta+media+type
diff --git a/content/changes/2014-04-25-user-content-security.md b/content/changes/2014-04-25-user-content-security.md
new file mode 100644
index 0000000000..f1faba04eb
--- /dev/null
+++ b/content/changes/2014-04-25-user-content-security.md
@@ -0,0 +1,35 @@
+---
+title: New user content domains
+author_name: azizshamim
+---
+
+## Securing your content
+
+The [GitHub Bug Bounty program](https://bounty.github.com) recently identified a few cross-domain vulnerabilities related to user-generated content, and we've shipped improvements today to address those issues.
+
+In order to better isolate your content from potentially malicious content uploaded by other users (e.g., content that might contain Cross-Site Scripting or other embedded attacks), we now serve user-generated content from subdomains of **githubusercontent.com**. This content is no longer served from subdomains of **github.com**.
+
+## What's affected?
+
+This change affects the following subdomains:
+
+* **raw.github.com** : Serves raw file content from your repository.
+* **embed.github.com** : Allows users to embed rich GitHub content on other sites.
+* **render.github.com** : Displays rich content on GitHub.com.
+* **f.cloud.github.com** : Hosts all those amazing gifs you use in Pull Requests and Issues.
+
+Content formerly served by these subdomains is now served from subdomains of **githubusercontent.com**.
+
+## Older links
+
+If you have old links to this content, don't worry: as of today, we're forcing the old domains to redirect to the new domains. Your existing links should continue to work automatically in your browser. If you're using a URL from Gist or GitHub to directly access user-generated content via `curl`, `wget`, or a library (like [HTTParty](https://github.com/jnunemaker/httparty)), be sure to configure that tool to follow the redirect.
+
+## Your proxies or filters
+
+Some security systems (web proxies, for example) may not recognize the **githubusercontent.com** domain. In those cases, you may need update your proxies and security software accordingly.
+
+As always, if you have any questions, please [get in touch][contact].
+
+*Happy and safe GitHubbing!*
+
+[contact]: https://github.com/contact?form[subject]=Changes+to+user+content+domains
diff --git a/content/changes/2014-05-06-gist-api-now-truncating-large-files.md b/content/changes/2014-05-06-gist-api-now-truncating-large-files.md
new file mode 100644
index 0000000000..9b1fa4c26c
--- /dev/null
+++ b/content/changes/2014-05-06-gist-api-now-truncating-large-files.md
@@ -0,0 +1,38 @@
+---
+title: "Changes to Gist API response for large files"
+author_name: leongersing
+---
+
+In order to provide a faster, more robust API for Gist, we are making two changes to better handle large files in [Gist API responses][gist-json-representation].
+
+### Truncating file contents larger than one megabyte
+
+The [Gist API response][gist-json-representation] includes data for every file in the Gist. That works well for Gists with reasonably-sized files. When a Gist contains large files, however, it can lead to timeouts when preparing or sending the API response.
+
+To eliminate those timeouts, the API now limits the amount of content returned for each file. If a file is larger than one megabyte in size, the API response will include the first megabyte of content for that file. (Few Gists have files this large. As a result, most API clients won't notice any impact from this change.)
+
+### New "truncated" attribute
+
+The JSON snippet below illustrates the attributes provided for each file in the Gist API response. In it, you'll notice a new `truncated` attribute included as part of the file metadata. This Boolean attribute indicates whether the `content` value is truncated for this request.
+
+ {
+ files: {
+ "my_large_file.md": {
+ "size": 2097152,
+ "content": "Large content. Truncated at end of first megabyte. [...]",
+ "truncated": true,
+ "raw_url": "https://raw.githubusercontent.com/[...]/my_large_file.md",
+ "type": "text/plain",
+ "language": "Markdown"
+ }
+ }
+ }
+
+### Getting the full content for truncated files
+
+We recognize that sometimes you'll still want the full content for a file, even if it's too large to get returned in the standard Gist API response. For files under 10 megabytes, simply make a request to the URL specified in the `raw_url` attribute, and you'll receive the complete content for that file. For larger files, you'll need to clone the gist locally via the ```git_pull_url``` to access the full file contents.
+
+If you have any questions, don’t hesitate to [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=Gist+API+now+truncates+large+files
+[gist-json-representation]: /v3/gists/#detailed-gist-representation
diff --git a/content/changes/2014-05-09-improved-pagination-for-the-repository-commits-api.md b/content/changes/2014-05-09-improved-pagination-for-the-repository-commits-api.md
new file mode 100644
index 0000000000..b6d535ad9b
--- /dev/null
+++ b/content/changes/2014-05-09-improved-pagination-for-the-repository-commits-api.md
@@ -0,0 +1,16 @@
+---
+title: Improved pagination for the Repository Commits API
+author_name: izuzak
+---
+
+The [Repository Commits API](/v3/repos/commits/) now supports an additional approach for paginating [commit lists](/v3/repos/commits/#list-commits-on-a-repository). As of today, this endpoint supports the "standard" [`page` and `per_page` parameters](/v3/#pagination) for controlling pagination. This API now uses these parameters by default when constructing [page links](/v3/#pagination).
+
+## Improved results and increased consistency
+
+This new approach improves the reliability of this endpoint, which on rare occasions skipped some commits during pagination. This enhancement also increases the overall consistency of the API, as all endpoints now paginate resource lists the same way.
+
+## Old parameters still supported
+
+The old way of paginating, using `top`, `last_sha`, and `per_page` parameters, is still supported in API v3, but it will be removed in the [next major version of the API](https://developer.github.com/v3/versions/#v3-deprecations). API clients that are manually constructing URLs for pages should be modified to use the new parameters. Even better, API clients shouldn't construct URLs for pages manually, but should use [page links provided by the `Link` header](/guides/traversing-with-pagination/) in API responses.
+
+Since both the new and the old pagination parameters are still supported in API v3, API clients shouldn't notice any changes today. Still, if you notice any problems with this endpoint, please [let us know](https://github.com/contact?form%5Bsubject%5D=API:+Commits+pagination+improvements).
diff --git a/content/changes/2014-05-19-deployments-api-updates.md b/content/changes/2014-05-19-deployments-api-updates.md
new file mode 100644
index 0000000000..8343de77c2
--- /dev/null
+++ b/content/changes/2014-05-19-deployments-api-updates.md
@@ -0,0 +1,94 @@
+---
+title: New attributes for the Deployments API
+author_name: atmos
+---
+
+We're continuing to iterate on the [Deployments API preview][deployments-preview], and we're starting to see it satisfy more and more use cases. Today we're introducing new attributes for Deployments and Deployment Statuses as well as a few payload changes.
+
+**This is a breaking change for Deployment Status payloads**. If you're trying out this new API during its preview period, you'll need to update your code to continue working with it.
+
+## API Changes
+
+For Deployments we're introducing the concept of an `environment`. An environment is basically a unique identifier for a deployment target. Lots of people tend toward the concept of environments for staging, QA, user acceptance testing, etc. We hope this enhancement will enable more use cases for our users that deploy to multiple environments.
+
+Deployments are also persisting the requested deployment `ref`. Previously we resolved a ref to the current SHA for that ref. Now we'll be keeping the ref around for historical purposes. This is especially helpful if you're deploying branches to verify them before you merge them into your default branch (e.g., "master").
+
+## JSON Payload Changes
+
+We're also adding a few attributes to the outbound Deployment payloads. We're now including the `ref` attribute so you know the branch or tag name that resolved to a specific SHA. The `environment` is also present.
+
+## Webhook Changes
+
+The Deployment Status payloads now embed the associated Deployment object. With this enhancement, Deployment Status events received via webhooks will have enough information to notify other systems, without having to call back to the GitHub API for the `environment`, `ref`, or payload that was deployed.
+
+### Example Deployment JSON
+
+``` json
+{
+ "url": "https://api.github.com/repos/my-org/my-repo/deployments/392",
+ "id": 392,
+ "sha": "837db83be4137ca555d9a5598d0a1ea2987ecfee",
+ "ref": "master",
+ "environment": "staging",
+ "payload": {
+ "fe": [
+ "fe1",
+ "fe2",
+ "fe3"
+ ]
+ },
+ "description": "ship it!",
+ "creator": {
+ "login": "my-org",
+ "id": 521,
+ "avatar_url": "https://avatars.githubusercontent.com/u/2988?",
+ "type": "User"
+ },
+ "created_at": "2014-05-09T19:56:47Z",
+ "updated_at": "2014-05-09T19:56:47Z",
+ "statuses_url": "https://api.github.com/repos/my-org/my-repo/deployments/392/statuses"
+}
+```
+
+### Example Deployment Status JSON
+
+``` json
+{
+ "url": "https://api.github.com/repos/my-org/my-repo/deployments/396/statuses/1",
+ "id": 1,
+ "state": "success",
+ "deployment": {
+ "url": "https://api.github.com/repos/my-org/my-repo/deployments/396",
+ "id": 392,
+ "sha": "837db83be4137ca555d9a5598d0a1ea2987ecfee",
+ "ref": "master",
+ "payload": {
+ "fe": [
+ "fe1",
+ "fe2",
+ "fe3"
+ ]
+ },
+ "environment": "production",
+ "description": "Deploying to production",
+ "creator": {
+ "login": "alysson-goldner",
+ "id": 540,
+ "type": "User"
+ },
+ "created_at": "2014-05-09T19:59:36Z",
+ "updated_at": "2014-05-09T19:59:36Z",
+ "statuses_url": "https://api.github.com/repos/my-org/my-repo/deployments/396/statuses"
+ },
+ "description": "Deployment succeeded",
+ "target_url": "https://deploy.myorg.com/apps/my-repo/logs/420",
+ "created_at": "2014-05-09T19:59:39Z",
+ "updated_at": "2014-05-09T19:59:39Z",
+ "deployment_url": "https://api.github.com/repos/my-org/my-repo/deployments/396"
+}
+```
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=Deployments+API
+[deployments-preview]: https://developer.github.com/changes/2014-01-09-preview-the-new-deployments-api/
diff --git a/content/changes/2014-06-09-new-attributes-for-pull-request-review-comment-events.md b/content/changes/2014-06-09-new-attributes-for-pull-request-review-comment-events.md
new file mode 100644
index 0000000000..e8420a7c35
--- /dev/null
+++ b/content/changes/2014-06-09-new-attributes-for-pull-request-review-comment-events.md
@@ -0,0 +1,11 @@
+---
+title: New attributes for PullRequestReviewComment events
+author_name: jdpace
+---
+
+We've enhanced the [PullRequestReviewComment events payloads][pr-review-comment-events] to include `action` and `pull_request` attributes. With the addition of the `pull_request` attribute, you now have immediate access to detailed information about the pull request without needing an additional API request.
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=PullRequestReviewComment+Event+Payloads
+[pr-review-comment-events]: https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
diff --git a/content/changes/2014-06-11-improved-ci-support-for-deployments-api.md b/content/changes/2014-06-11-improved-ci-support-for-deployments-api.md
new file mode 100644
index 0000000000..8f5a6e1ab3
--- /dev/null
+++ b/content/changes/2014-06-11-improved-ci-support-for-deployments-api.md
@@ -0,0 +1,20 @@
+---
+title: Improved CI support for the Deployments API
+author_name: atmos
+---
+
+Today we're making a few minor changes to the [Deployments API preview][2]. With the introduction of [combined statuses][4] in a [recent update][3], we noticed a few inconsistencies with the API that we'd like to remedy.
+
+We're introducing a new parameter called `required_contexts`. This parameter accepts an array of named [commit status][5] contexts that are ensured to be in a "success" state before the deployment is created. This allows you to verify that more than one system verified your code before you deploy it.
+
+We've removed support for the `force` parameter. The force parameter existed to bypass both the auto-merge and commit status checks. The same behavior can now be accomplished by setting `auto_merge` and `required_contexts` appropriately.
+
+We're also setting a context for all [commit statuses][5]. If a commit status is created without a context, we'll now set it to the string "default".
+
+If you have any questions or concerns, [drop us a line][1].
+
+[1]: https://github.com/contact?form[subject]=Deployments+API
+[2]: https://developer.github.com/changes/2014-01-09-preview-the-new-deployments-api/
+[3]: https://developer.github.com/changes/2014-04-10-deployment-api-preview-extension/
+[4]: https://developer.github.com/changes/2014-03-27-combined-status-api/
+[5]: https://developer.github.com/v3/repos/statuses/
diff --git a/content/changes/2014-06-19-combined-status-api-pagination.md b/content/changes/2014-06-19-combined-status-api-pagination.md
new file mode 100644
index 0000000000..7cb5fc9c98
--- /dev/null
+++ b/content/changes/2014-06-19-combined-status-api-pagination.md
@@ -0,0 +1,20 @@
+---
+title: Pagination in the Combined Status API
+author_name: bhuga
+---
+
+We're getting close to bringing the [Combined Status API][1] out of preview
+mode, and have just a couple of small changes to make before it's :sparkles:.
+
+First, we're now [paginating][2] combined status API calls. The combined status
+`state` field will always take all statuses into account, but we'll now only
+return 100 embedded statuses at a time.
+
+Second, we're adding a `total_count` field, mirroring the Search API. This
+count represents the number of contexts submitted for the given commit.
+
+As always, we're interested in [hearing your feedback][3].
+
+[1]: /v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
+[2]: /v3/#pagination
+[3]: https://github.com/contact?form[subject]=Combined+Status+API
diff --git a/content/changes/2014-06-23-the-github-enterprise-api-documentation-has-a-new-home.md b/content/changes/2014-06-23-the-github-enterprise-api-documentation-has-a-new-home.md
new file mode 100644
index 0000000000..4ec77ea539
--- /dev/null
+++ b/content/changes/2014-06-23-the-github-enterprise-api-documentation-has-a-new-home.md
@@ -0,0 +1,10 @@
+---
+title: The GitHub Enterprise API documentation has a new home!
+author_name: gjtorikian
+---
+
+[GitHub Enterprise](https://enterprise.github.com) offers the same set of APIs as GitHub.com, as well as its own set of Enterprise-specific functionality.
+
+The GitHub Enterprise API has been documented on the Enterprise Help for some time. We've now [moved the resources to this site](https://developer.github.com/v3/enterprise/) to be hosted alongside the rest of the GitHub API documentation.
+
+Is there an API workflow you're particularly interested in? [Let us know](https://github.com/contact?form%5Bsubject%5D=Suggestion+for+an+Enterprise+Guide) and we'll do our best to [write a guide](https://developer.github.com/guides/)!
diff --git a/content/changes/2014-07-07-example-webhook-payloads.md b/content/changes/2014-07-07-example-webhook-payloads.md
new file mode 100644
index 0000000000..b7403f75f8
--- /dev/null
+++ b/content/changes/2014-07-07-example-webhook-payloads.md
@@ -0,0 +1,17 @@
+---
+title: New example webhook payloads
+author_name: kdaigle
+---
+
+Today, we’ve added example [webhook][webhooks] payloads to the [event types][event-types] page.
+Alongside existing descriptions for each event, we now include an [example payload][full-payload]
+so that you can quickly see the data provided by the event. You can learn more about how webhooks
+work with our [Webhooks Guide][webhooks-guide].
+
+If you have any questions or feedback, please [get in touch][get-in-touch].
+
+[webhooks]: https://github.com/blog/1778-webhooks-level-up
+[event-types]: /v3/activity/events/types/
+[full-payload]: /v3/activity/events/types/#issuesevent
+[webhooks-guide]: /webhooks/
+[get-in-touch]: https://github.com/contact?form[subject]=Example+webhook+payloads
diff --git a/content/changes/2014-07-09-status-contexts-are-official.md b/content/changes/2014-07-09-status-contexts-are-official.md
new file mode 100644
index 0000000000..614febd9d4
--- /dev/null
+++ b/content/changes/2014-07-09-status-contexts-are-official.md
@@ -0,0 +1,35 @@
+---
+title: The Combined Status API is official
+author_name: bhuga
+---
+
+We're happy to announce that the [Combined Status API][docs] is officially part
+of the GitHub API v3. We now consider it stable for production use.
+
+Thanks to everyone who provided feedback during the comment period. We got
+some great feedback, and hope this feature helps you build the tools you
+need to make GitHub the best place to ship exactly the way you want.
+
+### Preview media type no longer needed
+
+If you used the Combined Status API during the preview period, you needed to
+provide a custom media type in the `Accept` header:
+
+ application/vnd.github.she-hulk-preview+json
+
+Now that the preview period has ended, you no longer need to pass this custom
+media type.
+
+Instead, we [recommend][media-types] that you specify `v3` as the version in the
+`Accept` header:
+
+ application/vnd.github.v3+json
+
+### Feedback
+
+We'll never be done listening to you! As always, please don't hesitate to
+[share your feedback][feedback].
+
+[docs]: /v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
+[media-types]: /v3/media
+[feedback]: https://github.com/contact?form[subject]=Combined+Status+API
diff --git a/content/changes/2014-07-28-assignee-and-label-actions-for-issue-events.md b/content/changes/2014-07-28-assignee-and-label-actions-for-issue-events.md
new file mode 100644
index 0000000000..80e7045040
--- /dev/null
+++ b/content/changes/2014-07-28-assignee-and-label-actions-for-issue-events.md
@@ -0,0 +1,13 @@
+---
+title: New assigned/labeled actions for issue and pull request events
+author_name: jdpace
+---
+
+As part of the [new GitHub Issues][issues-three], we've added new actions to the issues and pull requests webhook events: "labeled", "unlabeled", "assigned", and "unassigned". The payload will also include the respective assignee or label for these new actions.
+
+If you already have a [webhook](/webhooks/) subscribed to the `issues` or `pull_request` events, you'll start seeing these new actions immediately. The new events can also be fetched from the [issue events API](/v3/issues/events/).
+
+For more information, be sure to check out our documentation for the [IssuesEvent](/v3/activity/events/types/#issuesevent) or [PullRequestEvent](/v3/activity/events/types/#pullrequestevent). If you have any questions or feedback, please [drop us a line][contact].
+
+[issues-three]: https://github.com/blog/1866-the-new-github-issues
+[contact]: https://github.com/contact?form%5Bsubject%5D=New+Assigned+and+Labeled+Actions+for+Issues+and+Pull+Request+Events
diff --git a/content/changes/2014-08-05-team-memberships-api.md b/content/changes/2014-08-05-team-memberships-api.md
new file mode 100644
index 0000000000..fb85053ecb
--- /dev/null
+++ b/content/changes/2014-08-05-team-memberships-api.md
@@ -0,0 +1,38 @@
+---
+title: We're changing the way you add new members to your organization
+author_name: jakeboxer
+---
+
+Today, we're announcing a change to the way organization owners add new members to their organization.
+
+Previously, if you were an organization owner, you could use the [add team member][add-team-member] endpoint to add any GitHub user to any team on your organization without any sort of approval from them. Now, we're increasing user security by sending [invitations][org-invitations] to users when they're added to teams on organizations that they aren't yet a part of.
+
+With this change, if you use the [add team member][add-team-member] endpoint to add a user to a team and that user isn't already on another team in your organization, the request will fail.
+
+### The new Team Memberships API
+
+You should change all your [add team member][add-team-member] requests to use the new [add team membership][add-team-membership] endpoint. This new endpoint works exactly the same as the old one, with one important change: if the membership being added is for a user who is unaffiliated with the team's organization, that user will be sent an invitation via email.
+
+Unlike the [add team member][add-team-member] endpoint, a successful request to the [add team membership][add-team-membership] endpoint does *not* guarantee that the user is now a member of the team. If you're trying to migrate to the new endpoint and need to know when a user has been successfully added (not just invited) to a team, please check out [TeamAddEvent][team-add-event].
+
+### Preview period
+
+We're making the new Team Memberships API (and the breaking changes to the [add team member][add-team-member] API) available today for developers to preview. During this period, we may change aspects of these endpoints. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.
+
+While these new APIs are in their preview period, you'll need to provide the following custom media type in the `Accept` header:
+
+ application/vnd.github.the-wasp-preview+json
+
+We expect the preview period to last 30-60 days. At the end of the preview period, the Team Memberships API will become an official component of GitHub API v3, as will the [add team member][add-team-member] API's breaking changes.
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[contact]: https://github.com/contact?form[subject]=Team+Memberships+API
+[org-invitations]: https://help.github.com/articles/adding-organization-members-to-a-team
+[add-team-member]: /v3/orgs/teams/#add-team-member
+[add-team-membership]: /v3/orgs/teams/#add-team-membership
+[get-team-member]: /v3/orgs/teams/#get-team-member
+[get-team-membership]: /v3/orgs/teams/#get-team-membership
+[remove-team-member]: /v3/orgs/teams/#remove-team-member
+[remove-team-membership]: /v3/orgs/teams/#remove-team-membership
+[team-add-event]: /v3/activity/events/types/#teamaddevent
diff --git a/content/changes/2014-08-15-deployments-api-changes.md b/content/changes/2014-08-15-deployments-api-changes.md
new file mode 100644
index 0000000000..ac6455dc22
--- /dev/null
+++ b/content/changes/2014-08-15-deployments-api-changes.md
@@ -0,0 +1,27 @@
+---
+title: New features for the Deployments API preview
+author_name: atmos
+---
+
+We've added two new features to the [Deployments API preview][deployments-preview]: the ability to query deployments and a new `task` attribute for different types of deployment tasks.
+
+## API changes
+
+You can now search for deployments via query parameters to the [listing endpoint][listing-endpoint]. You can filter on `sha`, `ref`, `task`, and `environment`. This makes it easier to answer questions like "when was the last time someone deployed to staging?"
+
+``` command-line
+$ curl -H "Authorization: token [yours]" \
+ https://api.github.com/repos/octocat/my-repo/deployments?environment=staging
+```
+
+## New attribute
+
+We've also added a `task` attribute to the deployment resource. The `task` attribute allows you to specify tasks other than just pushing code. Popular deployment tools like [capistrano][capistrano] and [fabric][fabric] support named tasks to do things like running schema migrations. We hope this attribute will give integrators the flexibility they need to provide custom functionality.
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=Deployments+API
+[deployments-preview]: https://developer.github.com/changes/2014-01-09-preview-the-new-deployments-api/
+[listing-endpoint]: https://developer.github.com/v3/repos/deployments/#list-deployments
+[fabric]: http://www.fabfile.org/
+[capistrano]: http://capistranorb.com/
diff --git a/content/changes/2014-08-28-accepting-organization-invitations-from-the-api.md b/content/changes/2014-08-28-accepting-organization-invitations-from-the-api.md
new file mode 100644
index 0000000000..e62023979b
--- /dev/null
+++ b/content/changes/2014-08-28-accepting-organization-invitations-from-the-api.md
@@ -0,0 +1,36 @@
+---
+title: Accepting organization invitations from the API
+author_name: jakeboxer
+---
+
+The upcoming [Team Memberships API][team-memberships-api] gives you the power to [invite][org-invitations] new GitHub users to your organization via the API. We're expanding the API to also allow users to view their organization membership statuses and accept any invitations they've received.
+
+### The new Organization Memberships API
+
+When someone [invites][org-invitations] you to an organization, your membership with that organization begins in the "pending" state. The new [list organization memberships][list-org-memberships] endpoint allows you to find your pending memberships. You can then change them to "active" (accepting the invitation in the process) by using the [edit organization membership][edit-org-membership] endpoint.
+
+### New Team Membership API response attribute
+
+Previously, responses from the [add team membership][add-team-membership] and [get team membership][get-team-membership] endpoints included a "status" attribute, which could either be "active" or "pending". We've renamed this attribute from "status" to "state" for better consistency with our other API calls.
+
+To give you time to update your apps, we'll keep the legacy "status" attribute around alongside the new "state" attribute until **September 4th, 2014**.
+
+### Preview period
+
+The new Organization Memberships API is available for developers to preview alongside the [Team Memberships API][team-memberships-api]. During this period, we may change aspects of these endpoints. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.
+
+While these new APIs are in their preview period, you'll need to provide the following custom media type in the `Accept` header:
+
+ application/vnd.github.the-wasp-preview+json
+
+We expect the preview period to last 30-60 days. At the end of the preview period, the Team and Organization Memberships APIs will become official components of GitHub API v3.
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[contact]: https://github.com/contact?form[subject]=Team+Memberships+API
+[team-memberships-api]: /changes/2014-08-05-team-memberships-api/
+[org-invitations]: https://help.github.com/articles/adding-organization-members-to-a-team
+[list-org-memberships]: /v3/orgs/members/#list-your-organization-memberships
+[edit-org-membership]: /v3/orgs/members/#edit-your-organization-membership
+[add-team-membership]: /v3/orgs/teams/#add-team-membership
+[get-team-membership]: /v3/orgs/teams/#get-team-membership
diff --git a/content/changes/2014-09-05-removing-gravatar-id.md b/content/changes/2014-09-05-removing-gravatar-id.md
new file mode 100644
index 0000000000..3d9f4442a1
--- /dev/null
+++ b/content/changes/2014-09-05-removing-gravatar-id.md
@@ -0,0 +1,21 @@
+---
+title: Removing Gravatar ID from user payloads
+author_name: mastahyeti
+---
+
+We have deprecated the `gravatar_id` attribute in the [user
+representation](https://developer.github.com/v3/users/). Starting September 19,
+the API will always provide an empty string as the value for this attribute.
+
+Users have been able to upload avatars directly to GitHub for [a while
+now](https://github.com/blog/1803-switch-your-picture-with-ease). If users
+haven't uploaded an avatar, we still try to fetch one from Gravatar, but that
+happens behind the scenes on GitHub's servers. As a result, the `gravatar_id`
+attribute no longer identifies a GitHub user's canonical avatar. Instead, API
+consumers should use the `avatar_url` to fetch a user's avatar. The `avatar_url`
+attribute has always been present in the [v3 user representation](/v3/users/)
+and is the only reliable way to find a GitHub user's avatar.
+
+If you have any questions or feedback, please [get drop us a line][contact].
+
+[contact]: https://github.com/contact?form[subject]=Removing+Gravatar+ID
diff --git a/content/changes/2014-09-12-changing-organization-feeds.md b/content/changes/2014-09-12-changing-organization-feeds.md
new file mode 100644
index 0000000000..c885113e98
--- /dev/null
+++ b/content/changes/2014-09-12-changing-organization-feeds.md
@@ -0,0 +1,44 @@
+---
+title: Changing organization feeds in the Feeds API
+author_name: mastahyeti
+---
+
+We have deprecated the `current_user_organization_url` attribute and the
+`current_user_organization.href` attribute in the [Feeds API][docs]. If you make
+use of these attributes, you'll want to update your code to use the new
+`current_user_organization_urls` attribute instead.
+
+### Changes to the deprecated attributes
+
+Previously, the deprecated attributes returned URI template. For example:
+
+``` json
+"current_user_organization_url":
+ "https://github.com/organizations/{org}/mastahyeti.private.atom?token=abc123"
+```
+
+The template included a deprecated authentication token. Our new tokens are
+valid only for a concrete feed URL (not for a URI template). Because the
+deprecated attributes were templates and did not specify a concrete URL, the API
+could not provide a token that could be used for organization feeds.
+
+Starting today, the API returns empty values for the deprecated attributes.
+
+### New attribute for organization feeds
+
+In order to preserve the functionality of this API, we have added a new
+attribute that lists specific Atom feed urls for each of the user's
+organizations.
+
+``` json
+"current_user_organization_urls": [
+ "https://github.com/organizations/github/mastahyeti.private.atom?token=abc123"
+ "https://github.com/organizations/requests/mastahyeti.private.atom?token=token=def456"
+]
+```
+
+Check out the updated [Feeds API documentation][docs] for the new fields. If you
+have any questions or feedback, please [get drop us a line][contact].
+
+[docs]: /v3/activity/feeds/
+[contact]: https://github.com/contact?form[subject]=Changing+organization+feeds+in+the+Feeds+API
diff --git a/content/changes/2014-09-16-finalizing-the-organization-and-team-membership-apis.md b/content/changes/2014-09-16-finalizing-the-organization-and-team-membership-apis.md
new file mode 100644
index 0000000000..5b6f7b340b
--- /dev/null
+++ b/content/changes/2014-09-16-finalizing-the-organization-and-team-membership-apis.md
@@ -0,0 +1,28 @@
+---
+title: Finalizing the Organization and Team Membership APIs
+author_name: jakeboxer
+---
+
+For the past few weeks, the new [Organization Membership][org-membership-api] and [Team Membership][team-membership-api] APIs have been available for early access via a preview media type. As of today, these APIs are stable and suitable for production use.
+
+### Preview period ends on September 23
+
+On September 23, 2014, these APIs will become official parts of the GitHub API v3. At that time, the preview media type will no longer be required to access these APIs.
+
+### Reminder: Breaking change to legacy endpoint
+
+The [breaking change to the "Add team member" endpoint][add-team-member] will also go into effect for all requests on **September 23, 2014**. At that time, if you use the [add team member][add-team-member] endpoint to add a user to a team and that user isn't already on another team in your organization, the request will fail. To avoid this, be sure to use the [add team membership][add-team-membership] endpoint.
+
+### Addition to the Organization Membership API
+
+Thanks to your feedback, we've updated the Organization Membership API to provide direct access to basic information about the organization whenever you fetch a [list of memberships][list-org-memberships] or a [single membership][get-org-membership].
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[contact]: https://github.com/contact?form[subject]=Organization+and+Team+Membership+APIs
+[org-membership-api]: /changes/2014-08-28-accepting-organization-invitations-from-the-api/
+[team-membership-api]: /changes/2014-08-05-team-memberships-api/
+[add-team-member]: /v3/orgs/teams/#add-team-member
+[add-team-membership]: /v3/orgs/teams/#add-team-membership
+[list-org-memberships]: /v3/orgs/members/#list-your-organization-memberships
+[get-org-membership]: /v3/orgs/members/#get-your-organization-membership
diff --git a/content/changes/2014-09-23-one-more-week-before-the-add-team-member-api-breaking-change.md b/content/changes/2014-09-23-one-more-week-before-the-add-team-member-api-breaking-change.md
new file mode 100644
index 0000000000..8ef7561d6d
--- /dev/null
+++ b/content/changes/2014-09-23-one-more-week-before-the-add-team-member-api-breaking-change.md
@@ -0,0 +1,21 @@
+---
+title: One more week before the "Add team member" API breaking change
+author_name: jakeboxer
+---
+
+**UPDATE (2014-09-30):** In response to feedback from developers, we're delaying the breaking change to the ["Add team member" API][add-team-member] until Monday, **October 6, 2014**. The change will go into effect for all requests on that date.
+
+Starting October 6, if you use [the "Add team member" API][add-team-member] to add a user to a team and that user isn't already on another team in your organization, the request will fail. To avoid this, be sure to use the ["Add team membership" API][add-team-membership].
+
+### The Organization and Team Membership APIs are now official
+
+As promised in [our blog post earlier this month][finalizing], the [Organization Membership][org-membership-api] and [Team Membership][team-membership-api] APIs are now an official part of the GitHub API! The preview media type is no longer required to access them.
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[add-team-member]: /v3/orgs/teams/#add-team-member
+[add-team-membership]: /v3/orgs/teams/#add-team-membership
+[finalizing]: /changes/2014-09-16-finalizing-the-organization-and-team-membership-apis/
+[org-membership-api]: /changes/2014-08-28-accepting-organization-invitations-from-the-api/
+[team-membership-api]: /changes/2014-08-05-team-memberships-api/
+[contact]: https://github.com/contact?form[subject]=Organization+and+Team+Membership+APIs
diff --git a/content/changes/2014-10-06-new-attributes-for-issue-events-api.md b/content/changes/2014-10-06-new-attributes-for-issue-events-api.md
new file mode 100644
index 0000000000..009d26b12c
--- /dev/null
+++ b/content/changes/2014-10-06-new-attributes-for-issue-events-api.md
@@ -0,0 +1,17 @@
+---
+title: New Attributes for Issue Events API
+author_name: jdpace
+---
+
+We've made it easier to track changes to issues. The Issue Events API now provides more context for several event types:
+
+- `assigned` and `unassigned` events now include an `assignee` object so you can see just who was assigned or unassigned.
+- `labeled` and `unlabeled` events include a `label` object.
+- `milestoned` and `demilesoned` events include a `milestone` object.
+- `renamed` events include a `rename` object with the title before and after the rename.
+
+Check out the [Issue Events API documentation][issue-events] for a full list of supported events. If you have
+any questions or feedback, please [drop us a line][contact].
+
+[issue-events]: /v3/issues/events/
+[contact]: https://github.com/contact?form[subject]=New+Attrs+for+Issue+Events+API
diff --git a/content/changes/2014-10-16-removed-ssl-version-3-support-from-webhooks-and-services.md b/content/changes/2014-10-16-removed-ssl-version-3-support-from-webhooks-and-services.md
new file mode 100644
index 0000000000..9414413fd5
--- /dev/null
+++ b/content/changes/2014-10-16-removed-ssl-version-3-support-from-webhooks-and-services.md
@@ -0,0 +1,14 @@
+---
+title: Removed SSLv3 support from webhooks and services
+author_name: kdaigle
+---
+
+This morning, we [removed support][github-services-pr] for the `ssl_version` webhook configuration
+option and made `TLS 1.X` the default cryptographic protocol to address the [POODLE exploit][poodle].
+You should no longer set or rely on the `ssl_version` configuration option.
+
+If you have any questions or feedback, please [drop us a line][contact].
+
+[github-services-pr]: https://github.com/github/github-services/pull/949
+[poodle]: https://www.openssl.org/~bodo/ssl-poodle.pdf
+[contact]: https://github.com/contact?form[subject]=Removed+SSLv3+support+from+webhooks+and+services
diff --git a/content/changes/2014-10-21-deployment-webhook-payload-changes.md b/content/changes/2014-10-21-deployment-webhook-payload-changes.md
new file mode 100644
index 0000000000..e74d85137c
--- /dev/null
+++ b/content/changes/2014-10-21-deployment-webhook-payload-changes.md
@@ -0,0 +1,152 @@
+---
+title: Deployment webhook payload changes
+author_name: atmos
+---
+
+On November 4th, 2014, we will begin sending a new format for [deployment][1] and [deployment status][2] payloads for webhooks. In the meantime we'll be running in a compatibility mode that will give integrators the time needed to start taking advantage of the new format. Integrators who are working with webhooks and deployments are advised to upgrade to the new payload format to avoid service interruption.
+
+This change brings the payloads for these events more inline with the responses you'd receive from the API. Instead of having deployment and deployment status attributes as top-level keys, we will now nest them under `deployment` and `deployment_status` keys. Since we're still in the [preview period][3] for the deployments API we felt it was best to correct this inconsistency now.
+
+## DeploymentEvent Changes
+
+#### Old Format
+
+``` json
+{
+ "id": 42,
+ "sha": "deadbeef",
+ "ref": "master",
+ "task": "deploy",
+ "name": "my-org/our-app",
+ "environment": "production",
+ "payload": {…},
+ "description": "Deploying master",
+ "repository": {…},
+ "sender": {…}
+}
+```
+
+#### Current Format - 2014/10/22
+
+``` json
+{
+ "id": 42,
+ "sha": "deadbeef",
+ "ref": "master",
+ "task": "deploy",
+ "name": "my-org/our-app",
+ "environment": "production",
+ "payload": {…},
+ "description": "Deploying master",
+ "repository": {…},
+ "deployment": {
+ "url": "https://api.github.com/repos/my-org/our-app/deployments/42",
+ "id": 42,
+ "sha": "deadbeef",
+ "ref": "master",
+ "task": "deploy",
+ "environment": "production",
+ "payload": {…},
+ "description": "Deploying master",
+ "creator": {…},
+ "created_at": "2014-09-23T16:37:49Z",
+ "updated_at": "2014-09-23T16:37:49Z",
+ "statuses_url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses"
+ },
+ "sender": {…}
+}
+```
+
+#### New Format - 2014/11/05
+
+``` json
+{
+ "deployment": {
+ "url": "https://api.github.com/repos/my-org/our-app/deployments/42",
+ "id": 42,
+ "sha": "deadbeef",
+ "ref": "master",
+ "task": "deploy",
+ "environment": "production",
+ "payload": {…},
+ "description": "Deploying master",
+ "creator": {…},
+ "created_at": "2014-09-23T16:37:49Z",
+ "updated_at": "2014-09-23T16:37:49Z",
+ "statuses_url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses"
+ },
+ "repository": {…},
+ "sender": {…}
+}
+```
+
+## DeploymentStatusEvent Changes
+
+#### Old Format
+
+``` json
+{
+ "id": 2600,
+ "state": "success",
+ "deployment": {…},
+ "target_url": "https://gist.github.com/deadbeef",
+ "description": "Deployment was successful",
+ "repository": {…},
+ "sender": {…}
+}
+```
+
+#### Current Format - 2014/10/22
+
+``` json
+{
+ "id": 2600,
+ "state": "success",
+ "target_url": "https://gist.github.com/deadbeef",
+ "description": "Deployment was successful",
+ "repository": {…},
+ "deployment_status": {
+ "url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses2600",
+ "id": 2600,
+ "state": "success",
+ "creator": {…},
+ "target_url": "https://gist.github.com/deadbeef",
+ "description": "Deployment was successful",
+ "created_at": "2014-09-23T16:45:49Z",
+ "updated_at": "2014-09-23T16:45:49Z",
+ "deployment_url": "https://api.github.com/repos/my-org/our-app/deployments/42",
+ "repository_url": "https://api.github.com/repos/my-org/our-app"
+ },
+ "deployment": {…},
+ "sender": {…}
+}
+```
+
+#### New Format - 2014/11/05
+
+``` json
+{
+ "deployment_status": {
+ "url": "https://api.github.com/repos/my-org/our-app/deployments/42/statuses2600",
+ "id": 2600,
+ "state": "success",
+ "creator": {…},
+ "target_url": "https://gist.github.com/deadbeef",
+ "description": "Deployment was successful",
+ "created_at": "2014-09-23T16:45:49Z",
+ "updated_at": "2014-09-23T16:45:49Z",
+ "deployment_url": "https://api.github.com/repos/my-org/our-app/deployments/42",
+ "repository_url": "https://api.github.com/repos/my-org/our-app"
+ },
+ "deployment": {…},
+ "repository": {…},
+ "sender": {…}
+}
+```
+
+If you have any questions or feedback, please [get in touch][get-in-touch].
+
+[1]: https://developer.github.com/v3/activity/events/types/#deploymentevent
+[2]: https://developer.github.com/v3/activity/events/types/#deploymentstatusevent
+[3]: https://developer.github.com/changes/2014-01-09-preview-the-new-deployments-api/
+[get-in-touch]: https://github.com/contact?form[subject]=Deployments+API
diff --git a/content/changes/2014-10-24-status-api-limits.md b/content/changes/2014-10-24-status-api-limits.md
new file mode 100644
index 0000000000..c58ae0ebe4
--- /dev/null
+++ b/content/changes/2014-10-24-status-api-limits.md
@@ -0,0 +1,16 @@
+---
+title: Status API Limits
+author_name: rsanheim
+---
+
+To ensure a high level of service for all API consumers, we will soon limit the number of [statuses]
+to 1000 per commit SHA, repository, and context.
+
+Beginning Monday, November 3rd, we will trim existing data sets that exceed this limit, deleting the oldest
+records first. Attempts to create statuses beyond that limit will result in a [validation error].
+
+If you have any feedback or questions, please don't hesitate to [contact] us.
+
+[statuses]: /v3/repos/statuses/
+[validation error]: https://developer.github.com/v3/#client-errors
+[contact]: https://github.com/contact?form[subject]=Combined+Status+API
diff --git a/content/changes/2014-11-25-the-deployments-api-is-official.md b/content/changes/2014-11-25-the-deployments-api-is-official.md
new file mode 100644
index 0000000000..90bcc90c4d
--- /dev/null
+++ b/content/changes/2014-11-25-the-deployments-api-is-official.md
@@ -0,0 +1,35 @@
+---
+title: The Deployments API is official
+author_name: atmos
+---
+
+We're happy to announce that the [Deployments API][docs] is officially part
+of GitHub API v3. We now consider it stable for production use.
+
+Thanks to everyone who provided feedback during the preview period. We got
+some great feedback, and hope this feature helps you build the tools you
+need to make GitHub the best place to ship exactly the way you want.
+
+### Preview media type no longer needed
+
+If you used the Deployments API during the preview period, you needed to
+provide a custom media type in the `Accept` header:
+
+ application/vnd.github.cannonball-preview+json
+
+Now that the preview period has ended, you no longer need to pass this custom
+media type.
+
+Instead, we [recommend][media-types] that you specify `v3` as the version in the
+`Accept` header:
+
+ application/vnd.github.v3+json
+
+### Feedback
+
+We'll never be done listening to you! As always, please don't hesitate to
+[share your feedback][feedback].
+
+[docs]: /v3/repos/deployments
+[media-types]: /v3/media
+[feedback]: https://github.com/contact?form[subject]=Deployments+API
diff --git a/content/changes/2014-12-03-preview-the-new-organization-webhooks-api.md b/content/changes/2014-12-03-preview-the-new-organization-webhooks-api.md
new file mode 100644
index 0000000000..f64f7a2f3a
--- /dev/null
+++ b/content/changes/2014-12-03-preview-the-new-organization-webhooks-api.md
@@ -0,0 +1,40 @@
+---
+title: Preview the New Organization Webhooks API
+author_name: jdpace
+---
+
+Today we're very excited [to announce Organization Webhooks][dotcom-blog-post].
+Organization Webhooks allow you to subscribe to events that happen across an
+entire organization.
+
+In addition to being able to subscribe to the existing repository oriented
+events across an organization, we're also adding some new events which are
+exclusive to organization webhooks. The new [`repository`
+event][repository-event] allows you to receive webhook payloads when a new
+repository is created. By subscribing to the [`membership`
+event][membership-event], you'll be notified whenever a user is added or
+removed from a team.
+
+We’re making this new API for Organization Webhooks available today [for
+developers to preview][docs-preview]. The preview period will allow us to [get
+your feedback][contact] before declaring the Organization Webhooks API final.
+We expect the preview
+period to last for roughly 30-60 days.
+
+As we discover opportunities to improve the API during the preview period, we
+may ship changes that break clients using the preview version of the API. We
+want to iterate quickly. To do so, we will announce any changes here (on the
+developer blog), but we will not provide any advance notice.
+
+At the end of preview period, the Organization Webhooks API will become an
+official component of GitHub API v3. At that point, the new Organization
+Webhooks API will be stable and suitable for production use.
+
+We hope you’ll take it for a spin and [send us your feedback][contact].
+
+[dotcom-blog-post]: https://github.com/blog/1933-introducing-organization-webhooks
+[repository-event]: /v3/activity/events/types/#repositoryevent
+[membership-event]: /v3/activity/events/types/#membershipevent
+[docs]: /v3/orgs/hooks/
+[docs-preview]: /v3/orgs/hooks/
+[contact]: https://github.com/contact?form[subject]=Organization+Webhooks
diff --git a/content/changes/2014-12-08-organization-permissions-api-preview.md b/content/changes/2014-12-08-organization-permissions-api-preview.md
new file mode 100644
index 0000000000..cc32c582c4
--- /dev/null
+++ b/content/changes/2014-12-08-organization-permissions-api-preview.md
@@ -0,0 +1,105 @@
+---
+title: Preview the upcoming organization permission changes
+author_name: jakeboxer
+---
+**UPDATE (2014-12-12):** The [List your organizations][list-your-organizations] API is now included in this preview as well.
+
+We have some upcoming changes that will affect the way organization members and repositories are managed. The most important changes are:
+
+- The Owners team will no longer be special.
+- The [List your repositories][list-your-repos] API will include organization-owned repositories.
+- The [List user organizations][list-user-organizations] API will only include public organization memberships.
+- The [List your organizations][list-your-organizations] API will require `user` scope or `read:org` scope.
+
+## What's happening to the Owners team?
+
+Currently, members of your Owners team are administrators of your organization. Soon, your Owners team will become a totally normal team. Adding and removing Owners team members won't change their administrator status anymore. Instead, you'll be able to directly grant admin permissions to your organization's members without adding them to any special teams.
+
+We won't delete your Owners team, but you'll be able to delete or rename it yourself if you want. Organizations created after the change won't have an Owners team.
+
+### What should you do?
+
+In preparation for this change to the Owners team, we're releasing a few new APIs. You'll be able to use these APIs to manage organization admins without relying on the Owners team.
+
+#### Adding an organization admin
+
+To add a new organization admin, use the new [Add or update organization membership][add-org-membership] endpoint, specifying a role of `"admin"` in the request body. This replaces adding or inviting people to the Owners team.
+
+#### Removing an organization admin
+
+To remove someone from the organization role but keep them as a member of their teams, use the new [Add or update organization membership][add-org-membership] endpoint, specifying a role of `"member"` in the request body. This replaces removing people from the Owners team.
+
+#### Listing organization admins
+
+To get a list of all your organization's admins, use the [Organization members list][list-org-members] endpoint, specifying a role of `"admin"` in the query string. This replaces listing the members of the Owners team.
+
+#### Checking if someone is an organization admin
+
+To check if a given user is an organization admin, use the new [Get organization membership][get-org-membership] endpoint. If the returned `"role"` attribute is set to `"admin"` and the returned `"state"` attribute is set to `"active"`, the user is an organization admin. This replaces checking if a user is on the Owners team.
+
+## What's happening to the "List your repositories" API?
+
+Currently, the [List your repositories][list-your-repos] API only returns repositories that are owned by users, not by organizations. If you want a list of *all* the repositories that the authenticated user has access to, you need to use multiple API methods.
+
+Soon, this API will include all repositories that the authenticated user has access to (whether they're owned by a user or by an organization).
+
+### What should you do?
+
+Many apps use the [List your repositories][list-your-repos] API in conjunction with the [List your organizations][list-your-orgs] and [List organization repositories][list-org-repos] APIs to build up a list of all the repositories the authenticated user has access to. If your app is doing this, you'll be able to get rid of all the organization-related API calls and just use the [List your repositories][list-your-repos] API.
+
+If your app uses the [List your repositories][list-your-repos] API for another purpose, you'll need to update your app to handle the new organization-owned repositories we'll be returning.
+
+## What's happening to the "List user organizations" API?
+
+The [List user organizations][list-user-organizations] API is intended provide [public organization memberships][public-org-membership] for any user. When you use this API to fetch *your own* organizations, this API currently returns your public and private organization memberships.
+
+Soon, this API will only return public organization memberships.
+
+### What should you do?
+
+If your app uses the [List user organizations][list-user-organizations] API to fetch all of the organization memberships (public and private) for the authenticated user, you'll need to update your app to use the [List your organizations][list-your-organizations] API instead. The [List your organizations][list-your-organizations] API returns all organizations (public and private) that your app is authorized to access.
+
+## What's happening to the "List your organizations" API?
+
+OAuth requests will soon require minimum [scopes][] in order to access the [List your organizations][list-your-organizations] API.
+
+Currently, the API response always includes your [public organization memberships][public-org-membership], regardless of the OAuth scopes associated with your request. If you have `user`, `read:org`, `write:org`, or `admin:org` scope, the response also includes your private organization memberships.
+
+Soon, this API will only return organizations that your authorization allows you to operate on in some way (e.g., you can list teams with `read:org` scope, you can publicize your organization membership with `user` scope, etc.). Therefore, this API will require at least `user` or `read:org` scope. (`write:org` and `admin:org` scope implicitly include `read:org` scope.) OAuth requests with insufficient scope will receive a `403 Forbidden` response.
+
+### What should you do?
+
+If you [authenticate via username and password][username-password-authn], you are not affected by this change.
+
+If your app only needs to fetch the user's public organization memberships, you should use the [List user organizations][list-user-organizations] API instead. Since that API only returns public information, it does not require any scopes.
+
+## Preview period
+
+Starting **today**, these new APIs are available for developers to preview. We expect the preview period to last for four weeks. (Stay tuned to the developer blog for updates.) At the end of the preview period, these additions will become official components of the GitHub API.
+
+While these additions are in their preview period, you'll need to provide the following custom media type in the `Accept` header:
+
+ application/vnd.github.moondragon-preview+json
+
+During the preview period, we may change aspects of these endpoints. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.
+
+## Migration period
+
+At the end of the preview period, we will announce the start of a migration period. At that time, developers should update their applications to use the new APIs for managing organization admins. During this period, you will still be able to use the Owners team to manage your organization's admins, so that you have time to update your applications to use the new APIs without breakage. We expect the migration period to last for four weeks.
+
+At the end of the migration period, the Owners team will no longer be special, and you'll no longer be able to rely on it for managing organization admins.
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[contact]: https://github.com/contact?form[subject]=Organization+Admin+Pre-release+Preview
+[list-your-repos]: /v3/repos/#list-your-repositories
+[list-your-orgs]: /v3/orgs/#list-your-organizations
+[list-org-repos]: /v3/repos/#list-organization-repositories
+[add-org-membership]: /v3/orgs/members/#add-or-update-organization-membership
+[list-org-members]: /v3/orgs/members/#members-list
+[get-org-membership]: /v3/orgs/members/#get-organization-membership
+[list-user-organizations]: /v3/orgs/#list-user-organizations
+[list-your-organizations]: /v3/orgs/#list-your-organizations
+[public-org-membership]: https://help.github.com/articles/publicizing-or-concealing-organization-membership
+[username-password-authn]: /v3/auth/#via-username-and-password
+[scopes]: /v3/oauth/#scopes
diff --git a/content/changes/2014-12-08-removing-authorizations-token.md b/content/changes/2014-12-08-removing-authorizations-token.md
new file mode 100644
index 0000000000..994fe04884
--- /dev/null
+++ b/content/changes/2014-12-08-removing-authorizations-token.md
@@ -0,0 +1,103 @@
+---
+title: Removing token attribute from Authorizations API responses
+author_name: ptoomey3
+---
+
+Since OAuth access tokens function like passwords, they should be treated with
+care. Today we are making it easier to more securely work with authorizations
+via the Authorizations API. We are deprecating the use of the `token`
+attribute in the majority of the [Authorizations API](/v3/oauth_authorizations/)
+responses. For the [affected APIs][authorizations-token-deprecation-notice], the
+`token` attribute will soon return an empty string. To get ready for that
+change, we are giving developers a chance to
+[preview the updated API](#preview-period) starting today.
+
+## What's changing?
+
+The current [OAuth Authorizations API](/v3/oauth_authorizations/) requires GitHub to store the full value for
+each OAuth token on our servers. In order to increase the security for our
+users, we are changing our architecture to store the SHA-256 digest of OAuth
+tokens instead. GitHub securely hashes user passwords using bcrypt and we want
+to provide comparable security for OAuth tokens as well.
+
+Rest assured that this change is an entirely proactive measure from GitHub and is not associated with any security incident.
+
+## Who is affected?
+
+This change affects any code that relies on accessing the `token` attribute from
+[these OAuth Authorizations API responses][authorizations-token-deprecation-notice].
+For example, our own [GitHub for Mac][github-for-mac] and
+[GitHub for Windows][github-for-windows] applications relied on reading the `token`
+from the [Get-or-create an authorization for a specific app][get-or-create-for-app] API, in order to support multiple installations of our desktop application for a single user.
+
+## What should you do?
+
+In order to reduce the impact of removing the `token` attribute, the OAuth
+Authorizations API has added a new request attribute (`fingerprint`), added
+three new response attributes (`token_last_eight`, `hashed_token`, and
+`fingerprint`), and added [one new API][get-or-create-for-app-fingerprint].
+While these new APIs and attributes do not replace the full functionality that
+previously existed, they can be used in place of `token` for most common use cases.
+
+* `token_last_eight` returns the last eight characters of the associated OAuth
+token. As an example, `token_last_eight` could be used to display a list of
+partial token values to help a user manage their OAuth tokens.
+
+* `hashed_token` is the base64 of the SHA-256 digest of the token.
+`hashed_token` could be used to programmatically validate that a given token
+matches an authorization returned by the API.
+
+* `fingerprint` is a new optional request parameter that allows an OAuth
+application to create multiple authorizations for a single user. `fingerprint`
+should be a string that distinguishes the new authorization from others
+for the same client ID and user.
+
+ For example, to differentiate installations of a desktop application across
+ multiple devices you might set `fingerprint` to
+ `SHA256_HEXDIGEST("GitHub for Mac - MAC_ADDRESS_OF_MACHINE")`. Since
+ `fingerprint` is not meant to be a user-facing value, you should still set
+ the `note` attribute to help a user differentiate between authorizations on their
+ [OAuth applications listing on GitHub][app-listing].
+
+* [Get-or-create an authorization for a specific app and fingerprint][get-or-create-for-app-fingerprint]
+is a new API that is analogous to the
+[Get-or-create an authorization for a specific app][get-or-create-for-app]
+API, but adds support for the new `fingerprint` request parameter.
+
+## Preview period
+
+We are making the new Authorizations API available today for developers to
+preview. During this period, we may change aspects of these endpoints. If we do,
+we will announce the changes on the developer blog, but we will not provide any
+advance notice.
+
+While these new APIs are in their preview period, you’ll need to provide the
+following custom media type in the Accept header:
+
+ application/vnd.github.mirage-preview+json
+
+We expect the preview period to last 4-6 weeks. (Stay tuned to the developer blog for updates.) At the end of the preview period, these changes will become an official and stable part of GitHub API.
+
+## Migration period
+
+At the end of the preview period, we will announce the start of a migration period. Developers will have 8 weeks to update existing code to use the new APIs.
+
+## Why SHA-256 over bcrypt?
+
+Some users may be curious why we are not using bcrypt to hash our OAuth tokens
+like we do for user passwords. Bcrypt is purposefully computationally expensive
+in order to mitigate brute force attacks against low entropy passwords. However,
+OAuth tokens are highly random and are not susceptible to brute force attacks.
+Given that OAuth token validation occurs for each request to the API we chose
+SHA-256 for performance reasons.
+
+If you have any questions or feedback, please [drop us a line][contact].
+
+[contact]: https://github.com/contact?form[subject]=Removing+authorizations+token
+[app-listing]: https://github.com/settings/applications
+[create-a-new-authorization]: /v3/oauth_authorizations/#create-a-new-authorization
+[get-or-create-for-app]: /v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
+[get-or-create-for-app-fingerprint]: /v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint
+[github-for-mac]: https://mac.github.com/
+[github-for-windows]: https://windows.github.com/
+[authorizations-token-deprecation-notice]: /v3/oauth_authorizations/#deprecation-notice
diff --git a/content/changes/2014-12-09-new-attributes-for-stars-api.md b/content/changes/2014-12-09-new-attributes-for-stars-api.md
new file mode 100644
index 0000000000..8f0f6673d4
--- /dev/null
+++ b/content/changes/2014-12-09-new-attributes-for-stars-api.md
@@ -0,0 +1,19 @@
+---
+title: New Attributes for Starring API
+author_name: arfon
+---
+
+You can now see when a user starred a repository. To receive the new response format containing the `starred_at` field, request the new media type:
+
+``` command-line
+curl -H "Accept: application/vnd.github.v3.star+json" https://api.github.com/users/andrew/starred
+```
+
+Note the starred repository is now available in the repo field.
+
+### Feedback
+
+If you have any questions or feedback about these changes, please [drop us a line][contact].
+
+[starring]: /v3/activity/starring/#list-repositories-being-starred-with-star-creation-timestamps
+[contact]: https://github.com/contact?form[subject]=New+Attributes+for+Starring+API
diff --git a/content/changes/2014-12-12-replace-older-ssh-keys-created-by-your-application.md b/content/changes/2014-12-12-replace-older-ssh-keys-created-by-your-application.md
new file mode 100644
index 0000000000..41c509f4cc
--- /dev/null
+++ b/content/changes/2014-12-12-replace-older-ssh-keys-created-by-your-application.md
@@ -0,0 +1,35 @@
+---
+title: Replace older SSH keys created by your application
+author_name: jasonrudolph
+---
+Back in February, we [improved the security audit trail for SSH keys](/changes/2014-02-24-finer-grained-scopes-for-ssh-keys/#keys-are-now-immutable). Soon, organizations will be able to block access for SSH keys that were created prior to those improvements. If your application relies on [deploy keys](/guides/managing-deploy-keys/#deploy-keys) or [user keys](/v3/users/keys/) for repository access, we recommend replacing any keys created before February 24, 2014.
+
+To ensure that your application is not affected by organizations blocking access to these keys, **you should replace the affected keys by January 15, 2015**.
+
+## How should you replace these keys?
+
+We recommend the following steps for identifying and replacing the affected keys.
+
+### 1. Identify the affected keys
+
+You only need to replace keys that your application created prior to February 24, 2014. If you don't know when your app created a given key, you can get the creation timestamp from the API. The `created_at` property is available for [deploy keys](/v3/repos/keys/) and for [user keys](/v3/users/keys/#list-your-public-keys).
+
+### 2. Inform the affected users
+
+Once you know which keys you need to replace, we recommend that you inform the affected users.
+
+For security, GitHub automatically sends an email to a user whenever a new SSH key is added to their account. Similarly, when a new deploy key is added to a repository, GitHub sends an email to the repository's administrators. When you replace your application's old keys with new ones, GitHub will email the affected users. To avoid surprising those users, you should alert them that you'll be replacing your keys. You may want to include a link to this post in your message.
+
+### 3. Add a new key
+
+Use the API to add the new [deploy key](/v3/repos/keys/#add-a-new-deploy-key) or [user key](/v3/users/keys/#create-a-public-key).
+
+### 4. Delete the old key
+
+Once your application is using the new key, use the API to delete the old one. There's an [API for deleting deploy keys](/v3/repos/keys/#remove-a-deploy-key) and an [API for deleting user keys](/v3/users/keys/#delete-a-public-key).
+
+## We're here to help
+
+As always, if you have any questions or concerns, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form[subject]=Replace+SSH+keys+created+by+application
diff --git a/content/changes/2015-01-07-prepare-for-organization-permissions-changes.md b/content/changes/2015-01-07-prepare-for-organization-permissions-changes.md
new file mode 100644
index 0000000000..9df288c09f
--- /dev/null
+++ b/content/changes/2015-01-07-prepare-for-organization-permissions-changes.md
@@ -0,0 +1,36 @@
+---
+title: Prepare for upcoming organization permissions changes
+author_name: jakeboxer
+---
+
+**UPDATE (2015-06-10):** As [announced on June 10][2015-06-10-update], these changes will become an official part of GitHub API v3 on June 24. (This post originally announced that these changes would come to GitHub API v3 on February 24.)
+
+Last month, we [released a preview][org-permissions-preview] of several API changes related to managing organization members and repositories. Today, we're finalizing these changes. This new functionality is now stable and suitable for production use. If your application relies on any of the affected functionality (described below), be sure to **update your code before June 24** to account for these changes.
+
+## Breaking changes coming on June 24
+
+If your application uses any of the following APIs, then you are affected by this change:
+
+- APIs for managing your organization's admins through the Owners team
+- The [List your repositories][list-your-repos] API
+- The [List your organizations][list-your-organizations] API
+- The [List user organizations][list-user-organizations] API
+
+If your application uses these APIs, we urge you to update your application as soon as possible. (Read [last month's announcement][org-permissions-preview] for more details on the changes.)
+
+Starting today, we're offering a migration period allowing applications to opt in to these changes (as described below). On June 24, these changes will become official parts of the GitHub API v3. At that time, these changes will apply to all API consumers.
+
+## Migration period
+
+During the migration period, you can opt-in to these changes using the following custom media type in the `Accept` header:
+
+ application/vnd.github.moondragon+json
+
+We want to make these updates as smooth as possible for everyone, and we hope that the migration period gives you flexibility to adopt these changes on your own schedule. If you have any questions or feedback, please [get in touch with us][contact]!
+
+[org-permissions-preview]: /changes/2014-12-08-organization-permissions-api-preview/
+[list-your-repos]: /v3/repos/#list-your-repositories
+[list-user-organizations]: /v3/orgs/#list-user-organizations
+[list-your-organizations]: /v3/orgs/#list-your-organizations
+[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API
+[2015-06-10-update]: /changes/2015-06-10-breaking-changes-to-organization-permissions-coming-on-june-24/
diff --git a/content/changes/2015-01-08-discovering-resources-for-a-user.md b/content/changes/2015-01-08-discovering-resources-for-a-user.md
new file mode 100644
index 0000000000..7687d01fcd
--- /dev/null
+++ b/content/changes/2015-01-08-discovering-resources-for-a-user.md
@@ -0,0 +1,10 @@
+---
+title: "New guide: Discovering resources for a user"
+author_name: jasonrudolph
+---
+
+Is your application taking advantage of the recommended workflow for discovering a user's repositories and organizations? With the [recent improvements to the API](/changes/2014-12-08-organization-permissions-api-preview/), the process is simpler than ever. In our newest guide, we show you how to [reliably identify the resources that your app can access for a given user](/guides/discovering-resources-for-a-user/).
+
+If you have any questions or feedback, we'd love to [hear from you][contact].
+
+[contact]: https://github.com/contact?form%5Bsubject%5D=API+v3:+Discovering+resources+for+a+user
diff --git a/content/changes/2015-01-19-an-integrators-guide-to-organization-application-policies.md b/content/changes/2015-01-19-an-integrators-guide-to-organization-application-policies.md
new file mode 100644
index 0000000000..0630465be3
--- /dev/null
+++ b/content/changes/2015-01-19-an-integrators-guide-to-organization-application-policies.md
@@ -0,0 +1,97 @@
+---
+title: "An integrator's guide to organization application policies"
+author_name: pengwynn
+---
+
+As we [announced over on the GitHub blog][ann], organization admins can now
+control how third-party applications access their organization data. Allowing
+admins to approve or deny applications will ultimately result in deeper trust
+and increase overall adoption of integrations within organizations on GitHub.
+
+As an integrator, here's what you need to know about organization application
+policies and how this feature could impact your application.
+
+### Guiding principles
+
+We've tried to strike the right balance between organization privacy and the
+user experience for integrators and end users. Organizations should be able to
+prevent applications they do not trust from accessing their organization data
+without creating a multitude of new edge cases for integrators.
+
+With that goal in mind, the feature works like this: **if an organization's
+application policy prevents an application from accessing its resources, the
+API behaves as if the authenticating user is not a member of the
+organization**. Specifically, this means an application authenticating on
+behalf of a user using OAuth will have:
+
+- **Read-only access to public resources.** Organization-owned public
+ repositories, issues, and other resources will be visible via the API and
+ show up in resource listings, but mutating methods (`POST`, `PATCH`, `PUT`,
+ and `DELETE`) will return status `403`.
+- **No access to private resources.** Organization-owned private repositories,
+ issues, and other resources will not be visible via the API and will not
+ show up in resource [listings][] that co-mingle public and private
+ resources. Hooks for these private repositories are muted and will not be
+ delivered as long as the application is restricted by the organization.
+
+Since applications should already handle the scenario where a user loses access
+to organization resources, this reduces the work integrators need to do.
+
+### Checking organization access
+
+As organization admins adopt application whitelists and restrict third-party
+application access to organization resources, your application may lose access
+to those resources. If an organization member is not aware of the new access
+policy, they may wonder why their private repositories or other resources no
+longer work or show up in your application.
+
+There are a couple ways to help troubleshoot access for your end users.
+
+- **Via the GitHub UI.** The simplest way to help end users understand how
+ organization access policies affect their access to your application is to
+ provide a link to [their authorization details][help-request-approval]
+ under their GitHub account settings as [described in the OAuth
+ documentation][auth-link].
+
+- **Via the API.** For an even better user experience, [use the
+ API][discovering-guide] to list which user organizations your application
+ can access, and provide users with the link mentioned above to request
+ access from their organization admins.
+
+### Listing accessible organization resources
+
+In addition to checking access to a user's organizations, you'll want to ensure
+you're discovering their accessible resources in the most efficient way. Recent
+changes to the [Repositories API][listing-repos] might reduce the API calls
+your application needs to make to find a user's repositories across all of
+their organization memberships.
+
+### Ensuring uninterrupted SSH access
+
+Since applications should already handle the scenario where a user loses access
+to organization resources (e.g., when a user leaves an organization), this
+reduces the work integrators need to do. Keys created by OAuth applications (or
+those created before GitHub started tracking that information) will not have
+access to repositories owned by organizations that restrict third-party
+applications. If your application uses keys **created before February 24,
+2014**, you [should replace those older keys][keys] to ensure things keep
+running smoothly for your application.
+
+### We're here to help
+
+This is a big feature, and we're sure it will impact many of our integrators as
+organizations adopt third-party application restrictions. We also think it
+provides a huge net benefit for integrators as organizations choose to use
+OAuth integrations with more confidence.
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[ann]: https://github.com/blog/1941-organization-approved-applications
+[auth-link]: /v3/oauth/#directing-users-to-review-their-access-for-an-application
+[help-request-approval]: https://help.github.com/articles/requesting-organization-approval-for-your-authorized-applications/
+[list-orgs]: /v3/orgs/#list-your-organizations
+[contact]: https://github.com/contact?form[subject]=Organization+Access+Policies+help+for+integrators
+[listing-repos]: /v3/repos/#list-your-repositories
+[discovering-guide]: /guides/discovering-resources-for-a-user/
+[keys]: /changes/2014-12-12-replace-older-ssh-keys-created-by-your-application/
+[listings]: /v3/issues/#list-issues
diff --git a/content/changes/2015-02-03-removing-authorizations-token-update.md b/content/changes/2015-02-03-removing-authorizations-token-update.md
new file mode 100644
index 0000000000..a7d53f037b
--- /dev/null
+++ b/content/changes/2015-02-03-removing-authorizations-token-update.md
@@ -0,0 +1,15 @@
+---
+title: Removing token attribute from Authorizations API responses (Update)
+author_name: ptoomey3
+---
+
+In December, we [released a preview][removing-authorizations-token] of several API changes related to managing OAuth application authorizations. As part of those changes we introduced several new response attributes (`token_last_eight`, `hashed_token`, and `fingerprint`) to the Authorizations API. We have decided to modify `hashed_token` to return the SHA-256 hex digest of the associated token instead of Base64. Given that Base64 has several common variants (original, URL safe, etc) we decided that returning the value as hex is less ambiguous and will be more useful for developers.
+
+### Extended preview period
+
+Because of the change to `hashed_token`, we are extending the preview period by two weeks. If no additional changes are made during this extended preview period we will announce the end of the preview and beginning of the eight week migration period on February 17. The migration period will allow applications to opt in to these changes before they become an official part of the GitHub API v3.
+
+If you have any questions or feedback, please [drop us a line][contact]!
+
+[removing-authorizations-token]: /changes/2014-12-08-removing-authorizations-token/
+[contact]: https://github.com/contact?form[subject]=Removing+authorizations+token
diff --git a/content/changes/2015-02-18-new-releases-api-methods.md b/content/changes/2015-02-18-new-releases-api-methods.md
new file mode 100644
index 0000000000..639bcb10b4
--- /dev/null
+++ b/content/changes/2015-02-18-new-releases-api-methods.md
@@ -0,0 +1,19 @@
+---
+title: New Releases API methods
+author_name: pengwynn
+---
+
+We've added two new methods to the [Releases API][]. You can now get the [latest published release][latest] for a repository.
+
+ GET /repos/:owner/:repo/releases/latest
+
+You can also get a [release by tag name][by-tag].
+
+ GET /repos/:owner/:repo/releases/tags/:tag
+
+If you have any questions or feedback, please [get in touch][contact].
+
+[Releases API]: /v3/repos/releases/
+[latest]: /v3/repos/releases/#get-the-latest-release
+[by-tag]: /v3/repos/releases/#get-a-release-by-tag-name
+[contact]: https://github.com/contact?form[subject]=New+Releases+API+methods
diff --git a/content/changes/2015-02-20-migration-period-removing-authorizations-token.md b/content/changes/2015-02-20-migration-period-removing-authorizations-token.md
new file mode 100644
index 0000000000..9b154e13f2
--- /dev/null
+++ b/content/changes/2015-02-20-migration-period-removing-authorizations-token.md
@@ -0,0 +1,38 @@
+---
+title: Breaking changes to Authorizations API responses on April 20
+author_name: ptoomey3
+---
+
+A couple weeks ago we [extended the preview period][removing-authorizations-token-extended-preview] of several API changes related to managing OAuth application authorizations. Today, we're finalizing these changes. This new functionality is now stable and suitable for production use. If your application relies on any of the affected functionality (described below), be sure to **update your code before April 20** to account for these changes.
+
+### Breaking changes coming on April 20
+
+If your application uses any of the following APIs, then you may be affected by this change:
+
+- The [List your authorizations][list-your-authorizations] API
+- The [Get a single authorization][get-a-single-authorization] API
+- The [Get-or-create an authorization for a specific app][get-or-create-an-authorization-for-a-specific-app] API (`token` is still returned for "create")
+- The [Get-or-create an authorization for a specific app and fingerprint][get-or-create-an-authorization-for-a-specific-app-and-fingerprint] API (`token` is still returned for "create")
+- The [Update an existing authorization][update-an-existing-authorization] API
+
+
+If your application uses these APIs, we urge you to update your application as soon as possible. (Read [the December announcement][removing-authorizations-token] for more details on the changes.)
+
+Starting today, we're offering a migration period allowing applications to opt in to these changes (as described below). On April 20, these changes will become official parts of the GitHub API v3. At that time, these changes will apply to all API consumers.
+
+### Migration period
+
+During the migration period, you can opt-in to these changes using the following custom media type in the `Accept` header:
+
+ application/vnd.github.mirage-preview+json
+
+We want to make these updates as smooth as possible for everyone, and we hope that the migration period gives you flexibility to adopt these changes on your own schedule. If you have any questions or feedback, please [get in touch with us][contact]!
+
+[removing-authorizations-token-extended-preview]: /changes/2015-02-03-removing-authorizations-token-update/
+[removing-authorizations-token]: /changes/2014-12-08-removing-authorizations-token/
+[list-your-authorizations]: /v3/oauth_authorizations/#list-your-authorizations
+[get-a-single-authorization]: /v3/oauth_authorizations/#get-a-single-authorization
+[get-or-create-an-authorization-for-a-specific-app]: /v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
+[get-or-create-an-authorization-for-a-specific-app-and-fingerprint]: /v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint
+[update-an-existing-authorization]: /v3/oauth_authorizations/#update-an-existing-authorization
+[contact]: https://github.com/contact?form[subject]=Removing+authorizations+token
diff --git a/content/changes/2015-02-24-more-time-to-prepare-for-the-breaking-changes-to-organization-permissions.md b/content/changes/2015-02-24-more-time-to-prepare-for-the-breaking-changes-to-organization-permissions.md
new file mode 100644
index 0000000000..0b9370abd7
--- /dev/null
+++ b/content/changes/2015-02-24-more-time-to-prepare-for-the-breaking-changes-to-organization-permissions.md
@@ -0,0 +1,11 @@
+---
+title: More time to prepare for the breaking changes to organization permissions
+author_name: jakeboxer
+---
+
+After listening to your feedback on the upcoming [breaking changes to organization permissions][org-permissions-preview], we're giving developers more time to update their applications. We'll announce an updated timeline for these changes in the coming weeks.
+
+In the meantime, if your application relies on any of the affected functionality described in our [previous blog post][org-permissions-preview], please **update your code** to account for these changes. If you have any questions or feedback, please [get in touch with us][contact]!
+
+[org-permissions-preview]: /changes/2014-12-08-organization-permissions-api-preview/
+[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API
diff --git a/content/changes/2015-03-09-licenses-api.md b/content/changes/2015-03-09-licenses-api.md
new file mode 100644
index 0000000000..c38277b3b5
--- /dev/null
+++ b/content/changes/2015-03-09-licenses-api.md
@@ -0,0 +1,24 @@
+---
+title: Licenses API
+author_name: benbalter
+---
+
+We're introducing a new [license API](/v3/licenses) preview to support [open source license usage on GitHub.com](https://github.com/blog/1964-license-usage-on-github-com).
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.drax-preview+json
+
+This will then expose two new API endpoints. You can get a list of all known licenses:
+
+ GET /licenses
+
+Or get information about a particular license:
+
+ GET /licenses/mit
+
+When the preview media type is passed, the repository api will also return information about a repository's license file when you get an individual repository:
+
+ GET /repos/github/hubot
+
+For more information, see the [licenses API documentation](/v3/licenses/), and if you have any questions or feedback, please [let us know](https://github.com/contact?form%5Bsubject%5D=Licenses+API).
diff --git a/content/changes/2015-04-17-preview-repository-redirects.md b/content/changes/2015-04-17-preview-repository-redirects.md
new file mode 100644
index 0000000000..9f185466b8
--- /dev/null
+++ b/content/changes/2015-04-17-preview-repository-redirects.md
@@ -0,0 +1,38 @@
+---
+title: Preview repository redirects
+author_name: jasonrudolph
+---
+
+From time to time, repository names change. If you make a GitHub API request using a repository's old name in the URL, the API has historically responded with `404 Not Found`. To help API clients gracefully handle renamed repositories, the API will soon begin [redirecting][redirects] to the repository's new location.
+
+You can preview these redirects now. In the coming weeks, we'll announce the timeline for enabling these redirects for everyone.
+
+## How can I try out the redirects?
+
+Starting today, developers can preview the redirect functionality for relocated repositories. To access this redirect functionality during the preview period, you’ll need to provide the following custom [media type][] in the `Accept` header:
+
+ application/vnd.github.quicksilver-preview+json
+
+During the preview period, we may change aspects of the redirect behavior based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+## When will the redirects occur?
+
+To understand when these redirects would take place, you'll want to understand how to identify a repository's location. Repositories are located using the combination of the owner's name and the repository's name. For example, the [@twbs][] organization owns the popular [bootstrap repository](https://github.com/twbs/bootstrap). We identify this repository as [twbs/bootstrap](https://github.com/twbs/bootstrap).
+
+The repository's location changes in the following scenarios:
+
+- When the owner changes the repository name.
+- When the owner renames their user account or organization account.
+- When the owner transfers the repository to a new owner.
+
+Continuing our [twbs/bootstrap](https://github.com/twbs/bootstrap) example, this repository used to be owned by the [@twitter][] organization, and it was therefore located at [twitter/bootstrap](https://github.com/twitter/bootstrap). With repository redirects, you'll be able to make an API request using the repository's old location and receive [either a `301` or `307` HTTP redirect][redirects], depending on the type of request being made. You can then follow the redirect to the new location.
+
+## Send us your feedback
+
+We hope you'll take these redirects for a spin and [let us know what you think][contact]. Happy redirecting!
+
+[@twbs]: https://github.com/twbs
+[@twitter]: https://github.com/twitter
+[contact]: https://github.com/contact?form%5Bsubject%5D=API+Repository+Redirects
+[media type]: /v3/media/
+[redirects]: /v3/#http-redirects
diff --git a/content/changes/2015-04-20-authorizations-api-response-changes-are-now-in-effect.md b/content/changes/2015-04-20-authorizations-api-response-changes-are-now-in-effect.md
new file mode 100644
index 0000000000..46a41d715e
--- /dev/null
+++ b/content/changes/2015-04-20-authorizations-api-response-changes-are-now-in-effect.md
@@ -0,0 +1,36 @@
+---
+title: Authorizations API response changes are now in effect
+author_name: ptoomey3
+---
+
+Two months ago, we
+[announced the migration period][migration-period-announcement]
+for several [API changes related to managing OAuth authorizations][original-announcement].
+As promised, the migration period concluded today, and these changes are
+now in effect for all requests.
+
+### Preview media type no longer needed
+
+If you used the updated Authorizations API during the migration period, you needed
+to provide a custom media type in the `Accept` header:
+
+ application/vnd.github.mirage-preview+json
+
+Now that the migration period has ended, you no longer need to pass this custom
+media type.
+
+Instead, we [recommend][media-types] that you specify `v3` as the version in the
+`Accept` header:
+
+ application/vnd.github.v3+json
+
+### Feedback
+
+As always, if you have any feedback, please don't hesitate to
+[get in touch with us][contact].
+
+[migration-period-announcement]: /changes/2015-02-20-migration-period-removing-authorizations-token
+[original-announcement]: /changes/2014-12-08-removing-authorizations-token/
+[docs]: /v3/oauth_authorizations
+[media-types]: /v3/media
+[contact]: https://github.com/contact?form[subject]=Removing+token+from+Authorizations+API
diff --git a/content/changes/2015-04-21-organization-hooks-api-finalized.md b/content/changes/2015-04-21-organization-hooks-api-finalized.md
new file mode 100644
index 0000000000..9d0e70aea1
--- /dev/null
+++ b/content/changes/2015-04-21-organization-hooks-api-finalized.md
@@ -0,0 +1,28 @@
+---
+title: Organization Webhooks API finalized
+author_name: pengwynn
+---
+
+After [four months in preview release][ann], the [Organization Webhooks API][docs] is now considered stable and ready for production use.
+
+### Preview media type no longer needed
+
+During the preview period, you needed to provide a custom media type in the `Accept` header when using the Organization Webhooks API:
+
+ application/vnd.github.sersi-preview+json
+
+Now that the preview has ended, you no longer need to pass this custom
+media type, though providing an explicit [media type][media-types] is recommended:
+
+ application/vnd.github.v3+json
+
+### Feedback
+
+If you have any questions or feedback on this API, please [get in touch][contact].
+
+[ann]: /changes/2014-12-03-preview-the-new-organization-webhooks-api/
+[docs]: /v3/orgs/hooks
+[media-types]: /v3/media
+[contact]: https://github.com/contact?form%5Bsubject%5D=Organization+Webhooks
+
+
diff --git a/content/changes/2015-05-26-repository-redirects-are-coming.md b/content/changes/2015-05-26-repository-redirects-are-coming.md
new file mode 100644
index 0000000000..ff577c0648
--- /dev/null
+++ b/content/changes/2015-05-26-repository-redirects-are-coming.md
@@ -0,0 +1,20 @@
+---
+title: Repository redirects are coming to API v3 in July
+author_name: jasonrudolph
+---
+
+Last month, we announced the [upcoming repository redirect behavior for the API][original announcement], and we made it available for developers to preview. Starting **July 21, 2015**, the API will automatically provide these redirects for all API consumers.
+
+To learn more about repository redirects and how they will benefit your applications, be sure to check out the [original announcement][].
+
+To start enjoying repository redirects right away, just provide the following custom [media type][] in the `Accept` header:
+
+ application/vnd.github.quicksilver-preview+json
+
+Thanks to everyone that tried out this enhancement during the preview period.
+
+As always, if you have any questions, please [get in touch][contact]. We love hearing from you.
+
+[media type]: /v3/media/
+[original announcement]: /changes/2015-04-17-preview-repository-redirects/
+[contact]: https://github.com/contact?form%5Bsubject%5D=API+Repository+Redirects
diff --git a/content/changes/2015-06-10-breaking-changes-to-organization-permissions-coming-on-june-24.md b/content/changes/2015-06-10-breaking-changes-to-organization-permissions-coming-on-june-24.md
new file mode 100644
index 0000000000..d56295e02b
--- /dev/null
+++ b/content/changes/2015-06-10-breaking-changes-to-organization-permissions-coming-on-june-24.md
@@ -0,0 +1,37 @@
+---
+title: Breaking changes to organization permissions coming on June 24
+author_name: jakeboxer
+---
+
+Back in January, we [encouraged developers to update their applications][org-permissions-finalization] to prepare for [upcoming API changes][org-permissions-preview] related to managing organization members and repositories. In order to support the upcoming [improvements to organization permissions][direct-org-membership-blog-post], these changes will become official parts of GitHub API v3 on **June 24**.
+
+If your application relies on any of the affected functionality (described below), be sure to **update your code before June 24** to account for these changes.
+
+## Breaking changes coming on June 24
+
+If your application uses any of the following APIs, then you are affected by this change:
+
+- APIs for managing your organization's admins through the Owners team
+- The [List your repositories][list-your-repos] API
+- The [List your organizations][list-your-organizations] API
+- The [List user organizations][list-user-organizations] API
+
+If your application uses these APIs, we urge you to update your application as soon as possible. (Read [December's announcement][org-permissions-preview] for full details on the changes.)
+
+In January, we [announced a migration period][org-permissions-finalization] allowing API consumers to opt in to these changes. If you haven't already opted in to these changes, you still do so as described below. On June 24, these changes will become official parts of GitHub API v3. At that time, these changes will apply to all API consumers.
+
+## Migration period
+
+During these final days of the migration period, you can opt in to these changes using the following custom media type in the `Accept` header:
+
+ application/vnd.github.moondragon+json
+
+We want to make these updates as smooth as possible for everyone, and we hope that the migration period gives you flexibility to adopt these changes on your own schedule. If you have any questions or feedback, please [get in touch with us][contact]!
+
+[org-permissions-finalization]: /changes/2015-01-07-prepare-for-organization-permissions-changes/
+[org-permissions-preview]: /changes/2014-12-08-organization-permissions-api-preview/
+[direct-org-membership-blog-post]: https://github.com/blog/2020-improved-organization-permissions/
+[list-your-repos]: /v3/repos/#list-your-repositories
+[list-user-organizations]: /v3/orgs/#list-user-organizations
+[list-your-organizations]: /v3/orgs/#list-your-organizations
+[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API
diff --git a/content/changes/2015-06-11-pages-a-records.md b/content/changes/2015-06-11-pages-a-records.md
new file mode 100644
index 0000000000..a18197d3b8
--- /dev/null
+++ b/content/changes/2015-06-11-pages-a-records.md
@@ -0,0 +1,31 @@
+---
+title: GitHub Pages' A Records Added to Meta API
+author_name: leereilly
+---
+
+The [Meta API](/v3/meta/) now includes the A record IP addresses for [GitHub Pages](https://pages.github.com/).
+
+``` command-line
+$ curl https://api.github.com/meta
+```
+
+``` json
+{
+ "verifiable_password_authentication": true,
+ "github_services_sha": "23c6105183b626cf74c045f6d53af7a178bfdb4c",
+ "hooks": [
+ "192.30.252.0/22"
+ ],
+ "git": [
+ "192.30.252.0/22"
+ ],
+ "pages": [
+ "192.30.252.153/32",
+ "192.30.252.154/32"
+ ]
+}
+```
+
+These IP addresses are used to [configure A records with your DNS provider for GitHub Pages](https://help.github.com/articles/tips-for-configuring-an-a-record-with-your-dns-provider/). These addresses have changed a few times in the past. This API always provides the current addresses so that you can automate the process of keeping your DNS records up to date.
+
+If you have any questions, please [get in touch](https://github.com/contact?form%5Bsubject%5D=GitHub+Pages+A+Records+Added+to+API). We’ll be happy to help.
diff --git a/content/changes/2015-06-17-organizations-endpoint.md b/content/changes/2015-06-17-organizations-endpoint.md
new file mode 100644
index 0000000000..39326640a0
--- /dev/null
+++ b/content/changes/2015-06-17-organizations-endpoint.md
@@ -0,0 +1,29 @@
+---
+title: List all organizations
+author_name: keavy
+---
+
+We've added a [new API method](/v3/orgs#list-all-organizations) to list all organizations:
+
+``` command-line
+$ curl https://api.github.com/organizations
+
+> [
+> {
+> "login": "github",
+> "id": 9919,
+> "url": "https://api.github.com/orgs/github",
+> "repos_url": "https://api.github.com/orgs/github/repos",
+> "events_url": "https://api.github.com/orgs/github/events",
+> "members_url": "https://api.github.com/orgs/github/members{/member}",
+> "public_members_url": "https://api.github.com/orgs/github/public_members{/member}",
+> "avatar_url": "https://avatars.githubusercontent.com/u/9919?v=3",
+> "description": "GitHub, the company."
+> },
+> ...
+> ]
+```
+
+As always, if you have any questions or feedback, please [drop us a line][contact].
+
+[contact]: https://github.com/contact?form[subject]=API+-+Listing+Organizations
diff --git a/content/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions.md b/content/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions.md
new file mode 100644
index 0000000000..1bd6623359
--- /dev/null
+++ b/content/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions.md
@@ -0,0 +1,86 @@
+---
+title: API enhancements for working with organization permissions
+author_name: jakeboxer
+---
+
+We're introducing several enhancements to allow API developers to take advantage of the [improved organization permissions][dotcom-blog-post] that we are rolling out. Learn about these enhancements and how you can try them out below.
+
+Since we're rolling out the [improved organization permissions][dotcom-blog-post] improvements slowly, these enhancements will only apply to certain organizations at first. Most of these enhancements will degrade gracefully (returning an empty array or something similar) if used on an organization that doesn't support improved organization permissions yet. Check the documentation for your specific API to see if errors are possible.
+
+## API enhancements
+
+### Team permissions
+
+In our improved permissions system, a team no longer has a single permission that applies to all of its repositories. Instead, each repository is added to a team with its own permission. For example, an organization could use a single team to grant pull access to one repository, push access to a second, and admin access to a third.
+
+The team APIs now support this more granular notion of permissions:
+
+- The [Add team repository][add-team-repo] API accepts a `permission` parameter, so that you can specify whether a team should grant `pull`, `push`, or `admin` access on a given repository.
+- In the [List team repositories][list-team-repos] and [Check if a team manages a repository][get-team-repo] API, the response includes a `permissions` attribute, indicating whether the team grants `pull`, `push`, or `admin` access on each repository.
+- The `permission` parameter in the [Create team][create-team] and [Edit team][edit-team] APIs is deprecated. Since teams can grant a different permission on each repository, this parameter no longer dictates what permission a team grants on all of its repositories. Instead, it dictates the default permission that the [Add team repository][add-team-repo] API will use for requests where no `permission` parameter is specified.
+
+### Team privacy
+
+We now allow you to modify the privacy level of your teams. A "secret" team can only be seen by organization owners and people who are members of that team (which is how all teams have worked historically), while a "closed" team is visible to every member of the organization (which makes it easier to use [@mentions][team-mentions] throughout your organization).
+
+The team APIs now support this new team privacy concept:
+
+- The [Create team][create-team] and [Edit team][edit-team] APIs accept a `privacy` parameter, so that you can specify whether a team should be `secret` or `closed`.
+- All team resources in the API now include a `privacy` attribute, indicating whether the team is `secret` or `closed`.
+
+### Team maintainers
+
+We've added the ability for you to delegate team maintenance to non-owners, reducing the workload for your organization's owners. You can now promote a non-owner member of a team to be a "maintainer" of that team. A maintainer can add and remove team members and change the team's title and description.
+
+The team membership APIs now support this new team maintainer concept:
+
+- The [Add team membership][add-team-membership] API accepts a `role` parameter, so that you can specify whether a given team member should be a `maintainer` or a regular `member`.
+- The [List team members][list-team-members] API accepts an optional `role` parameter, allowing you to fetch only `maintainer`s or only regular `member`s.
+- In the [Get team membership][get-team-membership] and [Add team membership][add-team-membership] APIs, the response includes a `role` attribute, indicating whether a user is a `maintainer` or a regular `member` of the team.
+
+For more information on our improved team permissions, check out our [documentation][understanding-team-permissions].
+
+### Filtering organization members by role
+
+The organization [Members list][org-members-list] API now accepts a `role` parameter, so that you can request to see only the owners (or non-owners) of your organization.
+
+### Repository collaborators
+
+We now allow you to add collaborators directly to organization-owned repositories, just like we always have for user-owned repositories.
+
+The collaborator APIs now support organization-owned repositories:
+
+- The [Add user as a collaborator][add-collab] API works for organization-owned repositories. We've also added a `permission` parameter to it (currently valid for organization-owned repositories only), so that you can specify what level of access the collaborator should have on the repository.
+- In the [List collaborators][list-collabs] API, the response includes a `permissions` attribute describing the permissions that each collaborator has on your organization's repositories.
+
+## Preview period
+
+Starting today, these API enhancements are available for developers to preview. At the end of the preview period, these enhancements will become official components of the GitHub API.
+
+While these enhancements are in their preview period, you'll need to provide the following [custom media type][custom-media-types] in the `Accept` header:
+
+ application/vnd.github.ironman-preview+json
+
+During the preview period, we may change aspects of these enhancements. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.
+
+## Send us your feedback
+
+We would love to hear your thoughts on these enhancements. If you have any questions or feedback, please [get in touch with us][contact]!
+
+[dotcom-blog-post]: https://github.com/blog/2020-improved-organization-permissions
+[understanding-team-permissions]: https://help.github.com/articles/improved-organization-permissions/#understanding-team-permissions
+[create-team]: /v3/orgs/teams/#create-team
+[edit-team]: /v3/orgs/teams/#edit-team
+[list-team-members]: /v3/orgs/teams/#list-team-members
+[get-team-membership]: /v3/orgs/teams/#get-team-membership
+[add-team-membership]: /v3/orgs/teams/#add-team-membership
+[list-team-repos]: /v3/orgs/teams/#list-team-repos
+[get-team-repo]: /v3/orgs/teams/#check-if-a-team-manages-a-repository
+[add-team-repo]: /v3/orgs/teams/#add-or-update-team-repository
+[org-members-list]: /v3/orgs/members/#members-list
+[org-public-members-list]: /v3/orgs/members/#public-members-list
+[list-collabs]: /v3/repos/collaborators/#list-collaborators
+[add-collab]: /v3/repos/collaborators/#add-user-as-a-collaborator
+[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API
+[team-mentions]: https://github.com/blog/1121-introducing-team-mentions
+[custom-media-types]: /v3/media/
diff --git a/content/changes/2015-06-24-breaking-changes-to-organization-permissions-are-now-official.md b/content/changes/2015-06-24-breaking-changes-to-organization-permissions-are-now-official.md
new file mode 100644
index 0000000000..fdecc9b91d
--- /dev/null
+++ b/content/changes/2015-06-24-breaking-changes-to-organization-permissions-are-now-official.md
@@ -0,0 +1,16 @@
+---
+title: Breaking changes to organization permissions are now official
+author_name: jakeboxer
+---
+
+As [promised earlier this month][notice], the [API changes][api-changes] related to managing organization members and repositories are now official parts of the GitHub API.
+
+During the migration period, you needed to [provide a custom media type in the `Accept` header][migration-period] to opt-in to the changes. Now that the migration period has ended, you no longer need to specify this custom [media type][media-types].
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[notice]: /changes/2015-06-10-breaking-changes-to-organization-permissions-coming-on-june-24
+[api-changes]: /changes/2014-12-08-organization-permissions-api-preview/
+[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API
+[media-types]: /v3/media
+[migration-period]: /changes/2015-06-10-breaking-changes-to-organization-permissions-coming-on-june-24/#migration-period
diff --git a/content/changes/2015-06-24-licenses-api-update.md b/content/changes/2015-06-24-licenses-api-update.md
new file mode 100644
index 0000000000..26f5b340d3
--- /dev/null
+++ b/content/changes/2015-06-24-licenses-api-update.md
@@ -0,0 +1,20 @@
+---
+title: Licenses API update
+author_name: mislav
+---
+
+We are expanding the [Licenses API](/v3/licenses) to make it more useful for auditing license usage across all repositories owned by a user or organization.
+
+Before, license information was only returned for an individual repository:
+
+ GET /repos/github/hubot
+
+Now, license information will also be included in responses from endpoints that list multiple repositories, such as [List organization repositories](/v3/repos/#list-organization-repositories):
+
+ GET /orgs/github/repos
+
+As before, to access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.drax-preview+json
+
+For more information, see the [Licenses API documentation](/v3/licenses/), and if you have any questions or feedback, please [let us know](https://github.com/contact?form%5Bsubject%5D=Licenses+API).
diff --git a/content/changes/2015-07-21-automatic-redirects-for-renamed-repositories.md b/content/changes/2015-07-21-automatic-redirects-for-renamed-repositories.md
new file mode 100644
index 0000000000..4477688d15
--- /dev/null
+++ b/content/changes/2015-07-21-automatic-redirects-for-renamed-repositories.md
@@ -0,0 +1,15 @@
+---
+title: Automatic redirects for renamed repositories
+author_name: jasonrudolph
+---
+
+To help API clients gracefully handle renamed repositories, the API now [automatically redirects to the repository’s new location][original-announcement].
+
+Our thanks goes out to everyone that tried out this enhancement [during the preview period][original-announcement]. During the preview period, you needed to [provide a custom media type in the `Accept` header][preview-media-type] to opt-in to the redirects. Now that the preview period has ended, you no longer need to specify this custom [media type][].
+
+To learn more about these redirects and how they benefit your applications, be sure to check out the [preview period announcement][original-announcement]. As always, if you have any questions, we're [here to help][contact].
+
+[contact]: https://github.com/contact?form%5Bsubject%5D=API+Repository+Redirects
+[media type]: /v3/media/
+[original-announcement]: /changes/2015-04-17-preview-repository-redirects/
+[preview-media-type]: /changes/2015-04-17-preview-repository-redirects/#how-can-i-try-out-the-redirects
diff --git a/content/changes/2015-07-22-more-flexible-options-for-listing-repositories.md b/content/changes/2015-07-22-more-flexible-options-for-listing-repositories.md
new file mode 100644
index 0000000000..26a762e414
--- /dev/null
+++ b/content/changes/2015-07-22-more-flexible-options-for-listing-repositories.md
@@ -0,0 +1,16 @@
+---
+title: More flexible options for listing repositories
+author_name: jakeboxer
+---
+
+The [List your repositories][list-your-repos] API now offers additional parameters to help you fetch the exact set of repositories you're looking for:
+
+- The `visibility` parameter lets you request only your public repositories, only your private repositories, or both.
+- With the `affiliation` parameter, you can ask for repositories you own, repositories where you are a collaborator, repositories you have access to as an organization member, or any combination that suits your needs.
+
+Use these new parameters separately, together, or in combination with other parameters to craft flexible queries that fetch the specific repositories you're seeking.
+
+For full details, check out the [documentation][list-your-repos]. If you have any questions, please [get in touch][contact]!
+
+[list-your-repos]: /v3/repos/#list-your-repositories
+[contact]: https://github.com/contact?form[subject]=List+your+repositories+API
diff --git a/content/changes/2015-08-04-get-license-contents.md b/content/changes/2015-08-04-get-license-contents.md
new file mode 100644
index 0000000000..676bfbc447
--- /dev/null
+++ b/content/changes/2015-08-04-get-license-contents.md
@@ -0,0 +1,24 @@
+---
+title: Get the contents of a repository’s license
+author_name: benbalter
+---
+
+The [License API Preview](/v3/licenses/) now allows you to retrieve the contents of a repository's open source license. As before, when the appropriate preview media type is passed, the repository endpoint will return information about the detected license, if any:
+
+``` command-line
+curl -H "Accept: application/vnd.github.drax-preview+json" https://api.github.com/repos/benbalter/gman
+```
+
+You can now also get the contents of the repository's license file, whether or not the license was successfully identified via the license contents endpoint:
+
+``` command-line
+curl -H "Accept: application/vnd.github.drax-preview+json" https://api.github.com/repos/benbalter/gman/license
+```
+
+Similar to [the repository contents API](/v3/repos/contents/#get-contents), the license contents method also supports [custom media types](/v3/repos/contents/#custom-media-types) for retrieving the raw license content or rendered license HTML.
+
+``` command-line
+curl -H "Accept: application/vnd.github.drax-preview.raw" https://api.github.com/repos/benbalter/gman/license
+```
+
+For more information, see [the license API documentation](/v3/licenses/#get-the-contents-of-a-repositorys-license), and as always, if you have any questions or feedback, please [get in touch with us](https://github.com/contact?form%5Bsubject%5D=License+API).
diff --git a/content/changes/2015-09-03-ensure-your-app-is-ready-for-protected-branches.md b/content/changes/2015-09-03-ensure-your-app-is-ready-for-protected-branches.md
new file mode 100644
index 0000000000..e32d9ef35f
--- /dev/null
+++ b/content/changes/2015-09-03-ensure-your-app-is-ready-for-protected-branches.md
@@ -0,0 +1,55 @@
+---
+title: Ensure your app is ready for Protected Branches
+author_name: aroben
+---
+
+We’ve begun to [roll out Protected Branches][blog] across GitHub. When you
+protect a branch in one of your repositories, you will be prevented from
+force pushing to that branch or deleting it. You can also configure required
+status checks for your protected branch. When configured, changing a branch to
+point at a new commit will fail unless that commit (or another commit with
+the same [Git tree][tree]) has a [Status][statuses] in the `success` state for
+each required status check.
+
+These restrictions apply to branch manipulations performed via the GitHub API
+as well. So when you protect a branch, you will no longer be able to [delete
+the branch][delete] via the API or [update it][update] to point at a
+non-ancestor commit, even with `"force": true`. And if your branch has required
+status checks, you won’t be able to [update it][update] or [merge pull
+requests][merge] into that branch until `success` Statuses have been posted to
+the target commit for all required status checks.
+
+These restrictions are all represented by 422 errors:
+
+``` command-line
+$ curl -i -H 'Authorization: token TOKEN' \
+$ -X DELETE https://api.github.com/repos/octocat/hubot/git/refs/heads/master
+
+> HTTP/1.1 422 Unprocessable Entity
+> {
+> "message": "Cannot delete a protected branch",
+> "documentation_url": "https://help.github.com/articles/about-protected-branches"
+> }
+```
+
+Protected branches and required status checks are a great way to ensure your
+project’s conventions are followed. For example, you could write a Status
+integration that only posts a `success` Status when the pull request’s author
+has signed your project’s Contributor License Agreement. Or you could write one
+that only posts a `success` Status when three or more members of your
+`@initech/senior-engineers` team have left a comment saying they’ve reviewed
+the changes. If you configure these integrations as required status checks, you
+can be sure that these conditions have been satisfied before a pull request is
+merged. See our [Status API guide][guide] to learn how to create integrations
+like these.
+
+If you have any questions, please [let us know][contact].
+
+[blog]: https://github.com/blog/2051-protected-branches-and-required-status-checks
+[statuses]: /v3/repos/statuses/
+[tree]: http://git-scm.com/book/en/v2/Git-Internals-Git-Objects#Tree-Objects
+[delete]: /v3/git/refs/#delete-a-reference
+[update]: /v3/git/refs/#update-a-reference
+[merge]: /v3/pulls/#merge-a-pull-request-merge-button
+[contact]: https://github.com/contact?form[subject]=Protected+Branches+in+API+responses
+[guide]: /guides/building-a-ci-server/
diff --git a/content/changes/2015-11-11-protected-branches-api.md b/content/changes/2015-11-11-protected-branches-api.md
new file mode 100644
index 0000000000..6b09f0ac9b
--- /dev/null
+++ b/content/changes/2015-11-11-protected-branches-api.md
@@ -0,0 +1,40 @@
+---
+title: Protected Branches API Preview Period
+author_name: nakajima
+---
+
+**UPDATE (2016-06-27):** As [announced](/changes/2016-06-27-protected-branches-api-update/), there is an extended version of the protected branches API available. This older version will be removed once the new one becomes official.
+
+We're starting a preview period for the [protected branches](https://github.com/blog/2051-protected-branches-and-required-status-checks) API. Protecting a branch prevents force-pushes to it as well as deleting it. You can also specify required status checks that are required to merge code into the branch.
+
+To protect a branch, make a `PATCH` request to the URL of the branch:
+
+``` command-line
+curl "https://api.github.com/repos/github/hubot/branches/master" \
+ -XPATCH \
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.loki-preview" \
+ -d '{
+ "protection": {
+ "enabled": true,
+ "required_status_checks": {
+ "enforcement_level": "everyone",
+ "contexts": [
+ "required-status"
+ ]
+ }
+ }
+ }'
+```
+
+#### How can I try it?
+
+To access this functionality during the preview period, you’ll need to provide the following custom media type in the Accept header:
+
+```
+application/vnd.github.loki-preview+json
+```
+
+Take a look at [the docs here](/v3/repos/branches/).
+
+If you have any questions, please [get in touch](https://github.com/contact?form%5Bsubject%5D=Protected+Branches+API+Preview).
diff --git a/content/changes/2016-01-05-api-enhancements-for-working-with-organization-permissions-are-now-official.md b/content/changes/2016-01-05-api-enhancements-for-working-with-organization-permissions-are-now-official.md
new file mode 100644
index 0000000000..84fb64bbb2
--- /dev/null
+++ b/content/changes/2016-01-05-api-enhancements-for-working-with-organization-permissions-are-now-official.md
@@ -0,0 +1,16 @@
+---
+title: API enhancements for working with organization permissions are now official
+author_name: jakeboxer
+---
+
+To allow API developers to take advantage of the [improved organization permissions][dotcom-blog-post] that launched in September 2015, we're making the [API enhancements][api-enhancements-blog-post] for working with organization permissions a part of the official GitHub API.
+
+During the preview period, you needed to [provide a custom media type in the `Accept` header][preview-period] to opt-in to the changes. Now that the preview period has ended, you no longer need to specify this custom [media type][custom-media-types].
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[dotcom-blog-post]: https://github.com/blog/2064-new-organization-permissions-now-available
+[api-enhancements-blog-post]: /changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/
+[preview-period]: /changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/#preview-period
+[custom-media-types]: /v3/media/
+[contact]: https://github.com/contact?form[subject]=Organization+Permissions+API
diff --git a/content/changes/2016-02-11-issue-locking-api.md b/content/changes/2016-02-11-issue-locking-api.md
new file mode 100644
index 0000000000..07177d4910
--- /dev/null
+++ b/content/changes/2016-02-11-issue-locking-api.md
@@ -0,0 +1,43 @@
+---
+title: Issue Locking and Unlocking API Preview Period
+author_name: davidcelis
+---
+
+We're introducing new API methods to allow repository collaborators to [lock and unlock conversations][lock-an-issue]. Developers with [collaborator permissions][permissions] on a repository can start experimenting with these new endpoints today during the preview period.
+
+To lock a conversation, make a `PUT` request to the conversation's issue:
+
+``` command-line
+$ curl "https://api.github.com/repos/github/hubot/issues/1/lock" \
+ -X PUT \
+ -H "Authorization: token $TOKEN" \
+ -H "Content-Length: 0" \
+ -H "Accept: application/vnd.github.the-key-preview"
+```
+
+To unlock a conversation, make a similarly constructed `DELETE` request:
+
+``` command-line
+$ curl "https://api.github.com/repos/github/hubot/issues/1/lock" \
+ -X DELETE \
+ -H "Authorization: token $TOKEN" \
+ -H "Accept: application/vnd.github.the-key-preview"
+```
+
+#### How can I try it?
+
+Starting today, developers can preview these new API methods. To use them during the preview period, you’ll need to provide the following custom [media type][media-types] in the `Accept` header:
+
+```
+application/vnd.github.the-key-preview+json
+```
+
+During the preview period, we may change aspects of these API methods based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+Take a look at [the documentation][docs] and, if you have any questions, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form%5Bsubject%5D=Issue+Locking+and+Unlocking+API+Preview
+[docs]: /v3/issues/#lock-an-issue
+[lock-an-issue]: https://help.github.com/articles/locking-conversations/
+[media-types]: /v3/media/
+[permissions]: https://help.github.com/articles/what-are-the-different-access-permissions/
diff --git a/content/changes/2016-02-19-source-import-preview-api.md b/content/changes/2016-02-19-source-import-preview-api.md
new file mode 100644
index 0000000000..1caf3c446e
--- /dev/null
+++ b/content/changes/2016-02-19-source-import-preview-api.md
@@ -0,0 +1,18 @@
+---
+title: Preview the Source Import API
+author_name: spraints
+---
+
+We've added an API for source imports, which will let you start an import from a Git, Subversion, Mercurial, or Team Foundation Server source repository. This is the same functionality as [the GitHub Importer](https://help.github.com/articles/importing-from-other-version-control-systems-to-github/).
+
+To access [the Source Import API][docs] during the preview period, you must provide a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.barred-rock-preview
+
+During the preview period, we may change aspects of these API methods based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+If you have any questions or feedback, please [let us know][contact]!
+
+[media-type]: /v3/media
+[docs]: /v3/migration/source_imports/
+[contact]: https://github.com/contact?form%5Bsubject%5D=Source+Import+API
diff --git a/content/changes/2016-02-24-commit-reference-sha-api.md b/content/changes/2016-02-24-commit-reference-sha-api.md
new file mode 100644
index 0000000000..e78af07bab
--- /dev/null
+++ b/content/changes/2016-02-24-commit-reference-sha-api.md
@@ -0,0 +1,41 @@
+---
+title: Commit Reference SHA-1 Preview Period
+author_name: mikemcquaid
+---
+
+We're introducing a new API media type to allow users to get the SHA-1 of a commit reference. This can be useful in working out if you have the latest version of a remote branch based on your local branch's SHA-1. Developers with read access to a repository can start experimenting with this new media type today during the preview period.
+
+To get the commit reference's SHA-1, make a `GET` request to the repository's reference:
+
+``` command-line
+$ curl "https://api.github.com/repos/Homebrew/homebrew/commits/master" \
+ -H "Accept: application/vnd.github.chitauri-preview+sha"
+```
+
+To check if a remote branch's SHA-1 is the same as your local branch's SHA-1, make a `GET` request to the repository's branch and provide the current SHA-1 for the local branch as the ETag:
+
+``` command-line
+$ curl "https://api.github.com/repos/Homebrew/homebrew/commits/master" \
+ -H "Accept: application/vnd.github.chitauri-preview+sha" \
+ -H "If-None-Match: \"814412cfbd631109df337e16c807207e78c0d24e\""
+```
+
+If the remote and your local branch point to the same SHA-1 then this call will return a `304 Unmodified` status code (and not use your rate limit).
+
+You can see an example of this API in a pull request to Homebrew/homebrew's updater: https://github.com/Homebrew/homebrew/pull/49219.
+
+#### How can I try it?
+
+To use this new API media type during the preview period, you’ll need to provide the following custom [media type][media-types] in the `Accept` header:
+
+```
+application/vnd.github.chitauri-preview+sha
+```
+
+During the preview period, we may change aspects of this API media type based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+Take a look at [the documentation][docs] and, if you have any questions, please [get in touch][contact].
+
+[contact]: https://github.com/contact?form%5Bsubject%5D=Commit+Reference+SHA-1+Preview
+[docs]: /v3/repos/commits/#get-the-sha-1-of-a-commit-reference
+[media-types]: /v3/media/
diff --git a/content/changes/2016-03-15-new-webhook-actions.md b/content/changes/2016-03-15-new-webhook-actions.md
new file mode 100644
index 0000000000..82e916d655
--- /dev/null
+++ b/content/changes/2016-03-15-new-webhook-actions.md
@@ -0,0 +1,53 @@
+---
+title: New webhook event actions are coming
+author_name: davidcelis
+---
+
+We will soon begin introducing new `action` values for several existing webhook events. If you currently subscribe to webhooks but do not check the payload's `action` value, you may end up incorrectly processing events after this change is released. To ensure that your webhook processing is not affected by these new `action` values, **you should audit your webhook processing logic by April 15th, 2016**.
+
+We are providing an advance notice to warn of these changes. In the future, we may continue adding new actions without providing further warning.
+
+### A brief overview of GitHub webhook actions
+
+Webhook events can have multiple actions. For example, the [`IssuesEvent`](https://developer.github.com/v3/activity/events/types/#issuesevent) has several possible actions. These include `opened` when the issue is created, `closed` when the issue is closed, and `assigned` when the issue is assigned to someone. Historically, we haven't added new actions to webhook events that have only one action. However, as GitHub's feature set grows, we may occasionally add new actions to existing event types. We encourage you to take some time and ensure that your application explicitly checks the action before doing any processing.
+
+### What to avoid when working with event actions
+
+Here's an example of functionality that **will not work** when attempting to process an `IssuesEvent`. In this example, the `process_closed` method will be called for any event action which is not `opened` or `assigned`. This means that the `process_closed` method will be called for events with the `closed` action, but also other events with actions other than `opened` or `assigned` that are delivered to the webhook.
+
+```ruby
+# The following is not future-proof!
+case action
+when "opened"
+ process_opened
+when "assigned"
+ process_assigned
+else
+ process_closed
+end
+```
+
+### How to work with new event actions
+
+We suggest that you explicitly check event actions and act accordingly. In this example, the `closed` action is checked first before calling the `process_closed` method. Additionally, for unknown actions, we log that something new was encountered:
+
+```ruby
+# The following is recommended
+case action
+when "opened"
+ process_opened
+when "assigned"
+ process_assigned
+when "closed"
+ process_closed
+else
+ puts "Ooohh, something new from GitHub!"
+end
+```
+
+We may also add new webhook event types from time to time. If your webhook is configured to "Send me **everything**", your code should also explicitly check for the event type in a similar way as we have done with checking for the action type above. Take a look at our [integrators best practices guide][best-practices] for more tips.
+
+If you have any questions or feedback, please [get in touch][get-in-touch].
+
+[best-practices]: https://developer.github.com/guides/best-practices-for-integrators/
+[get-in-touch]: https://github.com/contact?form[subject]=New+Webhook+Actions
diff --git a/content/changes/2016-03-17-the-451-status-code-is-now-supported.md b/content/changes/2016-03-17-the-451-status-code-is-now-supported.md
new file mode 100644
index 0000000000..d9c1d1a451
--- /dev/null
+++ b/content/changes/2016-03-17-the-451-status-code-is-now-supported.md
@@ -0,0 +1,26 @@
+---
+title: The 451 status code is now supported
+author_name: gjtorikian
+---
+
+In December 2015, [the IETF ratified status code `451`](https://datatracker.ietf.org/doc/rfc7725/). A `451` response indicates that a resource is unavailable due to an external legal request.
+
+The GitHub API will now respond with a `451` status code for resources it has been asked to take down due to a DMCA notice. For example:
+
+``` command-line
+$ curl https://api.github.com/repos/github/a-repository-that-s-been-taken-down
+> HTTP/1.1 451
+> Server: GitHub.com
+
+> {
+> "message": "Repository access blocked",
+> "block": {
+> "reason": "dmca",
+> "created_at": "2016-03-17T15:39:46-07:00"
+> }
+> }
+```
+
+This `451` code will be returned for repositories and gists. Previously, the API responded with a `403 - Forbidden`. Aside from the semantic difference, we feel that it's important for users to know precisely why their data cannot be served.
+
+If you're receiving a `451` due to a DMCA takedown, please read our article on [submitting a DMCA counter notice](https://help.github.com/articles/guide-to-submitting-a-dmca-counter-notice/) and know your rights. For more information, see [GitHub's DMCA Takedown Policy](https://help.github.com/articles/dmca-takedown-policy/).
diff --git a/content/changes/2016-04-01-squash-api-preview.md b/content/changes/2016-04-01-squash-api-preview.md
new file mode 100644
index 0000000000..9d43ccac5e
--- /dev/null
+++ b/content/changes/2016-04-01-squash-api-preview.md
@@ -0,0 +1,29 @@
+---
+title: Preview Squash Support for the Pull Request Merge API
+author_name: scottjg
+---
+
+With the [recent addition](https://github.com/blog/2141-squash-your-commits) of squashing Pull Requests via the merge button, we're adding support to squash Pull Requests in the API as well. You can squash a pull request in the [Pull Request Merge API][docs] during the preview period by providing a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.polaris-preview
+
+For example:
+
+``` command-line
+curl "https://api.github.com/repos/github/hubot/pulls/123/merge" \
+ -XPUT \
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.polaris-preview" \
+ -d '{
+ "squash": true,
+ "commit_title": "Never tell me the odds"
+ }'
+```
+
+During the preview period, we may change aspects of these API methods based on developer feedback. We will announce the changes here on the developer blog, but we will not provide advance notice.
+
+If you have any questions or feedback, please [let us know][contact].
+
+[media-type]: /v3/media
+[docs]: /v3/pulls/#merge-a-pull-request-merge-button
+[contact]: https://github.com/contact?form%5Bsubject%5D=Squash+API+Preview
diff --git a/content/changes/2016-04-04-git-signing-api-preview.md b/content/changes/2016-04-04-git-signing-api-preview.md
new file mode 100644
index 0000000000..cd8a9364ea
--- /dev/null
+++ b/content/changes/2016-04-04-git-signing-api-preview.md
@@ -0,0 +1,29 @@
+---
+title: Preview support for Git signing
+author_name: mastahyeti
+---
+
+GitHub [recently started verifying GPG signed commits and tags](https://github.com/blog/2144-gpg-signature-verification). We are adding API support for signature verification and user GPG key management as well. You can enable these changes during the preview period by providing a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.cryptographer-preview
+
+For example:
+
+``` command-line
+curl "https://api.github.com/user/gpg_keys" \
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.cryptographer-preview" \
+```
+
+You can learn more about the new signature verification response objects in the updated [repository commit][repo-commit-doc], [Git commit][git-commit-doc], and [Git tag][git-tag-doc] documentation. There is also new [GPG key management][gpg-keys-doc] documentation.
+
+During the preview period, we may change aspects of these APIs based on developer feedback. We will announce the changes here on the developer blog, but we will not provide advance notice.
+
+If you have any questions or feedback, please [let us know][contact].
+
+[media-type]: /v3/media
+[repo-commit-doc]: /v3/repos/commits
+[git-commit-doc]: /v3/git/commits
+[git-tag-doc]: /v3/git/tags
+[gpg-keys-doc]: /v3/users/gpg_keys
+[contact]: https://github.com/contact?form%5Bsubject%5D=Squash+API+Preview
diff --git a/content/changes/2016-04-06-deployment-and-deployment-status-enhancements.md b/content/changes/2016-04-06-deployment-and-deployment-status-enhancements.md
new file mode 100644
index 0000000000..c13aa14ccb
--- /dev/null
+++ b/content/changes/2016-04-06-deployment-and-deployment-status-enhancements.md
@@ -0,0 +1,49 @@
+---
+title: Deployment and DeploymentStatus API enhancements preview period
+author_name: tarebyte
+---
+
+We've expanded our Deployments APIs to accommodate more powerful deployment practices and to lay the foundation for a more seamless integration of deployments within GitHub.
+
+## Link to a live deployment
+
+To enable easy access to a live version of a deployment, we've added an `environment_url` field to the Deployments API. This environment will be exposed as a link in the Pull Request timeline to enable users to directly access a running version of their code without leaving the context of their work.
+
+*Note: To add some clarity, we've renamed the `target_url` field to `log_url`. We will continue accept `target_url` to support legacy uses, but we recommend modifying this to the new name to avoid confusion. Future API versions might not support `target_url`*.
+
+## Inactive deployment status
+
+We recognize that deployments in many common practices don't last forever. So, we've added a new `inactive` state to Deployment Statuses. You can use this state to communicate that a deployment is no longer active (e.g. something different has been deployed to the environment or the environment has been destroyed).
+
+## More information about environments
+
+We've expanded our Deployments API to provide additional information about the environments associated with deployments.
+
+We've added a new `transient_environment` field to allow you to communicate that an environment is specific to a deployment and will no longer exist at some point in the future (e.g. a temporary testing environment like a [Heroku Review App][heroku-review-app]). By pairing this with other additions, we can determine that an `inactive` deployment associated with a `transient_environment` has an `environment_url` that is no longer accessible.
+
+Similarly, we've added a new `production_environment` field to allow you to communicate that an environment is one with which end users directly interact. We automatically set `production_environment` to `true` if the value for `environment` is ``"production"``.
+
+## Automatic creation of inactive statuses
+
+Each time we receive a new successful deployment status, we automatically add a new `inactive` status to all previous deployments made within the relevant repository to the same environment (based on the value of `environment`) given the environment is both non-transient and non-production. You can opt out of this behavior by passing `false` with the new `auto_inactive` parameter.
+
+For example, if `feature-branch` within `https://github.com/user/repository` is deployed to an environment named `staging` (which is a non-transient, non-production environment) and `bugfix-branch` within `https://github.com/user/repository` is later deployed to an environment named `staging`, we would automatically create a new `inactive` status for the deployment associated with `feature-branch`.
+
+#### How can I try it?
+
+Starting today, these API enhancements are available for developers to preview. At the end of the preview period, these enhancements will become official components of the GitHub API.
+
+To access the API during the preview period, you must provide a custom [media type][media-types] in the Accept header:
+
+```
+application/vnd.github.ant-man-preview+json
+```
+
+During the preview period, we may change aspects of these enhancements. If we do, we will announce the changes on the developer blog, but we will not provide any advance notice.
+
+Take a look at [the documentation][docs] for full details. We would love to hear your thoughts on these enhancements. If you have any questions or feedback, please [get in touch with us][contact]!
+
+[contact]: https://github.com/contact?form%5Bsubject%5D=Deployment+and+DeploymentStatus+API+enhancements+preview+period
+[media-types]: /v3/media/
+[heroku-review-app]: https://devcenter.heroku.com/articles/github-integration-review-apps
+[docs]:https://developer.github.com/v3/repos/deployments/
diff --git a/content/changes/2016-04-12-commit-reference-sha-api-is-now-official.md b/content/changes/2016-04-12-commit-reference-sha-api-is-now-official.md
new file mode 100644
index 0000000000..adbec89580
--- /dev/null
+++ b/content/changes/2016-04-12-commit-reference-sha-api-is-now-official.md
@@ -0,0 +1,14 @@
+---
+title: Commit Reference SHA-1 API is now official
+author_name: mikemcquaid
+---
+
+We're making the [Commit Reference SHA-1 API][api-enhancements-blog-post] part of the official GitHub API.
+
+During the preview period you needed to provide the `application/vnd.github.chitauri-preview+sha` preview media type in the `Accept` header to opt-in to the changes. Now that the preview period has ended the custom [media type][custom-media-types] has changed to `application/vnd.github.v3.sha` (but the preview type will continue to work).
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[api-enhancements-blog-post]: /changes/2016-02-24-commit-reference-sha-api/
+[custom-media-types]: /v3/media/
+[contact]: https://github.com/contact?form[subject]=Commit+Reference+SHA-1+API
diff --git a/content/changes/2016-04-18-new-webhook-actions-are-live.md b/content/changes/2016-04-18-new-webhook-actions-are-live.md
new file mode 100644
index 0000000000..40c28b16ce
--- /dev/null
+++ b/content/changes/2016-04-18-new-webhook-actions-are-live.md
@@ -0,0 +1,65 @@
+---
+title: New webhook event actions are now live
+author_name: davidcelis
+---
+
+As [promised last month][notice], we've expanded several webhook events with new functionality. Webhook events involving repositories, issues, and comments have all been updated to include new actions.
+
+Repository events will now fire when a repository is deleted, made public, or made private. In addition, while repository creation events will still only fire for organizations, the new repository event actions can be delivered for user-owned repositories.
+
+Events for issues, pull requests, and comments have also been updated and will now fire when these objects are edited or deleted. When an issue, pull request, or a comment has been edited, the event's payload will include a "changes" object. For example, if you've updated the title and body of an issue, the webhook payload informs you of what the issue used to look like:
+
+```json
+{
+ "action": "edited",
+ "changes": {
+ "title": { "from": "This is the old title." },
+ "body": { "from": "This is the old body." }
+ },
+ "issue": {
+ "title": "This is the new title.",
+ "body": "This is the new body."
+ }
+}
+```
+
+The new values will be present in the `issue` object itself, as detailed above. Unchanged values will not be present within the `changes` object. Comment edits follow a similar pattern, though because they have no titles, the only change included in the payload would be the comment's body.
+
+## List of comprehensive changes
+
+New actions were added to five events, all of which are detailed below.
+
+### [RepositoryEvent][repository-event]
+
+* `deleted`: sent when a user-owned or organization-owned repository is deleted.
+* `publicized`: sent when a user-owned or organization-owned repository is switched from private to public.
+* `privatized`: sent when a user-owned or organization-owned repository is switched from public to private.
+
+### [IssuesEvent][issues-event]
+
+* `edited`: sent when the title and/or body of an issue is edited.
+
+### [IssueCommentEvent][issue-comment-event]
+
+* `edited`: sent when a comment on an issue or pull request is edited
+* `deleted`: sent when a comment on an issue or pull request is deleted
+
+### [PullRequestEvent][pull-request-event]
+
+* `edited`: sent when the title and/or body of a pull request is edited.
+
+### [PullRequestReviewCommentEvent][pull-request-review-comment-event]
+
+* `edited`: sent when a comment on a pull request's unified diff (in the Files Changed tab) is edited
+* `deleted`: sent when a comment on a pull request's unified diff (in the Files Changed tab) is deleted
+
+Take a look at [the documentation][docs] for full details. If you have any questions or feedback, please [get in touch][get-in-touch].
+
+[docs]: https://developer.github.com/webhooks/
+[get-in-touch]: https://github.com/contact?form[subject]=New+Webhook+Actions
+[issue-comment-event]: https://developer.github.com/v3/activity/events/types/#issuecommentevent
+[issues-event]: https://developer.github.com/v3/activity/events/types/#issuesevent
+[notice]: https://developer.github.com/changes/2016-03-15-new-webhook-actions/
+[pull-request-event]: https://developer.github.com/v3/activity/events/types/#pullrequestevent
+[pull-request-review-comment-event]: https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
+[repository-event]: https://developer.github.com/v3/activity/events/types/#repositoryevent
diff --git a/content/changes/2016-04-21-oauth-authorizations-grants-api-preview.md b/content/changes/2016-04-21-oauth-authorizations-grants-api-preview.md
new file mode 100644
index 0000000000..7e60f4baec
--- /dev/null
+++ b/content/changes/2016-04-21-oauth-authorizations-grants-api-preview.md
@@ -0,0 +1,29 @@
+---
+title: Preview support for OAuth authorizations grants API
+author_name: ptoomey3
+---
+
+GitHub recently made changes to [the application authorizations settings screen within GitHub][authorized-application-listing] to display one entry for each OAuth application a user has authorized. Previously this screen showed one entry for each OAuth token that was generated by an OAuth application. For example, if you installed two instances of GitHub Desktop, you would see one entry for each installation. To simplify OAuth application management, we now show a single entry for each OAuth application. For OAuth applications that use the [web flow][web-flow] this was not a problem, since the web flow never generates more than one token for a given OAuth application and user. However, going forward, GitHub would like to allow all OAuth applications, including those that use the web flow, to generate more than one token.
+
+In preparation for that change, we are adding API support to simplify management of OAuth applications that matches what is available on GitHub.com. You can enable these changes during the preview period by providing a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.damage-preview
+
+For example:
+
+``` command-line
+curl -u username "https://api.github.com/applications/grants" \
+ -H "Accept: application/vnd.github.damage-preview"
+```
+
+You can learn more about the new APIs in the [OAuth authorizations][oauth-authorizations-api] documentation.
+
+During the preview period, we may change aspects of these APIs based on developer feedback. We will announce the changes here on the developer blog, but we will not provide advance notice.
+
+If you have any questions or feedback, please [let us know][contact].
+
+[media-type]: /v3/media
+[oauth-authorizations-api]: /v3/oauth_authorizations
+[authorized-application-listing]: https://github.com/settings/applications#authorized
+[contact]: https://github.com/contact?form%5Bsubject%5D=OAuth+Authorizations+Grants+API+Preview
+[web-flow]: /v3/oauth/#web-application-flow
diff --git a/content/changes/2016-05-03-source-import-api-enhancements-for-working-with-git-lfs.md b/content/changes/2016-05-03-source-import-api-enhancements-for-working-with-git-lfs.md
new file mode 100644
index 0000000000..4f7f8bb308
--- /dev/null
+++ b/content/changes/2016-05-03-source-import-api-enhancements-for-working-with-git-lfs.md
@@ -0,0 +1,40 @@
+---
+title: Source Import API enhancements for working with Git LFS
+author_name: lizzhale
+---
+
+Today we're introducing enhancements to the [Source Import API][docs] to support importing repositories with files larger than 100MB.
+
+**Changes to parameters for starting an import**
+
+[Starting an import][start-an-import] no longer requires a `vcs` parameter. Please be aware that without this parameter, the import job will take additional time to detect the vcs type before beginning the import. This detection step will be reflected in the response.
+
+**New methods**
+
+We've added 3 new methods that will enable API consumers to:
+
+ * [update][update-existing-import] the authentication or project choice for an import. If no parameters are provided during the request, the import will be restarted. Please note that this is a **breaking change**. Updating authentication for the originating URL is no longer supported through the [start an import][start-an-import] method. Please update your applications to use the new method.
+
+ * [set their preference][set-git-lfs-preference] for using Git LFS to import files larger than 100MB.
+
+ * [list all the files larger than 100MB][get-large-files] that were found during the import.
+
+**New attributes for Git LFS**
+
+Several new response attributes (`use_lfs`, `has_large_files`, `large_files_size`, `large_files`) were added to provide details regarding the large files found during the import. You can read more about the attributes [here][git-lfs-related-fields].
+
+As before, to access the API during the preview period, you must provide a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.barred-rock-preview
+
+For more information, see the [Source Import API documentation][docs], and if you have any questions or feedback, please [let us know][contact].
+
+
+[docs]: /v3/migration/source_imports/
+[start-an-import]: /v3/migration/source_imports/#start-an-import
+[update-existing-import]: /v3/migration/source_imports/#update-existing-import
+[set-git-lfs-preference]: /v3/migration/source_imports/#set-git-lfs-preference
+[get-large-files]: /v3/migration/source_imports/#get-large-files
+[git-lfs-related-fields]: /v3/migration/source_imports/#git-lfs-related-fields
+[media-type]: /v3/media
+[contact]: https://github.com/contact?form%5Bsubject%5D=Source+Import+API
diff --git a/content/changes/2016-05-12-reactions-api-preview.md b/content/changes/2016-05-12-reactions-api-preview.md
new file mode 100644
index 0000000000..fbf93d1aa7
--- /dev/null
+++ b/content/changes/2016-05-12-reactions-api-preview.md
@@ -0,0 +1,33 @@
+---
+title: Preview support for Reactions API
+author_name: kneemer
+---
+
+GitHub recently added [Reactions to Pull Requests, Issues, and Comments][reactions-blog-post] to help people express their feelings more simply and effectively in conversations. We are adding endpoints for Reactions so that you can now react and unreact via the API. You can enable these changes during the preview period by providing a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+For example:
+
+To view reactions on an issue:
+
+``` command-line
+$ curl "https://api.github.com/repos/github/hubot/issues/1/reactions" \
+ -H "Accept: application/vnd.github.squirrel-girl-preview"
+```
+
+
+You can learn more about the new reaction response objects in the updated [Commit comment][commit-comment-doc], [Issue][issue-doc], [Issue comment][issue-comment-doc], and [Review Comment][review-comment-doc] documentation. There is also new [Reaction][reaction-doc] documentation.
+
+During the preview period, we may change aspects of these APIs based on developer feedback. We will announce the changes here on the developer blog, but we will not provide advance notice.
+
+If you have any questions or feedback, please [let us know][contact].
+
+[media-type]: /v3/media
+[reaction-doc]: /v3/reactions
+[issue-doc]: /v3/issues#preview-period-org-issues
+[issue-comment-doc]: /v3/issues/comments#preview-period-issue-comments
+[review-comment-doc]: /v3/pulls/comments#preview-period-pull-comments
+[commit-comment-doc]: /v3/repos/comments#preview-period-commits-comments
+[contact]: https://github.com/contact?form%5Bsubject%5D=Reactions+API+Preview
+[reactions-blog-post]: https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments
diff --git a/content/changes/2016-05-23-timeline-preview-api.md b/content/changes/2016-05-23-timeline-preview-api.md
new file mode 100644
index 0000000000..2400991a20
--- /dev/null
+++ b/content/changes/2016-05-23-timeline-preview-api.md
@@ -0,0 +1,19 @@
+---
+title: Preview the Timeline API
+author_name: nickh
+---
+
+We've added an API for issue timelines, which will let you fetch a list
+of events from an issue or pull request timeline.
+
+To access [the Timeline API][docs] during the preview period, you must provide a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.mockingbird-preview
+
+During the preview period, we may change aspects of these API methods based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+If you have any questions or feedback, please [let us know][contact]!
+
+[media-type]: /v3/media
+[docs]: /v3/issues/timeline/
+[contact]: https://github.com/contact?form%5Bsubject%5D=Timeline+API
diff --git a/content/changes/2016-06-07-reactions-api-update.md b/content/changes/2016-06-07-reactions-api-update.md
new file mode 100644
index 0000000000..017d189394
--- /dev/null
+++ b/content/changes/2016-06-07-reactions-api-update.md
@@ -0,0 +1,46 @@
+---
+title: Reactions API Preview now includes user information
+author_name: kneemer
+---
+
+To avoid making extra API calls, we've updated the [Reactions API preview][initial-reaction-api-post] to include additional user information when listing Reactions.
+
+**This is a breaking change for Reaction payloads**. If you're trying out this new API during its preview period, you'll need to update your code to continue working with it.
+
+## JSON Payload Changes
+
+We're replacing the `user_id` attribute with `user` and changing the schema type from a number to a JSON object.
+
+## Example Reaction JSON
+```json
+[
+ {
+ "id": 1,
+ "user": {
+ "login": "octocat",
+ "id": 1,
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/octocat",
+ "html_url": "https://github.com/octocat",
+ "followers_url": "https://api.github.com/users/octocat/followers",
+ "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+ "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+ "organizations_url": "https://api.github.com/users/octocat/orgs",
+ "repos_url": "https://api.github.com/users/octocat/repos",
+ "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/octocat/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "content": "heart"
+ }
+]
+```
+
+As always, if you have any questions or feedback, please [get in touch][contact].
+
+[initial-reaction-api-post]: /changes/2016-05-12-reactions-api-preview
+[contact]: https://github.com/contact?form%5Bsubject%5D=Reactions+API+Preview
diff --git a/content/changes/2016-06-14-repository-invitations.md b/content/changes/2016-06-14-repository-invitations.md
new file mode 100644
index 0000000000..00cddde89d
--- /dev/null
+++ b/content/changes/2016-06-14-repository-invitations.md
@@ -0,0 +1,28 @@
+---
+title: API changes for Repository Invitations
+author_name: CoralineAda
+---
+
+We announced [repository invitation functionality][repo-invitations-announcement] on May 23. Using the site, you can invite collaborators to work on your repository. Invitees will receive an email with the invitation and have the option to accept or decline.
+
+We have now have endpoints for managing repository invitations for both repository administrators and invitation recipients through the GitHub API. You can enable these changes during the preview period by providing a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.swamp-thing-preview
+
+For example:
+
+``` command-line
+curl "https://api.github.com/repos/github/hubot/invitations" \
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.swamp-thing-preview"
+```
+
+You can learn more about the new endpoints in the updated [Collaborators][collaborators] and new [Repository Invitations][repo-invitations] documentation.
+
+If you have any questions or feedback, please [let us know][contact].
+
+[media-type]: /v3/media
+[collaborators]: /v3/repos/collaborators
+[repo-invitations]: /v3/repos/invitations
+[repo-invitations-announcement]: https://github.com/blog/2170-repository-invitations
+[contact]: https://github.com/contact?form%5Bsubject%5D=Repository+Invitations+API+Preview
diff --git a/content/changes/2016-06-22-issue-locking-api-is-now-official.md b/content/changes/2016-06-22-issue-locking-api-is-now-official.md
new file mode 100644
index 0000000000..81fb174003
--- /dev/null
+++ b/content/changes/2016-06-22-issue-locking-api-is-now-official.md
@@ -0,0 +1,14 @@
+---
+title: Issue locking and unlocking APIs are now official
+author_name: davidcelis
+---
+
+We're making the [Issue locking and unlocking APIs][issue-locking-blog-post] part of the official GitHub API.
+
+During the preview period you needed to provide the `application/vnd.github.the-key-preview+json` preview media type in the `Accept` header to opt-in to the new endpoints. Now that the preview period has ended, you no longer need to specify this custom [media type][custom-media-types].
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[issue-locking-blog-post]: /changes/2016-02-11-issue-locking-api/
+[custom-media-types]: /v3/media/
+[contact]: https://github.com/contact?form[subject]=Issue+Locking+and+Unlocking+API
diff --git a/content/changes/2016-06-27-protected-branches-api-update.md b/content/changes/2016-06-27-protected-branches-api-update.md
new file mode 100644
index 0000000000..6ce7053298
--- /dev/null
+++ b/content/changes/2016-06-27-protected-branches-api-update.md
@@ -0,0 +1,22 @@
+---
+title: Update to Protected Branches API Preview
+author_name: tma
+---
+
+Over the past few months, we've made a few [improvements](https://github.com/blog/2137-protected-branches-improvements) to the way [protected branches](https://github.com/blog/2051-protected-branches-and-required-status-checks) work in our web interface. Today, we're modifying the protected branches API [preview period](https://developer.github.com/changes/2015-11-11-protected-branches-api/) to include these improvements.
+
+Included in these API changes is the ability to allow organizations to specify which members and teams should be able to push to a protected branch, as well as providing a new setting for required status checks which will remove the requirement of a pull request to be up to date before merging.
+
+You'll notice a new endpoint structure. One set of endpoints for modifying the branch settings as a whole (`PATCH /repos/:owner/:repo/branches/:branch` has been updated to be `PUT /repos/:owner/:repo/branches/:branch/protection`), and a series of more granular endpoints to modify a subset of the branch protection settings.
+
+**This will be a breaking change for the protected branch API.** The deprecated API endpoint will be removed when the protected branches API will leave the preview period. If you're trying out the old protected branches API, you'll need to update your code.
+
+#### How can I try it?
+
+To access this functionality during the preview period, you’ll need to provide the following custom media type in the Accept header:
+
+```
+application/vnd.github.loki-preview+json
+```
+
+Take a look at [the docs here](/v3/repos/branches/). If you have any questions, please [get in touch](https://github.com/contact?form%5Bsubject%5D=Protected+Branches+API+Preview).
diff --git a/content/changes/2016-07-06-github-pages-preview-api.md b/content/changes/2016-07-06-github-pages-preview-api.md
new file mode 100644
index 0000000000..ab14cbee46
--- /dev/null
+++ b/content/changes/2016-07-06-github-pages-preview-api.md
@@ -0,0 +1,43 @@
+---
+title: Introducing the GitHub Pages preview API
+author_name: benbalter
+---
+
+We're introducing additional preview functionality to the [GitHub Pages API](/v3/repos/pages/) to give developers better control over their GitHub Pages site.
+
+#### Requesting a page build
+
+You can now manually request a build of your GitHub Pages site without needing to push a new commit by making a `POST` request to the endpoint already available to see past builds. For example:
+
+``` command-line
+curl "https://api.github.com/repos/github/developer.github.com/pages/builds" \
+ -X POST
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.mister-fantastic-preview" \
+```
+
+#### Retrieving a site's URL
+
+With the introduction of [HTTPS support for GitHub Pages sites](https://github.com/blog/2186-https-for-github-pages), it's important to know not just a site's custom domain, if it has one, but also if it has HTTPS enforcement enabled. The GitHub Pages API will now return an additional `html_url` field, which will include the computed absolute URL to the site.
+
+The resulting URL can be `https://username.github.io` (or `http://username.github.io`) for user sites without a custom domain, `https://username.gituhb.io/project` for project sites, or `http://example.com` for sites with custom domains, saving third-party applications the trouble of having to construct complicated URL logic based on the username, owner, and CNAME, as was previously necessary.
+
+For example, to request the HTML URL:
+
+``` command-line
+curl "https://api.github.com/repos/github/developer.github.com/pages" \
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.mister-fantastic-preview" \
+```
+
+#### How can I try it?
+
+To access this functionality during the preview period, you’ll need to provide the following custom media type in the Accept header:
+
+```
+application/vnd.github.mister-fantastic-preview+json
+```
+
+During the preview period, we may change aspects of these API methods based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+For more information, take a look at [the docs here](/v3/repos/pages/), and if you have any questions, please [get in touch](https://github.com/contact?form%5Bsubject%5D=GitHub+Pages+API+Preview).
diff --git a/content/changes/2016-07-12-ending-multiple-assignees-preview-period.md b/content/changes/2016-07-12-ending-multiple-assignees-preview-period.md
new file mode 100644
index 0000000000..13f6fc318b
--- /dev/null
+++ b/content/changes/2016-07-12-ending-multiple-assignees-preview-period.md
@@ -0,0 +1,13 @@
+---
+title: Multiple Assignees API is now official
+author_name: nakajima
+---
+
+We're making [Multiple Assignees][blog-post] part of the official GitHub API.
+
+During the preview period you needed to provide the `application/vnd.github.cerberus-preview` preview media type in the `Accept` header to opt-in to the changes. Now that the preview period has ended, you no longer need to specify this custom media type.
+
+If you have any questions or feedback, please [get in touch with us][contact]!
+
+[blog-post]: /changes/2016-5-27-multiple-assignees/
+[contact]: https://github.com/contact?form[subject]=Multiple+Assignees+API
diff --git a/content/changes/2016-08-09-breaking-change-removed-sensitive-fields-from-organization-api-responses-for-owner.md b/content/changes/2016-08-09-breaking-change-removed-sensitive-fields-from-organization-api-responses-for-owner.md
new file mode 100644
index 0000000000..22f0e9cd3c
--- /dev/null
+++ b/content/changes/2016-08-09-breaking-change-removed-sensitive-fields-from-organization-api-responses-for-owner.md
@@ -0,0 +1,22 @@
+---
+title: "Breaking change: Removed sensitive fields from Organization API responses for non-owners"
+author_name: kdaigle
+---
+
+We're removing some values from [Organization API](https://developer.github.com/v3/orgs/) responses to help protect our
+users' privacy. Previously, these fields were returned to all members of the organization.
+As of today, you must be an Organization owner to
+receive values for the following fields in Organization responses:
+
+* `private_gists`
+* `disk_usage`
+* `collaborators`
+* `billing_email`
+
+If you're not an organization owner, the above keys will now return `null`.
+We will continue to send these fields without their values to minimize the impact
+of this change.
+
+If you have any questions or feedback, please [drop us a line][contact].
+
+[contact]: https://github.com/contact?form[subject]=Removed+sensitive+fields+from+org+api
diff --git a/content/changes/2016-08-15-traffic-api-preview.md b/content/changes/2016-08-15-traffic-api-preview.md
new file mode 100644
index 0000000000..60b089e380
--- /dev/null
+++ b/content/changes/2016-08-15-traffic-api-preview.md
@@ -0,0 +1,18 @@
+---
+title: Preview the Repository Traffic API
+author_name: shreyasjoshis
+---
+
+ We've added an API for repository traffic, which will let you fetch details about traffic for repositories you have push access to. This data is already available in graphical form in the [Graphs section](https://help.github.com/articles/about-repository-graphs/#traffic) on GitHub.com.
+
+To access [the Traffic API][docs] during the preview period, you must provide a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.spiderman-preview
+
+During the preview period, we may change aspects of these API methods based on developer feedback. If we do, we will announce the changes here on the developer blog, but we will not provide any advance notice.
+
+If you have any questions or feedback, please [let us know][contact]!
+
+[media-type]: /v3/media
+[docs]: /v3/repos/traffic/
+[contact]: https://github.com/contact?form%5Bsubject%5D=Traffic+API
diff --git a/content/changes/2016-08-23-change-base.md b/content/changes/2016-08-23-change-base.md
new file mode 100644
index 0000000000..a83f67b8e3
--- /dev/null
+++ b/content/changes/2016-08-23-change-base.md
@@ -0,0 +1,25 @@
+---
+title: API changes for changing the base branch on Pull Requests
+author_name: scottjg
+---
+GitHub recently added the ability to [change the base branch][blog post] on a Pull Request after it's created. Now we're updating the Pull Request API to enable the new functionality.
+
+For example:
+
+``` command-line
+curl "https://api.github.com/repos/github/hubot/pulls/123" \
+ -H 'Authorization: token TOKEN' \
+ -d '{ "base": "master" }'
+```
+
+The Pull Request base will be updated to point to the master branch.
+
+You can learn more about the new responses and endpoints in the updated [Pull Request][pulls] documentation.
+
+If you have any questions or feedback, please [let us know][contact]!
+
+
+[pulls]: /v3/pulls
+[blog post]: https://github.com/blog/2224-change-the-base-branch-of-a-pull-request
+[contact]: https://github.com/contact?form%5Bsubject%5D=Change+base+on+Pull+Requests
+
diff --git a/content/changes/2016-5-27-multiple-assignees.md b/content/changes/2016-5-27-multiple-assignees.md
new file mode 100644
index 0000000000..1a9c70fbb0
--- /dev/null
+++ b/content/changes/2016-5-27-multiple-assignees.md
@@ -0,0 +1,28 @@
+---
+title: API changes for Multiple Issue Assignees
+author_name: nakajima
+---
+GitHub recently added the ability to assign up to ten people to issues. We're updating Issue payloads and adding a couple new endpoints to help you build apps. You can enable these changes during the preview period by providing a custom [media type][media-type] in the `Accept` header:
+
+ application/vnd.github.cerberus-preview
+
+For example:
+
+``` command-line
+curl "https://api.github.com/repos/github/hubot/issues" \
+ -H 'Authorization: token TOKEN' \
+ -H "Accept: application/vnd.github.cerberus-preview" \
+```
+
+The issues returned in this list will include the new `assignees` key.
+
+You can learn more about the new responses and endpoints in the updated [Issues][issues] and [Issue Assignees][issue-assignees] documentation.
+
+If you have any questions or feedback, please [let us know][contact]!
+
+
+[media-type]: /v3/media
+[issues]: /v3/issues
+[issue-assignees]: /v3/issues/assignees
+[contact]: https://github.com/contact?form%5Bsubject%5D=Multiple+Assignees+API
+
diff --git a/content/changes/index.html b/content/changes/index.html
index f11cff1475..e51085796f 100644
--- a/content/changes/index.html
+++ b/content/changes/index.html
@@ -3,5 +3,8 @@
layout: blog
---
-<%= render '_changes', :changes => api_changes %>
+<%= renderp '/_changes.*', :changes => paginated_api_changes(0, 9) %>
+
diff --git a/content/guides/automating-deployments-to-integrators.md b/content/guides/automating-deployments-to-integrators.md
new file mode 100644
index 0000000000..c5b7628c63
--- /dev/null
+++ b/content/guides/automating-deployments-to-integrators.md
@@ -0,0 +1,74 @@
+---
+title: Automating deployments to integrators
+---
+
+# Automating deployments to integrators
+
+{:toc}
+
+The "[Delivering deployments](/guides/delivering-deployments/)" guide describes how to build a server that uses the [Deployments API][deploy API] to easily get your code from GitHub into production. But what if you don't want to host a separate service for deploying code? What if you just want to merge code and have it deploy without thinking about maintaining another app?
+
+You can use the GitHub Auto-Deployment service to receive changes made to your repository and configure it to deliver a deployment to integrators. The Auto-Deployment service can deliver payloads based on two events: whenever a push is made and whenever [the CI status is passing](/guides/building-a-ci-server/).
+
+Here's a diagram demonstrating what the process might look like:
+
+```
++--------------------+ +--------+ +-----------+
+| GitHub Auto-Deploy | | GitHub | | Heroku |
+| Service | +--------+ +-----------+
++--------------------+ | |
+ | | |
+ | Create Deployment | |
+ |------------------------>| |
+ | | |
+ | | |
+ | | Deployment Event |
+ | |--------------------------------->|
+ | | |
+ | | Deployment Status (pending) |
+ | |<---------------------------------|
+ | | |
+ | | |
+ | | Deployment Status (success) |
+ | |<---------------------------------|
+ | | |
+```
+
+{{#tip}}
+
+Note that the Auto-Deployment service only picks up changes from your default branch, which is usually `master`.
+
+{{/tip}}
+
+## Sending deployments whenever you push to a repository
+
+The Auto-Deployment service will be responsible for creating deployments when a push is made to your default branch. Next, we'll set up a service to receive those deployment events and handle the deployment of your project.
+
+1. Navigate to the repository where you’re setting up your deployments.
+2. In your repository's right sidebar, click .
+3. On the left, click **Webhooks & Services**.
+
+4. Click **Add service**, then type "GitHub Auto-Deployment." 
+5. Under **GitHub token**, paste an access token you've created. It must have at least the `repo` scope. For more information, see "[Creating an access token for command-line use](https://help.github.com/articles/creating-an-access-token-for-command-line-use)."
+6. Under **Environments**, optionally provide a list of environments you'd like to send your deployments to. This can be [any string you define](https://developer.github.com/v3/repos/deployments/#parameters) to describe your environment. The default is "production."
+7. If you *only* want builds that successfully passed a continuous test suite, select **Deploy on status**.
+8. If you're running this service on GitHub Enterprise, you must pass in your appliance's [endpoint URL](https://developer.github.com/v3/enterprise/#endpoint-urls).
+9. Click **Add service**.
+
+## Hooking up an integrator to deployments
+
+To implement our deployments, we'll use Heroku as an example service.
+
+1. Navigate to the repository where you’re setting up your deployments.
+2. In your repository's right sidebar, click .
+3. On the left, click **Webhooks & Services**.
+
+4. Click **Add service**, then type "Heroku." 
+5. Type the name of the Heroku application your GitHub repository should deploy to.
+6. Enter in your [Heroku OAuth token](https://devcenter.heroku.com/articles/oauth#direct-authorization). You must generate this yourself following the instructions in Heroku's documentation.
+7. Under **GitHub token**, paste the same token you provided earlier.
+8. Click **Add service**.
+
+From now on, any commits made to your `master` branch--including those generated from merging pull requests--will automatically trigger a deployment to your Heroku application.
+
+[deploy API]: /v3/repos/deployments/
diff --git a/content/guides/basics-of-authentication.md b/content/guides/basics-of-authentication.md
index a59a2696dd..f67f9e8f0e 100644
--- a/content/guides/basics-of-authentication.md
+++ b/content/guides/basics-of-authentication.md
@@ -1,18 +1,20 @@
---
-title: Basics of Authentication | GitHub API
+title: Basics of Authentication
---
# Basics of Authentication
-* TOC
{:toc}
In this section, we're going to focus on the basics of authentication. Specifically,
we're going to create a Ruby server (using [Sinatra][Sinatra]) that implements
the [web flow][webflow] of an application in several different ways.
-Note: you can download the complete source code for this project
-[from the platform-samples repo][platform samples].
+{{#tip}}
+
+You can download the complete source code for this project [from the platform-samples repo](https://github.com/github/platform-samples/tree/master/api/).
+
+{{/tip}}
## Registering your app
@@ -23,7 +25,7 @@ into your repository.
You can fill out every piece of information however you like, except the
**Authorization callback URL**. This is easily the most important piece to setting
-up your application. It's the callback URL that GitHub returns the user to after
+up your application. It's the callback URL that {{ site.data.variables.product.product_name }} returns the user to after
successful authentication.
Since we're running a regular Sinatra server, the location of the local instance
@@ -33,42 +35,44 @@ is set to `http://localhost:4567`. Let's fill in the callback URL as `http://loc
Now, let's start filling out our simple server. Create a file called _server.rb_ and paste this into it:
- #!ruby
- require 'sinatra'
- require 'rest-client'
- require 'json'
+``` ruby
+require 'sinatra'
+require 'rest-client'
+require 'json'
- CLIENT_ID = ENV['GH_BASIC_CLIENT_ID']
- CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID']
+CLIENT_ID = ENV['GH_BASIC_CLIENT_ID']
+CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID']
- get '/' do
- erb :index, :locals => {:client_id => CLIENT_ID}
- end
+get '/' do
+ erb :index, :locals => {:client_id => CLIENT_ID}
+end
+```
Your client ID and client secret keys come from [your application's configuration
page][app settings]. You should **never, _ever_** store these values in
-GitHub--or any other public place, for that matter. We recommend storing them as
+{{ site.data.variables.product.product_name }}--or any other public place, for that matter. We recommend storing them as
[environment variables][about env vars]--which is exactly what we've done here.
Next, in _views/index.erb_, paste this content:
- #!html+erb
-
-
-
-
-
- Well, hello there!
-
-
- We're going to now talk to the GitHub API. Ready?
- Click here to begin!
-
-
- If that link doesn't work, remember to provide your own Client ID!
-
-
-
+``` erb
+
+
+
+
+
+ Well, hello there!
+
+
+ We're going to now talk to the GitHub API. Ready?
+ Click here to begin!
+
+
+ If that link doesn't work, remember to provide your own Client ID!
+
+
+
+```
(If you're unfamiliar with how Sinatra works, we recommend [reading the Sinatra guide][Sinatra guide].)
@@ -77,38 +81,39 @@ Also, notice that the URL uses the `scope` query parameter to define the
requesting `user:email` scope for reading private email addresses.
Navigate your browser to `http://localhost:4567`. After clicking on the link, you
-should be taken to GitHub, and presented with a dialog that looks something like this:
-
+should be taken to {{ site.data.variables.product.product_name }}, and presented with a dialog that looks something like this:
+
If you trust yourself, click **Authorize App**. Wuh-oh! Sinatra spits out a
`404` error. What gives?!
Well, remember when we specified a Callback URL to be `callback`? We didn't provide
-a route for it, so GitHub doesn't know where to drop the user after they authorize
+a route for it, so {{ site.data.variables.product.product_name }} doesn't know where to drop the user after they authorize
the app. Let's fix that now!
### Providing a callback
In _server.rb_, add a route to specify what the callback should do:
- #!ruby
- get '/callback' do
- # get temporary GitHub code...
- session_code = request.env['rack.request.query_hash']['code']
-
- # ... and POST it back to GitHub
- result = RestClient.post('https://github.com/login/oauth/access_token',
- {:client_id => CLIENT_ID,
- :client_secret => CLIENT_SECRET,
- :code => session_code},
- :accept => :json)
-
- # extract the token and granted scopes
- access_token = JSON.parse(result)['access_token']
- end
-
-After a successful app authentication, GitHub provides a temporary `code` value.
-You'll need to `POST` this code back to GitHub in exchange for an `access_token`.
+``` ruby
+get '/callback' do
+ # get temporary GitHub code...
+ session_code = request.env['rack.request.query_hash']['code']
+
+ # ... and POST it back to GitHub
+ result = RestClient.post('https://github.com/login/oauth/access_token',
+ {:client_id => CLIENT_ID,
+ :client_secret => CLIENT_SECRET,
+ :code => session_code},
+ :accept => :json)
+
+ # extract the token and granted scopes
+ access_token = JSON.parse(result)['access_token']
+end
+```
+
+After a successful app authentication, {{ site.data.variables.product.product_name }} provides a temporary `code` value.
+You'll need to `POST` this code back to {{ site.data.variables.product.product_name }} in exchange for an `access_token`.
To simplify our GET and POST HTTP requests, we're using the [rest-client][REST Client].
Note that you'll probably never access the API through REST. For a more serious
application, you should probably use [a library written in the language of your choice][libraries].
@@ -123,10 +128,17 @@ were granted for the token by the user.
The scopes that were granted are returned as a part of the response from
exchanging a token.
- #!ruby
- # check if we were granted user:email scope
- scopes = JSON.parse(result)['scope'].split(',')
- has_user_email_scope = scopes.include? 'user:email'
+``` ruby
+get '/callback' do
+ # ...
+ # Get the access_token using the code sample above
+ # ...
+
+ # check if we were granted user:email scope
+ scopes = JSON.parse(result)['scope'].split(',')
+ has_user_email_scope = scopes.include? 'user:email'
+end
+```
In our application, we're using `scopes.include?` to check if we were granted
the `user:email` scope needed for fetching the authenticated user's private
@@ -139,7 +151,7 @@ if the application had asked for `user` scope, it might have been granted only
`user:email` scope. In that case, the application wouldn't have been granted
what it asked for, but the granted scopes would have still been sufficient.
-Checking for scopes only before making requests is not enough since it's posible
+Checking for scopes only before making requests is not enough since it's possible
that users will change the scopes in between your check and the actual request.
In case that happens, API calls you expected to succeed might fail with a `404`
or `401` status, or return a different subset of information.
@@ -157,36 +169,39 @@ changes in available application functionality.
At last, with this access token, you'll be able to make authenticated requests as
the logged in user:
- #!ruby
- # fetch user information
- auth_result = JSON.parse(RestClient.get('https://api.github.com/user',
- {:params => {:access_token => access_token}}))
+``` ruby
+# fetch user information
+auth_result = JSON.parse(RestClient.get('https://api.github.com/user',
+ {:params => {:access_token => access_token}}))
- # if the user authorized it, fetch private emails
- if has_user_email_scope
- auth_result['private_emails'] =
- JSON.parse(RestClient.get('https://api.github.com/user/emails',
- {:params => {:access_token => access_token}}))
+# if the user authorized it, fetch private emails
+if has_user_email_scope
+ auth_result['private_emails'] =
+ JSON.parse(RestClient.get('https://api.github.com/user/emails',
+ {:params => {:access_token => access_token}}))
+end
- erb :basic, :locals => auth_result
+erb :basic, :locals => auth_result
+```
We can do whatever we want with our results. In this case, we'll just dump them straight into _basic.erb_:
- #!html+erb
-
Hello, <%= login %>!
-
- <% if !email.nil? && !email.empty? %> It looks like your public email address is <%= email %>.
- <% else %> It looks like you don't have a public email. That's cool.
- <% end %>
-
-
- <% if defined? private_emails %>
- With your permission, we were also able to dig up your private email addresses:
- <%= private_emails.join(', ') %>
- <% else %>
- Also, you're a bit secretive about your private email addresses.
- <% end %>
-
+``` erb
+
Hello, <%= login %>!
+
+ <% if !email.nil? && !email.empty? %> It looks like your public email address is <%= email %>.
+ <% else %> It looks like you don't have a public email. That's cool.
+ <% end %>
+
+
+ <% if defined? private_emails %>
+ With your permission, we were also able to dig up your private email addresses:
+ <%= private_emails.map{ |private_email_address| private_email_address["email"] }.join(', ') %>
+ <% else %>
+ Also, you're a bit secretive about your private email addresses.
+ <% end %>
+
+```
## Implementing "persistent" authentication
@@ -196,7 +211,7 @@ time they needed to access the web page. For example, try navigating directly to
What if we could circumvent the entire
"click here" process, and just _remember_ that, as long as the user's logged into
-GitHub, they should be able to access this application? Hold on to your hat,
+{{ site.data.variables.product.product_name }}, they should be able to access this application? Hold on to your hat,
because _that's exactly what we're going to do_.
Our little server above is rather simple. In order to wedge in some intelligent
@@ -212,86 +227,86 @@ the `user:email` scope.
Create a file called _advanced_server.rb_, and paste these lines into it:
- #!ruby
- require 'sinatra'
- require 'rest_client'
- require 'json'
-
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- # if ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
- # CLIENT_ID = ENV['GITHUB_CLIENT_ID']
- # CLIENT_SECRET = ENV['GITHUB_CLIENT_SECRET']
- # end
-
- CLIENT_ID = ENV['GH_BASIC_CLIENT_ID']
- CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID']
-
- use Rack::Session::Cookie, :secret => rand.to_s()
-
- def authenticated?
- session[:access_token]
+``` ruby
+require 'sinatra'
+require 'rest_client'
+require 'json'
+
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+# if ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
+# CLIENT_ID = ENV['GITHUB_CLIENT_ID']
+# CLIENT_SECRET = ENV['GITHUB_CLIENT_SECRET']
+# end
+
+CLIENT_ID = ENV['GH_BASIC_CLIENT_ID']
+CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID']
+
+use Rack::Session::Pool, :cookie_only => false
+
+def authenticated?
+ session[:access_token]
+end
+
+def authenticate!
+ erb :index, :locals => {:client_id => CLIENT_ID}
+end
+
+get '/' do
+ if !authenticated?
+ authenticate!
+ else
+ access_token = session[:access_token]
+ scopes = []
+
+ begin
+ auth_result = RestClient.get('https://api.github.com/user',
+ {:params => {:access_token => access_token},
+ :accept => :json})
+ rescue => e
+ # request didn't succeed because the token was revoked so we
+ # invalidate the token stored in the session and render the
+ # index page so that the user can start the OAuth flow again
+
+ session[:access_token] = nil
+ return authenticate!
end
- def authenticate!
- erb :index, :locals => {:client_id => CLIENT_ID}
+ # the request succeeded, so we check the list of current scopes
+ if auth_result.headers.include? :x_oauth_scopes
+ scopes = auth_result.headers[:x_oauth_scopes].split(', ')
end
- get '/' do
- if !authenticated?
- authenticate!
- else
- access_token = session[:access_token]
- scopes = []
-
- begin
- auth_result = RestClient.get('https://api.github.com/user',
- {:params => {:access_token => access_token},
- :accept => :json})
- rescue => e
- # request didn't succeed because the token was revoked so we
- # invalidate the token stored in the session and render the
- # index page so that the user can start the OAuth flow again
-
- session[:access_token] = nil
- return authenticate!
- end
-
- # the request succeeded, so we check the list of current scopes
- if auth_result.headers.include? :x_oauth_scopes
- scopes = auth_result.headers[:x_oauth_scopes].split(', ')
- end
-
- auth_result = JSON.parse(auth_result)
-
- if scopes.include? 'user:email'
- auth_result['private_emails'] =
- JSON.parse(RestClient.get('https://api.github.com/user/emails',
- {:params => {:access_token => access_token},
- :accept => :json}))
- end
-
- erb :advanced, :locals => auth_result
- end
+ auth_result = JSON.parse(auth_result)
+
+ if scopes.include? 'user:email'
+ auth_result['private_emails'] =
+ JSON.parse(RestClient.get('https://api.github.com/user/emails',
+ {:params => {:access_token => access_token},
+ :accept => :json}))
end
- get '/callback' do
- session_code = request.env['rack.request.query_hash']['code']
+ erb :advanced, :locals => auth_result
+ end
+end
- result = RestClient.post('https://github.com/login/oauth/access_token',
- {:client_id => CLIENT_ID,
- :client_secret => CLIENT_SECRET,
- :code => session_code},
- :accept => :json)
+get '/callback' do
+ session_code = request.env['rack.request.query_hash']['code']
- session[:access_token] = JSON.parse(result)['access_token']
+ result = RestClient.post('https://github.com/login/oauth/access_token',
+ {:client_id => CLIENT_ID,
+ :client_secret => CLIENT_SECRET,
+ :code => session_code},
+ :accept => :json)
- redirect '/'
- end
+ session[:access_token] = JSON.parse(result)['access_token']
+ redirect '/'
+end
+```
Much of the code should look familiar. For example, we're still using `RestClient.get`
-to call out to the GitHub API, and we're still passing our results to be rendered
+to call out to the {{ site.data.variables.product.product_name }} API, and we're still passing our results to be rendered
in an ERB template (this time, it's called `advanced.erb`).
Also, we now have the `authenticated?` method which checks if the user is already
@@ -300,27 +315,28 @@ OAuth flow and updates the session with the granted token and scopes.
Next, create a file in _views_ called _advanced.erb_, and paste this markup into it:
- #!html+erb
-
-
-
-
-
Well, well, well, <%= login %>!
-
- <% if !email.empty? %> It looks like your public email address is <%= email %>.
- <% else %> It looks like you don't have a public email. That's cool.
- <% end %>
-
-
- <% if defined? private_emails %>
- With your permission, we were also able to dig up your private email addresses:
- <%= private_emails.join(', ') %>
- <% else %>
- Also, you're a bit secretive about your private email addresses.
- <% end %>
-
-
-
+``` erb
+
+
+
+
+
Well, well, well, <%= login %>!
+
+ <% if !email.empty? %> It looks like your public email address is <%= email %>.
+ <% else %> It looks like you don't have a public email. That's cool.
+ <% end %>
+
+
+ <% if defined? private_emails %>
+ With your permission, we were also able to dig up your private email addresses:
+ <%= private_emails.map{ |private_email_address| private_email_address["email"] }.join(', ') %>
+ <% else %>
+ Also, you're a bit secretive about your private email addresses.
+ <% end %>
+
+
+
+```
From the command line, call `ruby advanced_server.rb`, which starts up your
server on port `4567` -- the same port we used when we had a simple Sinatra app.
@@ -329,10 +345,10 @@ which redirects you to `/callback`. `/callback` then sends us back to `/`,
and since we've been authenticated, renders _advanced.erb_.
We could completely simplify this roundtrip routing by simply changing our callback
-URL in GitHub to `/`. But, since both _server.rb_ and _advanced.rb_ are relying on
+URL in {{ site.data.variables.product.product_name }} to `/`. But, since both _server.rb_ and _advanced.rb_ are relying on
the same callback URL, we've got to do a little bit of wonkiness to make it work.
-Also, if we had never authorized this application to access our GitHub data,
+Also, if we had never authorized this application to access our {{ site.data.variables.product.product_name }} data,
we would've seen the same confirmation dialog from earlier pop-up and warn us.
If you'd like, you can play around with [yet another Sinatra-GitHub auth example][sinatra auth github test]
@@ -341,7 +357,7 @@ available as a separate project.
[webflow]: /v3/oauth/#web-application-flow
[Sinatra]: http://www.sinatrarb.com/
[about env vars]: http://en.wikipedia.org/wiki/Environment_variable#Getting_and_setting_environment_variables
-[Sinatra guide]: http://sinatra-book.gittr.com/#hello_world_application
+[Sinatra guide]: https://github.com/sinatra/sinatra-book/blob/master/book/Introduction.markdown#hello-world-application
[REST Client]: https://github.com/archiloque/rest-client
[libraries]: /libraries/
[sinatra auth github test]: https://github.com/atmos/sinatra-auth-github-test
@@ -350,4 +366,4 @@ available as a separate project.
[check token valid]: /v3/oauth_authorizations/#check-an-authorization
[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/basics-of-authentication
[new oauth app]: https://github.com/settings/applications/new
-[app settings]: https://github.com/settings/applications
+[app settings]: https://github.com/settings/developers
diff --git a/content/guides/best-practices-for-integrators.md b/content/guides/best-practices-for-integrators.md
new file mode 100644
index 0000000000..f0cd17c9b4
--- /dev/null
+++ b/content/guides/best-practices-for-integrators.md
@@ -0,0 +1,162 @@
+---
+title: Best practices for integrators
+---
+
+# Best practices for integrators
+
+Interested in integrating with the GitHub platform? [You're in good company](https://github.com/integrations). This guide will help you build an app that provides the best experience for your users *and* ensure that it's reliably interacting with the API.
+
+{:toc}
+
+## Secure payloads delivered from GitHub
+
+It's very important that you secure [the payloads sent from GitHub][event-types]. Although no personal information (like passwords) is ever transmitted in a payload, leaking *any* information is not good. Some information that might be sensitive include committer email address or the names of private repositories.
+
+There are three steps you can take to secure receipt of payloads delivered by GitHub:
+
+1. Ensure that your receiving server is on an HTTPS connection. By default, GitHub will verify SSL certificates when delivering payloads.
+2. You can whitelist [the IP address we use when delivering hooks](https://help.github.com/articles/what-ip-addresses-does-github-use-that-i-should-whitelist) to your server. To ensure that you're always checking the right IP address, you can [use the `/meta` endpoint](/v3/meta/#meta) to find the address we use.
+3. Provide [a secret token](/webhooks/securing/) to ensure payloads are definitely coming from GitHub. By enforcing a secret token, you're ensuring that any data received by your server is absolutely coming from GitHub. Ideally, you should provide a different secret token *per user* of your service. That way, if one token is compromised, no other user would be affected.
+
+## Favor asynchronous work over synchronous
+
+GitHub expects that integrations respond within thirty seconds of receiving the webhook payload. If your service takes longer than that to complete, then GitHub terminates the connection and the payload is lost.
+
+Since it's impossible to predict how fast your service will complete, you should do all of "the real work" in a background job. [Resque](https://github.com/resque/resque/) (for Ruby), [RQ](http://python-rq.org/) (for Python), or [RabbitMQ](http://www.rabbitmq.com/) (for Java) are examples of libraries that can handle queuing and processing of background jobs.
+
+Note that even with a background job running, GitHub still expects your server to respond within thirty seconds. Your server simply needs to acknowledge that it received the payload by sending some sort of response. It's critical that your service to performs any validations on a payload as soon as possible, so that you can accurately report whether your server will continue with the request or not.
+
+## Use appropriate HTTP status codes when responding to GitHub
+
+Every webhook has its own "Recent Deliveries" section, which lists whether a deployment was successful or not.
+
+
+
+You should make use of proper HTTP status codes in order to inform users. You can use codes like `201` or `202` to acknowledge receipt of payload that won't be processed (for example, a payload delivered by a branch that's not the default). Reserve the `500` error code for catastrophic failures.
+
+## Provide as much information as possible to the user
+
+Users can dig into the server responses you send back to GitHub. Ensure that your messages are clear and informative.
+
+
+
+## Follow any redirects that the API sends you
+
+GitHub is explicit in telling you when a resource has moved by providing a redirect status code. You should follow these redirections. Every redirect response sets the `Location` header with the new URI to go to. If you receive a redirect, it's best to update your code to follow the new URI, in case you're requesting a deprecated path that we might remove.
+
+We've provided [a list of HTTP status codes](/v3/#http-redirects) to watch out for when designing your app to follow redirects.
+
+## Don't manually parse URLs
+
+Often, API responses contain data in the form of URLs. For example, when requesting a repository, we'll send a key called `clone_url` with a URL you can use to clone the repository.
+
+For the stability of your app, you shouldn't try to parse this data or try to guess and construct the format of future URLs. Your app is liable to break if we decide to change the URL.
+
+For example, when working with paginated results, it's often tempting to construct URLs that append `?page=` to the end. Avoid that temptation. [Our guide on pagination](/guides/traversing-with-pagination) offers some safe tips on dependably following paginated results.
+
+## Check the event type and action before processing the event
+
+There are multiple [webhook event types][event-types], and each event can have multiple actions. As GitHub's feature set grows, we will occasionally add new event types or add new actions to existing event types. Ensure that your application explicitly checks the type and action of an event before doing any webhook processing. The `X-GitHub-Event` request header can be used to know which event has been received so that processing can be handled appropriately. Similarly, the payload has a top-level `action` key that can be used to know which action was taken on the relevant object.
+
+For example, if you have configured a GitHub webhook to "Send me **everything**", your application will begin receiving new event types and actions as they are added. It is therefore **not recommended to use any sort of catch-all else clause**. Take the following code example:
+
+```ruby
+# Not recommended: a catch-all else clause
+def receive
+ event_type = request.headers["X-GitHub-Event"]
+ payload = request.body
+
+ case event_type
+ when "repository"
+ process_repository(payload)
+ when "issues"
+ process_issues(payload)
+ else
+ process_pull_requests
+ end
+end
+```
+
+In this code example, the `process_repository` and `process_issues` methods will be correctly called if a `repository` or `issues` event was received. However, any other event type would result in `process_pull_requests` being called. As new event types are added, this would result in incorrect behavior and new event types would be processed in the same way that a `pull_request` event would be processed.
+
+Instead, we suggest explicitly checking event types and acting accordingly. In the following code example, we explicitly check for a `pull_request` event and the `else` clause simply logs that we've received a new event type:
+
+```ruby
+# Recommended: explicitly check each event type
+def receive
+ event_type = request.headers["X-GitHub-Event"]
+ payload = JSON.parse(request.body)
+
+ case event_type
+ when "repository"
+ process_repository(payload)
+ when "issues"
+ process_issue(payload)
+ when "pull_request"
+ process_pull_requests(payload)
+ else
+ puts "Oooh, something new from GitHub: #{event_type}"
+ end
+end
+```
+
+Because each event can also have multiple actions, it's recommended that actions are checked similarly. For example, the [`IssuesEvent`](https://developer.github.com/v3/activity/events/types/#issuesevent) has several possible actions. These include `opened` when the issue is created, `closed` when the issue is closed, and `assigned` when the issue is assigned to someone.
+
+As with adding event types, we may add new actions to existing events. It is therefore again **not recommended to use any sort of catch-all else clause** when checking an event's action. Instead, we suggest explicitly checking event actions as we did with the event type. An example of this looks very similar to what we suggested for event types above:
+
+```ruby
+# Recommended: explicitly check each action
+def process_issue(payload)
+ case payload["action"]
+ when "opened"
+ process_issue_opened(payload)
+ when "assigned"
+ process_issue_assigned(payload)
+ when "closed"
+ process_issue_closed(payload)
+ else
+ puts "Oooh, something new from GitHub: #{payload["action"]}"
+ end
+end
+```
+
+In this example the `closed` action is checked first before calling the `process_closed` method. Any unidentified actions are logged for future reference.
+
+{% if page.version == 'dotcom' %}
+
+## Dealing with rate limits
+
+The GitHub API [rate limit](/v3/#rate-limiting) ensures that the API is fast and available for everyone.
+
+If you hit a rate limit, it's expected that you back off from making requests and try again later when you're permitted to do so. Failure to do so may result in the banning of your app.
+
+You can always [check your rate limit status](/v3/rate_limit/) at any time. Checking your rate limit incurs no cost against your rate limit.
+
+## Dealing with abuse rate limits
+
+[Abuse rate limits](/v3/#abuse-rate-limits) are another way we ensure the API's availability.
+To avoid hitting this limit, you should ensure your application follows the guidelines below.
+
+* Make authenticated requests, or use your application's client ID and secret. Unauthenticated
+ requests are subject to more aggressive abuse rate limiting.
+* Make requests for a single user or client ID serially. Do not make requests for a single user
+ or client ID concurrently.
+* If you're making a large number of `POST`, `PATCH`, `PUT`, or `DELETE` requests for a single user
+ or client ID, wait at least one second between each request.
+* Requests that create content which triggers notifications, such as issues, comments and pull requests,
+ may be further limited. Please create this content at a reasonable pace to avoid further limiting.
+* When you have been limited, wait the number of seconds specified in the `Retry-After` response header.
+
+We reserve the right to change these guidelines as needed to ensure availability.
+
+{% endif %}
+
+## Dealing with API errors
+
+Although your code would never introduce a bug, you may find that you've encountered successive errors when trying to access the API.
+
+Rather than ignore repeated `4xx` and `5xx` status codes, you should ensure that you're correctly interacting with the API. For example, if an endpoint requests a string and you're passing it a numeric value, you're going to receive a `5xx` validation error, and your call won't succeed. Similarly, attempting to access an unauthorized or nonexistent endpoint will result in a `4xx` error.
+
+Intentionally ignoring repeated validation errors may result in the suspension of your app for abuse.
+
+[event-types]: /v3/activity/events/types/
diff --git a/content/guides/building-a-ci-server.md b/content/guides/building-a-ci-server.md
new file mode 100644
index 0000000000..be7373dc57
--- /dev/null
+++ b/content/guides/building-a-ci-server.md
@@ -0,0 +1,176 @@
+---
+title: Building a CI server
+---
+
+# Building a CI server
+
+{:toc}
+
+The [Status API][status API] is responsible for tying together commits with
+a testing service, so that every push you make can be tested and represented
+in a {{ site.data.variables.product.product_name }} pull request.
+
+This guide will use that API to demonstrate a setup that you can use.
+In our scenario, we will:
+
+* Run our CI suite when a Pull Request is opened (we'll set the CI status to pending).
+* When the CI is finished, we'll set the Pull Request's status accordingly.
+
+Our CI system and host server will be figments of our imagination. They could be
+Travis, Jenkins, or something else entirely. The crux of this guide will be setting up
+and configuring the server managing the communication.
+
+If you haven't already, be sure to [download ngrok][ngrok], and learn how
+to [use it][using ngrok]. We find it to be a very useful tool for exposing local
+connections.
+
+Note: you can download the complete source code for this project
+[from the platform-samples repo][platform samples].
+
+## Writing your server
+
+We'll write a quick Sinatra app to prove that our local connections are working.
+Let's start with this:
+
+``` ruby
+require 'sinatra'
+require 'json'
+
+post '/event_handler' do
+ payload = JSON.parse(params[:payload])
+ "Well, it worked!"
+end
+```
+
+(If you're unfamiliar with how Sinatra works, we recommend [reading the Sinatra guide][Sinatra].)
+
+Start this server up. By default, Sinatra starts on port `4567`, so you'll want
+to configure ngrok to start listening for that, too.
+
+In order for this server to work, we'll need to set a repository up with a webhook.
+The webhook should be configured to fire whenever a Pull Request is created, or merged.
+Go ahead and create a repository you're comfortable playing around in. Might we
+suggest [@octocat's Spoon/Knife repository](https://github.com/octocat/Spoon-Knife)?
+After that, you'll create a new webhook in your repository, feeding it the URL
+that ngrok gave you, and choosing `application/x-www-form-urlencoded` as the
+content type:
+
+
+
+Click **Update webhook**. You should see a body response of `Well, it worked!`.
+Great! Click on **Let me select individual events**, and select the following:
+
+* Status
+* Pull Request
+
+These are the events {{ site.data.variables.product.product_name }} will send to our server whenever the relevant action
+occurs. Let's update our server to *just* handle the Pull Request scenario right now:
+
+``` ruby
+post '/event_handler' do
+ @payload = JSON.parse(params[:payload])
+
+ case request.env['HTTP_X_GITHUB_EVENT']
+ when "pull_request"
+ if @payload["action"] == "opened"
+ process_pull_request(@payload["pull_request"])
+ end
+ end
+end
+
+helpers do
+ def process_pull_request(pull_request)
+ puts "It's #{pull_request['title']}"
+ end
+end
+```
+
+What's going on? Every event that {{ site.data.variables.product.product_name }} sends out attached a `X-GitHub-Event`
+HTTP header. We'll only care about the PR events for now. From there, we'll
+take the payload of information, and return the title field. In an ideal scenario,
+our server would be concerned with every time a pull request is updated, not just
+when it's opened. That would make sure that every new push passes the CI tests.
+But for this demo, we'll just worry about when it's opened.
+
+To test out this proof-of-concept, make some changes in a branch in your test
+repository, and open a pull request. Your server should respond accordingly!
+
+## Working with statuses
+
+With our server in place, we're ready to start our first requirement, which is
+setting (and updating) CI statuses. Note that at any time you update your server,
+you can click **Redeliver** to send the same payload. There's no need to make a
+new pull request every time you make a change!
+
+Since we're interacting with the {{ site.data.variables.product.product_name }} API, we'll use [Octokit.rb][octokit.rb]
+to manage our interactions. We'll configure that client with
+[a personal access token][access token]:
+
+``` ruby
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+ACCESS_TOKEN = ENV['MY_PERSONAL_TOKEN']
+
+before do
+ @client ||= Octokit::Client.new(:access_token => ACCESS_TOKEN)
+end
+```
+
+After that, we'll just need to update the pull request on {{ site.data.variables.product.product_name }} to make clear
+that we're processing on the CI:
+
+``` ruby
+def process_pull_request(pull_request)
+ puts "Processing pull request..."
+ @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'pending')
+end
+```
+
+We're doing three very basic things here:
+
+* we're looking up the full name of the repository
+* we're looking up the last SHA of the pull request
+* we're setting the status to "pending"
+
+That's it! From here, you can run whatever process you need to in order to execute
+your test suite. Maybe you're going to pass off your code to Jenkins, or call
+on another web service via its API, like [Travis][travis api]. After that, you'd
+be sure to update the status once more. In our example, we'll just set it to `"success"`:
+
+``` ruby
+def process_pull_request(pull_request)
+ @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'pending')
+ sleep 2 # do busy work...
+ @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'success')
+ puts "Pull request processed!"
+end
+```
+
+## Conclusion
+
+At GitHub, we've used a version of [Janky][janky] to manage our CI for years.
+The basic flow is essentially the exact same as the server we've built above.
+At GitHub, we:
+
+* Fire to Jenkins when a pull request is created or updated (via Janky)
+* Wait for a response on the state of the CI
+* If the code is green, we merge the pull request
+
+All of this communication is funneled back to our chat rooms. You don't need to
+build your own CI setup to use this example.
+You can always rely on [GitHub integrations][integrations].
+
+[deploy API]: /v3/repos/deployments/
+[status API]: /v3/repos/statuses/
+[ngrok]: https://ngrok.com/
+[using ngrok]: /webhooks/configuring/#using-ngrok
+[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/building-a-ci-server
+[Sinatra]: http://www.sinatrarb.com/
+[webhook]: /webhooks/
+[octokit.rb]: https://github.com/octokit/octokit.rb
+[access token]: https://help.github.com/articles/creating-an-access-token-for-command-line-use
+[travis api]: https://api.travis-ci.org/docs/
+[janky]: https://github.com/github/janky
+[heaven]: https://github.com/atmos/heaven
+[hubot]: https://github.com/github/hubot
+[integrations]: https://github.com/integrations
diff --git a/content/guides/delivering-deployments.md b/content/guides/delivering-deployments.md
new file mode 100644
index 0000000000..8644ae2d2f
--- /dev/null
+++ b/content/guides/delivering-deployments.md
@@ -0,0 +1,193 @@
+---
+title: Delivering deployments
+---
+
+# Delivering deployments
+
+{:toc}
+
+The [Deployments API][deploy API] provides your projects hosted on {{ site.data.variables.product.product_name }} with
+the capability to launch them on a server that you own. Combined with
+[the Status API][status API], you'll be able to coordinate your deployments
+the moment your code lands on `master`.
+
+This guide will use that API to demonstrate a setup that you can use.
+In our scenario, we will:
+
+* Merge a pull request
+* When the CI is finished, we'll set the pull request's status accordingly.
+* When the pull request is merged, we'll run our deployment to our server.
+
+Our CI system and host server will be figments of our imagination. They could be
+Heroku, Amazon, or something else entirely. The crux of this guide will be setting up
+and configuring the server managing the communication.
+
+If you haven't already, be sure to [download ngrok][ngrok], and learn how
+to [use it][using ngrok]. We find it to be a very useful tool for exposing local
+connections.
+
+Note: you can download the complete source code for this project
+[from the platform-samples repo][platform samples].
+
+## Writing your server
+
+We'll write a quick Sinatra app to prove that our local connections are working.
+Let's start with this:
+
+``` ruby
+require 'sinatra'
+require 'json'
+
+post '/event_handler' do
+ payload = JSON.parse(params[:payload])
+ "Well, it worked!"
+end
+```
+
+(If you're unfamiliar with how Sinatra works, we recommend [reading the Sinatra guide][Sinatra].)
+
+Start this server up. By default, Sinatra starts on port `4567`, so you'll want
+to configure ngrok to start listening for that, too.
+
+In order for this server to work, we'll need to set a repository up with a webhook.
+The webhook should be configured to fire whenever a pull request is created, or merged.
+Go ahead and create a repository you're comfortable playing around in. Might we
+suggest [@octocat's Spoon/Knife repository](https://github.com/octocat/Spoon-Knife)?
+After that, you'll create a new webhook in your repository, feeding it the URL
+that ngrok gave you, and choosing `application/x-www-form-urlencoded` as the
+content type:
+
+
+
+Click **Update webhook**. You should see a body response of `Well, it worked!`.
+Great! Click on **Let me select individual events.**, and select the following:
+
+* Deployment
+* Deployment status
+* Pull Request
+
+These are the events {{ site.data.variables.product.product_name }} will send to our server whenever the relevant action
+occurs. We'll configure our server to *just* handle when pull requests are merged
+right now:
+
+``` ruby
+post '/event_handler' do
+ @payload = JSON.parse(params[:payload])
+
+ case request.env['HTTP_X_GITHUB_EVENT']
+ when "pull_request"
+ if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
+ puts "A pull request was merged! A deployment should start now..."
+ end
+ end
+end
+```
+
+What's going on? Every event that {{ site.data.variables.product.product_name }} sends out attached a `X-GitHub-Event`
+HTTP header. We'll only care about the PR events for now. When a pull request is
+merged (its state is `closed`, and `merged` is `true`), we'll kick off a deployment.
+
+To test out this proof-of-concept, make some changes in a branch in your test
+repository, open a pull request, and merge it. Your server should respond accordingly!
+
+## Working with deployments
+
+With our server in place, the code being reviewed, and our pull request
+merged, we want our project to be deployed.
+
+We'll start by modifying our event listener to process pull requests when they're
+merged, and start paying attention to deployments:
+
+``` ruby
+when "pull_request"
+ if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
+ start_deployment(@payload["pull_request"])
+ end
+when "deployment"
+ process_deployment(@payload)
+when "deployment_status"
+ update_deployment_status
+end
+```
+
+Based on the information from the pull request, we'll start by filling out the
+`start_deployment` method:
+
+``` ruby
+def start_deployment(pull_request)
+ user = pull_request['user']['login']
+ payload = JSON.generate(:environment => 'production', :deploy_user => user)
+ @client.create_deployment(pull_request['head']['repo']['full_name'], pull_request['head']['sha'], {:payload => payload, :description => "Deploying my sweet branch"})
+end
+```
+
+Deployments can have some metadata attached to them, in the form of a `payload`
+and a `description`. Although these values are optional, it's helpful to use
+for logging and representing information.
+
+When a new deployment is created, a completely separate event is triggered. That's
+why we have a new `switch` case in the event handler for `deployment`. You can
+use this information to be notified when a deployment has been triggered.
+
+Deployments can take a rather long time, so we'll want to listen for various events,
+such as when the deployment was created, and what state it's in.
+
+Let's simulate a deployment that does some work, and notice the effect it has on
+the output. First, let's complete our `process_deployment` method:
+
+``` ruby
+def process_deployment
+ payload = JSON.parse(@payload['payload'])
+ # you can send this information to your chat room, monitor, pager, etc.
+ puts "Processing '#{@payload['description']}' for #{payload['deploy_user']} to #{payload['environment']}"
+ sleep 2 # simulate work
+ @client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'pending')
+ sleep 2 # simulate work
+ @client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'success')
+end
+```
+
+Finally, we'll simulate storing the status information as console output:
+
+``` ruby
+def update_deployment_status
+ puts "Deployment status for #{@payload['id']} is #{@payload['state']}"
+end
+```
+
+Let's break down what's going on. A new deployment is created by `start_deployment`,
+which triggers the `deployment` event. From there, we call `process_deployment`
+to simulate work that's going on. During that processing, we also make a call to
+`create_deployment_status`, which lets a receiver know what's going on, as we
+switch the status to `pending`.
+
+After the deployment is finished, we set the status to `success`.
+
+## Conclusion
+
+At GitHub, we've used a version of [Heaven][heaven] to manage
+our deployments for years. The basic flow is essentially the exact same as the
+server we've built above. At GitHub, we:
+
+* Wait for a response on the state of the CI
+* If the code is green, we merge the pull request
+* Heaven takes the merged code, and deploys it to our production and staging servers
+* In the meantime, Heaven also notifies everyone about the build, via [Hubot][hubot] sitting in our chat rooms
+
+That's it! You don't need to build your own deployment setup to use this example.
+You can always rely on [GitHub integrations][integrations].
+
+[deploy API]: /v3/repos/deployments/
+[status API]: /guides/building-a-ci-server
+[ngrok]: https://ngrok.com/
+[using ngrok]: /webhooks/configuring/#using-ngrok
+[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/delivering-deployments
+[Sinatra]: http://www.sinatrarb.com/
+[webhook]: /webhooks/
+[octokit.rb]: https://github.com/octokit/octokit.rb
+[access token]: https://help.github.com/articles/creating-an-access-token-for-command-line-use
+[travis api]: https://api.travis-ci.org/docs/
+[janky]: https://github.com/github/janky
+[heaven]: https://github.com/atmos/heaven
+[hubot]: https://github.com/github/hubot
+[integrations]: https://github.com/integrations
diff --git a/content/guides/discovering-resources-for-a-user.md b/content/guides/discovering-resources-for-a-user.md
new file mode 100644
index 0000000000..05de85254b
--- /dev/null
+++ b/content/guides/discovering-resources-for-a-user.md
@@ -0,0 +1,102 @@
+---
+title: Discovering resources for a user
+---
+
+# Discovering resources for a user
+
+{:toc}
+
+When making authenticated requests to the {{ site.data.variables.product.product_name }} API, applications often need to fetch the current user's repositories and organizations. In this guide, we'll explain how to reliably discover those resources.
+
+To interact with the {{ site.data.variables.product.product_name }} API, we'll be using [Octokit.rb][octokit.rb]. You can find the complete source code for this project in the [platform-samples][platform samples] repository.
+
+## Getting started
+
+If you haven't already, you should read the ["Basics of Authentication"][basics-of-authentication] guide before working through the examples below. The examples below assume that you have [registered an OAuth application][register-oauth-app] and that your [application has an OAuth token for a user][make-authenticated-request-for-user].
+
+## Discover the repositories that your app can access for a user
+
+In addition to having their own personal repositories, a user may be a collaborator on repositories owned by other users and organizations. Collectively, these are the repositories where the user has privileged access: either it's a private repository where the user has read or write access, or it's a public repository where the user has write access.
+
+[OAuth scopes][scopes] and [organization application policies][oap] determine which of those repositories your app can access for a user. Use the workflow below to discover those repositories.
+
+As always, first we'll require [GitHub's Octokit.rb][octokit.rb] Ruby library. Then we'll configure Octokit.rb to automatically handle [pagination][pagination] for us.
+
+``` ruby
+require 'octokit'
+
+Octokit.auto_paginate = true
+```
+
+Next, we'll pass in our application's [OAuth token for a given user][make-authenticated-request-for-user]:
+
+``` ruby
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below.
+client = Octokit::Client.new :access_token => ENV["OAUTH_ACCESS_TOKEN"]
+```
+
+Then, we're ready to fetch the [repositories that our application can access for the user][list-repositories-for-current-user]:
+
+``` ruby
+client.repositories.each do |repository|
+ full_name = repository[:full_name]
+ has_push_access = repository[:permissions][:push]
+
+ access_type = if has_push_access
+ "write"
+ else
+ "read-only"
+ end
+
+ puts "User has #{access_type} access to #{full_name}."
+end
+```
+
+## Discover the organizations that your app can access for a user
+
+Applications can perform all sorts of organization-related tasks for a user. To perform these tasks, the app needs an [OAuth authorization][scopes] with sufficient permission. For example, the `read:org` scope allows you to [list teams][list-teams], and the `user` scope lets you [publicize the user’s organization membership][publicize-membership]. Once a user has granted one or more of these scopes to your app, you're ready to fetch the user’s organizations.
+
+Just as we did when discovering repositories above, we'll start by requiring [GitHub's Octokit.rb][octokit.rb] Ruby library and configuring it to take care of [pagination][pagination] for us:
+
+``` ruby
+require 'octokit'
+
+Octokit.auto_paginate = true
+```
+
+Next, we'll pass in our application's [OAuth token for a given user][make-authenticated-request-for-user] to initialize our API client:
+
+``` ruby
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below.
+client = Octokit::Client.new :access_token => ENV["OAUTH_ACCESS_TOKEN"]
+```
+
+Then, we can [list the organizations that our application can access for the user][list-orgs-for-current-user]:
+
+``` ruby
+client.organizations.each do |organization|
+ puts "User belongs to the #{organization[:login]} organization."
+end
+```
+
+### Don’t rely on public organizations
+
+If you've read the docs from cover to cover, you may have noticed an [API method for listing a user's public organization memberships][list-public-orgs]. Most applications should avoid this API method. This method only returns the user's public organization memberships, not their private organization memberships.
+
+As an application, you typically want all of the user's organizations (public and private) that your app is authorized to access. The workflow above will give you exactly that.
+
+[basics-of-authentication]: /guides/basics-of-authentication/
+[list-public-orgs]: /v3/orgs/#list-user-organizations
+[list-repositories-for-current-user]: /v3/repos/#list-your-repositories
+[list-orgs-for-current-user]: /v3/orgs/#list-your-organizations
+[list-teams]: /v3/orgs/teams/#list-teams
+[make-authenticated-request-for-user]: /guides/basics-of-authentication/#making-authenticated-requests
+[oap]: /changes/2015-01-19-an-integrators-guide-to-organization-application-policies/
+[octokit.rb]: https://github.com/octokit/octokit.rb
+[pagination]: /v3/#pagination
+[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/discovering-resources-for-a-user
+[publicize-membership]: /v3/orgs/members/#publicize-a-users-membership
+[register-oauth-app]: /guides/basics-of-authentication/#registering-your-app
+[scopes]: /v3/oauth/#scopes
diff --git a/content/guides/getting-started.md b/content/guides/getting-started.md
index 83b668c593..f1dd314067 100644
--- a/content/guides/getting-started.md
+++ b/content/guides/getting-started.md
@@ -1,10 +1,9 @@
---
-title: Getting Started | GitHub API
+title: Getting Started
---
# Getting Started
-* TOC
{:toc}
Let's walk through core API concepts as we tackle some everyday use cases.
@@ -20,61 +19,61 @@ There's no easier way to kick the tires than through [cURL][curl].
### Hello World
Let's start by testing our setup. Open up a command prompt and enter the
-following command (without the `$`):
+following command:
-
+> Keep it logically awesome.
+```
The response will be a random selection from our design philosophies.
Next, let's `GET` [Chris Wanstrath's][defunkt github] [GitHub profile][users api]:
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/users/defunkt
+
+> HTTP/1.1 200 OK
+> Server: GitHub.com
+> Date: Sun, 11 Nov 2012 18:43:28 GMT
+> Content-Type: application/json; charset=utf-8
+> Connection: keep-alive
+> Status: 200 OK
+> ETag: "bfd85cbf23ac0b0c8a29bee02e7117c6"
+> X-RateLimit-Limit: 60
+> X-RateLimit-Remaining: 57
+> X-RateLimit-Reset: 1352660008
+> X-GitHub-Media-Type: github.v3
+> Vary: Accept
+> Cache-Control: public, max-age=60, s-maxage=60
+> X-Content-Type-Options: nosniff
+> Content-Length: 692
+> Last-Modified: Tue, 30 Oct 2012 18:58:42 GMT
+
+> {
+> "login": "defunkt",
+> "id": 2,
+> "url": "{{ site.data.variables.product.api_url_pre }}/users/defunkt",
+> "html_url": "https://github.com/defunkt",
+> ...
+> }
+```
There are a few interesting bits in the response headers. As expected, the
`Content-Type` is `application/json`.
@@ -82,7 +81,7 @@ There are a few interesting bits in the response headers. As expected, the
Any headers beginning with `X-` are custom headers, and are not included in the
HTTP spec. Let's take a look at a few of them:
-* `X-GitHub-Media-Type` has a value of `github.beta`. This lets us know the [media type][media types]
+* `X-GitHub-Media-Type` has a value of `github.v3`. This lets us know the [media type][media types]
for the response. Media types have helped us version our output in API v3. We'll
talk more about that later.
* Take note of the `X-RateLimit-Limit` and `X-RateLimit-Remaining` headers. This
@@ -93,19 +92,19 @@ client has already spent.
## Authentication
Unauthenticated clients can make 60 requests per hour. To get more, we'll need to
-_authenticate_. In fact, doing anything interesting with the GitHub API requires
+_authenticate_. In fact, doing anything interesting with the {{ site.data.variables.product.product_name }} API requires
[authentication][authentication].
### Basic
-The easiest way to authenticate with the GitHub API is by simply using your GitHub
+The easiest way to authenticate with the {{ site.data.variables.product.product_name }} API is by simply using your {{ site.data.variables.product.product_name }}
username and password via Basic Authentication.
-
+> Enter host password for user your_username:
+```
The `-u` flag sets the username, and cURL will prompt you for the password. You
can use `-u "username:password"` to avoid the prompt, but this leaves your
@@ -121,19 +120,19 @@ reading and writing private information via the API.
If you have [two-factor authentication][2fa] enabled, the API will return a
`401 Unauthorized` error code for the above request (and every other API request):
-
+> {
+> "message": "Must specify two-factor authentication OTP code.",
+> "documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication"
+> }
+```
The easiest way to get around that error is to create an OAuth token and use
OAuth authentication instead of Basic Authentication. See the
@@ -142,32 +141,32 @@ OAuth authentication instead of Basic Authentication. See the
### Get your own user profile
When properly authenticated, you can take advantage of the permissions
-associated with your GitHub account. For example, try getting
+associated with your {{ site.data.variables.product.product_name }} account. For example, try getting
[your own user profile][auth user api]:
-
+``` command-line
+$ curl -i -u your_username {{ site.data.variables.product.api_url_pre }}/user
+
+> {
+> ...
+> "plan": {
+> "space": 2516582,
+> "collaborators": 10,
+> "private_repos": 20,
+> "name": "medium"
+> }
+> ...
+> }
+```
This time, in addition to the same set of public information we
retrieved for [@defunkt][defunkt github] earlier, you should also see the non-public
information for your user profile. For example, you'll see a `plan` object
-in the response which gives details about the GitHub plan for the account.
+in the response which gives details about the {{ site.data.variables.product.product_name }} plan for the account.
### OAuth
-While convenient, Basic Authentication isn't ideal because you shouldn't give your GitHub
+While convenient, Basic Authentication isn't ideal because you shouldn't give your {{ site.data.variables.product.product_name }}
username and password to anyone. Applications that need to read or write
private information using the API on behalf of another user should use [OAuth][oauth].
@@ -179,58 +178,61 @@ features:
will provide before authorizing a third party app
Normally, tokens are created via a [web flow][webflow]. An application
-sends users to GitHub to log in. GitHub then presents a dialog
+sends users to {{ site.data.variables.product.product_name }} to log in. {{ site.data.variables.product.product_name }} then presents a dialog
indicating the name of the app, as well as the level of access the app
-has once it's authorized by the user. After a user authorizes access, GitHub
+has once it's authorized by the user. After a user authorizes access, {{ site.data.variables.product.product_name }}
redirects the user back to the application:
-
+
However, you don't need to set up the entire web flow to begin working with OAuth tokens.
-An easier way to get a token is to [create a **Personal token**][personal token] via your
-[Application settings page][application settings]:
+An easier way to get a token is to [create a **personal access token**][personal token] via your
+[Personal access tokens settings page][tokens settings]:
-
+
Also, the [**Authorizations API**][authorizations api] makes it simple to use Basic Authentication
to create an OAuth token. Try pasting and running the following command:
-
+``` command-line
+$ curl -i -u your_username -d '{"scopes": ["repo", "user"], "note": "getting-started"}' \
+$ {{ site.data.variables.product.api_url_pre }}/authorizations
+
+> HTTP/1.1 201 Created
+> Location: {{ site.data.variables.product.api_url_pre }}/authorizations/2
+> Content-Length: 384
+
+> {
+> "scopes": [
+> "repo",
+> "user"
+> ],
+> "token": "5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4",
+> "updated_at": "2012-11-14T14:04:24Z",
+> "url": "{{ site.data.variables.product.api_url_pre }}/authorizations/2",
+> "app": {
+> "url": "https://developer.github.com/v3/oauth/#oauth-authorizations-api",
+> "name": "GitHub API"
+> },
+> "created_at": "2012-11-14T14:04:24Z",
+> "note_url": null,
+> "id": 2,
+> "note": "getting-started"
+> }
+```
There's a lot going on in this one little call, so let's break it down. First,
the `-d` flag indicates we're doing a `POST`, using the
`application/x-www-form-urlencoded` content type (as opposed to `GET`). All `POST`
-requests to the GitHub API should be in JSON.
+requests to the {{ site.data.variables.product.product_name }} API should be in JSON.
Next, let's look at the `scopes` we're sending over in this call. When creating
a new token, we include an optional array of [_scopes_][scopes], or access
levels, that indicate what information this token can access. In this case,
we're setting up the token with _repo_ access, which grants access to read and
-write to private repositories. See [the scopes docs][scopes] for a full list of
+write to public and private repositories, and _user_ scope, which grants read
+and write access to public and private user profile data. See
+[the scopes docs][scopes] for a full list of
scopes. You should **only** request scopes that your application actually needs,
in order to not frighten users with potentially invasive actions. The `201`
status code tells us that the call was successful, and the JSON returned
@@ -241,10 +243,11 @@ return the [previously described `401 Unauthorized` error code][2fa section]
for the above request. You can get around that error by providing a 2FA OTP code
in the [X-GitHub-OTP request header][2fa header]:
-
+``` command-line
+$ curl -i -u your_username -H "X-GitHub-OTP: your_2fa_OTP_code" \
+ -d '{"scopes": ["repo", "user"], "note": "getting-started"}' \
+ {{ site.data.variables.product.api_url_pre }}/authorizations
+```
If you enabled 2FA with a mobile application, go ahead and get an OTP code from
your one-time password application on your phone. If you enabled 2FA with text
@@ -254,10 +257,10 @@ this endpoint.
Now, we can use the forty character `token` instead of a username and password
in the rest of our examples. Let's grab our own user info again, using OAuth this time:
-
+ {{ site.data.variables.product.api_url_pre }}/user
+```
**Treat OAuth tokens like passwords!** Don't share them with other users or store
them in insecure places. The tokens in these examples are fake and the names have
@@ -268,32 +271,32 @@ the [Repositories API][repos-api].
## Repositories
-Almost any meaningful use of the GitHub API will involve some level of Repository
+Almost any meaningful use of the {{ site.data.variables.product.product_name }} API will involve some level of Repository
information. We can [`GET` repository details][get repo] in the same way we fetched user
details earlier:
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/repos/twbs/bootstrap
+```
In the same way, we can [view repositories for the authenticated user][user repos api]:
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/users/technoweenie/repos
+```
Or, we can [list repositories for an organization][org repos api]:
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/orgs/mozilla/repos
+```
The information returned from these calls will depend on how we authenticate:
@@ -307,9 +310,9 @@ can filter the repositories returned based on what type of access the user has
for the repository. In this way, we can fetch only directly-owned repositories,
organization repositories, or repositories the user collaborates on via a team.
-
+``` command-line
+$ curl -i "{{ site.data.variables.product.api_url_pre }}/users/technoweenie/repos?type=owner"
+```
In this example, we grab only those repositories that technoweenie owns, not the
ones on which he collaborates. Note the quoted URL above. Depending on your
@@ -319,10 +322,10 @@ query string.
### Create a repository
Fetching information for existing repositories is a common use case, but the
-GitHub API supports creating new repositories as well. To [create a repository][create repo],
+{{ site.data.variables.product.product_name }} API supports creating new repositories as well. To [create a repository][create repo],
we need to `POST` some JSON containing the details and configuration options.
-
+ {{ site.data.variables.product.api_url_pre }}/user/repos
+```
In this minimal example, we create a new repository for our blog (to be served
on [GitHub Pages][pages], perhaps). Though the blog will be public, we've made
the repository private. In this single step, we'll also initialize it with
-a README and a [nanoc][nanoc]-flavored [.gitignore template][gitignore
-templates].
+a README and a [nanoc][nanoc]-flavored [.gitignore template][gitignore templates].
The resulting repository will be found at `https://github.com//blog`.
To create a repository under an organization for which you're
@@ -345,50 +347,50 @@ an owner, just change the API method from `/user/repos` to `/orgs//rep
Next, let's fetch our newly created repository:
-
-$ curl -i https://api.github.com/repos/pengwynn/blog
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/repos/pengwynn/blog
-HTTP/1.1 404 Not Found
+> HTTP/1.1 404 Not Found
-{
- "message": "Not Found"
-}
-
+> {
+> "message": "Not Found"
+> }
+```
Oh noes! Where did it go? Since we created the repository as _private_, we need
to authenticate in order to see it. If you're a grizzled HTTP user, you might
expect a `403` instead. Since we don't want to leak information about private
-repositories, the GitHub API returns a `404` in this case, as if to say "we can
+repositories, the {{ site.data.variables.product.product_name }} API returns a `404` in this case, as if to say "we can
neither confirm nor deny the existence of this repository."
## Issues
-The UI for Issues on GitHub aims to provide 'just enough' workflow while
-staying out of your way. With the GitHub [Issues API][issues-api], you can pull
+The UI for Issues on {{ site.data.variables.product.product_name }} aims to provide 'just enough' workflow while
+staying out of your way. With the {{ site.data.variables.product.product_name }} [Issues API][issues-api], you can pull
data out or create issues from other tools to create a workflow that works for
your team.
Just like github.com, the API provides a few methods to view issues for the
authenticated user. To [see all your issues][get issues api], call `GET /issues`:
-
+ {{ site.data.variables.product.api_url_pre }}/issues
+```
-To get only the [issues under one of your GitHub organizations][get issues api], call `GET
+To get only the [issues under one of your {{ site.data.variables.product.product_name }} organizations][get issues api], call `GET
/orgs//issues`:
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/repos/rails/rails/issues
+```
### Pagination
@@ -396,14 +398,15 @@ A project the size of Rails has thousands of issues. We'll need to [paginate][pa
making multiple API calls to get the data. Let's repeat that last call, this
time taking note of the response headers:
-
+> ...
+> Link: <{{ site.data.variables.product.api_url_pre }}/repositories/8514/issues?page=2>; rel="next", <{{ site.data.variables.product.api_url_pre }}/repositories/8514/issues?page=30>; rel="last"
+> ...
+```
The [`Link` header][link-header] provides a way for a response to link to
external resources, in this case additional pages of data. Since our call found
@@ -420,55 +423,55 @@ OAuth token in the header. Also, we'll pass the title, body, and labels in the J
body to the `/issues` path underneath the repository in which we want to create
the issue:
-
+> HTTP/1.1 200 OK
+> ETag: "bfd85cbf23ac0b0c8a29bee02e7117c6"
+```
In addition to the JSON body, take note of the HTTP status code of `200` and
the `ETag` header.
The [ETag][etag] is a fingerprint of the response. If we pass that on subsequent calls,
we can tell the API to give us the resource again, only if it has changed:
-
+> HTTP/1.1 304 Not Modified
+```
The `304` status indicates that the resource hasn't changed since the last time
we asked for it and the response will contain no body. As a bonus, `304`
responses don't count against your [rate limit][rate-limiting].
-Woot! Now you know the basics of the GitHub API!
+Woot! Now you know the basics of the {{ site.data.variables.product.product_name }} API!
* Basic & OAuth authentication
* Fetching and creating repositories and issues
@@ -521,10 +524,10 @@ Keep learning with the next API guide [Basics of Authentication][auth guide]!
[scopes]: /v3/oauth/#scopes
[repos-api]: /v3/repos/
[pages]: http://pages.github.com
-[nanoc]: http://nanoc.stoneship.org/
+[nanoc]: http://nanoc.ws/
[gitignore templates]: https://github.com/github/gitignore
[issues-api]: /v3/issues/
-[link-header]: http://www.w3.org/wiki/LinkHeader
+[link-header]: http://www.w3.org/wiki/LinkHeader/
[conditional-requests]: /v3/#conditional-requests
[rate-limiting]: /v3/#rate-limiting
[users api]: /v3/users/#get-a-single-user
@@ -537,7 +540,7 @@ Keep learning with the next API guide [Basics of Authentication][auth guide]!
[2fa header]: /v3/auth/#working-with-two-factor-authentication
[oauth section]: /guides/getting-started/#oauth
[personal token]: https://help.github.com/articles/creating-an-access-token-for-command-line-use
-[application settings]: https://github.com/settings/applications
+[tokens settings]: https://github.com/settings/tokens
[pagination]: /v3/#pagination
[get repo]: /v3/repos/#get
[create repo]: /v3/repos/#create
diff --git a/content/guides/index.md b/content/guides/index.md
index 3ca3085f3b..4b2d2e5219 100644
--- a/content/guides/index.md
+++ b/content/guides/index.md
@@ -1,12 +1,12 @@
---
-title: Development Guides | GitHub API
+title: Development Guides
layout: guides
---
# Development Guides
This section of the documentation is intended to get you up-and-running with
-real-world GitHub API applications. We'll cover everything you need to know, from
+real-world {{ site.data.variables.product.product_name }} API applications. We'll cover everything you need to know, from
authentication, to manipulating results, to combining results with other services.
Every tutorial here will have a project, and every project will be
@@ -15,4 +15,4 @@ stored and documented in our public
Feel free to fork, clone, and improve these guides.
-
+
diff --git a/content/guides/managing-deploy-keys.md b/content/guides/managing-deploy-keys.md
new file mode 100644
index 0000000000..5c830b6b62
--- /dev/null
+++ b/content/guides/managing-deploy-keys.md
@@ -0,0 +1,127 @@
+---
+title: Managing deploy keys
+---
+
+# Managing Deploy Keys
+
+{:toc}
+
+There are four ways to manage SSH keys on your servers when automating deployment scripts:
+
+* SSH agent forwarding
+* HTTPS with OAuth tokens
+* Deploy keys
+* Machine users
+
+This guide will help you decide what strategy is best for you.
+
+## SSH agent forwarding
+
+In many cases, especially in the beginning of a project, SSH agent forwarding is the quickest and simplest method to use. Agent forwarding uses the same SSH keys that your local development computer uses.
+
+#### Pros
+
+* You do not have to generate or keep track of any new keys.
+* There is no key management; users have the same permissions on the server that they do locally.
+* No keys are stored on the server, so in case the server is compromised, you don't need to hunt down and remove the compromised keys.
+
+#### Cons
+
+* Users **must** SSH in to deploy; automated deploy processes can't be used.
+* SSH agent forwarding can be troublesome to run for Windows users.
+
+#### Setup
+
+1. Turn on agent forwarding locally. See [our guide on SSH agent forwarding][ssh-agent-forwarding] for more information.
+2. Set your deploy scripts to use agent forwarding. For example, on a bash script, enabling agent forwarding would look something like this: `ssh -A serverA 'bash -s' < deploy.sh`
+
+## HTTPS cloning with OAuth tokens
+
+If you don't want to use SSH keys, you can use [HTTPS with OAuth tokens][git-automation].
+
+#### Pros
+
+* Anyone with access to the server can deploy the repository.
+* Users don't have to change their local SSH settings.
+* Multiple tokens (one for each user) are not needed; one token per server is enough.
+* A token can be revoked at any time, turning it essentially into a one-use password.
+* Generating new tokens can be easily scripted using [the OAuth API](https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization)
+
+#### Cons
+
+* You must make sure that you configure your token with the correct access scopes.
+* Tokens are essentially passwords, and must be protected the same way.
+
+#### Setup
+
+See [our guide on Git automation with tokens][git-automation].
+
+## Deploy keys
+
+A deploy key is an SSH key that is stored on your server and grants access to a single {{ site.data.variables.product.product_name }} repository. This key is attached directly to the repository instead of to a personal user account.
+
+#### Pros
+
+* Anyone with access to the repository and server has the ability to deploy the project.
+* Users don't have to change their local SSH settings.
+* Deploy keys can read and write by default, but can be made read-only.
+
+#### Cons
+
+* Deploy keys only grant access to a single repository. More complex projects may have many repositories to pull to the same server.
+* Deploy keys are usually not protected by a passphrase, making the key easily accessible if the server is compromised.
+
+#### Setup
+
+1. [Run the `ssh-keygen` procedure][generating-ssh-keys] on your server.
+2. In the top right corner of any {{ site.data.variables.product.product_name }} page, click your profile photo.
+ 
+3. On your profile page, click the **Repositories** tab, then click the name of your repository.
+ 
+4. In your repository's right sidebar, click **Settings**.
+ 
+3. In the sidebar, click **Deploy Keys**.
+ 
+3. Click **Add deploy key**. Paste your public key in and submit.
+ 
+
+## Machine users
+
+If your server needs to access multiple repositories, you can choose to create a new {{ site.data.variables.product.product_name }} account and attach an SSH key that will be used exclusively for automation. Since this {{ site.data.variables.product.product_name }} account won't be used by a human, it's called a machine user. You can then [add the machine user as collaborator][collaborator] or [add the machine user to a team][team] with access to the repositories it needs to manipulate. **NOTE**: Adding a machine user as a collaborator always grants read/write access. Adding a machine user to a team grants the permissions of the team.
+
+{% if page.version == 'dotcom' %}
+
+{{#tip}}
+
+**Tip:** Our [terms of service][tos] state:
+
+> *Accounts registered by "bots" or other automated methods are not permitted.*
+
+This means that you cannot automate the creation of accounts. But if you want to create a single machine user for automating tasks such as deploy scripts in your project or organization, that is totally cool.
+
+{{/tip}}
+
+{% endif %}
+
+#### Pros
+
+* Anyone with access to the repository and server has the ability to deploy the project.
+* No (human) users need to change their local SSH settings.
+* Multiple keys are not needed; one per server is adequate.
+
+#### Cons
+
+* Only organizations have access to create teams; therefore only organizations can use them to restrict machine users to read-only access. Personal repositories always grant collaborators read/write access.
+* Machine user keys, like deploy keys, are usually not protected by a passphrase.
+
+#### Setup
+
+1. [Run the `ssh-keygen` procedure][generating-ssh-keys] on your server and attach the public key to the machine user account.
+2. Give that account access to the repositories it will need to access. You can do this by [adding the account as collaborator][collaborator] or [adding it to a team][team] in an organization.
+
+[ssh-agent-forwarding]: /guides/using-ssh-agent-forwarding/
+[generating-ssh-keys]: https://help.github.com/articles/generating-ssh-keys
+[tos]: https://help.github.com/articles/github-terms-of-service/
+[git-automation]: https://help.github.com/articles/git-automation-with-oauth-tokens
+[collaborator]: https://help.github.com/articles/how-do-i-add-a-collaborator
+[team]: https://help.github.com/articles/adding-organization-members-to-a-team
diff --git a/content/guides/rendering-data-as-graphs.md b/content/guides/rendering-data-as-graphs.md
index f7948cdd89..02d61e1fc9 100644
--- a/content/guides/rendering-data-as-graphs.md
+++ b/content/guides/rendering-data-as-graphs.md
@@ -1,16 +1,15 @@
---
-title: Rendering Data as Graphs | GitHub API
+title: Rendering Data as Graphs
---
# Rendering Data as Graphs
-* TOC
{:toc}
In this guide, we're going to use the API to fetch information about repositories
that we own, and the programming languages that make them up. Then, we'll
visualize that information in a couple of different ways using the [D3.js][D3.js] library. To
-interact with the GitHub API, we'll be using the excellent Ruby library, [Octokit][Octokit].
+interact with the {{ site.data.variables.product.product_name }} API, we'll be using the excellent Ruby library, [Octokit][Octokit].
If you haven't already, you should read the ["Basics of Authentication"][basics-of-authentication]
guide before starting this example. You can find the complete source code for this project in the [platform-samples][platform samples] repository.
@@ -19,60 +18,62 @@ Let's jump right in!
## Setting up an OAuth application
-First, [register a new application][new oauth application] on GitHub. Set the main and callback
+First, [register a new application][new oauth application] on {{ site.data.variables.product.product_name }}. Set the main and callback
URLs to `http://localhost:4567/`. As [before][basics-of-authentication], we're going to handle authentication for the API by
implementing a Rack middleware using [sinatra-auth-github][sinatra auth github]:
- #!ruby
- require 'sinatra/auth/github'
-
- module Example
- class MyGraphApp < Sinatra::Base
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- # if ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
- # CLIENT_ID = ENV['GITHUB_CLIENT_ID']
- # CLIENT_SECRET = ENV['GITHUB_CLIENT_SECRET']
- # end
-
- CLIENT_ID = ENV['GH_GRAPH_CLIENT_ID']
- CLIENT_SECRET = ENV['GH_GRAPH_SECRET_ID']
-
- enable :sessions
-
- set :github_options, {
- :scopes => "repo",
- :secret => CLIENT_SECRET,
- :client_id => CLIENT_ID,
- :callback_url => "/"
- }
-
- register Sinatra::Auth::Github
-
- get '/' do
- if !authenticated?
- authenticate!
- else
- access_token = github_user["token"]
- end
- end
+``` ruby
+require 'sinatra/auth/github'
+
+module Example
+ class MyGraphApp < Sinatra::Base
+ # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+ # Instead, set and test environment variables, like below
+ # if ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
+ # CLIENT_ID = ENV['GITHUB_CLIENT_ID']
+ # CLIENT_SECRET = ENV['GITHUB_CLIENT_SECRET']
+ # end
+
+ CLIENT_ID = ENV['GH_GRAPH_CLIENT_ID']
+ CLIENT_SECRET = ENV['GH_GRAPH_SECRET_ID']
+
+ enable :sessions
+
+ set :github_options, {
+ :scopes => "repo",
+ :secret => CLIENT_SECRET,
+ :client_id => CLIENT_ID,
+ :callback_url => "/"
+ }
+
+ register Sinatra::Auth::Github
+
+ get '/' do
+ if !authenticated?
+ authenticate!
+ else
+ access_token = github_user["token"]
end
end
+ end
+end
+```
Set up a similar _config.ru_ file as in the previous example:
- #!ruby
- ENV['RACK_ENV'] ||= 'development'
- require "rubygems"
- require "bundler/setup"
+``` ruby
+ENV['RACK_ENV'] ||= 'development'
+require "rubygems"
+require "bundler/setup"
- require File.expand_path(File.join(File.dirname(__FILE__), 'server'))
+require File.expand_path(File.join(File.dirname(__FILE__), 'server'))
- run Example::MyGraphApp
+run Example::MyGraphApp
+```
## Fetching repository information
-This time, in order to talk to the GitHub API, we're going to use the [Octokit
+This time, in order to talk to the {{ site.data.variables.product.product_name }} API, we're going to use the [Octokit
Ruby library][Octokit]. This is much easier than directly making a bunch of
REST calls. Plus, Octokit was developed by a GitHubber, and is actively maintained,
so you know it'll work.
@@ -80,43 +81,48 @@ so you know it'll work.
Authentication with the API via Octokit is easy. Just pass your login
and token to the `Octokit::Client` constructor:
- #!ruby
- if !authenticated?
- authenticate!
- else
- octokit_client = Octokit::Client.new(:login => github_user.login, :oauth_token => github_user.token)
- end
+``` ruby
+if !authenticated?
+ authenticate!
+else
+ octokit_client = Octokit::Client.new(:login => github_user.login, :oauth_token => github_user.token)
+end
+```
Let's do something interesting with the data about our repositories. We're going
to see the different programming languages they use, and count which ones are used
most often. To do that, we'll first need a list of our repositories from the API.
With Octokit, that looks like this:
- #!ruby
- repos = client.repositories
+``` ruby
+repos = client.repositories
+```
-Next, we'll iterate over each repository, and count the language that GitHub
+Next, we'll iterate over each repository, and count the language that {{ site.data.variables.product.product_name }}
associates with it:
- #!ruby
- language_obj = {}
- repos.each do |repo|
- # sometimes language can be nil
- if repo.language
- if !language_obj[repo.language]
- language_obj[repo.language] = 1
- else
- language_obj[repo.language] += 1
- end
- end
+``` ruby
+language_obj = {}
+repos.each do |repo|
+ # sometimes language can be nil
+ if repo.language
+ if !language_obj[repo.language]
+ language_obj[repo.language] = 1
+ else
+ language_obj[repo.language] += 1
end
+ end
+end
- languages.to_s
+languages.to_s
+```
When you restart your server, your web page should display something
that looks like this:
- {"JavaScript"=>13, "PHP"=>1, "Perl"=>1, "CoffeeScript"=>2, "Python"=>1, "Java"=>3, "Ruby"=>3, "Go"=>1, "C++"=>1}
+``` ruby
+{"JavaScript"=>13, "PHP"=>1, "Perl"=>1, "CoffeeScript"=>2, "Python"=>1, "Java"=>3, "Ruby"=>3, "Go"=>1, "C++"=>1}
+```
So far, so good, but not very human-friendly. A visualization
would be great in helping us understand how these language counts are distributed. Let's feed
@@ -131,13 +137,14 @@ check out ["D3 for Mortals"][D3 mortals].
D3 is a JavaScript library, and likes working with data as arrays. So, let's convert our Ruby hash into
a JSON array for use by JavaScript in the browser.
- #!ruby
- languages = []
- language_obj.each do |lang, count|
- languages.push :language => lang, :count => count
- end
+``` ruby
+languages = []
+language_obj.each do |lang, count|
+ languages.push :language => lang, :count => count
+end
- erb :lang_freq, :locals => { :languages => languages.to_json}
+erb :lang_freq, :locals => { :languages => languages.to_json}
+```
We're simply iterating over each key-value pair in our object and pushing them into
a new array. The reason we didn't do this earlier is because we didn't want to iterate
@@ -147,83 +154,84 @@ Now, _lang_freq.erb_ is going to need some JavaScript to support rendering a bar
For now, you can just use the code provided here, and refer to the resources linked above
if you want to learn more about how D3 works:
- #!html
-
-
-
-
-
-
-
-
-
Check this sweet data out:
-
-
-
-
-
+``` html
+
+
+
+
+
+
+
+
+
Check this sweet data out:
+
+
+
+
+
+```
Phew! Again, don't worry about what most of this code is doing. The relevant part
here is a line way at the top--`var data = <%= languages %>;`--which indicates
@@ -246,100 +254,104 @@ should be a great way to visualize the sizes of our coding languages used, rathe
than simply the count. We'll need to construct an array of objects that looks
something like this:
- #!javascript
- [ { "name": "language1", "size": 100},
- { "name": "language2", "size": 23}
- ...
- ]
+``` json
+[ { "name": "language1", "size": 100},
+ { "name": "language2", "size": 23}
+ ...
+]
+```
Since we already have a list of repositories above, let's inspect each one, and
call [the language listing API method][language API]:
- #!ruby
- repos.each do |repo|
- repo_name = repo.name
- repo_langs = octokit_client.languages("#{github_user.login}/#{repo_name}")
- end
+``` ruby
+repos.each do |repo|
+ repo_name = repo.name
+ repo_langs = octokit_client.languages("#{github_user.login}/#{repo_name}")
+end
+```
From there, we'll cumulatively add each language found to a "master list":
- #!ruby
- repo_langs.each do |lang, count|
- if !language_obj[lang]
- language_obj[lang] = count
- else
- language_obj[lang] += count
- end
- end
+``` ruby
+repo_langs.each do |lang, count|
+ if !language_obj[lang]
+ language_obj[lang] = count
+ else
+ language_obj[lang] += count
+ end
+end
+```
After that, we'll format the contents into a structure that D3 understands:
- #!ruby
- language_obj.each do |lang, count|
- language_byte_count.push :name => "#{lang} (#{count})", :count => count
- end
+``` ruby
+language_obj.each do |lang, count|
+ language_byte_count.push :name => "#{lang} (#{count})", :count => count
+end
- # some mandatory formatting for D3
- language_bytes = [ :name => "language_bytes", :elements => language_byte_count]
+# some mandatory formatting for D3
+language_bytes = [ :name => "language_bytes", :elements => language_byte_count]
+```
(For more information on D3 tree map magic, check out [this simple tutorial][language API].)
To wrap up, we pass this JSON information over to the same ERB template:
- #!ruby
- erb :lang_freq, :locals => { :languages => languages.to_json, :language_byte_count => language_bytes.to_json}
-
+``` ruby
+erb :lang_freq, :locals => { :languages => languages.to_json, :language_byte_count => language_bytes.to_json}
+```
Like before, here's a bunch of JavaScript that you can drop
directly into your template:
- #!html
-
-
+``` html
+
+
+```
Et voila! Beautiful rectangles containing your repo languages, with relative
proportions that are easy to see at a glance. You might need to
@@ -350,10 +362,10 @@ arguments to `drawTreemap` above, to get all the information to show up properly
[D3.js]: http://d3js.org/
[basics-of-authentication]: ../basics-of-authentication/
[sinatra auth github]: https://github.com/atmos/sinatra_auth_github
-[Octokit]: https://github.com/pengwynn/octokit
+[Octokit]: https://github.com/octokit/octokit.rb
[D3 mortals]: http://www.recursion.org/d3-for-mere-mortals/
[D3 treemap]: http://bl.ocks.org/mbostock/4063582
-[language API]: http://developer.github.com/v3/repos/#list-languages
+[language API]: https://developer.github.com/v3/repos/#list-languages
[simple tree map]: http://2kittymafiasoftware.blogspot.com/2011/09/simple-treemap-visualization-with-d3.html
[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/rendering-data-as-graphs
[new oauth application]: https://github.com/settings/applications/new
diff --git a/content/guides/traversing-with-pagination.md b/content/guides/traversing-with-pagination.md
index b82e765c24..ff4d11cf0b 100644
--- a/content/guides/traversing-with-pagination.md
+++ b/content/guides/traversing-with-pagination.md
@@ -1,38 +1,39 @@
---
-title: Traversing with Pagination | GitHub API
+title: Traversing with Pagination
---
# Traversing with Pagination
-* TOC
{:toc}
-The GitHub API provides a vast wealth of information for developers to consume.
+The {{ site.data.variables.product.product_name }} API provides a vast wealth of information for developers to consume.
Most of the time, you might even find that you're asking for _too much_ information,
and in order to keep our servers happy, the API will automatically [paginate the requested items][pagination].
-In this guide, we'll make some calls to the GitHub Search API, and iterate over
-the results using pagination. You can find the complete source code for this project
-in the [platform-samples][platform samples] repository.
+In this guide, we'll make some calls to the {{ site.data.variables.product.product_name }} Search API, and iterate over
+the results using pagination. You can find the complete source code for this project
+in the [platform-samples][platform samples] repository.
## Basics of Pagination
To start with, it's important to know a few facts about receiving paginated items:
1. Different API calls respond with different defaults. For example, a call to
-[list GitHub's public repositories](http://developer.github.com/v3/repos/#list-all-public-repositories)
+[list GitHub's public repositories](https://developer.github.com/v3/repos/#list-all-public-repositories)
provides paginated items in sets of 30, whereas a call to the GitHub Search API
provides items in sets of 100
2. You can specify how many items to receive (up to a maximum of 100); but,
-3. For technical reasons, not every endpoint behaves the same. For example,
-[events](http://developer.github.com/v3/activity/events/) won't let you set a maximum for items to receive.
+3. For technical reasons, not every endpoint behaves the same. For example,
+[events](https://developer.github.com/v3/activity/events/) won't let you set a maximum for items to receive.
Be sure to read the documentation on how to handle paginated results for specific endpoints.
Information about pagination is provided in [the Link header](http://tools.ietf.org/html/rfc5988)
of an API call. For example, let's make a curl request to the search API, to find
out how many times Mozilla projects use the phrase `addClass`:
- curl -I "https://api.github.com/search/code?q=addClass+user:mozilla"
+``` command-line
+$ curl -I "{{ site.data.variables.product.api_url_pre }}/search/code?q=addClass+user:mozilla"
+```
The `-I` parameter indicates that we only care about the headers, not the actual
content. In examining the result, you'll notice some information in the Link header
@@ -50,7 +51,7 @@ Nice!
Keep in mind that you should **always** rely on these link relations provided
to you. Don't try to guess or construct your own URL. Some API calls, like [listing
commits on a repository][listing commits], use pagination results that are based
-on SHA values, not numbers.
+on SHA values, not numbers.
### Navigating through the pages
@@ -59,7 +60,9 @@ through the pages to consume the results. You do this by passing in a `page`
parameter. By default, `page` always starts at `1`. Let's jump ahead to page 14
and see what happens:
- curl -I "https://api.github.com/search/code?q=addClass+user:mozilla&page=14"
+``` command-line
+$ curl -I "https://api.github.com/search/code?q=addClass+user:mozilla&page=14"
+```
Here's the link header once more:
@@ -79,7 +82,9 @@ between the first, previous, next, or last list of results in an API call.
By passing the `per_page` parameter, you can specify how many items you want
each page to return, up to 100 items. Let's try asking for 50 items about `addClass`:
- curl -I "https://api.github.com/search/code?q=addClass+user:mozilla&per_page=50"
+``` command-line
+$ curl -I "https://api.github.com/search/code?q=addClass+user:mozilla&per_page=50"
+```
Notice what it does to the header response:
@@ -99,20 +104,22 @@ just described above.
As always, first we'll require [GitHub's Octokit.rb][octokit.rb] Ruby library, and
pass in our [personal access token][personal token]:
- #!ruby
- require 'octokit'
+``` ruby
+require 'octokit'
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+```
-Next, we'll execute the search, using Octokit's `search_code` method. Unlike
+Next, we'll execute the search, using Octokit's `search_code` method. Unlike
using `curl`, we can also immediately retrieve the number of results, so let's
do that:
- #!ruby
- results = client.search_code('addClass user:mozilla')
- total_count = results.total_count
+``` ruby
+results = client.search_code('addClass user:mozilla')
+total_count = results.total_count
+```
Now, let's grab the number of the last page, similar to `page=34>; rel="last"`
information in the link header. Octokit.rb support pagination information through
@@ -126,123 +133,127 @@ on. These relations also contain information about the resulting URL, by calling
Knowing this, let's grab the page number of the last result, and present all
this information to the user:
- #!ruby
- last_response = client.last_response
- number_of_pages = last_response.rels[:last].href.match(/page=(\d+)$/)[1]
+``` ruby
+last_response = client.last_response
+number_of_pages = last_response.rels[:last].href.match(/page=(\d+).*$/)[1]
- puts "There are #{total_count} results, on #{number_of_pages} pages!"
+puts "There are #{total_count} results, on #{number_of_pages} pages!"
+```
Finally, let's iterate through the results. You could do this with a loop `for i in 1..number_of_pages.to_i`,
-but instead, let's follow the `rels[:next]` headers to retrieve information from
+but instead, let's follow the `rels[:next]` headers to retrieve information from
each page. For the sake of simplicity, let's just grab the file path of the first
result from each page. To do this, we'll need a loop; and at the end of every loop,
we'll retrieve the data set for the next page by following the `rels[:next]` information.
The loop will finish when there is no `rels[:next]` information to consume (in other
words, we are at `rels[:last]`). It might look something like this:
- #!ruby
- loop do
- puts last_response.data.items.first.path
- last_response = last_response.rels[:next].get
- sleep 4 # back off from the API rate limiting; don't do this in Real Life
- break if last_response.rels[:next].nil?
- end
+``` ruby
+puts last_response.data.items.first.path
+until last_response.rels[:next].nil?
+ last_response = last_response.rels[:next].get
+ puts last_response.data.items.first.path
+end
+```
Changing the number of items per page is extremely simple with Octokit.rb. Simply
pass a `per_page` options hash to the initial client construction. After that,
your code should remain intact:
- #!ruby
- require 'octokit'
+``` ruby
+require 'octokit'
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
- results = client.search_code('addClass user:mozilla', :per_page => 100)
- total_count = results.total_count
+results = client.search_code('addClass user:mozilla', :per_page => 100)
+total_count = results.total_count
- last_response = client.last_response
- number_of_pages = last_response.rels[:last].href.match(/page=(\d+)$/)[1]
+last_response = client.last_response
+number_of_pages = last_response.rels[:last].href.match(/page=(\d+).*$/)[1]
- puts last_response.rels[:last].href
- puts "There are #{total_count} results, on #{number_of_pages} pages!"
+puts last_response.rels[:last].href
+puts "There are #{total_count} results, on #{number_of_pages} pages!"
- puts "And here's the first path for every set"
+puts "And here's the first path for every set"
- loop do
- puts last_response.data.items.first.path
- last_response = last_response.rels[:next].get
- sleep 4 # back off from the API rate limiting; don't do this in Real Life
- break if last_response.rels[:next].nil?
- end
+puts last_response.data.items.first.path
+until last_response.rels[:next].nil?
+ last_response = last_response.rels[:next].get
+ puts last_response.data.items.first.path
+end
+```
## Constructing Pagination Links
-Normally, with pagination, your goal isn't to concatenate all of the possible
+Normally, with pagination, your goal isn't to concatenate all of the possible
results, but rather, to produce a set of navigation, like this:
-
+
Let's sketch out a micro-version of what that might entail.
-From the code above, we already know we can get the `number_of_pages` in the
+From the code above, we already know we can get the `number_of_pages` in the
paginated results from the first call:
- #!ruby
- require 'octokit'
+``` ruby
+require 'octokit'
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
- results = client.search_code('addClass user:mozilla')
- total_count = results.total_count
+results = client.search_code('addClass user:mozilla')
+total_count = results.total_count
- last_response = client.last_response
- number_of_pages = last_response.rels[:last].href.match(/page=(\d+)$/)[1]
-
- puts last_response.rels[:last].href
- puts "There are #{total_count} results, on #{number_of_pages} pages!"
+last_response = client.last_response
+number_of_pages = last_response.rels[:last].href.match(/page=(\d+).*$/)[1]
+puts last_response.rels[:last].href
+puts "There are #{total_count} results, on #{number_of_pages} pages!"
+```
From there, we can construct a beautiful ASCII representation of the number boxes:
-
- #!ruby
- numbers = ""
- for i in 1..number_of_pages.to_i
- numbers << "[#{i}] "
- end
- puts numbers
+``` ruby
+numbers = ""
+for i in 1..number_of_pages.to_i
+ numbers << "[#{i}] "
+end
+puts numbers
+```
Let's simulate a user clicking on one of these boxes, by constructing a random
number:
- #!ruby
- random_page = Random.new
- random_page = random_page.rand(1..number_of_pages.to_i)
+``` ruby
+random_page = Random.new
+random_page = random_page.rand(1..number_of_pages.to_i)
- puts "A User appeared, and clicked number #{random_page}!"
+puts "A User appeared, and clicked number #{random_page}!"
+```
Now that we have a page number, we can use Octokit to explicitly retrieve that
individual page, by passing the `:page` option:
- #!ruby
- clicked_results = client.search_code('addClass user:mozilla', :page => random_page)
+``` ruby
+clicked_results = client.search_code('addClass user:mozilla', :page => random_page)
+```
+
+If we wanted to get fancy, we could also grab the previous and next pages, in
+order to generate links for back (`<<`) and forward (`>>`) elements:
-If we wanted to get fancy, we could also grab the previous and next pages, in
-order to generate links for back (`<<`) and foward (`>>`) elements:
+``` ruby
+prev_page_href = client.last_response.rels[:prev] ? client.last_response.rels[:prev].href : "(none)"
+next_page_href = client.last_response.rels[:next] ? client.last_response.rels[:next].href : "(none)"
- #!ruby
- prev_page_href = client.last_response.rels[:prev] ? client.last_response.rels[:prev].href : "(none)"
- next_page_href = client.last_response.rels[:next] ? client.last_response.rels[:next].href : "(none)"
-
- puts "The prev page link is #{prev_page_href}"
- puts "The next page link is #{next_page_href}"
+puts "The prev page link is #{prev_page_href}"
+puts "The next page link is #{next_page_href}"
+```
[pagination]: /v3/#pagination
[platform samples]: https://github.com/github/platform-samples/tree/master/api/ruby/traversing-with-pagination
[octokit.rb]: https://github.com/octokit/octokit.rb
[personal token]: https://help.github.com/articles/creating-an-access-token-for-command-line-use
[hypermedia-relations]: https://github.com/octokit/octokit.rb#pagination
-[listing commits]: http://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
+[listing commits]: https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
diff --git a/content/guides/using-ssh-agent-forwarding.md b/content/guides/using-ssh-agent-forwarding.md
new file mode 100644
index 0000000000..6a19d0c804
--- /dev/null
+++ b/content/guides/using-ssh-agent-forwarding.md
@@ -0,0 +1,155 @@
+---
+title: Using SSH Agent Forwarding
+---
+
+# Using SSH agent forwarding
+
+{:toc}
+
+SSH agent forwarding can be used to make deploying to a server simple. It allows you to use your local SSH keys instead of leaving keys (without passphrases!) sitting on your server.
+
+If you've already set up an SSH key to interact with {{ site.data.variables.product.product_name }}, you're probably familiar with `ssh-agent`. It's a program that runs in the background and keeps your key loaded into memory, so that you don't need to enter your passphrase every time you need to use the key. The nifty thing is, you can choose to let servers access your local `ssh-agent` as if they were already running on the server. This is sort of like asking a friend to enter their password so that you can use their computer.
+
+Check out [Steve Friedl's Tech Tips guide][tech-tips] for a more detailed explanation of SSH agent forwarding.
+
+## Setting up SSH agent forwarding
+
+Ensure that your own SSH key is set up and working. You can use [our guide on generating SSH keys][generating-keys] if you've not done this yet.
+
+You can test that your local key works by entering `ssh -T git@github.com` in the terminal:
+
+``` command-line
+$ ssh -T git@github.com
+# Attempt to SSH in to github
+> Hi username! You've successfully authenticated, but GitHub does not provide
+> shell access.
+```
+
+We're off to a great start. Let's set up SSH to allow agent forwarding to your server.
+
+1. Using your favorite text editor, open up the file at `~/.ssh/config`. If this file doesn't exist, you can create it by entering `touch ~/.ssh/config` in the terminal.
+
+2. Enter the following text into the file, replacing `example.com` with your server's domain name or IP:
+
+ Host example.com
+ ForwardAgent yes
+
+{{#warning}}
+
+**Warning:** You may be tempted to use a wildcard like `Host *` to just apply this setting to all SSH connections. That's not really a good idea, as you'd be sharing your local SSH keys with *every* server you SSH into. They won't have direct access to the keys, but they will be able to use them *as you* while the connection is established. **You should only add servers you trust and that you intend to use with agent forwarding.**
+
+{{/warning}}
+
+## Testing SSH agent forwarding
+
+To test that agent forwarding is working with your server, you can SSH into your server and run `ssh -T git@github.com` once more. If all is well, you'll get back the same prompt as you did locally.
+
+If you're unsure if your local key is being used, you can also inspect the `SSH_AUTH_SOCK` variable on your server:
+
+``` command-line
+$ echo "$SSH_AUTH_SOCK"
+# Print out the SSH_AUTH_SOCK variable
+> /tmp/ssh-4hNGMk8AZX/agent.79453
+```
+
+If the variable is not set, it means that agent forwarding is not working:
+
+``` command-line
+$ echo "$SSH_AUTH_SOCK"
+# Print out the SSH_AUTH_SOCK variable
+> [No output]
+$ ssh -T git@github.com
+# Try to SSH to github
+> Permission denied (publickey).
+```
+
+## Troubleshooting SSH agent forwarding
+
+Here are some things to look out for when troubleshooting SSH agent forwarding.
+
+### You must be using an SSH URL to check out code
+
+SSH forwarding only works with SSH URLs, not HTTP(s) URLs. Check the *.git/config* file on your server and ensure the URL is an SSH-style URL like below:
+
+``` command-line
+[remote "origin"]
+ url = git@github.com:yourAccount/yourProject.git
+ fetch = +refs/heads/*:refs/remotes/origin/*
+```
+
+### Your SSH keys must work locally
+
+Before you can make your keys work through agent forwarding, they must work locally first. [Our guide on generating SSH keys][generating-keys] can help you set up your SSH keys locally.
+
+### Your system must allow SSH agent forwarding
+
+Sometimes, system configurations disallow SSH agent forwarding. You can check if a system configuration file is being used by entering the following command in the terminal:
+
+``` command-line
+$ ssh -v example.com
+# Connect to example.com with verbose debug output
+> OpenSSH_5.6p1, OpenSSL 0.9.8r 8 Feb 2011
+> debug1: Reading configuration data /Users/you/.ssh/config
+> debug1: Applying options for example.com
+> debug1: Reading configuration data /etc/ssh_config
+> debug1: Applying options for *
+$ exit
+# Returns to your local command prompt
+```
+
+In the example above, the file *~/.ssh/config* is loaded first, then */etc/ssh_config* is read. We can inspect that file to see if it's overriding our options by running the following commands:
+
+``` command-line
+$ cat /etc/ssh_config
+# Print out the /etc/ssh_config file
+> Host *
+> SendEnv LANG LC_*
+> ForwardAgent no
+```
+
+In this example, our */etc/ssh_config* file specifically says `ForwardAgent no`, which is a way to block agent forwarding. Deleting this line from the file should get agent forwarding working once more.
+
+### Your server must allow SSH agent forwarding on inbound connections
+
+Agent forwarding may also be blocked on your server. You can check that agent forwarding is permitted by SSHing into the server and running `sshd_config`. The output from this command should indicate that `AllowAgentForwarding` is set.
+
+### Your local `ssh-agent` must be running
+
+On most computers, the operating system automatically launches `ssh-agent` for you. On Windows, however, you need to do this manually. We have [a guide on how to start `ssh-agent` whenever you open Git Bash][autolaunch-ssh-agent].
+
+To verify that `ssh-agent` is running on your computer, type the following command in the terminal:
+
+``` command-line
+$ echo "$SSH_AUTH_SOCK"
+# Print out the SSH_AUTH_SOCK variable
+> /tmp/launch-kNSlgU/Listeners
+```
+
+### Your key must be available to `ssh-agent`
+
+You can check that your key is visible to `ssh-agent` by running the following command:
+
+``` command-line
+ssh-add -L
+```
+
+If the command says that no identity is available, you'll need to add your key:
+
+``` command-line
+$ ssh-add yourkey
+```
+
+{{#tip}}
+
+On Mac OS X, `ssh-agent` will "forget" this key, once it gets restarted during reboots. But you can import your SSH keys into Keychain using this command:
+
+``` command-line
+$ /usr/bin/ssh-add -K yourkey
+```
+
+{{/tip}}
+
+[tech-tips]: http://www.unixwiz.net/techtips/ssh-agent-forwarding.html
+[generating-keys]: https://help.github.com/articles/generating-ssh-keys
+[ssh-passphrases]: https://help.github.com/ssh-key-passphrases/
+[autolaunch-ssh-agent]: https://help.github.com/articles/working-with-ssh-key-passphrases#auto-launching-ssh-agent-on-msysgit
diff --git a/content/guides/working-with-comments.md b/content/guides/working-with-comments.md
index 10ebe0e475..13a4266023 100644
--- a/content/guides/working-with-comments.md
+++ b/content/guides/working-with-comments.md
@@ -1,17 +1,16 @@
---
-title: Working with Comments | GitHub API
+title: Working with Comments
---
# Working with Comments
-* TOC
{:toc}
-For any Pull Request, GitHub provides three kinds of comment views:
+For any Pull Request, {{ site.data.variables.product.product_name }} provides three kinds of comment views:
[comments on the Pull Request][PR comment] as a whole, [comments on a specific line][PR line comment] within the Pull Request,
and [comments on a specific commit][commit comment] within the Pull Request.
-Each of these types of comments goes through a different portion of the GitHub API.
+Each of these types of comments goes through a different portion of the {{ site.data.variables.product.product_name }} API.
In this guide, we'll explore how you can access and manipulate each one. For every
example, we'll be using [this sample Pull Request made][sample PR] on the "octocat"
repository. As always, samples can be found in [our platform-samples repository][platform-samples].
@@ -29,20 +28,21 @@ We'll demonstrate fetching Pull Request comments by creating a Ruby script using
The following code should help you get started accessing comments from a Pull Request
using Octokit.rb:
- #!ruby
- require 'octokit'
+``` ruby
+require 'octokit'
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
- client.issue_comments("octocat/Spoon-Knife", 1176).each do |comment|
- username = comment[:user][:login]
- post_date = comment[:created_at]
- content = comment[:body]
+client.issue_comments("octocat/Spoon-Knife", 1176).each do |comment|
+ username = comment[:user][:login]
+ post_date = comment[:created_at]
+ content = comment[:body]
- puts "#{username} made a comment on #{post_date}. It says:\n'#{content}'\n"
- end
+ puts "#{username} made a comment on #{post_date}. It says:\n'#{content}'\n"
+end
+```
Here, we're specifically calling out to the Issues API to get the comments (`issue_comments`),
providing both the repository's name (`octocat/Spoon-Knife`), and the Pull Request ID
@@ -57,22 +57,23 @@ within a changed file. The endpoint URL for this discussion comes from [the Pull
The following code fetches all the Pull Request comments made on files, given a single Pull Request number:
- #!ruby
- require 'octokit'
+``` ruby
+require 'octokit'
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
- client.pull_request_comments("octocat/Spoon-Knife", 1176).each do |comment|
- username = comment[:user][:login]
- post_date = comment[:created_at]
- content = comment[:body]
- path = comment[:path]
- position = comment[:position]
+client.pull_request_comments("octocat/Spoon-Knife", 1176).each do |comment|
+ username = comment[:user][:login]
+ post_date = comment[:created_at]
+ content = comment[:body]
+ path = comment[:path]
+ position = comment[:position]
- puts "#{username} made a comment on #{post_date} for the file called #{path}, on line #{position}. It says:\n'#{content}'\n"
- end
+ puts "#{username} made a comment on #{post_date} for the file called #{path}, on line #{position}. It says:\n'#{content}'\n"
+end
+```
You'll notice that it's incredibly similar to the example above. The difference
between this view and the Pull Request comment is the focus of the conversation.
@@ -88,20 +89,21 @@ they make use of [the commit comment API][commit comment API].
To retrieve the comments on a commit, you'll want to use the SHA1 of the commit.
In other words, you won't use any identifier related to the Pull Request. Here's an example:
- #!ruby
- require 'octokit'
+``` ruby
+require 'octokit'
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
+# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
+# Instead, set and test environment variables, like below
+client = Octokit::Client.new :access_token => ENV['MY_PERSONAL_TOKEN']
- client.commit_comments("octocat/Spoon-Knife", "cbc28e7c8caee26febc8c013b0adfb97a4edd96e").each do |comment|
- username = comment[:user][:login]
- post_date = comment[:created_at]
- content = comment[:body]
+client.commit_comments("octocat/Spoon-Knife", "cbc28e7c8caee26febc8c013b0adfb97a4edd96e").each do |comment|
+ username = comment[:user][:login]
+ post_date = comment[:created_at]
+ content = comment[:body]
- puts "#{username} made a comment on #{post_date}. It says:\n'#{content}'\n"
- end
+ puts "#{username} made a comment on #{post_date}. It says:\n'#{content}'\n"
+end
+```
Note that this API call will retrieve single line comments, as well as comments made
on the entire commit.
@@ -111,8 +113,8 @@ on the entire commit.
[commit comment]: https://github.com/octocat/Spoon-Knife/commit/cbc28e7c8caee26febc8c013b0adfb97a4edd96e#commitcomment-4049848
[sample PR]: https://github.com/octocat/Spoon-Knife/pull/1176
[platform-samples]: https://github.com/github/platform-samples/tree/master/api/ruby/working-with-comments
-[issues]: http://developer.github.com/v3/issues/comments/
+[issues]: https://developer.github.com/v3/issues/comments/
[personal token]: https://help.github.com/articles/creating-an-access-token-for-command-line-use
[octokit.rb]: https://github.com/octokit/octokit.rb
-[PR Review API]: http://developer.github.com/v3/pulls/comments/
-[commit comment API]: http://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
+[PR Review API]: https://developer.github.com/v3/pulls/comments/
+[commit comment API]: https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
diff --git a/content/index.md b/content/index.md
index 2024c05223..1cf54f6892 100644
--- a/content/index.md
+++ b/content/index.md
@@ -1,6 +1,7 @@
---
title: GitHub Developer
layout: overview
+hide_from_search: true
---
@@ -10,7 +11,7 @@ layout: overview
Get started with one of our guides, or jump straight into the API documentation.
diff --git a/content/integrations-directory/getting-listed.md b/content/integrations-directory/getting-listed.md
new file mode 100644
index 0000000000..7a96f11057
--- /dev/null
+++ b/content/integrations-directory/getting-listed.md
@@ -0,0 +1,86 @@
+---
+title: Getting listed in the Integrations Directory
+---
+
+# Getting your integration listed
+
+{:toc}
+
+## Listing requirements
+
+### Provide the right contacts
+
+We want to be sure GitHub can contact your team, if needed. Specifically, we're asking for:
+
+* A technical support contact
+* A security contact
+* An escalation contact
+
+All three are for GitHub-use only. If there's an urgent issue that needs your attention, we'll contact your escalation contact and expect a response within one business day. A delayed response from your escalation contact may result in temporary or permanent de-listing of your integration from the directory.
+
+### Provide standard links
+
+We'd like to have a minimum set of links to include in every integration listing, so that our users have all the information they need. These are:
+
+- Pricing - If your integration costs money or has differed priced tiers of service, please include this URL.
+- Documentation - Please provide a URL with more information on how to use your integration.
+- Terms of service - Please provide the Terms of Service URL for users using your integration.
+- Privacy Policy - If different than Terms of Service, please include the URL here.
+- Support - Please provide a URL or email address for users to contact you directly.
+- Status - You should provide us a URL that will be updated when your application is down or experiencing problems. This could be a status site, a blog, a Twitter account, or more. This URL should be publicly accessible.
+- Installation - Provide the URL for direct installation for users. Note the OAuth requirement below.
+
+### Provide updates to your listing
+
+We want GitHub users to have consistent messaging within the Integrations Directory and your
+marketing site. As your product changes, keep your Integration Directory listing up to date. We ask that you refresh the information at least once a year. Please send updates to [partnerships@github.com](mailto:partnerships@github.com).
+
+### Provide categories for your listing
+
+Help GitHub users find your integration faster with the appropriate categories. Please send us your suggested categories for the listing from those available in the [Integrations Directory](https://github.com/integrations). If you don't see a category that fits quite right, just let us know. We reserve the right to change categories associated with the listing. If we do so, we'll do our best to keep you informed.
+
+If your integration supports both GitHub.com and GitHub Enterprise, please let us know.
+
+## Technical requirements
+
+### Use TLS
+
+Anytime you display GitHub data in your integration, use TLS. If you also use [webhooks](https://developer.github.com/webhooks/) to receive updated data from GitHub, use SSL/TLS there too.
+
+### Delete GitHub data once you lose access to the information
+
+Once you realize you've lost access to a user, organization, repository, or its related objects,
+delete that information in your system within 60 days.
+
+## Choose your type of listing
+
+We offer two types of listings: OAuth installation listings and "learn more" listings.
+
+### OAuth installation listing
+
+{{#tip}}
+
+This is our preferred type of listing wherever possible.
+
+{{/tip}}
+
+The OAuth installation listings are used so customers can immediately install your integration directly
+within GitHub's UI. To use this type of listing, provide a URL that will immediately redirect to
+GitHub's OAuth authorization flow.
+
+We are happy to help you identify if your integration can already support this. If you'd like a direct installation from the Integrations Directory, your provided installation URL should always forward the user immediately to an OAuth authorization screen. You should never add interstitial pages within that flow.
+
+### "Learn more" listing
+
+The "learn more" listing is used when a user cannot use GitHub OAuth to sign up for an account within
+your integration. You will provide a URL that will link a "learn more" button within your
+listing to your website. This type of listing is *only used when OAuth is not available before
+account creation*.
+
+## Send us your information
+
+In addition to this checklist, please follow the [Marketing Guidelines](/integrations-directory/marketing-guidelines/) as well. The best format for delivery is Markdown (.md) or plain text (.txt).
+
+Please attach images at the proper resolution. We aren't able to extract photos from PDFs or Word docs.
+
+Once you're ready, just send the materials over email to [partnerships@github.com](mailto:partnerships@github.com). Thanks! We're looking forward to reviewing your listing.
diff --git a/content/integrations-directory/index.md b/content/integrations-directory/index.md
new file mode 100644
index 0000000000..04385850e7
--- /dev/null
+++ b/content/integrations-directory/index.md
@@ -0,0 +1,10 @@
+---
+title: Integrations Directory
+layout: /integrations-directory.*
+---
+
+# Overview
+
+As one of our integrators, we're excited to tell the world about your GitHub integration at [https://github.com/integrations](https://github.com/integrations). To ensure the GitHub community has the best experience finding and using your integrations, we've outlined a [short list of requirements](/integrations-directory/getting-listed/) to follow.
+
+We're happy to chat about these if you have any questions. Feel free to reach out to [partnerships@github.com](mailto:partnerships@github.com) for additional detail.
diff --git a/content/integrations-directory/marketing-guidelines.md b/content/integrations-directory/marketing-guidelines.md
new file mode 100644
index 0000000000..cc713af89b
--- /dev/null
+++ b/content/integrations-directory/marketing-guidelines.md
@@ -0,0 +1,74 @@
+---
+title: Integrations Directory marketing guidelines
+---
+
+# Marketing guidelines
+
+{:toc}
+
+This document will help you write compelling and well-structured marketing materials to help GitHub users understand the value of your integration. The sections below outline the document structure for integration pages.
+
+## One line blurb
+
+This is a short sentence (70 characters max), that'll show up right below your logo. It can be used for a tagline or quick summary of the integration.
+
+## Description
+
+Write a single paragraph that describes your integration clearly and speaks directly to the audience (think “you” and “your” over “we” and “our”). Answer the following questions in your description:
+
+- What does it do?
+- How does it integrate with GitHub?
+- How does it empower developers?
+
+Keep this section short and sweet.
+
+**Example**
+
+> Sample CI helps you deploy your code with confidence by continuously running your test suite. Avoid bugs and avert deployment disasters by catching bugs before they reach your users. Sample CI can update the build status on your pull requests as they progress and can deploy successful builds to production automatically.
+
+## Images
+
+Images are optional. Well curated images will help people get a sense for how your integration works with GitHub. Use multiple images as an opportunity to tell a story about your integration's workflow.
+
+### Image guidelines
+- Images should show your product in action
+- When possible, show how your product integrates with GitHub
+- Use no more than four images
+- Images must be 1290x728 pixels (will appear as 645x364 pixels)
+
+## Features
+
+List some features to give people a better sense of what your integration offers. An ideal number is between three and six—pick the great ones.
+
+### Feature guidelines
+- Each feature should have a heading.
+- Does the feature have a name? What is it?
+- What does the feature do?
+- How does it help people build better software?
+- Does it interact with any external services (e.g., can deploy to Heroku, Engine Yard Cloud, etc.)?
+- Does your feature require any setup?
+
+**Example**
+
+> **Deploy anywhere, with confidence**
+
+> Deploying to production after a successful build is as easy as setting up a bit of configuration, and we’ll deploy your code to Heroku, Engine Yard Cloud, Nodejitsu, cloudControl, OpenShift, CloudFoundry, AppFog, and Amazon OpsWorks.
+
+> Using a custom deployment? Customize the build to deploy to your servers!
+
+## General tips
+- Do not use `H1` level headings.
+- Use `H3` for section headings, `H4` for subsections.
+- Avoid italics. Use bold for emphasis instead.
+- Use sentence case for titles.
+- Do not write in all caps to provide emphasis.
+- Write in [GitHub Flavored markdown](https://help.github.com/articles/github-flavored-markdown/).
+
+## Logo
+- Provide your integration logo as a 128x128 pixel PNG.
+- Negative space must be transparent.
+- Do not stretch or squish your logo to fill the space.
+- You'll need to attach this logo to your GitHub Application, before the listing is published.
+
+## Samples
+Feel free to look at existing listings in the Integrations Directory, such as [Gitter](https://github.com/integrations/gitter) or [ZenHub](https://github.com/integrations/zenhub).
diff --git a/content/libraries.md b/content/libraries.md
index 2cef000824..2958416746 100644
--- a/content/libraries.md
+++ b/content/libraries.md
@@ -1,5 +1,5 @@
---
-title: Libraries | GitHub API
+title: Libraries
layout: libraries
---
@@ -12,11 +12,17 @@ many flavors
Post a video or a blog on your website about your integration
-
+
Ready to join the GitHub Developer Program?
Membership is open to individual developers and companies who have:
diff --git a/content/search/search-index.json b/content/search/search-index.json
new file mode 100644
index 0000000000..708851ff81
--- /dev/null
+++ b/content/search/search-index.json
@@ -0,0 +1,26 @@
+<%
+ #build the JSON tree
+ if @config[:audience]
+ @preface = "/enterprise/#{@config[:audience]}"
+ end
+ @output = []
+ @items.select { |item| !item.attributes[:hide_from_search] }.each do |item|
+ next if item[:filename].nil? || !item[:filename].end_with?('.md')
+ @path = item[:filename].split('/')[1..-1].join('/')[0..-4]
+ @path.chomp!('/index') if @path.end_with?('/index')
+
+ @output.push({
+ :title => "#{clean_for_json(item[:title])}",
+ :url => "#{@preface}/#{@path}/",
+ :body => "#{clean_for_json(item.compiled_content)}"
+ })
+ end
+%>
+<%=
+ #output the generated tree
+ if ENV['RACK_ENV'] == "production"
+ JSON.generate(@output.sort{|a, b| a[:title] <=> b[:title]})
+ else
+ JSON.pretty_generate(@output.sort{|a, b| a[:title] <=> b[:title]})
+ end
+%>
diff --git a/content/v3.md b/content/v3.md
index d8563b3d52..a387737d67 100644
--- a/content/v3.md
+++ b/content/v3.md
@@ -4,48 +4,43 @@ title: GitHub API v3
# Overview
-This describes the resources that make up the official GitHub API v3. If you have any problems or requests please contact
+This describes the resources that make up the official {{ site.data.variables.product.product_name }} API v3. If you have any problems or requests please contact
[support][].
-* TOC
{:toc}
## Current Version
-There are [two versions](/v3/versions) of the GitHub API: **beta** and **v3**. By default, all requests receive the beta version:
+By default, all requests receive the **v3** [version](/v3/versions) of the API.
+We encourage you to [explicitly request this version via the `Accept` header](/v3/media/#request-specific-version).
- Accept: application/vnd.github.beta+json
-
-Soon, v3 will become the default version. Check out the [blog post](/changes/2014-01-07-upcoming-change-to-default-media-type/) for details.
-
-We encourage you to [request a specific version via the `Accept` header](/v3/media/#beta-v3-and-the-future).
+ Accept: application/vnd.github.v3+json
## Schema
-All API access is over HTTPS, and accessed from the `api.github.com`
-domain (or through `yourdomain.com/api/v3/` for enterprise). All data is
+All API access is over HTTPS, and accessed from the `{{ site.data.variables.product.api_url_code }}`. All data is
sent and received as JSON.
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/users/octocat/orgs
+
+> HTTP/1.1 200 OK
+> Server: nginx
+> Date: Fri, 12 Oct 2012 23:33:14 GMT
+> Content-Type: application/json; charset=utf-8
+> Connection: keep-alive
+> Status: 200 OK
+> ETag: "a00049ba79152d03380c34652f2cb612"
+> X-GitHub-Media-Type: github.v3
+{% if page.version == 'dotcom' %}
+> X-RateLimit-Limit: 5000
+> X-RateLimit-Remaining: 4987
+> X-RateLimit-Reset: 1350085394
+{% endif %}
+> Content-Length: 5
+> Cache-Control: max-age=0, private, must-revalidate
+> X-Content-Type-Options: nosniff
+```
Blank fields are included as `null` instead of being omitted.
@@ -89,22 +84,42 @@ Many API methods take optional parameters. For GET requests, any parameters not
specified as a segment in the path can be passed as an HTTP query string
parameter:
-
+``` command-line
+$ curl -i "{{ site.data.variables.product.api_url_pre }}/repos/vmg/redcarpet/issues?state=closed"
+```
-In this example, the 'mojombo' and 'jekyll' values are provided for the `:owner`
+In this example, the 'vmg' and 'redcarpet' values are provided for the `:owner`
and `:repo` parameters in the path while `:state` is passed in the query
string.
For POST, PATCH, PUT, and DELETE requests, parameters not included in the URL should be encoded as JSON
-with a Content-Type of 'application/x-www-form-urlencoded':
+with a Content-Type of 'application/json':
+
+``` command-line
+$ curl -i -u username -d '{"scopes":["public_repo"]}' {{ site.data.variables.product.api_url_pre }}/authorizations
+```
+
+## Root Endpoint
+
+You can issue a `GET` request to the root endpoint to get all the endpoint categories that the API supports:
+
+``` command-line
+$ curl {{ site.data.variables.product.api_url_pre }}
+```
+
+{% if page.version != 'dotcom' %}
-
+{{#tip}}
+**Tip:** For GitHub Enterprise, [as with all other endpoints](https://developer.github.com/v3/enterprise/#endpoint-urls), you'll need to pass in your GitHub Enterprise endpoint as the hostname, *as well as your username and password*:
+``` command-line
+$ curl https://hostname/api/v3/ -u username:password
+```
+
+{{/tip}}
+
+{% endif %}
## Client Errors
@@ -124,7 +139,7 @@ receive request bodies:
HTTP/1.1 400 Bad Request
Content-Length: 40
- {"message":"Body should be a JSON Hash"}
+ {"message":"Body should be a JSON object"}
3. Sending invalid fields will result in a `422 Unprocessable Entity`
response.
@@ -156,7 +171,7 @@ Error Name | Description
`invalid` | This means the formatting of a field is invalid. The documentation for that resource should be able to give you more specific information.
`already_exists` | This means another resource has the same value as this field. This can happen in resources that must have some unique key (such as Label names).
-If resources have custom validation errors, they will be documented with the resource.
+Resources may also send custom validation errors (where `code` is `custom`). Custom errors will always have a `message` field describing the error, and most errors will also include a `documentation_url` field pointing to some content that might help you resolve the error.
## HTTP Redirects
@@ -182,35 +197,35 @@ Verb | Description
-----|-----------
`HEAD` | Can be issued against any resource to get just the HTTP header info.
`GET` | Used for retrieving resources.
-`POST` | Used for creating resources, or performing custom actions (such as merging a pull request).
+`POST` | Used for creating resources.
`PATCH` | Used for updating resources with partial JSON data. For instance, an Issue resource has `title` and `body` attributes. A PATCH request may accept one or more of the attributes to update the resource. PATCH is a relatively new and uncommon HTTP verb, so resource endpoints also accept `POST` requests.
`PUT` | Used for replacing resources or collections. For `PUT` requests with no `body` attribute, be sure to set the `Content-Length` header to zero.
`DELETE` |Used for deleting resources.
## Authentication
-There are three ways to authenticate through GitHub API v3. Requests that
+There are three ways to authenticate through {{ site.data.variables.product.product_name }} API v3. Requests that
require authentication will return `404 Not Found`, instead of
`403 Forbidden`, in some places. This is to prevent the accidental leakage
of private repositories to unauthorized users.
### Basic Authentication
-
-$ curl -u "username" https://api.github.com
-
+``` command-line
+$ curl -u "username" {{ site.data.variables.product.api_url_pre }}
+```
### OAuth2 Token (sent in a header)
-
+``` command-line
+$ curl {{ site.data.variables.product.api_url_pre }}/?access_token=OAUTH-TOKEN
+```
Read [more about OAuth2](/v3/oauth/). Note that OAuth2 tokens can be [acquired
programmatically](/v3/oauth_authorizations/#create-a-new-authorization), for applications that
@@ -218,43 +233,46 @@ are not websites.
### OAuth2 Key/Secret
-
+``` command-line
+$ curl '{{ site.data.variables.product.api_url_pre }}/users/whatever?client_id=xxxx&client_secret=yyyy'
+```
This should only be used in server to server scenarios. Don't leak your
-OAuth application's client secret to your users. Read [more about
-unauthenticated rate limiting](#unauthenticated-rate-limited-requests).
+OAuth application's client secret to your users.
+
+{% if page.version == 'dotcom' %}
+
+Read [more about unauthenticated rate limiting](#increasing-the-unauthenticated-rate-limit-for-oauth-applications).
+
+{% endif %}
### Failed login limit
Authenticating with invalid credentials will return `401 Unauthorized`:
-
+> {
+> "message": "Bad credentials",
+> "documentation_url": "https://developer.github.com/v3"
+> }
+```
After detecting several requests with invalid credentials within a short period,
the API will temporarily reject all authentication attempts for that user
(including ones with valid credentials) with `403 Forbidden`:
-
+> {
+> "message": "Maximum number of login attempts exceeded. Please try again later.",
+> "documentation_url": "https://developer.github.com/v3"
+> }
+```
## Hypermedia
@@ -286,11 +304,11 @@ Requests that return multiple items will be paginated to 30 items by
default. You can specify further pages with the `?page` parameter. For some
resources, you can also set a custom page size up to 100 with the `?per_page` parameter.
Note that for technical reasons not all endpoints respect the `?per_page` parameter,
-see [events](http://developer.github.com/v3/activity/events/) for example.
+see [events](https://developer.github.com/v3/activity/events/) for example.
-
+``` command-line
+$ curl '{{ site.data.variables.product.api_url_pre }}/user/repos?page=2&per_page=100'
+```
Note that page numbering is 1-based and that omitting the `?page`
parameter will return the first page.
@@ -311,35 +329,39 @@ SHA1 and not on page number.
_Linebreak is included for readability._
+This `Link` response header contains one or more [Hypermedia](/v3/#hypermedia) link relations, some of which may require expansion as [URI templates](http://tools.ietf.org/html/rfc6570).
+
The possible `rel` values are:
Name | Description
-----------|-----------|
-`next` |Shows the URL of the immediate next page of results.
-`last` |Shows the URL of the last page of results.
-`first` |Shows the URL of the first page of results.
-`prev` |Shows the URL of the immediate previous page of results.
+`next` |The link relation for the immediate next page of results.
+`last` |The link relation for the last page of results.
+`first` |The link relation for the first page of results.
+`prev` |The link relation for the immediate previous page of results.
+
+{% if page.version == 'dotcom' %}
## Rate Limiting
For requests using Basic Authentication or OAuth, you can make up to 5,000
requests per hour. For unauthenticated requests, the rate limit allows you to
-make up to 60 requests per hour. (The Search API has [custom rate limit
-rules](/v3/search/#rate-limit).)
+make up to 60 requests per hour. Unauthenticated requests are associated with your IP address,
+and not the user making requests. Note that [the Search API has custom rate limit
+rules](/v3/search/#rate-limit).
You can check the returned HTTP headers of any API request to see your current
rate limit status:
-
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/users/whatever
+> HTTP/1.1 200 OK
+> Date: Mon, 01 Jul 2013 17:27:06 GMT
+> Status: 200 OK
+> X-RateLimit-Limit: 60
+> X-RateLimit-Remaining: 56
+> X-RateLimit-Reset: 1372700873
+```
The headers tell you everything you need to know about your current rate limit status:
@@ -351,46 +373,44 @@ Header Name | Description
If you need the time in a different format, any modern programming language can get the job done. For example, if you open up the console on your web browser, you can easily get the reset time as a JavaScript Date object.
-
+> {
+> "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
+> "documentation_url": "https://developer.github.com/v3/#rate-limiting"
+> }
+```
You can also [check your rate limit status](/v3/rate_limit) without incurring an
API hit.
-### Unauthenticated rate limited requests
-
-If you need to make unauthenticated calls but need to use a higher rate limit
-associated with your OAuth application, you can send over your client ID and
-secret in the query string.
+### Increasing the unauthenticated rate limit for OAuth applications
-
-$ curl -i 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy'
+If your OAuth application needs to make unauthenticated calls with a higher rate limit, you can pass your app's client ID and secret as part of the query string.
-HTTP/1.1 200 OK
-Date: Mon, 01 Jul 2013 17:27:06 GMT
-Status: 200 OK
-X-RateLimit-Limit: 5000
-X-RateLimit-Remaining: 4966
-X-RateLimit-Reset: 1372700873
-
+``` command-line
+$ curl -i '{{ site.data.variables.product.api_url_pre }}/users/whatever?client_id=xxxx&client_secret=yyyy'
+> HTTP/1.1 200 OK
+> Date: Mon, 01 Jul 2013 17:27:06 GMT
+> Status: 200 OK
+> X-RateLimit-Limit: 5000
+> X-RateLimit-Remaining: 4966
+> X-RateLimit-Reset: 1372700873
+```
This method should only be used for server-to-server calls. You should never
share your client secret with anyone or include it in client-side browser code.
@@ -405,133 +425,179 @@ If you're using conditional requests and still exceeding your rate
limit, please [contact us][support] to request a
higher rate limit for your OAuth application.
+### Abuse Rate Limits
+
+To protect the quality of service from GitHub, additional rate limits may apply to some actions.
+For example, rapidly creating content, polling aggressively instead of using webhooks,
+making API calls with a high concurrency, or repeatedly requesting data that is computationally expensive
+may result in abuse rate limiting.
+
+It is not intended for this rate limit to interfere with any legitimate use of
+the API. Your normal [rate limits](/v3/#rate-limiting) should be the only
+limit you target. Please [contact support][abuse-support] if your use is affected by
+this rate limit. To ensure you're acting as a good API citizen, check out our
+[Best Practices guidelines](/guides/best-practices-for-integrators/).
+
+If your application triggers this rate limit, you'll receive an informative
+response:
+
+``` command-line
+> HTTP/1.1 403 Forbidden
+> Content-Type: application/json; charset=utf-8
+> Connection: close
+
+> {
+> "message": "You have triggered an abuse detection mechanism and have been temporarily blocked from content creation. Please retry your request again later.",
+> "documentation_url": "https://developer.github.com/v3#abuse-rate-limits"
+> }
+```
+
+{% endif %}
+
## User Agent Required
All API requests MUST include a valid `User-Agent` header. Requests with no `User-Agent`
-header will be rejected. We request that you use your GitHub username, or the name of your
+header will be rejected. We request that you use your {{ site.data.variables.product.product_name }} username, or the name of your
application, for the `User-Agent` header value. This allows us to contact you if there are problems.
Here's an example:
-
+```
If you provide an invalid `User-Agent` header, you will receive a `403 Forbidden` response:
-
-$ curl -iH 'User-Agent: ' https://api.github.com/meta
-HTTP/1.0 403 Forbidden
-Connection: close
-Content-Type: text/html
+``` command-line
+$ curl -iH 'User-Agent: ' {{ site.data.variables.product.api_url_pre }}/meta
+> HTTP/1.0 403 Forbidden
+> Connection: close
+> Content-Type: text/html
-Request forbidden by administrative rules.
-Please make sure your request has a User-Agent header.
-Check https://developer.github.com for other possible causes.
-
+> Request forbidden by administrative rules.
+> Please make sure your request has a User-Agent header.
+> Check https://developer.github.com for other possible causes.
+```
## Conditional requests
Most responses return an `ETag` header. Many responses also return a `Last-Modified` header. You can use the values
of these headers to make subsequent requests to those resources using the
`If-None-Match` and `If-Modified-Since` headers, respectively. If the resource
-has not changed, the server will return a `304 Not Modified`. Also note: making
-a conditional request and receiving a 304 response does not count against your
-[Rate Limit](#rate-limiting), so we encourage you to use it whenever possible.
-
-
+> /**/foo({
+> "meta": {
+> "status": 200,
+{% if page.version == 'dotcom' %}
+> "X-RateLimit-Limit": "5000",
+> "X-RateLimit-Remaining": "4966",
+> "X-RateLimit-Reset": "1372700873",
+{% endif %}
+> "Link": [ // pagination headers and other links
+> ["https://api.github.com?page=2", {"rel": "next"}]
+> ]
+> },
+> "data": {
+> // the data
+> }
+> })
+```
You can write a JavaScript handler to process the callback. Here's a minimal example you can try out:
@@ -583,7 +649,7 @@ For API calls that allow for a timestamp to be specified, we use that exact
timestamp. An example of this is the [Commits API](/v3/git/commits).
These timestamps look something like `2014-02-27T15:05:06+01:00`. Also see
-[this example](http://developer.github.com/v3/git/commits/#example-input) for
+[this example](https://developer.github.com/v3/git/commits/#example-input) for
how these timestamps can be specified.
#### Using the `Time-Zone` header
@@ -591,7 +657,9 @@ how these timestamps can be specified.
It is possible to supply a `Time-Zone` header which defines a timezone according
to the [list of names from the Olson database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- $ curl -H "Time-Zone: Europe/Amsterdam" -X POST https://api.github.com/repos/github/linguist/contents/new_file.md
+``` command-line
+$ curl -H "Time-Zone: Europe/Amsterdam" -X POST {{ site.data.variables.product.api_url_pre }}/repos/github/linguist/contents/new_file.md
+```
This means that we generate a timestamp for the moment your API call is made in
the timezone this header defines. For example, the [Contents API](/v3/repos/contents/)
@@ -602,8 +670,8 @@ that current timestamp.
#### Using the last known timezone for the user
If no `Time-Zone` header is specified and you make an authenticated call to the
-API, we use the last known timezone for the authenticated user. The last know
-timezone is updated whenever you browse the GitHub.com website.
+API, we use the last known timezone for the authenticated user. The last known
+timezone is updated whenever you browse the {{ site.data.variables.product.product_name }} website.
#### UTC
@@ -611,4 +679,5 @@ If the steps above don't result in any information, we use UTC as the timezone
to create the git commit.
[support]: https://github.com/contact?form[subject]=APIv3
+[abuse-support]: https://github.com/contact?form[subject]=API+Abuse+Rate+Limits
[pagination-guide]: /guides/traversing-with-pagination
diff --git a/content/v3/activity.md b/content/v3/activity.md
index 79a516815b..cdac1ca8a7 100644
--- a/content/v3/activity.md
+++ b/content/v3/activity.md
@@ -1,11 +1,20 @@
---
-title: Activity | GitHub API
+title: Activity
---
# Activity
-Serving up the 'social' in Social Coding™, the Activity APIs provide access to
+Serving up the 'social' in Social Coding, the Activity APIs provide access to
notifications, subscriptions, and timelines.
+## [Events][]
+
+The [Events API][Events] is a read-only interface to all the [event
+types][types] that power the various activity streams on {{ site.data.variables.product.product_name }}.
+
+## [Feeds][]
+
+List of [Atom feeds][Feeds] available for the authenticated user.
+
## [Notifications][]
Notifications of new comments are delivered to users. [The Notifications
@@ -22,18 +31,9 @@ have no effect on notifications or the activity feed.
[Watching a Repository][Watching] registers the user to receive notifications on new
discussions, as well as events in the user's activity feed.
-## [Events][]
-
-The [Events API][Events] is a read-only interface to all the [event
-types][types] that power the various activity streams on GitHub.
-
-## [Feeds][]
-
-List of [Atom feeds][Feeds] available for the authenticating user.
-
-[Notifications]: /v3/activity/notifications/
-[Starring]: /v3/activity/starring/
-[Watching]: /v3/activity/watching/
[Events]: /v3/activity/events/
[types]: /v3/activity/events/types/
[Feeds]: /v3/activity/feeds/
+[Notifications]: /v3/activity/notifications/
+[Starring]: /v3/activity/starring/
+[Watching]: /v3/activity/watching/
diff --git a/content/v3/activity/events.md b/content/v3/activity/events.md
index f6d81d45d5..5541291631 100644
--- a/content/v3/activity/events.md
+++ b/content/v3/activity/events.md
@@ -1,13 +1,12 @@
---
-title: Events | GitHub API
+title: Events
---
# Events
-This is a read-only API to the GitHub events. These events power the
+This is a read-only API to the {{ site.data.variables.product.product_name }} events. These events power the
various activity streams on the site.
-* TOC
{:toc}
Events are optimized for polling with the "ETag" header. If no new events have
@@ -16,24 +15,30 @@ rate limit will be untouched. There is also an "X-Poll-Interval" header that
specifies how often (in seconds) you are allowed to poll. In times of high
server load, the time may increase. Please obey the header.
- $ curl -I https://api.github.com/users/tater/events
- HTTP/1.1 200 OK
- X-Poll-Interval: 60
- ETag: "a18c3bded88eb5dbb5c849a489412bf3"
+``` command-line
+$ curl -I {{ site.data.variables.product.api_url_pre }}/users/tater/events
+> HTTP/1.1 200 OK
+> X-Poll-Interval: 60
+> ETag: "a18c3bded88eb5dbb5c849a489412bf3"
- # The quotes around the ETag value are important
- $ curl -I https://api.github.com/users/tater/events \
- -H 'If-None-Match: "a18c3bded88eb5dbb5c849a489412bf3"'
- HTTP/1.1 304 Not Modified
- X-Poll-Interval: 60
+# The quotes around the ETag value are important
+$ curl -I {{ site.data.variables.product.api_url_pre }}/users/tater/events \
+$ -H 'If-None-Match: "a18c3bded88eb5dbb5c849a489412bf3"'
+> HTTP/1.1 304 Not Modified
+> X-Poll-Interval: 60
+```
Events support [pagination](/v3/#pagination),
however the `per_page` option is unsupported. The fixed page size is 30 items.
Fetching up to ten pages is supported, for a total of 300 events.
+Only events created within the past 90 days will be included in timelines. Events
+older than 90 days will not be included (even if the total number of events
+in the timeline is less than 300).
+
All Events have the same response format:
-<%= headers 200, :pagination => { :next => 'https://api.github.com/resource?page=2' } %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:event) { |h| [h] } %>
## List public events
@@ -47,7 +52,7 @@ All Events have the same response format:
## List issue events for a repository
Repository issue events have a different format than other events,
-as documented in the [Issue Events API](http://developer.github.com/v3/issues/events/).
+as documented in the [Issue Events API](https://developer.github.com/v3/issues/events/).
GET /repos/:owner/:repo/issues/events
@@ -65,26 +70,26 @@ These are events that you've received by watching repos and following
users. If you are authenticated as the given user, you will see private
events. Otherwise, you'll only see public events.
- GET /users/:user/received_events
+ GET /users/:username/received_events
## List public events that a user has received
- GET /users/:user/received_events/public
+ GET /users/:username/received_events/public
## List events performed by a user
If you are authenticated as the given user, you will see your private
events. Otherwise, you'll only see public events.
- GET /users/:user/events
+ GET /users/:username/events
## List public events performed by a user
- GET /users/:user/events/public
+ GET /users/:username/events/public
## List events for an organization
This is the user's organization dashboard. You must be authenticated as
the user to view this.
- GET /users/:user/events/orgs/:org
+ GET /users/:username/events/orgs/:org
diff --git a/content/v3/activity/events/types.md b/content/v3/activity/events/types.md
index 76fd8e5a5d..9504e2de89 100644
--- a/content/v3/activity/events/types.md
+++ b/content/v3/activity/events/types.md
@@ -1,48 +1,47 @@
---
-title: Event Types | GitHub API
+title: Event Types & Payloads
---
-# Event Types
+# Event Types & Payloads
Each event has a similar JSON schema, but a unique `payload` object that is
-determined by its event type. [Repository hook](/v3/repos/hooks/) names relate to event types, and will have the exact same payload. The only exception to this is the `push` hook, which has a larger, more detailed payload.
+determined by its event type.
-This describes just the payload of an event. A full event will also
-show the user that performed the event (actor), the repository, and the
-organization (if applicable).
+Event names are used by [repository webhooks](/v3/repos/hooks/) to specify
+which events the webhook should receive. The included payloads below are from webhook deliveries but
+match events returned by the [Events API](/v3/activity/events/) (except where noted). The Events API uses the CamelCased name (e.g. `CommitCommentEvent`) in the `type` field of an event object and does not include the `repository` or `sender` fields in the event payload object.
-Note that some of these events may not be rendered in timelines.
-They're only created for various internal and repository hooks.
-* TOC
+**Note:** Some of these events may not be rendered in timelines, they're only
+created for various internal and webhook purposes.
+
{:toc}
## CommitCommentEvent
Triggered when a [commit comment](/v3/repos/comments/#list-commit-comments-for-a-repository) is created.
-### Hook name
-
-`commit_comment`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`comment`|`object` | The [comment](/v3/repos/comments/#list-commit-comments-for-a-repository) itself.
+### Webhook event name
-## CreateEvent
+`commit_comment`
-Represents a created repository, branch, or tag.
+### Webhook payload example
-Note: webhooks will not receive this event for created repositories.
+<%= webhook_payload "commit_comment" %>
-### Hook name
+## CreateEvent
-`create`
+Represents a created repository, branch, or tag.
-### Payload
+Note: webhooks will not receive this event for created repositories. Additionally, webhooks will not receive this event for tags if more than three tags are pushed at once.
+
+### Events API payload
Key | Type | Description
----|------|-------------
@@ -51,63 +50,84 @@ Key | Type | Description
`master_branch`|`string` | The name of the repository's default branch (usually `master`).
`description`|`string` | The repository's current description.
+### Webhook event name
+
+`create`
+
+### Webhook payload example
+
+<%= webhook_payload "create" %>
## DeleteEvent
Represents a [deleted branch or tag](/v3/git/refs/#delete-a-reference).
-### Hook name
+Note: webhooks will not receive this event for tags if more than three tags are deleted at once.
-`delete`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`ref_type`|`string` | The object that was deleted. Can be "branch" or "tag".
`ref`|`string` | The full git ref.
-## DeploymentEvent
+### Webhook event name
-Represents a [deployment](/v3/repos/deployments/#list-deployments).
+`delete`
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+### Webhook payload example
-### Hook name
+<%= webhook_payload "delete" %>
-`deployment`
+## DeploymentEvent
+
+Represents a [deployment](/v3/repos/deployments/#list-deployments).
+
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
-`sha` |`string` | The commit SHA for which this deployment was created.
-`name` |`string` | Name of repository for this deployment, formatted as `:owner/:repo`.
-`payload` |`string` | The optional extra information for this deployment.
-`description`|`string` | The optional human-readable description added to the deployment.
+`deployment` |`object` | The [deployment](/v3/repos/deployments/#list-deployments).
+`deployment`[`"sha"`] |`string` | The commit SHA for which this deployment was created.
+`deployment`[`"payload"`] |`string` | The optional extra information for this deployment.
+`deployment`[`"environment"`] |`string` | The optional environment to deploy to. Default: `"production"`
+`deployment`[`"description"`] |`string` | The optional human-readable description added to the deployment.
+`repository` |`object` | The [repository](/v3/repos/) for this deployment.
+### Webhook event name
-## DeploymentStatusEvent
+`deployment`
-Represents a [deployment status](/v3/repos/deployments/#list-deployment-statuses).
+### Webhook payload example
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+<%= webhook_payload "deployment" %>
-### Hook name
+## DeploymentStatusEvent
-`deployment_status`
+Represents a [deployment status](/v3/repos/deployments/#list-deployment-statuses).
+
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
-`sha` |`string` | The commit SHA for the associated deployment.
-`name` |`string` | Name of repository for the associated deployment, formatted as `:owner/:repo`.
-`state` |`string` | The new state. Can be `pending`, `success`, `failure`, or `error`.
-`payload` |`string` | The optional extra information for the associated deployment.
-`target_url` |`string` | The optional link added to the status.
-`description`|`string` | The optional human-readable description added to the status.
+`deployment_status` |`object` | The [deployment status](/v3/repos/deployments/#list-deployment-statuses).
+`deployment_status["state"]` |`string` | The new state. Can be `pending`, `success`, `failure`, or `error`.
+`deployment_status["target_url"]` |`string` | The optional link added to the status.
+`deployment_status["description"]`|`string` | The optional human-readable description added to the status.
+`deployment` |`object` | The [deployment](/v3/repos/deployments/#list-deployments) that this status is associated with.
+`repository` |`object` | The [repository](/v3/repos/) for this deployment.
+
+### Webhook event name
+
+`deployment_status`
+
+### Webhook payload example
+<%= webhook_payload "deployment_status" %>
## DownloadEvent
@@ -115,48 +135,49 @@ Triggered when a new [download](/v3/repos/downloads/) is created.
Events of this type are **no longer created**, but it's possible that they exist in timelines of some users.
-### Hook name
-
-`download`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`download`|`object` | The [download](/v3/repos/downloads/) that was just created.
+### Webhook event name
+
+`download`
## FollowEvent
Triggered when a user [follows another user](/v3/users/followers/#follow-a-user).
-Events of this type are not visible in timelines, they are only used to trigger hooks.
-
-### Hook name
-
-`follow`
+Events of this type are **no longer created**, but it's possible that they exist in timelines of some users.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`target`|`object` | The [user](/v3/users) that was just followed.
+### Webhook event name
+
+`follow`
## ForkEvent
Triggered when a user [forks a repository](/v3/repos/forks/#create-a-fork).
-### Hook name
-
-`fork`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`forkee`|`object` | The created [repository](/v3/repos/).
+### Webhook event name
+
+`fork`
+
+### Webhook payload example
+
+<%= webhook_payload "fork" %>
## ForkApplyEvent
@@ -164,11 +185,7 @@ Triggered when a patch is applied in the Fork Queue.
Events of this type are **no longer created**, but it's possible that they exist in timelines of some users.
-### Hook name
-
-`fork_apply`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
@@ -176,6 +193,9 @@ Key | Type | Description
`before`|`string` | SHA of the repository state before the patch.
`after`|`string` | SHA of the repository state after the patch.
+### Webhook event name
+
+`fork_apply`
## GistEvent
@@ -183,27 +203,22 @@ Triggered when a [Gist](/v3/gists/) is created or updated.
Events of this type are **no longer created**, but it's possible that they exist in timelines of some users.
-### Hook name
-
-`gist`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`action`|`string` | The action that was performed. Can be "create" or "update"
`gist`|`object` | The [gist](/v3/gists/) itself.
+### Webhook event name
+
+`gist`
## GollumEvent
Triggered when a Wiki page is created or updated.
-### Hook name
-
-`gollum`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
@@ -214,55 +229,105 @@ Key | Type | Description
`pages[][sha]`|`string` | The latest commit SHA of the page.
`pages[][html_url]`|`string` | Points to the HTML wiki page.
+### Webhook event name
-## IssueCommentEvent
+`gollum`
-Triggered when an [issue comment](/v3/issues/comments/) is created.
+### Webhook payload example
-### Hook name
+<%= webhook_payload "gollum" %>
-`issue_comment`
+## IssueCommentEvent
+
+{% if page.version == 'dotcom' or page.version > 2.6 %}
+Triggered when an [issue comment](/v3/issues/comments/) is created, edited, or deleted.
+{% else %}
+Triggered when an [issue is commented on](/v3/issues/comments/).
+{% endif %}
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
-`action`|`string` | The action that was performed on the comment. Currently, can only be "created".
+`action`|`string` | The action that was performed on the comment. {% if page.version == 'dotcom' or page.version > 2.6 %}Can be one of "created", "edited", or "deleted".
+`changes`|`object` | The changes to the comment if the action was "edited".
+`changes[body][from]` |`string` | The previous version of the body if the action was "edited".{% else %}Currently, can only be "created".{% endif %}
`issue`|`object` | The [issue](/v3/issues/) the comment belongs to.
`comment`|`object` | The [comment](/v3/issues/comments/) itself.
+### Webhook event name
-## IssuesEvent
+`issue_comment`
-Triggered when an [issue](/v3/issues) is created, closed or reopened.
+### Webhook payload example
-### Hook name
+<%= webhook_payload "issue_comment" %>
-`issues`
+## IssuesEvent
+
+Triggered when an [issue](/v3/issues) is assigned, unassigned, labeled, unlabeled, opened, {% if page.version == 'dotcom' or page.version > 2.6 %}edited, {% endif %}closed, or reopened.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
-`action`|`string` | The action that was performed. Can be one of "opened", "closed", or "reopened".
-`issue`|`object` | The [issue](/v3/issues) itself.
+`action`|`string` | The action that was performed. Can be one of "assigned", "unassigned", "labeled", "unlabeled", "opened", {% if page.version == 'dotcom' or page.version > 2.6 %}"edited", {% endif %}"closed", or "reopened".
+`issue`|`object` | The [issue](/v3/issues) itself.{% if page.version == 'dotcom' or page.version > 2.6 %}
+`changes`|`object`| The changes to the issue if the action was "edited".
+`changes[title][from]`|`string` | The previous version of the title if the action was "edited".
+`changes[body][from]`|`string` | The previous version of the body if the action was "edited".{% endif %}
+`assignee`|`object` | The optional user who was assigned or unassigned from the issue.
+`label`|`object` | The optional label that was added or removed from the issue.
+### Webhook event name
-## MemberEvent
+`issues`
-Triggered when a user is [added as a collaborator](/v3/repos/collaborators/#add-collaborator) to a repository.
+### Webhook payload example
-### Hook name
+<%= webhook_payload "issues" %>
-`member`
+## MemberEvent
+
+Triggered when a user is [added as a collaborator](/v3/repos/collaborators/#add-user-as-a-collaborator) to a repository.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`member`|`object` | The [user](/v3/users/) that was added.
`action`|`string` | The action that was performed. Currently, can only be "added".
+### Webhook event name
+
+`member`
+
+### Webhook payload example
+
+<%= webhook_payload "member" %>
+
+## MembershipEvent
+
+Triggered when a user is added or removed from a team.
+
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
+
+### Events API payload
+
+Key | Type | Description
+----|------|-------------
+`action` |`string` | The action that was performed. Can be "added" or "removed".
+`scope` |`string` | The scope of the membership. Currently, can only be "team".
+`member` |`object` | The [user](/v3/users/) that was added or removed.
+`team` |`object` | The [team](/v3/orgs/teams/) for the membership.
+
+### Webhook event name
+
+`membership`
+
+### Webhook payload example
+
+<%= webhook_payload "membership" %>
## PageBuildEvent
@@ -270,77 +335,105 @@ Represents an attempted build of a GitHub Pages site, whether successful or not.
Triggered on push to a GitHub Pages enabled branch (`gh-pages` for project pages, `master` for user and organization pages).
-### Hook Name
-
-`page_build`
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
-### Payload
+### Events API payload
Key | Type | Description
----|------|------------
-`build` | `object` | The [page build](http://developer.github.com/v3/repos/pages/#list-pages-builds) itself.
+`build` | `object` | The [page build](https://developer.github.com/v3/repos/pages/#list-pages-builds) itself.
+### Webhook event name
+
+`page_build`
+
+### Webhook payload example
+
+<%= webhook_payload "page_build" %>
## PublicEvent
-Triggered when a private repository is [open sourced](/v3/repos/#edit). Without a doubt: the best GitHub event.
+Triggered when a private repository is [open sourced](/v3/repos/#edit). Without a doubt: the best {{ site.data.variables.product.product_name }} event.
+
+### Events API payload
-### Hook name
+### Webhook event name
`public`
-### Payload
+### Webhook payload example
-(empty payload)
+<%= webhook_payload "public" %>
## PullRequestEvent
-Triggered when a [pull request](/v3/pulls) is created, closed, reopened or synchronized.
+Triggered when a [pull request](/v3/pulls) is assigned, unassigned, labeled, unlabeled, opened, {% if page.version == 'dotcom' or page.version > 2.6 %}edited, {% endif %}closed, reopened, or synchronized.
-### Hook name
-
-`pull_request`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
-`action`|`string` | The action that was performed. Can be one of "opened", "closed", "synchronize", or "reopened".
-`number`|`integer` | The pull request number.
+`action`|`string` | The action that was performed. Can be one of "assigned", "unassigned", "labeled", "unlabeled", "opened", {% if page.version == 'dotcom' or page.version > 2.6 %}"edited", {% endif %}"closed", or "reopened", or "synchronize". If the action is "closed" and the `merged` key is `false`, the pull request was closed with unmerged commits. If the action is "closed" and the `merged` key is `true`, the pull request was merged.
+`number`|`integer` | The pull request number.{% if page.version == 'dotcom' or page.version > 2.6 %}
+`changes`|`object`| The changes to the comment if the action was "edited".
+`changes[title][from]`|`string` | The previous version of the title if the action was "edited".
+`changes[body][from]`|`string` | The previous version of the body if the action was "edited".{% endif %}
`pull_request`|`object` | The [pull request](/v3/pulls) itself.
+### Webhook event name
-## PullRequestReviewCommentEvent
+`pull_request`
-Triggered when a [comment is created on a portion of the unified diff](/v3/pulls/comments) of a pull request.
+### Webhook payload example
-### Hook name
+<%= webhook_payload "pull_request" %>
-`pull_request_review_comment`
+## PullRequestReviewCommentEvent
+
+{% if page.version == 'dotcom' or page.version > 2.6 %}
+Triggered when a [comment on a Pull Request's unified diff](/v3/pulls/comments) is created, edited, or deleted (in the Files Changed tab).
+{% else %}
+Triggered when a [Pull Request's unified diff is commented on](/v3/pulls/comments) (in the Files Changed tab).
+{% endif %}
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
+`action`|`string` | The action that was performed on the comment. {% if page.version == 'dotcom' or page.version > 2.6 %}Can be one of "created", "edited", or "deleted".
+`changes`|`object`| The changes to the comment if the action was "edited".
+`changes[body][from]`|`string` | The previous version of the body if the action was "edited".{% else %}Currently, can only be "created".{% endif %}
+`pull_request`|`object` | The [pull request](/v3/pulls/) the comment belongs to.
`comment`|`object` | The [comment](/v3/pulls/comments) itself.
+### Webhook event name
+
+`pull_request_review_comment`
+
+### Webhook payload example
+
+<%= webhook_payload "pull_request_review_comment" %>
## PushEvent
-Triggered when a repository branch is pushed to.
+Triggered when a repository branch is pushed to. In addition to branch pushes, webhook [`push` events](/webhooks/#events) are also triggered when repository tags are pushed.
-### Hook name
+{{#tip}}
-`push`
+The Events API `PushEvent` payload is described in the table below. The example payload below that is from a webhook delivery and will differ from the Events API `PushEvent` payload.
-### Payload
+{{/tip}}
+
+### Events API payload
Key | Type | Description
----|------|-------------
-`head`|`string` | The SHA of the HEAD commit on the repository.
-`ref`|`string` | The full Git ref that was pushed. Example: "refs/heads/master"
+`ref`|`string` | The full Git ref that was pushed. Example: `"refs/heads/master"`.
+`head`|`string` | The SHA of the most recent commit on `ref` after the push.
+`before`|`string` | The SHA of the most recent commit on `ref` before the push.
`size`|`integer` | The number of commits in the push.
-`commits`|`array` | An array of commit objects describing the pushed commits. (The array includes a maximum of 20 commits. If necessary, you can use the [Commits API](/v3/repos/commits/) to fetch additional commits.)
+`distinct_size`|`integer` | The number of distinct commits in the push.
+`commits`|`array` | An array of commit objects describing the pushed commits. (The array includes a maximum of 20 commits. If necessary, you can use the [Commits API](/v3/repos/commits/) to fetch additional commits. This limit is applied to timeline events only and isn't applied to webhook deliveries.)
`commits[][sha]`|`string` | The SHA of the commit.
`commits[][message]`|`string` | The commit message.
`commits[][author]`|`object` | The git author of the commit.
@@ -349,33 +442,61 @@ Key | Type | Description
`commits[][url]`|`url` | Points to the commit API resource.
`commits[][distinct]`|`boolean` | Whether this commit is distinct from any that have been pushed before.
+### Webhook event name
+
+`push`
+
+### Webhook payload example
+
+<%= webhook_payload "push" %>
+
## ReleaseEvent
Triggered when a [release](/v3/repos/releases/#get-a-single-release) is published.
-### Hook name
+### Events API payload
+
+Key | Type | Description
+----|------|-------------
+`action`|`string` | The action that was performed. Currently, can only be "published".
+`release`|`object` | The [release](/v3/repos/releases/#get-a-single-release) itself.
+
+### Webhook event name
`release`
-### Payload
+### Webhook payload example
+
+<%= webhook_payload "release" %>
+
+## RepositoryEvent
+
+Triggered when a repository is created{% if page.version == 'dotcom' or page.version > 2.6 %}, deleted, made public, or made private{% endif %}.
+
+Events of this type are not visible in timelines. These events are only used to trigger {% if page.version != 'dotcom' and page.version <= 2.6 %}organization {% endif %}hooks.
+
+### Events API payload
Key | Type | Description
----|------|-------------
-`action`|`string` | The action that was performed. Currently, can only be "published".
-`release`|`object` | The [release](/v3/repos/releases/#get-a-single-release) itself.
+`action` |`string` | The action that was performed. {% if page.version == 'dotcom' or page.version > 2.6 %}This can be one of "created", "deleted", "publicized", or "privatized".{% else %}Currently, can only be "created".{% endif %}
+`repository`|`object` | The [repository](/v3/repos/) itself.
+### Webhook event name
-## StatusEvent
+`repository`
-Triggered when the status of a Git commit changes.
+### Webhook payload example
+
+<%= webhook_payload "repository" %>
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+## StatusEvent
-### Hook name
+Triggered when the status of a Git commit changes.
-`status`
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
@@ -385,40 +506,53 @@ Key | Type | Description
`target_url`|`string` | The optional link added to the status.
`branches`|`array` | An array of branch objects containing the status' SHA. Each branch contains the given SHA, but the SHA may or may not be the head of the branch. The array includes a maximum of 10 branches.
+### Webhook event name
-## TeamAddEvent
+`status`
-Triggered when a [user is added to a team](/v3/orgs/teams/#add-team-member) or when a [repository is added to a team](/v3/orgs/teams/#add-team-repo).
+### Webhook payload example
-Note: this event is created in [users' organization timelines](/v3/activity/events/#list-events-for-an-organization).
+<%= webhook_payload "status" %>
-### Hook name
+## TeamAddEvent
-`team_add`
+Triggered when a [repository is added to a team](/v3/orgs/teams/#add-or-update-team-repository).
+
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`team`|`object` | The [team](/v3/orgs/teams/) that was modified. Note: older events may not include this in the payload.
-`user`|`object` | The [user](/v3/users/) that was added to this team.
-`repo`|`object` | The [repository](/v3/repos/) that was added to this team.
+`repository`|`object` | The [repository](/v3/repos/) that was added to this team.
+
+### Webhook event name
+
+`team_add`
+
+### Webhook payload example
+<%= webhook_payload "team_add" %>
## WatchEvent
The WatchEvent is related to [starring a repository](/v3/activity/starring/#star-a-repository), not [watching](/v3/activity/watching/).
-See [this API blog post](/changes/2012-9-5-watcher-api/) for an explanation.
+See [this API blog post](/changes/2012-09-05-watcher-api/) for an explanation.
The event’s actor is the [user](/v3/users/) who starred a repository, and the
event’s repository is the [repository](/v3/repos/) that was starred.
-### Hook name
-
-`watch`
-
-### Payload
+### Events API payload
Key | Type | Description
----|------|-------------
`action`|`string` | The action that was performed. Currently, can only be `started`.
+
+### Webhook event name
+
+`watch`
+
+### Webhook payload example
+
+<%= webhook_payload "watch" %>
diff --git a/content/v3/activity/feeds.md b/content/v3/activity/feeds.md
index 56ce2f9a59..11c583fa9b 100644
--- a/content/v3/activity/feeds.md
+++ b/content/v3/activity/feeds.md
@@ -1,26 +1,25 @@
---
-title: Feeds | GitHub API
+title: Feeds
---
# Feeds
-* TOC
{:toc}
## List Feeds
-GitHub provides several timeline resources in [Atom][] format. The Feeds API
-lists all the feeds available to the authenticating user:
+{{ site.data.variables.product.product_name }} provides several timeline resources in [Atom][] format. The Feeds API
+lists all the feeds available to the authenticated user:
-* **Timeline**: The GitHub global public timeline
+* **Timeline**: The {{ site.data.variables.product.product_name }} global public timeline
* **User**: The public timeline for any user, using [URI template][]
* **Current user public**: The public timeline for the authenticated user
* **Current user**: The private timeline for the authenticated user
* **Current user actor**: The private timeline for activity created by the authenticated user
-* **Current user organization**: The private timeline for the authenticated user for a given organization, using [URI template][]
+* **Current user organizations**: The private timeline for the organizations the authenticated user is a member of.
**Note**: Private feeds are only returned when [authenticating via Basic
-Auth][authenticating] since current feed URIs use the older, non revokable auth
+Auth][authenticating] since current feed URIs use the older, non revocable auth
tokens.
GET /feeds
@@ -32,4 +31,4 @@ tokens.
[Atom]: http://en.wikipedia.org/wiki/Atom_(standard)
[authenticating]: /v3/#basic-authentication
-[URI template]: http://developer.github.com/v3/#hypermedia
+[URI template]: https://developer.github.com/v3/#hypermedia
diff --git a/content/v3/activity/notifications.md b/content/v3/activity/notifications.md
index 7ba5af3e87..b09ec649a7 100644
--- a/content/v3/activity/notifications.md
+++ b/content/v3/activity/notifications.md
@@ -1,21 +1,19 @@
---
-title: Notifications | GitHub API
+title: Notifications
---
# Notifications
-* TOC
{:toc}
-GitHub Notifications are powered by [watched repositories](/v3/activity/watching/).
-Users receive notifications for discussions in repositories they watch
+Users receive notifications for conversations in repositories they watch
including:
* Issues and their comments
* Pull Requests and their comments
* Comments on any commits
-Notifications are also sent for discussions in unwatched repositories when the
+Notifications are also sent for conversations in unwatched repositories when the
user is involved including:
* **@mentions**
@@ -37,17 +35,19 @@ leaving your current rate limit untouched. There is an "X-Poll-Interval"
header that specifies how often (in seconds) you are allowed to poll. In times
of high server load, the time may increase. Please obey the header.
- # Add authentication to your requests
- $ curl -I https://api.github.com/notifications
- HTTP/1.1 200 OK
- Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
- X-Poll-Interval: 60
+``` command-line
+# Add authentication to your requests
+$ curl -I {{ site.data.variables.product.api_url_pre }}/notifications
+HTTP/1.1 200 OK
+Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
+X-Poll-Interval: 60
- # Pass the Last-Modified header exactly
- $ curl -I https://api.github.com/notifications
- -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
- HTTP/1.1 304 Not Modified
- X-Poll-Interval: 60
+# Pass the Last-Modified header exactly
+$ curl -I {{ site.data.variables.product.api_url_pre }}/notifications
+$ -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
+> HTTP/1.1 304 Not Modified
+> X-Poll-Interval: 60
+```
## Notification Reasons
@@ -59,20 +59,20 @@ Here's a list of potential `reason`s for receiving a notification:
Reason Name | Description
------------|------------
`subscribed` | The notification arrived because you're watching the repository
-`manual` | The notification arrived because you've specifically decided to watch the item (via an Issue or Pull Request)
-`author` | The notification arrived because you've created the item
-`comment` | The notification arrived because you've commented on the item
-`mention` | The notification arrived because you were specifically **@mentioned** in the content
-`team_mention` | The notification arrived because you were on a team that was mentioned (like @org/team)
-`state_change` | The notification arrived because you changed the item state (like closing an Issue or merging a Pull Request)
-`assign` | The notification arrived because you were assigned to the Issue
+`manual` | The notification arrived because you've specifically decided to subscribe to the thread (via an Issue or Pull Request)
+`author` | The notification arrived because you've created the thread
+`comment` | The notification arrived because you've commented on the thread
+`mention` | The notification arrived because you were specifically **@mentioned** in the content
+`team_mention` | The notification arrived because you were on a team that was mentioned (like @org/team)
+`state_change` | The notification arrived because you changed the thread state (like closing an Issue or merging a Pull Request)
+`assign` | The notification arrived because you were assigned to the Issue
Note that the `reason` is modified on a per-thread basis, and can change, if the
-`reason` on a later notification is different.
+`reason` on a later notification is different.
-For example, if you are the author of an issue, subsequent notifications on that
-issue will have a `reason` of `author`. If you're then **@mentioned** on the same
-issue, the notifications you fetch thereafter will have a `reason` of `mention`.
+For example, if you are the author of an issue, subsequent notifications on that
+issue will have a `reason` of `author`. If you're then **@mentioned** on the same
+issue, the notifications you fetch thereafter will have a `reason` of `mention`.
The `reason` remains as `mention`, regardless of whether you're ever mentioned again.
## List your notifications
@@ -87,12 +87,16 @@ Name | Type | Description
-----|------|--------------
`all`|`boolean` | If `true`, show notifications marked as read. Default: `false`
`participating`|`boolean` | If `true`, only shows notifications in which the user is directly participating or mentioned. Default: `false`
-`since`|`string` | Filters out any notifications updated before the given time. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Default: `Time.now`
-
+`since`|`string` | Only show notifications updated after the given time. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Default: `Time.now`
+`before`|`string` | Only show notifications updated before the given time. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`.
### Response
+{% if page.version == 'dotcom' or page.version > 2.5 %}
+<%= headers 200, :pagination => default_pagination_rels %>
+{% else %}
<%= headers 200 %>
+{% endif %}
<%= json(:thread) { |h| [h] } %>
## List your notifications in a repository
@@ -107,18 +111,22 @@ Name | Type | Description
-----|------|--------------
`all`|`boolean` | If `true`, show notifications marked as read. Default: `false`
`participating`|`boolean` | If `true`, only shows notifications in which the user is directly participating or mentioned. Default: `false`
-`since`|`string` | Filters out any notifications updated before the given time. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Default: `Time.now`
-
+`since`|`string` | Only show notifications updated after the given time. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Default: `Time.now`
+`before`|`string` | Only show notifications updated before the given time. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`.
### Response
+{% if page.version == 'dotcom' or page.version > 2.5 %}
+<%= headers 200, :pagination => default_pagination_rels %>
+{% else %}
<%= headers 200 %>
+{% endif %}
<%= json(:thread) { |h| [h] } %>
## Mark as read
Marking a notification as "read" removes it from the [default view
-on GitHub.com](https://github.com/notifications).
+on {{ site.data.variables.product.product_name }}](https://github.com/notifications).
PUT /notifications
@@ -136,13 +144,13 @@ Name | Type | Description
## Mark notifications as read in a repository
Marking all notifications in a repository as "read" removes them
-from the [default view on GitHub.com](https://github.com/notifications).
+from the [default view on {{ site.data.variables.product.product_name }}](https://github.com/notifications).
PUT /repos/:owner/:repo/notifications
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`last_read_at`|`string` | Describes the last point that notifications were checked. Anything updated since this time will not be updated. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Default: `Time.now`
@@ -173,6 +181,12 @@ Name | Type | Description
This checks to see if the current user is subscribed to a thread. You can also
[get a Repository subscription](/v3/activity/watching/#get-a-repository-subscription).
+{{#tip}}
+
+Note that subscriptions are only generated if a user is participating in a conversation--for example, they've replied to the thread, were **@mention**ed, or manually subscribe to a thread.
+
+{{/tip}}
+
GET /notifications/threads/:id/subscription
### Response
@@ -182,10 +196,7 @@ This checks to see if the current user is subscribed to a thread. You can also
## Set a Thread Subscription
-This lets you subscribe to a thread, or ignore it. Subscribing to a thread
-is unnecessary if the user is already subscribed to the repository. Ignoring
-a thread will mute all future notifications (until you comment or get
-@mentioned).
+This lets you subscribe or unsubscribe from a conversation. Unsubscribing from a conversation mutes all future notifications (until you comment or get **@mention**ed once more).
PUT /notifications/threads/:id/subscription
@@ -209,4 +220,3 @@ Name | Type | Description
### Response
<%= headers 204 %>
-
diff --git a/content/v3/activity/starring.md b/content/v3/activity/starring.md
index bb78af0460..b32b1a7c0b 100644
--- a/content/v3/activity/starring.md
+++ b/content/v3/activity/starring.md
@@ -1,10 +1,9 @@
---
-title: Starring | GitHub API
+title: Starring
---
# Starring
-* TOC
{:toc}
Repository Starring is a feature that lets users bookmark repositories. Stars
@@ -15,10 +14,10 @@ Watching](/v3/activity/watching).
### Starring vs. Watching
In August 2012, we [changed the way watching
-works](https://github.com/blog/1204-notifications-stars) on GitHub. Many API
+works](https://github.com/blog/1204-notifications-stars) on {{ site.data.variables.product.product_name }}. Many API
client applications may be using the original "watcher" endpoints for accessing
this data. You can now start using the "star" endpoints instead (described
-below). Check out the [Watcher API Change post](/changes/2012-9-5-watcher-api/)
+below). Check out the [Watcher API Change post](/changes/2012-09-05-watcher-api/)
for more details.
## List Stargazers
@@ -30,11 +29,20 @@ for more details.
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:user) { |h| [h] } %>
+### Alternative response with star creation timestamps
+
+You can also find out _when_ stars were created by passing the following custom [media type](/v3/media/) via the `Accept` header:
+
+ Accept: application/vnd.github.v3.star+json
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:stargazer_with_timestamps) { |hash| [hash] } %>
+
## List repositories being starred
List repositories being starred by a user.
- GET /users/:user/starred
+ GET /users/:username/starred
List repositories being starred by the authenticated user.
@@ -42,17 +50,25 @@ List repositories being starred by the authenticated user.
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`sort`|`string` | One of `created` (when the repository was starred) or `updated` (when it was last pushed to). Default: `created`
`direction`|`string` | One of `asc` (ascending) or `desc` (descending). Default: `desc`
-
### Response
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:repo) { |h| [h] } %>
+### Alternative response with star creation timestamps
+
+You can also find out _when_ stars were created by passing the following custom [media type](/v3/media/) via the `Accept` header:
+
+ Accept: application/vnd.github.v3.star+json
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:starred_repo) { |hash| [hash] } %>
+
## Check if you are starring a repository
Requires for the user to be authenticated.
@@ -73,6 +89,8 @@ Requires for the user to be authenticated.
PUT /user/starred/:owner/:repo
+<%= fetch_content(:put_content_length) %>
+
### Response
<%= headers 204 %>
diff --git a/content/v3/activity/watching.md b/content/v3/activity/watching.md
index 1f387aba15..40b39b87bd 100644
--- a/content/v3/activity/watching.md
+++ b/content/v3/activity/watching.md
@@ -1,10 +1,9 @@
---
-title: Watching | GitHub API
+title: Watching
---
# Watching
-* TOC
{:toc}
Watching a Repository registers the user to receive notifications on new
@@ -21,7 +20,7 @@ legacy "watcher" endpoints continue to provide starring data.
To provide access to watching data, the v3 Watcher API uses the "subscription"
endpoints described below. Check out the [Watcher API Change
-post](/changes/2012-9-5-watcher-api/) for more details.
+post](/changes/2012-09-05-watcher-api/) for more details.
## List watchers
@@ -36,7 +35,7 @@ post](/changes/2012-9-5-watcher-api/) for more details.
List repositories being watched by a user.
- GET /users/:user/subscriptions
+ GET /users/:username/subscriptions
List repositories being watched by the authenticated user.
@@ -66,11 +65,16 @@ List repositories being watched by the authenticated user.
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`subscribed`|`boolean`| Determines if notifications should be received from this repository.
`ignored`|`boolean`| Determines if all notifications should be blocked from this repository.
+{{#tip}}
+
+If you would like to watch a repository, set `subscribed` to `true`. If you would like to ignore notifications made within a repository, set `ignored` to `true`. If you would like to stop watching a repository, [delete the repository's subscription](#delete-a-repository-subscription) completely.
+
+{{/tip}}
### Response
@@ -79,6 +83,12 @@ Name | Type | Description
## Delete a Repository Subscription
+{{#tip}}
+
+This endpoint should only be used to stop watching a repository. To control whether or not you wish to receive notifications from a repository, [set the repository's subscription manually](#set-a-repository-subscription).
+
+{{/tip}}
+
DELETE /repos/:owner/:repo/subscription
### Response
@@ -101,10 +111,12 @@ Requires for the user to be authenticated.
## Watch a repository (LEGACY)
-Requires for the user to be authenticated.
+Requires the user to be authenticated.
PUT /user/subscriptions/:owner/:repo
+<%= fetch_content(:put_content_length) %>
+
### Response
<%= headers 204 %>
diff --git a/content/v3/auth.md b/content/v3/auth.md
index e5c9a79e6b..ca387bfaa0 100644
--- a/content/v3/auth.md
+++ b/content/v3/auth.md
@@ -1,17 +1,16 @@
---
-title: Other Authentication Methods | GitHub API
+title: Other Authentication Methods
---
# Other Authentication Methods
-* TOC
{:toc}
While the API provides multiple methods for authentication, we strongly
recommend using [OAuth](/v3/oauth/) for production applications. The other
methods provided are intended to be used for scripts or testing (i.e., cases
where full OAuth would be overkill). Third party applications that rely on
-GitHub for authentication should not ask for or collect GitHub credentials.
+{{ site.data.variables.product.product_name }} for authentication should not ask for or collect {{ site.data.variables.product.product_name }} credentials.
Instead, they should use the [OAuth web flow](/v3/oauth).
## Basic Authentication
@@ -20,34 +19,31 @@ The API supports Basic Authentication as defined in
[RFC2617](http://www.ietf.org/rfc/rfc2617.txt) with a few slight differences.
The main difference is that the RFC requires unauthenticated requests to be
answered with `401 Unauthorized` responses. In many places, this would disclose
-the existence of user data. Instead, the GitHub API responds with `404 Not Found`.
+the existence of user data. Instead, the {{ site.data.variables.product.product_name }} API responds with `404 Not Found`.
This may cause problems for HTTP libraries that assume a `401 Unauthorized`
response. The solution is to manually craft the `Authorization` header.
### Via Username and Password
-To use Basic Authentication with the GitHub API, simply send the username and
+To use Basic Authentication with the {{ site.data.variables.product.product_name }} API, simply send the username and
password associated with the account.
For example, if you're accessing the API via [cURL][curl], the following command
-would authenticate you if you replace `` with your GitHub username.
+would authenticate you if you replace `` with your {{ site.data.variables.product.product_name }} username.
(cURL will prompt you to enter the password.)
-
+``` command-line
+$ curl -u username {{ site.data.variables.product.api_url_pre }}/user
+```
### Via OAuth Tokens
-Alternatively, you can authenticate using [personal access
-tokens][personal-access-tokens] or OAuth tokens. To do so, provide the token as
-the username and provide a blank password or a password of `x-oauth-basic`. If
-you're accessing the API via cURL, replace `` with your OAuth token in
-the following command:
+Alternatively, you can use [personal access
+tokens][personal-access-tokens] or OAuth tokens instead of your password.
-
+``` command-line
+$ curl -u username:token {{ site.data.variables.product.api_url_pre }}/user
+```
This approach is useful if your tools only support Basic Authentication but you
want to take advantage of OAuth access token security features.
@@ -56,7 +52,7 @@ want to take advantage of OAuth access token security features.
For users with two-factor authentication enabled, Basic Authentication requires
an extra step. When you attempt to authenticate with Basic Authentication, the
-server will respond with a `401` and an `X-GitHub-OTP: required;:2fa-type`
+server will respond with a `401` and an `X-GitHub-OTP: required; :2fa-type`
header. This indicates that a two-factor authentication code is needed (in
addition to the username and password). The `:2fa-type` in this header indicates
whether the account receives its two-factor authentication codes via SMS or via
@@ -68,8 +64,7 @@ Because these authentication codes expire quickly, we recommend using the
Authorizations API to [create an access token][create-access] and using that
token to [authenticate via OAuth][oauth-auth] for most API access.
-Alternately, you can create access tokens from the Personal Access Token
-section of your [application settings page](https://github.com/settings/applications).
+Alternately, you can create access tokens from the Personal Access Token [settings page](https://github.com/settings/tokens).
[create-access]: /v3/oauth_authorizations/#create-a-new-authorization
[curl]: http://curl.haxx.se/
diff --git a/content/v3/changelog.md b/content/v3/changelog.md
index 5852a338a1..9a102517b7 100644
--- a/content/v3/changelog.md
+++ b/content/v3/changelog.md
@@ -2,4 +2,4 @@
title: GitHub API Changelog
---
-The API changelog can now be found on the [homepage](/). Please update your links.
+The API changelog can now be found [here](/changes). Please update your links.
diff --git a/content/v3/emojis.md b/content/v3/emojis.md
index 4f5dc5b3ce..b80e96eb51 100644
--- a/content/v3/emojis.md
+++ b/content/v3/emojis.md
@@ -1,10 +1,10 @@
---
-title: Emojis | GitHub API
+title: Emojis
---
# Emojis
-Lists all the emojis available to use on GitHub.
+Lists all the emojis available to use on {{ site.data.variables.product.product_name }}.
GET /emojis
diff --git a/content/v3/enterprise.md b/content/v3/enterprise.md
new file mode 100644
index 0000000000..2bcd997e44
--- /dev/null
+++ b/content/v3/enterprise.md
@@ -0,0 +1,46 @@
+---
+title: Enterprise
+---
+
+# Enterprise <%= config[:latest_enterprise_version] %>
+
+{:toc}
+
+[GitHub Enterprise](https://enterprise.github.com/) supports the same powerful API available on GitHub.com as well as its own set of API endpoints. You can find a list of these endpoints on the sidebar, with the exception of the [User Administration][] API, which is within its own section.
+
+## Endpoint URLs
+
+All API endpoints—except [Management Console][] API endpoints—are prefixed with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3/
+```
+
+[Management Console][] API endpoints are only prefixed with a hostname:
+
+``` command-line
+http(s)://hostname/
+```
+
+## Authentication
+
+Your Enterprise installation's API endpoints accept [the same authentication methods](http://developer.github.com/v3/#authentication) as the GitHub.com API. Specifically, you can authenticate yourself with **[OAuth tokens][]** (which can be created using the [Authorizations API][]) or **[basic authentication][]**.
+
+Every Enterprise API endpoint is only accessible to GitHub Enterprise site administrators, with the exception of the [Management Console][] API, which is only accessible via the [Management Console password][].
+
+[Authorizations API]: /v3/oauth_authorizations/#create-a-new-authorization
+[OAuth tokens]: /v3/oauth/
+[basic authentication]: /v3/#basic-authentication
+[Management Console]: /v3/enterprise/management_console/
+[User Administration]: /v3/users/administration/
+[Management Console password]: https://help.github.com/enterprise/admin/articles/accessing-the-management-console/
+
+## Releases
+
+The latest release for GitHub Enterprise is <%= config[:versions][0] %>. The GitHub APIs available to this release are located at />.
+
+Documentation for the API that's bundled with the GitHub Enterprise appliance is available for the following releases:
+
+<% config[:versions][1..-1].each do |version| %>
+* [API documentation for <%= version %>](https://developer.github.com/enterprise/<%= version %>/)
+<% end %>
diff --git a/content/v3/enterprise/admin_stats.md b/content/v3/enterprise/admin_stats.md
new file mode 100644
index 0000000000..2b91118bf3
--- /dev/null
+++ b/content/v3/enterprise/admin_stats.md
@@ -0,0 +1,44 @@
+---
+title: Admin Stats
+---
+
+# Admin Stats
+
+{:toc}
+
+The Admin Stats API provides a variety of metrics about your installation. *It is only available to [authenticated](/v3/#authentication) site administrators.* Normal users will receive a `404` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Get statistics
+
+### Request
+
+ GET /enterprise/stats/:type
+
+There are a variety of types to choose from:
+
+Type | Description
+-------------|-------------------------------------
+`issues` | The number of open and closed issues.
+`hooks` | The number of active and inactive hooks.
+`milestones` | The number of open and closed milestones.
+`orgs` | The number of organizations, teams, team members, and disabled organizations.
+`comments` | The number of comments on issues, pull requests, commits, and gists.
+`pages` | The number of GitHub Pages sites.
+`users` | The number of suspended and admin users.
+`gists` | The number of private and public gists.
+`pulls` | The number of merged, mergeable, and unmergeable pull requests.
+`repos` | The number of organization-owned repositories, root repositories, forks, pushed commits, and wikis.
+`all` | All of the statistics listed above.
+
+These statistics are cached and will be updated approximately every 10 minutes.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:admin_stats) %>
diff --git a/content/v3/enterprise/ldap.md b/content/v3/enterprise/ldap.md
new file mode 100644
index 0000000000..b234a5c73b
--- /dev/null
+++ b/content/v3/enterprise/ldap.md
@@ -0,0 +1,79 @@
+---
+title: LDAP
+---
+
+# LDAP
+
+{:toc}
+
+You can use the LDAP API to update account relationships between a GitHub Enterprise user or team and its linked LDAP entry or queue a new synchronization.
+
+With the LDAP mapping endpoints, you're able to update the Distinguished Name (DN) that a user or team maps to. Note that the LDAP endpoints are generally only effective if your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/admin/guides/user-management/using-ldap). As of GitHub Enterprise 2.3.1, the [Update LDAP mapping for a user](#update-ldap-mapping-for-a-user) can be used when LDAP is enabled, even if LDAP Sync is disabled.
+
+## Update LDAP mapping for a user
+
+ PATCH /admin/ldap/users/:username/mapping
+
+### Body parameters
+
+Pass a JSON payload with the new LDAP Distinguished Name.
+
+#### Example
+
+``` json
+'{"ldap_dn": "uid=asdf,ou=users,dc=github,dc=com"}'
+```
+
+### Response
+
+<%= headers 200 %>
+<%= json :ldap_user_update %>
+
+## Sync LDAP mapping for a user
+
+{{#tip}}
+
+Note that this API call does not automatically initiate an LDAP sync. Rather, if a `201` is returned, the sync job is queued successfully, and is performed when the instance is ready.
+
+{{/tip}}
+
+ POST /admin/ldap/users/:username/sync
+
+### Response
+
+<%= headers 201 %>
+<%= json :ldap_sync_confirm %>
+
+## Update LDAP mapping for a team
+
+ PATCH /admin/ldap/teams/:team_id/mapping
+
+### Body parameters
+
+Pass a JSON payload with the new LDAP Distinguished Name.
+
+#### Example
+
+``` json
+'{"ldap_dn": "cn=Enterprise Ops,ou=teams,dc=github,dc=com"}'
+```
+
+### Response
+
+<%= headers 200 %>
+<%= json :ldap_team_update %>
+
+## Sync LDAP mapping for a team
+
+{{#tip}}
+
+Note that this API call does not automatically initiate an LDAP sync. Rather, if a `201` is returned, the sync job is queued successfully, and is performed when the instance is ready.
+
+{{/tip}}
+
+ POST /admin/ldap/teams/:team_id/sync
+
+### Response
+
+<%= headers 201 %>
+<%= json :ldap_sync_confirm %>
diff --git a/content/v3/enterprise/license.md b/content/v3/enterprise/license.md
new file mode 100644
index 0000000000..bdf5ba9d22
--- /dev/null
+++ b/content/v3/enterprise/license.md
@@ -0,0 +1,26 @@
+---
+title: License
+---
+
+# License
+
+{:toc}
+
+The License API provides information on your Enterprise license. *It is only available to [authenticated](/v3/#authentication) site administrators.* Normal users will receive a `404` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Get license information
+
+### Request
+
+ GET /enterprise/settings/license
+
+### Response
+
+<%= headers 200 %>
+<%= json(:licensing) %>
diff --git a/content/v3/enterprise/management_console.md b/content/v3/enterprise/management_console.md
new file mode 100644
index 0000000000..e2915032a7
--- /dev/null
+++ b/content/v3/enterprise/management_console.md
@@ -0,0 +1,286 @@
+---
+title: Management Console
+---
+
+# Management Console
+
+{:toc}
+
+The Management Console API helps you manage your GitHub Enterprise installation.
+
+{{#tip}}
+
+You must explicitly set the port number when making API calls to the Management Console. If SSL is enabled on your Enterprise instance, the port number is `8443`; otherwise, the port number is `8080`.
+
+If you don't want to provide a port number, you'll need to configure your tool to automatically follow redirects.
+
+You may also need to add the [`-k` flag](http://curl.haxx.se/docs/manpage.html#-k) when using `curl`, since GitHub Enterprise uses a self-signed certificate before you [add your own SSL certificate](https://help.github.com/enterprise/admin/guides/installation/dns-hostname-subdomain-isolation-and-ssl/#ssl).
+
+{{/tip}}
+
+## Authentication
+
+You need to pass your [Management Console password](https://help.github.com/enterprise/admin/articles/accessing-the-management-console/) as an authentication token to every Management Console API endpoint except [`/setup/api/start`](#upload-a-license-for-the-first-time).
+
+Use the `api_key` parameter to send this token with each request. For example:
+
+``` command-line
+$ curl -L 'https://hostname:admin_port/setup/api?api_key=your-amazing-password'
+```
+
+You can also use standard HTTP authentication to send this token. For example:
+
+``` command-line
+$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api'
+```
+
+## Upload a license for the first time
+
+When you boot a virtual machine for the first time, you can use the following endpoint to upload a license:
+
+ POST /setup/api/start
+
+Note that you need to POST to [`/setup/api/configure`](#start-a-configuration-process) to start the actual configuration process.
+
+{{#warning}}
+
+When using this endpoint, your Enterprise instance must have a password set. This can be accomplished two ways:
+
+1. If you're working directly with the API before accessing the web interface, you must pass in the password parameter to set your password.
+2. If you set up your instance via the web interface before accessing the API, your calls to this endpoint do not need the password parameter.
+
+{{/warning}}
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`license`|`string` | **Required**. The content of your *.ghl* license file.
+`password`|`string` | You **must** provide a password *only if* you are uploading your license for the first time. If you previously set a password through the web interface, you don't need this parameter.
+`settings`| `string`| Optional path to a JSON file containing your installation settings.
+
+For a list of the available settings, see [the `/setup/api/settings` endpoint](#retrieve-settings).
+
+### Response
+
+``` command-line
+> HTTP/1.1 202 Created
+> Location: http://hostname:admin_port/setup/api/configcheck
+```
+
+### Example
+
+``` command-line
+$ curl -L -X POST 'https://hostname:admin_port/setup/api/start' -F license=@/path/to/github-enterprise.ghl -F "password=your-amazing-password" -F settings=</path/to/settings.json
+```
+
+## Upgrade a license
+
+This API upgrades your license and also triggers the configuration process:
+
+ POST /setup/api/upgrade
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`license`|`string` | The content of your new *.ghl* license file.
+
+### Response
+
+``` command-line
+> HTTP/1.1 202 Accepted
+> Location: http://hostname:admin_port/setup/api/configcheck
+```
+
+### Example
+
+``` command-line
+$ curl -L -X POST 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/upgrade'
+```
+
+## Check configuration status
+
+This endpoint allows you to check the status of the most recent configuration process:
+
+ GET /setup/api/configcheck
+
+Note that you may need to wait several seconds after you start a process before you can
+check its status.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:config_statuses) %>
+
+The different statuses are:
+
+Status | Description
+--------------|----------------------------------
+`PENDING` | The job has not started yet
+`CONFIGURING` | The job is running
+`DONE` | The job has finished correctly
+`FAILED` | The job has finished unexpectedly
+
+### Example
+
+``` command-line
+$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/configcheck'
+```
+
+## Start a configuration process
+
+This endpoint allows you to start a configuration process at any time for your updated settings to take effect:
+
+ POST /setup/api/configure
+
+### Response
+
+``` command-line
+> HTTP/1.1 202 Accepted
+> Location: http://hostname:admin_port/setup/api/configcheck
+```
+
+### Example
+
+``` command-line
+$ curl -L -X POST 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/configure'
+```
+
+## Retrieve settings
+
+ GET /setup/api/settings
+
+### Response
+
+<%= headers 200 %>
+<%= json(:fetch_settings) %>
+
+### Example
+
+``` command-line
+$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings'
+```
+
+## Modify settings
+
+ PUT /setup/api/settings
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`settings`|`string` | **Required**. A JSON string with the new settings.
+
+### Response
+
+``` command-line
+> HTTP/1.1 204 No Content
+```
+
+### Example
+
+``` command-line
+$ curl -L -X PUT 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings' --data-urlencode "settings=`cat /path/to/settings.json`"
+```
+
+## Check maintenance status
+
+Check your installation's maintenance status:
+
+ GET /setup/api/maintenance
+
+### Response
+
+<%= headers 200 %>
+<%= json(:check_maintenance_status) %>
+
+### Example
+
+``` command-line
+$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/maintenance'
+```
+
+## Enable or disable maintenance mode
+
+ POST /setup/api/maintenance
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`maintenance`|`string` | **Required**. A JSON string with the attributes `enabled` and `when`.
+
+The possible values for `enabled` are `true` and `false`. When it's `false`,
+the attribute `when` is ignored and the maintenance mode is turned off. `when` defines the time period when the maintenance was enabled.
+
+The possible values for `when` are `now` or any date parseable by
+[mojombo/chronic](https://github.com/mojombo/chronic).
+
+### Response
+
+<%= headers 200 %>
+<%= json(:set_maintenance_status) %>
+
+### Example
+
+``` command-line
+$ curl -L -X POST 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/maintenance' -d 'maintenance={"enabled":true, "when":"now"}'
+```
+
+## Retrieve authorized SSH keys
+
+ GET /setup/api/settings/authorized-keys
+
+### Response
+
+<%= headers 200 %>
+<%= json(:get_authorized_ssh_keys) %>
+
+### Example
+
+``` command-line
+$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys'
+```
+
+## Add a new authorized SSH key
+
+ POST /setup/api/settings/authorized-keys
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`authorized_key`|`string` | **Required**. The path to the public SSH key.
+
+### Response
+
+<%= headers 201 %>
+<%= json(:get_authorized_ssh_keys) { |h| h.push({"key" => "ssh-rsa AAAAB3NzaC1yc2EAAAAB...", "pretty-print" => "ssh-rsa 01:14:0f:f2:0f:e2:fe:e8:f4:72:62:af:75:f7:1a:88:3e:04:92:64"}); h }%>
+
+### Example
+
+``` command-line
+$ curl -L -X POST 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys' -F authorized_key=@/path/to/key.pub
+```
+
+## Remove an authorized SSH key
+
+ DELETE /setup/api/settings/authorized-keys
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`authorized_key`|`string` | **Required**. The path to the public SSH key.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:get_authorized_ssh_keys) { |h| h.shift; h } %>
+
+### Example
+
+``` command-line
+$ curl -L -X DELETE 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys' -F authorized_key=@/path/to/key.pub
+```
diff --git a/content/v3/enterprise/orgs.md b/content/v3/enterprise/orgs.md
new file mode 100644
index 0000000000..cc6013e48e
--- /dev/null
+++ b/content/v3/enterprise/orgs.md
@@ -0,0 +1,40 @@
+---
+title: Organization Administration
+---
+
+# Organization Administration
+
+{:toc}
+
+The Organization Administration API allows you to create organizations on a GitHub Enterprise appliance. *It is only available to [authenticated](/v3/#authentication) site administrators.* Normal users will receive a `404` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Create an organization
+
+ POST /admin/organizations
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`login`|`string` | **Required.** The organization's username.
+`admin`|`string`| **Required.** The login of the user who will manage this organization.
+`profile_name`|`string` | The organization's display name.
+
+#### Example
+
+<%= json \
+ :login => "github",
+ :profile_name => "GitHub, Inc.",
+ :admin => "monalisaoctocat"
+%>
+
+### Response
+
+<%= headers 201 %>
+<%= json :org %>
diff --git a/content/v3/enterprise/pre_receive_environments.md b/content/v3/enterprise/pre_receive_environments.md
new file mode 100644
index 0000000000..ac12fe2409
--- /dev/null
+++ b/content/v3/enterprise/pre_receive_environments.md
@@ -0,0 +1,193 @@
+---
+title: Pre-receive Environments
+---
+
+# Pre-receive Environments
+
+{{#tip}}
+
+
+
+ APIs for managing pre-receive hooks are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.eye-scream-preview
+
+{{/tip}}
+
+{:toc}
+
+The Pre-receive Environments API allows you to create, list, update and delete environments for pre-receive hooks. *It is only available to [authenticated](/v3/#authentication) site administrators.* Normal users will receive a `404` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Object attributes
+
+### Pre-receive Environment
+
+| Name | Type | Description |
+|-----------------------|-----------|----------------------------------------------------------------------------|
+| `name` | `string` | The name of the environment as displayed in the UI. |
+| `image_url` | `string` | URL to the tarball that will be downloaded and extracted. |
+| `default_environment` | `boolean` | Whether this is the default environment that ships with GitHub Enterprise. |
+| `download` | `object` | This environment's download status. |
+| `hooks_count` | `integer` | The number of pre-receive hooks that use this environment. |
+
+### Pre-receive Environment Download
+
+| Name | Type | Description |
+|-----------------|----------|---------------------------------------------------------|
+| `state` | `string` | The state of the most recent download. |
+| `downloaded_at` | `string` | The time when the most recent download started. |
+| `message` | `string` | On failure, this will have any error messages produced. |
+
+Possible values for `state` are `not_started`, `in_progress`, `success`, `failed`.
+
+
+## Get a single pre-receive environment
+
+ GET /admin/pre-receive-environments/:id
+
+<%= headers 200 %>
+<%= json :pre_receive_environment %>
+
+## List pre-receive environments
+
+ GET /admin/pre_receive_environments
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json :pre_receive_environments %>
+
+## Create a pre-receive environment
+
+ POST /admin/pre_receive_environments
+
+### Parameters
+
+| Name | Type | Description |
+|-------------|----------|-------------------------------------------------------------------------|
+| `name` | `string` | **Required**. The new pre-receive environment's name. |
+| `image_url` | `string` | **Required**. URL from which to download a tarball of this environment. |
+
+<%= json \
+ :name => 'DevTools Hook Env',
+ :image_url => 'https://my_file_server/path/to/devtools_env.tar.gz'
+%>
+
+### Response
+
+<%= headers 201 %>
+<%= json :pre_receive_environment_create %>
+
+## Edit a pre-receive environment
+
+ PATCH /admin/pre_receive_environments/:id
+
+### Parameters
+
+| Name | Type | Description |
+|-------------|----------|-----------------------------------------------------------|
+| `name` | `string` | This pre-receive environment's new name. |
+| `image_url` | `string` | URL from which to download a tarball of this environment. |
+
+### Response
+<%= headers 200 %>
+<%= json :pre_receive_environment %>
+
+#### Client Errors
+
+If you attempt to modify the default environment, you will get a response like this:
+
+<%= headers 422 %>
+<%=
+ json :message => "Validation Failed",
+ :errors => [{
+ :resource => :PreReceiveEnvironment,
+ :code => :custom,
+ :message => 'Cannot modify or delete the default environment'
+ }]
+%>
+
+## Delete a pre-receive environment
+
+ DELETE /admin/pre_receive_environments/:id
+
+### Response
+
+<%= headers 204 %>
+
+#### Client Errors
+
+If you attempt to delete an environment that cannot be deleted, you will get a response like this:
+
+<%= headers 422 %>
+<%=
+ json :message => "Validation Failed",
+ :errors => [{
+ :resource => :PreReceiveEnvironment,
+ :code => :custom,
+ :message => 'Cannot modify or delete the default environment'
+ }]
+%>
+
+The possible error messages are:
+
+- _Cannot modify or delete the default environment_
+- _Cannot delete environment that has hooks_
+- _Cannot delete environment when download is in progress_
+
+## Get a pre-receive environment's download status
+
+In addition to seeing the download status at the `/admin/pre-receive-environments/:id`, there is also a separate endpoint for just the status.
+
+ GET /admin/pre-receive-environments/:id/downloads/latest
+
+<%= headers 200 %>
+<%= json :pre_receive_environment_download_2 %>
+
+### Object attributes
+
+| Name | Type | Description |
+|-----------------|----------|---------------------------------------------------------|
+| `state` | `string` | The state of the most recent download. |
+| `downloaded_at` | `string` | The time when the most recent download started. |
+| `message` | `string` | On failure, this will have any error messages produced. |
+
+Possible values for `state` are `not_started`, `in_progress`, `success`, `failed`.
+
+## Trigger a pre-receive environment download
+
+Triggers a new download of the environment tarball from the environment's `image_url`. When the download is finished, the newly downloaded tarball will overwrite the existing environment.
+
+ POST /admin/pre_receive_environments/:id/downloads
+
+### Response
+
+<%= headers 202 %>
+<%= json :pre_receive_environment_download %>
+
+#### Client Errors
+
+If a download cannot be triggered, you will get a reponse like this:
+
+<%= headers 422 %>
+<%=
+ json :message => "Validation Failed",
+ :errors => [{
+ :resource => :PreReceiveEnvironment,
+ :code => :custom,
+ :message => 'Can not start a new download when a download is in progress'
+ }]
+%>
+
+The possible error messages are:
+
+- _Cannot modify or delete the default environment_
+- _Can not start a new download when a download is in progress_
+
diff --git a/content/v3/enterprise/pre_receive_hooks.md b/content/v3/enterprise/pre_receive_hooks.md
new file mode 100644
index 0000000000..876f242bbd
--- /dev/null
+++ b/content/v3/enterprise/pre_receive_hooks.md
@@ -0,0 +1,110 @@
+---
+title: Pre-receive Hooks
+---
+
+# Pre-receive Hooks
+
+{{#tip}}
+
+
+
+ APIs for managing pre-receive hooks are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.eye-scream-preview
+
+{{/tip}}
+
+{:toc}
+
+The Pre-receive Hooks API allows you to create, list, update and delete
+pre-receive hooks. *It is only available to
+[authenticated](/v3/#authentication) site administrators.* Normal users
+will receive a `404` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Object attributes
+
+### Pre-receive Hook
+
+| Name | Type | Description |
+|----------------------------------|-----------|-----------------------------------------------------------------|
+| `name` | `string` | The name of the hook. |
+| `script` | `string` | The script that the hook runs. |
+| `script_repository` | `object` | The GitHub repository where the script is kept. |
+| `environment` | `object` | The pre-receive environment where the script is executed. |
+| `enforcement` | `string` | The state of enforcement for this hook. |
+| `allow_downstream_configuration` | `boolean` | Whether enforcement can be overridden at the org or repo level. |
+
+Possible values for *enforcement* are `enabled`, `disabled` and`testing`. `disabled` indicates the pre-receive hook will not run. `enabled` indicates it will run and reject
+any pushes that result in a non-zero status. `testing` means the script will run but will not cause any pushes to be rejected.
+
+## Get a single pre-receive hook
+
+ GET /admin/pre-receive-hooks/:id
+
+<%= headers 200 %> <%= json :pre_receive_hook %>
+
+## List pre-receive hooks
+
+ GET /admin/pre-receive-hooks
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json :pre_receive_hooks %>
+
+## Create a pre-receive hook
+
+ POST /admin/pre-receive-hooks
+
+### Parameters
+
+| Name | Type | Description |
+|----------------------------------|-----------|----------------------------------------------------------------------------------|
+| `name` | `string` | **Required** The name of the hook. |
+| `script` | `string` | **Required** The script that the hook runs. |
+| `script_repository` | `object` | **Required** The GitHub repository where the script is kept. |
+| `environment` | `object` | **Required** The pre-receive environment where the script is executed. |
+| `enforcement` | `string` | The state of enforcement for this hook. default: `disabled` |
+| `allow_downstream_configuration` | `boolean` | Whether enforcement can be overridden at the org or repo level. default: `false` |
+
+<%= json \
+ :name => "Check Commits",
+ :script => "scripts/commit_check.sh",
+ :enforcement => "disabled",
+ :allow_downstream_configuration => false,
+ :script_repository => { :full_name => "DevIT/hooks" },
+ :environment => { :id => 2 }
+%>
+
+### Response
+<%= headers 201 %>
+<%= json :pre_receive_hook %>
+
+## Edit a pre-receive hook
+
+ PATCH /admin/pre_receive_hooks/:id
+
+<%= json \
+ :name => "Check Commits",
+ :environment => { :id => 1 },
+ :allow_downstream_configuration => true
+%>
+
+### Response
+<%= headers 200 %>
+<%= json :pre_receive_hook_update %>
+
+## Delete a pre-receive hook
+
+ DELETE /admin/pre_receive_hooks/:id
+
+### Response
+
+<%= headers 204 %>
diff --git a/content/v3/enterprise/search_indexing.md b/content/v3/enterprise/search_indexing.md
new file mode 100644
index 0000000000..d62fd98056
--- /dev/null
+++ b/content/v3/enterprise/search_indexing.md
@@ -0,0 +1,48 @@
+---
+title: Search Indexing
+---
+
+# Search Indexing
+
+{:toc}
+
+The Search Indexing API allows you to queue up a variety of search indexing tasks. *It is only available to [authenticated](/v3/#authentication) site administrators.* Normal users will receive a `404` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Queue an indexing job
+
+ POST /staff/indexing_jobs
+
+### Input
+
+Name | Type | Description
+--------|---------|--------------
+`target`|`string` | **Required**. A string representing the item to index.
+
+You can index the following targets (replace `:owner` with the name of a user or organization account and `:repository` with the name of a repository):
+
+Target | Description
+----------------------------|---------------------------------------------------------------------
+`:owner` | A user or organization account.
+`:owner/:repository` | A repository.
+`:owner/*` | All of a user or organization's repositories.
+`:owner/:repository/issues` | All the issues in a repository.
+`:owner/*/issues` | All the issues in all of a user or organization's repositories.
+`:owner/:repository/code` | All the source code in a repository.
+`:owner/*/code` | All the source code in all of a user or organization's repositories.
+
+### Example
+
+``` command-line
+$ curl -u jwatson -X POST -H "Content-Type: application/json" -d '{"target": "kansaichris/japaning"}' "http://hostname/api/v3/staff/indexing_jobs"
+```
+
+### Response
+
+<%= headers 202 %>
+<%= json(:indexing_success) %>
diff --git a/content/v3/gists.md b/content/v3/gists.md
index 058f8dfdf9..0f73102306 100644
--- a/content/v3/gists.md
+++ b/content/v3/gists.md
@@ -1,10 +1,9 @@
---
-title: Gists | GitHub API
+title: Gists
---
# Gists
-* TOC
{:toc}
## Authentication
@@ -15,21 +14,57 @@ You can read public gists and create them for anonymous users without a token; h
The API will return a 401 "Bad credentials" response if the gists scope was given to the application but the credentials are invalid. -->
-## List gists
+## Truncation
-List a user's gists:
+The Gist API provides up to one megabyte of content for each file in the gist. Each file returned for a gist through the API has a key called `truncated`. If `truncated` is `true`, the file is too large and only a portion of the contents were returned in `content`.
- GET /users/:user/gists
+If you need the full contents of the file, you can make a `GET` request to the URL specified by `raw_url`. Be aware that for files larger than ten megabytes, you'll need to clone the gist via the URL provided by `git_pull_url`.
+
+In addition to a specific file's contents being truncated, the entire files list may be truncated if the total number exceeds 300 files. If the top level `truncated` key is `true`, only the first 300 files have been returned in the files list. If you need to fetch all of the gist's files, you'll need to clone the gist via the URL provided by `git_pull_url`.
+
+## List a user's gists
+
+List public gists for the specified user:
+
+ GET /users/:username/gists
List the authenticated user's gists or if called anonymously, this will
return all public gists:
GET /gists
-List all public gists:
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`since`|`string` | A timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Only gists updated at or after this time are returned.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:gist) { |h| [h] } %>
+
+## List all public gists
+
+List all public gists sorted by most recently updated to least recently updated.
+
+Note: With [pagination](/v3/#pagination), you can fetch up to 3000 gists. For example, you can fetch 100 pages with 30 gists per page or 30 pages with 100 gists per page.
GET /gists/public
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`since`|`string` | A timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`. Only gists updated at or after this time are returned.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:gist) { |h| [h] } %>
+
+## List starred gists
+
List the authenticated user's starred gists:
GET /gists/starred
@@ -49,17 +84,22 @@ Name | Type | Description
GET /gists/:id
-### Response
+
-
+### Response
<%= headers 200 %>
<%= json :full_gist %>
+## Get a specific revision of a gist
+
+ GET /gists/:id/:sha
+
+### Response
+
+<%= headers 200 %>
+<%= json :full_gist_version %>
+
## Create a gist
POST /gists
@@ -68,11 +108,11 @@ Name | Type | Description
Name | Type | Description
-----|------|--------------
-`files`|`hash` | **Required**. Files that make up this gist.
+`files`|`object` | **Required**. Files that make up this gist.
`description`|`string` | A description of the gist.
`public`|`boolean` | Indicates whether the gist is public. Default: `false`
-The keys in the `files` hash are the `string` filename, and the value is another `hash` with a key of `content`, and a value of the file contents. For example:
+The keys in the `files` object are the `string` filename, and the value is another `object` with a key of `content`, and a value of the file contents. For example:
<%= json \
:description => "the description for this gist",
@@ -82,12 +122,15 @@ The keys in the `files` hash are the `string` filename, and the value is another
}
%>
-_Note:_ Don't name your files "gistfile" with a numerical suffix. This is the
-format of the automatic naming scheme that Gist uses internally.
+{{#tip}}
+
+**Note:** Don't name your files "gistfile" with a numerical suffix. This is the format of the automatic naming scheme that Gist uses internally.
+
+{{/tip}}
### Response
-<%= headers 201, :Location => "https://api.github.com/gists/1" %>
+<%= headers 201, :Location => get_resource(:full_gist)['url'] %>
<%= json :full_gist %>
## Edit a gist
@@ -99,11 +142,11 @@ format of the automatic naming scheme that Gist uses internally.
Name | Type | Description
-----|------|--------------
`description`|`string` | A description of the gist.
-`files`|`hash` | Files that make up this gist.
+`files`|`object` | Files that make up this gist.
`content`|`string` | Updated file contents.
`filename`|`string` | New name for this file.
-The keys in the `files` hash are the `string` filename. The value is another `hash` with a key of `content` (indicating the new contents), or `filename` (indicating the new filename). For example:
+The keys in the `files` object are the `string` filename. The value is another `object` with a key of `content` (indicating the new contents), or `filename` (indicating the new filename). For example:
<%= json \
:description => "the description for this gist",
@@ -114,9 +157,11 @@ The keys in the `files` hash are the `string` filename. The value is another `ha
"delete_this_file.txt" => nil,
} %>
-NOTE: All files from the previous version of the gist are carried over by
-default if not included in the hash. Deletes can be performed by
-including the filename with a `null` hash.
+{{#tip}}
+
+Note: All files from the previous version of the gist are carried over by default if not included in the object. Deletes can be performed by including the filename with a null object.
+
+{{/tip}}
### Response
@@ -124,10 +169,22 @@ including the filename with a `null` hash.
<%= headers 200 %>
<%= json :full_gist %>
+
+## List gist commits
+
+ GET /gists/:id/commits
+
+### Response
+
+<%= headers 200, :pagination => { :next => 'https://api.github.com/resource?page=2' } %>
+<%= json(:gist_history) %>
+
## Star a gist
PUT /gists/:id/star
+<%= fetch_content(:put_content_length) %>
+
### Response
<%= headers 204 %>
@@ -156,13 +213,26 @@ including the filename with a `null` hash.
POST /gists/:id/forks
-**Note**: This was previously `/gists/:id/fork`
+{{#tip}}
+
+**Note**: This was previously `/gists/:id/fork`.
+
+{{/tip}}
### Response
-<%= headers 201, :Location => "https://api.github.com/gists/2" %>
+<%= headers 201, :Location => get_resource(:gist)['url'] %>
<%= json(:gist) %>
+## List gist forks
+
+ GET /gists/:id/forks
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:gist_forks) %>
+
## Delete a gist
DELETE /gists/:id
@@ -172,3 +242,11 @@ including the filename with a `null` hash.
<%= headers 204 %>
[1]: /v3/oauth/#scopes
+
+## Custom media types
+
+The following media types are supported when fetching gist contents. You can read more about the
+use of media types in the API [here](/v3/media/).
+
+ application/vnd.github.VERSION.raw
+ application/vnd.github.VERSION.base64
diff --git a/content/v3/gists/comments.md b/content/v3/gists/comments.md
index 0a53cfa580..91249c09f6 100644
--- a/content/v3/gists/comments.md
+++ b/content/v3/gists/comments.md
@@ -1,10 +1,9 @@
---
-title: Gist Comments | GitHub API
+title: Gist Comments
---
# Comments
-* TOC
{:toc}
Gist Comments use [these custom media types](#custom-media-types).
@@ -17,7 +16,7 @@ You can read more about the use of media types in the API
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:gist_comment) { |h| [h] } %>
## Get a single comment
@@ -35,7 +34,7 @@ You can read more about the use of media types in the API
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`body`|`string` | **Required**. The comment text.
@@ -44,8 +43,7 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location => "https://api.github.com/gists/comments/1" %>
+<%= headers 201, :Location => get_resource(:gist_comment)['url'] %>
<%= json :gist_comment %>
## Edit a comment
@@ -54,7 +52,7 @@ Name | Type | Description
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`body`|`string` | **Required**. The comment text.
diff --git a/content/v3/git.md b/content/v3/git.md
index 8259eeda3d..a7ec1bd618 100644
--- a/content/v3/git.md
+++ b/content/v3/git.md
@@ -1,11 +1,11 @@
---
-title: Git Data | GitHub API
+title: Git Data
---
# Git Data
The Git Database API gives you access to read and write raw Git objects
-to your Git database on GitHub and to list and update your references
+to your Git database on {{ site.data.variables.product.product_name }} and to list and update your references
(branch heads and tags).
This basically allows you to reimplement a lot of Git functionality over
@@ -20,7 +20,7 @@ Support](https://github.com/contact?form[subject]=Commits API) if this response

For more information on the Git object database, please read the
-[Git Internals](http://git-scm.com/book/en/Git-Internals) chapter of
+[Git Internals](http://git-scm.com/book/en/v1/Git-Internals) chapter of
the Pro Git book.
As an example, if you wanted to commit a change to a file in your
diff --git a/content/v3/git/blobs.md b/content/v3/git/blobs.md
index 7238820939..df84b5c41f 100644
--- a/content/v3/git/blobs.md
+++ b/content/v3/git/blobs.md
@@ -1,17 +1,11 @@
---
-title: Git Blobs | GitHub API
+title: Git Blobs
---
# Blobs
-* TOC
{:toc}
-Since blobs can be any arbitrary binary data, the input and responses
-for the blob API takes an encoding parameter that can be either `utf-8`
-or `base64`. If your data cannot be losslessly sent as a UTF-8 string,
-you can base64 encode it.
-
Blobs leverage [these custom media types](#custom-media-types). You can
read more about the use of media types in the API [here](/v3/media/).
@@ -19,6 +13,8 @@ read more about the use of media types in the API [here](/v3/media/).
GET /repos/:owner/:repo/git/blobs/:sha
+The `content` in the response will always be Base64 encoded.
+
*Note*: This API supports blobs up to 100 megabytes in size.
### Response
@@ -30,14 +26,20 @@ read more about the use of media types in the API [here](/v3/media/).
POST /repos/:owner/:repo/git/blobs
-### Input
+### Parameters
+
+Name | Type | Description
+-----|------|-------------
+`content`|`string` | **Required**. The new blob's content.
+`encoding`|`string` | The encoding used for `content`. Currently, `"utf-8"` and `"base64"` are supported. Default: `"utf-8"`.
+
+### Example Input
<%= json :content => "Content of the blob", :encoding => "utf-8" %>
### Response
-<%= headers 201,
- :Location => "https://api.github.com/repos/octocat/example/git/blobs/3a0f86fb8db8eea7ccbb9a95f325ddbedfb25e15" %>
+<%= headers 201, :Location => get_resource(:blob_after_create)['url'] %>
<%= json :blob_after_create %>
## Custom media types
diff --git a/content/v3/git/commits.md b/content/v3/git/commits.md
index 6bfb8cdf2c..69a0da52fe 100644
--- a/content/v3/git/commits.md
+++ b/content/v3/git/commits.md
@@ -1,10 +1,9 @@
---
-title: Git Commits | GitHub API
+title: Git Commits
---
# Commits
-* TOC
{:toc}
## Get a Commit
@@ -31,20 +30,20 @@ Name | Type | Description
### Optional Parameters
-You can provide an additional `commiter` parameter, which is a hash containing
+You can provide an additional `committer` parameter, which is an object containing
information about the committer. Or, you can provide an `author` parameter, which
-is a hash containing information about the author.
+is an object containing information about the author.
The `committer` section is optional and will be filled with the `author`
data if omitted. If the `author` section is omitted, it will be filled
in with the authenticated user's information and the current date.
-Both the `author` and `commiter` parameters have the same keys:
+Both the `author` and `committer` parameters have the same keys:
Name | Type | Description
-----|------|-------------
-`name`|`string` | The name of the author (or commiter) of the commit
-`email`|`string` | The email of the author (or commiter) of the commit
+`name`|`string` | The name of the author (or committer) of the commit
+`email`|`string` | The email of the author (or committer) of the commit
`date`|`string` | Indicates when this commit was authored (or committed). This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`.
### Example Input
@@ -58,6 +57,61 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location => "https://api.github.com/repos/octocat/Hello-World/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd" %>
+<%= headers 201, :Location => get_resource(:new_commit)['url'] %>
<%= json :new_commit %>
+
+{% if page.version == 'dotcom' %}
+
+## Commit signature verification
+
+{{#tip}}
+
+Commit response objects including signature verification data are currently available for developers to preview.
+During the preview period, the object formats may change without advance notice.
+Please see the [blog post](/changes/2016-04-04-git-signing-api-preview) for full details.
+
+To receive signature verification data in commit objects you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.cryptographer-preview
+
+{{/tip}}
+
+ GET /repos/:owner/:repo/git/commits/:sha
+
+### Response
+
+<%= headers 200 %>
+<%= json(:signed_git_commit) %>
+
+### The `verification` object
+
+The response will include a `verification` field whose value is an object describing the result of verifying the commit's signature. The following fields are included in the `verification` object:
+
+Name | Type | Description
+-----|------|--------------
+`verified`|`boolean` | Does GitHub consider the signature in this commit to be verified?
+`reason`|`string` | The reason for `verified` value. Possible values and their meanings are enumerated in the table below.
+`signature`|`string` | The signature that was extracted from the commit.
+`payload`|`string` | The value that was signed.
+
+#### The `reason` field
+
+The following are possible `reason`s that may be included in the `verification` object:
+
+Value | Description
+------|------------
+`expired_key` | The key that made the signature is expired.
+`not_signing_key` | The "signing" flag is not among the usage flags in the GPG key that made the signature.
+`gpgverify_error` | There was an error communicating with the signature-verification service.
+`gpgverify_unavailable` | The signature-verification service is currently unavailable.
+`unsigned` | The object does not include a signature.
+`unknown_signature_type` | A non-PGP signature was found in the commit.
+`no_user` | No user was associated with the `committer` email address in the commit.
+`unverified_email` | The `committer` email address in the commit was associated with a user, but the email address is not verified on her/his account.
+`bad_email` | The `committer` email address in the commit is not included in the identities of the PGP key that made the signature.
+`unknown_key` | The key that made the signature has not been registered with any user's account.
+`malformed_signature` | There was an error parsing the signature.
+`invalid` | The signature could not be cryptographically verified using the key whose key-id was found in the signature.
+`valid` | None of the above errors applied, so the signature is considered to be verified.
+
+{% endif %}
diff --git a/content/v3/git/refs.md b/content/v3/git/refs.md
index d7707ec33d..ef4a444d92 100644
--- a/content/v3/git/refs.md
+++ b/content/v3/git/refs.md
@@ -1,10 +1,9 @@
---
-title: Git Refs | GitHub API
+title: Git Refs
---
# References
-* TOC
{:toc}
## Get a Reference
@@ -15,11 +14,26 @@ The `ref` in the URL must be formatted as `heads/branch`, not just `branch`. For
GET /repos/:owner/:repo/git/refs/heads/skunkworkz/featureA
-### Response
-
<%= headers 200 %>
<%= json :ref %>
+If the `ref` doesn't exist in the repository, but existing refs start with `ref`
+they will be returned as an array. For example, a call to get the data for a
+branch named `feature`, which doesn't exist, would return head refs
+including `featureA` and `featureB` which do.
+
+ GET /repos/:owner/:repo/git/refs/heads/feature
+
+<%= headers 200 %>
+<%= json :refs_matching %>
+
+If the `ref` doesn't match an existing ref or any prefixes a 404 will be returned.
+
+ GET /repos/:owner/:repo/git/refs/heads/feature-branch-that-no-longer-exists
+
+<%= headers 404 %>
+<%= json :refs_not_found %>
+
## Get all References
GET /repos/:owner/:repo/git/refs
@@ -36,7 +50,7 @@ references, you can call:
For a full refs listing, you'll get something that looks like:
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json :refs %>
@@ -48,8 +62,8 @@ For a full refs listing, you'll get something that looks like:
Name | Type | Description
-----|------|--------------
-`ref`|`type`| The name of the fully qualified reference (ie: `refs/heads/master`). If it doesn't start with 'refs' and have at least two slashes, it will be rejected.
-`sha`|`type`| The SHA1 value to set this reference to
+`ref`|`type`| **Required**. The name of the fully qualified reference (ie: `refs/heads/master`). If it doesn't start with 'refs' and have at least two slashes, it will be rejected.
+`sha`|`type`| **Required**. The SHA1 value to set this reference to
### Input
@@ -59,8 +73,7 @@ Name | Type | Description
### Response
-<%= headers 201, \
- :Location => "https://api.github.com/repos/octocat/Hello-World/git/refs/heads/featureA" %>
+<%= headers 201, :Location => get_resource(:ref)['url'] %>
<%= json :ref %>
## Update a Reference
@@ -71,7 +84,7 @@ Name | Type | Description
Name | Type | Description
-----|------|--------------
-`sha`|`type`| The SHA1 value to set this reference to
+`sha`|`type`| **Required**. The SHA1 value to set this reference to
`force`|`boolean`| Indicates whether to force the update or to make sure the update is a fast-forward update. Leaving this out or setting it to `false` will make sure you're not overwriting work. Default: `false`
diff --git a/content/v3/git/tags.md b/content/v3/git/tags.md
index 1b51ae7107..b0605da270 100644
--- a/content/v3/git/tags.md
+++ b/content/v3/git/tags.md
@@ -1,10 +1,9 @@
---
-title: Git Tags | GitHub API
+title: Git Tags
---
# Tags
-* TOC
{:toc}
This tags API only deals with tag objects - so only annotated tags, not
@@ -39,9 +38,9 @@ Name | Type | Description
`message`|`string`| The tag message
`object`|`string`| The SHA of the git object this is tagging
`type`|`string`| The type of the object we're tagging. Normally this is a `commit` but it can also be a `tree` or a `blob`.
-`tagger`|`hash`| A hash with information about the individual creating the tag.
+`tagger`|`object`| An object with information about the individual creating the tag.
-The `tagger` hash contains the following keys:
+The `tagger` object contains the following keys:
Name | Type | Description
-----|------|--------------
@@ -62,6 +61,61 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location => "https://api.github.com/repos/octocat/Hello-World/git/tags/940bd336248efae0f9ee5bc7b2d5c985887b16ac" %>
+<%= headers 201, :Location => get_resource(:gittag)['url'] %>
<%= json :gittag %>
+
+{% if page.version == 'dotcom' %}
+
+## Tag signature verification
+
+{{#tip}}
+
+Tag response objects including signature verification data are currently available for developers to preview.
+During the preview period, the object formats may change without advance notice.
+Please see the [blog post](/changes/2016-04-04-git-signing-api-preview) for full details.
+
+To receive signature verification data in tag objects you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.cryptographer-preview
+
+{{/tip}}
+
+ GET /repos/:owner/:repo/git/tags/:sha
+
+### Response
+
+<%= headers 200 %>
+<%= json(:signed_gittag) %>
+
+### The `verification` object
+
+The response will include a `verification` field whose value is an object describing the result of verifying the tag's signature. The following fields are included in the `verification` object:
+
+Name | Type | Description
+-----|------|--------------
+`verified`|`boolean` | Does GitHub consider the signature in this tag to be verified?
+`reason`|`string` | The reason for `verified` value. Possible values and their meanings are enumerated in the table below.
+`signature`|`string` | The signature that was extracted from the tag.
+`payload`|`string` | The value that was signed.
+
+#### The `reason` field
+
+The following are possible `reason`s that may be included in the `verification` object:
+
+Value | Description
+------|------------
+`expired_key` | The key that made the signature is expired.
+`not_signing_key` | The "signing" flag is not among the usage flags in the GPG key that made the signature.
+`gpgverify_error` | There was an error communicating with the signature-verification service.
+`gpgverify_unavailable` | The signature-verification service is currently unavailable.
+`unsigned` | The object does not include a signature.
+`unkown_signature_type` | A non-PGP signature was found in the tag.
+`no_user` | No user was associated with the `tagger` email address in the tag.
+`unverified_email` | The `tagger` email address in the tag was associated with a user, but the email address is not verified on her/his account.
+`bad_email` | The `tagger` email address in the tag is not included in the identities of the PGP key that made the signature.
+`unknown_key` | The key that made the signature has not been registered with any user's account.
+`malformed_signature` | There was an error parsing the signature.
+`invalid` | The signature could not be cryptographically verified using the key whose key-id was found in the signature.
+`valid` | None of the above errors applied, so the signature is considered to be verified.
+
+{% endif %}
diff --git a/content/v3/git/trees.md b/content/v3/git/trees.md
index dac6e4366c..485e622ada 100644
--- a/content/v3/git/trees.md
+++ b/content/v3/git/trees.md
@@ -1,10 +1,9 @@
---
-title: Git Trees | GitHub API
+title: Git Trees
---
# Trees
-* TOC
{:toc}
## Get a Tree
@@ -13,6 +12,12 @@ title: Git Trees | GitHub API
### Response
+{{#tip}}
+
+If `truncated` is `true`, the number of items in the `tree` array exceeded our maximum limit. If you need to fetch more items, you can clone the repository and iterate over the Git data locally.
+
+{{/tip}}
+
<%= headers 200 %>
<%= json :tree %>
@@ -22,6 +27,12 @@ title: Git Trees | GitHub API
### Response
+{{#tip}}
+
+If `truncated` is `true`, the number of items in the `tree` array exceeded our maximum limit. If you need to fetch more items, use the non-recursive method of fetching trees, and fetch one sub-tree at a time.
+
+{{/tip}}
+
<%= headers 200 %>
<%= json :tree_extra %>
@@ -38,7 +49,7 @@ a new tree out.
Name | Type | Description
-----|------|--------------
-`tree`|`array` of `hash`es | **Required**. Objects (of `path`, `mode`, `type`, and `sha`) specifying a tree structure
+`tree`|`array` of `object`s | **Required**. Objects (of `path`, `mode`, `type`, and `sha`) specifying a tree structure
`base_tree`| `string` | The SHA1 of the tree you want to update with new data. If you don't set this, the commit will be created on top of everything; however, it will only contain your change, the rest of your files will show up as deleted.
The `tree` parameter takes the following keys:
@@ -49,7 +60,7 @@ Name | Type | Description
`mode`|`string`| The file mode; one of `100644` for file (blob), `100755` for executable (blob), `040000` for subdirectory (tree), `160000` for submodule (commit), or `120000` for a blob that specifies the path of a symlink
`type`| `string`| Either `blob`, `tree`, or `commit`
`sha`|`string`| The SHA1 checksum ID of the object in the tree
-`content`|`string` | The content you want this file to have. GitHub will write this blob out and use that SHA for this entry. Use either this, or `tree.sha`.
+`content`|`string` | The content you want this file to have. {{ site.data.variables.product.product_name }} will write this blob out and use that SHA for this entry. Use either this, or `tree.sha`.
### Input
@@ -64,6 +75,5 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location => "https://api.github.com/repos/octocat/Hello-World/trees/cd8274d15fa3ae2ab983129fb037999f264ba9a7" %>
+<%= headers 201, :Location => get_resource(:tree_new)['url'] %>
<%= json :tree_new %>
diff --git a/content/v3/gitignore.md b/content/v3/gitignore.md
index bdd18a6e78..66fc12632d 100644
--- a/content/v3/gitignore.md
+++ b/content/v3/gitignore.md
@@ -1,15 +1,14 @@
---
-title: Gitignore | GitHub API
+title: Gitignore
---
# Gitignore
-* TOC
{:toc}
-When you create a new GitHub repository via the API, you can specify a
+When you create a new {{ site.data.variables.product.product_name }} repository via the API, you can specify a
[.gitignore template][what-is] to apply to the repository upon creation. The
-.gitignore Templates API lists and fetches templates from the [GitHub .gitignore repository][templates-repo].
+.gitignore Templates API lists and fetches templates from the [{{ site.data.variables.product.product_name }} .gitignore repository][templates-repo].
## Listing available templates
diff --git a/content/v3/issues.md b/content/v3/issues.md
index 0645aeadd2..59e7f99a29 100644
--- a/content/v3/issues.md
+++ b/content/v3/issues.md
@@ -1,10 +1,9 @@
---
-title: Issues | GitHub API
+title: Issues
---
# Issues
-* TOC
{:toc}
Issues use [these custom media types](#custom-media-types). You can
@@ -12,17 +11,25 @@ read more about the use of media types in the API [here](/v3/media/).
## List issues
-List all issues across all the authenticated user's visible repositories
+<%= fetch_content(:prs_as_issues) %>
+
+List all issues **assigned** to the authenticated user across all visible repositories
including owned repositories, member repositories, and organization
repositories:
GET /issues
-List all issues across owned and member repositories for the authenticated user:
+{{#tip}}
+
+You can use the `filter` query parameter to fetch issues that are not necessarily assigned to you. See the table below for more information.
+
+{{/tip}}
+
+List all issues across owned and member repositories assigned to the authenticated user:
GET /user/issues
-List all issues for a given organization for the authenticated user:
+List all issues for a given organization assigned to the authenticated user:
GET /orgs/:org/issues
@@ -42,17 +49,39 @@ Name | Type | Description
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:issue) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the issue payload is currently available for developers to preview. During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :issue_reaction_summary %>
+{% endif %}
+
## List issues for a repository
+<%= fetch_content(:prs_as_issues) %>
+
GET /repos/:owner/:repo/issues
### Parameters
Name | Type | Description
-----|------|--------------
-`milestone`|`integer` or `string`| If an `integer` is passed, it should refer to a milestone number. If the string `*` is passed, issues with any milestone are accepted. If the string `none` is passed, issues without milestones are returned. Default: `*`
+`milestone`|`integer` or `string`| If an `integer` is passed, it should refer to a milestone by its `number` field. If the string `*` is passed, issues with any milestone are accepted. If the string `none` is passed, issues without milestones are returned.
`state`|`string`| Indicates the state of the issues to return. Can be either `open`, `closed`, or `all`. Default: `open`
-`assignee`|`string`| Can be the name of a user. Pass in `none` for issues with no assigned user, and `*` for issues assigned to any user. Default: `*`
+`assignee`|`string`| Can be the name of a user. Pass in `none` for issues with no assigned user, and `*` for issues assigned to any user.
`creator`|`string`| The user that created the issue.
`mentioned`|`string`| A user that's mentioned in the issue.
`labels`|`string`| A list of comma separated label names. Example: `bug,ui,@high`
@@ -65,8 +94,31 @@ Name | Type | Description
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:issue) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the issue payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :issue_reaction_summary %>
+{% endif %}
+
## Get a single issue
+<%= fetch_content(:prs_as_issues) %>
+
GET /repos/:owner/:repo/issues/:number
### Response
@@ -74,11 +126,26 @@ Name | Type | Description
<%= headers 200 %>
<%= json :full_issue %>
-
-
- Note: Every pull request is an issue, but not every issue is a pull request. When using the v3 media type, if the issue is not a pull request, the response omits the pull_request attribute.
-
-
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the issue payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :issue_reaction_summary %>
+{% endif %}
## Create an issue
@@ -92,9 +159,10 @@ Name | Type | Description
-----|------|--------------
`title`|`string` | **Required**. The title of the issue.
`body`|`string` | The contents of the issue.
-`assignee`|`string` | Login for the user that this issue should be assigned to. _NOTE: Only users with push access can set the assignee for new issues. The assignee is silently dropped otherwise._
-`milestone`|`number` | Milestone to associate this issue with. _NOTE: Only users with push access can set the milestone for new issues. The milestone is silently dropped otherwise._
+`assignee`|`string` | Login for the user that this issue should be assigned to. _NOTE: Only users with push access can set the assignee for new issues. The assignee is silently dropped otherwise. **This field is [deprecated](https://developer.github.com/v3/versions/#v3-deprecations).**_
+`milestone`|`integer` | The `number` of the milestone to associate this issue with. _NOTE: Only users with push access can set the milestone for new issues. The milestone is silently dropped otherwise._
`labels`|`array` of `strings` | Labels to associate with this issue. _NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise._
+`assignees`|`array` of `strings` | Logins for Users to assign to this issue. _NOTE: Only users with push access can set assignees for new issues. Assignees are silently dropped otherwise._
#### Example
@@ -102,15 +170,14 @@ Name | Type | Description
:title => "Found a bug",
:body => "I'm having a problem with this.",
:assignee => "octocat",
+ :assignees => [get_resource(:user)],
:milestone => 1,
- :labels => %w(Label1 Label2)
+ :labels => %w(bug)
%>
### Response
-<%= headers 201,
- :Location =>
-'https://api.github.com/repos/user/repo/issues/1' %>
+<%= headers 201, :Location => get_resource(:full_issue)['url'] %>
<%= json :full_issue %>
## Edit an issue
@@ -123,13 +190,13 @@ Issue owners and users with push access can edit an issue.
Name | Type | Description
-----|------|--------------
-`title`|`string` | **Required**. The title of the issue.
+`title`|`string` | The title of the issue.
`body`|`string` | The contents of the issue.
-`assignee`|`string` | Login for the user that this issue should be assigned to.
+`assignee`|`string` | Login for the user that this issue should be assigned to. **This field is [deprecated](https://developer.github.com/v3/versions/#v3-deprecations).**
`state`|`string` | State of the issue. Either `open` or `closed`.
-`milestone`|`number` | Milestone to associate this issue with. _NOTE: Only users with push access can set the milestone for new issues. The milestone is silently dropped otherwise._
-`labels`|`array` of `strings` | Labels to associate with this issue. Pass one or more Labels to _replace_ the set of Labels on this Issue. Send an empty array (`[]`) to clear all Labels from the Issue. _NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise._
-
+`milestone`|`integer` | The `number` of the milestone to associate this issue with or `null` to remove current. _NOTE: Only users with push access can set the milestone for issues. The milestone is silently dropped otherwise._
+`labels`|`array` of `strings` | Labels to associate with this issue. Pass one or more Labels to _replace_ the set of Labels on this Issue. Send an empty array (`[]`) to clear all Labels from the Issue. _NOTE: Only users with push access can set labels for issues. Labels are silently dropped otherwise._
+`assignees`|`array` of `strings` | Logins for Users to assign to this issue. Pass one or more user logins to _replace_ the set of assignees on this Issue. .Send an empty array (`[]`) to clear all assignees from the Issue. _NOTE: Only users with push access can set assignees for new issues. Assignees are silently dropped otherwise._
#### Example
@@ -137,9 +204,10 @@ Name | Type | Description
:title => "Found a bug",
:body => "I'm having a problem with this.",
:assignee => "octocat",
+ :assignees => [get_resource(:user)],
:milestone => 1,
:state => "open",
- :labels => %w(Label1 Label2)
+ :labels => %w(bug)
%>
### Response
@@ -147,6 +215,63 @@ Name | Type | Description
<%= headers 200 %>
<%= json :full_issue %>
+{% if page.version == 'dotcom' or page.version >= 2.6 %}
+## Lock an issue
+
+{% if page.version == 2.6 %}
+{{#tip}}
+
+
+
+ The API to lock an issue is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2016-02-11-issue-locking-api) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.the-key-preview+json
+
+{{/tip}}
+{% endif %}
+
+Users with push access can lock an issue's conversation.
+
+ PUT /repos/:owner/:repo/issues/:number/lock
+
+<%= fetch_content(:put_content_length) %>
+
+### Response
+
+<%= headers 204 %>
+
+## Unlock an issue
+
+{% if page.version == 2.6 %}
+{{#tip}}
+
+
+
+ The API to unlock an issue is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2016-02-11-issue-locking-api) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.the-key-preview+json
+
+{{/tip}}
+{% endif %}
+
+Users with push access can unlock an issue's conversation.
+
+ DELETE /repos/:owner/:repo/issues/:number/lock
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
+
## Custom media types
These are the supported media types for issues. You can read more about the
diff --git a/content/v3/issues/assignees.md b/content/v3/issues/assignees.md
index 99b34ad9d6..4d0c1a59a0 100644
--- a/content/v3/issues/assignees.md
+++ b/content/v3/issues/assignees.md
@@ -1,22 +1,20 @@
---
-title: Issue Assignees | GitHub API
+title: Issue Assignees
---
# Assignees
-* TOC
{:toc}
## List assignees
-This call lists all the available assignees (owner + collaborators) to which
-issues may be assigned.
+This call lists all the [available assignees][] to which issues may be assigned.
GET /repos/:owner/:repo/assignees
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:user) { |h| [h] } %>
## Check assignee
@@ -35,3 +33,35 @@ If the given `assignee` login belongs to an assignee for the repository, a
Otherwise a `404` status code is returned.
<%= headers 404 %>
+
+[available assignees]: https://help.github.com/articles/assigning-issues-and-pull-requests-to-other-github-users/
+
+## Add assignees to an Issue
+
+This call adds the users passed in the `assignees` key (as their logins) to the issue.
+
+ POST /repos/:owner/:repo/issues/:number/assignees
+
+### Input
+
+<%= json({"assignees" => %w(hubot other_assignee)}) %>
+
+### Response
+
+<%= headers 201 %>
+<%= json :issue_with_assignees %>
+
+## Remove assignees from an Issue
+
+This call removes the users passed in the `assignees` key (as their logins) from the issue.
+
+ DELETE /repos/:owner/:repo/issues/:number/assignees
+
+### Input
+
+<%= json({"assignees" => %w(hubot other_assignee)}) %>
+
+### Response
+
+<%= headers 200 %>
+<%= json :issue_with_assignees %>
diff --git a/content/v3/issues/comments.md b/content/v3/issues/comments.md
index 2d29787ffe..b9d077b4a0 100644
--- a/content/v3/issues/comments.md
+++ b/content/v3/issues/comments.md
@@ -1,10 +1,9 @@
---
-title: Issue Comments | GitHub API
+title: Issue Comments
---
# Comments
-* TOC
{:toc}
The Issue Comments API supports listing, viewing, editing, and creating
@@ -18,11 +17,40 @@ You can read more about the use of media types in the API
GET /repos/:owner/:repo/issues/:number/comments
+Issue Comments are ordered by ascending ID.
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`since`|`string` | Only comments updated at or after this time are returned. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`.
+
### Response
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:issue_comment) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the issue comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :issue_comment_reaction_summary %>
+{% endif %}
+
## List comments in a repository
GET /repos/:owner/:repo/issues/comments
@@ -31,7 +59,7 @@ By default, Issue Comments are ordered by ascending ID.
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`sort`|`string` | Either `created` or `updated`. Default: `created`
`direction`|`string` | Either `asc` or `desc`. Ignored without the `sort` parameter.
@@ -41,7 +69,28 @@ Name | Type | Description
### Response
<%= headers 200 %>
-<%= json(:pull_comment) { |h| [h] } %>
+<%= json(:issue_comment) { |h| [h] } %>
+
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the issue comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :issue_comment_reaction_summary %>
+{% endif %}
## Get a single comment
@@ -49,9 +98,30 @@ Name | Type | Description
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json :issue_comment %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the issue comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :issue_comment_reaction_summary %>
+{% endif %}
+
## Create a comment
POST /repos/:owner/:repo/issues/:number/comments
@@ -63,13 +133,11 @@ Name | Type | Description
`body`|`string` | **Required**. The contents of the comment.
-<%= json :body => "a new comment" %>
+<%= json :body => "Me too" %>
### Response
-<%= headers 201,
- :Location =>
-"https://api.github.com/repos/user/repo/issues/comments/1" %>
+<%= headers 201, :Location => get_resource(:issue_comment)['url'] %>
<%= json :issue_comment %>
## Edit a comment
@@ -78,12 +146,12 @@ Name | Type | Description
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`body`|`string` | **Required**. The contents of the comment.
-<%= json :body => "String" %>
+<%= json :body => "Me too" %>
### Response
diff --git a/content/v3/issues/events.md b/content/v3/issues/events.md
index cc176a36a6..2b40755155 100644
--- a/content/v3/issues/events.md
+++ b/content/v3/issues/events.md
@@ -1,53 +1,119 @@
---
-title: Issue Events | GitHub API
+title: Issue Events
---
# Events
-* TOC
{:toc}
-Records various events that occur around an Issue or Pull Request. This is
+Records various events that occur around an issue or pull request. This is
useful both for display on issue/pull request information pages and also to
determine who should be notified of comments.
### Attributes
-actor
-: Always the User that generated the event.
+
+
id
+
The Integer ID of the event.
-commit_id
-: The String SHA of a commit that referenced this Issue
+
url
+
The API URL for fetching the event.
-event
-: Identifies the actual type of Event that occurred.
+
actor
+
The User object that generated the event.
+
+
commit_id
+
The String SHA of a commit that referenced this Issue
+
+
commit_url
+
The GitHub API link to a commit that referenced this Issue
+
+
event
+
Identifies the actual type of Event that occurred.
+
+
created_at
+
The timestamp indicating when the event occurred.
+
+
label
+
The Label object including `name` and `color` attributes. Only provided for `labeled`
+ and `unlabeled` events.
+
+
assignee
+
The User object which was assigned to (or unassigned from) this Issue. Only provided for 'assigned' and 'unassigned' events.
+
+ {% if page.version == 'dotcom' or page.version > 2.5 %}
+
assigner
+
The User object that performed the assignment (or unassignment) for this Issue. Only provided for 'assigned' and 'unassigned' events.
+ {% endif %}
+
+
milestone
+
The Milestone object including a `title` attribute. Only provided for `milestoned` and
+ `demilestoned` events.
+
+
rename
+
An object containing rename details including `from` and `to` attributes. Only
+ provided for `renamed` events.
+
### Events
-closed
-: The issue was closed by the actor. When the commit_id is present, it
+
+
closed
+
The issue was closed by the actor. When the commit_id is present, it
identifies the commit that closed the issue using "closes / fixes #NN"
- syntax.
+ syntax.
+
+
+
reopened
+
The issue was reopened by the actor.
-reopened
-: The issue was reopened by the actor.
+
subscribed
+
The actor subscribed to receive notifications for an issue.
-subscribed
-: The actor subscribed to receive notifications for an issue.
+
merged
+
The issue was merged by the actor. The `commit_id` attribute is the SHA1 of
+ the HEAD commit that was merged.
-merged
-: The issue was merged by the actor. The `commit_id` attribute is the SHA1 of
- the HEAD commit that was merged.
+
referenced
+
The issue was referenced from a commit message. The `commit_id` attribute is
+ the commit SHA1 of where that happened.
-referenced
-: The issue was referenced from a commit message. The `commit_id` attribute is
- the commit SHA1 of where that happened.
+
mentioned
+
The actor was @mentioned in an issue body.
-mentioned
-: The actor was @mentioned in an issue body.
+
assigned
+
The issue was assigned to the actor.
-assigned
-: The issue was assigned to the actor.
+
unassigned
+
The actor was unassigned from the issue.
+
+
labeled
+
A label was added to the issue.
+
+
unlabeled
+
A label was removed from the issue.
+
+
milestoned
+
The issue was added to a milestone.
+
+
demilestoned
+
The issue was removed from a milestone.
+
+
renamed
+
The issue title was changed.
+
+
locked
+
The issue was locked by the actor.
+
+
unlocked
+
The issue was unlocked by the actor.
+
+
head_ref_deleted
+
The pull request's branch was deleted.
+
+
head_ref_restored
+
The pull request's branch was restored.
+
## List events for an issue
@@ -75,4 +141,3 @@ assigned
<%= headers 200 %>
<%= json :full_issue_event %>
-
diff --git a/content/v3/issues/labels.md b/content/v3/issues/labels.md
index 2fa6022fe2..718a0c6339 100644
--- a/content/v3/issues/labels.md
+++ b/content/v3/issues/labels.md
@@ -1,10 +1,9 @@
---
-title: Issue Labels | GitHub API
+title: Issue Labels
---
# Labels
-* TOC
{:toc}
## List all labels for this repository
@@ -13,7 +12,7 @@ title: Issue Labels | GitHub API
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:label) { |h| [h] } %>
## Get a single label
@@ -31,19 +30,17 @@ title: Issue Labels | GitHub API
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`name`|`string` | **Required**. The name of the label.
`color`|`string` |**Required**. A 6 character hex code, without the leading `#`, identifying the color.
-<%= json :name => "API", :color => "FFFFFF" %>
+<%= json :name => "bug", :color => "f29513" %>
### Response
-<%= headers 201,
- :Location =>
-"https://api.github.com/repos/user/repo/labels/foo" %>
+<%= headers 201, :Location => get_resource(:label)['url'] %>
<%= json :label %>
## Update a label
@@ -52,13 +49,13 @@ Name | Type | Description
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`name`|`string` | **Required**. The name of the label.
-`color`|`string` |**Required**. A 6 character hex code, without the leading `#`, identifying the color.
+`name`|`string` | The name of the label.
+`color`|`string` | A 6 character hex code, without the leading `#`, identifying the color.
-<%= json :name => "API", :color => "FFFFFF" %>
+<%= json :name => "bug", :color => "f29513" %>
### Response
@@ -79,7 +76,7 @@ Name | Type | Description
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:label) { |h| [h] } %>
## Add labels to an issue
@@ -132,5 +129,5 @@ Sending an empty array (`[]`) will remove all Labels from the Issue.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:label) { |h| [h] } %>
diff --git a/content/v3/issues/milestones.md b/content/v3/issues/milestones.md
index 7156c88d7c..2438449bae 100644
--- a/content/v3/issues/milestones.md
+++ b/content/v3/issues/milestones.md
@@ -1,10 +1,9 @@
---
-title: Issue Milestones | GitHub API
+title: Issue Milestones
---
# Milestones
-* TOC
{:toc}
## List milestones for a repository
@@ -13,10 +12,10 @@ title: Issue Milestones | GitHub API
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`state`|`string` | The state of the milestone. Either `open` or `closed`. Default: `open`
-`sort`|`string` | What to sort results by. Either `due_date` or `completeness`. Default: `due_date`
+`state`|`string` | The state of the milestone. Either `open`, `closed`, or `all`. Default: `open`
+`sort`|`string` | What to sort results by. Either `due_on` or `completeness`. Default: `due_on`
`direction`|`string` | The direction of the sort. Either `asc` or `desc`. Default: `asc`
@@ -40,7 +39,7 @@ Name | Type | Description
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|---------------
`title`|`string` | **Required**. The title of the milestone.
`state`|`string` | The state of the milestone. Either `open` or `closed`. Default: `open`
@@ -50,17 +49,15 @@ Name | Type | Description
#### Example
<%= json \
- :title => "String",
- :state => "open or closed",
- :description => "String",
+ :title => "v1.0",
+ :state => "open",
+ :description => "Tracking milestone for version 1.0",
:due_on => "2012-10-09T23:39:01Z"
%>
### Response
-<%= headers 201,
- :Location =>
-"https://api.github.com/repos/user/repo/milestones/1" %>
+<%= headers 201, :Location => get_resource(:milestone)['url'] %>
<%= json :milestone %>
## Update a milestone
@@ -69,7 +66,7 @@ Name | Type | Description
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|---------------
`title`|`string` | The title of the milestone.
`state`|`string` | The state of the milestone. Either `open` or `closed`. Default: `open`
@@ -79,10 +76,10 @@ Name | Type | Description
#### Example
<%= json \
- :title => "String",
- :state => "open or closed",
- :description => "String",
- :due_on => "Time"
+ :title => "v1.0",
+ :state => "open",
+ :description => "Tracking milestone for version 1.0",
+ :due_on => "2012-10-09T23:39:01Z"
%>
### Response
@@ -97,4 +94,3 @@ Name | Type | Description
### Response
<%= headers 204 %>
-
diff --git a/content/v3/issues/timeline.md b/content/v3/issues/timeline.md
new file mode 100644
index 0000000000..c1ba039e0e
--- /dev/null
+++ b/content/v3/issues/timeline.md
@@ -0,0 +1,149 @@
+---
+title: Issue Timeline
+---
+
+{{#tip}}
+
+
+
+ The API to get issue timeline events is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-23-timeline-preview-api/) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.mockingbird-preview
+
+{{/tip}}
+
+# Timeline
+
+{:toc}
+
+Records various events that occur around an issue or pull request. This is
+useful both for display on issue and pull request information pages, as well as to
+determine who should be notified of comments.
+
+### Attributes
+
+
+
id
+
The Integer ID of the event.
+
+
url
+
The API URL for fetching the event.
+
+
actor
+
The User object that generated the event.
+
+
commit_id
+
The String SHA of a commit that referenced this Issue.
+
+
event
+
Identifies the actual type of Event that occurred.
+
+
created_at
+
The timestamp indicating when the event occurred.
+
+
label
+
The Label object including `name` and `color` attributes. Only provided for `labeled`
+ and `unlabeled` events.
+
+
assignee
+
The User object which was assigned to (or unassigned from) this Issue. Only provided for `assigned` and `unassigned` events.
+
+
milestone
+
The Milestone object including a `title` attribute. Only provided for `milestoned` and
+ `demilestoned` events.
+
+
source
+
The `id`, `actor`, and `url` for the source of a reference from
+another issue. Only provided for `cross-referenced` events.
+
+
rename
+
An object containing rename details including `from` and `to` attributes. Only
+ provided for `renamed` events.
+
+
+### Events
+
+
+
assigned
+
The issue was assigned to the assignee.
+
+
closed
+
The issue was closed by the actor. When the commit_id is present, it
+ identifies the commit that closed the issue using "closes / fixes #NN"
+ syntax.
+
+
commented
+
A comment was added to the issue.
+
+
committed
+
A commit was added to the pull request's `HEAD` branch. Only
+provided for pull requests.
+
+
cross-referenced
+
The issue was referenced from another issue. The `source`
+attribute contains the `id`, `actor`, and `url` of the reference's
+source.
+
+
demilestoned
+
The issue was removed from a milestone.
+
+
head_ref_deleted
+
The pull request's branch was deleted.
+
+
head_ref_restored
+
The pull request's branch was restored.
+
+
labeled
+
A label was added to the issue.
+
+
locked
+
The issue was locked by the actor.
+
+
mentioned
+
The actor was @mentioned in an issue body.
+
+
merged
+
The issue was merged by the actor. The `commit_id` attribute is the SHA1 of
+ the HEAD commit that was merged.
+
+
milestoned
+
The issue was added to a milestone.
+
+
referenced
+
The issue was referenced from a commit message. The `commit_id` attribute is
+ the commit SHA1 of where that happened.
+
+
renamed
+
The issue title was changed.
+
+
reopened
+
The issue was reopened by the actor.
+
+
subscribed
+
The actor subscribed to receive notifications for an issue.
+
+
unassigned
+
The assignee was unassigned from the issue.
+
+
unlabeled
+
A label was removed from the issue.
+
+
unlocked
+
The issue was unlocked by the actor.
+
+
unsubscribed
+
The actor unsubscribed to stop receiving notifications for an issue.
+
+
+## List events for an issue
+
+ GET /repos/:owner/:repo/issues/:issue_number/timeline
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:issue_event) { |h| [h] } %>
diff --git a/content/v3/licenses.md b/content/v3/licenses.md
new file mode 100644
index 0000000000..8fd40230aa
--- /dev/null
+++ b/content/v3/licenses.md
@@ -0,0 +1,77 @@
+---
+title: Licenses
+---
+
+# Licenses
+
+{:toc}
+
+{{#tip}}
+
+
+
+ The Licenses API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](https://github.com/blog/1964-open-source-license-usage-on-github-com) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.drax-preview+json
+
+{{/tip}}
+
+The Licenses API returns metadata about popular open source licenses and information about a particular project's license file.
+
+The Licenses API uses [the open source Ruby Gem Licensee](https://github.com/benbalter/licensee) to attempt to identity the project's license. Licensee matches the contents of a project's `LICENSE` file (if it exists) against a short list of known licenses. As a result, the API does not take into account the licenses of project dependencies or other means of documenting a project's license such as references to the license name in the documentation.
+
+If a license is matched, the license key and name returned conforms to the [SPDX specification](https://spdx.org/).
+
+{{#warning}}
+
+GitHub is a lot of things, but it’s not a law firm. As such, GitHub does not provide legal advice. Using the Licenses API or sending us an email about it does not constitute legal advice nor does it create an attorney-client relationship. If you have any questions about what you can and can't do with a particular license, you should consult with your own legal counsel before moving forward. In fact, you should always consult with your own lawyer before making any decisions that might have legal ramifications or that may impact your legal rights.
+
+GitHub created the License API to help users get information about open source licenses and the projects that use them. We hope it helps, but please keep in mind that we’re not lawyers (at least not most of us aren't) and that we make mistakes like everyone else. For that reason, GitHub provides the API on an “as-is” basis and makes no warranties regarding any information or licenses provided on or through it, and disclaims liability for damages resulting from using the API.
+
+{{/warning}}
+
+## List all licenses
+
+ GET /licenses
+
+### Response
+
+<%= headers 200 %>
+<%= json(:licenses) %>
+
+## Get an individual license
+
+ GET /licenses/mit
+
+### Response
+
+<%= headers 200 %>
+<%= json(:mit) %>
+
+## Get a repository's license
+
+When passed the preview media type, requests to get a repository will also return the repository's license, if it can be detected from the repository's license file.
+
+ GET /repos/:owner/:repo
+
+### Response
+
+<%= headers 200 %>
+<%= json(:licensee) %>
+
+## Get the contents of a repository's license
+
+This method returns the contents of the repository's license file, if one is detected.
+
+ GET /repos/:owner/:repo/license
+
+Similar to [the repository contents API](/v3/repos/contents/#get-contents), this method also supports [custom media types](/v3/repos/contents/#custom-media-types) for retrieving the raw license content or rendered license HTML.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:license_contents) %>
diff --git a/content/v3/markdown.md b/content/v3/markdown.md
index 11e74030db..6ae1867f01 100644
--- a/content/v3/markdown.md
+++ b/content/v3/markdown.md
@@ -1,10 +1,9 @@
---
-title: Markdown | GitHub API
+title: Markdown
---
# Markdown
-* TOC
{:toc}
## Render an arbitrary Markdown document
@@ -13,7 +12,7 @@ title: Markdown | GitHub API
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|---------------
`text`|`string` | **Required**.The Markdown text to render
`mode`|`string` | The rendering mode. Can be either: * `markdown` to render a document as plain Markdown, just like README files are rendered. * `gfm` to render a document as user-content, _e.g._ like user comments or issues are rendered. In GFM mode, hard line breaks are always taken into account, and issue and user mentions are linked accordingly. Default: `markdown`
diff --git a/content/v3/media.md b/content/v3/media.md
index 7a7ed081d0..539acc407c 100644
--- a/content/v3/media.md
+++ b/content/v3/media.md
@@ -1,9 +1,8 @@
---
-title: Media Types | GitHub API
+title: Media Types
---
# Media Types
-* TOC
{:toc}
Custom media types are used in the API to let consumers choose the format
@@ -12,7 +11,7 @@ the following types to the `Accept` header when you make a request. Media types
are specific to resources, allowing them to change independently and support
formats that other resources don't.
-All GitHub media types look like this:
+All {{ site.data.variables.product.product_name }} media types look like this:
application/vnd.github[.version].param[+json]
@@ -21,9 +20,19 @@ The most basic media types the API supports are:
application/json
application/vnd.github+json
-Neither of these specify a [version][versions], so you will always get the current default
-JSON representation of resources. If you're building an application and
-care about the stability of the API, specify a version like so:
+Neither of these specify a [version][versions], so you will always get the
+current default JSON representation of resources.
+
+
+
+ Important: The default version of the API may change in the
+ future. If you're building an application and care about the stability of
+ the API, be sure to request a specific version in the Accept
+ header as shown in the examples below.
+
+
+
+You can specify a version like so:
application/vnd.github.v3+json
@@ -35,34 +44,21 @@ put the version before the property:
You can check the current version through every response's headers. Look
for the `X-GitHub-Media-Type` header:
- $ curl https://api.github.com/users/technoweenie -I
- HTTP/1.1 200 OK
- X-GitHub-Media-Type: github.beta
-
- $ curl https://api.github.com/users/technoweenie -I \
- -H "Accept: application/vnd.github.full+json"
- HTTP/1.1 200 OK
- X-GitHub-Media-Type: github.beta; param=full; format=json
-
- $ curl https://api.github.com/users/technoweenie -I \
- -H "Accept: application/vnd.github.v3.full+json"
- HTTP/1.1 200 OK
- X-GitHub-Media-Type: github.v3; param=full; format=json
+``` command-line
+$ curl {{ site.data.variables.product.api_url_pre }}/users/technoweenie -I
+> HTTP/1.1 200 OK
+> X-GitHub-Media-Type: github.v3
+$ curl {{ site.data.variables.product.api_url_pre }}/users/technoweenie -I \
+$ -H "Accept: application/vnd.github.full+json"
+> HTTP/1.1 200 OK
+> X-GitHub-Media-Type: github.v3; param=full; format=json
-## Beta, v3, and the Future
-
-If you don't specify a version in the `Accept` header, you'll
-get the [beta version](/v3/versions#beta) (as shown above) by default.
-
-Soon, [v3](/v3/versions#v3) will become the default version. (Check out
-the [blog post](/changes/2014-01-07-upcoming-change-to-default-media-type/) for
-details.) We recommend that you start using v3 now. To get that version today,
-explicitly request the API v3 media type in the `Accept` header:
-
- application/vnd.github.v3+json
-
-Check out [version docs][versions] for the [full list of differences](/v3/versions#differences-from-beta-version) between beta and v3.
+$ curl {{ site.data.variables.product.api_url_pre }}/users/technoweenie -I \
+$ -H "Accept: application/vnd.github.v3.full+json"
+> HTTP/1.1 200 OK
+> X-GitHub-Media-Type: github.v3; param=full; format=json
+```
## Comment Body Properties
@@ -129,6 +125,37 @@ The Commit, Commit Comparison, and Pull Request resources support
application/vnd.github.VERSION.patch
+### sha
+
+ application/vnd.github.VERSION.sha
+
+## Repository contents
+
+### Raw
+
+ application/vnd.github.VERSION.raw
+
+Return the raw contents of a file. This is the default if you do not pass any specific media type.
+
+### HTML
+
+ application/vnd.github.VERSION.html
+
+For markup files such as Markdown or AsciiDoc, you can retrieve the rendered HTML using the `.html` media type. Markup languages are rendered to HTML using our open-source [Markup library](https://github.com/github/markup).
+
+## Gists
+
+### Raw
+
+ application/vnd.github.VERSION.raw
+
+Return the raw contents of a gist. This is the default if you do not pass any specific media type.
+
+### base64
+
+ application/vnd.github.VERSION.base64
+
+The gist contents are base64-encoded before being sent out. This can be useful if your gist contains any invalid UTF-8 sequences.
[gfm]:http://github.github.com/github-flavored-markdown/
[git-diff]: http://git-scm.com/docs/git-diff
diff --git a/content/v3/meta.md b/content/v3/meta.md
index 5c572982bd..6ba388351d 100644
--- a/content/v3/meta.md
+++ b/content/v3/meta.md
@@ -1,11 +1,18 @@
---
-title: Meta | GitHub API
+title: Meta
---
# Meta
+{% if page.version == 'dotcom' %}
+
This endpoint provides information about GitHub.com, the service.
-Or, if you access this endpoint on your organization's [GitHub Enterprise](https://enterprise.github.com/) installation, this endpoint provides information about that installation.
+
+{% else %}
+
+If you access this endpoint on your organization's [GitHub Enterprise](https://enterprise.github.com/) installation, this endpoint provides information about that installation.
+
+{% endif %}
GET /meta
@@ -18,6 +25,9 @@ Or, if you access this endpoint on your organization's [GitHub Enterprise](https
Name | Type | Description
-----|------|--------------
-`hooks`|`array` of `strings` | An Array of IP addresses in CIDR format specifying the addresses that incoming service hooks will originate from on GitHub.com. Subscribe to the [API Changes blog](http://developer.github.com/changes/) or follow [@GitHubAPI](https://twitter.com/GitHubAPI) on Twitter to get updated when this list changes.
+`verifiable_password_authentication`|`boolean` | Whether authentication with username and password is supported. {% if page.version != 'dotcom' %}GitHub Enterprise instances using CAS or OAuth for authentication will return `false`. Features like [Basic Authentication with a username and password](/v3/auth/#via-username-and-password), [sudo mode](https://help.github.com/articles/sudo-mode), and [two-factor authentication](https://help.github.com/articles/about-two-factor-authentication) are not supported on these servers.{% endif %}
+`github_services_sha` | `string` | The currently-deployed SHA of [`github-services`](https://github.com/github/github-services).
+`hooks`|`array` of `strings` | An Array of IP addresses in CIDR format specifying the addresses that incoming service hooks will originate from on GitHub.com. Subscribe to the [API Changes blog](https://developer.github.com/changes/) or follow [@GitHubAPI](https://twitter.com/GitHubAPI) on Twitter to get updated when this list changes.
`git`|`array` of `strings` | An Array of IP addresses in CIDR format specifying the Git servers for GitHub.com.
-`verifiable_password_authentication`|`boolean` | Whether authentication with username and password is supported. (GitHub Enterprise instances using CAS or OAuth for authentication will return `false`. Features like [Basic Authentication with a username and password](/v3/auth/#via-username-and-password), [sudo mode](https://help.github.com/articles/sudo-mode), and [two-factor authentication](https://help.github.com/articles/about-two-factor-authentication) are not supported on these servers.)
+`pages`|`array` of `strings` | An Array of IP addresses in CIDR format specifying the A records for [GitHub Pages](https://pages.github.com/).
+`importer`|`array` of `strings` | An Array of IP addresses specifying the addresses that source imports will originate from on GitHub.com.
diff --git a/content/v3/migration.md b/content/v3/migration.md
new file mode 100644
index 0000000000..5291cd5928
--- /dev/null
+++ b/content/v3/migration.md
@@ -0,0 +1,29 @@
+---
+title: Migration
+---
+
+# Migration
+
+These APIs help you move projects to or from {{ site.data.variables.product.product_name }}.
+
+{% if page.version == 'dotcom' %}
+
+## [Enterprise Migrations][migrations]
+
+The [Enterprise Migrations API][migrations] lets you move a repository from GitHub to GitHub Enterprise.
+
+## [Source Imports][source_imports]
+
+The [Source Imports API][source_imports] lets you import a source repository to
+{{ site.data.variables.product.product_name }}.
+
+{% else %}
+
+The migration APIs are only available on github.com. To learn more about migration,
+read the [API documentation on github.com](https://developer.github.com/v3/migration/)
+or check out the [Enterprise Migration Guide](https://help.github.com/enterprise/admin/guides/migrations/).
+
+{% endif %}
+
+[migrations]: /v3/migration/migrations/
+[source_imports]: /v3/migration/source_imports/
diff --git a/content/v3/migration/migrations.md b/content/v3/migration/migrations.md
new file mode 100644
index 0000000000..be76e44e2e
--- /dev/null
+++ b/content/v3/migration/migrations.md
@@ -0,0 +1,115 @@
+---
+title: Migrations
+---
+
+# Migrations
+
+{:toc}
+
+The Migrations API *is only available to [authenticated](https://developer.github.com/v3/#authentication) organization [owners](https://help.github.com/articles/permission-levels-for-an-organization/)*.
+
+{% if page.version != 'dotcom' %}
+
+{{#warning}}
+
+This API is not currently available on GitHub Enterprise.
+
+{{/warning}}
+
+{% endif %}
+
+{{#tip}}
+
+ To access the Migrations API, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.wyandotte-preview+json
+
+{{/tip}}
+
+## Start a migration
+
+Initiates the generation of a migration archive.
+
+ POST /orgs/:org/migrations
+
+### Parameters
+
+Name | Type | Description
+--------|---------|--------------
+`repositories` | `array` of `strings` | **Required**. A list of arrays indicating which repositories should be migrated.
+`lock_repositories`|`boolean` | Indicates whether repositories should be locked (to prevent manipulation) while migrating data. Default: `false`.
+`exclude_attachments`|`boolean` | Indicates whether attachments should be excluded from the migration (to reduce migration archive file size). Default: `false`.
+
+### Example
+
+<%= json \
+ :repositories => ["octocat/Hello-World"],
+ :lock_repositories => true
+%>
+
+### Response
+
+<%= headers 201 %>
+<%= json(:migrations) %>
+
+## Get a list of migrations
+
+Lists the most recent migrations.
+
+ GET /orgs/:org/migrations
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:migrations) { |h| [h] } %>
+
+## Get the status of a migration
+
+Fetches the status of a migration.
+
+ GET /orgs/:org/migrations/:id
+
+### Response
+
+The `state` of a migration can be one of the following values:
+
+* `pending`, which means the migration hasn't started yet.
+* `exporting`, which means the migration is in progress.
+* `exported`, which means the migration finished successfully.
+* `failed`, which means the migration failed.
+
+<%= headers 200 %>
+<%= json(:migrations) { |h| h['state'] = 'exported'; h } %>
+
+## Download a migration archive
+
+Fetches the URL to a migration archive.
+
+ GET /orgs/:org/migrations/:id/archive
+
+### Response
+
+<%= headers 302 %>
+
+
+## Delete a migration archive
+
+Deletes a previous migration archive. Migration archives are automatically deleted after seven days.
+
+ DELETE /orgs/:org/migrations/:id/archive
+
+### Response
+
+<%= headers 204 %>
+
+## Unlock a repository
+
+Unlocks a repository that was locked for migration. You should unlock each migrated repository and [delete them](/v3/repos/#delete-a-repository) when the migration is complete and you no longer need the source data.
+
+ DELETE /orgs/:org/migrations/:id/repos/:repo_name/lock
+
+### Response
+
+<%= headers 204 %>
diff --git a/content/v3/migration/source_imports.md b/content/v3/migration/source_imports.md
new file mode 100644
index 0000000000..044cc0079e
--- /dev/null
+++ b/content/v3/migration/source_imports.md
@@ -0,0 +1,321 @@
+---
+title: Source Imports | GitHub API
+---
+
+# Source Imports
+
+{:toc}
+
+{% if page.version != 'dotcom' %}
+
+{{#warning}}
+
+This API is not currently available on GitHub Enterprise.
+
+{{/warning}}
+
+{% endif %}
+
+{{#tip}}
+
+ The source import APIs are currently in public preview. During this period, the APIs may change in a backwards-incompatible way. To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.barred-rock-preview
+
+{{/tip}}
+
+The Source Import API lets you start an import from a Git, Subversion, Mercurial, or Team Foundation Server source repository. This is the same functionality as [the GitHub Importer](https://help.github.com/articles/importing-from-other-version-control-systems-to-github/).
+
+A typical source import would [start the import](#start-an-import) and then (optionally) [update the authors](#map-a-commit-author) and/or [set the preference](#set-git-lfs-preference) for using Git LFS if large files exist in the import. A more detailed example can be seen in this diagram:
+
+```
++---------+ +--------+ +---------------------+
+| Tooling | | GitHub | | Original Repository |
++---------+ +--------+ +---------------------+
+ | | |
+ | Start import | |
+ |----------------------------->| |
+ | | |
+ | | Download source data |
+ | |--------------------------------------------->|
+ | | Begin streaming data |
+ | |<---------------------------------------------|
+ | | |
+ | Get import progress | |
+ |----------------------------->| |
+ | "status": "importing" | |
+ |<-----------------------------| |
+ | | |
+ | Get commit authors | |
+ |----------------------------->| |
+ | | |
+ | Map a commit author | |
+ |----------------------------->| |
+ | | |
+ | | |
+ | | Finish streaming data |
+ | |<---------------------------------------------|
+ | | |
+ | | Rewrite commits with mapped authors |
+ | |------+ |
+ | | | |
+ | |<-----+ |
+ | | |
+ | | Update repository on GitHub |
+ | |------+ |
+ | | | |
+ | |<-----+ |
+ | | |
+ | Map a commit author | |
+ |----------------------------->| |
+ | | Rewrite commits with mapped authors |
+ | |------+ |
+ | | | |
+ | |<-----+ |
+ | | |
+ | | Update repository on GitHub |
+ | |------+ |
+ | | | |
+ | |<-----+ |
+ | | |
+ | Get large files | |
+ |----------------------------->| |
+ | | |
+ | opt_in to Git LFS | |
+ |----------------------------->| |
+ | | Rewrite commits for large files |
+ | |------+ |
+ | | | |
+ | |<-----+ |
+ | | |
+ | | Update repository on GitHub |
+ | |------+ |
+ | | | |
+ | |<-----+ |
+ | | |
+ | Get import progress | |
+ |----------------------------->| |
+ | "status": "complete" | |
+ |<-----------------------------| |
+ | | |
+ | | |
+```
+
+## Start an import
+
+Start a source import to a GitHub repository using GitHub Importer.
+
+ PUT /repos/:owner/:repo/import
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`vcs_url`|`url`|**Required** The URL of the originating repository.
+`vcs`|`string`|The originating VCS type. Can be one of `subversion`, `git`, `mercurial`, or `tfvc`. Please be aware that without this parameter, the import job will take additional time to detect the VCS type before beginning the import. This detection step will be reflected in the response.
+`vcs_username`|`string`|If authentication is required, the username to provide to `vcs_url`.
+`vcs_password`|`string`|If authentication is required, the password to provide to `vcs_url`.
+`tfvc_project`|`string`|For a tfvc import, the name of the project that is being imported.
+
+#### Example
+
+<%= json \
+ :vcs => "subversion",
+ :vcs_url => "http://svn.mycompany.com/svn/myproject",
+ :vcs_username => "octocat",
+ :vcs_password => "secret"
+%>
+
+### Response
+
+<%= headers 201, :Location => "https://api.github.com/repos/spraints/socm/import" %>
+<%= json :source_import %>
+
+## Get import progress
+
+View the progress of an import.
+
+ GET /repos/:owner/:repo/import
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_complete %>
+
+### Import `status`
+
+This section includes details about the possible values of the `status` field of the Import Progress response.
+
+An import that does not have errors will progress through these steps:
+
+* `detecting` - the "detection" step of the import is in progress because the request did not include a `vcs` parameter. The import is identifying the type of source control present at the URL.
+* `importing` - the "raw" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include `commit_count` (the total number of raw commits that will be imported) and `percent` (0 - 100, the current progress through the import).
+* `mapping` - the "rewrite" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.
+* `pushing` - the "push" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include `push_percent`, which is the percent value reported by `git push` when it is "Writing objects".
+* `complete` - the import is complete, and the repository is ready on GitHub.
+
+If there are problems, you will see one of these in the `status` field:
+
+* `auth_failed` - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the [Update Existing Import](#update-existing-import) section.
+* `error` - the import encountered an error. The import progress response will include the `failed_step` and an error message. [Contact support](https://github.com/contact?form%5Bsubject%5D=Source+Import+API+error) for more information.
+* `detection_needs_auth` - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the [Update Existing Import](#update-existing-import) section.
+* `detection_found_nothing` - the importer didn't recognize any source control at the URL. To resolve, [Cancel the import](#cancel-an-import) and [retry](#start-an-import) with the correct URL.
+* `detection_found_multiple` - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a `project_choices` field with the possible project choices as values. To update project choice, please see the [Update Existing Import](#update-existing-import) section.
+
+### The `project_choices` field
+
+When multiple projects are found at the provided URL, the response hash will include a `project_choices` field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.
+
+<%= json :source_import_project_choices %>
+
+### Git LFS related fields
+
+This section includes details about Git LFS related fields that may be present in the Import Progress response.
+
+* `use_lfs` - describes whether the import has been opted in or out of using Git LFS. The value can be `opt_in`, `opt_out`, or `undecided` if no action has been taken.
+* `has_large_files` - the boolean value describing whether files larger than 100MB were found during the `importing` step.
+* `large_files_size` - the total size in gigabytes of files larger than 100MB found in the originating repository.
+* `large_files_count` - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a "Get Large Files" request.
+
+## Update existing import
+
+An import can be updated with credentials or a project choice by passing in the appropriate parameters in this API request. If no parameters are provided, the import will be restarted.
+
+ PATCH /repos/:owner/:repo/import
+
+### Parameters for updating authentication
+
+Name | Type | Description
+-----|------|--------------
+`vcs_username`|`string`|The username to provide to the originating repository.
+`vcs_password`|`string`|The password to provide to the originating repository.
+
+### Example
+
+<%= json \
+ :vcs_username => "octocat",
+ :vcs_password => "secret"
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_update_auth %>
+
+### Parameters for updating project choice
+
+Some servers (e.g. TFS servers) can have several projects at a single URL. In those cases the import progress will have the status `detection_found_multiple` and the Import Progress response will include a `project_choices` array. You can select the project to import by providing one of the objects in the `project_choices` array in the update request.
+
+The following example demonstrates the workflow for updating an import with "project1" as the project choice. Given a `project_choices` array like such:
+
+<%= json :source_import_project_choices %>
+
+### Example
+
+<%= json\
+ "vcs": "tfvc",
+ "tfvc_project": "project1",
+ "human_name": "project1 (tfs)"
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_update_project_choice %>
+
+### Parameters for restarting import
+
+To restart an import, no parameters are provided in the update request.
+
+### Response
+
+<%= headers 200, :Location => "https://api.github.com/repos/spraints/socm/import" %>
+<%= json :source_import %>
+
+## Get commit authors
+
+Each type of source control system represents authors in a different way. For example, a Git commit author has a display name and an email address, but a Subversion commit author just has a username. The GitHub Importer will make the author information valid, but the author might not be correct. For example, it will change the bare Subversion username `hubot` into something like `hubot `.
+
+This API method and the "Map a commit author" method allow you to provide correct Git author information.
+
+ GET /repos/:owner/:repo/import/authors
+
+### Parameters
+
+Name | Type | Description
+-----|------|------------
+`since`|`string`|Only authors found after this id are returned. Provide the highest author ID you've seen so far. New authors may be added to the list at any point while the importer is performing the `raw` step.
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_authors %>
+
+## Map a commit author
+
+Update an author's identity for the import. Your application can continue updating authors any time before you push new commits to the repository.
+
+ PATCH /repos/:owner/:repo/import/authors/:author_id
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`email`|`string`|The new Git author email.
+`name`|`string`|The new Git author name.
+
+### Example
+
+<%= json \
+ :email => "hubot@github.com",
+ :name => "Hubot the Robot"
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_author %>
+
+## Set Git LFS preference
+
+You can import repositories from Subversion, Mercurial, and TFS that include files larger than 100MB. This ability is powered by [Git LFS](https://git-lfs.github.com). You can learn more about our LFS feature and working with large files [on our help site](https://help.github.com/articles/versioning-large-files/).
+
+ PATCH /:owner/:name/import/lfs
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`use_lfs`|`string`|**Required** Can be one of `opt_in` (large files will be stored using Git LFS) or `opt_out` (large files will be removed during the import).
+
+### Example
+
+<%= json \
+ :use_lfs => "opt_in"
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_complete %>
+
+## Get large files
+
+List files larger than 100MB found during the import
+
+ GET /:owner/:name/import/large_files
+
+### Response
+
+<%= headers 200 %>
+<%= json :source_import_large_files %>
+
+## Cancel an import
+
+Stop an import for a repository.
+
+ DELETE /repos/:owner/:repo/import
+
+### Response
+
+<%= headers 204 %>
diff --git a/content/v3/misc.md b/content/v3/misc.md
index ccb5447ad5..7fefcbb369 100644
--- a/content/v3/misc.md
+++ b/content/v3/misc.md
@@ -1,15 +1,15 @@
---
-title: Miscellaneous | GitHub API
+title: Miscellaneous
---
# Miscellaneous
-This is a miscellaneous set of APIs which provide access to top level GitHub resources and info.
+This is a miscellaneous set of APIs which provide access to top level {{ site.data.variables.product.product_name }} resources and info.
## [Emojis][]
The [Emojis API][Emojis] lets you list all the emojis available to use on
-GitHub.
+{{ site.data.variables.product.product_name }}.
## [Gitignore][]
@@ -22,16 +22,33 @@ The [Markdown API][Markdown] lets you render Markdown documents.
## [Meta][]
-The [Meta API][Meta] provides information about GitHub.com (the service) or your
+{% if page.version == 'dotcom' %}
+
+The [Meta API][Meta] provides information about GitHub.com (the service).
+
+{% else %}
+
+The [Meta API][Meta] provides information about your
organization's [GitHub Enterprise](https://enterprise.github.com/) installation.
+{% endif %}
+
+{% if page.version == 'dotcom' %}
+
## [Rate Limit][]
The [Rate Limit API][Rate Limit] lets you check your current rate limit
status at any time.
+{% endif %}
+
+## [Licenses][]
+
+The [Licenses API][Licenses] returns information about open source licenses or under what license, if any a given project is distributed.
+
[Emojis]: /v3/emojis
[Gitignore]: /v3/gitignore
[Markdown]: /v3/markdown
[Meta]: /v3/meta
[Rate Limit]: /v3/rate_limit
+[Licenses]: /v3/licenses
diff --git a/content/v3/oauth.md b/content/v3/oauth.md
index aa89d14dd1..1555d954d7 100644
--- a/content/v3/oauth.md
+++ b/content/v3/oauth.md
@@ -1,14 +1,13 @@
---
-title: OAuth | GitHub API
+title: OAuth
---
# OAuth
-* TOC
{:toc}
-OAuth2 is a protocol that lets external apps request authorization to
-private details in a user's GitHub account without getting their
+OAuth2 is a protocol that lets external applications request authorization to
+private details in a user's {{ site.data.variables.product.product_name }} account without getting their
password. This is preferred over [Basic Authentication](/v3/auth#basic-authentication) because tokens can
be limited to specific types of data, and can be revoked by users at any
time.
@@ -17,6 +16,10 @@ All developers need to [register their
application](https://github.com/settings/applications/new) before getting
started. A registered OAuth application is assigned a unique Client ID
and Client Secret. The Client Secret should not be shared.
+**You may create a [personal access token](https://github.com/settings/tokens/new)
+for your own use or implement the web flow below to allow other users to authorize your application.**
+
+GitHub's OAuth implementation supports the standard [authorization code grant type](https://tools.ietf.org/html/rfc6749#section-4.1). Developers should implement the web application flow described below to obtain an authorization code and then exchange it for a token. (The [implicit grant type](https://tools.ietf.org/html/rfc6749#section-4.2) is not supported.)
## Web Application Flow
@@ -31,9 +34,10 @@ This is a description of the OAuth2 flow from 3rd party web sites.
Name | Type | Description
-----|------|--------------
`client_id`|`string` | **Required**. The client ID you received from GitHub when you [registered](https://github.com/settings/applications/new).
-`redirect_uri`|`string` | The URL in your app where users will be sent after authorization. See details below about [redirect urls](#redirect-urls).
-`scope`|`string` | A comma separated list of [scopes](#scopes). If not provided, `scope` defaults to an empty list of scopes for users that don't have a valid token for the app. For users who do already have a valid token for the app, the user won't be shown the OAuth authorization page with the list of scopes. Instead, this step of the flow will automatically complete with the same scopes that were used last time the user completed the flow.
+`redirect_uri`|`string` | The URL in your application where users will be sent after authorization. See details below about [redirect urls](#redirect-urls).
+`scope`|`string` | A space delimited list of [scopes](#scopes). If not provided, `scope` defaults to an empty list for users that have not authorized any scopes for the application. For users who have authorized scopes for the application, the user won't be shown the OAuth authorization page with the list of scopes. Instead, this step of the flow will automatically complete with the set of scopes the user has authorized for the application. For example, if a user has already performed the web flow twice and has authorized one token with `user` scope and another token with `repo` scope, a third web flow that does not provide a `scope` will receive a token with `user` and `repo` scope.
`state`|`string` | An unguessable random string. It is used to protect against cross-site request forgery attacks.
+`allow_signup`|`boolean` | Whether or not unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. The default is `true`. Use `false` in the case that a policy prohibits signups.
### 2. GitHub redirects back to your site
@@ -52,8 +56,9 @@ Name | Type | Description
-----|------|---------------
`client_id`|`string` | **Required**. The client ID you received from GitHub when you [registered](https://github.com/settings/applications/new).
`client_secret`|`string` | **Required**. The client secret you received from GitHub when you [registered](https://github.com/settings/applications/new).
-`code`|`string` | **Required**. The code you received as a response to [Step 1](#redirect-users-to-request-github-access).
-`redirect_uri`|`string` | The URL in your app where users will be sent after authorization. See details below about [redirect urls](#redirect-urls).
+`code`|`string` | **Required**. The code you received as a response to [Step 1](#1-redirect-users-to-request-github-access).
+`redirect_uri`|`string` | The URL in your application where users will be sent after authorization. See details below about [redirect urls](#redirect-urls).
+`state`|`string` | The unguessable random string you optionally provided in [Step 1](#1-redirect-users-to-request-github-access).
### Response
@@ -74,6 +79,19 @@ header:
e72e16c7e42f292c6912e7710c838347ae178b4a
+#### Multiple tokens
+
+GitHub allows multiple tokens to exist for a user/application/scope combination.
+This can be used to create tokens for specific use cases. For example, your
+application might support one workflow that uses GitHub for sign in, and only
+requires basic user information. And, your application might support a different
+workflow that requires access to a user's private repositories. Using multiple
+tokens, your application can perform the web flow for each use case, requesting
+only the scopes needed. If a user only uses your application to sign in, they
+are never required to grant your application access to their private
+repositories. Note, there is a limit to the number of tokens that are issued per
+user/application/scope combination. If your application requests enough tokens
+to go over one of the limits, older tokens will stop working.
#### Requested scopes vs. granted scopes
@@ -117,7 +135,9 @@ cleaner approach is to include it in the Authorization header
For example, in curl you can set the Authorization header like this:
- curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/user
+``` command-line
+curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/user
+```
## Non-Web Application Flow
@@ -158,10 +178,12 @@ authorize form.
Check headers to see what OAuth scopes you have, and what the API action
accepts.
- $ curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/users/technoweenie -I
- HTTP/1.1 200 OK
- X-OAuth-Scopes: repo, user
- X-Accepted-OAuth-Scopes: user
+``` command-line
+$ curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/users/technoweenie -I
+HTTP/1.1 200 OK
+X-OAuth-Scopes: repo, user
+X-Accepted-OAuth-Scopes: user
+```
`X-OAuth-Scopes` lists the scopes your token has authorized.
`X-Accepted-OAuth-Scopes` lists the scopes that the action checks for.
@@ -173,8 +195,8 @@ Name | Description
`user` | Grants read/write access to profile info only. Note that this scope includes `user:email` and `user:follow`.
`user:email`| Grants read access to a user's email addresses.
`user:follow`| Grants access to follow or unfollow other users.
-`public_repo`| Grants read/write access to code, commit statuses, and deployment statuses for public repositories and organizations.
-`repo`| Grants read/write access to code, commit statuses, and deployment statuses for public and private repositories and organizations.
+`public_repo`| Grants read/write access to code, commit statuses, collaborators, and deployment statuses for public repositories and organizations. Also required for starring public repositories.
+`repo`| Grants read/write access to code, commit statuses, repository invitations, collaborators, and deployment statuses for public and private repositories and organizations.
`repo_deployment`| Grants access to [deployment statuses][deployments] for public and private repositories. This scope is only necessary to grant other users or services access to deployment statuses, *without* granting access to the code.
`repo:status`| Grants read/write access to public and private repository commit statuses. This scope is only necessary to grant other users or services access to private repository commit statuses *without* granting access to the code.
`delete_repo`| Grants access to delete adminable repositories.
@@ -183,19 +205,23 @@ Name | Description
`read:repo_hook`| Grants read and ping access to hooks in public or private repositories.
`write:repo_hook`| Grants read, write, and ping access to hooks in public or private repositories.
`admin:repo_hook`| Grants read, write, ping, and delete access to hooks in public or private repositories.
+`admin:org_hook`| Grants read, write, ping, and delete access to organization hooks. **Note:** OAuth tokens will only be able to perform these actions on organization hooks which were created by the OAuth application. Personal access tokens will only be able to perform these actions on organization hooks created by a user.
`read:org`| Read-only access to organization, teams, and membership.
`write:org`| Publicize and unpublicize organization membership.
`admin:org`| Fully manage organization, teams, and memberships.
`read:public_key`| List and view details for public keys.
`write:public_key`| Create, list, and view details for public keys.
`admin:public_key`| Fully manage public keys.
+{% if page.version == 'dotcom' %}`read:gpg_key`| List and view details for GPG keys.{% endif %}
+{% if page.version == 'dotcom' %}`write:gpg_key`| Create, list, and view details for GPG keys.{% endif %}
+{% if page.version == 'dotcom' %}`admin:gpg_key`| Fully manage GPG keys.{% endif %}
NOTE: Your application can request the scopes in the initial redirection. You
-can specify multiple scopes by separating them with a comma:
+can specify multiple scopes by separating them with a space:
https://github.com/login/oauth/authorize?
client_id=...&
- scope=user,public_repo
+ scope=user%20public_repo
## Common errors for the authorization request
@@ -207,12 +233,12 @@ these are some errors you might see:
If the OAuth application you set up has been suspended (due to reported
abuse, spam, or a mis-use of the API), GitHub will redirect to the
-registered callback URL with the following parameters summerizing the
+registered callback URL with the following parameters summarizing the
error:
http://your-application.com/callback?error=application_suspended
&error_description=Your+application+has+been+suspended.+Contact+support@github.com.
- &error_uri=http://developer.github.com/v3/oauth/%23application-suspended
+ &error_uri=https://developer.github.com/v3/oauth/%23application-suspended
&state=xyz
Please contact [support](https://github.com/contact) to solve issues
@@ -222,11 +248,11 @@ with suspended applications.
If you provide a redirect_uri that doesn't match what you've registered
with your application, GitHub will redirect to the registered callback
-URL with the following parameters summerizing the error:
+URL with the following parameters summarizing the error:
http://your-application.com/callback?error=redirect_uri_mismatch
&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.
- &error_uri=http://developer.github.com/v3/oauth/%23redirect-uri-mismatch
+ &error_uri=https://developer.github.com/v3/oauth/%23redirect-uri-mismatch
&state=xyz
To correct this error, either provide a redirect_uri that matches what
@@ -235,13 +261,13 @@ registered with your application.
### Access denied
-If the user rejects access to your application, GItHub will redirect to
-the registered callback URL with the following parameters summerizing
+If the user rejects access to your application, GitHub will redirect to
+the registered callback URL with the following parameters summarizing
the error:
http://your-application.com/callback?error=access_denied
&error_description=The+user+has+denied+your+application+access.
- &error_uri=http://developer.github.com/v3/oauth/%23access-denied
+ &error_uri=https://developer.github.com/v3/oauth/%23access-denied
&state=xyz
There's nothing you can do here as users are free to choose not to use
@@ -263,7 +289,7 @@ receive this error response.
<%= json :error => :incorrect_client_credentials,
:error_description => "The client_id and/or client_secret passed are incorrect.",
- :error_uri => "http://developer.github.com/v3/oauth/#incorrect-client-credentials"
+ :error_uri => "https://developer.github.com/v3/oauth/#incorrect-client-credentials"
%>
To solve this error, go back and make sure you have the correct
@@ -278,7 +304,7 @@ with your application, you will receive this error message:
<%= json :error => :redirect_uri_mismatch,
:error_description => "The redirect_uri MUST match the registered callback URL for this application.",
- :error_uri => "http://developer.github.com/v3/oauth/#redirect-uri-mismatch(2)"
+ :error_uri => "https://developer.github.com/v3/oauth/#redirect-uri-mismatch(2)"
%>
To correct this error, either provide a redirect_uri that matches what
@@ -295,13 +321,33 @@ receive this error.
<%= json :error => :bad_verification_code,
:error_description => "The code passed is incorrect or expired.",
- :error_uri => "http://developer.github.com/v3/oauth/#bad-verification-code"
+ :error_uri => "https://developer.github.com/v3/oauth/#bad-verification-code"
%>
-To solve this error, start the [OAuth process over from the beginning](#redirect-users-to-request-github-access)
+To solve this error, start the [OAuth process over from the beginning](#1-redirect-users-to-request-github-access)
and get a new code.
+## Directing users to review their access for an application
+
+Users can review and revoke their application authorizations from the [settings
+screen within GitHub][authorized-apps]. A user's organizations [control whether
+an application can access organization data][org-app-policies]. Integrators can
+deep link to the authorization information for their particular application to let their
+end users review these details.
+
+To build this link, you'll need your OAuth application's `client_id` you
+received from GitHub when you [registered the application][owned-apps].
+
+ https://github.com/settings/connections/applications/:client_id
+
+For tips on discovering the resources that your application can access for a
+user, be sure to check out our [guide][resource-discovery-guide].
+
[oauth changes blog]: /changes/2013-10-04-oauth-changes-coming/
[basics auth guide]: /guides/basics-of-authentication/
[deployments]: /v3/repos/deployments
[public keys]: /v3/users/keys/
+[authorized-apps]: https://github.com/settings/applications#authorized
+[owned-apps]: https://github.com/settings/developers
+[org-app-policies]: /changes/2015-01-19-an-integrators-guide-to-organization-application-policies/
+[resource-discovery-guide]: /guides/discovering-resources-for-a-user/
diff --git a/content/v3/oauth_authorizations.md b/content/v3/oauth_authorizations.md
index 23c7cf202a..785a6f0e9a 100644
--- a/content/v3/oauth_authorizations.md
+++ b/content/v3/oauth_authorizations.md
@@ -1,17 +1,108 @@
---
-title: Authorizations | GitHub API
+title: Authorizations
---
+{% if page.version == 'dotcom' or page.version > 2.6 %}
+
+{{#tip}}
+
+
+
+ APIs for managing OAuth grants are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-04-21-oauth-authorizations-grants-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.damage-preview
+
+{{/tip}}
+
+{% endif %}
+
+
+
+
Deprecation Notice
+
+
+ The token attribute is deprecated in all
+ of the following OAuth Authorizations API responses:
+
+
+ {% if page.version == 'dotcom' or page.version > 2.2 %}
+
+ To reduce the impact of removing the token value,
+ the OAuth Authorizations API now includes a new request attribute
+ (fingerprint), three new response attributes
+ (token_last_eight, hashed_token, and
+ fingerprint), and
+ one new endpoint.
+
+ {% else %}
+
+ To reduce the impact of removing the token value,
+ the OAuth Authorizations API now includes a new request attribute
+ (fingerprint) and three new response attributes
+ (token_last_eight, hashed_token, and
+ fingerprint).
+
+ {% endif %}
+
+ This functionality became the default for all requests on April 20, 2015. Please see the blog post for full details.
+
+
+
# OAuth Authorizations API
-* TOC
{:toc}
-There is an API for users to manage their own tokens. You can only access your
-own tokens, and only via [Basic Authentication](/v3/auth#basic-authentication).
-(Make sure you understand how to [work with two-factor
-authentication](/v3/auth/#working-with-two-factor-authentication) if you or your
-users have two-factor authentication enabled.)
+You can use this API to manage the access OAuth applications have to your account. You can only access this API via [Basic Authentication](/v3/auth#basic-authentication) using your username and password, not tokens.
+
+Make sure you understand how to [work with two-factor authentication](/v3/auth/#working-with-two-factor-authentication) if you or your users have two-factor authentication enabled.
+
+{% if page.version == 'dotcom' or page.version > 2.6 %}
+
+## List your grants
+
+You can use this API to list the set of OAuth applications that have been granted access to your account. Unlike the [list your authorizations](/v3/oauth_authorizations/#list-your-authorizations) API, this API does not manage individual tokens. This API will return one entry for each OAuth application that has been granted access to your account, regardless of the number of tokens an application has generated for your user. The list of OAuth applications returned matches what is shown on [the application authorizations settings screen within GitHub][authorized-application-listing]. The `scopes` returned are the union of scopes authorized for the application. For example, if an application has one token with `repo` scope and another token with `user` scope, the grant will return `["repo", "user"]`.
+
+ GET /applications/grants
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:oauth_authorization) { |h| [h] } %>
+
+## Get a single grant
+
+ GET /applications/grants/:id
+
+### Response
+
+<%= headers 200 %>
+<%= json(:oauth_authorization) %>
+
+## Delete a grant
+
+Deleting an OAuth application's grant will also delete all OAuth tokens associated with the application for your user. Once deleted, the application has no access to your account and is no longer listed on [the application authorizations settings screen within GitHub][authorized-application-listing].
+
+ DELETE /applications/grants/:id
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
## List your authorizations
@@ -20,7 +111,7 @@ users have two-factor authentication enabled.)
### Response
<%= headers 200, :pagination => default_pagination_rels %>
-<%= json(:oauth_access) { |h| [h] } %>
+<%= json(:oauth_access) { |h| [h.merge("token" => "")] } %>
## Get a single authorization
@@ -29,16 +120,16 @@ users have two-factor authentication enabled.)
### Response
<%= headers 200 %>
-<%= json :oauth_access %>
+<%= json(:oauth_access) { |h| h.merge("token" => "") } %>
## Create a new authorization
If you need a small number of tokens, implementing the [web flow](/v3/oauth/#web-application-flow)
-can be cumbersome. Instead, tokens can be created using the Authorizations API using
+can be cumbersome. Instead, tokens can be created using the OAuth Authorizations API using
[Basic Authentication](/v3/auth#basic-authentication). To create tokens for a particular OAuth application, you
must provide its client ID and secret, found on the OAuth application settings
-page, linked from your [OAuth applications listing on GitHub][app-listing]. OAuth tokens
-can also be created through the web UI via the [Application settings page](https://github.com/settings/applications).
+page, linked from your [OAuth applications listing on GitHub][app-listing]. If your OAuth application intends to create multiple tokens for one user you should use `fingerprint` to differentiate between them. OAuth tokens
+can also be created through the web UI via the [Personal access tokens settings][tokens-listing].
Read more about these tokens on the [GitHub Help page](https://help.github.com/articles/creating-an-access-token-for-command-line-use).
POST /authorizations
@@ -48,27 +139,27 @@ Read more about these tokens on the [GitHub Help page](https://help.github.com/a
Name | Type | Description
-----|------|--------------
`scopes`|`array` | A list of scopes that this authorization is in.
-`note`|`string` | A note to remind you what the OAuth token is for.
+`note`|`string` | **Required**. A note to remind you what the OAuth token is for. Tokens not associated with a specific OAuth application (i.e. personal access tokens) must have a unique note.
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
`client_id`|`string` | The 20 character OAuth app client key for which to create the token.
`client_secret`|`string` | The 40 character OAuth app client secret for which to create the token.
+`fingerprint`|`string` | A unique string to distinguish an authorization from others created for the same client ID and user.
<%= json :scopes => ["public_repo"], :note => 'admin script' %>
### Response
-<%= headers 201, :Location => "https://api.github.com/authorizations/1"
-%>
-<%= json :oauth_access %>
+<%= headers 201, :Location => get_resource(:oauth_access)['url'] %>
+<%= json(:oauth_access) { |h| h.merge("fingerprint" => "") } %>
## Get-or-create an authorization for a specific app
This method will create a new authorization for the specified OAuth application,
only if an authorization for that application doesn't already exist for the
-user. (The URL includes the 20 character client ID for the OAuth app that is
-requesting the token.) It returns the user's token for the application if one
-exists. Otherwise, it creates one.
+user. The URL includes the 20 character client ID for the OAuth app that is
+requesting the token. It returns the user's existing authorization for the
+application if one is present. Otherwise, it creates and returns a new one.
PUT /authorizations/clients/:client_id
@@ -76,26 +167,63 @@ exists. Otherwise, it creates one.
Name | Type | Description
-----|------|--------------
-`client_secret`|`string`| The 40 character OAuth app client secret associated with the client ID specified in the URL.
+`client_secret`|`string`| **Required**. The 40 character OAuth app client secret associated with the client ID specified in the URL.
`scopes`|`array` | A list of scopes that this authorization is in.
`note`|`string` | A note to remind you what the OAuth token is for.
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
+{% if page.version == 'dotcom' or page.version > 2.2 %}`fingerprint`|`string` | A unique string to distinguish an authorization from others created for the same client and user. If provided, this API is functionally equivalent to [Get-or-create an authorization for a specific app and fingerprint](/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint).{% endif %}
<%= json :client_secret => "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", :scopes => ["public_repo"], :note => 'admin script' %>
### Response if returning a new token
-<%= headers 201, :Location => "https://api.github.com/authorizations/1"
-%>
-<%= json :oauth_access %>
+<%= headers 201, :Location => get_resource(:oauth_access)['url'] %>
+<%= json(:oauth_access) { |h| h.merge("fingerprint" => "") } %>
### Response if returning an existing token
-<%= headers 200, :Location => "https://api.github.com/authorizations/1"
-%>
+<%= headers 200, :Location => get_resource(:oauth_access)['url'] %>
+<%= json(:oauth_access) { |h| h.merge("token" => "", "fingerprint" => "") } %>
+
+{% if page.version == 'dotcom' or page.version > 2.2 %}
+
+## Get-or-create an authorization for a specific app and fingerprint
+
+This method will create a new authorization for the specified OAuth application,
+only if an authorization for that application and fingerprint do not already
+exist for the user. The URL includes the 20 character client ID for the OAuth
+app that is requesting the token. `fingerprint` is a unique string to
+distinguish an authorization from others created for the same client ID and
+user. It returns the user's existing authorization for the application if one
+is present. Otherwise, it creates and returns a new one.
+
+ PUT /authorizations/clients/:client_id/:fingerprint
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`client_secret`|`string`| **Required**. The 40 character OAuth app client secret associated with the client ID specified in the URL.
+`scopes`|`array` | A list of scopes that this authorization is in.
+`note`|`string` | A note to remind you what the OAuth token is for.
+`note_url`|`string` | A URL to remind you what app the OAuth token is for.
+
+
+<%= json :client_secret => "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", :scopes => ["public_repo"], :note => 'admin script' %>
+
+### Response if returning a new token
+
+<%= headers 201, :Location => get_resource(:oauth_access)['url'] %>
<%= json :oauth_access %>
+### Response if returning an existing token
+
+<%= headers 200, :Location => get_resource(:oauth_access)['url'] %>
+<%= json(:oauth_access) { |h| h.merge("token" => "") } %>
+
+{% endif %}
+
## Update an existing authorization
PATCH /authorizations/:id
@@ -107,8 +235,9 @@ Name | Type | Description
`scopes`|`array` | Replaces the authorization scopes with these.
`add_scopes`|`array` | A list of scopes to add to this authorization.
`remove_scopes`|`array` | A list of scopes to remove from this authorization.
-`note`|`string` | A note to remind you what the OAuth token is for.
+`note`|`string` | A note to remind you what the OAuth token is for. Tokens not associated with a specific OAuth application (i.e. personal access tokens) must have a unique note.
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
+`fingerprint`|`string` | A unique string to distinguish an authorization from others created for the same client ID and user.
You can only send one of these scope keys at a time.
@@ -118,7 +247,7 @@ You can only send one of these scope keys at a time.
### Response
<%= headers 200 %>
-<%= json :oauth_access %>
+<%= json(:oauth_access) { |h| h.merge("token" => "") } %>
## Delete an authorization
@@ -144,19 +273,21 @@ will return `404 NOT FOUND`.
<%= headers 200 %>
<%= json(:oauth_access_with_user) %>
-## Revoke all authorizations for an application
+## Reset an authorization
-OAuth application owners can revoke every token for an OAuth application. You
-must use [Basic Authentication](/v3/auth#basic-authentication) when calling
-this method. The username is the OAuth application `client_id` and the password
-is its `client_secret`. Tokens are revoked via a background job, and it might
-take a few minutes for the process to complete.
+OAuth applications can use this API method to reset a valid OAuth token without
+end user involvement. Applications must save the "token" property in the
+response, because changes take effect immediately. You must use
+[Basic Authentication](/v3/auth#basic-authentication) when accessing it, where
+the username is the OAuth application `client_id` and the password is its
+`client_secret`. Invalid tokens will return `404 NOT FOUND`.
- DELETE /applications/:client_id/tokens
+ POST /applications/:client_id/tokens/:access_token
### Response
-<%= headers 204 %>
+<%= headers 200 %>
+<%= json(:oauth_access_with_user) %>
## Revoke an authorization for an application
@@ -187,5 +318,7 @@ links that might be of help:
* [Ruby Sinatra extension](https://github.com/atmos/sinatra_auth_github)
* [Ruby Warden strategy](https://github.com/atmos/warden-github)
-[app-listing]: https://github.com/settings/applications
+[app-listing]: https://github.com/settings/developers
+[tokens-listing]: https://github.com/settings/tokens
+[authorized-application-listing]: https://github.com/settings/applications#authorized
[basics auth guide]: /guides/basics-of-authentication/
diff --git a/content/v3/orgs.md b/content/v3/orgs.md
index f8d31b09da..aa7419a031 100644
--- a/content/v3/orgs.md
+++ b/content/v3/orgs.md
@@ -1,19 +1,18 @@
---
-title: Organizations | GitHub API
+title: Organizations
---
# Organizations
-* TOC
{:toc}
-## List User Organizations
+## List your organizations
-List all public organizations for an unauthenticated user. Lists private *and* public organizations for authenticated users.
+List organizations for the authenticated user.
- GET /users/:user/orgs
+### OAuth scope requirements
-List public and private organizations for the authenticated user.
+This only lists organizations that your authorization allows you to operate on in some way (e.g., you can list teams with `read:org` scope, you can publicize your organization membership with `user` scope, etc.). Therefore, this API requires at least `user` or `read:org` scope. OAuth requests with insufficient scope receive a `403 Forbidden` response.
GET /user/orgs
@@ -22,7 +21,51 @@ List public and private organizations for the authenticated user.
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:org) { |h| [h] } %>
-## Get an Organization
+{% if page.version == 'dotcom' or page.version >= 2.3 %}
+
+## List all organizations
+
+Lists all organizations, in the order that they were created on {{ site.data.variables.product.product_name }}.
+
+Note: Pagination is powered exclusively by the `since` parameter.
+Use the [Link header](/v3/#link-header) to get the URL for the next page of
+organizations.
+
+ GET /organizations
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`since`|`string`| The integer ID of the last Organization that you've seen.
+
+### Response
+
+<%= headers 200, :pagination => { :next => 'https://api.github.com/organizations?since=135' } %>
+<%= json(:org) {|h| [h] } %>
+
+{% endif %}
+
+## List user organizations
+
+List [public organization memberships](https://help.github.com/articles/publicizing-or-concealing-organization-membership) for the specified user.
+
+This method only lists *public* memberships, regardless of authentication. If you need to fetch all of the organization memberships (public and private) for the authenticated user, use the [List your organizations](#list-your-organizations) API instead.
+
+ GET /users/:username/orgs
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:org) { |h| [h] } %>
+
+## Get an organization
+
+{% if page.version == 'dotcom' or page.version >= 2.8 %}
+Note: To receive values for `private_gists`, `disk_usage`, `collaborators`, and
+`billing_email` in the Organization response, the authenticated user must be an
+organization owner and have authorized the `admin:org` scope.
+{% endif %}
GET /orgs/:org
@@ -31,19 +74,20 @@ List public and private organizations for the authenticated user.
<%= headers 200 %>
<%= json(:full_org) %>
-## Edit an Organization
+## Edit an organization
PATCH /orgs/:org
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`billing_email`|`string` | Billing email address. This address is not publicized.
`company`|`string` | The company name.
`email`|`string` | The publicly visible email address.
`location`|`string` | The location.
`name`|`string` | The shorthand name of the company.
+`description`|`string` | The description of the company.
### Example
@@ -53,7 +97,8 @@ Name | Type | Description
:company => "GitHub",
:email => "support@github.com",
:location => "San Francisco",
- :name => "github"
+ :name => "github",
+ :description => "GitHub, the company."
%>
### Response
diff --git a/content/v3/orgs/hooks.md b/content/v3/orgs/hooks.md
new file mode 100644
index 0000000000..a00c5c4836
--- /dev/null
+++ b/content/v3/orgs/hooks.md
@@ -0,0 +1,169 @@
+---
+title: Organization Webhooks
+---
+
+# Webhooks
+
+{:toc}
+
+{% if page.version != 'dotcom' and page.version <= 2.2 %}
+
+{{#tip}}
+
+The Organization Webhooks API is currently available for developers to preview.
+During the preview period, the API may change without advance notice.
+Please see the [blog post](/changes/2014-12-03-preview-the-new-organization-webhooks-api/) for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/enterprise/{{ page.version }}/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.sersi-preview+json
+```
+
+{{/tip}}
+
+{% endif %}
+
+Organization webhooks allow you to receive HTTP `POST` payloads whenever certain events happen within the organization. Subscribing to these events makes it possible to build integrations that react to actions on GitHub.com. For more information on actions you can subscribe to, check out our [Events documentation][webhook-events].
+
+## Scopes & Restrictions
+
+All actions against organization webhooks require the authenticated user to be an admin of the organization being managed. Additionally, OAuth tokens require [the `admin:org_hook` scope](/v3/oauth/#scopes).
+
+In order to protect sensitive data which may be present in webhook configurations, we also enforce the following access control rules:
+
+- OAuth applications cannot list, view, or edit webhooks which they did not create.
+- Users cannot list, view, or edit webhooks which were created by OAuth applications.
+
+## List hooks
+
+ GET /orgs/:org/hooks
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:org_hook) { |h| [h] } %>
+
+
+## Get single hook
+
+ GET /orgs/:org/hooks/:id
+
+### Response
+
+<%= headers 200 %>
+<%= json :org_hook %>
+
+
+## Create a hook
+
+ POST /orgs/:org/hooks
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`name`|`string` | **Required**. Must be passed as "web".
+`config`|`object` | **Required**. Key/value pairs to provide settings for this webhook. [These are defined below](#create-hook-config-params).
+`events`|`array` | Determines what [events][event-types] the hook is triggered for. Default: `["push"]`.
+`active`|`boolean` | Determines whether the hook is actually triggered on pushes.
+
+
+The `config` object can accept the following keys:
+
+<%= fetch_content(:org_hook_config_hash) %>
+
+#### Example
+
+Here's how you can create a hook that posts payloads in JSON format:
+
+<%= json \
+ :name => "web",
+ :active => true,
+ :events => ['push', 'pull_request'],
+ :config => {
+ :url => 'http://example.com/webhook',
+ :content_type => 'json'}
+%>
+
+### Response
+
+<%= headers 201, :Location => get_resource(:org_hook)['url'] %>
+<%= json :org_hook %>
+
+
+## Edit a hook
+
+ PATCH /orgs/:org/hooks/:id
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`config`|`object` | **Required**. Key/value pairs to provide settings for this webhook. [These are defined below](#update-hook-config-params).
+`events`|`array` | Determines what [events][event-types] the hook is triggered for. Default: `["push"]`.
+`active`|`boolean` | Determines whether the hook is actually triggered on pushes.
+
+
+The `config` object can accept the following keys:
+
+<%= fetch_content(:org_hook_config_hash) %>
+
+
+#### Example
+
+<%= json \
+ :active => true,
+ :events => ['pull_request']
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:org_hook) { |h| h.merge "events" => %w(pull_request) } %>
+
+
+## Ping a hook
+
+This will trigger a [ping event][ping-event-url] to be sent to the hook.
+
+ POST /orgs/:org/hooks/:id/pings
+
+### Response
+
+<%= headers 204 %>
+
+
+## Delete a hook
+
+ DELETE /orgs/:org/hooks/:id
+
+### Response
+
+<%= headers 204 %>
+
+
+## Receiving Webhooks
+
+In order for {{ site.data.variables.product.product_name }} to send webhook payloads, your server needs to be accessible from the Internet. We also highly suggest using SSL so that we can send encrypted payloads over HTTPS.
+
+For more best practices, [see our guide][best-integration-practices].
+
+### Webhook Headers
+
+{{ site.data.variables.product.product_name }} will send along several HTTP headers to differentiate between event types and payload identifiers.
+
+Name | Description
+-----|-----------|
+`X-GitHub-Event` | The [event type](/v3/activity/events/types/) that was triggered.
+`X-GitHub-Delivery` | A [guid][guid] to identify the payload and event being sent.
+`X-Hub-Signature` | The value of this header is computed as the HMAC hex digest of the body, using the `secret` config option as the key.
+
+
+[guid]: http://en.wikipedia.org/wiki/Globally_unique_identifier
+[ping-event-url]: /webhooks/#ping-event
+[webhook-events]: /webhooks/#events
+[event-types]: /v3/activity/events/types/
+[media-type]: /v3/media
+[best-integration-practices]: /guides/best-practices-for-integrators/
+[developer-blog-post]: /changes/2014-12-03-preview-the-new-organization-webhooks-api/
diff --git a/content/v3/orgs/members.md b/content/v3/orgs/members.md
index 5191f48347..6f1b79abe4 100644
--- a/content/v3/orgs/members.md
+++ b/content/v3/orgs/members.md
@@ -1,33 +1,49 @@
---
-title: Organization Members | GitHub API
+title: Organization Members
---
# Members
-* TOC
{:toc}
## Members list
-List all users who are members of an organization. A member is a user that
-belongs to at least 1 team in the organization. If the authenticated user is
-also an owner of this organization then both concealed and public members will
-be returned. If the requester is not an owner of the organization the query
-will be redirected to the [public members list](#public-members-list).
+List all users who are members of an organization. If the authenticated user is
+also a member of this organization then both concealed and public members will
+be returned.
GET /orgs/:org/members
-### Parameters {#audit-two-factor-auth}
+
+
+### Parameters
Name | Type | Description
--------|---------|--------------
-`filter`|`string` | Filter members returned in the list. Can be one of: * `2fa_disabled`: Members without [two-factor authentication][2fa-blog] enabled. Available for owners of organizations with private repositories. * `all`: All members the authenticated user can see.
If no permission is specified, the team's `permission` attribute will be used to determine what permission to grant the team on this repository.
+
+<%= fetch_content(:optional_put_content_length) %>
+
+{% endif %}
+
+
+{% if page.version != 'dotcom' and page.version > 2.3 and page.version < 2.6 %}
+
+{{#tip}}
+
+We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the [blog post](/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/) for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.ironman-preview+json
+```
+
+**Warning:** If you specify the `permission` attribute on an organization that hasn't had [improved organization permissions](https://github.com/blog/2020-improved-organization-permissions) enabled yet, you will get a `422` error response.
+
+{{/tip}}
+
+{% endif %}
+
### Response
<%= headers 204 %>
@@ -202,14 +556,22 @@ organization, you get:
:resource => :TeamMember}]
%>
-## Remove team repository {#remove-team-repo}
+
+
+## Remove team repository
-In order to remove a repository from a team, the authenticated user must be an
-owner of the org that the team is associated with. Also, since the Owners team
-always has access to all repositories in the organization, repositories cannot
-be removed from the Owners team.
+{% if page.version == 'dotcom' or page.version >= 2.4 %}
+
+In order to remove a repository from a team, the authenticated user must have
+admin access to the repository or be a maintainer of the team.
NOTE: This does not delete the repository, it just removes it from the team.
+{% else %}
+
+In order to remove a repository from a team, the authenticated user must be an owner of the org that the team is associated with. Also, since the Owners team always has access to all repositories in the organization, repositories cannot be removed from the Owners team.
+
+{% endif %}
+
DELETE /teams/:id/repos/:owner/:repo
### Response
@@ -219,14 +581,14 @@ NOTE: This does not delete the repository, it just removes it from the team.
## List user teams
List all of the teams across all of the organizations to which the
-authenticated user belongs. This method requires `user` or `repo`
-[scope][] when authenticating via [OAuth][].
+authenticated user belongs. This method requires `user`, `repo`, or
+`read:org` [scope][] when authenticating via [OAuth][].
GET /user/teams
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:full_team) { |h| [h] } %>
[OAuth]: /v3/oauth/
diff --git a/content/v3/pulls.md b/content/v3/pulls.md
index e4366c321e..332c98ff3d 100644
--- a/content/v3/pulls.md
+++ b/content/v3/pulls.md
@@ -1,10 +1,9 @@
---
-title: Pull Requests | GitHub API
+title: Pull Requests
---
# Pull Requests
-* TOC
{:toc}
The Pull Request API allows you to list, view, edit, create, and even merge
@@ -42,12 +41,11 @@ Name | Type | Description
`head`|`string` | Filter pulls by head user and branch name in the format of `user:ref-name`. Example: `github:new-script-format`.
`base`|`string` | Filter pulls by base branch name. Example: `gh-pages`.
`sort`|`string`| What to sort results by. Can be either `created`, `updated`, `popularity` (comment count) or `long-running` (age, filtering by pulls updated in the last month). Default: `created`
-`direction`|`string`| The direction of the sort. Can be either `asc` or `desc`. Default: `desc`
-
+`direction`|`string`| The direction of the sort. Can be either `asc` or `desc`. Default: `desc` when sort is `created` or sort is not specified, otherwise `asc`.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:pull) { |h| [h] } %>
## Get a single pull request
@@ -56,12 +54,9 @@ Name | Type | Description
### Response
-<%= headers 200 %>
-<%= json :full_pull %>
-
-### Mergability
+{{#tip}}
-Each time the pull request receives new commits, GitHub creates a merge commit
+Each time the pull request receives new commits, {{ site.data.variables.product.product_name }} creates a merge commit
to _test_ whether the pull request can be automatically merged into the base
branch. (This _test_ commit is not added to the base branch or the head branch.)
The `merge_commit_sha` attribute holds the SHA of the _test_ merge commit;
@@ -69,10 +64,19 @@ however, this attribute is [deprecated](/v3/versions/#v3-deprecations) and is sc
removal in the next version of the API. The Boolean `mergeable` attribute will
remain to indicate whether the pull request can be automatically merged.
-### Alternative Response Formats
+The value of the `mergeable` attribute can be `true`, `false`, or `null`. If
+the value is `null`, this means that the mergeability hasn't been computed yet,
+and a background job was started to compute it. Give the job a few moments to
+complete, and then submit the request again. When the job is complete, the
+response will include a non-`null` value for the `mergeable` attribute.
+
+{{/tip}}
Pass the appropriate [media type](/v3/media/#commits-commit-comparison-and-pull-requests) to fetch diff and patch formats.
+<%= headers 200 %>
+<%= json :full_pull %>
+
## Create a pull request
POST /repos/:owner/:repo/pulls
@@ -83,7 +87,7 @@ Name | Type | Description
-----|------|-------------
`title`|`string` | **Required**. The title of the pull request.
`head`|`string` | **Required**. The name of the branch where your changes are implemented. For cross-repository pull requests in the same network, namespace `head` with a user like this: `username:branch`.
-`base`|`string` | **Required**. The name of the branch you want your changes pulled into. This should be an existing branch on the current repository. You cannot submit a pull request to one repository that requests a merge to a base of another repository.
+`base`|`string` | **Required**. The name of the branch you want the changes pulled into. This should be an existing branch on the current repository. You cannot submit a pull request to one repository that requests a merge to a base of another repository.
`body`|`string` | The contents of the pull request.
@@ -103,19 +107,19 @@ Issue number instead of `title` and `body`.
Name | Type | Description
-----|------|--------------
-`issue`|`number` | **Required**. The issue number in this repository to turn into a Pull Request.
+`issue`|`integer` | **Required**. The issue number in this repository to turn into a Pull Request.
#### Example
<%= json \
- :issue => "5",
+ :issue => 5,
:head => "octocat:new-feature",
:base => "master"
%>
### Response
-<%= headers 201, :Location => "https://api.github.com/user/repo/pulls/1" %>
+<%= headers 201, :Location => get_resource(:pull)['url'] %>
<%= json :pull %>
## Update a pull request
@@ -128,14 +132,18 @@ Name | Type | Description
-----|------|--------------
`title`|`string` | The title of the pull request.
`body`|`string` | The contents of the pull request.
-`state`|`string` | State of this Pull Request. Either `open` or `closed`.
+`state`|`string` | State of this Pull Request. Either `open` or `closed`.{% if page.version == 'dotcom' or page.version >= 2.8 %}
+`base`|`string` | The name of the branch you want your changes pulled into. This should be an existing branch on the current repository. You cannot update the base branch on a pull request to point to another repository.
+{% endif %}
#### Example
<%= json \
:title => "new title",
:body => "updated body",
- :state => "open"
+ :state => "open"{% if page.version == 'dotcom' or page.version >= 2.8 %},
+ :base => "master"
+{% endif %}
%>
### Response
@@ -149,7 +157,7 @@ Name | Type | Description
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:commit) { |h| [h] } %>
Note: The response includes a maximum of 250 commits. If you are working with a pull request larger than that, you can use the [Commit List API](/v3/repos/commits/#list-commits-on-a-repository) to enumerate all commits in the pull request.
@@ -160,7 +168,7 @@ Note: The response includes a maximum of 250 commits. If you are working with a
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:file) { |h| [h] } %>
## Get if a pull request has been merged
@@ -175,7 +183,7 @@ Note: The response includes a maximum of 250 commits. If you are working with a
<%= headers 404 %>
-## Merge a pull request (Merge Button™)
+## Merge a pull request (Merge Button)
PUT /repos/:owner/:repo/pulls/:number/merge
@@ -183,8 +191,26 @@ Note: The response includes a maximum of 250 commits. If you are working with a
Name | Type | Description
-----|------|-------------
-`commit_message`|`string`| The message that will be used for the merge commit
+{% if page.version == 'dotcom' or page.version >= 2.6 %}`commit_title`|`string`| Title for the automatic commit message.{% endif %}
+`commit_message`|`string`| Extra detail to append to automatic commit message.
+`sha`|`string`| SHA that pull request head must match to allow merge
+{% if page.version == 'dotcom' or page.version >= 2.6 %}`squash`|`boolean`| Commit a single commit to the head branch.{% endif %}
+{% if page.version == 'dotcom' or page.version >= 2.6 %}
+
+{{#tip}}
+
+The `commit_title` and `squash` parameters are currently available for developers to preview. During the preview period, the API may change without advance notice. Please see the [blog post](/changes/2016-04-01-squash-api-preview) for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.polaris-preview+json
+```
+
+{{/tip}}
+
+{% endif %}
### Response if merge was successful
@@ -199,11 +225,22 @@ Name | Type | Description
<%= headers 405 %>
<%= json \
- :sha => nil,
- :merged => false,
- :message => 'Failure reason'
+ :message => "Pull Request is not mergeable",
+ :documentation_url => "https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button"
+%>
+
+### Response if sha was provided and pull request head did not match
+
+<%= headers 409 %>
+<%= json \
+ :message => "Head branch was modified. Review and try the merge again.",
+ :documentation_url => "https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button"
%>
+## Labels, assignees, and milestones
+
+Every pull request is an issue, but not every issue is a pull request. For this reason, "shared" actions for both features, like manipulating assignees, labels and milestones, are provided within [the Issues API](/v3/issues).
+
## Custom media types
These are the supported media types for pull requests. You can read more about the
@@ -213,3 +250,9 @@ use of media types in the API [here](/v3/media/).
application/vnd.github.VERSION.text+json
application/vnd.github.VERSION.html+json
application/vnd.github.VERSION.full+json
+ application/vnd.github.VERSION.diff
+ application/vnd.github.VERSION.patch
+
+
+
+If a diff is corrupt, contact {{ site.data.variables.contact.contact_support }} to receive help. Be sure to include the repository name and pull request ID.
diff --git a/content/v3/pulls/comments.md b/content/v3/pulls/comments.md
index 8554349576..fa543427ab 100644
--- a/content/v3/pulls/comments.md
+++ b/content/v3/pulls/comments.md
@@ -1,10 +1,9 @@
---
-title: Review Comments | GitHub API
+title: Review Comments
---
# Review Comments
-* TOC
{:toc}
Pull Request Review Comments are comments on a portion of the unified
@@ -22,9 +21,30 @@ types](#custom-media-types). You can read more about the use of media types in t
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:pull_comment) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the review comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :pull_comment_reaction_summary %>
+{% endif %}
+
## List comments in a repository
GET /repos/:owner/:repo/pulls/comments
@@ -42,18 +62,60 @@ Name | Type | Description
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:pull_comment) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the review comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :pull_comment_reaction_summary %>
+{% endif %}
+
## Get a single comment
- GET /repos/:owner/:repo/pulls/comments/:number
+ GET /repos/:owner/:repo/pulls/comments/:id
### Response
<%= headers 200 %>
<%= json :pull_comment %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the review comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :pull_comment_reaction_summary %>
+{% endif %}
+
## Create a comment
POST /repos/:owner/:repo/pulls/:number/comments
@@ -65,8 +127,15 @@ Name | Type | Description
`body`|`string` | **Required**. The text of the comment
`commit_id`|`string` | **Required**. The SHA of the commit to comment on.
`path`|`string` | **Required**. The relative path of the file to comment on.
-`position`|`number` | **Required**. The line index in the diff to comment on.
+`position`|`integer` | **Required**. The line index in the diff to comment on.
+
+{{#tip}}
+
+When passing the `commit_id`, use the SHA of the latest commit in the pull request or your comment may appear as "outdated" if the specified `position` has been modified in a subsequent commit.
+
+To comment on a specific line in a file, you will need to first determine the position in the diff. GitHub offers a `application/vnd.github.v3.diff` media type which you can use in a preceding request to view the pull request's diff. The diff needs to be [interpreted](https://en.wikipedia.org/wiki/Diff_utility#Unified_format) to translate from the *line in the file* to a *position in the diff*. The `position` value is the number of lines down from the first "@@" hunk header in the file you would like to comment on. The line just below the "@@" line is position 1, the next line is position 2, and so on. The position in the file's diff continues to increase through lines of whitespace and additional hunks until a new file is reached.
+{{/tip}}
#### Example
@@ -85,7 +154,7 @@ an existing Pull Request Comment like this:
Name | Type | Description
-----|------|--------------
`body`|`string` | **Required**. The text of the comment
-`in_reply_to`|`number` | **Required**. The comment id to reply to.
+`in_reply_to`|`integer` | **Required**. The comment id to reply to.
#### Example
@@ -97,14 +166,12 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location =>
-"https://api.github.com/repos/octocat/Hello-World/pulls/comments/1" %>
+<%= headers 201, :Location => get_resource(:pull_comment)['url'] %>
<%= json :pull_comment %>
## Edit a comment
- PATCH /repos/:owner/:repo/pulls/comments/:number
+ PATCH /repos/:owner/:repo/pulls/comments/:id
### Input
@@ -126,7 +193,7 @@ Name | Type | Description
## Delete a comment
- DELETE /repos/:owner/:repo/pulls/comments/:number
+ DELETE /repos/:owner/:repo/pulls/comments/:id
### Response
diff --git a/content/v3/rate_limit.md b/content/v3/rate_limit.md
index 83288c934a..cb27f21b3b 100644
--- a/content/v3/rate_limit.md
+++ b/content/v3/rate_limit.md
@@ -1,7 +1,9 @@
---
-title: Rate Limit | GitHub API
+title: Rate Limit
---
+{% if page.version == 'dotcom' %}
+
# Rate Limit
The overview documentation describes the [rate limit rules](/v3/#rate-limiting).
@@ -25,7 +27,7 @@ Note: Accessing this endpoint does not count against your rate limit.
<%=
json :resources => {
:core => {:limit => 5000, :remaining => 4999, :reset => 1372700873},
- :search => {:limit => 20, :remaining => 18, :reset => 1372697452},
+ :search => {:limit => 30, :remaining => 18, :reset => 1372697452},
},
:rate => {:limit => 5000, :remaining => 4999, :reset => 1372700873}
%>
@@ -36,16 +38,18 @@ Note: Accessing this endpoint does not count against your rate limit.
The Search API has a [custom rate limit](/v3/search/#rate-limit), separate from
the rate limit governing the rest of the API. For that reason, the response
(shown above) categorizes your rate limit by resource. Within the `"resources"`
-hash, the `"search"` hash provides your rate limit status for the
-[Search API](/v3/search). The `"core"` hash provides your rate limit status for
+object, the `"search"` object provides your rate limit status for the
+[Search API](/v3/search). The `"core"` object provides your rate limit status for
all the _rest_ of the API.
#### Deprecation Notice
-The `"rate"` hash (shown at the bottom of the response above) is
+The `"rate"` object (shown at the bottom of the response above) is
[deprecated](/v3/versions/#v3-deprecations) and is scheduled for removal in the next
version of the API.
If you're writing new API client code (or updating your existing code), you
-should use the `"core"` hash instead of the `"rate"` hash. The `"core"` hash
-contains the same information that is present in the `"rate"` hash.
+should use the `"core"` object instead of the `"rate"` object. The `"core"` object
+contains the same information that is present in the `"rate"` object.
+
+{% endif %}
diff --git a/content/v3/reactions.md b/content/v3/reactions.md
new file mode 100644
index 0000000000..d8effc8a38
--- /dev/null
+++ b/content/v3/reactions.md
@@ -0,0 +1,208 @@
+---
+title: Reactions
+---
+
+{% if page.version == 'dotcom' or page.version >= 2.7 %}
+
+# Reactions
+
+{{#tip}}
+
+
+
+ APIs for managing reactions are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+{{/tip}}
+
+{:toc}
+
+
+## Reaction types
+
+ When creating a reaction, the allowed values for the `content` parameter are as follows (with the corresponding emoji for reference):
+
+content | emoji
+-----|------
+`+1` | :+1:
+`-1` | :-1:
+`laugh` | :smile:
+`confused` | :confused:
+`heart` | :heart:
+`hooray` | :tada:
+
+
+## List reactions for a commit comment
+
+ GET /repos/:owner/:repo/comments/:id/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | Indicates which type of reaction to return.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:reaction) { |h| [h] } %>
+
+
+## Create reaction for a commit comment
+
+ POST /repos/:owner/:repo/comments/:id/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | **Required**. The reaction type
+
+<%= json :content => 'heart' %>
+
+### Response
+
+{{#tip}}
+
+ If you have already created a reaction of type `content`, the previously created reaction will be returned with `Status: 200 OK`.
+
+{{/tip}}
+
+<%= headers 201 %>
+<%= json :reaction %>
+
+
+## List reactions for an issue
+
+ GET /repos/:owner/:repo/issues/:number/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | Indicates which type of reaction to return.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:reaction) { |h| [h] } %>
+
+
+## Create reaction for an issue
+
+ POST /repos/:owner/:repo/issues/:number/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | **Required**. The reaction type
+
+<%= json :content => 'heart' %>
+
+### Response
+
+{{#tip}}
+
+ If you have already created a reaction of type `content`, the previously created reaction will be returned with `Status: 200 OK`.
+
+{{/tip}}
+
+<%= headers 201 %>
+<%= json :reaction %>
+
+
+## List reactions for an issue comment
+
+ GET /repos/:owner/:repo/issues/comments/:id/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | Indicates which type of reaction to return.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:reaction) { |h| [h] } %>
+
+
+## Create reaction for an issue comment
+
+ POST /repos/:owner/:repo/issues/comments/:id/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | **Required**. The reaction type
+
+<%= json :content => 'heart' %>
+
+### Response
+
+{{#tip}}
+
+ If you have already created a reaction of type `content`, the previously created reaction will be returned with `Status: 200 OK`.
+
+{{/tip}}
+
+<%= headers 201 %>
+<%= json :reaction %>
+
+
+## List reactions for a pull request review comment
+
+ GET /repos/:owner/:repo/pulls/comments/:id/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | Indicates which type of reaction to return.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:reaction) { |h| [h] } %>
+
+
+## Create reaction for a pull request review comment
+
+ POST /repos/:owner/:repo/pulls/comments/:id/reactions
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`content`|`string` | **Required**. The reaction type
+
+<%= json :content => 'heart' %>
+
+### Response
+
+{{#tip}}
+
+ If you have already created a reaction of type `content`, the previously created reaction will be returned with `Status: 200 OK`.
+
+{{/tip}}
+
+<%= headers 201 %>
+<%= json :reaction %>
+
+
+## Delete a reaction
+
+ DELETE /reactions/:id
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
diff --git a/content/v3/repos.md b/content/v3/repos.md
index c6c564b917..2e8b726228 100644
--- a/content/v3/repos.md
+++ b/content/v3/repos.md
@@ -1,19 +1,18 @@
---
-title: Repositories | GitHub API
+title: Repositories
---
# Repositories
-* TOC
{:toc}
## List your repositories
-List repositories for the authenticated user. Note that this does not include
-repositories owned by organizations which the user can access. You can
-[list user organizations](/v3/orgs/#list-user-organizations) and
-[list organization repositories](/v3/repos/#list-organization-repositories)
-separately.
+List repositories that are accessible to the authenticated user.
+
+This includes repositories owned by the authenticated user, repositories where
+the authenticated user is a collaborator, and repositories that the
+authenticated user has access to through an organization membership.
GET /user/repos
@@ -21,16 +20,17 @@ separately.
Name | Type | Description
-----|------|--------------
-`type`|`string` | Can be one of `all`, `owner`, `public`, `private`, `member`. Default: `all`
+`visibility` | `string` | Can be one of `all`, `public`, or `private`. Default: `all`
+`affiliation` | `string` | Comma-separated list of values. Can include: * `owner`: Repositories that are owned by the authenticated user. * `collaborator`: Repositories that the user has been added to as a collaborator. * `organization_member`: Repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on.
Default: `owner,collaborator,organization_member`
+`type`|`string` | Can be one of `all`, `owner`, `public`, `private`, `member`. Default: `all`
Will cause a `422` error if used in the same request as **visibility** or **affiliation**.
`sort`|`string` | Can be one of `created`, `updated`, `pushed`, `full_name`. Default: `full_name`
`direction`|`string` | Can be one of `asc` or `desc`. Default: when using `full_name`: `asc`; otherwise `desc`
-
## List user repositories
List public repositories for the specified user.
- GET /users/:user/repos
+ GET /users/:username/repos
### Parameters
@@ -59,12 +59,6 @@ Name | Type | Description
<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:repo) { |h| [h] } %>
-
-
- Note: When using the v3 media type, the response omits the master_branch attribute. API clients should instead use the default_branch attribute to obtain the repository's default branch.
-
-
-
## List all public repositories
This provides a dump of every public repository, in the order that they were created.
@@ -73,6 +67,19 @@ Note: Pagination is powered exclusively by the `since` parameter.
Use the [Link header](/v3/#link-header) to get the URL for the next page of
repositories.
+{% if page.version != 'dotcom' and page.version >= 2.3 %}
+
+If you are an [authenticated](/v3/#authentication) site administrator for your Enterprise instance,
+you will be able to list all repositories including private repositories.
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`visibility`|`string`| To include private repositories as well set to `all`. Default: `public`
+
+{% endif %}
+
GET /repositories
### Parameters
@@ -89,8 +96,7 @@ Name | Type | Description
## Create
-Create a new repository for the authenticated user. OAuth users must supply
-`repo` scope.
+Create a new repository for the authenticated user.
POST /user/repos
@@ -99,6 +105,13 @@ be a member of the specified organization.
POST /orgs/:org/repos
+### OAuth scope requirements
+
+When using [OAuth](/v3/oauth/#scopes), authorizations must include:
+
+- `public_repo` scope or `repo` scope to create a public repository
+- `repo` scope to create a private repository
+
### Input
Name | Type | Description
@@ -110,10 +123,10 @@ Name | Type | Description
`has_issues`|`boolean` | Either `true` to enable issues for this repository, `false` to disable them. Default: `true`
`has_wiki`|`boolean` | Either `true` to enable the wiki for this repository, `false` to disable it. Default: `true`
`has_downloads`|`boolean` | Either `true` to enable downloads for this repository, `false` to disable them. Default: `true`
-`team_id`|`number` | The id of the team that will be granted access to this repository. This is only valid when creating a repository in an organization.
+`team_id`|`integer` | The id of the team that will be granted access to this repository. This is only valid when creating a repository in an organization.
`auto_init`|`boolean` | Pass `true` to create an initial commit with empty README. Default: `false`
-`gitignore_template`|`string` | Desired language or platform [.gitignore template](https://github.com/github/gitignore) to apply. Use the name of the template without the extension. For example, "Haskell". _Ignored if the `auto_init` parameter is not provided._
-`license_template`|`string` | Desired [LICENSE template](https://github.com/github/choosealicense.com) to apply. Use the [name of the template](https://github.com/github/choosealicense.com/tree/gh-pages/licenses) without the extension. For example, "mit" or "mozilla". _Ignored if the `auto_init` parameter is not provided._
+`gitignore_template`|`string` | Desired language or platform [.gitignore template](https://github.com/github/gitignore) to apply. Use the name of the template without the extension. For example, "Haskell".
+`license_template`|`string` | Desired [LICENSE template](https://github.com/github/choosealicense.com) to apply. Use the [name of the template](https://github.com/github/choosealicense.com/tree/gh-pages/_licenses) without the extension. For example, "mit" or "mozilla".
#### Example
@@ -129,9 +142,7 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location =>
-'https://api.github.com/repos/octocat/Hello-World' %>
+<%= headers 201, :Location => get_resource(:repo)['url'] %>
<%= json :repo %>
## Get
@@ -144,12 +155,6 @@ The `parent` and `source` objects are present when the repository is a fork.
`parent` is the repository this repository was forked from,
`source` is the ultimate source for the network.
-
-
- Note: When using the v3 media type, the response omits the master_branch attribute. API clients should instead use the default_branch attribute to obtain the repository's default branch.
-
-
-
<%= headers 200 %>
<%= json :full_repo %>
@@ -191,6 +196,14 @@ Name | Type | Description
List contributors to the specified repository, sorted by the number of commits per contributor in descending order.
+{{#tip}}
+
+Contributors data is cached for performance reasons. This endpoint may return information that is a few hours old.
+
+Git contributors are identified by author email address. This API attempts to group contribution counts by GitHub user, across all of their associated email addresses. For performance reasons, only the first 500 author email addresses in the repository will be linked to GitHub users. The rest will appear as anonymous contributors without associated GitHub user information.
+
+{{/tip}}
+
GET /repos/:owner/:repo/contributors
### Parameters
@@ -202,7 +215,7 @@ Name | Type | Description
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:contributor) { |h| [h] } %>
## List languages
@@ -225,7 +238,7 @@ List languages for the specified repository. The value on the right of a languag
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:team) { |h| [h] } %>
## List Tags
@@ -234,27 +247,9 @@ List languages for the specified repository. The value on the right of a languag
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:tag) { |h| [h] } %>
-## List Branches
-
- GET /repos/:owner/:repo/branches
-
-### Response
-
-<%= headers 200 %>
-<%= json(:branches) %>
-
-## Get Branch
-
- GET /repos/:owner/:repo/branches/:branch
-
-### Response
-
-<%= headers 200 %>
-<%= json(:branch) %>
-
## Delete a Repository
Deleting a repository requires admin access. If OAuth is used, the
diff --git a/content/v3/repos/branches.md b/content/v3/repos/branches.md
new file mode 100644
index 0000000000..e620efd95c
--- /dev/null
+++ b/content/v3/repos/branches.md
@@ -0,0 +1,522 @@
+---
+title: Branches
+---
+
+# Branches
+
+{:toc}
+
+{% if page.version != 'dotcom' and page.version >= 2.5 and page.version < 2.7 %}
+
+## List Branches
+
+ GET /repos/:owner/:repo/branches
+
+### Parameters
+
+Name | Type | Description
+-----|------|-------------
+`protected`| `boolean` | Set to `true` to only return protected branches
+
+{{#tip}}
+
+
+
+ The Protected Branch API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2015-11-11-protected-branches-api) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.loki-preview+json
+
+ The `protection` key will only be present in branch payloads if this header is passed.
+
+{{/tip}}
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:branches) { |a| a.each { |b| b.merge!("protection" => {
+ "enabled" => false,
+ "required_status_checks" => {
+ "enforcement_level" => "off",
+ "contexts" => []
+ }
+}) } } %>
+
+## Get Branch
+
+ GET /repos/:owner/:repo/branches/:branch
+
+### Response
+
+{{#tip}}
+
+
+
+ The Protected Branch API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2015-11-11-protected-branches-api) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.loki-preview+json
+
+ The `protection` key will only be present in branch payloads if this header is passed.
+
+{{/tip}}
+
+<%= headers 200 %>
+<%= json(:branch) { |h| h.merge!("protection" => {
+ "enabled" => false,
+ "required_status_checks" => {
+ "enforcement_level" => "off",
+ "contexts" => []
+ }
+}) } %>
+
+## Enabling and disabling branch protection
+
+{{#tip}}
+
+
+
+ The Protected Branch API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2015-11-11-protected-branches-api) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.loki-preview+json
+
+{{/tip}}
+
+Protecting a branch requires admin access.
+
+ PATCH /repos/:owner/:repo/branches/:branch
+
+### Parameters
+
+You need to pass a `protection` object.
+
+Name | Type | Description
+-----|------|-------------
+`enabled`|`boolean` | **Required**. Should this branch be protected or not
+`required_status_checks`|`object`| Configure required status checks here
+
+The `required_status_checks` object must have the following keys:
+
+Name | Type | Description
+-----|------|-------------
+`enforcement_level`|`string` | **Required**. Who required status checks apply to. Options are `off`, `non_admins` or `everyone`.
+`contexts`|`array` | **Required**. The list of status checks to require in order to merge into this branch
+
+The `enforcement_level` key can have the following values:
+
+Name | Description
+------|------------
+`off` | Turn off required status checks for this branch.
+`non_admins` | Required status checks will be enforced for non-admins.
+`everyone` | Required status checks will be enforced for everyone (including admins).
+
+#### Example
+
+<%= json \
+ "protection" => {
+ "enabled" => true,
+ "required_status_checks" => {
+ "enforcement_level" => "everyone",
+ "contexts" => ["continuous-integration/travis-ci"]
+ }
+ }
+%>
+
+{% endif %}
+
+{% if page.version == 'dotcom' or page.version >= 2.7 %}
+
+{{#tip}}
+
+
+
+ The Protected Branch API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2016-06-27-protected-branches-api-update) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.loki-preview+json
+
+{{/tip}}
+
+## List Branches
+
+ GET /repos/:owner/:repo/branches
+
+### Parameters
+
+Name | Type | Description
+-----|------|-------------
+`protected` | `boolean` | Set to `true` to only return protected branches
+
+{{#tip}}
+
+
+
+ The Protected Branch API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2016-06-27-protected-branches-api-update) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.loki-preview+json
+
+ The `protected` key will only be present in branch payloads if this header is passed.
+
+{{/tip}}
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:branches) { |a| a.each { |b| b.merge!(
+ "protected": true,
+ "protection_url": "https://api.github.com/repos/octocat/Hello-World/branches/#{b["name"]}/protection",
+) } } %>
+
+## Get Branch
+
+ GET /repos/:owner/:repo/branches/:branch
+
+### Response
+
+{{#tip}}
+
+
+
+ The Protected Branch API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+ Please see the [blog post](/changes/2016-06-27-protected-branches-api-update) for full details.
+
+ To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.loki-preview+json
+
+ The `protected` key will only be present in branch payloads if this header is passed.
+
+{{/tip}}
+
+<%= headers 200 %>
+<%= json(:branch) { |h| h.merge!(
+ "protected": true,
+ "protection_url": "https://api.github.com/repos/octocat/Hello-World/branches/#{h["name"]}/protection",
+) } %>
+
+
+## Get branch protection
+
+ GET /repos/:owner/:repo/branches/:branch/protection
+
+<%= headers 200 %>
+<%= json(:repo_branch_protection) %>
+
+## Update branch protection
+
+Protecting a branch requires admin access.
+
+ PUT /repos/:owner/:repo/branches/:branch/protection
+
+### Parameters
+
+You must pass two objects: `required_status_checks` and `restrictions`. Both can have the value `null` for disabled.
+
+The `required_status_checks` object must have the following keys:
+
+Name | Type | Description
+-----|------|-------------
+`include_admins` | `boolean` | **Required**. Enforce required status checks for repository administrators.
+`strict` | `boolean` | **Required**. Require branches to be up to date before merging.
+`contexts` | `array` | **Required**. The list of status checks to require in order to merge into this branch
+
+The `restrictions` object must have the following keys:
+
+Name | Type | Description
+-----|------|-------------
+`users` | `array` | The list of user `login`s with push access
+`teams` | `array` | The list of team `slug`s with push access
+
+{{#tip}}
+
+* Teams and users `restrictions` are only available for organization-owned repositories.
+* The list of users and teams in total is limited to 100 items.
+
+{{/tip}}
+
+### Example
+
+<%= json \
+ "required_status_checks" => {
+ "include_admins" => true,
+ "strict" => true,
+ "contexts" => ["continuous-integration/travis-ci"]
+ },
+ "restrictions" => {
+ "users" => ["octocat"],
+ "teams" => ["justice-league"]
+ }
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:repo_branch_protection) %>
+
+## Remove branch protection
+
+ DELETE /repos/:owner/:repo/branches/:branch/protection
+
+<%= headers 204 %>
+
+## Get required status checks of protected branch
+
+ GET /repos/:owner/:repo/branches/:branch/protection/required_status_checks
+
+<%= headers 200 %>
+<%= json(:repo_branch_protection_required_status_checks) %>
+
+## Update required status checks of protected branch
+
+Updating required status checks requires admin access and branch protection to be enabled.
+
+ PATCH /repos/:owner/:repo/branches/:branch/protection/required_status_checks
+
+### Parameters
+
+The object passed can have the following keys:
+
+Name | Type | Description
+-----|------|-------------
+`include_admins`|`boolean` | Enforce required status checks for repository administrators.
+`strict`|`boolean` | Require branches to be up to date before merging.
+`contexts`|`array` | The list of status checks to require in order to merge into this branch
+
+### Example
+
+<%= json \
+ "include_admins" => true,
+ "strict" => true,
+ "contexts" => ["continuous-integration/travis-ci"]
+%>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:repo_branch_protection_required_status_checks) %>
+
+## Remove required status checks of protected branch
+
+ DELETE /repos/:owner/:repo/branches/:branch/protection/required_status_checks
+
+<%= headers 204 %>
+
+## List required status checks contexts of protected branch
+
+ GET /repos/:owner/:repo/branches/:branch/protection/required_status_checks/contexts
+
+<%= headers 200 %>
+<%= json ["continuous-integration/travis-ci"] %>
+
+## Replace required status checks contexts of protected branch
+
+ PUT /repos/:owner/:repo/branches/:branch/protection/required_status_checks/contexts
+
+### Example
+
+<%= json ["continuous-integration/travis-ci"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json ["continuous-integration/travis-ci"] %>
+
+## Add required status checks contexts of protected branch
+
+ POST /repos/:owner/:repo/branches/:branch/protection/required_status_checks/contexts
+
+### Example
+
+<%= json ["continuous-integration/jenkins"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json ["continuous-integration/travis-ci", "continuous-integration/jenkins"] %>
+
+## Remove required status checks contexts of protected branch
+
+ DELETE /repos/:owner/:repo/branches/:branch/protection/required_status_checks/contexts
+
+### Example
+
+<%= json ["continuous-integration/jenkins"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json ["continuous-integration/travis-ci"] %>
+
+
+## Get restrictions of protected branch
+
+{{#tip}}
+
+Teams and users `restrictions` are only available for organization-owned repositories.
+
+{{/tip}}
+
+ GET /repos/:owner/:repo/branches/:branch/protection/restrictions
+
+<%= headers 200 %>
+<%= json(:repo_branch_protection_restrictions) %>
+
+## Remove restrictions of protected branch
+
+ DELETE /repos/:owner/:repo/branches/:branch/protection/restrictions
+
+<%= headers 204 %>
+
+## List team restrictions of protected branch
+
+ GET /repos/:owner/:repo/branches/:branch/protection/restrictions/teams
+
+<%= headers 200 %>
+<%= json(:team) { |h| [h] } %>
+
+## Replace team restrictions of protected branch
+
+ PUT /repos/:owner/:repo/branches/:branch/protection/restrictions/teams
+
+### Body parameters
+
+Pass the list of team `slug`s with push access.
+
+{{#tip}}
+
+ The list of users and teams in total is limited to 100 items.
+
+{{/tip}}
+
+### Example
+
+<%= json ["justice-league"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:team) { |h| [h] } %>
+
+## Add team restrictions of protected branch
+
+ POST /repos/:owner/:repo/branches/:branch/protection/restrictions/teams
+
+### Body parameters
+
+Pass the list of team `slug`s with push access.
+
+{{#tip}}
+
+The list of users and teams in total is limited to 100 items.
+
+{{/tip}}
+
+### Example
+
+<%= json ["justice-league"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:team) { |h| [h] } %>
+
+## Remove team restrictions of protected branch
+
+ DELETE /repos/:owner/:repo/branches/:branch/protection/restrictions/teams
+
+### Example
+
+<%= json ["octocats"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:team) { |h| [h] } %>
+
+
+## List user restrictions of protected branch
+
+ GET /repos/:owner/:repo/branches/:branch/protection/restrictions/users
+
+<%= headers 200 %>
+<%= json(:user) { |h| [h] } %>
+
+## Replace user restrictions of protected branch
+
+ PUT /repos/:owner/:repo/branches/:branch/protection/restrictions/users
+
+### Body parameters
+
+Pass the list of user `login`s with push access.
+
+{{#tip}}
+
+The list of users and teams in total is limited to 100 items.
+
+{{/tip}}
+
+### Example
+
+<%= json ["octocat"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:user) { |h| [h] } %>
+
+## Add user restrictions of protected branch
+
+ POST /repos/:owner/:repo/branches/:branch/protection/restrictions/users
+
+### Body parameters
+
+Pass the list of user `login`s with push access.
+
+{{#tip}}
+
+The list of users and teams in total is limited to 100 items.
+
+{{/tip}}
+
+### Example
+
+<%= json ["octocat"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:user) { |h| [h] } %>
+
+## Remove user restrictions of protected branch
+
+ DELETE /repos/:owner/:repo/branches/:branch/protection/restrictions/users
+
+### Example
+
+<%= json ["defunkt"] %>
+
+### Response
+
+<%= headers 200 %>
+<%= json(:user) { |h| [h] } %>
+
+
+{% endif %}
diff --git a/content/v3/repos/collaborators.md b/content/v3/repos/collaborators.md
index 2c54d8114b..5e22e210d7 100644
--- a/content/v3/repos/collaborators.md
+++ b/content/v3/repos/collaborators.md
@@ -1,13 +1,14 @@
---
-title: Collaborators | GitHub API
+title: Collaborators
---
# Collaborators
-* TOC
{:toc}
-## List collaborators {#list}
+
+
+## List collaborators
GET /repos/:owner/:repo/collaborators
@@ -18,12 +19,33 @@ collaborators list.
### Response
-<%= headers 200 %>
+{% if page.version != 'dotcom' and page.version > 2.3 and page.version < 2.6 %}
+
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:user) { |h| [h] } %>
-## Check if a user is a collaborator {#get}
+### Alternative response with extra repository information
+
+{{#tip}}
+
+We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the [blog post](/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/) for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.ironman-preview+json
+```
+
+{{/tip}}
+
+{% endif %}
- GET /repos/:owner/:repo/collaborators/:user
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:collaborator) { |h| [h] } %>
+
+## Check if a user is a collaborator
+
+ GET /repos/:owner/:repo/collaborators/:username
### Response if user is a collaborator
@@ -33,17 +55,68 @@ collaborators list.
<%= headers 404 %>
-## Add user as a collaborator {#add-collaborator}
+## Add user as a collaborator
+
+ PUT /repos/:owner/:repo/collaborators/:username
+
+### Parameters
+
+{% if page.version == 'dotcom' or page.version >= 2.4 %}
+
+Name | Type | Description
+-----|------|--------------
+`permission`|`string` | The permission to grant the collaborator. **Only valid on organization-owned repositories.** Can be one of: * `pull` - can pull, but not push to or administer this repository. * `push` - can pull and push, but not administer this repository. * `admin` - can pull, push and administer this repository. Default: `push`
+
+<%= fetch_content(:optional_put_content_length) %>
+
+{{#tip}}
- PUT /repos/:owner/:repo/collaborators/:user
+We're currently offering a preview period allowing applications to opt in to the Repository Invitations API.
+
+To send an invitation to a collaborator rather than directly adding them, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.swamp-thing-preview+json
+```
+
+{{/tip}}
+
+{% if page.version != 'dotcom' and page.version > 2.3 and page.version < 2.6 %}
+
+{{#tip}}
+
+We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the [blog post](/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/) for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.ironman-preview+json
+```
+
+**Warning:** If you use this API to add a collaborator to a repository that's owned by an organization that hasn't had [improved organization permissions](https://github.com/blog/2020-improved-organization-permissions) enabled yet, you will get a `422` error response.
+
+{{/tip}}
+
+{% endif %}
+
+{% else %}
+
+<%= fetch_content(:put_content_length) %>
+
+{% endif %}
### Response
<%= headers 204 %>
-## Remove user as a collaborator {#remove-collaborator}
+### Response with preview media type
+
+<%= headers 201 %>
+<%= json(:repository_invitation) %>
+
+## Remove user as a collaborator
- DELETE /repos/:owner/:repo/collaborators/:user
+ DELETE /repos/:owner/:repo/collaborators/:username
### Response
diff --git a/content/v3/repos/comments.md b/content/v3/repos/comments.md
index 0385cf583f..e6f9bb5050 100644
--- a/content/v3/repos/comments.md
+++ b/content/v3/repos/comments.md
@@ -1,10 +1,9 @@
---
-title: Comments | GitHub API
+title: Comments
---
# Comments
-* TOC
{:toc}
## List commit comments for a repository
@@ -18,37 +17,78 @@ Comments are ordered by ascending ID.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:commit_comment) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the commit comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :commit_comment_reaction_summary %>
+{% endif %}
+
## List comments for a single commit
- GET /repos/:owner/:repo/commits/:sha/comments
+ GET /repos/:owner/:repo/commits/:ref/comments
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:commit_comment) { |h| [h] } %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the commit comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :commit_comment_reaction_summary %>
+{% endif %}
+
## Create a commit comment
POST /repos/:owner/:repo/commits/:sha/comments
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`sha`|`string` | **Required**. The SHA of the commit to comment on.
`body`|`string` | **Required**. The contents of the comment.
`path`|`string` | Relative path of the file to comment on.
-`position`|`number` | Line index in the diff to comment on.
-`line`|`number` | **Deprecated**. Use **position** parameter instead. Line number in the file to comment on.
+`position`|`integer` | Line index in the diff to comment on.
+`line`|`integer` | **Deprecated**. Use **position** parameter instead. Line number in the file to comment on.
#### Example
<%= json \
- :body => 'Nice change',
+ :body => 'Great stuff',
:path => 'file1.txt',
:position => 4,
:line => nil
@@ -56,7 +96,7 @@ Name | Type | Description
### Response
-<%= headers 201, :Location => "https://api.github.com/user/repo/comments/1" %>
+<%= headers 201, :Location => get_resource(:commit_comment)['url'] %>
<%= json :commit_comment %>
## Get a single commit comment
@@ -68,13 +108,34 @@ Name | Type | Description
<%= headers 200 %>
<%= json :commit_comment %>
+{% if page.version == 'dotcom' %}
+#### Reactions summary
+
+{{#tip}}
+
+
+
+ An additional `reactions` object in the commit comment payload is currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-05-12-reactions-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.squirrel-girl-preview
+
+ The `reactions` key will have the following payload where `url` can be used to construct the API location for [listing and creating](/v3/reactions) reactions.
+
+{{/tip}}
+<%= json :commit_comment_reaction_summary %>
+{% endif %}
+
## Update a commit comment
PATCH /repos/:owner/:repo/comments/:id
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`body`|`string` | **Required**. The contents of the comment
@@ -88,7 +149,7 @@ Name | Type | Description
### Response
<%= headers 200 %>
-<%= json :commit_comment %>
+<%= json(:commit_comment) { |h| h.merge('body' => 'Nice change') } %>
## Delete a commit comment
diff --git a/content/v3/repos/commits.md b/content/v3/repos/commits.md
index 95fc35fb2f..20c2ee69c3 100644
--- a/content/v3/repos/commits.md
+++ b/content/v3/repos/commits.md
@@ -1,10 +1,9 @@
---
-title: Commits | GitHub API
+title: Commits
---
# Commits
-* TOC
{:toc}
The Repo Commits API supports listing, viewing, and comparing commits in a repository.
@@ -13,29 +12,20 @@ The Repo Commits API supports listing, viewing, and comparing commits in a repos
GET /repos/:owner/:repo/commits
-_A special note on pagination:_ Due to the way Git works, commits are paginated
-based on SHA instead of page number. Please follow the link headers as outlined
-in the [pagination overview](http://developer.github.com/v3/#pagination)
-instead of constructing page links yourself.
-
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`sha`|`string` | SHA or branch to start listing commits from.
+`sha`|`string` | SHA or branch to start listing commits from. Default: the repository’s default branch (usually `master`).
`path`|`string` | Only commits containing this file path will be returned.
-`author`|`string` | GitHub login, name, or email by which to filter by commit author
+`author`|`string` | GitHub login or email address by which to filter by commit author.
`since`|`string` | Only commits after this date will be returned. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`.
`until`|`string` | Only commits before this date will be returned. This is a timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`.
### Response
-<%=
- headers 200, :pagination => {
- :next => 'https://api.github.com/repositories/417862/commits?top=master&last_sha=4f9890864feb48296917c2fcf3682d8dc3adf16a'
- }
-%>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:commit) { |h| [h] } %>
## Get a single commit
@@ -44,29 +34,108 @@ Name | Type | Description
### Response
+Diffs with binary data will have no 'patch' property. Pass the
+appropriate [media type](/v3/media/#commits-commit-comparison-and-pull-requests) to fetch diff and
+patch formats.
+
<%= headers 200 %>
<%= json(:full_commit) %>
-Note: Diffs with binary data will have no 'patch' property. Pass the
-appropriate [media type](/v3/media/#commits-commit-comparison-and-pull-requests) to fetch diff and
-patch formats.
+## Get the SHA-1 of a commit reference
+
+Users with read access can get the SHA-1 of a commit reference:
+
+ GET /repos/:owner/:repo/commits/:ref
+
+To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.VERSION.sha
+
+To check if a remote reference's SHA-1 is the same as your local reference's SHA-1, make a `GET` request and provide the current SHA-1 for the local reference as the ETag.
+
+### Response
+
+The SHA-1 of the commit reference.
+
+<%= headers 200 %>
+
+814412cfbd631109df337e16c807207e78c0d24e
+
## Compare two commits
GET /repos/:owner/:repo/compare/:base...:head
-Note: Both `:base` and `:head` can be either branch names in `:repo` or branch names in other repositories in the same network as `:repo`. For the latter case, use the format `user:branch`:
+Both `:base` and `:head` must be branch names in `:repo`. To compare branches across other repositories in the same network as `:repo`, use the format `:branch`. For example:
- GET /repos/:owner/:repo/compare/user1:branchname...user2:branchname
+ GET /repos/:owner/:repo/compare/hubot:branchname...octocat:branchname
### Response
-<%= json :commit_comparison %>
+The response from the API is equivalent to running the `git log base..head` command; however, commits are returned in reverse chronological order.
Pass the appropriate [media type](/v3/media/#commits-commit-comparison-and-pull-requests) to fetch diff and patch formats.
+<%= json :commit_comparison %>
+
### Working with large comparisons
The response will include a comparison of up to 250 commits. If you are working with a larger commit range, you can use the [Commit List API](/v3/repos/commits/#list-commits-on-a-repository) to enumerate all commits in the range.
For comparisons with extremely large diffs, you may receive an error response indicating that the diff took too long to generate. You can typically resolve this error by using a smaller commit range.
+
+{% if page.version == 'dotcom' %}
+
+## Commit signature verification
+
+{{#tip}}
+
+Commit response objects including signature verification data are currently available for developers to preview.
+During the preview period, the object formats may change without advance notice.
+Please see the [blog post](/changes/2016-04-04-git-signing-api-preview) for full details.
+
+To receive signature verification data in commit objects you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.cryptographer-preview
+
+{{/tip}}
+
+ GET /repos/:owner/:repo/commits/:sha
+
+### Response
+
+<%= headers 200 %>
+<%= json(:signed_commit) %>
+
+### The `verification` object
+
+The response will include a `verification` field whose value is an object describing the result of verifying the commit's signature. The following fields are included in the `verification` object:
+
+Name | Type | Description
+-----|------|--------------
+`verified`|`boolean` | Does GitHub consider the signature in this commit to be verified?
+`reason`|`string` | The reason for `verified` value. Possible values and their meanings are enumerated in the table below.
+`signature`|`string` | The signature that was extracted from the commit.
+`payload`|`string` | The value that was signed.
+
+#### The `reason` field
+
+The following are possible `reason`s that may be included in the `verification` object:
+
+Value | Description
+------|------------
+`expired_key` | The key that made the signature is expired.
+`not_signing_key` | The "signing" flag is not among the usage flags in the GPG key that made the signature.
+`gpgverify_error` | There was an error communicating with the signature-verification service.
+`gpgverify_unavailable` | The signature-verification service is currently unavailable.
+`unsigned` | The object does not include a signature.
+`unkown_signature_type` | A non-PGP signature was found in the commit.
+`no_user` | No user was associated with the `committer` email address in the commit.
+`unverified_email` | The `committer` email address in the commit was associated with a user, but the email address is not verified on her/his account.
+`bad_email` | The `committer` email address in the commit is not included in the identities of the PGP key that made the signature.
+`unknown_key` | The key that made the signature has not been registered with any user's account.
+`malformed_signature` | There was an error parsing the signature.
+`invalid` | The signature could not be cryptographically verified using the key whose key-id was found in the signature.
+`valid` | None of the above errors applied, so the signature is considered to be verified.
+
+{% endif %}
diff --git a/content/v3/repos/contents.md b/content/v3/repos/contents.md
index 1cc0021b6b..d1d352e335 100644
--- a/content/v3/repos/contents.md
+++ b/content/v3/repos/contents.md
@@ -1,14 +1,13 @@
---
-title: Contents | GitHub API
+title: Contents
---
# Contents
-* TOC
{:toc}
These API methods let you retrieve the contents of files within a repository as
-Base64 encoded content. See [media types](#custom-media-types) for requesting raw format.
+Base64 encoded content. See [media types](#custom-media-types) for requesting the raw format or rendered HTML (when supported).
## Get the README
@@ -16,11 +15,11 @@ This method returns the preferred README for a repository.
GET /repos/:owner/:repo/readme
-READMEs support [a custom media type](#custom-media-types) for getting the raw content.
+READMEs support [custom media types](#custom-media-types) for retrieving the raw content or rendered HTML.
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`ref`|`string` | The name of the commit/branch/tag. Default: the repository’s default branch (usually `master`)
@@ -35,17 +34,22 @@ This method returns the contents of a file or directory in a repository.
GET /repos/:owner/:repo/contents/:path
-Files and symlinks support [a custom media type](#custom-media-types) for getting the raw content.
-Directories and submodules do _not_ support custom media types.
+Files and symlinks support [a custom media type](#custom-media-types) for retrieving the raw content or rendered HTML (when supported).
+All content types support [a custom media type](#custom-media-types) to ensure the content is returned in a consistent object format.
-*Notes*:
+{{#tip}}
+
+**Note**:
- To get a repository's contents recursively, you can [recursively get the tree](/v3/git/trees/).
+- This API has an upper limit of 1,000 files for a directory. If you need to retrieve more files, use the [Git Trees API](/v3/git/trees/#get-a-tree).
- This API supports files up to 1 megabyte in size.
+{{/tip}}
+
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`path`|`string` | The content path.
`ref`|`string` | The name of the commit/branch/tag. Default: the repository’s default branch (usually `master`)
@@ -57,33 +61,35 @@ Name | Type | Description
### Response if content is a directory
-<%= headers 200 %>
-<%= json :directory_content %>
+The response will be an array of objects, one object for each item in the directory.
-Note: When listing the contents of a directory, submodules have their "type"
+When listing the contents of a directory, submodules have their "type"
specified as "file". Logically, the value *should* be "submodule". This behavior
exists in API v3 [for backwards compatibility purposes](https://github.com/github/developer.github.com/commit/1b329b04cece9f3087faa7b1e0382317a9b93490).
In the next major version of the API, the type will be returned as "submodule".
+<%= headers 200 %>
+<%= json :directory_content %>
+
### Response if content is a symlink
If the requested `:path` points to a symlink, and the symlink's target is a normal file in the repository, then the API responds with the content of the file (in the [format shown above](#response-if-content-is-a-file)).
-Otherwise, the API responds with a hash describing the symlink itself:
+Otherwise, the API responds with an object describing the symlink itself:
<%= headers 200 %>
<%= json :symlink_content %>
### Response if content is a submodule
-<%= headers 200 %>
-<%= json :submodule_content %>
-
The `submodule_git_url` identifies the location of the submodule repository, and the `sha` identifies a specific commit within the submodule repository.
Git uses the given URL when cloning the submodule repository, and checks out the submodule at that specific commit.
If the submodule repository is not hosted on github.com, the Git URLs (`git_url` and `_links["git"]`) and the github.com URLs (`html_url` and `_links["html"]`) will have null values.
+<%= headers 200 %>
+<%= json :submodule_content %>
+
## Create a file
This method creates a new file in a repository
@@ -92,7 +98,7 @@ This method creates a new file in a repository
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|-------------
`path`|`string` | **Required**. The content path.
`message`|`string` | **Required**. The commit message.
@@ -101,23 +107,23 @@ Name | Type | Description
### Optional Parameters
-You can provide an additional `commiter` parameter, which is a hash containing
+You can provide an additional `committer` parameter, which is an object containing
information about the committer. Or, you can provide an `author` parameter, which
-is a hash containing information about the author.
+is an object containing information about the author.
The `author` section is optional and is filled in with the `committer`
information if omitted. If the `committer` information is omitted, the authenticated
user's information is used.
You must provide values for both `name` and `email`, whether you choose to use
-`author` or `committer`. Otherwise, you'll receive a `500` status code.
+`author` or `committer`. Otherwise, you'll receive a `422` status code.
-Both the `author` and `commiter` parameters have the same keys:
+Both the `author` and `committer` parameters have the same keys:
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`name`|`string` | The name of the author (or commiter) of the commit
-`email`|`string` | The email of the author (or commiter) of the commit
+`name`|`string` | The name of the author (or committer) of the commit
+`email`|`string` | The email of the author (or committer) of the commit
### Example Input
@@ -139,33 +145,33 @@ This method updates a file in a repository
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`path`|`string` | **Required**. The content path.
`message`|`string` | **Required**. The commit message.
`content`|`string` | **Required**. The updated file content, Base64 encoded.
-`sha` | `string` | **Required**. The blob SHA of the file being replaced.
+`sha` | `string` | **Required**. The blob SHA of the file being replaced.
`branch` | `string` | The branch name. Default: the repository’s default branch (usually `master`)
### Optional Parameters
-You can provide an additional `commiter` parameter, which is a hash containing
+You can provide an additional `committer` parameter, which is an object containing
information about the committer. Or, you can provide an `author` parameter, which
-is a hash containing information about the author.
+is an object containing information about the author.
The `author` section is optional and is filled in with the `committer`
information if omitted. If the `committer` information is omitted, the authenticated
user's information is used.
You must provide values for both `name` and `email`, whether you choose to use
-`author` or `committer`. Otherwise, you'll receive a `500` status code.
+`author` or `committer`. Otherwise, you'll receive a `422` status code.
-Both the `author` and `commiter` parameters have the same keys:
+Both the `author` and `committer` parameters have the same keys:
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`name`|`string` | The name of the author (or commiter) of the commit
-`email`|`string` | The email of the author (or commiter) of the commit
+`name`|`string` | The name of the author (or committer) of the commit
+`email`|`string` | The email of the author (or committer) of the commit
### Example Input
@@ -189,32 +195,32 @@ This method deletes a file in a repository
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`path`|`string` | **Required**. The content path.
`message`|`string` | **Required**. The commit message.
-`sha` | `string` | **Required**. The blob SHA of the file being replaced.
+`sha` | `string` | **Required**. The blob SHA of the file being replaced.
`branch` | `string` | The branch name. Default: the repository’s default branch (usually `master`)
### Optional Parameters
-You can provide an additional `commiter` parameter, which is a hash containing
+You can provide an additional `committer` parameter, which is an object containing
information about the committer. Or, you can provide an `author` parameter, which
-is a hash containing information about the author.
+is an object containing information about the author.
The `author` section is optional and is filled in with the `committer`
information if omitted. If the `committer` information is omitted, the authenticated
user's information is used.
You must provide values for both `name` and `email`, whether you choose to use
-`author` or `committer`. Otherwise, you'll receive a `500` status code.
+`author` or `committer`. Otherwise, you'll receive a `422` status code.
-Both the `author` and `commiter` parameters have the same keys:
+Both the `author` and `committer` parameters have the same keys:
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
-`name`|`string` | The name of the author (or commiter) of the commit
-`email`|`string` | The email of the author (or commiter) of the commit
+`name`|`string` | The name of the author (or committer) of the commit
+`email`|`string` | The email of the author (or committer) of the commit
### Example Input
@@ -246,7 +252,7 @@ to make a second `GET` request.
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`archive_format`|`string` | Can be either `tarball` or `zipball`. Default: `tarball`
`ref`| `string` | A valid Git reference. Default: the repository’s default branch (usually `master`)
@@ -258,18 +264,30 @@ Name | Type | Description
To follow redirects with curl, use the `-L` switch:
-
-curl -L https://api.github.com/repos/pengwynn/octokit/tarball > octokit.tar.gz
+``` command-line
+$curl -L https://api.github.com/repos/octokit/octokit.rb/tarball > octokit.tar.gz
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
-100 206k 100 206k 0 0 146k 0 0:00:01 0:00:01 --:--:-- 790k
-
+> % Total % Received % Xferd Average Speed Time Time Time Current
+> Dload Upload Total Spent Left Speed
+> 100 206k 100 206k 0 0 146k 0 0:00:01 0:00:01 --:--:-- 790k
+```
## Custom media types
-[READMEs](#get-the-readme), [files](#get-contents), and [symlinks](#get-contents) support the following custom media type.
+[READMEs](#get-the-readme), [files](#get-contents), and [symlinks](#get-contents) support the following custom media types:
application/vnd.github.VERSION.raw
+ application/vnd.github.VERSION.html
+
+Use the `.raw` media type to retrieve the contents of the file.
+
+For markup files such as Markdown or AsciiDoc, you can retrieve the rendered HTML using the `.html` media type. Markup languages are rendered to HTML using our open-source [Markup library](https://github.com/github/markup).
+
+[All objects](#get-contents) support the following custom media type:
+
+ application/vnd.github.VERSION.object
+
+Use the `object` media type parameter to retrieve the contents in a consistent object format regardless of the content type. For example, instead of an array of objects
+for a directory, the response will be an object with an `entries` attribute containing the array of objects.
You can read more about the use of media types in the API [here](/v3/media/).
diff --git a/content/v3/repos/deployments.md b/content/v3/repos/deployments.md
index dfe6bab9e8..34e2574621 100644
--- a/content/v3/repos/deployments.md
+++ b/content/v3/repos/deployments.md
@@ -1,26 +1,12 @@
---
-title: Deployments | GitHub API
+title: Deployments
---
# Deployments
-* TOC
{:toc}
-
-
- The Deployments API is currently available for developers to preview.
- During the preview period, the API may change without advance notice.
- Please see the blog post for full details.
-
-
-
- To access the API during the preview period, you must provide a custom media type in the Accept header:
-
application/vnd.github.cannonball-preview+json
-
-
-
-Deployments are a request for a specific ref(branch,sha,tag) to be deployed.
+Deployments are a request for a specific ref (branch, SHA, tag) to be deployed.
GitHub then dispatches deployment events that external services can listen for
and act on. This enables developers and organizations to build loosely-coupled
tooling around deployments, without having to worry about implementation
@@ -44,7 +30,7 @@ made.
Below is a simple sequence diagram for how these interactions would work.
-
+```
+---------+ +--------+ +-----------+ +-------------+
| Tooling | | GitHub | | 3rd Party | | Your Server |
+---------+ +--------+ +-----------+ +-------------+
@@ -69,15 +55,15 @@ Below is a simple sequence diagram for how these interactions would work.
| | Deployment Status | |
| |<----------------------| |
| | | |
-
+```
Keep in mind that GitHub is never actually accessing your servers. It's up to
-your 3rd party integration to interact with deployment events.
-This allows for [github-services](https://github.com/github/github-services)
-integrations as well as running your own systems depending on your use case.
-Multiple systems can listen for deployment events, and it's up to each of
-those systems to decide whether or not they're responsible for pushing the code
-out to your servers, building native code, etc.
+your 3rd party integration to interact with deployment events. This allows for
+[GitHub integrations](https://github.com/integrations) as
+well as running your own systems depending on your use case. Multiple systems
+can listen for deployment events, and it's up to each of those systems to
+decide whether or not they're responsible for pushing the code out to your
+servers, building native code, etc.
Note that the `repo_deployment` [OAuth scope](/v3/oauth/#scopes) grants
targeted access to Deployments and Deployment Statuses **without**
@@ -86,10 +72,17 @@ as well.
## List Deployments
-Users with pull access can view deployments for a repository:
+Simple filtering of deployments is available via query parameters:
GET /repos/:owner/:repo/deployments
+Name | Type | Description
+-----|------|--------------
+`sha`|`string` | The SHA that was recorded at creation time. Default: `none`
+`ref`|`string` | The name of the ref. This can be a branch, tag, or SHA. Default: `none`
+`task`|`string` | The name of the task for the deployment. e.g. `deploy` or `deploy:migrations`. Default: `none`
+`environment`|`string` | The name of the environment that was deployed to. e.g. `staging` or `production`. Default: `none`
+
### Response
<%= headers 200, :pagination => default_pagination_rels %>
@@ -97,14 +90,16 @@ Users with pull access can view deployments for a repository:
## Create a Deployment
-If your repository is taking advantage of [commit statuses](/v3/repos/statuses),
-the API will reject requests that do not have a success status. (Your repository
-is not required to use commit statuses. If no commit statuses are present, the
-deployment will always be created.)
+Deployments offer a few configurable parameters with sane defaults.
-The `force` parameter can be used when you really just need a deployment to go
-out. In these cases, all checks are bypassed, and the deployment is created for
-the ref.
+The `ref` parameter can be any named branch, tag, or SHA. At GitHub we often
+deploy branches and verify them before we merge a pull request.
+
+The `environment` parameter allows deployments to be issued to different
+runtime environments. Teams often have multiple environments for verifying
+their applications, like 'production', 'staging', and 'qa'. This allows for
+easy tracking of which environments had deployments requested. The default
+environment is 'production'.
The `auto_merge` parameter is used to ensure that the requested ref is not
behind the repository's default branch. If the ref *is* behind the default
@@ -112,11 +107,23 @@ branch for the repository, we will attempt to merge it for you. If the merge
succeeds, the API will return a successful merge commit. If merge conflicts
prevent the merge from succeeding, the API will return a failure response.
+By default, [commit statuses](/v3/repos/statuses) for every submitted context
+must be in a 'success' state. The `required_contexts` parameter allows you to
+specify a subset of contexts that must be "success", or to specify contexts
+that have not yet been submitted. You are not required to use commit statuses
+to deploy. If you do not require any contexts or create any commit statuses,
+the deployment will always succeed.
+
The `payload` parameter is available for any extra information that a
deployment system might need. It is a JSON text field that will be passed on
when a deployment event is dispatched.
-Users with push access can create a deployment for a given ref:
+The `task` parameter is used by the deployment system to allow different
+execution paths. In the web world this might be 'deploy:migrations' to run
+schema changes on the system. In the compiled world this could be a flag to
+compile an application with debugging enabled.
+
+Users with `repo` or `repo_deployment` scopes can create a deployment for a given ref:
POST /repos/:owner/:repo/deployments
@@ -124,25 +131,78 @@ Users with push access can create a deployment for a given ref:
Name | Type | Description
-----|------|--------------
-`ref`|`string`| **Required**. The ref to deploy. This can be a branch, tag, or sha.
-`force`|`boolean`| Optional parameter to bypass any ahead/behind checks or commit status checks. Default: `false`
+`ref`|`string`| **Required**. The ref to deploy. This can be a branch, tag, or SHA.
+`task`|`string`| Optional parameter to specify a task to execute, e.g. `deploy` or `deploy:migrations`. Default: `deploy`
+`auto_merge`|`boolean`| Optional parameter to merge the default branch into the requested ref if it is behind the default branch. Default: `true`
+`required_contexts`|`Array`| Optional array of status contexts verified against commit status checks. If this parameter is omitted from the parameters then all unique contexts will be verified before a deployment is created. To bypass checking entirely pass an empty array. Defaults to all unique contexts.
`payload`|`string` | Optional JSON payload with extra information about the deployment. Default: `""`
-`auto_merge`|`boolean`| Optional parameter to merge the default branch into the requested deployment branch if necessary. Default: `false`
+`environment`|`string` | Optional name for the target deployment environment (e.g., production, staging, qa). Default: `"production"`
`description`|`string` | Optional short description. Default: `""`
+{% if page.version == 'dotcom' || page.version > 2.6 %} `transient_environment` | `boolean` | Optionally specifies if the given environment is specific to the deployment and will no longer exist at some point in the future. Default: `false` **This parameter requires a custom media type to be specified. Please see more in the alert below.**{% endif %}
+{% if page.version == 'dotcom' || page.version > 2.6 %} `production_environment` | `boolean` | Optionally specifies if the given environment is one that end-users directly interact with. Default: `true` when `environment` is `"production"` and `false` otherwise. **This parameter requires a custom media type to be specified. Please see more in the alert below.**{% endif %}
-#### Example
+{% if page.version == 'dotcom' || page.version > 2.6 %}
+{{#tip}}
+
+The new `transient_environment` and `production_environment` parameters are currently available for developers to preview. During the preview period, the API may change without advance notice. Please see the [blog post][blog-post] for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.ant-man-preview+json
+```
+
+{{/tip}}
+
+{% endif %}
+
+#### Simple Example
+
+A simple example putting the user and room into the payload to notify back to
+chat networks.
<%= json \
:ref => "topic-branch",
- :payload => "{\"environment\":\"production\",\"deploy_user\":\"atmos\",\"room_id\":123456}",
+ :payload => "{\"user\":\"atmos\",\"room_id\":123456}",
:description => "Deploying my sweet branch"
%>
-<%= headers 201,
- :Location =>
-'https://api.github.com/repos/octocat/example/deployments/1' %>
+### Successful response
+
+<%= headers 201, :Location => get_resource(:deployment)['url'] %>
<%= json :deployment %>
+#### Advanced Example
+
+A more advanced example specifying required commit statuses and bypassing auto-merging.
+
+<%= json \
+ :ref => "topic-branch",
+ :auto_merge => false,
+ :payload => "{\"user\":\"atmos\",\"room_id\":123456}",
+ :description => "Deploying my sweet branch",
+ :required_contexts => ["ci/janky", "security/brakeman"]
+%>
+
+### Successful response
+
+<%= headers 201, :Location => get_resource(:deployment)['url'] %>
+<%= json :deployment %>
+
+### Merge conflict response
+
+This error happens when the `auto_merge` option is enabled and when the default branch (in this case `master`), can't be merged into the branch that's being deployed (in this case `topic-branch`), due to merge conflicts.
+
+<%= headers 409 %>
+<%= json({ :message => "Conflict merging master into topic-branch" }) %>
+
+### Failed commit status checks
+
+This error happens when the `required_contexts` parameter indicates that one or more contexts need to have a `success` status for the commit to be deployed, but one or more of the required contexts do not have a state of `success`.
+
+<%= headers 409 %>
+<%= json({ :message => "Conflict: Commit status checks failed for topic-branch." }) %>
+
## Update a Deployment
Once a deployment is created, it cannot be updated. Information relating to the
@@ -166,7 +226,7 @@ Name | Type | Description
### Response
<%= headers 200, :pagination => default_pagination_rels %>
-<%= json(:deployment_status) { |h| [h] } %>
+<%= json(:deployment_status) { |h| h.delete("deployment"); [h] } %>
## Create a Deployment Status
@@ -178,9 +238,28 @@ Users with push access can create deployment statuses for a given deployment:
Name | Type | Description
-----|------|--------------
-`state`|`string` | **Required**. The state of the status. Can be one of `pending`, `success`, `error`, or `failure`.
+`state`|`string` | **Required**. The state of the status. Can be one of `pending`, `success`, `error`, {% if page.version == 'dotcom' || page.version > 2.6 %} `inactive`, {% endif %}or `failure` **The `inactive` state requires a custom media type to be specified. Please see more in the alert below.**.
`target_url`|`string` | The target URL to associate with this status. This URL should contain output to keep the user updated while the task is running or serve as historical information for what happened in the deployment. Default: `""`
-`description`|`string` | A short description of the status. Default: `""`
+{% if page.version == 'dotcom' || page.version > 2.6 %}`log_url`|`string` | This is functionally equivalent to `target_url`. We will continue accept `target_url` to support legacy uses, but we recommend modifying this to the new name to avoid confusion. Default: `""` **This parameter requires a custom media type to be specified. Please see more in the alert below.**{% endif %}
+`description`|`string` | A short description of the status. Maximum length of 140 characters. Default: `""`
+{% if page.version == 'dotcom' || page.version > 2.6 %}`environment_url`|`string`| Optionally set the URL for accessing your environment. Default: `""` **This parameter requires a custom media type to be specified. Please see more in the alert below.**{% endif %}
+{% if page.version == 'dotcom' || page.version > 2.6 %}`auto_inactive`|`boolean`| Optional parameter to add a new `inactive` status to all non-transient, non-production environment deployments with the same repository and environment name as the created status's deployment. Default: `true` **This parameter requires a custom media type to be specified. Please see more in the alert below.**{% endif %}
+
+{% if page.version == 'dotcom' || page.version > 2.6 %}
+
+{{#tip}}
+
+The new `inactive` state, rename of the `target_url` parameter to `log_url` and new `environment_url` and `auto_inactive` parameters are currently available for developers to preview. During the preview period, the API may change without advance notice. Please see the [blog post][blog-post] for full details.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.ant-man-preview+json
+```
+
+{{/tip}}
+
+{% endif %}
#### Example
@@ -192,7 +271,7 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location =>
-'https://api.github.com/repos/octocat/example/deployments/42/statuses/1' %>
+<%= headers 201, :Location => get_resource(:deployment_status)['url'] %>
<%= json :deployment_status %>
+
+[blog-post]: /changes/2016-04-06-deployment-and-deployment-status-enhancements
diff --git a/content/v3/repos/downloads.md b/content/v3/repos/downloads.md
index 36e0b30109..c5f027a106 100644
--- a/content/v3/repos/downloads.md
+++ b/content/v3/repos/downloads.md
@@ -1,23 +1,20 @@
---
-title: Downloads | GitHub API
+title: Downloads
---
# Downloads
-* TOC
{:toc}
### Downloads API is Deprecated
-
-
- The Downloads API (described below) was
- deprecated on December 11, 2012.
- It will be removed at a future date.
+{{#warning}}
- We recommend using Releases instead.
-
-
+The Downloads API (described below) was deprecated on December 11, 2012. It will be removed at a future date.
+
+We recommend using Releases instead.
+
+{{/warning}}
The downloads API is for package downloads only. If you want to get
source tarballs you should use [this](/v3/repos/contents/#get-archive-link)
@@ -29,7 +26,7 @@ instead.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:download) { |h| [h] } %>
## Get a single download
diff --git a/content/v3/repos/forks.md b/content/v3/repos/forks.md
index 3f8856121d..27c1c98f89 100644
--- a/content/v3/repos/forks.md
+++ b/content/v3/repos/forks.md
@@ -1,10 +1,9 @@
---
-title: Forks | GitHub API
+title: Forks
---
# Forks
-* TOC
{:toc}
## List forks
@@ -20,7 +19,7 @@ Name | Type | Description
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:repo) { |h| h['fork'] = true; [h] } %>
## Create a fork
@@ -29,14 +28,11 @@ Create a fork for the authenticated user.
POST /repos/:owner/:repo/forks
-One can either use the `organization` parameter or POST a JSON document with
-the field `organization`
-
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|-------------
-`organization`|`string` | The organization login. The repository will be forked into this organization.
+`organization`|`string` | Optional parameter to specify the organization name if forking into an organization.
### Response
diff --git a/content/v3/repos/hooks.md b/content/v3/repos/hooks.md
index bafe6c4748..2208924598 100644
--- a/content/v3/repos/hooks.md
+++ b/content/v3/repos/hooks.md
@@ -1,16 +1,17 @@
---
-title: Webhooks | GitHub API
+title: Repository Webhooks
---
# Webhooks
-* TOC
{:toc}
The Repository Webhooks API allows repository admins to manage the post-receive
hooks for a repository. Webhooks can be managed using the JSON HTTP API,
or the [PubSubHubbub API](#pubsubhubbub).
+If you would like to set up a single webhook to receive events from all of your organization's repositories, check out our [API documentation for Organization Webhooks][org-hooks].
+
## List hooks
GET /repos/:owner/:repo/hooks
@@ -33,28 +34,29 @@ or the [PubSubHubbub API](#pubsubhubbub).
POST /repos/:owner/:repo/hooks
-### Parameter
+**Note**: Repository service hooks (like email or Campfire) can have at most one configured at a time. Creating hooks for a service that already has one configured will [update the existing hook](#edit-a-hook).
+
+Repositories can have multiple webhooks installed. Each webhook should have a unique `config`. Multiple webhooks can share the same `config` as long as those webhooks do not have any `events` that overlap.
+
+### Parameters
Name | Type | Description
-----|------|--------------
-`name`|`string` | **Required**. The name of the service that is being called. (See [/hooks](https://api.github.com/hooks) for the list of valid hook names.)
-`config`|`hash` | **Required**. Key/value pairs to provide settings for this hook. These settings vary between the services and are defined in the [github-services](https://github.com/github/github-services) repository. Booleans are stored internally as "1" for true, and "0" for false. Any JSON `true`/`false` values will be converted automatically.
+`name`|`string` | **Required**. Use `web` for a webhook or use the name of a valid service. (See /hooks for the list of valid service names.)
+`config`|`object` | **Required**. Key/value pairs to provide settings for this hook. These settings vary between hooks and some are defined in the [github-services](https://github.com/github/github-services) repository. Booleans are stored internally as "1" for true, and "0" for false. Any JSON `true`/`false` values will be converted automatically.
`events`|`array` | Determines what events the hook is triggered for. Default: `["push"]`
`active`|`boolean` | Determines whether the hook is actually triggered on pushes.
#### Example
-The ["web" service hook](https://github.com/github/github-services/blob/master/lib/services/web.rb#L4-11)
-takes these fields in the `config`:
+To create [a webhook](/webhooks), the following fields are required by the `config`:
-Name | Type | Description
------|------|--------------
-`url`|`string` | **Required**. The URL to which the payloads will be delivered.
-`content_type`|`string` | The media type used to serialize the payloads. Supported values: `json` and `form`. Default: `form`.
-`secret`|`string` | If defined, then HTTP requests that deliver the payloads will include an `X-Hub-Signature` header. The value of this header is computed as the [HMAC hex digest of the body, using the `secret` as the key][hub-signature].
-`insecure_ssl`|`string` | Determines whether the SSL certificate of the host for `url` will be verified when delivering payloads. Supported values: `"0"` (verification is performed) and `"1"` (verification is not performed). Default: `"0"`.
+* `url`: A required string defining the URL to which the payloads will be delivered.
+* `content_type`: An optional string defining the media type used to serialize the payloads. Supported values include `json` and `form`. The default is `form`.
+* `secret`: An optional string that's passed with the HTTP requests as an `X-Hub-Signature` header. The value of this header is computed as the HMAC hex digest of the body, using the `secret` as the key.
+* `insecure_ssl`: An optional string that determines whether the SSL certificate of the host for `url` will be verified when delivering payloads. Supported values include `"0"` (verification is performed) and `"1"` (verification is not performed). The default is `"0"`.
-Here's how you can setup a hook that posts payloads in JSON format:
+Here's how you can create a hook that posts payloads in JSON format:
<%= json \
:name => "web",
@@ -67,19 +69,18 @@ Here's how you can setup a hook that posts payloads in JSON format:
### Response
-<%= headers 201,
- :Location => 'https://api.github.com/repos/user/repo/hooks/1' %>
+<%= headers 201, :Location => get_resource(:hook)['url'] %>
<%= json :hook %>
## Edit a hook
PATCH /repos/:owner/:repo/hooks/:id
-### Parameter
+### Parameters
Name | Type | Description
-----|------|--------------
-`config`|`hash` | Key/value pairs to provide settings for this hook. Modifying this will replace the entire config object. These settings vary between the services and are defined in the [github-services](https://github.com/github/github-services) repository. Booleans are stored internally as "1" for true, and "0" for false. Any JSON `true`/`false` values will be converted automatically.
+`config`|`object` | Key/value pairs to provide settings for this hook. Modifying this will replace the entire config object. These settings vary between hooks and some are defined in the [github-services](https://github.com/github/github-services) repository. Booleans are stored internally as "1" for true, and "0" for false. Any JSON `true`/`false` values will be converted automatically.
`events`|`array` | Determines what events the hook is triggered for. This replaces the entire array of events. Default: `["push"]`
`add_events`|`array` | Determines a list of events to be added to the list of events that the Hook triggers for.
`remove_events`|`array` | Determines a list of events to be removed from the list of events that the Hook triggers for.
@@ -133,17 +134,17 @@ This will trigger a [ping event][ping-event-url] to be sent to the hook.
## Receiving Webhooks
-In order for GitHub to send Webhook payloads to your service, your server needs to be accessible from the Internet. We also highly suggest using SSL so that we can send encrypted payloads over HTTPS.
+In order for {{ site.data.variables.product.product_name }} to send webhook payloads, your server needs to be accessible from the Internet. We also highly suggest using SSL so that we can send encrypted payloads over HTTPS.
### Webhook Headers
-GitHub will send along a few HTTP headers to differentiate between event types and payload identifiers.
+GitHub will send along several HTTP headers to differentiate between event types and payload identifiers.
Name | Description
-----|-----------|
`X-GitHub-Event` | The [event type](/v3/activity/events/types/) that was triggered.
`X-GitHub-Delivery` | A [guid][guid] to identify the payload and event being sent.
-`X-GitHub-Signature` | The value of this header is computed as the HMAC hex digest of the body, using the `secret` config option as the key.
+`X-Hub-Signature` | The value of this header is computed as the HMAC hex digest of the body, using the `secret` config option as the key.
## PubSubHubbub
@@ -181,16 +182,18 @@ Callback URLs can use either the `http://` protocol, or `github://`.
### Subscribing
-The GitHub PubSubHubbub endpoint is: https://api.github.com/hub.
-(GitHub Enterprise users should use http://yourhost/api/v3/hub as the
+The GitHub PubSubHubbub endpoint is: `https://api.github.com/hub`.
+(GitHub Enterprise users should use `http://yourhost/api/v3/hub` as the
PubSubHubbub endpoint, but not change the `hub.topic` URI format.) A
successful request with curl looks like:
- curl -u "user" -i \
- https://api.github.com/hub \
- -F "hub.mode=subscribe" \
- -F "hub.topic=https://github.com/:owner/:repo/events/push" \
- -F "hub.callback=http://postbin.org/123"
+``` command-line
+curl -u "user" -i \
+ https://api.github.com/hub \
+ -F "hub.mode=subscribe" \
+ -F "hub.topic=https://github.com/:owner/:repo/events/push" \
+ -F "hub.callback=http://postbin.org/123"
+```
PubSubHubbub requests can be sent multiple times. If the hook already
exists, it will be modified according to the request.
@@ -202,14 +205,13 @@ Name | Type | Description
``hub.mode``|`string` | **Required**. Either `subscribe` or `unsubscribe`.
``hub.topic``|`string` |**Required**. The URI of the GitHub repository to subscribe to. The path must be in the format of `/:owner/:repo/events/:event`.
``hub.callback``|`string` | The URI to receive the updates to the topic.
-``hub.secret``|`string` | A shared secret key that generates a SHA1 HMAC of the outgoing body content. You can verify a push came from GitHub by comparing the raw request body with the contents of the `X-Hub-Signature` header. You can see [our Ruby implementation][ruby-secret], or [the PubSubHubbub documentation][pshb-secret] for more details.
+``hub.secret``|`string` | A shared secret key that generates a SHA1 HMAC of the outgoing body content. You can verify a push came from GitHub by comparing the raw request body with the contents of the `X-Hub-Signature` header. You can see [the PubSubHubbub documentation][pshb-secret] for more details.
[guid]: http://en.wikipedia.org/wiki/Globally_unique_identifier
-[pubsub]: http://code.google.com/p/pubsubhubbub/
+[pubsub]: https://github.com/pubsubhubbub/PubSubHubbub
[post-receive]: http://help.github.com/post-receive-hooks/
-[ruby-secret]: https://github.com/github/github-services/blob/14f4da01ce29bc6a02427a9fbf37b08b141e81d9/lib/services/web.rb#L47-L50
-[hub-signature]: https://github.com/github/github-services/blob/f3bb3dd780feb6318c42b2db064ed6d481b70a1f/lib/service/http_helper.rb#L77
-[pshb-secret]: http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#authednotify
+[pshb-secret]: https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#authednotify
[events-url]: /webhooks/#events
[ping-event-url]: /webhooks/#ping-event
+[org-hooks]: /v3/orgs/hooks/
diff --git a/content/v3/repos/invitations.md b/content/v3/repos/invitations.md
new file mode 100644
index 0000000000..50469923aa
--- /dev/null
+++ b/content/v3/repos/invitations.md
@@ -0,0 +1,98 @@
+---
+title: Repository Invitations
+---
+
+# Repository Invitations
+
+{{#tip}}
+
+We're currently offering a preview of the Repository Invitations API.
+
+To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+```
+application/vnd.github.swamp-thing-preview+json
+```
+
+{{/tip}}
+
+{:toc}
+
+
+
+## Invite a user to a repository
+
+Use the API endpoint for adding a collaborator [here](/v3/repos/collaborators).
+
+
+
+## List invitations for a repository
+
+ GET /repositories/:repo_id/invitations
+
+When authenticating as a user with admin rights to a repository, this endpoint will list all currently open repository invitations.
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:repository_invitation) { |h| [h] } %>
+
+
+
+## Delete a repository invitation
+
+ DELETE /repositories/:repo_id/invitations/:invitation_id
+
+### Response
+
+<%= headers 204 %>
+
+
+
+## Update a repository invitation
+
+ PATCH /repositories/:repo_id/invitations/:invitation_id
+
+### Input
+
+Name | Type | Description
+-----|------|--------------
+`permissions`|`string` | The permissions that the associated user will have on the repository. Valid values are `read`, `write`, and `admin`.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:repository_invitation) %>
+
+
+
+## List a user's repository invitations
+
+ GET /user/repository_invitations
+
+When authenticating as a user, this endpoint will list all currently open repository invitations for that user.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:repository_invitation) { |h| [h] } %>
+
+
+
+## Accept a repository invitation
+
+ PATCH /user/repository_invitations/:invitation_id
+
+### Response
+
+<%= headers 204 %>
+
+
+
+## Decline a repository invitation
+
+ DELETE /user/repository_invitations/:invitation_id
+
+### Response
+
+<%= headers 204 %>
diff --git a/content/v3/repos/keys.md b/content/v3/repos/keys.md
index d5ad0efbb0..db2fdcc7cc 100644
--- a/content/v3/repos/keys.md
+++ b/content/v3/repos/keys.md
@@ -1,49 +1,68 @@
---
-title: Deploy Keys | GitHub API
+title: Deploy Keys
---
# Deploy Keys
-* TOC
{:toc}
-## List deploy keys {#list}
+
+
+## List deploy keys
GET /repos/:owner/:repo/keys
### Response
-<%= headers 200 %>
-<%= json(:public_key) { |h| [h] } %>
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:deploy_key) { |h| [h] } %>
+
+
-## Get a deploy key {#get}
+## Get a deploy key
GET /repos/:owner/:repo/keys/:id
### Response
<%= headers 200 %>
-<%= json :public_key %>
+<%= json :deploy_key %>
-## Add a new deploy key {#create}
+
+
+## Add a new deploy key
POST /repos/:owner/:repo/keys
-### Input
+### Parameters
+
+Name | Type | Description
+-----|------|-------------
+`title`|`string`|A name for the key.
+`key`|`string`|The contents of the key.
+`read_only`|`boolean`|If `true`, the key will only be able to read repository contents. Otherwise, the key will be able to read and write.
-<%= json :title => "octocat@octomac", :key => "ssh-rsa AAA..." %>
+#### Example
+
+Here's how you can create a read-only deploy key:
+
+<%= json :title => "octocat@octomac", :key => "ssh-rsa AAA...", :read_only => true %>
### Response
-<%= headers 201, :Location => "https://api.github.com/user/repo/keys/1" %>
-<%= json :public_key %>
+<%= headers 201, :Location => get_resource(:deploy_key)['url'] %>
+<%= json :deploy_key %>
-## Edit a deploy key {#edit}
+
+
+## Edit a deploy key
Deploy keys are immutable. If you need to update a key, [remove the
-key](#delete) and [create a new one](#create) instead.
+key](#remove-a-deploy-key) and [create a new one](#add-a-new-deploy-key) instead.
+
+
-## Remove a deploy key {#delete}
+## Remove a deploy key
DELETE /repos/:owner/:repo/keys/:id
diff --git a/content/v3/repos/merging.md b/content/v3/repos/merging.md
index 7d4734014a..ed5285c212 100644
--- a/content/v3/repos/merging.md
+++ b/content/v3/repos/merging.md
@@ -1,15 +1,14 @@
---
-title: Merging | GitHub API
+title: Merging
---
# Merging
-* TOC
{:toc}
The Repo Merging API supports merging branches in a repository. This accomplishes
essentially the same thing as merging one branch into another in a local repository
-and then pushing to GitHub. The benefit is that the merge is done on the server side
+and then pushing to {{ site.data.variables.product.product_name }}. The benefit is that the merge is done on the server side
and a local repository is not needed. This makes it more appropriate for automation
and other tools where maintaining local repositories would be cumbersome and inefficient.
@@ -21,7 +20,7 @@ The authenticated user will be the author of any merges done through this endpoi
### Input
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`base`|`string` | **Required**. The name of the base branch that the head will be merged into.
`head`|`string` | **Required**. The head to merge. This can be a branch name or a commit SHA1.
diff --git a/content/v3/repos/pages.md b/content/v3/repos/pages.md
index e882976a79..78f8c5ba94 100644
--- a/content/v3/repos/pages.md
+++ b/content/v3/repos/pages.md
@@ -1,19 +1,19 @@
---
-title: Pages | GitHub API
+title: Pages
---
# Pages
-* TOC
{:toc}
-The Pages API retrieves information about your GitHub Pages configuration, and
+The GitHub Pages API retrieves information about your GitHub Pages configuration, and
the statuses of your builds. Information about the site and the builds can only be
accessed by authenticated owners, even though the websites are public.
In JSON responses, `status` can be one of:
* `null`, which means the site has yet to be built
+* `queued`, which means the build has been requested but not yet begun
* `building`, which means the build is in progress
* `built`, which means the site has been built
* `errored`, which indicates an error occurred during the build
@@ -22,16 +22,65 @@ In JSON responses, `status` can be one of:
GET /repos/:owner/:repo/pages
+{% if page.version == 'dotcom' or page.version > 2.7 %}
+
+{{#tip}}
+
+
+
+ Additional functionality of the GitHub Pages API is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+
+ To access the additional functionality during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.mister-fantastic-preview+json
+
+ When the [preview flag](#preview-period) is passed, the response will contain an additional field, `html_url`, which will contain the absolute URL (with scheme) to the rendered site (e.g., `https://username.github.io`, or `http://example.com`).
+
+{{/tip}}
+
+{% endif %}
+
### Response
<%= headers 200 %>
<%= json(:pages) %>
+{% if page.version == 'dotcom' or page.version > 2.7 %}
+
+## Request a page build
+
+ POST /repos/:owner/:repo/pages/builds
+
+{{#tip}}
+
+
+
+ This endpoint is currently available for developers to preview.
+ During the preview period, the API may change without advance notice.
+
+ To access this endpoint during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.mister-fantastic-preview+json
+
+{{/tip}}
+
+You can request that your site be built from the latest revision on the default branch. This has the same effect as pushing a commit to your default branch, but does not require an additional commit. Manually triggering page builds can be helpful when diagnosing build warnings and failures.
+
+Build requests are limited to one concurrent build per repository and one concurrent build per requester. If you request a build while another is still in progress, the second request will be queued until the first completes.
+
+### Response
+
+<%= headers 200 %>
+<%= json(:pages_request_build) %>
+
+{% endif %}
+
## List Pages builds
GET /repos/:owner/:repo/pages/builds
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:pages_build) { |h| [h] } %>
## List latest Pages build
diff --git a/content/v3/repos/pre_receive_hooks.md b/content/v3/repos/pre_receive_hooks.md
new file mode 100644
index 0000000000..2eef1d9459
--- /dev/null
+++ b/content/v3/repos/pre_receive_hooks.md
@@ -0,0 +1,88 @@
+---
+title: Repository Pre-receive Hooks
+---
+
+# Repository Pre-receive Hooks (Enterprise)
+
+{{#tip}}
+
+
+
+ APIs for managing pre-receive hooks are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.eye-scream-preview
+
+{{/tip}}
+
+
+{:toc}
+
+The Repository Pre-receive Hooks API allows you to view and modify
+enforcement of the pre-receive hooks that are available to a repository.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+## Object attributes
+
+| Name | Type | Description |
+|---------------------|----------|-----------------------------------------------------------|
+| `name` | `string` | The name of the hook. |
+| `enforcement` | `string` | The state of enforcement for the hook on this repository. |
+| `configuration_url` | `string` | URL for the endpoint where enforcement is set. |
+
+Possible values for *enforcement* are `enabled`, `disabled` and`testing`. `disabled` indicates the pre-receive hook will not run. `enabled` indicates it will run and reject
+any pushes that result in a non-zero status. `testing` means the script will run but will not cause any pushes to be rejected.
+
+`configuration_url` may be a link to this repository, it's organization
+owner or global configuration. Authorization to access the endpoint at
+`configuration_url` is determined at the owner or site admin level.
+
+## List pre-receive hooks
+
+List all pre-receive hooks that are enabled or testing for this
+repository as well as any disabled hooks that are allowed to be enabled
+at the repository level. Pre-receive hooks that are disabled at a higher
+level and are not configurable will not be listed.
+
+ GET /repos/:owner/:repo/pre-receive-hooks
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json :pre_receive_hooks_repo %>
+
+## Get a single pre-receive hook
+
+ GET /repos/:owner/:repo/pre-receive-hooks/:id
+
+<%= headers 200 %> <%= json :pre_receive_hook_repo %>
+
+## Update pre-receive hook enforcement
+
+For pre-receive hooks which are allowed to be configured at the repo level, you can set `enforcement`
+
+ PATCH /repos/:owner/:repo/pre-receive-hooks/:id
+
+<%= json :enforcement => "enabled" %>
+
+### Response
+
+<%= headers 200 %><%= json :pre_receive_hook_repo_update %>
+
+## Remove enforcement overrides for a pre-receive hook
+
+Deletes any overridden enforcement on this repository for the specified
+hook.
+
+ DELETE /repos/:owner/:repo/pre-receive-hooks/:id
+
+### Response
+
+Responds with effective values inherited from owner and/or global level.
+
+<%= headers 200 %> <%= json :pre_receive_hook_repo %>
diff --git a/content/v3/repos/releases.md b/content/v3/repos/releases.md
index 65e01bf679..73a2e10891 100644
--- a/content/v3/repos/releases.md
+++ b/content/v3/repos/releases.md
@@ -1,27 +1,29 @@
---
-title: Releases | GitHub API
+title: Releases
---
# Releases
-* TOC
{:toc}
## List releases for a repository
-Users with push access to the repository will receive all releases
-(i.e., published releases and draft releases). Users with pull access
-will receive published releases only.
+{{#tip}}
- GET /repos/:owner/:repo/releases
-
-Note: This returns a list of releases, which does not include regular
+This returns a list of releases, which does not include regular
Git tags that have not been associated with a release.
To get a list of Git tags, use the [Repository Tags API][repo tags api].
+{{/tip}}
+
+Information about published releases are available to everyone.
+Only users with push access will receive listings for draft releases.
+
+ GET /repos/:owner/:repo/releases
+
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:release) { |h| [h] } %>
## Get a single release
@@ -30,11 +32,39 @@ To get a list of Git tags, use the [Repository Tags API][repo tags api].
### Response
+{{#tip}}
+
+
+
+**Note:** This returns an `upload_url` key corresponding to the endpoint for uploading release assets. This key is a [hypermedia resource](https://developer.github.com/v3/#hypermedia).
+
+{{/tip}}
+
+<%= headers 200 %>
+<%= json :release %>
+
+## Get the latest release
+
+View the latest published full release for the repository. Draft releases and prereleases are not returned by this endpoint.
+
+ GET /repos/:owner/:repo/releases/latest
+
+### Response
+
+<%= headers 200 %>
+<%= json :release %>
+
+## Get a release by tag name
+
+Get a published release with the specified tag.
+
+ GET /repos/:owner/:repo/releases/tags/:tag
+
+### Response
+
<%= headers 200 %>
<%= json :release %>
-Note: This returns an "upload_url" hypermedia relation that provides the [endpoint
-that creates release assets](#upload-a-release-asset).
## Create a release
@@ -66,8 +96,7 @@ Name | Type | Description
### Response
-<%= headers 201,
- :Location => 'https://api.github.com/repos/octocat/Hello-World/releases/1' %>
+<%= headers 201, :Location => get_resource(:created_release)['url'] %>
<%= json(:created_release) %>
## Edit a release
@@ -119,34 +148,32 @@ Users with push access to the repository can delete a release.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:release_asset) { |h| [h] } %>
## Upload a release asset
-This is a unique endpoint. The domain of the request changes from "api.github.com"
-to **"uploads.github.com"**. You need to use an HTTP client which supports
-[SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this
-endpoint.
+This endpoint makes use of [a Hypermedia relation](/v3/#hypermedia) to determine which URL to access.
+This endpoint is provided by a URI template in [the release's API response](#get-a-single-release).
+{% if page.version == 'dotcom' %}You need to use an HTTP client which supports
+SNI to make calls to this endpoint.{% endif %}
-The asset data is expected in its raw binary form,
-instead of JSON. Everything else about the endpoint is the same. Pass your
-authentication exactly the same as the rest of the API.
+The asset data is expected in its raw binary form, rather than JSON.
+Everything else about the endpoint is the same as the rest of the API. For example, you'll still need to pass your authentication to be able to upload an asset.
- POST https://uploads.github.com/repos/:owner/:repo/releases/:id/assets?name=foo.zip
+ POST https:///repos/:owner/:repo/releases/:id/assets?name=foo.zip
-This endpoint is provided by a URI template in [the release's API response](#get-a-single-release).
### Input
-The raw file is uploaded to GitHub. Set the content type appropriately, and the
-asset's name in a URI query parameter.
+The raw file is uploaded to {{ site.data.variables.product.product_name }}. Set the content type appropriately, and the
+asset's name and label in URI query parameters.
Name | Type | Description
-----|------|--------------
-`Content-Type`|`string` | **Required**. The content type of the asset. This should be set in the Header. Example: "application/zip". For a list of acceptable types, refer this list of [common media types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types).
-`name`|`string` | **Required**. The file name of the asset. This should be set in the URI query parameter.
-
+`Content-Type`|`string` | **Required**. The content type of the asset. This should be set in the Header. Example: `"application/zip"`. For a list of acceptable types, refer this list of [media types][media type list].
+`name`|`string` | **Required**. The file name of the asset. This should be set in a URI query parameter.
+`label`|`string` | An alternate short description of the asset. Used in place of the filename. This should be set in a URI query parameter.
Send the raw binary content of the asset as the request body.
@@ -157,7 +184,7 @@ Send the raw binary content of the asset as the request body.
### Response for upstream failure
-This may leave an empty asset with a state of "new". It can be safely deleted.
+This may leave an empty asset with a state of `"new"`. It can be safely deleted.
<%= headers 502 %>
@@ -167,15 +194,16 @@ This may leave an empty asset with a state of "new". It can be safely deleted.
### Response
-<%= headers 200 %>
-<%= json :release_asset %>
+{{#tip}}
+
+To download the asset's binary content, set the `Accept` header of the request to [`application/octet-stream`](https://developer.github.com/v3/media/#media-types).
+The API will either redirect the client to the location, or stream it directly if possible.
+API clients should handle both a `200` or `302` response.
-If you want to download the asset's binary content, pass a media type of
-"application/octet-stream". The API will either redirect the client to the
-location, or stream it directly if possible. API clients should handle both a
-200 or 302 response.
+{{/tip}}
-<%= headers 302 %>
+<%= headers 200 %>
+<%= json :release_asset %>
## Edit a release asset
@@ -188,7 +216,7 @@ Users with push access to the repository can edit a release asset.
Name | Type | Description
-----|------|--------------
`name`|`string` | **Required**. The file name of the asset.
-`label`|`string` | An alternate short description of the asset. Used in place of the filename.
+`label`|`string` | An alternate short description of the asset. Used in place of the filename.
#### Example
@@ -210,4 +238,5 @@ Name | Type | Description
<%= headers 204 %>
+[media type list]: https://www.iana.org/assignments/media-types/media-types.xhtml
[repo tags api]: /v3/repos/#list-tags
diff --git a/content/v3/repos/statistics.md b/content/v3/repos/statistics.md
index 9c43fc3622..5b829f33d8 100644
--- a/content/v3/repos/statistics.md
+++ b/content/v3/repos/statistics.md
@@ -1,13 +1,12 @@
---
-title: Statistics | GitHub API
+title: Statistics
---
# Statistics
-* TOC
{:toc}
-The Repository Statistics API allows you to fetch the data that GitHub uses for visualizing different
+The Repository Statistics API allows you to fetch the data that {{ site.data.variables.product.product_name }} uses for visualizing different
types of repository activity.
### A word about caching
@@ -22,26 +21,28 @@ then submit the request again. If the job has completed, that request will recei
Repository statistics are cached by the SHA of the repository's default branch,
which is usually master; pushing to the default branch resets the statistics cache.
-## Get contributors list with additions, deletions, and commit counts {#contributors}
+
+## Get contributors list with additions, deletions, and commit counts
GET /repos/:owner/:repo/stats/contributors
### Response
-<%= headers 200 %>
-<%= json(:repo_stats_contributors) %>
-
* `total` - The Total number of commits authored by the contributor.
-**Weekly Hash**
+Weekly Hash (`weeks` array):
* `w` - Start of the week, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time).
* `a` - Number of additions
* `d` - Number of deletions
* `c` - Number of commits
+<%= headers 200 %>
+<%= json(:repo_stats_contributors) %>
-## Get the last year of commit activity data {#commit-activity}
+
+
+## Get the last year of commit activity data
Returns the last year of commit activity grouped by week. The `days` array
is a group of commits per day, starting on `Sunday`.
@@ -53,7 +54,9 @@ is a group of commits per day, starting on `Sunday`.
<%= headers 200 %>
<%= json(:repo_stats_commit_activity) %>
-## Get the number of additions and deletions per week {#code-frequency}
+
+
+## Get the number of additions and deletions per week
GET /repos/:owner/:repo/stats/code_frequency
@@ -65,7 +68,9 @@ to a repository.
<%= headers 200 %>
<%= json(:repo_stats_code_frequency) %>
-## Get the weekly commit count for the repository owner and everyone else {#participation}
+
+
+## Get the weekly commit count for the repository owner and everyone else
GET /repos/:owner/:repo/stats/participation
@@ -73,14 +78,16 @@ to a repository.
Returns the total commit counts for the `owner` and total commit counts in `all`.
`all` is everyone combined, including the `owner` in the last 52 weeks. If you'd like to get the commit
-counts for non-owners, you can subtract `all` from `owner`.
+counts for non-owners, you can subtract `owner` from `all`.
The array order is oldest week (index 0) to most recent week.
<%= headers 200 %>
<%= json(:repo_stats_participation) %>
-## Get the number of commits per hour in each day {#punch-card}
+
+
+## Get the number of commits per hour in each day
GET /repos/:owner/:repo/stats/punch_card
diff --git a/content/v3/repos/statuses.md b/content/v3/repos/statuses.md
index 5a84e01fe5..0ab8ce9701 100644
--- a/content/v3/repos/statuses.md
+++ b/content/v3/repos/statuses.md
@@ -1,10 +1,9 @@
---
-title: Statuses | GitHub API
+title: Statuses
---
# Statuses
-* TOC
{:toc}
The Status API allows external services to mark commits with a success,
@@ -21,56 +20,97 @@ services to mark commits as passing or failing builds using Status. The
`description` would be the high level summary of what happened with the
build.
+Statuses can include a `context` to indicate what service is providing that status.
+For example, you may have your continuous integration service push statuses with a context of `ci`,
+and a security audit tool push statuses with a context of `security`. You can
+then use the [combined status endpoint](https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref)
+to retrieve the whole status for a commit.
+
Note that the `repo:status` [OAuth scope](/v3/oauth/#scopes) grants targeted
access to Statuses **without** also granting access to repository code, while the
`repo` scope grants permission to code as well as statuses.
+## Create a Status
+
+Users with push access can create commit statuses for a given ref:
+
+ POST /repos/:owner/:repo/statuses/:sha
+
+Note: there is a limit of 1000 statuses per `sha` and `context` within a Repository.
+Attempts to create more than 1000 statuses will result in a validation error.
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`state`|`string` | **Required**. The state of the status. Can be one of `pending`, `success`, `error`, or `failure`.
+`target_url`|`string` | The target URL to associate with this status. This URL will be linked from the {{ site.data.variables.product.product_name }} UI to allow users to easily see the 'source' of the Status. For example, if your Continuous Integration system is posting build status, you would want to provide the deep link for the build output for this specific SHA: `http://ci.example.com/user/repo/build/sha`.
+`description`|`string` | A short description of the status.
+`context`|`string` | A string label to differentiate this status from the status of other systems. Default: `"default"`
+
+#### Example
+
+<%= json \
+ :state => "success",
+ :target_url => "https://example.com/build/status",
+ :description => "The build succeeded!",
+ :context => "continuous-integration/jenkins"
+%>
+
+### Response
+
+<%= headers 201, :Location => get_resource(:status)['url'] %>
+<%= json :status %>
+
## List Statuses for a specific Ref
Users with pull access can view commit statuses for a given ref:
- GET /repos/:owner/:repo/statuses/:ref
+ GET /repos/:owner/:repo/commits/:ref/statuses
+
+{{#tip}}
+
+This resource is also available via a legacy route:
+`GET /repos/:owner/:repo/statuses/:ref`.
+
+{{/tip}}
Statuses are returned in reverse chronological order. The first status in the
list will be the latest one.
### Parameters
-Name | Type | Description
+Name | Type | Description
-----|------|--------------
`ref`|`string` | **Required**. Ref to list the statuses from. It can be a SHA, a branch name, or a tag name.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:status) { |h| [h] } %>
-## Create a Status
+## Get the combined Status for a specific Ref
-Users with push access can create commit statuses for a given ref:
+Users with pull access can access a combined view of commit statuses for a given ref.
- POST /repos/:owner/:repo/statuses/:sha
+ GET /repos/:owner/:repo/commits/:ref/status
-### Parameters
+The most recent status for each context is returned, up to 100. This field
+[paginates](/v3/#pagination) if there are over 100 contexts.
-Name | Type | Description
------|------|--------------
-`state`|`string` | **Required**. The state of the status. Can be one of `pending`, `success`, `error`, or `failure`.
-`target_url`|`string` | The target URL to associate with this status. This URL will be linked from the GitHub UI to allow users to easily see the 'source' of the Status. For example, if your Continuous Integration system is posting build status, you would want to provide the deep link for the build output for this specific SHA: `http://ci.example.com/user/repo/build/sha`.
-`description`|`string` | A short description of the status
+Additionally, a combined `state` is returned. The `state` is one of:
-#### Example
+ * **failure** if any of the contexts report as error or failure
+ * **pending** if there are no statuses or a context is pending
+ * **success** if the latest status for all contexts is success
-<%= json \
- :state => "success",
- :target_url => "https://example.com/build/status",
- :description => "The build succeeded!"
-%>
+### Parameters
-### Response
+Name | Type | Description
+-----|------|--------------
+`ref`|`string` | **Required**. Ref to fetch the status for. It can be a SHA, a branch name, or a tag name.
-<%= headers 201,
- :Location =>
-'https://api.github.com/repos/octocat/example/statuses/1' %>
-<%= json :status %>
+### Response
+<%= headers 200 %>
+<%= json(:combined_status) %>
diff --git a/content/v3/repos/traffic.md b/content/v3/repos/traffic.md
new file mode 100644
index 0000000000..483197db77
--- /dev/null
+++ b/content/v3/repos/traffic.md
@@ -0,0 +1,79 @@
+---
+title: Traffic
+---
+
+# Traffic
+{{#tip}}
+
+
+
+ APIs for repository traffic are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-08-15-traffic-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.spiderman-preview
+
+{{/tip}}
+
+{:toc}
+
+For repositories that you have push access to, the traffic API provides access
+to the information provided in the [graphs section](https://help.github.com/articles/about-repository-graphs/#traffic).
+
+
+
+## List referrers
+
+Get the top 10 referrers over the last 14 days.
+
+ GET /repos/:owner/:repo/traffic/popular/referrers
+
+### Response
+
+<%= headers 200 %>
+<%= json(:traffic_referrers) %>
+
+## List paths
+
+Get the top 10 popular contents over the last 14 days.
+
+ GET /repos/:owner/:repo/traffic/popular/paths
+
+### Response
+
+<%= headers 200%>
+<%= json(:traffic_contents) %>
+
+## Views
+
+Get the total number of views and breakdown per day or week for the last 14 days.
+
+ GET /repos/:owner/:repo/traffic/views
+
+### Parameters
+Name | Type | Description
+-----|------|--------------
+`per`|string|Must be one of: `day`, `week`. Default: `day`
+
+
+### Response
+<%= headers 200 %>
+<%= json(:traffic_views) %>
+
+## Clones
+
+Get the total number of clones and breakdown per day or week for the last 14 days.
+
+ GET /repos/:owner/:repo/traffic/clones
+
+### Parameters
+Name | Type | Description
+-----|------|--------------
+`per`|string|Must be one of: `day`, `week`. Default: `day`
+
+### Response
+
+<%= headers 200 %>
+<%= json(:traffic_clones) %>
diff --git a/content/v3/search.md b/content/v3/search.md
index 9f110c8e7e..bfdefdd175 100644
--- a/content/v3/search.md
+++ b/content/v3/search.md
@@ -1,10 +1,9 @@
---
-title: Search | GitHub API
+title: Search
---
# Search
-* TOC
{:toc}
### About the Search API
@@ -15,28 +14,42 @@ the way you think of performing a search on Google. It's designed to help you
find the one result you're looking for (or maybe the few results you're looking
for). Just like searching on Google, you sometimes want to see a few pages of
search results so that you can find the item that best meets your needs. To
-satisfy that need, the GitHub Search API provides **up to 1,000 results for each
+satisfy that need, the {{ site.data.variables.product.product_name }} Search API provides **up to 1,000 results for each
search**.
### Ranking search results
Unless another sort option is provided as a query parameter, results are sorted
by best match, as indicated by the `score` field for each item returned. This
-is a computed value representing the relevance of a item relative to the other
+is a computed value representing the relevance of an item relative to the other
items in the result set. Multiple factors are combined to boost the most
relevant item to the top of the result list.
+{% if page.version == 'dotcom' %}
+
### Rate limit
The Search API has a custom rate limit. For requests using [Basic
Authentication](/v3/#authentication), [OAuth](/v3/#authentication), or [client
-ID and secret](/v3/#unauthenticated-rate-limited-requests), you can make up to
-20 requests per minute. For unauthenticated requests, the rate limit allows you
-to make up to 5 requests per minute.
+ID and secret](/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications), you can make up to
+30 requests per minute. For unauthenticated requests, the rate limit allows you
+to make up to 10 requests per minute.
See the [rate limit documentation](/v3/#rate-limiting) for details on
determining your current rate limit status.
+{% endif %}
+
+### Timeouts and incomplete results
+
+To keep the Search API fast for everyone, we limit how long any individual query
+can run. For queries that [exceed the time limit](/changes/2014-04-07-understanding-search-results-and-potential-timeouts/),
+the API returns the matches that were already found prior to the timeout, and
+the response has the `incomplete_results` property set to `true`.
+
+Reaching a timeout does not necessarily mean that search results are incomplete.
+More results might have been found, but also might not.
+
## Search repositories
Find repositories via various criteria. This method returns up to 100 results [per page](/v3/#pagination).
@@ -51,23 +64,24 @@ Name | Type | Description
`sort`|`string`| The sort field. One of `stars`, `forks`, or `updated`. Default: results are sorted by best match.
`order`|`string`| The sort order if `sort` parameter is provided. One of `asc` or `desc`. Default: `desc`
-The `q` search term can also contain any combination of the supported repository search qualifiers:
+The `q` search term can also contain any combination of the supported repository search qualifiers as described by the in-browser [repository search documentation](https://help.github.com/articles/searching-repositories/) and [search syntax documentation](https://help.github.com/articles/search-syntax/):
-* [`in`](https://help.github.com/articles/searching-repositories#search-in)
+* [`in`](https://help.github.com/articles/searching-repositories#scope-the-search-fields)
Qualifies which fields are searched. With this qualifier you can restrict the
search to just the repository name, description, readme, or
any combination of these.
-* [`size`](https://help.github.com/articles/searching-repositories#size)
+* [`size`](https://help.github.com/articles/searching-repositories#search-based-on-the-size-of-a-repository)
Finds repositories that match a certain size (in kilobytes).
-* [`forks`](https://help.github.com/articles/searching-repositories#forks)
- Filters repositories based on the number of forks, and/or whether forked repositories should be included in the results at all.
-* [`created` or `pushed`](https://help.github.com/articles/searching-repositories#created-and-last-updated)
- Filters repositories based on times of creation, or when they were last updated.
-* [`user` or `repo`](https://help.github.com/articles/searching-repositories#users-organizations-and-repositories)
+* [`forks`](https://help.github.com/articles/searching-repositories#search-based-on-the-number-of-forks-the-parent-repository-has)
+ Filters repositories based on the number of forks.
+* [`fork`](https://help.github.com/articles/searching-repositories#search-based-on-the-number-of-forks-the-parent-repository-has) Filters whether forked repositories should be included (`true`) or only forked repositories should be returned (`only`).
+* [`created` or `pushed`](https://help.github.com/articles/searching-repositories#search-based-on-when-a-repository-was-created-or-last-updated)
+ Filters repositories based on date of creation, or when they were last updated.
+* [`user` or `repo`](https://help.github.com/articles/searching-repositories#search-within-a-users-or-organizations-repositories)
Limits searches to a specific user or repository.
-* [`language`](https://help.github.com/articles/searching-repositories#languages)
+* [`language`](https://help.github.com/articles/searching-repositories#search-based-on-the-main-language-of-a-repository)
Searches repositories based on the language they're written in.
-* [`stars`](https://help.github.com/articles/searching-repositories#stars)
+* [`stars`](https://help.github.com/articles/searching-repositories#search-based-on-the-number-of-stars-a-repository-has)
Searches repositories based on the number of stars.
Example
@@ -83,7 +97,7 @@ repositories where the primary language is Assembly. We're sorting by stars in
descending order, so that the most popular repositories appear first in the
search results.
-<%= headers 200, {'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19} %>
+<%= headers 200, {:pagination => default_pagination_rels{% if page.version == 'dotcom' %}, 'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19{% endif %}} %>
<%= json(:repo_search_v3_results) %>
### Highlighting Repository Search Results
@@ -94,8 +108,10 @@ use case. To get this metadata in your search results, specify the `text-match`
media type in your Accept header. For example, via curl, the above query would
look like this:
- curl -H 'Accept: application/vnd.github.v3.text-match+json' \
- https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc
+``` command-line
+curl -H 'Accept: application/vnd.github.v3.text-match+json' \
+ 'https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc'
+```
This produces the same JSON payload as above, with an extra key called
`text_matches`, an array of objects. These objects provide information such as
@@ -116,32 +132,46 @@ Find file contents via various criteria. (This method returns up to 100 results
GET /search/code
+### Considerations for code search
+
+Due to the complexity of searching code, there are a few restrictions on how searches are performed:
+
+
+
Only the default branch is considered. In most cases, this will be the master branch.
+
Only files smaller than {% if page.version != 'dotcom' and page.version >= 2.2 %} 10 MB {% else %} 384 KB {% endif %} are searchable.
+{% if page.version == 'dotcom' %}
+
You must always include at least one search term when searching source code. For example, searching for language:go is not valid, while amazing language:go is.
+{% endif %}
+
+
### Parameters
Name | Type | Description
-----|------|--------------
`q`|`string`| The search terms.
-`sort`|`string`| The sort field. Can only be `indexed`, which indicates how recently a file has been indexed by the GitHub search infrastructure. Default: results are sorted by best match.
+`sort`|`string`| The sort field. Can only be `indexed`, which indicates how recently a file has been indexed by the {{ site.data.variables.product.product_name }} search infrastructure. Default: results are sorted by best match.
`order`|`string`| The sort order if `sort` parameter is provided. One of `asc` or `desc`. Default: `desc`
-The `q` search term can also contain any combination of the supported code search qualifiers:
+The `q` search term can also contain any combination of the supported code search qualifiers as described by the in-browser [code search documentation](https://help.github.com/articles/searching-code/) and [search syntax documentation](https://help.github.com/articles/search-syntax/):
-* [`in`](https://help.github.com/articles/searching-code#search-in)
+* [`in`](https://help.github.com/articles/searching-code#scope-the-search-fields)
Qualifies which fields are searched. With this qualifier you can restrict the
- search to just the file contents, the file path, or both.
-* [`language`](https://help.github.com/articles/searching-code#language)
+ search to the file contents (`file`), the file path (`path`), or both.
+* [`language`](https://help.github.com/articles/searching-code#search-by-language)
Searches code based on the language it's written in.
-* [`fork`](https://help.github.com/articles/searching-code#forks)
- Specifies that code from forked repositories should be searched. Repository
+* [`fork`](https://help.github.com/articles/searching-code#search-by-the-number-of-forks-the-parent-repository-has)
+ Specifies that code from forked repositories should be searched (`true`). Repository
forks will not be searchable unless the fork has more stars than the parent
repository.
-* [`size`](https://help.github.com/articles/searching-code#size)
+* [`size`](https://help.github.com/articles/searching-code#search-by-the-size-of-the-parent-repository)
Finds files that match a certain size (in bytes).
-* [`path`](https://help.github.com/articles/searching-code#path)
- Specifies the path that the resulting file must be at.
-* [`extension`](https://help.github.com/articles/searching-code#extension)
- Matches files with a certain extension.
-* [`user` or `repo`](https://help.github.com/articles/searching-code#users-organizations-and-repositories)
+* [`path`](https://help.github.com/articles/searching-code#search-by-the-location-of-a-file-within-the-repository)
+ Specifies the path prefix that the resulting file must be under.
+* [`filename`](https://help.github.com/articles/searching-code#search-by-filename)
+ Matches files by a substring of the filename.
+* [`extension`](https://help.github.com/articles/searching-code#search-by-the-file-extension)
+ Matches files with a certain extension after a dot.
+* [`user` or `repo`](https://help.github.com/articles/searching-code#search-within-a-users-or-organizations-repositories)
Limits searches to a specific user or repository.
Example
@@ -156,7 +186,7 @@ Here, we're searching for the keyword `addClass` within a file's contents. We're
making sure that we're only looking in files where the language is JavaScript.
And we're scoping the search to the `repo:jquery/jquery` repository.
-<%= headers 200, {'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19} %>
+<%= headers 200, {:pagination => default_pagination_rels,{% if page.version == 'dotcom' %} 'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19{% endif %}} %>
<%= json(:code_search_v3_results) %>
### Highlighting Code Search Results
@@ -167,8 +197,10 @@ use case. To get this metadata in your search results, specify the `text-match`
media type in your Accept header. For example, via curl, the above query would
look like this:
- curl -H 'Accept: application/vnd.github.v3.text-match+json' \
- https://api.github.com/search/code?q=addClass+in:file+language:js+repo:jquery/jquery
+``` command-line
+curl -H 'Accept: application/vnd.github.v3.text-match+json' \
+ https://api.github.com/search/code?q=addClass+in:file+language:js+repo:jquery/jquery
+```
This produces the same JSON payload as above, with an extra key called
`text_matches`, an array of objects. These objects provide information such as
@@ -197,38 +229,54 @@ Name | Type | Description
`sort`|`string`| The sort field. Can be `comments`, `created`, or `updated`. Default: results are sorted by best match.
`order`|`string`| The sort order if `sort` parameter is provided. One of `asc` or `desc`. Default: `desc`
-The `q` search term can also contain any combination of the supported issue search qualifiers:
+The `q` search term can also contain any combination of the supported issue search qualifiers as described by the in-browser [issue search documentation](https://help.github.com/articles/searching-issues/) and [search syntax documentation](https://help.github.com/articles/search-syntax/):
- * [`type`](https://help.github.com/articles/searching-issues#type)
- With this qualifier you can restrict the search to issues or pull request only.
- * [`in`](https://help.github.com/articles/searching-issues#search-in)
+ * [`type`](https://help.github.com/articles/searching-issues#search-issues-or-pull-requests)
+ With this qualifier you can restrict the search to issues (`issue`) or pull request (`pr`) only.
+ * [`in`](https://help.github.com/articles/searching-issues#scope-the-search-fields)
Qualifies which fields are searched. With this qualifier you can restrict the
- search to just the title, body, comments, or any combination of these.
- * [`author`](https://help.github.com/articles/searching-issues#author)
- Finds issues created by a certain user.
- * [`assignee`](https://help.github.com/articles/searching-issues#assignee)
- Finds issues that are assigned to a certain user.
- * [`mentions`](https://help.github.com/articles/searching-issues#mentions)
- Finds issues that mention a certain user.
- * [`commenter`](https://help.github.com/articles/searching-issues#commenter)
- Finds issues that a certain user commented on.
- * [`involves`](https://help.github.com/articles/searching-issues#involves)
- Finds issues that were either created by a certain user, assigned to that
+ search to just the title (`title`), body (`body`), comments (`comments`), or any combination of these.
+ * [`author`](https://help.github.com/articles/searching-issues#search-by-the-author-of-an-issue-or-pull-request)
+ Finds issues or pull requests created by a certain user.
+ * [`assignee`](https://help.github.com/articles/searching-issues#search-by-the-assignee-of-an-issue-or-pull-request)
+ Finds issues or pull requests that are assigned to a certain user.
+ * [`mentions`](https://help.github.com/articles/searching-issues#search-by-a-mentioned-user-within-an-issue-or-pull-request)
+ Finds issues or pull requests that mention a certain user.
+ * [`commenter`](https://help.github.com/articles/searching-issues#search-by-a-commenter-within-an-issue-or-pull-request)
+ Finds issues or pull requests that a certain user commented on.
+ * [`involves`](https://help.github.com/articles/searching-issues#search-by-a-user-thats-involved-within-an-issue-or-pull-request)
+ Finds issues or pull requests that were either created by a certain user, assigned to that
user, mention that user, or were commented on by that user.
- * [`state`](https://help.github.com/articles/searching-issues#state)
- Filter issues based on whether they're open or closed.
- * [`labels`](https://help.github.com/articles/searching-issues#labels)
- Filters issues based on their labels.
- * [`language`](https://help.github.com/articles/searching-issues#language)
- Searches for issues within repositories that match a certain language.
- * [`created` or `updated`](https://help.github.com/articles/searching-issues#created-and-last-updated)
- Filters issues based on times of creation, or when they were last updated.
- * [`comments`](https://help.github.com/articles/searching-issues#comments)
- Filters issues based on the quantity of comments.
- * [`user` or `repo`](https://help.github.com/articles/searching-issues#users-organizations-and-repositories)
+ * [`team`](https://help.github.com/articles/searching-issues/#search-by-a-team-thats-mentioned-within-an-issue-or-pull-request)
+ For organizations you're a member of, finds issues or pull requests that @mention a team within the organization.
+ * [`state`](https://help.github.com/articles/searching-issues#search-based-on-whether-an-issue-or-pull-request-is-open)
+ Filter issues or pull requests based on whether they're open or closed.
+ * [`labels`](https://help.github.com/articles/searching-issues#search-by-the-labels-on-an-issue)
+ Filters issues or pull requests based on their labels.
+ * [`no`](https://help.github.com/articles/searching-issues#search-by-missing-metadata-on-an-issue-or-pull-request)
+ Filters items missing certain metadata, such as `label`, `milestone`, or `assignee`
+ * [`language`](https://help.github.com/articles/searching-issues#search-by-the-main-language-of-a-repository)
+ Searches for issues or pull requests within repositories that match a certain language.
+ * [`is`](https://help.github.com/articles/searching-issues#search-based-on-the-state-of-an-issue-or-pull-request)
+ Searches for items within repositories that match a certain state, such as `open`, `closed`, or `merged`
+ * [`created` or `updated`](https://help.github.com/articles/searching-issues#search-based-on-when-an-issue-or-pull-request-was-created-or-last-updated)
+ Filters issues or pull requests based on date of creation, or when they were last updated.
+ * [`merged`](https://help.github.com/articles/searching-issues#search-based-on-when-a-pull-request-was-merged)
+ Filters pull requests based on the date when they were merged.
+ * [`status`](https://help.github.com/articles/searching-issues#search-based-on-commit-status)
+ Filters pull requests based on the commit status.
+ * [`head` or `base`](https://help.github.com/articles/searching-issues#search-based-on-branch-names)
+ Filters pull requests based on the branch that they came from or that they are modifying.
+ * [`closed`](https://help.github.com/articles/searching-issues#search-based-on-when-an-issue-or-pull-request-was-closed)
+ Filters issues or pull requests based on the date when they were closed.
+ * [`comments`](https://help.github.com/articles/searching-issues#search-by-the-number-of-comments-an-issue-or-pull-request-has)
+ Filters issues or pull requests based on the quantity of comments.
+ * [`user` or `repo`](https://help.github.com/articles/searching-issues#search-within-a-users-or-organizations-repositories)
Limits searches to a specific user or repository.
+If you know the specific SHA hash of a commit, you can use also [use it to search for pull requests](https://help.github.com/articles/searching-issues#search-by-the-commit-shas-within-a-pull-request) that contain that SHA. Note that the SHA syntax must be at least seven characters.
+
Example
Let's say you want to find the oldest unresolved Python bugs on Windows. Your
@@ -241,7 +289,7 @@ that's labeled as `bug`. The search runs across repositories whose primary
language is Python. We’re sorting by creation date in ascending order, so that
the oldest issues appear first in the search results.
-<%= headers 200, {'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19} %>
+<%= headers 200, {:pagination => default_pagination_rels,{% if page.version == 'dotcom' %} 'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19{% endif %}} %>
<%= json(:issue_search_v3_results) %>
### Highlighting Issue Search Results
@@ -252,8 +300,10 @@ use case. To get this metadata in your search results, specify the `text-match`
media type in your Accept header. For example, via curl, the above query would
look like this:
- curl -H 'Accept: application/vnd.github.v3.text-match+json' \
- https://api.github.com/search/issues?q=windows+label:bug+language:python+state:open&sort=created&order=asc
+``` command-line
+curl -H 'Accept: application/vnd.github.v3.text-match+json' \
+ 'https://api.github.com/search/issues?q=windows+label:bug+language:python+state:open&sort=created&order=asc'
+```
This produces the same JSON payload as above, with an extra key called
`text_matches`, an array of objects. These objects provide information such as
@@ -282,24 +332,24 @@ Name | Type | Description
`sort`|`string`| The sort field. Can be `followers`, `repositories`, or `joined`. Default: results are sorted by best match.
`order`|`string`| The sort order if `sort` parameter is provided. One of `asc` or `desc`. Default: `desc`
-The `q` search term can also contain any combination of the supported user search qualifiers:
+The `q` search term can also contain any combination of the supported user search qualifiers as described by the in-browser [user search documentation](https://help.github.com/articles/searching-users/) and [search syntax documentation](https://help.github.com/articles/search-syntax/):
- * [`type`](https://help.github.com/articles/searching-users#type)
- With this qualifier you can restrict the search to just personal accounts or
- just organization accounts.
- * [`in`](https://help.github.com/articles/searching-users#search-in)
+ * [`type`](https://help.github.com/articles/searching-users#search-for-users-or-organizations)
+ With this qualifier you can restrict the search to just personal accounts (`user`) or
+ just organization accounts (`org`).
+ * [`in`](https://help.github.com/articles/searching-users#scope-the-search-fields)
Qualifies which fields are searched. With this qualifier you can restrict
- the search to just the username, public email, full name, or any
+ the search to just the username (`login`), public email (`email`), full name (`fullname`), or any
combination of these.
- * [`repos`](https://help.github.com/articles/searching-users#repository-count)
+ * [`repos`](https://help.github.com/articles/searching-users#search-based-on-the-number-of-repositories-a-user-has)
Filters users based on the number of repositories they have.
- * [`location`](https://help.github.com/articles/searching-users#location)
+ * [`location`](https://help.github.com/articles/searching-users#search-based-on-the-location-where-a-user-resides)
Filter users by the location indicated in their profile.
- * [`language`](https://help.github.com/articles/searching-users#language)
+ * [`language`](https://help.github.com/articles/searching-users#search-based-on-the-languages-of-a-users-repositories)
Search for users that have repositories that match a certain language.
- * [`created`](https://help.github.com/articles/searching-users#created)
+ * [`created`](https://help.github.com/articles/searching-users#search-based-on-when-a-user-joined-github)
Filter users based on when they joined.
- * [`followers`](https://help.github.com/articles/searching-users#followers)
+ * [`followers`](https://help.github.com/articles/searching-users#search-based-on-the-number-of-followers-a-user-has)
Filter users based on the number of followers they have.
Example
@@ -311,7 +361,7 @@ Imagine you're looking for a list of popular users. You might try out this query
Here, we're looking at users with the name Tom. We're only interested in those
with more than 42 repositories, and only if they have over 1,000 followers.
-<%= headers 200, {'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19} %>
+<%= headers 200, {:pagination => default_pagination_rels,{% if page.version == 'dotcom' %} 'X-RateLimit-Limit' => 20, 'X-RateLimit-Remaining' => 19{% endif %}} %>
<%= json(:user_search_v3_results) %>
### Highlighting User Search Results
@@ -322,8 +372,10 @@ use case. To get this metadata in your search results, specify the `text-match`
media type in your Accept header. For example, via curl, the above query would
look like this:
- curl -H 'Accept: application/vnd.github.v3.text-match+json' \
- https://api.github.com/search/users?q=tom+repos:%3E42+followers:%3E1000
+``` command-line
+curl -H 'Accept: application/vnd.github.v3.text-match+json' \
+ https://api.github.com/search/users?q=tom+repos:%3E42+followers:%3E1000
+```
This produces the same JSON payload as above, with an extra key called
`text_matches`, an array of objects. These objects provide information such as
@@ -353,7 +405,7 @@ in your Accept header.
application/vnd.github.v3.text-match+json
The results will provide the same JSON payloads as shown above, with an extra
-key called `text_matches`. Inside the `text_matches` array, each hash includes
+key called `text_matches`. Inside the `text_matches` array, each object includes
the following attributes:
@@ -370,8 +422,10 @@ Name | Description
Using curl, and the [example issue search](#issue-search-example) above, our API
request would look like this:
- curl -H 'Accept: application/vnd.github.v3.text-match+json' \
- https://api.github.com/search/issues?q=windows+label:bug+language:python+state:open&sort=created&order=asc
+``` command-line
+curl -H 'Accept: application/vnd.github.v3.text-match+json' \
+ 'https://api.github.com/search/issues?q=windows+label:bug+language:python+state:open&sort=created&order=asc'
+```
The response will include a `text_matches` array for each search result. In the
JSON below, we have two objects in the `text_matches` array.
diff --git a/content/v3/search/legacy.md b/content/v3/search/legacy.md
index eb2031b5fc..bcae61c3ff 100644
--- a/content/v3/search/legacy.md
+++ b/content/v3/search/legacy.md
@@ -1,10 +1,9 @@
---
-title: Legacy Search | GitHub API
+title: Legacy Search
---
# Legacy Search
-* TOC
{:toc}
This is a listing of the Legacy Search API features from API v2 that have been ported to API
@@ -12,15 +11,13 @@ v3. There should be no changes, other than the new URL and JSON output format.
### Legacy Search API is Deprecated
-
-
- The Legacy Search API (described below) is deprecated
- and is scheduled for removal in the next major version of the API.
+{{#warning}}
- We recommend using the v3 Search API instead.
- It contains new endpoints and much more functionality.
-
-
+The Legacy Search API (described below) is deprecated and is scheduled for removal in the next major version of the API.
+
+We recommend using the v3 Search API instead. It contains new endpoints and much more functionality.
+
+{{/warning}}
## Search issues
@@ -85,7 +82,7 @@ Name | Type | Description
This API call is added for compatibility reasons only. There's no guarantee
that full email searches will always be available. The `@` character in the
address must be left unencoded. Searches only against public email addresses
-(as configured on the user's GitHub profile).
+(as configured on the user's {{ site.data.variables.product.product_name }} profile).
GET /legacy/user/email/:email
diff --git a/content/v3/troubleshooting.md b/content/v3/troubleshooting.md
index 6fdb910697..09a0d04864 100644
--- a/content/v3/troubleshooting.md
+++ b/content/v3/troubleshooting.md
@@ -1,10 +1,9 @@
---
-title: Troubleshooting | GitHub API
+title: Troubleshooting
---
# Troubleshooting
-* TOC
{:toc}
If you're encountering some oddities in the API, here's a list of resolutions to
@@ -17,12 +16,11 @@ You might expect to see a `403 Forbidden` in these cases. However, since we don'
want to provide _any_ information about private repositories, the API returns a
`404` error instead.
-To fix this, you can either ensure that [you're authenticating correctly](/guides/getting-started/),
-or [make sure that your scopes are valid](/v3/oauth/#scopes).
+To troubleshoot, ensure [you're authenticating correctly](/guides/getting-started/), [your OAuth access token has the required scopes](/v3/oauth/#scopes), and [third-party application restrictions][oap-guide] are not blocking access.
## Why am I not seeing all my results?
-Most API calls accessing a list of resources (_e.g._, users, issues, _e.t.c._) support
+Most API calls accessing a list of resources (_e.g._, users, issues, _etc._) support
pagination. If you're making requests and receiving an incomplete set of results, you're
probably only seeing the first page. You'll need to request the remaining pages
in order to get more results.
@@ -31,9 +29,11 @@ It's important to *not* try and guess the format of the pagination URL. Not ever
API call uses the same structure. Instead, extract the pagination information from
[the Link Header](/v3/#pagination), which is sent with every request.
+{% if page.version == 'dotcom' %}
+
## Can I get my rate limits bumped?
-The GitHub API has a pretty lenient quota for rate limits, for your enjoyment and
+The {{ site.data.variables.product.product_name }} API has a pretty lenient quota for rate limits, for your enjoyment and
our safety. You can read more about it [here](/v3/#rate-limiting).
If you're using OAuth or Basic Authentication and are hitting your rate limits,
@@ -43,8 +43,6 @@ In certain exceptional cases, we may temporarily bump your rate limit higher. Yo
should be prepared to answer technical questions about your goal and your planned usage of the API. We may still choose not to bump your limit if we feel that you can achieve your wildest
dreams with the current rate limit (but don't worry, we'll help you out).
-## Why can't my server with SSL receive Webhooks?
+{% endif %}
-When we send events to your server, we attempt to negotiate either SSL version 2 or 3.
-If your server requires a specific SSL version and does not support SSL negotiation,
-you can specify a specific version within the [webhook's config block](http://developer.github.com/v3/repos/hooks/#edit-a-hook). Include a parameter called `ssl_version`, with a value of either `2` or `3`.
+[oap-guide]: /changes/2015-01-19-an-integrators-guide-to-organization-application-policies/
diff --git a/content/v3/users.md b/content/v3/users.md
index 73ac00f6ae..11e5479a4c 100644
--- a/content/v3/users.md
+++ b/content/v3/users.md
@@ -1,30 +1,29 @@
---
-title: Users | GitHub API
+title: Users
---
# Users
-* TOC
{:toc}
Many of the resources on the users API provide a shortcut for getting
information about the currently authenticated user. If a request URL
-does not include a `:user` parameter then the response will be for the
+does not include a `:username` parameter then the response will be for the
logged in user (and you must pass [authentication
information](/v3/#authentication) with your request).
## Get a single user
- GET /users/:user
+ GET /users/:username
### Response
-<%= headers 200 %>
-<%= json :full_user %>
-
Note: The returned email is the user's publicly visible email address
(or `null` if the user has not [specified a public email address in their profile](https://github.com/settings/profile)).
+<%= headers 200 %>
+<%= json :full_user %>
+
## Get the authenticated user
GET /user
@@ -69,8 +68,7 @@ Name | Type | Description
## Get all users
-This provides a dump of every user, in the order that they signed up for
-GitHub.
+Lists all users, in the order that they signed up on {{ site.data.variables.product.product_name }}. This list includes personal user accounts and organization accounts.
Note: Pagination is powered exclusively by the `since` parameter.
Use the [Link header](/v3/#link-header) to get the URL for the next page of
diff --git a/content/v3/users/administration.md b/content/v3/users/administration.md
new file mode 100644
index 0000000000..f918e2f38c
--- /dev/null
+++ b/content/v3/users/administration.md
@@ -0,0 +1,199 @@
+---
+title: User Administration
+---
+
+# Administration (Enterprise)
+
+{:toc}
+
+The User Administration API allows you to promote, demote, suspend, and unsuspend users on a GitHub Enterprise appliance. *It is only available to [authenticated](/v3/#authentication) site administrators.* Normal users will receive a `403` response if they try to access it.
+
+Prefix all the endpoints for this API with the following URL:
+
+``` command-line
+http(s)://hostname/api/v3
+```
+
+{% if page.version != 'dotcom' and page.version >= 2.3 %}
+
+## Create a new user
+
+{{#warning}}
+
+If an external authentication mechanism is used, the login name should match the
+login name in the external system. If you are using LDAP authentication, you should also
+[update the LDAP mapping](/v3/enterprise/ldap/#update-ldap-mapping-for-a-user)
+for the user.
+
+{{/warning}}
+
+ POST /admin/users
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`login`|`string` | **Required.** The user's username.
+`email`|`string` | **Required.** The user's email address.
+
+The login name will be normalized to only contain alphanumeric characters or
+single hyphens. For example, if you send `"octo_cat"` as the login, a user named
+`"octo-cat"` will be created.
+
+If the login name or email address is already associated with an account, the server will return a `422` response.
+
+#### Example
+
+<%= json \
+ :login => "monalisa",
+ :email => "octocat@github.com"
+%>
+
+### Response
+
+<%= headers 201 %>
+<%= json :user %>
+
+## Rename an existing user
+
+ PATCH /admin/users/:username
+
+### Parameters
+
+Name | Type | Description
+-----|------|--------------
+`login`|`string` | **Required.** The user's new username.
+
+#### Example
+
+<%= json \
+ :login => "thenewmonalisa"
+%>
+
+### Response
+
+<%= headers 202 %>
+<%= json \
+ :message => "Job queued to rename user. It may take a few minutes to complete.",
+ :url => "https://api.github.com/user/1"
+%>
+
+## Create an impersonation OAuth token
+
+ POST /admin/users/:username/authorizations
+
+### Parameters
+
+Name | Type | Description
+---- | ---- | -------------
+`scopes`|`array` | A list of [scopes](/v3/oauth/#scopes).
+
+### Response
+
+<%= headers 201 %>
+<%= json(:oauth_access) %>
+
+## Delete an impersonation OAuth token
+
+ DELETE /admin/users/:username/authorizations
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
+
+## Promote an ordinary user to a site administrator
+
+ PUT /users/:username/site_admin
+
+<%= fetch_content(:put_content_length) %>
+
+### Response
+
+<%= headers 204 %>
+
+## Demote a site administrator to an ordinary user
+
+ DELETE /users/:username/site_admin
+
+You can demote any user account except your own.
+
+### Response
+
+<%= headers 204 %>
+
+## Suspend a user
+
+{{#warning}}
+
+If your GitHub Enterprise appliance has [LDAP Sync with Active Directory LDAP servers](https://help.github.com/enterprise/admin/guides/user-management/using-ldap), this API is disabled and will return a `403` response. Users managed by an external account cannot be suspended via the API.
+
+{{/warning}}
+
+ PUT /users/:username/suspended
+
+You can suspend any user account except your own.
+
+<%= fetch_content(:put_content_length) %>
+
+### Response
+
+<%= headers 204 %>
+
+## Unsuspend a user
+
+{{#warning}}
+
+If your GitHub Enterprise appliance has [LDAP Sync with Active Directory LDAP servers](https://help.github.com/enterprise/admin/guides/user-management/using-ldap), this API is disabled and will return a `403` response. Users managed by an external account cannot be unsuspended via the API.
+
+{{/warning}}
+
+ DELETE /users/:username/suspended
+
+### Response
+
+<%= headers 204 %>
+
+{% if page.version != 'dotcom' and page.version >= 2.3 %}
+
+## List all public keys
+
+ GET /admin/keys
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:all_keys) { |public_key, deploy_key| \
+ [public_key, deploy_key.merge("id" => "2", "url" => "https://api.github.com/repos/octocat/Hello-World/keys/2")] \
+} %>
+
+{% if page.version != 'dotcom' and page.version >= 2.4 %}
+
+## Delete a user
+
+{{#warning}}
+
+Deleting a user will delete all their repositories, gists, applications, and personal settings. [Suspending a user](/v3/users/administration/#suspend-a-user) is often a better option.
+
+{{/warning}}
+
+ DELETE /admin/users/:username
+
+You can delete any user account except your own.
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
+
+## Delete a public key
+
+ DELETE /admin/keys/1
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
diff --git a/content/v3/users/emails.md b/content/v3/users/emails.md
index 284cc9cec0..0de8cb90b6 100644
--- a/content/v3/users/emails.md
+++ b/content/v3/users/emails.md
@@ -1,10 +1,9 @@
---
-title: User Emails | GitHub API
+title: User Emails
---
# Emails
-* TOC
{:toc}
Management of email addresses via the API requires that you are
@@ -18,34 +17,20 @@ This endpoint is accessible with the user:email scope.
### Response
-
-
- Deprecated: This response format is deprecated.
- The API will remove support for this response format in the future.
-
-
- We recommend that you start requesting the new response format as described
- in the Future Response section below.
-
-
-
-<%= headers 200 %>
-<%= json ["octocat@github.com", "support@github.com"] %>
-
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:user_email) {|e| [e]} %>
+
+## Add email address(es)
-#### Future Response
+{% if page.version != 'dotcom' && page.version >= 2.1 %}
-In the final version of the API, this method will return an array of hashes
-with extended information for each email address indicating if the address has
-been verified and if it's the user's primary email address for GitHub.
+{{#warning}}
-Until API v3 is finalized, use the `application/vnd.github.v3`
-[media type][media-types] to get this response format.
+If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/admin/guides/user-management/using-ldap) and the option to synchronize emails enabled, this API is disabled and will return a `403` response. Users managed in LDAP won't be able to add an email address via the API with these options enabled.
-<%= headers 200 %>
-<%= json(:user_email) {|e| [e]} %>
+{{/warning}}
-## Add email address(es)
+{% endif %}
POST /user/emails
@@ -58,10 +43,31 @@ You can post a single email address or an array of addresses:
### Response
<%= headers 201 %>
-<%= json ["octocat@github.com", "support@github.com"] %>
+<%= json [
+ {
+ "email" => "octocat@github.com",
+ "primary" => false,
+ "verified" => false
+ },
+ {
+ "email" => "support@github.com",
+ "primary" => false,
+ "verified" => false
+ },
+] %>
## Delete email address(es)
+{% if page.version != 'dotcom' && page.version >= 2.1 %}
+
+{{#warning}}
+
+If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/admin/guides/user-management/using-ldap) and the option to synchronize emails enabled, this API is disabled and will return a `403` response. Users managed in LDAP won't be able to remove an email address via the API with these options enabled.
+
+{{/warning}}
+
+{% endif %}
+
DELETE /user/emails
### Input
diff --git a/content/v3/users/followers.md b/content/v3/users/followers.md
index b449aee004..258d8d5e31 100644
--- a/content/v3/users/followers.md
+++ b/content/v3/users/followers.md
@@ -1,17 +1,16 @@
---
-title: User Followers | GitHub API
+title: User Followers
---
# Followers
-* TOC
{:toc}
## List followers of a user
List a user's followers:
- GET /users/:user/followers
+ GET /users/:username/followers
List the authenticated user's followers:
@@ -26,7 +25,7 @@ List the authenticated user's followers:
List who a user is following:
- GET /users/:user/following
+ GET /users/:username/following
List who the authenticated user is following:
@@ -39,7 +38,7 @@ List who the authenticated user is following:
## Check if you are following a user
- GET /user/following/:user
+ GET /user/following/:username
### Response if you are following this user
@@ -51,7 +50,7 @@ List who the authenticated user is following:
## Check if one user follows another
- GET /users/:user/following/:target_user
+ GET /users/:username/following/:target_user
### Response if user follows target user
@@ -63,7 +62,9 @@ List who the authenticated user is following:
## Follow a user
- PUT /user/following/:user
+ PUT /user/following/:username
+
+<%= fetch_content(:put_content_length) %>
Following a user requires the user to be logged in and authenticated with basic
auth or OAuth with the `user:follow` scope.
@@ -74,7 +75,7 @@ auth or OAuth with the `user:follow` scope.
## Unfollow a user
- DELETE /user/following/:user
+ DELETE /user/following/:username
Unfollowing a user requires the user to be logged in and authenticated with basic
auth or OAuth with the `user:follow` scope.
diff --git a/content/v3/users/gpg_keys.md b/content/v3/users/gpg_keys.md
new file mode 100644
index 0000000000..448737dc56
--- /dev/null
+++ b/content/v3/users/gpg_keys.md
@@ -0,0 +1,78 @@
+---
+title: User GPG Keys
+---
+
+{% if page.version == 'dotcom' %}
+
+# GPG Keys
+
+{{#tip}}
+
+
+
+ APIs for managing user GPG keys are currently available for developers to preview.
+ During the preview period, the APIs may change without advance notice.
+ Please see the [blog post](/changes/2016-04-04-git-signing-api-preview) for full details.
+
+ To access the API you must provide a custom [media type](/v3/media) in the `Accept` header:
+
+ application/vnd.github.cryptographer-preview
+
+{{/tip}}
+
+{:toc}
+
+## List your GPG keys
+
+ GET /user/gpg_keys
+
+Lists the current user's GPG keys. Requires that you are authenticated via
+Basic Auth or via OAuth with at least `read:gpg_key`
+[scope](/v3/oauth/#scopes).
+
+### Response
+
+<%= headers 200, :pagination => default_pagination_rels %>
+<%= json(:gpg_key) { |h| [h] } %>
+
+## Get a single GPG key
+
+View extended details for a single GPG key. Requires that you are
+authenticated via Basic Auth or via OAuth with at least `read:gpg_key`
+[scope](/v3/oauth/#scopes).
+
+ GET /user/gpg_keys/:id
+
+### Response
+
+<%= headers 200 %>
+<%= json :gpg_key %>
+
+## Create a GPG key
+
+Creates a GPG key. Requires that you are authenticated via Basic Auth,
+or OAuth with at least `write:gpg_key` [scope](/v3/oauth/#scopes).
+
+ POST /user/gpg_keys
+
+### Input
+
+<%= json :armored_public_key => "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----" %>
+
+### Response
+
+<%= headers 201, :Location => get_resource(:gpg_key)['url'] %>
+<%= json :gpg_key %>
+
+## Delete a GPG key
+
+Removes a GPG key. Requires that you are authenticated via Basic Auth
+or via OAuth with at least `admin:gpg_key` [scope](/v3/oauth/#scopes).
+
+ DELETE /user/gpg_keys/:id
+
+### Response
+
+<%= headers 204 %>
+
+{% endif %}
diff --git a/content/v3/users/keys.md b/content/v3/users/keys.md
index bc5152f1e8..25378d75f4 100644
--- a/content/v3/users/keys.md
+++ b/content/v3/users/keys.md
@@ -1,21 +1,20 @@
---
-title: User Public Keys | GitHub API
+title: User Public Keys
---
# Public Keys
-* TOC
{:toc}
## List public keys for a user
- GET /users/:user/keys
+ GET /users/:username/keys
Lists the _verified_ public keys for a user. This is accessible by anyone.
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:simple_public_key) { |h| [h] } %>
@@ -29,7 +28,7 @@ Basic Auth or via OAuth with at least `read:public_key`
### Response
-<%= headers 200 %>
+<%= headers 200, :pagination => default_pagination_rels %>
<%= json(:public_key) { |h| [h] } %>
## Get a single public key
@@ -50,6 +49,16 @@ authenticated via Basic Auth or via OAuth with at least `read:public_key`
Creates a public key. Requires that you are authenticated via Basic Auth,
or OAuth with at least `write:public_key` [scope](/v3/oauth/#scopes).
+{% if page.version != 'dotcom' && page.version >= 2.1 %}
+
+{{#warning}}
+
+If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/admin/guides/user-management/using-ldap) and the option to synchronize SSH keys enabled, this API is disabled and will return a `403` response. Users managed in LDAP won't be able to add an SSH key address via the API with these options enabled.
+
+{{/warning}}
+
+{% endif %}
+
POST /user/keys
### Input
@@ -58,7 +67,7 @@ or OAuth with at least `write:public_key` [scope](/v3/oauth/#scopes).
### Response
-<%= headers 201, :Location => "https://api.github.com/user/keys/1" %>
+<%= headers 201, :Location => get_resource(:public_key)['url'] %>
<%= json :public_key %>
## Update a public key
@@ -72,6 +81,16 @@ instead.
Removes a public key. Requires that you are authenticated via Basic Auth
or via OAuth with at least `admin:public_key` [scope](/v3/oauth/#scopes).
+{% if page.version != 'dotcom' && page.version >= 2.1 %}
+
+{{#warning}}
+
+If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/admin/guides/user-management/using-ldap) and the option to synchronize SSH keys enabled, this API is disabled and will return a `403` response. Users managed in LDAP won't be able to remove an SSH key address via the API with these options enabled.
+
+{{/warning}}
+
+{% endif %}
+
DELETE /user/keys/:id
### Response
diff --git a/content/v3/versions.md b/content/v3/versions.md
index 0cf73ad2f2..53c7cf6f33 100644
--- a/content/v3/versions.md
+++ b/content/v3/versions.md
@@ -1,15 +1,15 @@
---
-title: Versions | GitHub API
+title: Versions
---
# Versions
-There are two stable versions of the GitHub API: [beta](#beta) and [v3](#v3). There are just a few [differences between these two versions](#differences-from-beta-version).
+There are two stable versions of the GitHub API: the [v3](#v3) version and the deprecated [beta](#beta) version. There are just a few [differences between these two versions](#differences-from-beta-version).
-By default, all requests receive the beta version. Soon, v3 will become the default version. (Check out the [blog post](/changes/2014-01-07-upcoming-change-to-default-media-type/) for details.) We encourage you to [request a specific version via the `Accept` header](/v3/media/#beta-v3-and-the-future).
+By default, all requests receive the v3 version. We encourage you to [request a specific version via the `Accept` header](/v3/media/#request-specific-version).
# v3
-The [v3 API](/v3) is stable and unchangeable. Please [file a support issue][support] if you have problems.
+The [v3 API](/v3) is stable, and we strive to ensure that all [changes](/changes) are backwards compatible. Please [file a support issue][support] if you have problems.
Some v3 functionality is [deprecated](#v3-deprecations) and will be removed in the next major version of the API.
@@ -31,7 +31,7 @@ For [Repositories](/v3/repos/#get), the v3 media type omits the `master_branch`
### User Emails JSON
-For [User Emails](/v3/users/emails/#list-email-addresses-for-a-user), the v3 media type returns an array of hashes (instead of an array of strings).
+For [User Emails](/v3/users/emails/#list-email-addresses-for-a-user), the v3 media type returns an array of objects (instead of an array of strings).
## v3 deprecations
@@ -42,61 +42,129 @@ functionality _will be removed_ in the next major version of the API.
The recommendations below will help you prepare your application for the next major version of the API.
1. Method: /gists/:id/fork
-: Recommendation: Use **/gists/:id/forks** (plural) instead.
+
+ Recommendation: Use **/gists/:id/forks** (plural) instead.
1. Method: /legacy/issues/search/:owner/:repository/:state/:keyword
-: Recommendation: Use [v3 Issue Search API](/v3/search/#search-issues) instead.
+
+ Recommendation: Use [v3 Issue Search API](/v3/search/#search-issues) instead.
1. Method: /legacy/repos/search/:keyword
-: Recommendation: Use [v3 Repository Search API](/v3/search/#search-repositories) instead.
+
+ Recommendation: Use [v3 Repository Search API](/v3/search/#search-repositories) instead.
1. Method: /legacy/user/search/:keyword
-: Recommendation: Use [v3 User Search API](/v3/search/#search-users) instead.
+
+ Recommendation: Use [v3 User Search API](/v3/search/#search-users) instead.
1. Method: /legacy/user/email/:email
-: Recommendation: Use [v3 User Search API](/v3/search/#search-users) instead.
+
+ Recommendation: Use [v3 User Search API](/v3/search/#search-users) instead.
1. Method: /repos/:owner/:repo/hooks/:id/test
-: Recommendation: Use **/repos/:owner/:repo/hooks/:id/tests** (plural) instead.
+
+ Recommendation: Use **/repos/:owner/:repo/hooks/:id/tests** (plural) instead.
+
+1. Method: /teams/:id/members/:username
+
+ Recommendation: Use [Get Team Membership](/v3/orgs/teams/#get-team-membership), [Add Team Membership](/v3/orgs/teams/#add-team-membership), and [Remove Team Membership](/v3/orgs/teams/#remove-team-membership) instead.
1. Query parameters when POSTing to /repos/:owner/:repo/forks
-: Recommendation: Use JSON to POST to this method instead.
+
+ Recommendation: Use JSON to POST to this method instead.
1. Query parameter value: Passing "watchers" as the value for the "sort" parameter in a GET request to /repos/:owner/:repo/forks
-: Recommendation: Use **stargazers** as the value instead.
+
+ Recommendation: Use **stargazers** as the value instead.
1. Pull Request attribute: merge_commit_sha
-: Recommendation: [Do not use this attribute](/changes/2013-04-25-deprecating-merge-commit-sha/).
+
+ Recommendation: [Do not use this attribute](/changes/2013-04-25-deprecating-merge-commit-sha/).
1. Rate Limit attribute: rate
-: Recommendation: Use **resources["core"]** instead.
+
+ Recommendation: Use **resources["core"]** instead.
1. Repository attribute: forks
-: Recommendation: Use **fork_count** instead.
+
+ Recommendation: Use **forks_count** instead.
1. Repository attribute: master_branch
-: Recommendation: Use **default_branch** instead.
+
+ Recommendation: Use **default_branch** instead.
1. Repository attribute: open_issues
-: Recommendation: Use **open_issues_count** instead.
+
+ Recommendation: Use **open_issues_count** instead.
1. Repository attribute: public
-: Recommendation: When [creating a repository](/v3/repos/#create), use the
+
+ Recommendation: When [creating a repository](/v3/repos/#create), use the
**private** attribute to indicate whether the repository should be public or
private. Do not use the **public** attribute.
1. Repository attribute: watchers
-: Recommendation: Use **watchers_count** instead.
+
+ Recommendation: Use **watchers_count** instead.
1. User attribute: bio
-: Recommendation: Do not use this attribute. It is obsolete.
+ Recommendation: Do not use this attribute. It is obsolete.
+
+1. User attribute: plan["collaborators"]
+
+ Recommendation: Do not use this attribute. It is obsolete.
+
+1. User attribute: gravatar_id
+
+ Recommendation: Use **avatar_url** instead.
+
+1. Feed attribute: current_user_organization_url
+
+ Recommendation: Use **current_user_organization_urls** instead.
+
+1. Feed attribute: current_user_organization
+
+ Recommendation: Use **current_user_organizations** instead.
+
+1. Pagination parameters `top` and `sha` for method: /repos/:owner/:repo/commits
+
+ Recommendation: When fetching [the list of commits for a repository](/v3/repos/commits/#list-commits-on-a-repository)
+ use the [standard `per_page` and `page` parameters](/v3/#pagination) for pagination, instead of `per_page`,
+ `top`, and `sha`.
+
+1. Authorization attribute: token
+
+ Recommendation: This attribute will return an empty string in the majority of
+ the Authorizations API responses. Please see
+ [the deprecation blog post](/changes/2015-04-20-authorizations-api-response-changes-are-now-in-effect/)
+ and the [Authorizations API deprecation notice](/v3/oauth_authorizations/#deprecation-notice)
+ for full details.
+
+1. Team attribute: permission
+
+ Recommendation: This attribute no longer dictates the permission a team has on its repositories; it only dictates the default permission that the [Add or update team repository](/v3/orgs/teams/#add-or-update-team-repository) API will use for requests where no `permission` attribute is specified. To change the permission level for every repository on a team, use the [List team repositories](/v3/orgs/teams/#list-team-repos) API to list all of the team's repositories, and then use the [Add or update team repository](/v3/orgs/teams/#add-or-update-team-repository) with a `permission` attribute to update each repository's permission separately.
+
+1. Issue attribute: assignee
+
+ Recommendation: Use the [`assignees`](https://developer.github.com/v3/issues/#create-an-issue) key instead, since issues can have more than one assignee. Alternatively, you can use the
+ [assignees](https://developer.github.com/v3/issues/assignees/) endpoints.
+
+
+
+# beta (Deprecated)
+
+The [beta API](/v3) is deprecated. Its current functionality is stable, and we strive to ensure that any [changes](/changes) are backwards compatible. Please [file a support issue][support] if you have problems.
+
+{{#tip}}
+
+Note: We recommend using the v3 API instead of the deprecated beta version of the API.
-# beta
+The beta media type differs from the v3 media type in just a few places. In most cases, migrating an application from the beta media type to the v3 media type is smooth and painless.
-The [beta API](/v3) is now stable and unchangeable. Please [file a support issue][support] if you have problems.
+We will eventually retire the beta version, but we have no official retirement date to announce at the moment. When the time comes, rest assured that we'll announce the retirement with plenty of notice.
-Starting April 15, 2014, the [beta version will no longer be the _default_ version](/changes/2014-01-07-upcoming-change-to-default-media-type/). However, we expect to continue supporting the beta version for a while. We will eventually retire the beta version, but we have no official retirement date to annouce at the moment. When the time comes, rest assured that we'll announce the retirement with plenty of notice.
+{{/tip}}
## Breaking beta changes
@@ -106,7 +174,7 @@ Starting April 15, 2014, the [beta version will no longer be the _default_ versi
responses that include users or orgs. A default size is no longer
included in the URL.
* Creating new gists (both anonymously and with an authenticated user)
- should use `POST /gists` from now on. `POST /users/:user/gists` is no
+ should use `POST /gists` from now on. `POST /users/:username/gists` is no
longer supported.
### June 1st, 2011:
diff --git a/content/webhooks/configuring/index.md b/content/webhooks/configuring.md
similarity index 74%
rename from content/webhooks/configuring/index.md
rename to content/webhooks/configuring.md
index bcf05488b0..c48be12ffb 100644
--- a/content/webhooks/configuring/index.md
+++ b/content/webhooks/configuring.md
@@ -1,11 +1,10 @@
---
-title: Configuring Your Server | GitHub API
+title: Configuring your server
layout: webhooks
---
# Configuring Your Server
-* TOC
{:toc}
Now that our webhook is ready to deliver messages, we'll set up a basic Sinatra server
@@ -25,14 +24,15 @@ First, we'll install a program to expose our local host to the Internet. We'll u
ngrok to do this. [ngrok is a free download](https://ngrok.com/download) available
for all major operating systems.
-When you're done with that, you can expose your localhost by running `./ngrok 4567`
+When you're done with that, you can expose your localhost by running `./ngrok http 4567`
on the command line. You should see a line that looks something like this:
- #!bash
- Forwarding http://7e9ea9dc.ngrok.com -> 127.0.0.1:4567
+``` command-line
+$ Forwarding http://7e9ea9dc.ngrok.io -> 127.0.0.1:4567
+```
-Copy that funky `*.ngrok.com` URL! We're now going to go *back* to the Payload
-URL and pasting this server into that field. It should look something like `http://7e9ea9dc.ngrok.com/payload`.
+Copy that funky `*.ngrok.io` URL! We're now going to go *back* to the Payload
+URL and pasting this server into that field. It should look something like `http://7e9ea9dc.ngrok.io/payload`.
By doing this, we've set ourselves up to expose our localhost at path `/payload`
to the Internet.
@@ -47,14 +47,15 @@ can happily test out our code locally.
Let's set up a little Sinatra app to do something with the information. Our initial
setup might look something like this:
- #!ruby
- require 'sinatra'
- require 'json'
+``` ruby
+require 'sinatra'
+require 'json'
- post '/payload' do
- push = JSON.parse(params[:payload])
- puts "I got some JSON: #{push.inspect}"
- end
+post '/payload' do
+ push = JSON.parse(request.body.read)
+ puts "I got some JSON: #{push.inspect}"
+end
+```
(If you're unfamiliar with how Sinatra works, we recommend [reading the Sinatra guide][Sinatra].)
@@ -64,13 +65,14 @@ Since we set up our webhook to listen to events dealing with `Issues`, go ahead
and create a new Issue on the repository you're testing with. Once you create
it, switch back to your terminal. You should see something like this in your output:
- #!bash
- ~/Developer/platform-samples/hooks/ruby/configuring-your-server $ ruby server.rb
- == Sinatra/1.4.4 has taken the stage on 4567 for development with backup from Thin
- >> Thin web server (v1.5.1 codename Straight Razor)
- >> Maximum connections set to 1024
- >> Listening on localhost:4567, CTRL+C to stop
- I got some JSON: {"action"=>"opened", "issue"=>{"url"=>"...
+``` command-line
+$ ~/Developer/platform-samples/hooks/ruby/configuring-your-server $ ruby server.rb
+> == Sinatra/1.4.4 has taken the stage on 4567 for development with backup from Thin
+> >> Thin web server (v1.5.1 codename Straight Razor)
+> >> Maximum connections set to 1024
+> >> Listening on localhost:4567, CTRL+C to stop
+> I got some JSON: {"action"=>"opened", "issue"=>{"url"=>"...
+```
Success! You've successfully configured your server to listen to webhooks. Your
server can now process this information any way you see fit. For example, if you
diff --git a/content/webhooks/creating/index.md b/content/webhooks/creating.md
similarity index 55%
rename from content/webhooks/creating/index.md
rename to content/webhooks/creating.md
index 70d65ab3d6..06170155d1 100644
--- a/content/webhooks/creating/index.md
+++ b/content/webhooks/creating.md
@@ -1,33 +1,31 @@
---
-title: Creating Webhooks | GitHub API
+title: Creating webhooks
layout: webhooks
---
# Creating Webhooks
-* TOC
{:toc}
-At their core, webhooks are events generated by GitHub that deliver a payload of
-information about activity in a repository. Webhooks can trigger across several
-different actions. For example, you can fire a payload of information any time
-a commit is made, a repository is forked, or an issue is created.
-
-In this tutorial, our webhook will be responsible for listing out how popular our
-repository is, based on the number of Issues it receives per day.
+Now that we understand [the basics of webhooks][webhooks-overview], let's go
+through the process of building out our own webhook powered integration. In
+this tutorial, we'll create a repository webhook that will be responsible for
+listing out how popular our repository is, based on the number of Issues it
+receives per day.
Creating a webhook is a two-step process. You'll first need to set up how you want
-your webhook to behave through GitHub--what events should it listen to. After that,
+your webhook to behave through {{ site.data.variables.product.product_name }}--what events should it listen to. After that,
you'll set up your server to receive and manage the payload.
## Setting up a Webhook
-To set up a webhook on GitHub, head over to the **Settings** page of your repository,
-and click on **Webhooks & services**. After that, click on **Add webhook**.
+To set up a repository webhook on {{ site.data.variables.product.product_name }}, head over to the **Settings** page of
+your repository, and click on **Webhooks & services**. After that, click on
+**Add webhook**.
Alternatively, you can choose to build and manage a webhook [through the Webhooks API][webhook-api].
-Webhooks require a few configuration options before you can use of them.
+Webhooks require a few configuration options before you can make use of them.
We'll go through each of these settings below.
## Payload URL
@@ -37,10 +35,16 @@ This is the server endpoint that will receive the webhook payload.
Since we're developing locally for our tutorial, let's set it to `http://localhost:4567/payload`.
We'll explain why in the [Configuring Your Server](/webhooks/configuring/) docs.
-## Payload version
+## Content Type
+
+Webhooks can be delivered using different content types:
-Webhooks can deliver various [media types](/v3/media/) as defined by the GitHub API.
-Choose the one that best fits your needs. For this tutorial, the default format is fine.
+- The `application/json` content type will deliver the JSON payload directly as the body of the POST.
+- The `application/x-www-form-urlencoded` content type will send the JSON payload as a form parameter
+ called "payload".
+
+Choose the one that best fits your needs. For this tutorial, the default content type of
+`application/json` is fine.
## Events
@@ -56,6 +60,6 @@ When you're finished, click on **Add webhook**. Phew! Now that the webhook is cr
it's time to set up our local server to test the webhook. Head on over to
[Configuring Your Server](/webhooks/configuring/) to learn how to do that.
+[webhooks-overview]: /webhooks/
[webhook-api]: /v3/repos/hooks/
[hooks-api]: /webhooks/#events
-
diff --git a/content/webhooks/index.md b/content/webhooks/index.md
index 94b3a0930a..03fc42d1ca 100644
--- a/content/webhooks/index.md
+++ b/content/webhooks/index.md
@@ -1,105 +1,150 @@
---
-title: Webhooks | GitHub API
+title: Webhooks
layout: webhooks
---
# Webhooks
-* TOC
{:toc}
-Every GitHub repository has the option to communicate with a web server whenever
-the repository is pushed to. These "webhooks" can be used to update an external
-issue tracker, trigger CI builds, update a backup mirror, or even deploy to your
-production server.
-Each hook can be configured for a specific [service](#services) and one or
-more [events](#events), regardless of the API used to do so. Repository admins
-can configure hooks programmatically [via the API](/v3/repos/hooks/).
+Webhooks allow you to build or set up integrations which subscribe to certain
+events on GitHub.com. When one of those events is triggered, we'll send a HTTP
+POST payload to the webhook's configured URL. Webhooks can be used to update
+an external issue tracker, trigger CI builds, update a backup mirror, or even
+deploy to your production server. You're only limited by your imagination.
-## Services
-
-A service is basically the name used to refer to a hook that has configuration
-settings, a list of available events, and default events.
-
-> For instance, the
-[email](https://github.com/github/github-services/blob/master/lib/services/email.rb)
-service is a built-in GitHub service that will send event [payloads](#payloads)
-to, at most, two email addresses. It will trigger for the `push`
-event by default and supports the `public` event type as well.
-
-A number of services have been integrated through the open source
-[github-services](https://github.com/github/github-services) project. When
-[creating a hook](/webhooks/creating/), the `:name` parameter must refer to one of
-these services. A generic
-[Web](https://github.com/github/github-services/blob/master/lib/services/web.rb)
-service is available that can configured to trigger for any of the available
-[events](#events).
-
-Documentation for all available service hooks can be found in the
-[docs directory](https://github.com/github/github-services/tree/master/docs)
-of the github-services repository. A JSON representation of their names,
-default events, supported events, and configuration options can be seen
-at [api.github.com/hooks](https://api.github.com/hooks).
+Each webhook can be installed [on an organization][org-hooks] or [a specific
+repository][repo-hooks]. Once installed, they will be triggered each time one
+or more subscribed events occurs on that organization or repository.
+You can create up to 20 webhooks for each event on each installation target
+(specific organization or specific repository).
## Events
-Active hooks can be configured to trigger for one or more service supported
-events. In other words, the service must support listening for the event you
-want to trigger.
+When configuring a webhook, you can choose which events you would like to
+receive payloads for. You can [even opt-in to all current and future
+events][wildcard-section]. Only subscribing to the specific events you plan on
+handling is useful for limiting the number of HTTP requests to your server. You
+can change the list of subscribed events through the API or UI anytime. By
+default, webhooks are only subscribed to the `push` event.
+
+Each event corresponds to a certain set of actions that can happen to your
+organization and/or repository. For example, if you subscribe to the `issues`
+event you'll receive [detailed payloads][payloads-section] every time an issue
+is opened, closed, labeled, etc.
-For example, the
-[Web](https://github.com/github/github-services/blob/master/lib/services/web.rb)
-service listens for all events, while the
-[IRC](https://github.com/github/github-services/blob/master/lib/services/irc.rb)
-service can only listen for `push`, `issues`, and `pull_request` events.
The available events are:
Name | Description
-----|-----------|
-`*` | Any time any event is triggered ([Wildcard Event](#wildcard-event)).
-`commit_comment` | Any time a Commit is commented on.
-`create` | Any time a Repository, Branch, or Tag is created.
-`delete` | Any time a Branch or Tag is deleted.
-`deployment_status` | Any time a deployment for the Repository has a status update from the API.
-`deployment` | Any time a Repository has a new deployment created from the API.
-`fork` | Any time a Repository is forked.
-`gollum` | Any time a Wiki page is updated.
-`issue_comment` | Any time an Issue is commented on.
-`issues` | Any time an Issue is opened or closed.
-`member` | Any time a User is added as a collaborator to a non-Organization Repository.
-`page_build` | Any time a Pages site is built or results in a failed build.
-`public` | Any time a Repository changes from private to public.
-`pull_request_review_comment` | Any time a Commit is commented on while inside a Pull Request review (the Files Changed tab).
-`pull_request` | Any time a Pull Request is opened, closed, or synchronized (updated due to a new push in the branch that the pull request is tracking).
-`push` | Any git push to a Repository. **This is the default event.**
-`release` | Any time a Release is published in the Repository.
-`status` | Any time a Repository has a status update from the API
-`team_add` | Any time a team is added or modified on a Repository.
-`watch` | Any time a User watches the Repository.
-
-### Payloads
-
-The payloads for all hooks mirror [the payloads for the Event
-types](/v3/activity/events/types/), with the exception of [the original `push`
-event](http://help.github.com/post-receive-hooks/),
-which has a more detailed payload.
-
-## Wildcard Event
+`*` | Any time any event is triggered ([Wildcard Event][wildcard-section]).
+[`commit_comment`][event-types-commit_comment] | Any time a Commit is commented on.
+[`create`][event-types-create] | Any time a Branch or Tag is created.
+[`delete`][event-types-delete] | Any time a Branch or Tag is deleted.
+[`deployment`][event-types-deployment] | Any time a Repository has a new deployment created from the API.
+[`deployment_status`][event-types-deployment_status] | Any time a deployment for a Repository has a status update from the API.
+[`fork`][event-types-fork] | Any time a Repository is forked.
+[`gollum`][event-types-gollum] | Any time a Wiki page is updated.
+[`issue_comment`][event-types-issue_comment] | {% if page.version == 'dotcom' or page.version > 2.6 %}Any time a [comment on an issue](/v3/issues/comments/) is created, edited, or deleted.{% else %}Any time an [issue is commented on](/v3/issues/comments).{% endif %}
+[`issues`][event-types-issues] | Any time an Issue is assigned, unassigned, labeled, unlabeled, opened, {% if page.version == 'dotcom' or page.version > 2.6 %}edited, {% endif %}closed, or reopened.
+[`member`][event-types-member] | Any time a User is added as a collaborator to a Repository.
+[`membership`][event-types-membership] | Any time a User is added or removed from a team. **Organization hooks only**.
+[`page_build`][event-types-page_build] | Any time a Pages site is built or results in a failed build.
+[`public`][event-types-public] | Any time a Repository changes from private to public.
+[`pull_request_review_comment`][event-types-pull_request_review_comment] | {% if page.version == 'dotcom' or page.version > 2.6 %}Any time a [comment on a Pull Request's unified diff](/v3/pulls/comments) is created, edited, or deleted{% else %}Any time a [Pull Request's unified diff is commented on](/v3/pulls/comments){% endif %} (in the Files Changed tab).
+[`pull_request`][event-types-pull_request] | Any time a Pull Request is assigned, unassigned, labeled, unlabeled, opened, {% if page.version == 'dotcom' or page.version > 2.6 %}edited, {% endif %}closed, reopened, or synchronized (updated due to a new push in the branch that the pull request is tracking).
+[`push`][event-types-push] | Any Git push to a Repository, including editing tags or branches. Commits via API actions that update references are also counted. **This is the default event.**
+[`repository`][event-types-repository] | Any time a Repository is created{% if page.version == 'dotcom' or page.version > 2.6 %}, deleted, made public, or made private{% else %}. **Organization hooks only**{% endif %}.
+[`release`][event-types-release] | Any time a Release is published in a Repository.
+[`status`][event-types-status] | Any time a Repository has a status update from the API
+[`team_add`][event-types-team_add] | Any time a team is added or modified on a Repository.
+[`watch`][event-types-watch] | Any time a User stars a Repository.
+
+### Wildcard Event
We also support a wildcard (`*`) that will match all supported events. When you
-add the wildcard event, we'll replace any existing events you have configured with
-the wildcard event and send you payloads for all supported events. You'll also
-automatically get any new events we might add in the future.
+add the wildcard event, we'll replace any existing events you have configured
+with the wildcard event and send you payloads for all supported events. You'll
+also automatically get any new events we might add in the future.
+
+
+## Payloads
+
+Each event type has a specific payload format with the relevant event
+information. All event payloads mirror [the payloads for the Event
+types][event-types], with the exception of [the original `push`
+event][event-types-push], which has a more detailed webhook payload.
+
+In addition to the fields [documented for each event][event-types], webhook
+payloads include the user who performed the event (`sender`) as well as the
+organization (`organization`) and/or repository (`repository`) which the event
+occurred on.
+
+{{#tip}}
+
+**Note:** Payloads are capped at 5 MB. If your event generates a larger payload, a webhook will not be fired. This may happen, for example, on a `create` event if many branches or tags are pushed at once. We suggest monitoring your payload size to ensure delivery.
+
+{{/tip}}
+
+### Delivery headers
+
+HTTP requests made to your webhook's configured URL endpoint will contain
+several special headers:
+
+Header | Description
+-------|-------------|
+`X-GitHub-Event`| Name of the [event][events-section] that triggered this delivery.
+`X-Hub-Signature`| HMAC hex digest of the payload, using [the hook's `secret`][repo-hooks-create] as the key (if configured).
+`X-GitHub-Delivery`| Unique ID for this delivery.
+
+Also, the `User-Agent` for the requests will have the prefix `GitHub-Hookshot/`.
+
+### Example delivery
+
+``` command-line
+> POST /payload HTTP/1.1
+
+> Host: localhost:4567
+> X-Github-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
+> User-Agent: GitHub-Hookshot/044aadd
+> Content-Type: application/json
+> Content-Length: 6615
+> X-GitHub-Event: issues
+
+> {
+> "action": "opened",
+> "issue": {
+> "url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
+> "number": 1347,
+> ...
+> },
+> "repository" : {
+> "id": 1296269,
+> "full_name": "octocat/Hello-World",
+> "owner": {
+> "login": "octocat",
+> "id": 1,
+> ...
+> },
+> ...
+> },
+> "sender": {
+> "login": "octocat",
+> "id": 1,
+> ...
+> }
+> }
+```
## Ping Event
When you create a new webhook, we'll send you a simple `ping` event to let you
know you've set up the webhook correctly. This event isn't stored so it isn't
-retrievable via the [Events API](/v3/activity/events/). You can trigger a `ping`
-again by calling the [ping endpoint](/v3/repos/hooks/#ping-a-hook).
+retrievable via the [Events API][events-api]. You can trigger a `ping` again by
+calling the [ping endpoint][repo-hooks-ping].
### Ping Event Payload
@@ -107,3 +152,37 @@ Key | Value |
----| ----- |
zen | Random string of GitHub zen |
hook_id | The ID of the webhook that triggered the ping |
+hook | The [webhook configuration][repo-hooks-show] |
+
+[service-hooks-section]: #service-hooks
+[events-section]: #events
+[wildcard-section]: #wildcard-event
+[payloads-section]: #payloads
+[org-hooks]: /v3/orgs/hooks/
+[repo-hooks]: /v3/repos/hooks/
+[repo-hooks-show]: /v3/repos/hooks/#get-single-hook
+[repo-hooks-create]: /v3/repos/hooks/#create-a-hook
+[repo-hooks-ping]: /v3/repos/hooks/#ping-a-hook
+[events-api]: /v3/activity/events/
+[event-types]: /v3/activity/events/types/
+[event-types-commit_comment]: /v3/activity/events/types/#commitcommentevent
+[event-types-create]: /v3/activity/events/types/#createevent
+[event-types-delete]: /v3/activity/events/types/#deleteevent
+[event-types-deployment]: /v3/activity/events/types/#deploymentevent
+[event-types-deployment_status]: /v3/activity/events/types/#deploymentstatusevent
+[event-types-fork]: /v3/activity/events/types/#forkevent
+[event-types-gollum]: /v3/activity/events/types/#gollumevent
+[event-types-issue_comment]: /v3/activity/events/types/#issuecommentevent
+[event-types-issues]: /v3/activity/events/types/#issuesevent
+[event-types-member]: /v3/activity/events/types/#memberevent
+[event-types-membership]: /v3/activity/events/types/#membershipevent
+[event-types-page_build]: /v3/activity/events/types/#pagebuildevent
+[event-types-public]: /v3/activity/events/types/#publicevent
+[event-types-pull_request]: /v3/activity/events/types/#pullrequestevent
+[event-types-pull_request_review_comment]: /v3/activity/events/types/#pullrequestreviewcommentevent
+[event-types-push]: /v3/activity/events/types/#pushevent
+[event-types-release]: /v3/activity/events/types/#releaseevent
+[event-types-repository]: /v3/activity/events/types/#repositoryevent
+[event-types-status]: /v3/activity/events/types/#statusevent
+[event-types-team_add]: /v3/activity/events/types/#teamaddevent
+[event-types-watch]: /v3/activity/events/types/#watchevent
diff --git a/content/webhooks/securing.md b/content/webhooks/securing.md
new file mode 100644
index 0000000000..407ea1f26b
--- /dev/null
+++ b/content/webhooks/securing.md
@@ -0,0 +1,71 @@
+---
+title: Securing your webhooks
+layout: webhooks
+---
+
+# Securing your webhooks
+
+{:toc}
+
+Once your server is configured to receive payloads, it'll listen for any payload sent to the endpoint you configured. For security reasons, you probably want to limit requests to those coming from GitHub. There are a few ways to go about this--for example, you could opt to whitelist requests from GitHub's IP address--but a far easier method is to set up a secret token and validate the information.
+
+
+## Setting your secret token
+
+You'll need to set up your secret token in two places: GitHub and your server.
+
+To set your token on GitHub:
+
+1. Navigate to the repository where you're setting up your webhook.
+2. Fill out the Secret textbox. Use a random string with high entropy (e.g., by taking the output of `ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'` at the terminal).
+
+3. Click **Update Webhook**.
+
+Next, set up an environment variable on your server that stores this token. Typically, this is as simple as running:
+
+``` command-line
+$ export SECRET_TOKEN=your_token
+```
+
+**Never** hardcode the token into your app!
+
+## Validating payloads from GitHub
+
+When your secret token is set, GitHub uses it to create a hash signature with each payload.
+
+This hash signature is passed along with each request in the headers as `X-Hub-Signature`. Suppose you have a basic server listening to webhooks that looks like this:
+
+``` ruby
+require 'sinatra'
+require 'json'
+
+post '/payload' do
+ push = JSON.parse(params[:payload])
+ puts "I got some JSON: #{push.inspect}"
+end
+```
+
+The goal is to compute a hash using your `SECRET_TOKEN`, and ensure that the hash from GitHub matches. GitHub uses an HMAC hexdigest to compute the hash, so you could change your server to look a little like this:
+
+``` ruby
+post '/payload' do
+ request.body.rewind
+ payload_body = request.body.read
+ verify_signature(payload_body)
+ push = JSON.parse(params[:payload])
+ puts "I got some JSON: #{push.inspect}"
+end
+
+def verify_signature(payload_body)
+ signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ENV['SECRET_TOKEN'], payload_body)
+ return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
+end
+```
+
+Obviously, your language and server implementations may differ than this code. There's a couple of very important thing to point out, however:
+
+* No matter which implementation you use, the hash signature starts with `sha1=`, using the key of your secret token and your payload body.
+
+* Using a plain `==` operator is **not advised**. A method like [`secure_compare`][secure_compare] performs a "constant time" string comparison, which renders it safe from certain timing attacks against regular equality operators.
+
+[secure_compare]: http://rubydoc.info/github/rack/rack/master/Rack/Utils.secure_compare
diff --git a/content/webhooks/testing/index.md b/content/webhooks/testing.md
similarity index 76%
rename from content/webhooks/testing/index.md
rename to content/webhooks/testing.md
index 0b8278270b..c57a2ba788 100644
--- a/content/webhooks/testing/index.md
+++ b/content/webhooks/testing.md
@@ -1,11 +1,10 @@
---
-title: Testing Webhooks | GitHub API
+title: Testing webhooks
layout: webhooks
---
# Testing Webhooks
-* TOC
{:toc}
Now that you've [configured your local server](/webhooks/configuring/), you might
@@ -16,9 +15,9 @@ view provides some tooling for testing your deployed payloads.
## Listing recent deliveries
Every webhook has its own "Recent Deliveries" section, which lists, at a glance
-whether a deployment was successful (green dot) or failed (red dot).
+whether a deployment was successful (green check) or failed (red x).
-
+
You can also identify when each delivery was attempted.
@@ -33,8 +32,12 @@ both the HTTP Request and Response.
The webhook delivery view provides information on which Headers were sent by GitHub.
It also includes details about the JSON payload.
+
+
### Response
The response tab lists how your server replied once it received the payload from
GitHub. This includes the status code, the headers, and any additional data
within the response body.
+
+
diff --git a/css/960.css b/css/960.css
deleted file mode 100644
index 5e00e1847b..0000000000
--- a/css/960.css
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- 960 Grid System ~ Core CSS.
- Learn more ~ http://960.gs/
-
- Licensed under GPL and MIT.
-*/
-
-/*
- Forces backgrounds to span full width,
- even if there is horizontal scrolling.
- Increase this if your layout is wider.
-
- Note: IE6 works fine without this fix.
-*/
-
-body {
- min-width: 960px;
-}
-
-/* `Containers
-----------------------------------------------------------------------------------------------------*/
-
-.container_12,
-.container_16 {
- margin-left: auto;
- margin-right: auto;
- width: 960px;
-}
-
-/* `Grid >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.grid_1,
-.grid_2,
-.grid_3,
-.grid_4,
-.grid_5,
-.grid_6,
-.grid_7,
-.grid_8,
-.grid_9,
-.grid_10,
-.grid_11,
-.grid_12,
-.grid_13,
-.grid_14,
-.grid_15,
-.grid_16 {
- display: inline;
- float: left;
- margin-left: 10px;
- margin-right: 10px;
-}
-
-.push_1, .pull_1,
-.push_2, .pull_2,
-.push_3, .pull_3,
-.push_4, .pull_4,
-.push_5, .pull_5,
-.push_6, .pull_6,
-.push_7, .pull_7,
-.push_8, .pull_8,
-.push_9, .pull_9,
-.push_10, .pull_10,
-.push_11, .pull_11,
-.push_12, .pull_12,
-.push_13, .pull_13,
-.push_14, .pull_14,
-.push_15, .pull_15 {
- position: relative;
-}
-
-.container_12 .grid_3,
-.container_16 .grid_4 {
- width: 220px;
-}
-
-.container_12 .grid_6,
-.container_16 .grid_8 {
- width: 460px;
-}
-
-.container_12 .grid_9,
-.container_16 .grid_12 {
- width: 700px;
-}
-
-.container_12 .grid_12,
-.container_16 .grid_16 {
- width: 940px;
-}
-
-/* `Grid >> Children (Alpha ~ First, Omega ~ Last)
-----------------------------------------------------------------------------------------------------*/
-
-.alpha {
- margin-left: 0;
-}
-
-.omega {
- margin-right: 0;
-}
-
-/* `Grid >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .grid_1 {
- width: 60px;
-}
-
-.container_12 .grid_2 {
- width: 140px;
-}
-
-.container_12 .grid_4 {
- width: 300px;
-}
-
-.container_12 .grid_5 {
- width: 380px;
-}
-
-.container_12 .grid_7 {
- width: 540px;
-}
-
-.container_12 .grid_8 {
- width: 620px;
-}
-
-.container_12 .grid_10 {
- width: 780px;
-}
-
-.container_12 .grid_11 {
- width: 860px;
-}
-
-/* `Grid >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .grid_1 {
- width: 40px;
-}
-
-.container_16 .grid_2 {
- width: 100px;
-}
-
-.container_16 .grid_3 {
- width: 160px;
-}
-
-.container_16 .grid_5 {
- width: 280px;
-}
-
-.container_16 .grid_6 {
- width: 340px;
-}
-
-.container_16 .grid_7 {
- width: 400px;
-}
-
-.container_16 .grid_9 {
- width: 520px;
-}
-
-.container_16 .grid_10 {
- width: 580px;
-}
-
-.container_16 .grid_11 {
- width: 640px;
-}
-
-.container_16 .grid_13 {
- width: 760px;
-}
-
-.container_16 .grid_14 {
- width: 820px;
-}
-
-.container_16 .grid_15 {
- width: 880px;
-}
-
-/* `Prefix Extra Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .prefix_3,
-.container_16 .prefix_4 {
- padding-left: 240px;
-}
-
-.container_12 .prefix_6,
-.container_16 .prefix_8 {
- padding-left: 480px;
-}
-
-.container_12 .prefix_9,
-.container_16 .prefix_12 {
- padding-left: 720px;
-}
-
-/* `Prefix Extra Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .prefix_1 {
- padding-left: 80px;
-}
-
-.container_12 .prefix_2 {
- padding-left: 160px;
-}
-
-.container_12 .prefix_4 {
- padding-left: 320px;
-}
-
-.container_12 .prefix_5 {
- padding-left: 400px;
-}
-
-.container_12 .prefix_7 {
- padding-left: 560px;
-}
-
-.container_12 .prefix_8 {
- padding-left: 640px;
-}
-
-.container_12 .prefix_10 {
- padding-left: 800px;
-}
-
-.container_12 .prefix_11 {
- padding-left: 880px;
-}
-
-/* `Prefix Extra Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .prefix_1 {
- padding-left: 60px;
-}
-
-.container_16 .prefix_2 {
- padding-left: 120px;
-}
-
-.container_16 .prefix_3 {
- padding-left: 180px;
-}
-
-.container_16 .prefix_5 {
- padding-left: 300px;
-}
-
-.container_16 .prefix_6 {
- padding-left: 360px;
-}
-
-.container_16 .prefix_7 {
- padding-left: 420px;
-}
-
-.container_16 .prefix_9 {
- padding-left: 540px;
-}
-
-.container_16 .prefix_10 {
- padding-left: 600px;
-}
-
-.container_16 .prefix_11 {
- padding-left: 660px;
-}
-
-.container_16 .prefix_13 {
- padding-left: 780px;
-}
-
-.container_16 .prefix_14 {
- padding-left: 840px;
-}
-
-.container_16 .prefix_15 {
- padding-left: 900px;
-}
-
-/* `Suffix Extra Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .suffix_3,
-.container_16 .suffix_4 {
- padding-right: 240px;
-}
-
-.container_12 .suffix_6,
-.container_16 .suffix_8 {
- padding-right: 480px;
-}
-
-.container_12 .suffix_9,
-.container_16 .suffix_12 {
- padding-right: 720px;
-}
-
-/* `Suffix Extra Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .suffix_1 {
- padding-right: 80px;
-}
-
-.container_12 .suffix_2 {
- padding-right: 160px;
-}
-
-.container_12 .suffix_4 {
- padding-right: 320px;
-}
-
-.container_12 .suffix_5 {
- padding-right: 400px;
-}
-
-.container_12 .suffix_7 {
- padding-right: 560px;
-}
-
-.container_12 .suffix_8 {
- padding-right: 640px;
-}
-
-.container_12 .suffix_10 {
- padding-right: 800px;
-}
-
-.container_12 .suffix_11 {
- padding-right: 880px;
-}
-
-/* `Suffix Extra Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .suffix_1 {
- padding-right: 60px;
-}
-
-.container_16 .suffix_2 {
- padding-right: 120px;
-}
-
-.container_16 .suffix_3 {
- padding-right: 180px;
-}
-
-.container_16 .suffix_5 {
- padding-right: 300px;
-}
-
-.container_16 .suffix_6 {
- padding-right: 360px;
-}
-
-.container_16 .suffix_7 {
- padding-right: 420px;
-}
-
-.container_16 .suffix_9 {
- padding-right: 540px;
-}
-
-.container_16 .suffix_10 {
- padding-right: 600px;
-}
-
-.container_16 .suffix_11 {
- padding-right: 660px;
-}
-
-.container_16 .suffix_13 {
- padding-right: 780px;
-}
-
-.container_16 .suffix_14 {
- padding-right: 840px;
-}
-
-.container_16 .suffix_15 {
- padding-right: 900px;
-}
-
-/* `Push Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .push_3,
-.container_16 .push_4 {
- left: 240px;
-}
-
-.container_12 .push_6,
-.container_16 .push_8 {
- left: 480px;
-}
-
-.container_12 .push_9,
-.container_16 .push_12 {
- left: 720px;
-}
-
-/* `Push Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .push_1 {
- left: 80px;
-}
-
-.container_12 .push_2 {
- left: 160px;
-}
-
-.container_12 .push_4 {
- left: 320px;
-}
-
-.container_12 .push_5 {
- left: 400px;
-}
-
-.container_12 .push_7 {
- left: 560px;
-}
-
-.container_12 .push_8 {
- left: 640px;
-}
-
-.container_12 .push_10 {
- left: 800px;
-}
-
-.container_12 .push_11 {
- left: 880px;
-}
-
-/* `Push Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .push_1 {
- left: 60px;
-}
-
-.container_16 .push_2 {
- left: 120px;
-}
-
-.container_16 .push_3 {
- left: 180px;
-}
-
-.container_16 .push_5 {
- left: 300px;
-}
-
-.container_16 .push_6 {
- left: 360px;
-}
-
-.container_16 .push_7 {
- left: 420px;
-}
-
-.container_16 .push_9 {
- left: 540px;
-}
-
-.container_16 .push_10 {
- left: 600px;
-}
-
-.container_16 .push_11 {
- left: 660px;
-}
-
-.container_16 .push_13 {
- left: 780px;
-}
-
-.container_16 .push_14 {
- left: 840px;
-}
-
-.container_16 .push_15 {
- left: 900px;
-}
-
-/* `Pull Space >> Global
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .pull_3,
-.container_16 .pull_4 {
- left: -240px;
-}
-
-.container_12 .pull_6,
-.container_16 .pull_8 {
- left: -480px;
-}
-
-.container_12 .pull_9,
-.container_16 .pull_12 {
- left: -720px;
-}
-
-/* `Pull Space >> 12 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_12 .pull_1 {
- left: -80px;
-}
-
-.container_12 .pull_2 {
- left: -160px;
-}
-
-.container_12 .pull_4 {
- left: -320px;
-}
-
-.container_12 .pull_5 {
- left: -400px;
-}
-
-.container_12 .pull_7 {
- left: -560px;
-}
-
-.container_12 .pull_8 {
- left: -640px;
-}
-
-.container_12 .pull_10 {
- left: -800px;
-}
-
-.container_12 .pull_11 {
- left: -880px;
-}
-
-/* `Pull Space >> 16 Columns
-----------------------------------------------------------------------------------------------------*/
-
-.container_16 .pull_1 {
- left: -60px;
-}
-
-.container_16 .pull_2 {
- left: -120px;
-}
-
-.container_16 .pull_3 {
- left: -180px;
-}
-
-.container_16 .pull_5 {
- left: -300px;
-}
-
-.container_16 .pull_6 {
- left: -360px;
-}
-
-.container_16 .pull_7 {
- left: -420px;
-}
-
-.container_16 .pull_9 {
- left: -540px;
-}
-
-.container_16 .pull_10 {
- left: -600px;
-}
-
-.container_16 .pull_11 {
- left: -660px;
-}
-
-.container_16 .pull_13 {
- left: -780px;
-}
-
-.container_16 .pull_14 {
- left: -840px;
-}
-
-.container_16 .pull_15 {
- left: -900px;
-}
-
-/* `Clear Floated Elements
-----------------------------------------------------------------------------------------------------*/
-
-/* http://sonspring.com/journal/clearing-floats */
-
-.clear {
- clear: both;
- display: block;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0;
-}
-
-/* http://www.yuiblog.com/blog/2010/09/27/clearfix-reloaded-overflowhidden-demystified */
-
-.clearfix:before,
-.clearfix:after {
- content: '\0020';
- display: block;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0;
-}
-
-.clearfix:after {
- clear: both;
-}
-
-/*
- The following zoom:1 rule is specifically for IE6 + IE7.
- Move to separate stylesheet if invalid CSS is a problem.
-*/
-
-.clearfix {
- zoom: 1;
-}
\ No newline at end of file
diff --git a/css/uv_active4d.css b/css/uv_active4d.css
deleted file mode 100644
index 60e909b3ad..0000000000
--- a/css/uv_active4d.css
+++ /dev/null
@@ -1,115 +0,0 @@
-pre.active4d code {
- background:none;
- color:#000;
- font-size:1.1em
-}
-
-pre.active4d .DiffHeader {
- background-color: #656565;
- color: #FFFFFF;
-}
-pre.active4d .Operator {
-}
-pre.active4d .InheritedClass {
-}
-pre.active4d .TypeName {
- color: #21439C;
-}
-pre.active4d .Number {
- color: #A8017E;
-}
-pre.active4d .EmbeddedSource {
- background-color: #ECF1FF;
-}
-pre.active4d {
- background-color: #FFFFFF;
- color: #000000;
-}
-pre.active4d .DiffInsertedLine {
- background-color: #98FF9A;
- color: #000000;
-}
-pre.active4d .LibraryVariable {
- color: #A535AE;
-}
-pre.active4d .Storage {
- color: #FF5600;
-}
-pre.active4d .InterpolatedEntity {
- color: #66CCFF;
-}
-pre.active4d .line-numbers {
- background-color: #BAD6FD;
- color: #000000;
-}
-pre.active4d .LocalVariable {
- color: #6392FF;
-}
-pre.active4d .DiffLineRange {
- background-color: #1B63FF;
- color: #FFFFFF;
-}
-pre.active4d .BlockComment {
- color: #D33435;
-}
-pre.active4d .TagName {
- color: #016CFF;
-}
-pre.active4d .FunctionArgument {
-}
-pre.active4d .BuiltInConstant {
- color: #A535AE;
-}
-pre.active4d .LineComment {
- color: #D33535;
-}
-pre.active4d .DiffDeletedLine {
- background-color: #FF7880;
- color: #000000;
-}
-pre.active4d .NamedConstant {
- color: #B7734C;
-}
-pre.active4d .CommandMethod {
- color: #45AE34;
-}
-pre.active4d .TableField {
- color: #0BB600;
-}
-pre.active4d .PlainXmlText {
- color: #000000;
-}
-pre.active4d .Invalid {
- background-color: #990000;
- color: #FFFFFF;
-}
-pre.active4d .LibraryClassType {
- color: #A535AE;
-}
-pre.active4d .TagAttribute {
- color: #963DFF;
-}
-pre.active4d .Keyword {
- color: #006699;
-}
-pre.active4d .UserDefinedConstant {
-}
-pre.active4d .String {
- color: #666666;
-}
-pre.active4d .DiffUnchangedLine {
- color: #5E5E5E;
-}
-pre.active4d .TagContainer {
- color: #7A7A7A;
-}
-pre.active4d .FunctionName {
- color: #21439C;
-}
-pre.active4d .Variable {
- color: #0053FF;
-}
-pre.active4d .DateTimeLiteral {
- font-weight: bold;
- color: #66CCFF;
-}
\ No newline at end of file
diff --git a/data/variables/contact.yml b/data/variables/contact.yml
new file mode 100644
index 0000000000..6728eb4501
--- /dev/null
+++ b/data/variables/contact.yml
@@ -0,0 +1,6 @@
+contact_support:
+ {% if page.version == 'dotcom' %}
+ '[GitHub support](https://github.com/contact)'
+ {% else %}
+ 'your GitHub Enterprise site administrator'
+ {% endif %}
diff --git a/data/variables/product.yml b/data/variables/product.yml
new file mode 100644
index 0000000000..221100b3ca
--- /dev/null
+++ b/data/variables/product.yml
@@ -0,0 +1,20 @@
+api_url_pre:
+ {% if page.version == 'dotcom' %}
+ 'https://api.github.com'
+ {% else %}
+ 'http(s)://[hostname]/api/v3'
+ {% endif %}
+
+api_url_code:
+ {% if page.version == 'dotcom' %}
+ 'https://api.github.com'
+ {% else %}
+ 'http(s)://[hostname]/api/v3'
+ {% endif %}
+
+product_name:
+ {% if page.version == 'dotcom' %}
+ 'GitHub'
+ {% else %}
+ 'GitHub Enterprise'
+ {% endif %}
diff --git a/guides/basics-of-authentication/index.html b/guides/basics-of-authentication/index.html
deleted file mode 100644
index eae0bf9493..0000000000
--- a/guides/basics-of-authentication/index.html
+++ /dev/null
@@ -1,458 +0,0 @@
-
-
-
-
-
-
-
- Basics of Authentication | GitHub API
-
-
-
-
-
-
-
-
-
-
-
-
In this section, we’re going to focus on the basics of authentication. Specifically,
-we’re going to create a Ruby server (using Sinatra) that implements
-the web flow of an application in several different ways.
First, you’ll need to register your application. Every
-registered OAuth application is assigned a unique Client ID and Client Secret.
-The Client Secret should not be shared! That includes checking the string
-into your repository.
-
-
You can fill out every piece of information however you like, except the
-Authorization callback URL. This is easily the most important piece to setting
-up your application. It’s the callback URL that GitHub returns the user to after
-successful authentication.
-
-
Since we’re running a regular Sinatra server, the location of the local instance
-is set to http://localhost:4567. Let’s fill in the callback URL as http://localhost:4567/callback.
-
-
Accepting user authorization
-
-
Now, let’s start filling out our simple server. Create a file called server.rb and paste this into it:
Your client ID and client secret keys come from your application’s configuration
-page. You should never, ever store these values in
-GitHub–or any other public place, for that matter. We recommend storing them as
-environment variables–which is exactly what we’ve done here.
-
-
Next, in views/index.erb, paste this content:
-
-
<html>
- <head>
- </head>
- <body>
- <p>
- Well, hello there!
- </p>
- <p>
- We're going to now talk to the GitHub API. Ready?
- <ahref="https://github.com/login/oauth/authorize?scope=user:email&client_id=<%=client_id%>">Click here</a> to begin!</a>
- </p>
- <p>
- If that link doesn't work, remember to provide your own <ahref="/v3/oauth/#web-application-flow">Client ID</a>!
- </p>
- </body>
-</html>
Also, notice that the URL uses the scope query parameter to define the
-scopes requested by the application. For our application, we’re
-requesting user:email scope for reading private email addresses.
-
-
Navigate your browser to http://localhost:4567. After clicking on the link, you
-should be taken to GitHub, and presented with a dialog that looks something like this:
-
-
-
If you trust yourself, click Authorize App. Wuh-oh! Sinatra spits out a
-404 error. What gives?!
-
-
Well, remember when we specified a Callback URL to be callback? We didn’t provide
-a route for it, so GitHub doesn’t know where to drop the user after they authorize
-the app. Let’s fix that now!
-
-
Providing a callback
-
-
In server.rb, add a route to specify what the callback should do:
-
-
get'/callback'do
- # get temporary GitHub code...
- session_code=request.env['rack.request.query_hash']['code']
-
- # ... and POST it back to GitHub
- result=RestClient.post('https://github.com/login/oauth/access_token',
- {:client_id=>CLIENT_ID,
- :client_secret=>CLIENT_SECRET,
- :code=>session_code},
- :accept=>:json)
-
- # extract the token and granted scopes
- access_token=JSON.parse(result)['access_token']
-end
-
-
After a successful app authentication, GitHub provides a temporary code value.
-You’ll need to POST this code back to GitHub in exchange for an access_token.
-To simplify our GET and POST HTTP requests, we’re using the rest-client.
-Note that you’ll probably never access the API through REST. For a more serious
-application, you should probably use a library written in the language of your choice.
-
-
Checking granted scopes
-
-
In the future, users will be able to edit the scopes you requested,
-and your application might be granted less access than you originally asked for.
-So, before making any requests with the token, you should check the scopes that
-were granted for the token by the user.
-
-
The scopes that were granted are returned as a part of the response from
-exchanging a token.
-
-
# check if we were granted user:email scope
-scopes=JSON.parse(result)['scope'].split(',')
-has_user_email_scope=scopes.include?'user:email'
-
-
In our application, we’re using scopes.include? to check if we were granted
-the user:email scope needed for fetching the authenticated user’s private
-email addresses. Had the application asked for other scopes, we would have
-checked for those as well.
-
-
Also, since there’s a hierarchical relationship between scopes, you should
-check that you were granted the lowest level of required scopes. For example,
-if the application had asked for user scope, it might have been granted only
-user:email scope. In that case, the application wouldn’t have been granted
-what it asked for, but the granted scopes would have still been sufficient.
-
-
Checking for scopes only before making requests is not enough since it’s posible
-that users will change the scopes in between your check and the actual request.
-In case that happens, API calls you expected to succeed might fail with a 404
-or 401 status, or return a different subset of information.
-
-
To help you gracefully handle these situations, all API responses for requests
-made with valid tokens also contain an X-OAuth-Scopes header.
-This header contains the list of scopes of the token that was used to make the
-request. In addition to that, the Authorization API provides an endpoint to
-check a token for validity.
-Use this information to detect changes in token scopes, and inform your users of
-changes in available application functionality.
-
-
Making authenticated requests
-
-
At last, with this access token, you’ll be able to make authenticated requests as
-the logged in user:
-
-
# fetch user information
-auth_result=JSON.parse(RestClient.get('https://api.github.com/user',
- {:params=>{:access_token=>access_token}}))
-
-# if the user authorized it, fetch private emails
-ifhas_user_email_scope
- auth_result['private_emails']=
- JSON.parse(RestClient.get('https://api.github.com/user/emails',
- {:params=>{:access_token=>access_token}}))
-
-erb:basic,:locals=>auth_result
-
-
We can do whatever we want with our results. In this case, we’ll just dump them straight into basic.erb:
-
-
<p>Hello, <%=login%>!</p>
-<p>
- <%if!email.empty?%> It looks like your public email address is <%=email%>.
- <%else%> It looks like you don't have a public email. That's cool.
- <%end%>
-</p>
-<p>
- <%ifdefined?private_emails%>
- With your permission, we were also able to dig up your private email addresses:
- <%=private_emails.join(', ')%>
- <%else%>
- Also, you're a bit secretive about your private email addresses.
- <%end%>
-</p>
-
-
Implementing “persistent” authentication
-
-
It’d be a pretty bad model if we required users to log into the app every single
-time they needed to access the web page. For example, try navigating directly to
-http://localhost:4567/basic. You’ll get an error.
-
-
What if we could circumvent the entire
-“click here” process, and just remember that, as long as the user’s logged into
-GitHub, they should be able to access this application? Hold on to your hat,
-because that’s exactly what we’re going to do.
-
-
Our little server above is rather simple. In order to wedge in some intelligent
-authentication, we’re going to switch over to using sessions for storing tokens.
-This will make authentication transparent to the user.
-
-
Also, since we’re persisting scopes within the session, we’ll need to
-handle cases when the user updates the scopes after we checked them, or revokes
-the token. To do that, we’ll use a rescue block and check that the first API
-call succeeded, which verifies that the token is still valid. After that, we’ll
-check the X-OAuth-Scopes response header to verify that the user hasn’t revoked
-the user:email scope.
-
-
Create a file called advanced_server.rb, and paste these lines into it:
-
-
require'sinatra'
-require'rest_client'
-require'json'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-# if ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
-# CLIENT_ID = ENV['GITHUB_CLIENT_ID']
-# CLIENT_SECRET = ENV['GITHUB_CLIENT_SECRET']
-# end
-
-CLIENT_ID=ENV['GH_BASIC_CLIENT_ID']
-CLIENT_SECRET=ENV['GH_BASIC_SECRET_ID']
-
-useRack::Session::Cookie,:secret=>rand.to_s()
-
-defauthenticated?
- session[:access_token]
-end
-
-defauthenticate!
- erb:index,:locals=>{:client_id=>CLIENT_ID}
-end
-
-get'/'do
- if!authenticated?
- authenticate!
- else
- access_token=session[:access_token]
- scopes=[]
-
- begin
- auth_result=RestClient.get('https://api.github.com/user',
- {:params=>{:access_token=>access_token},
- :accept=>:json})
- rescue=>e
- # request didn't succeed because the token was revoked so we
- # invalidate the token stored in the session and render the
- # index page so that the user can start the OAuth flow again
-
- session[:access_token]=nil
- returnauthenticate!
- end
-
- # the request succeeded, so we check the list of current scopes
- ifauth_result.headers.include?:x_oauth_scopes
- scopes=auth_result.headers[:x_oauth_scopes].split(', ')
- end
-
- auth_result=JSON.parse(auth_result)
-
- ifscopes.include?'user:email'
- auth_result['private_emails']=
- JSON.parse(RestClient.get('https://api.github.com/user/emails',
- {:params=>{:access_token=>access_token},
- :accept=>:json}))
- end
-
- erb:advanced,:locals=>auth_result
- end
-end
-
-get'/callback'do
- session_code=request.env['rack.request.query_hash']['code']
-
- result=RestClient.post('https://github.com/login/oauth/access_token',
- {:client_id=>CLIENT_ID,
- :client_secret=>CLIENT_SECRET,
- :code=>session_code},
- :accept=>:json)
-
- session[:access_token]=JSON.parse(result)['access_token']
-
- redirect'/'
-end
-
-
Much of the code should look familiar. For example, we’re still using RestClient.get
-to call out to the GitHub API, and we’re still passing our results to be rendered
-in an ERB template (this time, it’s called advanced.erb).
-
-
Also, we now have the authenticated? method which checks if the user is already
-authenticated. If not, the authenticate! method is called, which performs the
-OAuth flow and updates the session with the granted token and scopes.
-
-
Next, create a file in views called advanced.erb, and paste this markup into it:
-
-
<html>
- <head>
- </head>
- <body>
- <p>Well, well, well, <%=login%>!</p>
- <p>
- <%if!email.empty?%> It looks like your public email address is <%=email%>.
- <%else%> It looks like you don't have a public email. That's cool.
- <%end%>
- </p>
- <p>
- <%ifdefined?private_emails%>
- With your permission, we were also able to dig up your private email addresses:
- <%=private_emails.join(', ')%>
- <%else%>
- Also, you're a bit secretive about your private email addresses.
- <%end%>
- </p>
- </body>
-</html>
-
-
From the command line, call ruby advanced_server.rb, which starts up your
-server on port 4567 – the same port we used when we had a simple Sinatra app.
-When you navigate to http://localhost:4567, the app calls authenticate!
-which redirects you to /callback. /callback then sends us back to /,
-and since we’ve been authenticated, renders advanced.erb.
-
-
We could completely simplify this roundtrip routing by simply changing our callback
-URL in GitHub to /. But, since both server.rb and advanced.rb are relying on
-the same callback URL, we’ve got to do a little bit of wonkiness to make it work.
-
-
Also, if we had never authorized this application to access our GitHub data,
-we would’ve seen the same confirmation dialog from earlier pop-up and warn us.
Let’s walk through core API concepts as we tackle some everyday use cases.
-
-
Overview
-
-
Most applications will use an existing wrapper library in the language
-of your choice, but it’s important to familiarize yourself with the underlying API
-HTTP methods first.
-
-
There’s no easier way to kick the tires than through cURL.
-
-
Hello World
-
-
Let’s start by testing our setup. Open up a command prompt and enter the
-following command (without the $):
-
-
-$ curl https://api.github.com/zen
-
-Keep it logically awesome.
-
-
-
The response will be a random selection from our design philosophies.
There are a few interesting bits in the response headers. As expected, the
-Content-Type is application/json.
-
-
Any headers beginning with X- are custom headers, and are not included in the
-HTTP spec. Let’s take a look at a few of them:
-
-
-
-X-GitHub-Media-Type has a value of github.beta. This lets us know the media type
-for the response. Media types have helped us version our output in API v3. We’ll
-talk more about that later.
-
Take note of the X-RateLimit-Limit and X-RateLimit-Remaining headers. This
-pair of headers indicate how many requests a client can make in
-a rolling time period (typically an hour) and how many of those requests the
-client has already spent.
-
-
-
Authentication
-
-
Unauthenticated clients can make 60 requests per hour. To get more, we’ll need to
-authenticate. In fact, doing anything interesting with the GitHub API requires
-authentication.
-
-
Basic
-
-
The easiest way to authenticate with the GitHub API is by simply using your GitHub
-username and password via Basic Authentication.
-
-
-$ curl -i -u <your_username> https://api.github.com/users/defunkt
-
-Enter host password for user '<your_username>':
-
-
-
The -u flag sets the username, and cURL will prompt you for the password. You
-can use -u "username:password" to avoid the prompt, but this leaves your
-password in shell history and isn’t recommended. When authenticating, you
-should see your rate limit bumped to 5,000 requests an hour, as indicated in the
-X-RateLimit-Limit header.
-
-
In addition to just getting more calls per hour, authentication is the key to
-reading and writing private information via the API.
-
-
Two-factor authentication
-
-
If you have two-factor authentication enabled, the API will return a
-401 Unauthorized error code for the above request (and every other API request):
The easiest way to get around that error is to create an OAuth token and use
-OAuth authentication instead of Basic Authentication. See the
-OAuth section below for more information.
-
-
Get your own user profile
-
-
When properly authenticated, you can take advantage of the permissions
-associated with your GitHub account. For example, try getting
-your own user profile:
This time, in addition to the same set of public information we
-retrieved for @defunkt earlier, you should also see the non-public
-information for your user profile. For example, you’ll see a plan object
-in the response which gives details about the GitHub plan for the account.
-
-
OAuth
-
-
While convenient, Basic Authentication isn’t ideal because you shouldn’t give your GitHub
-username and password to anyone. Applications that need to read or write
-private information using the API on behalf of another user should use OAuth.
-
-
Instead of usernames and passwords, OAuth uses tokens. Tokens provide two big
-features:
-
-
-
-Revokable access: users can revoke authorization to third party apps at any time
-
-Limited access: users can review the specific access that a token
-will provide before authorizing a third party app
-
-
-
Normally, tokens are created via a web flow. An application
-sends users to GitHub to log in. GitHub then presents a dialog
-indicating the name of the app, as well as the level of access the app
-has once it’s authorized by the user. After a user authorizes access, GitHub
-redirects the user back to the application:
There’s a lot going on in this one little call, so let’s break it down. First,
-the -d flag indicates we’re doing a POST, using the
-application/x-www-form-urlencoded content type (as opposed to GET). All POST
-requests to the GitHub API should be in JSON.
-
-
Next, let’s look at the scopes we’re sending over in this call. When creating
-a new token, we include an optional array of scopes, or access
-levels, that indicate what information this token can access. In this case,
-we’re setting up the token with repo access, which grants access to read and
-write to private repositories. See the scopes docs for a full list of
-scopes. You should only request scopes that your application actually needs,
-in order to not frighten users with potentially invasive actions. The 201
-status code tells us that the call was successful, and the JSON returned
-contains the details of our new OAuth token.
If you enabled 2FA with a mobile application, go ahead and get an OTP code from
-your one-time password application on your phone. If you enabled 2FA with text
-messages, you’ll receive an SMS with your OTP code after making a request to
-this endpoint.
-
-
Now, we can use the forty character token instead of a username and password
-in the rest of our examples. Let’s grab our own user info again, using OAuth this time:
Treat OAuth tokens like passwords! Don’t share them with other users or store
-them in insecure places. The tokens in these examples are fake and the names have
-been changed to protect the innocent.
-
-
Now that we’ve got the hang of making authenticated calls, let’s move along to
-the Repositories API.
-
-
Repositories
-
-
Almost any meaningful use of the GitHub API will involve some level of Repository
-information. We can GET repository details in the same way we fetched user
-details earlier:
The information returned from these calls will depend on how we authenticate:
-
-
-
Using Basic Authentication, the response includes all repositories the
-the user has access to see on github.com.
-
Using OAuth, private repositories are only returned if the OAuth token
-contains the reposcope.
-
-
-
As the docs indicate, these methods take a type parameter that
-can filter the repositories returned based on what type of access the user has
-for the repository. In this way, we can fetch only directly-owned repositories,
-organization repositories, or repositories the user collaborates on via a team.
In this example, we grab only those repositories that technoweenie owns, not the
-ones on which he collaborates. Note the quoted URL above. Depending on your
-shell setup, cURL sometimes requires a quoted URL or else it ignores the
-query string.
-
-
Create a repository
-
-
Fetching information for existing repositories is a common use case, but the
-GitHub API supports creating new repositories as well. To create a repository,
-we need to POST some JSON containing the details and configuration options.
In this minimal example, we create a new repository for our blog (to be served
-on GitHub Pages, perhaps). Though the blog will be public, we’ve made
-the repository private. In this single step, we’ll also initialize it with
-a README and a nanoc-flavored .gitignore template.
-
-
The resulting repository will be found at https://github.com/<your_username>/blog.
-To create a repository under an organization for which you’re
-an owner, just change the API method from /user/repos to /orgs/<org_name>/repos.
-
-
Next, let’s fetch our newly created repository:
-
-
-$ curl -i https://api.github.com/repos/pengwynn/blog
-
-HTTP/1.1 404 Not Found
-
-{
- "message": "Not Found"
-}
-
-
-
Oh noes! Where did it go? Since we created the repository as private, we need
-to authenticate in order to see it. If you’re a grizzled HTTP user, you might
-expect a 403 instead. Since we don’t want to leak information about private
-repositories, the GitHub API returns a 404 in this case, as if to say “we can
-neither confirm nor deny the existence of this repository.”
-
-
Issues
-
-
The UI for Issues on GitHub aims to provide ‘just enough’ workflow while
-staying out of your way. With the GitHub Issues API, you can pull
-data out or create issues from other tools to create a workflow that works for
-your team.
-
-
Just like github.com, the API provides a few methods to view issues for the
-authenticated user. To see all your issues, call GET /issues:
A project the size of Rails has thousands of issues. We’ll need to paginate,
-making multiple API calls to get the data. Let’s repeat that last call, this
-time taking note of the response headers:
The Link header provides a way for a response to link to
-external resources, in this case additional pages of data. Since our call found
-more than thirty issues (the default page size), the API tells us where we can
-find the next page and the last page of results.
-
-
Creating an issue
-
-
Now that we’ve seen how to paginate lists of issues, let’s create an issue from
-the API.
-
-
To create an issue, we need to be authenticated, so we’ll pass an
-OAuth token in the header. Also, we’ll pass the title, body, and labels in the JSON
-body to the /issues path underneath the repository in which we want to create
-the issue:
The response gives us a couple of pointers to the newly created issue, both in
-the Location response header and the url field of the JSON response.
-
-
Conditional requests
-
-
A big part of being a good API citizen is respecting rate limits by
-caching information that hasn’t changed. The API supports conditional
-requests and helps you do the right thing. Consider the
-first call we made to get defunkt’s profile:
In addition to the JSON body, take note of the HTTP status code of 200 and
-the ETag header.
-The ETag is a fingerprint of the response. If we pass that on subsequent calls,
-we can tell the API to give us the resource again, only if it has changed:
The 304 status indicates that the resource hasn’t changed since the last time
-we asked for it and the response will contain no body. As a bonus, 304
-responses don’t count against your rate limit.
This section of the documentation is intended to get you up-and-running with
-real-world GitHub API applications. We’ll cover everything you need to know, from
-authentication, to manipulating results, to combining results with other services.
-
-
Every tutorial here will have a project, and every project will be
-stored and documented in our public
-platform-samples repository.
-
-
Feel free to fork, clone, and improve these guides.
In this guide, we’re going to use the API to fetch information about repositories
-that we own, and the programming languages that make them up. Then, we’ll
-visualize that information in a couple of different ways using the D3.js library. To
-interact with the GitHub API, we’ll be using the excellent Ruby library, Octokit.
-
-
If you haven’t already, you should read the “Basics of Authentication”
-guide before starting this example. You can find the complete source code for this project in the platform-samples repository.
-
-
Let’s jump right in!
-
-
Setting up an OAuth application
-
-
First, register a new application on GitHub. Set the main and callback
-URLs to http://localhost:4567/. As before, we’re going to handle authentication for the API by
-implementing a Rack middleware using sinatra-auth-github:
-
-
require'sinatra/auth/github'
-
-moduleExample
- classMyGraphApp<Sinatra::Base
- # !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
- # Instead, set and test environment variables, like below
- # if ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
- # CLIENT_ID = ENV['GITHUB_CLIENT_ID']
- # CLIENT_SECRET = ENV['GITHUB_CLIENT_SECRET']
- # end
-
- CLIENT_ID=ENV['GH_GRAPH_CLIENT_ID']
- CLIENT_SECRET=ENV['GH_GRAPH_SECRET_ID']
-
- enable:sessions
-
- set:github_options,{
- :scopes=>"repo",
- :secret=>CLIENT_SECRET,
- :client_id=>CLIENT_ID,
- :callback_url=>"/"
- }
-
- registerSinatra::Auth::Github
-
- get'/'do
- if!authenticated?
- authenticate!
- else
- access_token=github_user["token"]
- end
- end
- end
-end
-
-
Set up a similar config.ru file as in the previous example:
This time, in order to talk to the GitHub API, we’re going to use the Octokit
-Ruby library. This is much easier than directly making a bunch of
-REST calls. Plus, Octokit was developed by a GitHubber, and is actively maintained,
-so you know it’ll work.
-
-
Authentication with the API via Octokit is easy. Just pass your login
-and token to the Octokit::Client constructor:
Let’s do something interesting with the data about our repositories. We’re going
-to see the different programming languages they use, and count which ones are used
-most often. To do that, we’ll first need a list of our repositories from the API.
-With Octokit, that looks like this:
-
-
repos=client.repositories
-
-
Next, we’ll iterate over each repository, and count the language that GitHub
-associates with it:
-
-
language_obj={}
-repos.eachdo|repo|
- # sometimes language can be nil
- ifrepo.language
- if!language_obj[repo.language]
- language_obj[repo.language]=1
- else
- language_obj[repo.language]+=1
- end
- end
-end
-
-languages.to_s
-
-
When you restart your server, your web page should display something
-that looks like this:
So far, so good, but not very human-friendly. A visualization
-would be great in helping us understand how these language counts are distributed. Let’s feed
-our counts into D3 to get a neat bar graph representing the popularity of the languages we use.
-
-
Visualizing language counts
-
-
D3.js, or just D3, is a comprehensive library for creating many kinds of charts, graphs, and interactive visualizations.
-Using D3 in detail is beyond the scope of this guide, but for a good introductory article,
-check out “D3 for Mortals”.
-
-
D3 is a JavaScript library, and likes working with data as arrays. So, let’s convert our Ruby hash into
-a JSON array for use by JavaScript in the browser.
We’re simply iterating over each key-value pair in our object and pushing them into
-a new array. The reason we didn’t do this earlier is because we didn’t want to iterate
-over our language_obj object while we were creating it.
-
-
Now, lang_freq.erb is going to need some JavaScript to support rendering a bar graph.
-For now, you can just use the code provided here, and refer to the resources linked above
-if you want to learn more about how D3 works:
Phew! Again, don’t worry about what most of this code is doing. The relevant part
-here is a line way at the top–var data = <%= languages %>;–which indicates
-that we’re passing our previously created languages array into ERB for manipulation.
-
-
As the “D3 for Mortals” guide suggests, this isn’t necessarily the best use of
-D3. But it does serve to illustrate how you can use the library, along with Octokit,
-to make some really amazing things.
-
-
Combining different API calls
-
-
Now it’s time for a confession: the language attribute within repositories
-only identifies the “primary” language defined. That means that if you have
-a repository that combines several languages, the one with the most bytes of code
-is considered to be the primary language.
-
-
Let’s combine a few API calls to get a true representation of which language
-has the greatest number of bytes written across all our code. A treemap
-should be a great way to visualize the sizes of our coding languages used, rather
-than simply the count. We’ll need to construct an array of objects that looks
-something like this:
Et voila! Beautiful rectangles containing your repo languages, with relative
-proportions that are easy to see at a glance. You might need to
-tweak the height and width of your treemap, passed as the first two
-arguments to drawTreemap above, to get all the information to show up properly.
The GitHub API provides a vast wealth of information for developers to consume.
-Most of the time, you might even find that you’re asking for too much information,
-and in order to keep our servers happy, the API will automatically paginate the requested items.
-
-
In this guide, we’ll make some calls to the GitHub Search API, and iterate over
-the results using pagination. You can find the complete source code for this project
-in the platform-samples repository.
-
-
Basics of Pagination
-
-
To start with, it’s important to know a few facts about receiving paginated items:
-
-
-
Different API calls respond with different defaults. For example, a call to
-list GitHub’s public repositories
-provides paginated items in sets of 30, whereas a call to the GitHub Search API
-provides items in sets of 100
-
You can specify how many items to receive (up to a maximum of 100); but,
-
For technical reasons, not every endpoint behaves the same. For example,
-events won’t let you set a maximum for items to receive.
-Be sure to read the documentation on how to handle paginated results for specific endpoints.
-
-
-
Information about pagination is provided in the Link header
-of an API call. For example, let’s make a curl request to the search API, to find
-out how many times Mozilla projects use the phrase addClass:
The -I parameter indicates that we only care about the headers, not the actual
-content. In examining the result, you’ll notice some information in the Link header
-that looks like this:
Let’s break that down. rel="next" says that the next page is page=2. This makes
-sense, since by default, all paginated queries start at page 1.rel="last"
-provides some more information, stating that the last page of results is on page 34.
-Thus, we have 33 more pages of information about addClass that we can consume.
-Nice!
-
-
Keep in mind that you should always rely on these link relations provided
-to you. Don’t try to guess or construct your own URL. Some API calls, like listing
-commits on a repository, use pagination results that are based
-on SHA values, not numbers.
-
-
Navigating through the pages
-
-
Now that you know how many pages there are to receive, you can start navigating
-through the pages to consume the results. You do this by passing in a page
-parameter. By default, page always starts at 1. Let’s jump ahead to page 14
-and see what happens:
As expected, rel="next" is at 15, and rel="last" is still 34. But now we’ve
-got some more information: rel="first" indicates the URL for the first page,
-and more importantly, rel="prev" lets you know the page number of the previous
-page. Using this information, you could construct some UI that lets users jump
-between the first, previous, next, or last list of results in an API call.
-
-
Changing the number of items received
-
-
By passing the per_page parameter, you can specify how many items you want
-each page to return, up to 100 items. Let’s try asking for 50 items about addClass:
As you might have guessed, the rel="last" information says that the last page
-is now 20. This is because we are asking for more information per page about
-our results.
-
-
Consuming the information
-
-
You don’t want to be making low-level curl calls just to be able to work with
-pagination, so let’s write a little Ruby script that does everything we’ve
-just described above.
require'octokit'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-client=Octokit::Client.new:access_token=>ENV['MY_PERSONAL_TOKEN']
-
-
Next, we’ll execute the search, using Octokit’s search_code method. Unlike
-using curl, we can also immediately retrieve the number of results, so let’s
-do that:
Now, let’s grab the number of the last page, similar to page=34>; rel="last"
-information in the link header. Octokit.rb support pagination information through
-an implementation called “Hypermedia link relations.”
-We won’t go into detail about what that is, but, suffice to say, each element
-in the results variable has a hash called rels, which can contain information
-about :next, :last, :first, and :prev, depending on which result you’re
-on. These relations also contain information about the resulting URL, by calling
-rels[:last].href.
-
-
Knowing this, let’s grab the page number of the last result, and present all
-this information to the user:
-
-
last_response=client.last_response
-number_of_pages=last_response.rels[:last].href.match(/page=(\d+)$/)[1]
-
-puts"There are #{total_count} results, on #{number_of_pages} pages!"
-
-
Finally, let’s iterate through the results. You could do this with a loop for i in 1..number_of_pages.to_i,
-but instead, let’s follow the rels[:next] headers to retrieve information from
-each page. For the sake of simplicity, let’s just grab the file path of the first
-result from each page. To do this, we’ll need a loop; and at the end of every loop,
-we’ll retrieve the data set for the next page by following the rels[:next] information.
-The loop will finish when there is no rels[:next] information to consume (in other
-words, we are at rels[:last]). It might look something like this:
-
-
loopdo
- putslast_response.data.items.first.path
- last_response=last_response.rels[:next].get
- sleep4# back off from the API rate limiting; don't do this in Real Life
- breakiflast_response.rels[:next].nil?
-end
-
-
Changing the number of items per page is extremely simple with Octokit.rb. Simply
-pass a per_page options hash to the initial client construction. After that,
-your code should remain intact:
-
-
require'octokit'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-client=Octokit::Client.new:access_token=>ENV['MY_PERSONAL_TOKEN']
-
-results=client.search_code('addClass user:mozilla',:per_page=>100)
-total_count=results.total_count
-
-last_response=client.last_response
-number_of_pages=last_response.rels[:last].href.match(/page=(\d+)$/)[1]
-
-putslast_response.rels[:last].href
-puts"There are #{total_count} results, on #{number_of_pages} pages!"
-
-puts"And here's the first path for every set"
-
-loopdo
- putslast_response.data.items.first.path
- last_response=last_response.rels[:next].get
- sleep4# back off from the API rate limiting; don't do this in Real Life
- breakiflast_response.rels[:next].nil?
-end
-
-
Constructing Pagination Links
-
-
Normally, with pagination, your goal isn’t to concatenate all of the possible
-results, but rather, to produce a set of navigation, like this:
-
-
-
-
Let’s sketch out a micro-version of what that might entail.
-
-
From the code above, we already know we can get the number_of_pages in the
-paginated results from the first call:
-
-
require'octokit'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-client=Octokit::Client.new:access_token=>ENV['MY_PERSONAL_TOKEN']
-
-results=client.search_code('addClass user:mozilla')
-total_count=results.total_count
-
-last_response=client.last_response
-number_of_pages=last_response.rels[:last].href.match(/page=(\d+)$/)[1]
-
-putslast_response.rels[:last].href
-puts"There are #{total_count} results, on #{number_of_pages} pages!"
-
-
From there, we can construct a beautiful ASCII representation of the number boxes:
If we wanted to get fancy, we could also grab the previous and next pages, in
-order to generate links for back (<<) and foward (>>) elements:
-
-
prev_page_href=client.last_response.rels[:prev]?client.last_response.rels[:prev].href:"(none)"
-next_page_href=client.last_response.rels[:next]?client.last_response.rels[:next].href:"(none)"
-
-puts"The prev page link is #{prev_page_href}"
-puts"The next page link is #{next_page_href}"
Each of these types of comments goes through a different portion of the GitHub API.
-In this guide, we’ll explore how you can access and manipulate each one. For every
-example, we’ll be using this sample Pull Request made on the “octocat”
-repository. As always, samples can be found in our platform-samples repository.
-
-
Pull Request Comments
-
-
To access comments on a Pull Request, you’ll go through the Issues API.
-This may seem counterintuitive at first. But once you understand that a Pull
-Request is just an Issue with code, it makes sense to use the Issues API to
-create comments on a Pull Request.
-
-
We’ll demonstrate fetching Pull Request comments by creating a Ruby script using
-Octokit.rb. You’ll also want to create a personal access token.
-
-
The following code should help you get started accessing comments from a Pull Request
-using Octokit.rb:
-
-
require'octokit'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-client=Octokit::Client.new:access_token=>ENV['MY_PERSONAL_TOKEN']
-
-client.issue_comments("octocat/Spoon-Knife",1176).eachdo|comment|
- username=comment[:user][:login]
- post_date=comment[:created_at]
- content=comment[:body]
-
- puts"#{username} made a comment on #{post_date}. It says:\n'#{content}'\n"
-end
-
-
Here, we’re specifically calling out to the Issues API to get the comments (issue_comments),
-providing both the repository’s name (octocat/Spoon-Knife), and the Pull Request ID
-we’re interested in (1176). After that, it’s simply a matter of iterating through
-the comments to fetch information about each one.
-
-
Pull Request Comments on a Line
-
-
Within the diff view, you can start a discussion on a particular aspect of a singular
-change made within the Pull Request. These comments occur on the individual lines
-within a changed file. The endpoint URL for this discussion comes from the Pull Request Review API.
-
-
The following code fetches all the Pull Request comments made on files, given a single Pull Request number:
-
-
require'octokit'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-client=Octokit::Client.new:access_token=>ENV['MY_PERSONAL_TOKEN']
-
-client.pull_request_comments("octocat/Spoon-Knife",1176).eachdo|comment|
- username=comment[:user][:login]
- post_date=comment[:created_at]
- content=comment[:body]
- path=comment[:path]
- position=comment[:position]
-
- puts"#{username} made a comment on #{post_date} for the file called #{path}, on line #{position}. It says:\n'#{content}'\n"
-end
-
-
You’ll notice that it’s incredibly similar to the example above. The difference
-between this view and the Pull Request comment is the focus of the conversation.
-A comment made on a Pull Request should be reserved for discussion or ideas on
-the overall direction of the code. A comment made as part of a Pull Request review should
-deal specifically with the way a particular change was implemented within a file.
-
-
Commit Comments
-
-
The last type of comments occur specifically on individual commits. For this reason,
-they make use of the commit comment API.
-
-
To retrieve the comments on a commit, you’ll want to use the SHA1 of the commit.
-In other words, you won’t use any identifier related to the Pull Request. Here’s an example:
-
-
require'octokit'
-
-# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
-# Instead, set and test environment variables, like below
-client=Octokit::Client.new:access_token=>ENV['MY_PERSONAL_TOKEN']
-
-client.commit_comments("octocat/Spoon-Knife","cbc28e7c8caee26febc8c013b0adfb97a4edd96e").eachdo|comment|
- username=comment[:user][:login]
- post_date=comment[:created_at]
- content=comment[:body]
-
- puts"#{username} made a comment on #{post_date}. It says:\n'#{content}'\n"
-end
-
-
Note that this API call will retrieve single line comments, as well as comments made
-on the entire commit.