Skip to content

Commit

Permalink
Merge pull request #900 from ckeditor/ck/14330
Browse files Browse the repository at this point in the history
Feature (ci): Added a script to send a notification on a Slack channel from CircleCI. Closes ckeditor/ckeditor5#14330.
  • Loading branch information
pomek authored Jul 7, 2023
2 parents 06be76a + ec8b43d commit 208e8b9
Show file tree
Hide file tree
Showing 9 changed files with 432 additions and 329 deletions.
120 changes: 120 additions & 0 deletions packages/ckeditor5-dev-ci/bin/notify-circle-status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env node

/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* eslint-env node */

const formatMessage = require( '../lib/format-message' );
const slackNotify = require( 'slack-notify' );

// This script assumes that is being executed on Circle CI.
// Step it is used on should have set value: `when: on_fail`, since it does not
// check whether the build failed when determining whether the notification should be sent.
// Described environment variables starting with "CKE5" should be added by the integrator.

const {
/**
* Required. Token to a Github account with the scope: "repos". It is required for obtaining an author of
* the commit if the build failed. The repository can be private and we can't use the public API.
*/
CKE5_GITHUB_TOKEN,

/**
* Required. CircleCI API token used for obtaining data about the build from API.
*/
CKE5_CIRCLE_TOKEN,

/**
* Required. Webhook URL of the Slack channel where the notification should be sent.
*/
CKE5_SLACK_WEBHOOK_URL,

/**
* Optional. If both are defined, the script will use the URL as the commit URL.
* Otherwise, URL will be constructed using current repository data.
*/
CKE5_TRIGGER_REPOSITORY_SLUG,
CKE5_TRIGGER_COMMIT_HASH,

/**
* Optional. If set to "true", commit author will be hidden.
* See: https://github.com/ckeditor/ckeditor5/issues/9252.
*/
CKE5_SLACK_NOTIFY_HIDE_AUTHOR,

// Variables that are available by default in Circle environment.
CIRCLE_BRANCH,
CIRCLE_BUILD_NUM,
CIRCLE_BUILD_URL,
CIRCLE_PROJECT_REPONAME,
CIRCLE_PROJECT_USERNAME,
CIRCLE_SHA1
} = process.env;

notifyCircleStatus();

async function notifyCircleStatus() {
if ( !CKE5_GITHUB_TOKEN ) {
throw new Error( 'Missing environment variable: CKE5_GITHUB_TOKEN' );
}

if ( !CKE5_SLACK_WEBHOOK_URL ) {
throw new Error( 'Missing environment variable: CKE5_SLACK_WEBHOOK_URL' );
}

const jobData = await getJobData();

const message = await formatMessage( {
slackMessageUsername: 'Circle CI',
iconUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Circleci-icon-logo.svg/475px-Circleci-icon-logo.svg.png',
repositoryOwner: CIRCLE_PROJECT_USERNAME,
repositoryName: CIRCLE_PROJECT_REPONAME,
branch: CIRCLE_BRANCH,
jobUrl: CIRCLE_BUILD_URL,
jobId: CIRCLE_BUILD_NUM,
githubToken: CKE5_GITHUB_TOKEN,
triggeringCommitUrl: getTriggeringCommitUrl(),
startTime: Math.ceil( ( new Date( jobData.started_at ) ).getTime() / 1000 ),
endTime: Math.ceil( ( new Date() ) / 1000 ),
shouldHideAuthor: CKE5_SLACK_NOTIFY_HIDE_AUTHOR === 'true'
} );

return slackNotify( CKE5_SLACK_WEBHOOK_URL )
.send( message )
.catch( err => console.log( 'API error occurred:', err ) );
}

async function getJobData() {
const fetchUrl = [
'https://circleci.com/api/v2/project/gh',
CIRCLE_PROJECT_USERNAME,
CIRCLE_PROJECT_REPONAME,
'job',
CIRCLE_BUILD_NUM
].join( '/' );

const fetchOptions = {
method: 'GET',
headers: { 'Circle-Token': CKE5_CIRCLE_TOKEN }
};

const rawResponse = await fetch( fetchUrl, fetchOptions );
return rawResponse.json();
}

function getTriggeringCommitUrl() {
let repoSlug, hash;

if ( CKE5_TRIGGER_REPOSITORY_SLUG && CKE5_TRIGGER_COMMIT_HASH ) {
repoSlug = CKE5_TRIGGER_REPOSITORY_SLUG;
hash = CKE5_TRIGGER_COMMIT_HASH;
} else {
repoSlug = [ CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME ].join( '/' );
hash = CIRCLE_SHA1;
}

return [ 'https://github.com', repoSlug, 'commit', hash ].join( '/' );
}
112 changes: 112 additions & 0 deletions packages/ckeditor5-dev-ci/bin/notify-travis-status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env node

/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* eslint-env node */

const formatMessage = require( '../lib/format-message' );
const slackNotify = require( 'slack-notify' );

const ALLOWED_BRANCHES = [
'stable',
'master'
];

const ALLOWED_EVENTS = [
'push',
'cron',
'api'
];

// This script assumes that is being executed on Travis CI.
// Described environment variables should be added by the integrator.

const {
/**
* POSIX timestamps created when the script has begun and ended the job.
* Timestamps should be in seconds instead of milliseconds.
*/
START_TIME,
END_TIME,

/**
* Token to a Github account with the scope: "repos". It is required for obtaining an author of
* the commit if the build failed. The repository can be private and we can't use the public API.
*/
GITHUB_TOKEN,

/**
* Required. Webhook URL of the Slack channel where the notification should be sent.
*/
SLACK_WEBHOOK_URL,

/**
* Optional. If defined, the script will use the URL as the commit URL.
* Otherwise, URL will be constructed using current repository data.
*/
SLACK_NOTIFY_COMMIT_URL,

/**
* Optional. If set to "true", commit author will be hidden.
* See: https://github.com/ckeditor/ckeditor5/issues/9252.
*/
SLACK_NOTIFY_HIDE_AUTHOR,

// Variables that are available by default in Travis environment.
TRAVIS_BRANCH,
TRAVIS_COMMIT,
TRAVIS_EVENT_TYPE,
TRAVIS_JOB_NUMBER,
TRAVIS_JOB_WEB_URL,
TRAVIS_REPO_SLUG,
TRAVIS_TEST_RESULT
} = process.env;

notifyTravisStatus();

async function notifyTravisStatus() {
// Send a notification only for main branches...
if ( !ALLOWED_BRANCHES.includes( TRAVIS_BRANCH ) ) {
console.log( `Aborting slack notification due to an invalid branch (${ TRAVIS_BRANCH }).` );

process.exit();
}

// ...and an event that triggered the build is correct...
if ( !ALLOWED_EVENTS.includes( TRAVIS_EVENT_TYPE ) ) {
console.log( `Aborting slack notification due to an invalid event type (${ TRAVIS_EVENT_TYPE }).` );

process.exit();
}

// ...and for builds that failed.
if ( TRAVIS_TEST_RESULT == 0 ) {
console.log( 'The build did not fail. The notification will not be sent.' );

process.exit();
}

const [ repositoryOwner, repositoryName ] = TRAVIS_REPO_SLUG.split( '/' );

const message = await formatMessage( {
slackMessageUsername: 'Travis CI',
iconUrl: 'https://a.slack-edge.com/66f9/img/services/travis_36.png',
repositoryOwner,
repositoryName,
branch: TRAVIS_BRANCH,
jobUrl: TRAVIS_JOB_WEB_URL,
jobId: TRAVIS_JOB_NUMBER,
githubToken: GITHUB_TOKEN,
triggeringCommitUrl: SLACK_NOTIFY_COMMIT_URL || `https://github.com/${ TRAVIS_REPO_SLUG }/commit/${ TRAVIS_COMMIT }`,
startTime: Number( START_TIME ),
endTime: Number( END_TIME ),
shouldHideAuthor: SLACK_NOTIFY_HIDE_AUTHOR === 'true'
} );

return slackNotify( SLACK_WEBHOOK_URL )
.send( message )
.catch( err => console.log( 'API error occurred:', err ) );
}
88 changes: 0 additions & 88 deletions packages/ckeditor5-dev-ci/bin/notifytravisstatus.js

This file was deleted.

3 changes: 3 additions & 0 deletions packages/ckeditor5-dev-ci/lib/data/bots.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"CKTravisBot"
]
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
"ldrobnik": "U04DJ7B7ZCJ",
"LukaszGudel": "U01FRHAT8T1",
"mabryl": "U045033D401",
"Mgsy": "U5A38S2PN",
"martnpaneq": "U045B560E00",
"mabryl": "U045033D401",
"Mgsy": "U5A38S2PN",
"mlewand": "U03UQQ1N3",
"mmotyczynska": "U02NSTQCTB8",
"mremiszewski": "U04ACUBMDGT",
Expand All @@ -31,6 +30,5 @@
"pszczesniak": "U04167FKV88",
"Reinmar": "U03UQRP0C",
"scofalik": "U05611ZMM",
"wwalc": "U03UQQ8PY",
"CKTravisBot": "CKTravisBot"
"wwalc": "U03UQQ8PY"
}
Loading

0 comments on commit 208e8b9

Please sign in to comment.