notify-travis-status.js 3.7 KB

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