-$ curl foobar -.... --``` - -This is not a `curl` tutorial though. Not every API call needs -to show how to access it with `curl`. - -[block boundaries]: http://kramdown.gettalong.org/syntax.html#block-boundaries - -## Development - -Nanoc compiles the site into static files living in `./output`. It's -smart enough not to try to compile unchanged files: - -```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 - -Site compiled in 5.81s. +``` sh +$ rake generate_json_from_responses ``` -You can set up whatever you want to view the files. If using the adsf -gem (as listed in the Gemfile), you can start Webrick: +The generated files will end up in *json-dump/*. -```sh -$ bundle exec nanoc view -$ open http://localhost:3000 -``` +### Terminal blocks -## Deploy +You can specify terminal blocks by using the `command-line` syntax highlighting. -```sh -$ bundle exec rake publish -``` + ``` command-line + $ curl foobar + ``` + +You can use certain characters, like `$` and `#`, to emphasize different parts +of commands. + + ``` command-line + # call foobar + $ curl foobar + .... + ``` + +For more information, see [the reference documentation](https://github.com/gjtorikian/extended-markdown-filter#command-line-highlighting). + +## Licenses + +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. + +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: + +> Content based on +> developer.github.com +> used under the +> CC-BY-4.0 +> license. + +This means you can use the code and content in this repository except for +GitHub trademarks in your own projects. + +When you contribute to this repository you are doing so under the above +licenses. diff --git a/Rakefile b/Rakefile index 4b3b54de35..066f1ab736 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,8 @@ require_relative 'lib/resources' require 'tmpdir' +Dir.glob('tasks/**/*.rake').each { |r| load r } + task :default => [:test] desc 'Builds the site' @@ -19,19 +21,33 @@ task :build do end desc "Test the output" -task :test => [:remove_tmp_dir, :remove_output_dir, :build, :run_proofer] +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}] - latest_ent_version = GitHub::Resources::Helpers::CONTENT['LATEST_ENTERPRISE_VERSION'] + require 'html-proofer' + ignored_links = [%r{www.w3.org}, /api\.github\.com/, /import\.github\.com/] # swap versionless Enterprise articles with versioned paths - href_swap = { - %r{help\.github\.com/enterprise/admin/} => "help.github.com/enterprise/#{latest_ent_version}/admin/", - %r{help\.github\.com/enterprise/user/} => "help.github.com/enterprise/#{latest_ent_version}/user/" + 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/" } - HTML::Proofer.new("./output", :href_ignore => ignored_links, :href_swap => href_swap).run + 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" @@ -57,6 +73,7 @@ def commit_message(no_commit_msg = false) end 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 @@ -81,3 +98,14 @@ task :publish, [:no_commit_msg] => [:remove_tmp_dir, :remove_output_dir, :build] 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 d3bc230fce..c04b63886d 100755 --- a/Rules +++ b/Rules @@ -5,89 +5,85 @@ # * The order of rules is important: for each item, only the first matching # rule is applied. -# 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]) -end - -compile '/static/**/*' do + @items.each do |item| + ConrefFS.apply_attributes(@config, item, :default) + end end passthrough '/CNAME' -compile '/feed.*' do +compile '/changes.atom' do filter :erb - filter :kramdown, :toc_levels => [2] end compile '/integrations-directory/*' do + filter :'conref-fs-filter' filter :erb - filter :kramdown, :toc_levels => [2] - filter :tip_filter - filter :colorize_syntax, - :colorizers => {:javascript => :rouge} + filter :html_pipeline, @config[:pipeline_config] layout item[:layout] || '/integrations-directory.*' end compile '/v3{.*,/**/*}' do - filter :search + filter :'conref-fs-filter' filter :erb - filter :kramdown, :toc_levels => [2] - filter :enterprise_only_filter - filter :not_enterprise_filter - filter :tip_filter - filter :colorize_syntax, - :colorizers => {:javascript => :rouge} + filter :html_pipeline, @config[:pipeline_config] layout(item[:layout] ? "/#{item[:layout]}.*" : '/api.*') end compile "/changes/20*" do + filter :'conref-fs-filter' filter :erb - filter :kramdown, :toc_levels => [2] - filter :colorize_syntax, - :colorizers => {:javascript => :rouge} + filter :html_pipeline, @config[:pipeline_config] layout '/changes.*' layout(item[:layout] ? "/#{item[:layout]}.*" : '/blog.*') end compile '/guides/**/*' do - filter :kramdown, :toc_levels => [2] - filter :tip_filter + filter :'conref-fs-filter' + filter :html_pipeline, @config[:pipeline_config] filter :erb - filter :colorize_syntax, :default_colorizer => :rouge layout(item[:layout] ? "/#{item[:layout]}.*" : '/guides.*') end compile '/webhooks/**/*' do - filter :kramdown, :toc_levels => [2] - filter :tip_filter + filter :'conref-fs-filter' filter :erb - filter :colorize_syntax, :default_colorizer => :rouge + filter :html_pipeline, @config[:pipeline_config] layout(item[:layout] ? "/#{item[:layout]}.*" : '/webhooks.*') end +compile '/search/search-index.json' do + filter :erb +end + compile '/**/*' do + filter :'conref-fs-filter' filter :erb - filter :kramdown, :toc_levels => [2] - filter :colorize_syntax, - :colorizers => {:javascript => :rouge} + filter :html_pipeline, @config[:pipeline_config] layout(item[:layout] ? "/#{item[:layout]}.*" : '/default.*') end -route '/static/**/*' do - item.identifier.to_s.sub(/\A\/static/, '') +route '/changes.atom' do + '/changes.atom' end -route '/feed.*' do - '/changes.atom' +route '/search/search-index.json' do + item.identifier.to_s end route '/**/index.*' do item.identifier.without_ext + '.html' end +route '/404.html' do + '/404.html' +end + route '/**/*' do item.identifier.without_ext + '/index.html' end diff --git a/assets/images/personal_token.png b/assets/images/personal_token.png index 4b9baa1dbd..188873d592 100644 Binary files a/assets/images/personal_token.png and b/assets/images/personal_token.png differ diff --git a/assets/javascripts/documentation.js b/assets/javascripts/documentation.js index 7980106193..d006cd551e 100644 --- a/assets/javascripts/documentation.js +++ b/assets/javascripts/documentation.js @@ -4,7 +4,7 @@ $(function() { helpList = $('#js-sidebar .js-topic'), firstOccurance = true, styleTOC = function() { - var pathRegEx = /\/\/[^\/]+(\/.+)/g, + var pathRegEx = /\/\/[^\/]+([A-Za-z0-9-_./]+)/g, docUrl = pathRegEx.exec(window.location.toString()) if (docUrl){ $('#js-sidebar .js-topic a').each(function(){ @@ -74,20 +74,6 @@ $(function() { return false }) - $('.help-search .search-box').focus(function(){ - $(this).css('background-position','0px -25px') - }) - - $('.help-search .search-box').focusout(function(){ - if($(this).val() == ''){ - $(this).css('background-position','0px 0px') - } - }) - - // Dynamic year for footer copyright - var currentYear = (new Date).getFullYear(); - $.each($(".js-year"), (function() { $(this).text( currentYear ) })); - // Grab API status $.getJSON('https://status.github.com/api/status.json?callback=?', function(data) { if(data) { @@ -100,189 +86,6 @@ $(function() { } }); - // Add link anchors for headers with IDs - $(".content h1, .content h2, .content h3, .content h4").each(function(e){ - var id = $(this).attr("id"); - if (!id) return; - - $(this).prepend(""); - }); - - // #### Search #### - var searchIndex, - searchHits; - - // Load the JSON containing all pages - // Has it been loaded before (and stored with localstorage)? - if (localStorage['searchIndex']) { - searchIndex = JSON.parse(localStorage['searchIndex']); - - if (localStorageHasExpired()) - loadSearchIndex(); - } else { - loadSearchIndex(); - } - - function loadSearchIndex() { - $.getJSON('/assets/search-index.json', function(data) { - searchIndex = data["pages"]; - localStorage['searchIndex'] = JSON.stringify(searchIndex); - localStorage['updated'] = new Date().getTime(); - }); - } - - function localStorageHasExpired() { - // Expires in one day (86400000 ms) - if (new Date().getTime() - parseInt(localStorage['updated'],10) > 86400000) { - return true; - } - - return false; - } - - // Expand and activate search if the page loaded with a value set for the search field - if ($("#searchfield").val().length > 0) { - $("#search-container").addClass("active"); - searchForString($("#searchfield").val()); - } - - // On input change, update the search results - $("#searchfield").on("input", function(e) { - $(this).val().length > 0 ? $("#search-container").addClass("active") : $("#search-container").removeClass("active"); - - searchForString($(this).val()); - }); - - // Global keyboard shortcuts - $("body").keyup(function(e) { - if (e.keyCode == 83) { - // S key - if ($("#searchfield").is(":focus")) - return; - - e.preventDefault(); - $("#searchfield").focus(); - } - }); - - // Keyboard support for the search field - $("#searchfield").keyup(function(e) { - if (e.keyCode == 27) { - // ESC - e.preventDefault(); - $("#searchfield").val().length > 0 ? cancelSearch() : $("#searchfield").blur(); - } else if (e.keyCode == 13) { - // Return/enter - e.preventDefault(); - goToSelectedSearchResult(); - } else if (e.keyCode == 8 || e.keyCode == 46) { - // Update search if backspace/delete was pressed - // IE9 doesn't trigger the input event on backspace/delete, - // but they do trigger keyUp - $(this).val().length > 0 ? $("#search-container").addClass("active") : $("#search-container").removeClass("active"); - - searchForString($(this).val()); - } - }).keydown(function(e) { - if (e.keyCode == 38) { - // Arrow up - e.preventDefault(); - moveSearchSelectionUp(); - } else if (e.keyCode == 40) { - // Arrow down - e.preventDefault(); - moveSearchSelectionDown(); - } else if (e.keyCode == 27) { - // Prevent default on ESC key - // IE inputs come with some native behaviors that will - // prevent the DOM from updating correctly unless prevented - e.preventDefault(); - } - }); - - // Make clicking the label focus the input label - // for browsers (IE) that doesn't support pointer-events: none - $("#search-container .search-placeholder").click(function(e) { - $("#searchfield").focus(); - }); - - $(".cancel-search").click(function(e) { - cancelSearch(); - }); - - function cancelSearch() { - $("#searchfield").val(""); - $("#search-container").removeClass("active"); - } - - function searchForString(searchString) { - searchHits = []; - searchString = searchString.toLowerCase(); - - // Search for string in all pages - for (var i = 0; i < searchIndex.length; i++) { - var page = searchIndex[i]; - - // Add the page to the array of hits if there's a match - if (page.title.toLowerCase().indexOf(searchString) !== -1) { - searchHits.push(page); - } - } - - renderResultsForSearch(searchString); - } - - // Update the UI representation of the search hits - function renderResultsForSearch(searchString){ - $("#search-results").empty(); - - // Check if there are any results. If not, show placeholder and exit - if (searchHits.length < 1) { - $('
+```
+--------------------+ +--------+ +-----------+
| GitHub Auto-Deploy | | GitHub | | Heroku |
| Service | +--------+ +-----------+
@@ -33,7 +32,7 @@ Here's a diagram demonstrating what the process might look like:
| | Deployment Status (success) |
| |<---------------------------------|
| | |
-
+```
{{#tip}}
diff --git a/content/guides/basics-of-authentication.md b/content/guides/basics-of-authentication.md
index 822c67f997..f67f9e8f0e 100644
--- a/content/guides/basics-of-authentication.md
+++ b/content/guides/basics-of-authentication.md
@@ -1,19 +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.
-You can download the complete source code for this project from the platform-samples repo.
-- 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].) @@ -78,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]. @@ -124,16 +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 - 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 +``` 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 @@ -146,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. @@ -164,37 +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}})) - end +# 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.map{ |private_email_address| private_email_address["email"] }.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 @@ -204,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 @@ -220,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::Pool, :cookie_only => false - - 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 @@ -308,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.map{ |private_email_address| private_email_address["email"] }.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. @@ -337,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] diff --git a/content/guides/best-practices-for-integrators.md b/content/guides/best-practices-for-integrators.md index b5e402a4b5..f0cd17c9b4 100644 --- a/content/guides/best-practices-for-integrators.md +++ b/content/guides/best-practices-for-integrators.md @@ -1,17 +1,16 @@ --- -title: Best practices for integrators | GitHub API +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 {:toc} ## Secure payloads delivered from GitHub -It's very important that you secure [the payloads sent from GitHub](/v3/activity/events/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. +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: @@ -55,6 +54,76 @@ For the stability of your app, you shouldn't try to parse this data or try to gu For example, when working with paginated results, it's often tempting to construct URLs that append `?page=-Tip: Our terms of service do mention that 'Accounts registered by "bots" or other automated methods are not permitted.' and that 'One person or legal entity may not maintain more than one free account.' But don't fear, we won't send rabid lawyers out to hunt you down if you create a single machine user for your organization's deploy scripts. Creating a single machine user for your project or organization is totally cool. -
-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 diff --git a/content/guides/traversing-with-pagination.md b/content/guides/traversing-with-pagination.md index 090922169d..ff4d11cf0b 100644 --- a/content/guides/traversing-with-pagination.md +++ b/content/guides/traversing-with-pagination.md @@ -1,17 +1,16 @@ --- -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 +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. @@ -32,8 +31,9 @@ Information about pagination is provided in [the Link header](http://tools.ietf. 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`: -{:.terminal} - 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 @@ -60,8 +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: -{:.terminal} - 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: @@ -81,8 +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`: -{:.terminal} - 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: @@ -102,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 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 @@ -129,11 +133,12 @@ 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 @@ -143,40 +148,42 @@ we'll retrieve the data set for the next page by following the `rels[:next]` inf 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 - 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 +``` 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" - 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 +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 @@ -190,56 +197,59 @@ 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: - #!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 foward (`>>`) elements: +order to generate links for back (`<<`) and forward (`>>`) 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 diff --git a/content/guides/using-ssh-agent-forwarding.md b/content/guides/using-ssh-agent-forwarding.md index 0dd11186bd..6a19d0c804 100644 --- a/content/guides/using-ssh-agent-forwarding.md +++ b/content/guides/using-ssh-agent-forwarding.md @@ -1,15 +1,14 @@ --- -title: Using SSH Agent Forwarding | GitHub API +title: Using SSH Agent Forwarding --- # Using SSH agent forwarding -* TOC {: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 GitHub, 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. +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. @@ -19,12 +18,12 @@ Ensure that your own SSH key is set up and working. You can use [our guide on ge 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. -+# 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. @@ -35,11 +34,11 @@ We're off to a great start. Let's set up SSH to allow agent forwarding to your s Host example.com ForwardAgent yes -
-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.
-
+``` command-line $ echo "$SSH_AUTH_SOCK" -# Print out the SSH_AUTH_SOCK variable -/tmp/ssh-4hNGMk8AZX/agent.79453 -+# 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] +# Print out the SSH_AUTH_SOCK variable +> [No output] $ ssh -T git@github.com -# Try to SSH to github -Permission denied (publickey). -+# Try to SSH to github +> Permission denied (publickey). +``` ## Troubleshooting SSH agent forwarding @@ -72,11 +71,11 @@ Here are some things to look out for when troubleshooting SSH agent forwarding. 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 @@ -86,27 +85,27 @@ Before you can make your keys work through agent forwarding, they must work loca 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 * +# 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 -+# 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 -+# 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. @@ -120,32 +119,33 @@ On most computers, the operating system automatically launches `ssh-agent` for y 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 -+# 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: -{:.terminal} - ssh-add -L +``` command-line +ssh-add -L +``` If the command says that no identity is available, you'll need to add your key: -
-ssh-add yourkey -+``` 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: -
-/usr/bin/ssh-add -K yourkey -+``` command-line +$ /usr/bin/ssh-add -K yourkey +``` {{/tip}} diff --git a/content/guides/working-with-comments.md b/content/guides/working-with-comments.md index 3a1f3850bf..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. diff --git a/content/index.md b/content/index.md index 1b41d3b5f2..1cf54f6892 100644 --- a/content/index.md +++ b/content/index.md @@ -1,6 +1,7 @@ --- title: GitHub Developer layout: overview +hide_from_search: true ---
+{{#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
@@ -161,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).
-Resources may also send custom validation errors (where `code` is `custom`). Custom errors will always have a `message` field describing the error, as well as a `documentation_url` field pointing to some content that might help you resolve the error.
+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
@@ -194,25 +204,28 @@ Verb | Description
## 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
-{:.terminal}
- $ 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)
-{:.terminal}
- $ curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com
+``` command-line
+$ curl -H "Authorization: token OAUTH-TOKEN" {{ site.data.variables.product.api_url_pre }}
+```
### OAuth2 Token (sent as a parameter)
-{:.terminal}
- $ curl https://api.github.com/?access_token=OAUTH-TOKEN
+``` 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
@@ -220,40 +233,46 @@ are not websites.
### OAuth2 Key/Secret
-{:.terminal}
- $ curl 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy'
+``` 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](#increasing-the-unauthenticated-rate-limit-for-oauth-applications).
+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`:
-{:.terminal}
- $ curl -i https://api.github.com -u foo:bar
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }} -u foo:bar
+> HTTP/1.1 401 Unauthorized
- HTTP/1.1 401 Unauthorized
-
- {
- "message": "Bad credentials",
- "documentation_url": "https://developer.github.com/v3"
- }
+> {
+> "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`:
-{:.terminal}
- $ curl -i https://api.github.com -u valid_username:valid_password
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }} -u valid_username:valid_password
+> HTTP/1.1 403 Forbidden
- HTTP/1.1 403 Forbidden
-
- {
- "message": "Maximum number of login attempts exceeded. Please try again later.",
- "documentation_url": "https://developer.github.com/v3"
- }
+> {
+> "message": "Maximum number of login attempts exceeded. Please try again later.",
+> "documentation_url": "https://developer.github.com/v3"
+> }
+```
## Hypermedia
@@ -287,8 +306,9 @@ resources, you can also set a custom page size up to 100 with the `?per_page` pa
Note that for technical reasons not all endpoints respect the `?per_page` parameter,
see [events](https://developer.github.com/v3/activity/events/) for example.
-{:.terminal}
- $ curl 'https://api.github.com/user/repos?page=2&per_page=100'
+``` 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.
@@ -320,6 +340,8 @@ Name | Description
`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
@@ -331,15 +353,15 @@ rules](/v3/search/#rate-limit).
You can check the returned HTTP headers of any API request to see your current
rate limit status:
-{:.terminal}
- $ curl -i https://api.github.com/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
+``` 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,24 +373,26 @@ 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.
- #!javascript
- new Date(1372700873 * 1000)
- // => Mon Jul 01 2013 13:47:53 GMT-0400 (EDT)
+``` javascript
+new Date(1372700873 * 1000)
+// => Mon Jul 01 2013 13:47:53 GMT-0400 (EDT)
+```
Once you go over the rate limit you will receive an error response:
-{:.terminal}
- HTTP/1.1 403 Forbidden
- Date: Tue, 20 Aug 2013 14:50:41 GMT
- Status: 403 Forbidden
- X-RateLimit-Limit: 60
- X-RateLimit-Remaining: 0
- X-RateLimit-Reset: 1377013266
-
- {
- "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"
- }
+``` command-line
+> HTTP/1.1 403 Forbidden
+> Date: Tue, 20 Aug 2013 14:50:41 GMT
+> Status: 403 Forbidden
+> X-RateLimit-Limit: 60
+> X-RateLimit-Remaining: 0
+> X-RateLimit-Reset: 1377013266
+
+> {
+> "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.
@@ -378,15 +402,15 @@ API hit.
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.
-{:.terminal}
- $ curl -i 'https://api.github.com/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
+``` 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.
@@ -406,7 +430,7 @@ higher rate limit for your OAuth application.
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. These rate limits do not apply to GitHub Enterprise installations.
+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
@@ -417,80 +441,102 @@ this rate limit. To ensure you're acting as a good API citizen, check out our
If your application triggers this rate limit, you'll receive an informative
response:
-{:.terminal}
- HTTP/1.1 403 Forbidden
- Content-Type: application/json; charset=utf-8
- Connection: close
+``` 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"
- }
+> {
+> "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:
-{:.terminal}
- User-Agent: Awesome-Octocat-App
+``` command-line
+User-Agent: Awesome-Octocat-App
+```
If you provide an invalid `User-Agent` header, you will receive a `403 Forbidden` response:
-{:.terminal}
- $ 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.
-
-{:.terminal}
- $ curl -i https://api.github.com/user
- HTTP/1.1 200 OK
- Cache-Control: private, max-age=60
- ETag: "644b5b0155e6404a9cc4bd9d8b1ae730"
- Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
- Status: 200 OK
- Vary: Accept, Authorization, Cookie
- X-RateLimit-Limit: 5000
- X-RateLimit-Remaining: 4996
- X-RateLimit-Reset: 1372700873
-
- $ curl -i https://api.github.com/user -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"'
- HTTP/1.1 304 Not Modified
- Cache-Control: private, max-age=60
- ETag: "644b5b0155e6404a9cc4bd9d8b1ae730"
- Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
- Status: 304 Not Modified
- Vary: Accept, Authorization, Cookie
- X-RateLimit-Limit: 5000
- X-RateLimit-Remaining: 4996
- X-RateLimit-Reset: 1372700873
-
- $ curl -i https://api.github.com/user -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT"
- HTTP/1.1 304 Not Modified
- Cache-Control: private, max-age=60
- Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
- Status: 304 Not Modified
- Vary: Accept, Authorization, Cookie
- X-RateLimit-Limit: 5000
- X-RateLimit-Remaining: 4996
- X-RateLimit-Reset: 1372700873
+has not changed, the server will return a `304 Not Modified`.
+
+{% if page.version == 'dotcom' %}
+
+{{#tip}}
+
+**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.
+
+{{/tip}}
+
+{% endif %}
+
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }}/user
+> HTTP/1.1 200 OK
+> Cache-Control: private, max-age=60
+> ETag: "644b5b0155e6404a9cc4bd9d8b1ae730"
+> Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
+> Status: 200 OK
+> Vary: Accept, Authorization, Cookie
+{% if page.version == 'dotcom' %}
+> X-RateLimit-Limit: 5000
+> X-RateLimit-Remaining: 4996
+> X-RateLimit-Reset: 1372700873
+{% endif %}
+
+$ curl -i {{ site.data.variables.product.api_url_pre }}/user -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"'
+> HTTP/1.1 304 Not Modified
+> Cache-Control: private, max-age=60
+> ETag: "644b5b0155e6404a9cc4bd9d8b1ae730"
+> Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
+> Status: 304 Not Modified
+> Vary: Accept, Authorization, Cookie
+{% if page.version == 'dotcom' %}
+> X-RateLimit-Limit: 5000
+> X-RateLimit-Remaining: 4996
+> X-RateLimit-Reset: 1372700873
+{% endif %}
+
+$ curl -i {{ site.data.variables.product.api_url_pre }}/user -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT"
+> HTTP/1.1 304 Not Modified
+> Cache-Control: private, max-age=60
+> Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
+> Status: 304 Not Modified
+> Vary: Accept, Authorization, Cookie
+{% if page.version == 'dotcom' %}
+> X-RateLimit-Limit: 5000
+> X-RateLimit-Remaining: 4996
+> X-RateLimit-Reset: 1372700873
+{% endif %}
+```
## Cross Origin Resource Sharing
@@ -503,50 +549,55 @@ HTML 5 Security Guide.
Here's a sample request sent from a browser hitting
`http://example.com`:
-{:.terminal}
- $ curl -i https://api.github.com -H "Origin: http://example.com"
- HTTP/1.1 302 Found
- Access-Control-Allow-Origin: *
- Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
- Access-Control-Allow-Credentials: true
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }} -H "Origin: http://example.com"
+HTTP/1.1 302 Found
+Access-Control-Allow-Origin: *
+Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, {% if page.version == 'dotcom' %}X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset,{% endif %} X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
+Access-Control-Allow-Credentials: true
+```
This is what the CORS preflight request looks like:
-{:.terminal}
- $ curl -i https://api.github.com -H "Origin: http://example.com" -X OPTIONS
- HTTP/1.1 204 No Content
- Access-Control-Allow-Origin: *
- Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-GitHub-OTP, X-Requested-With
- Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
- Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
- Access-Control-Max-Age: 86400
- Access-Control-Allow-Credentials: true
+``` command-line
+$ curl -i {{ site.data.variables.product.api_url_pre }} -H "Origin: http://example.com" -X OPTIONS
+HTTP/1.1 204 No Content
+Access-Control-Allow-Origin: *
+Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-GitHub-OTP, X-Requested-With
+Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
+Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, {% if page.version == 'dotcom' %}X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset,{% endif %} X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
+Access-Control-Max-Age: 86400
+Access-Control-Allow-Credentials: true
+```
## JSON-P Callbacks
You can send a `?callback` parameter to any GET call to have the results
wrapped in a JSON function. This is typically used when browsers want
-to embed GitHub content in web pages by getting around cross domain
+to embed {{ site.data.variables.product.product_name }} content in web pages by getting around cross domain
issues. The response includes the same data output as the regular API,
plus the relevant HTTP Header information.
-{:.terminal}
- $ curl https://api.github.com?callback=foo
-
- /**/foo({
- "meta": {
- "status": 200,
- "X-RateLimit-Limit": "5000",
- "X-RateLimit-Remaining": "4966",
- "X-RateLimit-Reset": "1372700873",
- "Link": [ // pagination headers and other links
- ["https://api.github.com?page=2", {"rel": "next"}]
- ]
- },
- "data": {
- // the data
- }
- })
+``` command-line
+$ curl https://api.github.com?callback=foo
+
+> /**/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:
@@ -606,8 +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).
-{:.terminal}
- $ 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/)
@@ -619,7 +671,7 @@ that current timestamp.
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 known
-timezone is updated whenever you browse the GitHub.com website.
+timezone is updated whenever you browse the {{ site.data.variables.product.product_name }} website.
#### UTC
diff --git a/content/v3/activity.md b/content/v3/activity.md
index 6aa9140234..cdac1ca8a7 100644
--- a/content/v3/activity.md
+++ b/content/v3/activity.md
@@ -1,5 +1,5 @@
---
-title: Activity | GitHub API
+title: Activity
---
# Activity
@@ -9,7 +9,7 @@ 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 GitHub.
+types][types] that power the various activity streams on {{ site.data.variables.product.product_name }}.
## [Feeds][]
diff --git a/content/v3/activity/events.md b/content/v3/activity/events.md
index 273bc09797..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,17 +15,18 @@ 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.
-{:.terminal}
- $ curl -I https://api.github.com/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
+``` 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 {{ 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.
diff --git a/content/v3/activity/events/types.md b/content/v3/activity/events/types.md
index 9938151ab3..9504e2de89 100644
--- a/content/v3/activity/events/types.md
+++ b/content/v3/activity/events/types.md
@@ -1,5 +1,5 @@
---
-title: Event Types & Payloads | GitHub API
+title: Event Types & Payloads
---
# Event Types & Payloads
@@ -15,7 +15,6 @@ match events returned by the [Events API](/v3/activity/events/) (except where no
**Note:** Some of these events may not be rendered in timelines, they're only
created for various internal and webhook purposes.
-* TOC
{:toc}
## CommitCommentEvent
@@ -40,7 +39,7 @@ Key | Type | Description
Represents a created repository, branch, or tag.
-Note: webhooks will not receive this event for created repositories.
+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
@@ -63,6 +62,8 @@ Key | Type | Description
Represents a [deleted branch or tag](/v3/git/refs/#delete-a-reference).
+Note: webhooks will not receive this event for tags if more than three tags are deleted at once.
+
### Events API payload
Key | Type | Description
@@ -82,7 +83,7 @@ Key | Type | Description
Represents a [deployment](/v3/repos/deployments/#list-deployments).
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
### Events API payload
@@ -107,7 +108,7 @@ Key | Type | Description
Represents a [deployment status](/v3/repos/deployments/#list-deployment-statuses).
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
### Events API payload
@@ -238,13 +239,19 @@ Key | Type | Description
## IssueCommentEvent
-Triggered when an [issue comment](/v3/issues/comments/) is created on an issue or pull request.
+{% 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 %}
### 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.
@@ -258,14 +265,17 @@ Key | Type | Description
## IssuesEvent
-Triggered when an [issue](/v3/issues) is assigned, unassigned, labeled, unlabeled, opened, closed, or reopened.
+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.
### Events API payload
Key | Type | Description
----|------|-------------
-`action`|`string` | The action that was performed. Can be one of "assigned", "unassigned", "labeled", "unlabeled", "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.
@@ -279,7 +289,7 @@ Key | Type | Description
## MemberEvent
-Triggered when a user is [added as a collaborator](/v3/repos/collaborators/#add-collaborator) to a repository.
+Triggered when a user is [added as a collaborator](/v3/repos/collaborators/#add-user-as-a-collaborator) to a repository.
### Events API payload
@@ -300,7 +310,7 @@ Key | Type | Description
Triggered when a user is added or removed from a team.
-Events of this type are not visible in timelines, they are only used to trigger organization webhooks.
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
### Events API payload
@@ -325,7 +335,7 @@ 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).
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
### Events API payload
@@ -343,7 +353,7 @@ Key | Type | Description
## 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
@@ -357,14 +367,17 @@ Triggered when a private repository is [open sourced](/v3/repos/#edit). Without
## PullRequestEvent
-Triggered when a [pull request](/v3/pulls) is assigned, unassigned, labeled, unlabeled, opened, 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.
### Events API payload
Key | Type | Description
----|------|-------------
-`action`|`string` | The action that was performed. Can be one of "assigned", "unassigned", "labeled", "unlabeled", "opened", "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.
+`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
@@ -377,13 +390,19 @@ Key | Type | Description
## PullRequestReviewCommentEvent
-Triggered when a [comment is created on a portion of the unified diff](/v3/pulls/comments) of a pull request.
+{% 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 %}
### 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 %}
`pull_request`|`object` | The [pull request](/v3/pulls/) the comment belongs to.
`comment`|`object` | The [comment](/v3/pulls/comments) itself.
@@ -452,16 +471,16 @@ Key | Type | Description
## RepositoryEvent
-Triggered when a repository is created.
+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, they are only used to trigger organization webhooks.
+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 "created".
-`repository`|`object` | The [repository](/v3/repos/) that was created.
+`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
@@ -475,7 +494,7 @@ Key | Type | Description
Triggered when the status of a Git commit changes.
-Events of this type are not visible in timelines, they are only used to trigger hooks.
+Events of this type are not visible in timelines. These events are only used to trigger hooks.
### Events API payload
@@ -497,7 +516,7 @@ Key | Type | Description
## TeamAddEvent
-Triggered when a [repository is added to a team](/v3/orgs/teams/#add-team-repo).
+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.
diff --git a/content/v3/activity/feeds.md b/content/v3/activity/feeds.md
index a80cb4ed02..11c583fa9b 100644
--- a/content/v3/activity/feeds.md
+++ b/content/v3/activity/feeds.md
@@ -1,18 +1,17 @@
---
-title: Feeds | GitHub API
+title: Feeds
---
# Feeds
-* TOC
{:toc}
## List Feeds
-GitHub provides several timeline resources in [Atom][] format. The Feeds API
+{{ 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
diff --git a/content/v3/activity/notifications.md b/content/v3/activity/notifications.md
index ef9aa37aa2..b09ec649a7 100644
--- a/content/v3/activity/notifications.md
+++ b/content/v3/activity/notifications.md
@@ -1,10 +1,9 @@
---
-title: Notifications | GitHub API
+title: Notifications
---
# Notifications
-* TOC
{:toc}
Users receive notifications for conversations in repositories they watch
@@ -36,18 +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.
-{:.terminal}
- # 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
@@ -92,7 +92,11 @@ Name | Type | Description
### 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
@@ -112,13 +116,17 @@ Name | Type | Description
### 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,7 +144,7 @@ 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
diff --git a/content/v3/activity/starring.md b/content/v3/activity/starring.md
index 8f92bcde90..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,7 +14,7 @@ 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-09-05-watcher-api/)
diff --git a/content/v3/activity/watching.md b/content/v3/activity/watching.md
index e96bf5f41a..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
diff --git a/content/v3/auth.md b/content/v3/auth.md
index 1f1f3920a8..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,29 +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 `+``` command-line http(s)://hostname/api/v3/ -+``` [Management Console][] API endpoints are only prefixed with a hostname: -
+``` command-line http(s)://hostname/ -+``` ## Authentication @@ -34,16 +33,14 @@ Every Enterprise API endpoint is only accessible to GitHub Enterprise site admin [basic authentication]: /v3/#basic-authentication [Management Console]: /v3/enterprise/management_console/ [User Administration]: /v3/users/administration/ -[Management Console password]: https://help.github.com/enterprise/2.0/admin/articles/accessing-the-management-console/ +[Management Console password]: https://help.github.com/enterprise/admin/articles/accessing-the-management-console/ -## Past Releases +## Releases -The latest release for GitHub Enterprise is <%= fetch_content(:latest_enterprise_version) %>. The GitHub APIs available to this release are located at
+``` command-line http(s)://hostname/api/v3 -+``` ## Get statistics diff --git a/content/v3/enterprise/ldap.md b/content/v3/enterprise/ldap.md index 7afd319271..b234a5c73b 100644 --- a/content/v3/enterprise/ldap.md +++ b/content/v3/enterprise/ldap.md @@ -4,7 +4,6 @@ title: LDAP # LDAP -* TOC {: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. @@ -21,8 +20,9 @@ Pass a JSON payload with the new LDAP Distinguished Name. #### Example - #!javascript - '{"ldap_dn": "uid=asdf,ou=users,dc=github,dc=com"}' +``` json +'{"ldap_dn": "uid=asdf,ou=users,dc=github,dc=com"}' +``` ### Response @@ -54,8 +54,9 @@ Pass a JSON payload with the new LDAP Distinguished Name. #### Example - #!javascript - '{"ldap_dn": "cn=Enterprise Ops,ou=teams,dc=github,dc=com"}' +``` json +'{"ldap_dn": "cn=Enterprise Ops,ou=teams,dc=github,dc=com"}' +``` ### Response diff --git a/content/v3/enterprise/license.md b/content/v3/enterprise/license.md index 3660c1a089..bdf5ba9d22 100644 --- a/content/v3/enterprise/license.md +++ b/content/v3/enterprise/license.md @@ -1,19 +1,18 @@ --- -title: License | GitHub API +title: License --- # License -* TOC {: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 diff --git a/content/v3/enterprise/management_console.md b/content/v3/enterprise/management_console.md index 4c9cfba70a..e2915032a7 100644 --- a/content/v3/enterprise/management_console.md +++ b/content/v3/enterprise/management_console.md @@ -1,10 +1,9 @@ --- -title: Management Console | GitHub API +title: Management Console --- # Management Console -* TOC {:toc} The Management Console API helps you manage your GitHub Enterprise installation. @@ -15,23 +14,25 @@ You must explicitly set the port number when making API calls to the Management 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/2.0/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). +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: -
-$ curl -L 'http://hostname:admin_port/setup/api?api_key=your-amazing-password' -+``` 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: -
-$ curl -L 'http://api_key:your-amazing-password@hostname:admin_port/setup/api' -+``` command-line +$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api' +``` ## Upload a license for the first time @@ -62,16 +63,16 @@ For a list of the available settings, see [the `/setup/api/settings` endpoint](# ### Response -
-HTTP/1.1 202 Created -Location: http://hostname:admin_port/setup/api/configcheck -+``` command-line +> HTTP/1.1 202 Created +> Location: http://hostname:admin_port/setup/api/configcheck +``` ### Example -
-curl -L -X POST 'http://hostname:admin_port/setup/api/start' -F license=@/path/to/github-enterprise.ghl -F "password=your-amazing-password" -F settings=</path/to/settings.json -+``` 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 @@ -87,16 +88,16 @@ Name | Type | Description ### Response -
-HTTP/1.1 202 Accepted -Location: http://hostname:admin_port/setup/api/configcheck -+``` command-line +> HTTP/1.1 202 Accepted +> Location: http://hostname:admin_port/setup/api/configcheck +``` ### Example -
-curl -L -X POST 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/upgrade' -+``` command-line +$ curl -L -X POST 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/upgrade' +``` ## Check configuration status @@ -123,9 +124,9 @@ Status | Description ### Example -
-curl -L 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/configcheck' -+``` command-line +$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/configcheck' +``` ## Start a configuration process @@ -135,16 +136,16 @@ This endpoint allows you to start a configuration process at any time for your u ### Response -
-HTTP/1.1 202 Accepted -Location: http://hostname:admin_port/setup/api/configcheck -+``` command-line +> HTTP/1.1 202 Accepted +> Location: http://hostname:admin_port/setup/api/configcheck +``` ### Example -
-curl -L -X POST 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/configure' -+``` command-line +$ curl -L -X POST 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/configure' +``` ## Retrieve settings @@ -157,9 +158,9 @@ curl -L -X POST 'http://api_key:your-amazing-password@hostname ### Example -
-curl -L 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/settings' -+``` command-line +$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings' +``` ## Modify settings @@ -173,15 +174,15 @@ Name | Type | Description ### Response -
-HTTP/1.1 204 No Content -+``` command-line +> HTTP/1.1 204 No Content +``` ### Example -
-curl -L -X PUT 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/settings' --data-urlencode "settings=`cat /path/to/settings.json`" -+``` 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 @@ -196,9 +197,9 @@ Check your installation's maintenance status: ### Example -
-curl -L 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/maintenance' -+``` command-line +$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/maintenance' +``` ## Enable or disable maintenance mode @@ -223,9 +224,9 @@ The possible values for `when` are `now` or any date parseable by ### Example -
-curl -L -X POST 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/maintenance' -d 'maintenance={"enabled":true, "when":"now"}'
-
+``` 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
@@ -238,9 +239,9 @@ curl -L -X POST 'http://api_key:your-amazing-password@hostname
### Example
--curl -L 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys' -+``` command-line +$ curl -L 'https://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys' +``` ## Add a new authorized SSH key @@ -259,9 +260,9 @@ Name | Type | Description ### Example -
-curl -L -X POST 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys' -F authorized_key=@/path/to/key.pub -+``` 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 @@ -280,6 +281,6 @@ Name | Type | Description ### Example -
-curl -L -X DELETE 'http://api_key:your-amazing-password@hostname:admin_port/setup/api/settings/authorized-keys' -F authorized_key=@/path/to/key.pub -+``` 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 index 60e9be3138..cc6013e48e 100644 --- a/content/v3/enterprise/orgs.md +++ b/content/v3/enterprise/orgs.md @@ -1,19 +1,18 @@ --- -title: Organization Administration | GitHub API +title: Organization Administration --- # Organization Administration -* TOC {: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 `403` response if they try to access it. +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 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 index 72c6afc7a9..d62fd98056 100644 --- a/content/v3/enterprise/search_indexing.md +++ b/content/v3/enterprise/search_indexing.md @@ -1,19 +1,18 @@ --- -title: Search Indexing | GitHub API +title: Search Indexing --- # Search Indexing -* TOC {: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 @@ -39,10 +38,9 @@ Target | Description ### 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
diff --git a/content/v3/gists.md b/content/v3/gists.md
index dc78684b55..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
@@ -17,13 +16,15 @@ The API will return a 401 "Bad credentials" response if the gists scope was give
## Truncation
-The Gist API provides up to one megabyte of content for each file in the gist. Every call to retrieve 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`.
+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`.
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`.
-## List gists
+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 a user's gists
+
+List public gists for the specified user:
GET /users/:username/gists
@@ -32,10 +33,38 @@ 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
@@ -55,7 +84,9 @@ Name | Type | Description
GET /gists/:id
-### Response {#detailed-gist-representation}
+
+
+### Response
<%= headers 200 %>
<%= json :full_gist %>
@@ -91,11 +122,11 @@ The keys in the `files` object are the `string` filename, and the value is anoth
}
%>
-- Note: Don't name your files "gistfile" with a numerical suffix. This is the format of the automatic naming scheme that Gist uses internally. -
-null object.
-
+
{{/tip}}
@@ -182,11 +213,11 @@ The keys in the `files` object are the `string` filename. The value is another `
POST /gists/:id/forks
-
- Note: This was previously /gists/:id/fork
-
token is still returned for "create" token is still returned for "create"
To reduce the impact of removing the token value,
the OAuth Authorizations API now includes a new request attribute
@@ -35,12 +48,62 @@ Make sure you understand how to [work with two-factor authentication](/v3/auth/#
fingerprint), and
one new endpoint.
+ 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).
+
This functionality became the default for all requests on April 20, 2015. Please see the blog post for full details.
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+{% 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 in the Accept header:
-
application/vnd.github.ironman-preview+json- -
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+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 in the Accept header:
-
application/vnd.github.ironman-preview+json- +To access the API during the preview period, you must provide a custom [media type](/v3/media) in the `Accept` header: -
- Warning: If you specify the privacy attribute on an organization that hasn't had improved organization permissions enabled yet, you will get a 422 error response.
-
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+**Warning:** If you specify the `privacy` 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. -
- To access the API during the preview period, you must provide a custom media type in the Accept header:
-
application/vnd.github.ironman-preview+json- +{{/tip}} -
- Warning: If you specify the privacy attribute on an organization that hasn't had improved organization permissions enabled yet, you will get a 422 error response.
-
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+`role`|`string`| Filters members returned by their role in the team. Can be one of:
- To access the API during the preview period, you must provide a custom media type in the Accept header:
-
application/vnd.github.ironman-preview+json- -
- The "Get team member" API (described below) is - deprecated and is scheduled for - removal in the next major version of the API. +{{#tip}} - We recommend using the - Get team membership API - instead. It allows you to get both active and pending memberships. -
-- The "Add team member" API (described below) is - deprecated and is scheduled for - removal in the next major version of the API. +{{#tip}} - We recommend using the - Add team membership API - instead. It allows you to invite new organization members to your teams. -
-- The "Remove team member" API (described below) is - deprecated and is scheduled for - removal in the next major version of the API. +{{#tip}} + +The "Remove team member" API (described below) is +[deprecated](/v3/versions/#v3-deprecations) and is scheduled for +removal in the next major version of the API. - We recommend using the - Remove team membership API - instead. It allows you to remove both active and pending memberships. -
-- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. 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.ironman-preview+json- - -
- Warning: If you specify the role attribute on an organization that hasn't had improved organization permissions enabled yet, you will get a 422 error response.
-
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+{% if page.version == 'dotcom' or page.version >= 2.4 %} -
- To access the API during the preview period, you must provide a custom media type in the Accept header:
-
application/vnd.github.ironman-preview+json- -
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+{% endif %} -
- To access the API during the preview period, you must provide a custom media type 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 enabled yet, you will get a 422 error response.
-
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+{{#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}} -
- To access the API during the preview period, you must provide a custom media type in the Accept header:
-
application/vnd.github.ironman-preview+json- -
- We're currently offering a preview period allowing applications to opt in to the Organization Permissions API. Please see the blog post for full details. -
+{{#tip}} + +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}} -
- To access the API during the preview period, you must provide a custom media type in the Accept header:
-
application/vnd.github.ironman-preview+json- +{% if page.version != 'dotcom' and page.version > 2.3 and page.version < 2.6 %} -
- 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 enabled yet, you will get a 422 error response.
-
+814412cfbd631109df337e16c807207e78c0d24e ++ ## Compare two commits GET /repos/:owner/:repo/compare/:base...:head @@ -65,3 +83,59 @@ Pass the appropriate [media type](/v3/media/#commits-commit-comparison-and-pull- 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 b112e24576..d1d352e335 100644 --- a/content/v3/repos/contents.md +++ b/content/v3/repos/contents.md @@ -1,10 +1,9 @@ --- -title: Contents | GitHub API +title: Contents --- # Contents -* TOC {:toc} These API methods let you retrieve the contents of files within a repository as @@ -265,12 +264,13 @@ Name | Type | Description To follow redirects with curl, use the `-L` switch: -{:.terminal} - curl -L https://api.github.com/repos/octokit/octokit.rb/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 diff --git a/content/v3/repos/deployments.md b/content/v3/repos/deployments.md index c4980ada99..34e2574621 100644 --- a/content/v3/repos/deployments.md +++ b/content/v3/repos/deployments.md @@ -1,13 +1,12 @@ --- -title: Deployments | GitHub API +title: Deployments --- # Deployments -* TOC {:toc} -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 @@ -31,7 +30,7 @@ made. Below is a simple sequence diagram for how these interactions would work. -
+```
+---------+ +--------+ +-----------+ +-------------+
| Tooling | | GitHub | | 3rd Party | | Your Server |
+---------+ +--------+ +-----------+ +-------------+
@@ -56,11 +55,11 @@ 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
+[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
@@ -79,8 +78,8 @@ Simple filtering of deployments is available via query parameters:
Name | Type | Description
-----|------|--------------
-`sha`|`string` | The short or long 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`
+`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`
@@ -93,7 +92,7 @@ Name | Type | Description
Deployments offer a few configurable parameters with sane defaults.
-The `ref` parameter can be any named branch, tag, or sha. At GitHub we often
+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
@@ -132,13 +131,30 @@ Users with `repo` or `repo_deployment` scopes can create a deployment for a give
Name | Type | Description
-----|------|--------------
-`ref`|`string`| **Required**. The ref to deploy. This can be a branch, tag, or sha.
+`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: `""`
`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 %}
+
+{% 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
@@ -151,6 +167,8 @@ chat networks.
:description => "Deploying my sweet branch"
%>
+### Successful response
+
<%= headers 201, :Location => get_resource(:deployment)['url'] %>
<%= json :deployment %>
@@ -166,9 +184,25 @@ A more advanced example specifying required commit statuses and bypassing auto-m
: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
@@ -204,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
@@ -220,3 +273,5 @@ Name | Type | Description
<%= 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 5a3b78cb13..c5f027a106 100644
--- a/content/v3/repos/downloads.md
+++ b/content/v3/repos/downloads.md
@@ -1,10 +1,9 @@
---
-title: Downloads | GitHub API
+title: Downloads
---
# Downloads
-* TOC
{:toc}
### Downloads API is Deprecated
diff --git a/content/v3/repos/forks.md b/content/v3/repos/forks.md
index a00eff8da0..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
diff --git a/content/v3/repos/hooks.md b/content/v3/repos/hooks.md
index 03602ee13f..2208924598 100644
--- a/content/v3/repos/hooks.md
+++ b/content/v3/repos/hooks.md
@@ -1,17 +1,16 @@
---
-title: Repository 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 respositories, check out our [API documentation for Organization Webhooks][org-hooks].
+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
@@ -44,17 +43,17 @@ Repositories can have multiple webhooks installed. Each webhook should have a un
Name | Type | Description
-----|------|--------------
`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 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` | **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
-To create [a webhook](/webhooks), [the following fields are required](https://github.com/github/github-services/blob/master/lib/services/web.rb#L4-11) by the `config`:
+To create [a webhook](/webhooks), the following fields are required by the `config`:
* `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][hub-signature].
+* `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 create a hook that posts payloads in JSON format:
@@ -81,7 +80,7 @@ Here's how you can create a hook that posts payloads in JSON format:
Name | Type | Description
-----|------|--------------
-`config`|`object` | 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.
@@ -135,7 +134,7 @@ 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, 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
@@ -183,17 +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:
-{:.terminal}
- 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.
@@ -205,14 +205,12 @@ 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]: 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]: https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#authednotify
[events-url]: /webhooks/#events
[ping-event-url]: /webhooks/#ping-event
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 949a74d396..db2fdcc7cc 100644
--- a/content/v3/repos/keys.md
+++ b/content/v3/repos/keys.md
@@ -1,13 +1,14 @@
---
-title: Deploy Keys | GitHub API
+title: Deploy Keys
---
# Deploy Keys
-* TOC
{:toc}
-## List deploy keys {#list}
+
+
+## List deploy keys
GET /repos/:owner/:repo/keys
@@ -16,7 +17,9 @@ title: Deploy Keys | GitHub API
<%= 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
@@ -25,7 +28,9 @@ title: Deploy Keys | GitHub API
<%= headers 200 %>
<%= json :deploy_key %>
-## Add a new deploy key {#create}
+
+
+## Add a new deploy key
POST /repos/:owner/:repo/keys
@@ -48,12 +53,16 @@ Here's how you can create a read-only deploy 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 d952319a0f..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,11 +22,60 @@ 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
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 d7a14d061c..73a2e10891 100644
--- a/content/v3/repos/releases.md
+++ b/content/v3/repos/releases.md
@@ -1,10 +1,9 @@
---
-title: Releases | GitHub API
+title: Releases
---
# Releases
-* TOC
{:toc}
## List releases for a repository
@@ -156,8 +155,8 @@ Users with push access to the repository can delete a release.
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).
-You need to use an HTTP client which supports
-SNI to make calls to this endpoint.
+{% 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, 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.
@@ -167,12 +166,12 @@ Everything else about the endpoint is the same as the rest of the API. For examp
### Input
-The raw file is uploaded to GitHub. Set the content type appropriately, and the
+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).
+`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.
@@ -197,10 +196,9 @@ This may leave an empty asset with a state of `"new"`. It can be safely deleted
{{#tip}}
-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.
+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.
{{/tip}}
@@ -240,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 85dfbcddc4..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,7 +21,8 @@ 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
@@ -40,7 +40,9 @@ Weekly Hash (`weeks` array):
<%= 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`.
@@ -52,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
@@ -64,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
@@ -79,7 +85,9 @@ 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 8f6a1c9450..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,
@@ -45,7 +44,7 @@ Attempts to create more than 1000 statuses will result in a validation error.
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.
- This resource is also available via a legacy route:
- GET /repos/:owner/:repo/statuses/:ref.
-
master branch.language:go is not valid, while amazing language:go is.language:go is not valid, while amazing language:go is.+``` 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 @@ -26,6 +36,12 @@ 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 \ @@ -85,6 +101,8 @@ Name | Type | Description <%= headers 204 %> +{% endif %} + ## Promote an ordinary user to a site administrator PUT /users/:username/site_admin @@ -109,7 +127,7 @@ You can demote any user account except your own. {{#warning}} -If your GitHub Enterprise appliance has [LDAP Sync with Active Directory LDAP servers](https://help.github.com/enterprise/2.1/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. +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}} @@ -127,7 +145,7 @@ You can suspend any user account except your own. {{#warning}} -If your GitHub Enterprise appliance has [LDAP Sync with Active Directory LDAP servers](https://help.github.com/enterprise/2.1/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. +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}} @@ -137,6 +155,8 @@ If your GitHub Enterprise appliance has [LDAP Sync with Active Directory LDAP se <%= headers 204 %> +{% if page.version != 'dotcom' and page.version >= 2.3 %} + ## List all public keys GET /admin/keys @@ -148,6 +168,8 @@ If your GitHub Enterprise appliance has [LDAP Sync with Active Directory LDAP se [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}} @@ -164,6 +186,8 @@ You can delete any user account except your own. <%= headers 204 %> +{% endif %} + ## Delete a public key DELETE /admin/keys/1 @@ -171,3 +195,5 @@ You can delete any user account except your own. ### Response <%= headers 204 %> + +{% endif %} diff --git a/content/v3/users/emails.md b/content/v3/users/emails.md index fd7aab4211..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 @@ -23,15 +22,15 @@ This endpoint is accessible with the user:email scope. ## Add email address(es) -{{#enterprise-only}} +{% if page.version != 'dotcom' && page.version >= 2.1 %} {{#warning}} -If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/2.1/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. +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. {{/warning}} -{{/enterprise-only}} +{% endif %} POST /user/emails @@ -59,15 +58,15 @@ You can post a single email address or an array of addresses: ## Delete email address(es) -{{#enterprise-only}} +{% if page.version != 'dotcom' && page.version >= 2.1 %} {{#warning}} -If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/2.1/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. +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}} -{{/enterprise-only}} +{% endif %} DELETE /user/emails diff --git a/content/v3/users/followers.md b/content/v3/users/followers.md index 7989914107..258d8d5e31 100644 --- a/content/v3/users/followers.md +++ b/content/v3/users/followers.md @@ -1,10 +1,9 @@ --- -title: User Followers | GitHub API +title: User Followers --- # Followers -* TOC {:toc} ## List followers of a user 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 c376ce1567..25378d75f4 100644 --- a/content/v3/users/keys.md +++ b/content/v3/users/keys.md @@ -1,10 +1,9 @@ --- -title: User Public Keys | GitHub API +title: User Public Keys --- # Public Keys -* TOC {:toc} ## List public keys for a user @@ -50,15 +49,15 @@ 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). -{{#enterprise-only}} +{% if page.version != 'dotcom' && page.version >= 2.1 %} {{#warning}} -If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/2.1/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. +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}} -{{/enterprise-only}} +{% endif %} POST /user/keys @@ -82,15 +81,15 @@ 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). -{{#enterprise-only}} +{% if page.version != 'dotcom' && page.version >= 2.1 %} {{#warning}} -If your GitHub Enterprise appliance has [LDAP Sync enabled](https://help.github.com/enterprise/2.1/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. +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}} -{{/enterprise-only}} +{% endif %} DELETE /user/keys/:id diff --git a/content/v3/versions.md b/content/v3/versions.md index 6bd31a5fdf..53c7cf6f33 100644 --- a/content/v3/versions.md +++ b/content/v3/versions.md @@ -1,5 +1,5 @@ --- -title: Versions | GitHub API +title: Versions --- # Versions @@ -42,86 +42,117 @@ 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. + + 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 **forks_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. + + Recommendation: Do not use this attribute. It is obsolete. 1. User attribute: gravatar_id -: Recommendation: Use **avatar_url** instead. + + Recommendation: Use **avatar_url** instead. 1. Feed attribute: current_user_organization_url -: Recommendation: Use **current_user_organization_urls** instead. + + Recommendation: Use **current_user_organization_urls** instead. 1. Feed attribute: current_user_organization -: Recommendation: Use **current_user_organizations** instead. + + 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) + + 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 + + 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 team repository](/v3/orgs/teams/#add-team-repo) 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 team repository](/v3/orgs/teams/#add-team-repo) with a `permission` attribute to update each repository's permission separately. -# beta (Deprecated) {#beta} + 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. diff --git a/content/webhooks/configuring/index.md b/content/webhooks/configuring.md similarity index 79% rename from content/webhooks/configuring/index.md rename to content/webhooks/configuring.md index 9d8a9a243a..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 @@ -28,8 +27,9 @@ for all major operating systems. 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.io -> 127.0.0.1:4567 +``` command-line +$ Forwarding http://7e9ea9dc.ngrok.io -> 127.0.0.1:4567 +``` 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`. @@ -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(request.body.read) - 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 89% rename from content/webhooks/creating/index.md rename to content/webhooks/creating.md index 7bc5b7a714..06170155d1 100644 --- a/content/webhooks/creating/index.md +++ b/content/webhooks/creating.md @@ -1,11 +1,10 @@ --- -title: Creating webhooks | GitHub API +title: Creating webhooks layout: webhooks --- # Creating Webhooks -* TOC {:toc} Now that we understand [the basics of webhooks][webhooks-overview], let's go @@ -15,12 +14,12 @@ 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 repository webhook on GitHub, head over to the **Settings** page of +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**. diff --git a/content/webhooks/index.md b/content/webhooks/index.md index 2c04285e3e..03fc42d1ca 100644 --- a/content/webhooks/index.md +++ b/content/webhooks/index.md @@ -1,11 +1,10 @@ --- -title: Webhooks | GitHub API +title: Webhooks layout: webhooks --- # Webhooks -* TOC {:toc} @@ -17,7 +16,7 @@ deploy to your production server. You're only limited by your imagination. 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. +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). @@ -49,16 +48,16 @@ Name | Description [`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] | Any time an Issue or Pull Request is [commented](/v3/issues/comments/) on. -[`issues`][event-types-issues] | Any time an Issue is assigned, unassigned, labeled, unlabeled, opened, closed, or reopened. -[`member`][event-types-member] | Any time a User is added as a collaborator to a non-Organization Repository. +[`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] | Any time a [comment is created on a portion of the unified diff](/v3/pulls/comments) of a pull request (the Files Changed tab). -[`pull_request`][event-types-pull_request] | Any time a Pull Request is assigned, unassigned, labeled, unlabeled, opened, closed, reopened, or synchronized (updated due to a new push in the branch that the pull request is tracking). +[`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. **Organization hooks only**. +[`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. @@ -84,6 +83,12 @@ 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 @@ -91,48 +96,48 @@ several special headers: Header | Description -------|-------------| -`X-Github-Event`| Name of the [event][events-section] that triggered this delivery. +`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. +`X-GitHub-Delivery`| Unique ID for this delivery. Also, the `User-Agent` for the requests will have the prefix `GitHub-Hookshot/`. ### Example delivery -{:.terminal} - 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, - ... - } - } - +``` 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 @@ -149,42 +154,10 @@ 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 - -In addition to webhooks, we also offer the ability to install pre-rolled -integrations for a variety of existing services. These services [are contributed -and maintained by the Open Source community][github-services]. - -Service hooks are installed and configured in a similar fashion as webhooks. -When [creating a hook][webhooks-guide-create], just set the `:name` parameter to -a service name instead of "web" (for webhook). The main differences to keep in -mind between webhooks and service hooks are: - -- Service hooks cannot be installed on organizations, only repositories. -- You can only install a one service per integrator for a repository, whereas - multiple webhooks can be installed on each organization/repository. -- Each service hook only supports a specific set of events, depending on the - services implementation. -- Each service has its own unique set of configuration options. - -To see a full list of available services, their supported events, and -configuration options, check out https://api.github.com/hooks. Documentation for all -service hooks can be found in the [docs directory][github-services-docs] of the -github-services repository. - -**Note:** If you are building a new integration, you should build it as webhook. -We suggest creating an [OAuth application][oauth-applications] to automatically -install and manage your users' webhooks. We will no longer be accepting new -services to the [github-services repository][github-services]. - - [service-hooks-section]: #service-hooks [events-section]: #events [wildcard-section]: #wildcard-event [payloads-section]: #payloads -[webhooks-guide-create]: /webhooks/creating/ [org-hooks]: /v3/orgs/hooks/ [repo-hooks]: /v3/repos/hooks/ [repo-hooks-show]: /v3/repos/hooks/#get-single-hook @@ -213,6 +186,3 @@ services to the [github-services repository][github-services]. [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 -[github-services]: https://github.com/github/github-services -[github-services-docs]: https://github.com/github/github-services/tree/master/docs -[oauth-applications]: /v3/oauth/ diff --git a/content/webhooks/securing/index.md b/content/webhooks/securing.md similarity index 67% rename from content/webhooks/securing/index.md rename to content/webhooks/securing.md index 0abe20d2b2..407ea1f26b 100644 --- a/content/webhooks/securing/index.md +++ b/content/webhooks/securing.md @@ -1,11 +1,10 @@ --- -title: Securing your webhooks | GitHub API +title: Securing your webhooks layout: webhooks --- # Securing your webhooks -* TOC {: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. @@ -24,42 +23,44 @@ To set your token on GitHub: Next, set up an environment variable on your server that stores this token. Typically, this is as simple as running: -
-export SECRET_TOKEN=your_token -+``` 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. You can find details on the implementation [in our Ruby implementation][ruby-secret]. +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' +``` 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(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 +``` 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: @@ -67,5 +68,4 @@ Obviously, your language and server implementations may differ than this code. T * 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. -[ruby-secret]: https://github.com/github/github-services/blob/14f4da01ce29bc6a02427a9fbf37b08b141e81d9/lib/services/web.rb#L47-L50 [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 96% rename from content/webhooks/testing/index.md rename to content/webhooks/testing.md index 95c902155e..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 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/gulpfile.js b/gulpfile.js index f63cb03c59..8b858f499b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -36,18 +36,28 @@ gulp.task("css", function() { gulp.task("javascript", function () { gulp.src("assets/javascripts/dev_mode.js") .pipe(gulp.dest("output/assets/javascripts/")); - gulp.src("assets/search-index.json") - .pipe(gulp.dest("output/assets/")); return gulp.src([ + "assets/javascripts/initial.js", "assets/javascripts/documentation.js", + "assets/javascripts/search.js", + "assets/javascripts/images.js", "assets/vendor/retinajs/src/retinajs" ]) .pipe(gulpif(transformCS, coffee())) .pipe(concat("application.js")) + .pipe(replace(/\{\{ site\.version \}\}/g, CONFIG.latest_enterprise_version)) .pipe(gulpif(IS_PRODUCTION, uglify())) .pipe(gulp.dest("output/assets/javascripts")); }); +gulp.task("javascript_workers", function () { + return gulp.src([ + "assets/javascripts/search_worker.js", + "assets/vendor/lunr.js/lunr.min.js" + ]) + .pipe(gulp.dest("output/assets/javascripts")); +}); + gulp.task("octicons", function() { return gulp.src("assets/vendor/octicons/octicons/**/*") .pipe(gulp.dest("output/assets/stylesheets")); @@ -70,7 +80,8 @@ gulp.task("server", function() { connect = require("gulp-connect"); connect.server({ port: 4000, - root: ["output"] + root: ["output"], + fallback: "output/404.html" }); }); @@ -91,6 +102,6 @@ gulp.task("watch:assets", function() { }); gulp.task("serve", [ "server", "watch:nanoc", "watch:assets" ]); -gulp.task("assets", [ "css", "javascript", "octicons", "images" ]); +gulp.task("assets", [ "css", "javascript", "javascript_workers", "octicons", "images" ]); gulp.task("build", [ "nanoc:compile", "assets" ]); gulp.task("default", [ "build", "serve" ]); diff --git a/layouts/_changes.html b/layouts/_changes.html index 929a281426..35b25d854e 100644 --- a/layouts/_changes.html +++ b/layouts/_changes.html @@ -1,6 +1,6 @@ <% @changes.each do |article| %>