@graphql-inspector/action
Version:
GraphQL Inspector functionality for GitHub Actions
121 lines (120 loc) • 4.51 kB
JavaScript
import { __awaiter } from "tslib";
import { buildSchema } from 'graphql';
import { diff } from '@graphql-inspector/core';
import { createConfig, } from './helpers/config.js';
import { loadSources } from './helpers/loaders.js';
import { createLogger } from './helpers/logger.js';
import { notifyWithDiscord, notifyWithSlack, notifyWithWebhook } from './helpers/notifications.js';
export function handleSchemaChangeNotifications({ context, ref, repo, owner, before, loadFile, loadConfig, onError, release, action, }) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const id = `${owner}/${repo}#${ref}`;
const logger = createLogger('NOTIFICATIONS', context, release);
logger.info(`started - ${id}`);
logger.info(`action - ${action}`);
const isBranchPush = ref.startsWith('refs/heads/');
if (!isBranchPush) {
logger.warn(`Received Push event is not a branch push event (ref "${ref}")`);
return;
}
const rawConfig = yield loadConfig();
if (!rawConfig) {
logger.error(`Missing config file`);
return;
}
const branch = ref.replace('refs/heads/', '');
// eslint-disable-next-line @typescript-eslint/no-empty-function
const config = createConfig(rawConfig, () => { }, [branch]);
if (!config.notifications) {
logger.info(`disabled. Skipping...`);
return;
}
logger.info(`enabled`);
if (config.branch !== branch) {
logger.info(`Received branch "${branch}" doesn't match expected branch "${config.branch}". Skipping...`);
return;
}
const oldPointer = {
path: config.schema,
ref: before,
};
const newPointer = {
path: config.schema,
ref,
};
const sources = yield loadSources({
config,
oldPointer,
newPointer,
loadFile,
});
const schemas = {
old: buildSchema(sources.old, {
assumeValid: true,
assumeValidSDL: true,
}),
new: buildSchema(sources.new, {
assumeValid: true,
assumeValidSDL: true,
}),
};
logger.info(`built schemas`);
const changes = yield diff(schemas.old, schemas.new);
if (!changes.length) {
logger.info(`schemas are equal. Skipping...`);
return;
}
const notifications = config.notifications;
function actionRunner(target, fn) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield fn();
}
catch (error) {
onError(error);
logger.error(`Failed to send a notification via ${target}`, error);
}
});
}
if (hasNotificationsEnabled(notifications)) {
const actions = [];
const commit = (_b = (_a = context.payload.commits) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.id;
if (notifications.slack) {
actions.push(actionRunner('slack', () => notifyWithSlack({
url: notifications.slack,
changes,
environment: config.name,
repo,
owner,
commit,
})));
}
if (notifications.discord) {
actions.push(actionRunner('discord', () => notifyWithDiscord({
url: notifications.discord,
changes,
environment: config.name,
repo,
owner,
commit,
})));
}
if (notifications.webhook) {
actions.push(actionRunner('webhook', () => notifyWithWebhook({
url: notifications.webhook,
changes,
environment: config.name,
repo,
owner,
commit,
})));
}
if (actions.length) {
yield Promise.all(actions);
}
}
});
}
function hasNotificationsEnabled(notifications) {
return notifications && typeof notifications === 'object';
}