GitHub permite definir webhooks para los repositorios.
Si sobre el repositorio se realiza cierta acción (usualmente un push), github ejecuta el webhook que se haya asociado a esa acción (usualmente una solicitud post a un url indicado).
Por ejemplo, para el repositorio https://github.com/akobashikawa/travis-test-dev entro a Settings, Webhooks & services, Webhooks, Add webhook:
Payload URL: http://mydomain.com/postreceive
Content type: application/json
Secret: some_secret_word
Which events would you like to trigger this webhook?: Just the push event.
[x] Active
Por ejemplo, http://localhost:3000 puede ser visto en http://12345abc.ngrok.io/
Eso evita tener que usar un hosting para simplemente probar un webhook.
De ese modo, para probar el webhook, cree rápidamente este servidor web con nodejs:
Levanté el servidor:
$ nodemon index.js
Una ventaja de usar nodemon es que el servidor se recarga automáticamente cada vez que actualizo el código.
Lugo ejecuté ngrok (que descargué de https://ngrok.com/download) en otra consola:
$ ./ngrok http 3000
...
Luego defino un webhook con el payload URL: https://57cdad67.ngrok.io/postreceive
Pruebo luego hacer un push al repositorio y observo en la consola la solicitud post que github envía:
La acción que definí en el servidor web fue la de de mostrar en consola la solicitud post enviada por github. Se puede usar esa señal para ejecutar cualquier acción que se crea conveniente. Por ejemplo, descargar el repositorio y deployarlo automáticamente.
Si sobre el repositorio se realiza cierta acción (usualmente un push), github ejecuta el webhook que se haya asociado a esa acción (usualmente una solicitud post a un url indicado).
Por ejemplo, para el repositorio https://github.com/akobashikawa/travis-test-dev entro a Settings, Webhooks & services, Webhooks, Add webhook:
Payload URL: http://mydomain.com/postreceive
Content type: application/json
Secret: some_secret_word
Which events would you like to trigger this webhook?: Just the push event.
[x] Active
ngrok
ngrok es un servicio que permite que un servidor local pueda tener un ip público.Por ejemplo, http://localhost:3000 puede ser visto en http://12345abc.ngrok.io/
Eso evita tener que usar un hosting para simplemente probar un webhook.
De ese modo, para probar el webhook, cree rápidamente este servidor web con nodejs:
var express = require('express'); var app = express(); var bodyParser = require('body-parser'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.get('/', function(req, res) { console.log(req.url); res.send('Hello Express!'); }); app.post('/postreceive', function(req, res) { console.log(req.body); res.send('Post Response'); }); app.listen(3000, function() { console.log('Express app listening in 3000'); });
Levanté el servidor:
$ nodemon index.js
Una ventaja de usar nodemon es que el servidor se recarga automáticamente cada vez que actualizo el código.
Lugo ejecuté ngrok (que descargué de https://ngrok.com/download) en otra consola:
$ ./ngrok http 3000
...
ngrok by @inconshreveable (Ctrl+C to quit) Tunnel Status online Version 2.0.25/2.1.1 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://57cdad67.ngrok.io -> localhost:3000 Forwarding https://57cdad67.ngrok.io -> localhost:3000 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00
Luego defino un webhook con el payload URL: https://57cdad67.ngrok.io/postreceive
Pruebo luego hacer un push al repositorio y observo en la consola la solicitud post que github envía:
{ ref: 'refs/heads/master', before: '8d8523134683128d06e2178c49eacde2d46bddb3', after: 'd313dfc1d46a08773c4d1ac429654a2e1a375b62', created: false, deleted: false, forced: false, base_ref: null, compare: 'https://github.com/akobashikawa/travis-test-dev/compare/8d8523134683...d313dfc1d46a', commits: [ { id: 'd313dfc1d46a08773c4d1ac429654a2e1a375b62', tree_id: 'd5746c384d3f2d6afae9f5b0f7b4ea44f7bbf8a5', distinct: true, message: 'Update README.md', timestamp: '2016-05-20T00:06:31-05:00', url: 'https://github.com/akobashikawa/travis-test-dev/commit/d313dfc1d46a08773c4d1ac429654a2e1a375b62', author: [Object], committer: [Object], added: [], removed: [], modified: [Object] } ], head_commit: { id: 'd313dfc1d46a08773c4d1ac429654a2e1a375b62', tree_id: 'd5746c384d3f2d6afae9f5b0f7b4ea44f7bbf8a5', distinct: true, message: 'Update README.md', timestamp: '2016-05-20T00:06:31-05:00', url: 'https://github.com/akobashikawa/travis-test-dev/commit/d313dfc1d46a08773c4d1ac429654a2e1a375b62', author: { name: 'Rulo Kobashikawa', email: 'akobashikawa@gmail.com', username: 'akobashikawa' }, committer: { name: 'Rulo Kobashikawa', email: 'akobashikawa@gmail.com', username: 'akobashikawa' }, added: [], removed: [], modified: [ 'README.md' ] }, repository: { id: 55999700, name: 'travis-test-dev', full_name: 'akobashikawa/travis-test-dev', owner: { name: 'akobashikawa', email: 'akobashikawa@gmail.com' }, private: false, html_url: 'https://github.com/akobashikawa/travis-test-dev', description: 'Tetsing travis. Dev repo.', fork: false, url: 'https://github.com/akobashikawa/travis-test-dev', forks_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/forks', keys_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/keys{/key_id}', collaborators_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/collaborators{/collaborator}', teams_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/teams', hooks_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/hooks', issue_events_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/issues/events{/number}', events_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/events', assignees_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/assignees{/user}', branches_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/branches{/branch}', tags_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/tags', blobs_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/git/blobs{/sha}', git_tags_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/git/tags{/sha}', git_refs_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/git/refs{/sha}', trees_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/git/trees{/sha}', statuses_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/statuses/{sha}', languages_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/languages', stargazers_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/stargazers', contributors_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/contributors', subscribers_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/subscribers', subscription_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/subscription', commits_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/commits{/sha}', git_commits_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/git/commits{/sha}', comments_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/comments{/number}', issue_comment_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/issues/comments{/number}', contents_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/contents/{+path}', compare_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/compare/{base}...{head}', merges_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/merges', archive_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/{archive_format}{/ref}', downloads_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/downloads', issues_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/issues{/number}', pulls_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/pulls{/number}', milestones_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/milestones{/number}', notifications_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/notifications{?since,all,participating}', labels_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/labels{/name}', releases_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/releases{/id}', deployments_url: 'https://api.github.com/repos/akobashikawa/travis-test-dev/deployments', created_at: 1460401727, updated_at: '2016-04-11T19:21:17Z', pushed_at: 1463720793, git_url: 'git://github.com/akobashikawa/travis-test-dev.git', ssh_url: 'git@github.com:akobashikawa/travis-test-dev.git', clone_url: 'https://github.com/akobashikawa/travis-test-dev.git', svn_url: 'https://github.com/akobashikawa/travis-test-dev', homepage: null, size: 3295, stargazers_count: 0, watchers_count: 0, language: 'PHP', has_issues: true, has_downloads: true, has_wiki: true, has_pages: false, forks_count: 0, mirror_url: null, open_issues_count: 1, forks: 0, open_issues: 1, watchers: 0, default_branch: 'master', stargazers: 0, master_branch: 'master' }, pusher: { name: 'akobashikawa', email: 'akobashikawa@gmail.com' }, sender: { login: 'akobashikawa', id: 108734, avatar_url: 'https://avatars.githubusercontent.com/u/108734?v=3', gravatar_id: '', url: 'https://api.github.com/users/akobashikawa', html_url: 'https://github.com/akobashikawa', followers_url: 'https://api.github.com/users/akobashikawa/followers', following_url: 'https://api.github.com/users/akobashikawa/following{/other_user}', gists_url: 'https://api.github.com/users/akobashikawa/gists{/gist_id}', starred_url: 'https://api.github.com/users/akobashikawa/starred{/owner}{/repo}', subscriptions_url: 'https://api.github.com/users/akobashikawa/subscriptions', organizations_url: 'https://api.github.com/users/akobashikawa/orgs', repos_url: 'https://api.github.com/users/akobashikawa/repos', events_url: 'https://api.github.com/users/akobashikawa/events{/privacy}', received_events_url: 'https://api.github.com/users/akobashikawa/received_events', type: 'User', site_admin: false } }Si ngrok se detiene (con CTRL+C), cuando se vuelve a ejecutar nos dará un url distinto al anterior y será necesario ir a github para editar la definición del webhook y colocar el nuevo payload url.
La acción que definí en el servidor web fue la de de mostrar en consola la solicitud post enviada por github. Se puede usar esa señal para ejecutar cualquier acción que se crea conveniente. Por ejemplo, descargar el repositorio y deployarlo automáticamente.