notify-travis-status.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. */
  15. const buildBranch = process.env.TRAVIS_BRANCH;
  16. // Send a notification only for main branches...
  17. if ( buildBranch !== 'master' && buildBranch !== 'master-revisions' ) {
  18. process.exit();
  19. }
  20. // ...and "push" builds...
  21. if ( process.env.TRAVIS_EVENT_TYPE !== 'push' ) {
  22. process.exit();
  23. }
  24. // ...and for builds that failed.
  25. if ( process.env.TRAVIS_TEST_RESULT == 0 ) {
  26. process.exit();
  27. }
  28. const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
  29. const slack = require( 'slack-notify' )( SLACK_WEBHOOK_URL );
  30. const buildId = process.env.TRAVIS_JOB_NUMBER.split( '.' )[ 0 ];
  31. const buildUrl = process.env.TRAVIS_JOB_WEB_URL;
  32. const buildCommit = process.env.TRAVIS_COMMIT;
  33. const [ owner, repo ] = process.env.TRAVIS_REPO_SLUG.split( '/' );
  34. const commitUrl = `https://github.com/${ owner }/${ repo }/commit/${ buildCommit }`;
  35. const shortCommit = buildCommit.substring( 0, 7 );
  36. const execTime = getExecutionTime( parseInt( process.env.END_TIME ), parseInt( process.env.START_TIME ) );
  37. const messageOptions = {
  38. icon_url: 'https://a.slack-edge.com/66f9/img/services/travis_36.png',
  39. unfurl_links: 1,
  40. username: 'Travis CI',
  41. attachments: [
  42. {
  43. color: 'danger',
  44. fields: [
  45. {
  46. title: 'Branch',
  47. value: `<https://github.com/${ owner }/${ repo }/tree/${ buildBranch }|#${ buildBranch }>`,
  48. short: true
  49. },
  50. {
  51. title: 'Commit',
  52. value: `<${ commitUrl }|${ shortCommit }>`,
  53. short: true
  54. },
  55. {
  56. title: 'Build',
  57. value: `<${ buildUrl }|#${ buildId }>`,
  58. short: true
  59. },
  60. {
  61. title: 'Testing time',
  62. value: `${ execTime.mins } min ${ execTime.secs } sec`,
  63. short: true
  64. },
  65. {
  66. title: 'Commit message',
  67. value: getFormattedMessage( process.env.TRAVIS_COMMIT_MESSAGE, owner, repo ),
  68. short: false
  69. },
  70. ]
  71. },
  72. ]
  73. };
  74. slack.onError = err => {
  75. console.log( 'API error occurred:', err );
  76. };
  77. slack.send( messageOptions );
  78. /**
  79. * Returns an object that compares two dates.
  80. *
  81. * @param {Number} endTime
  82. * @param {Number} startTime
  83. * @returns {Object}
  84. */
  85. function getExecutionTime( endTime, startTime ) {
  86. const execTime = {
  87. ms: endTime - startTime
  88. };
  89. execTime.days = Math.floor( execTime.ms / 86400 );
  90. execTime.hours = Math.floor( ( execTime.ms - 86400 * execTime.days ) / 3600 );
  91. execTime.mins = Math.floor( ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) / 60 );
  92. execTime.secs = ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) - 60 * execTime.mins;
  93. return execTime;
  94. }
  95. /**
  96. * Replaces `#Id` and `Repo/Owner#Id` with URls to Github Issues.
  97. *
  98. * @param {String} message
  99. * @param {String} repoOwner
  100. * @param {String} repoName
  101. * @returns {string}
  102. */
  103. function getFormattedMessage( message, repoOwner, repoName ) {
  104. return message
  105. .replace( / #(\d+)/g, ( _, issueId ) => {
  106. return ` <https://github.com/${ repoOwner }/${ repoName }/issues/${ issueId }|#${ issueId }>`;
  107. } )
  108. .replace( /([\w-]+\/[\w-]+)#(\d+)/g, ( _, repoSlug, issueId ) => {
  109. return `<https://github.com/${ repoSlug }/issues/${ issueId }|${ repoSlug }#${ issueId }>`;
  110. } );
  111. }