notify-travis-status.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. // TODO: Remove Slack
  19. if ( buildBranch !== 'master' && buildBranch !== 'master-revisions' && buildBranch !== 'slack' ) {
  20. process.exit();
  21. }
  22. const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL;
  23. const slack = require( 'slack-notify' )( SLACK_WEBHOOK_URL );
  24. const GitHubApi = require( '@octokit/rest' );
  25. const github = new GitHubApi( {
  26. version: '3.0.0'
  27. } );
  28. const buildResult = process.env.TRAVIS_TEST_RESULT == 0;
  29. const messageColor = buildResult ? 'good' : 'danger';
  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 = {
  37. ms: parseInt( process.env.END_TIME ) - parseInt( process.env.START_TIME )
  38. };
  39. execTime.days = Math.floor( execTime.ms / 86400 );
  40. execTime.hours = Math.floor( ( execTime.ms - 86400 * execTime.days ) / 3600 );
  41. execTime.mins = Math.floor( ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) / 60 );
  42. execTime.secs = ( ( execTime.ms - 86400 * execTime.days ) - 3600 * execTime.hours ) - 60 * execTime.mins;
  43. const message = `Build <${ buildUrl }|#${ buildId }> (<${ commitUrl }|${ shortCommit }>) of \
  44. ${ owner }/${ repo }@${ buildBranch } by [Author] ${ buildResult ? 'passed' : 'errored' } \
  45. in ${ execTime.mins } min ${ execTime.secs } sec`;
  46. const messageOptions = {
  47. icon_url: 'https://a.slack-edge.com/66f9/img/services/travis_36.png',
  48. unfurl_links: 1,
  49. username: 'Travis CI',
  50. attachments: [
  51. {
  52. color: messageColor,
  53. }
  54. ]
  55. };
  56. slack.onError = err => {
  57. console.log( 'API error occurred:', err );
  58. };
  59. github.repos.getCommit( { owner, repo, sha: buildCommit } )
  60. .then( response => {
  61. messageOptions.attachments[ 0 ].text = message.replace( '[Author]', response.data.commit.author.name );
  62. } )
  63. .catch( () => {
  64. messageOptions.attachments[ 0 ].text = message.replace( 'by [Author] ', '' );
  65. messageOptions.attachments[ 0 ].pretext = '_Could not fetch an author of the commit._';
  66. } )
  67. .then( () => {
  68. slack.send( messageOptions );
  69. } );