notify-travis-status.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #!/usr/bin/env node
  2. /**
  3. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  4. * For licensing, see LICENSE.md.
  5. */
  6. /* eslint-env node */
  7. /*
  8. This script assumes that is being executed on Travis CI. It requires three environment variables:
  9. - SLACK_WEBHOOK_URL - a URL where the notification should be sent
  10. - START_TIME - POSIX time (when the script has begun the job)
  11. - END_TIME - POSIX time (when the script has finished the job)
  12. It also has some dependencies:
  13. - "slack-notify"
  14. - "@octokit/rest@^16.13.4"
  15. */
  16. const buildBranch = process.env.TRAVIS_BRANCH;
  17. // Send a notification only for main branches...
  18. if ( buildBranch !== 'master' && buildBranch !== 'master-revisions' ) {
  19. process.exit();
  20. }
  21. // ...and "push" builds...
  22. if ( process.env.TRAVIS_EVENT_TYPE !== 'push' ) {
  23. process.exit();
  24. }
  25. // ...and for builds that failed.
  26. if ( process.env.TRAVIS_TEST_RESULT == 0 ) {
  27. process.exit();
  28. }
  29. const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
  30. const slack = require( 'slack-notify' )( SLACK_WEBHOOK_URL );
  31. const GitHubApi = require( '@octokit/rest' );
  32. const github = new GitHubApi( {
  33. version: '3.0.0'
  34. } );
  35. const buildId = process.env.TRAVIS_JOB_NUMBER.split( '.' )[ 0 ];
  36. const buildUrl = process.env.TRAVIS_JOB_WEB_URL;
  37. const buildCommit = process.env.TRAVIS_COMMIT;
  38. const [ owner, repo ] = process.env.TRAVIS_REPO_SLUG.split( '/' );
  39. const commitUrl = `https://github.com/${ owner }/${ repo }/commit/${ buildCommit }`;
  40. const shortCommit = buildCommit.substring( 0, 7 );
  41. const execTime = getExecutionTime( parseInt( process.env.END_TIME ), parseInt( process.env.START_TIME ) );
  42. const message = `Build <${ buildUrl }|#${ buildId }> (<${ commitUrl }|${ shortCommit }>) of \
  43. ${ owner }/${ repo }@${ buildBranch } by [Author] errored \
  44. in ${ execTime.mins } min ${ execTime.secs } sec`;
  45. const messageOptions = {
  46. icon_url: 'https://a.slack-edge.com/66f9/img/services/travis_36.png',
  47. unfurl_links: 1,
  48. username: 'Travis CI',
  49. attachments: [
  50. {
  51. color: 'danger',
  52. }
  53. ]
  54. };
  55. slack.onError = err => {
  56. console.log( 'API error occurred:', err );
  57. };
  58. github.repos.getCommit( { owner, repo, sha: buildCommit } )
  59. .then( response => {
  60. messageOptions.attachments[ 0 ].text = message.replace( '[Author]', response.data.commit.author.name );
  61. } )
  62. .catch( () => {
  63. messageOptions.attachments[ 0 ].text = message.replace( 'by [Author] ', '' );
  64. messageOptions.attachments[ 0 ].pretext = '_Could not fetch an author of the commit._';
  65. } )
  66. .then( () => {
  67. slack.send( messageOptions );
  68. } );
  69. /**
  70. * @param {Number} endTime
  71. * @param {Number} startTime
  72. * @returns {Object}
  73. */
  74. function getExecutionTime( endTime, startTime ) {
  75. const execTime = {
  76. ms: endTime - startTime
  77. };
  78. execTime.days = Math.floor( execTime.ms / 86400 );
  79. execTime.hours = Math.floor( ( execTime.ms - 86400 * execTime.days ) / 3600 );
  80. execTime.mins = Math.floor( ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) / 60 );
  81. execTime.secs = ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) - 60 * execTime.mins;
  82. return execTime;
  83. }