notify-travis-status.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #!/usr/bin/env node
  2. /**
  3. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  4. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  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. slack.onError = err => {
  46. console.log( 'API error occurred:', err );
  47. };
  48. slack.send( {
  49. icon_url: 'https://a.slack-edge.com/66f9/img/services/travis_36.png',
  50. unfurl_links: 1,
  51. username: 'Travis CI',
  52. attachments: [
  53. {
  54. color: 'danger',
  55. fields: [
  56. {
  57. title: 'Branch',
  58. value: `<https://github.com/${ owner }/${ repo }/tree/${ buildBranch }|#${ buildBranch }>`,
  59. short: true
  60. },
  61. {
  62. title: 'Commit',
  63. value: `<${ commitUrl }|${ shortCommit }>`,
  64. short: true
  65. },
  66. {
  67. title: 'Build',
  68. value: `<${ buildUrl }|#${ buildId }>`,
  69. short: true
  70. },
  71. {
  72. title: 'Testing time',
  73. value: `${ execTime.mins } min ${ execTime.secs } sec`,
  74. short: true
  75. },
  76. {
  77. title: 'Commit message',
  78. value: getFormattedMessage( process.env.TRAVIS_COMMIT_MESSAGE, owner, repo ),
  79. short: false
  80. },
  81. ]
  82. },
  83. ]
  84. } );
  85. /**
  86. * Returns an object that compares two dates.
  87. *
  88. * @param {Number} endTime
  89. * @param {Number} startTime
  90. * @returns {Object}
  91. */
  92. function getExecutionTime( endTime, startTime ) {
  93. const execTime = {
  94. ms: endTime - startTime
  95. };
  96. execTime.days = Math.floor( execTime.ms / 86400 );
  97. execTime.hours = Math.floor( ( execTime.ms - 86400 * execTime.days ) / 3600 );
  98. execTime.mins = Math.floor( ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) / 60 );
  99. execTime.secs = ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) - 60 * execTime.mins;
  100. return execTime;
  101. }
  102. /**
  103. * Replaces `#Id` and `Repo/Owner#Id` with URls to Github Issues.
  104. *
  105. * @param {String} message
  106. * @param {String} repoOwner
  107. * @param {String} repoName
  108. * @returns {string}
  109. */
  110. function getFormattedMessage( message, repoOwner, repoName ) {
  111. return message
  112. .replace( / #(\d+)/g, ( _, issueId ) => {
  113. return ` <https://github.com/${ repoOwner }/${ repoName }/issues/${ issueId }|#${ issueId }>`;
  114. } )
  115. .replace( /([\w-]+\/[\w-]+)#(\d+)/g, ( _, repoSlug, issueId ) => {
  116. return `<https://github.com/${ repoSlug }/issues/${ issueId }|${ repoSlug }#${ issueId }>`;
  117. } );
  118. }