/* eslint-disable no-unused-vars */ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only exports.id = "plugin_template"; // Cherry-pick bot requires using the "require()" function to load any modules, // rather than the "import" statement. const config = require("./config.json"); // Non-instanced modules can be loaded directly. const gerritTools = require("../../gerritRESTTools"); // Set default values with the config file, but prefer environment variable. function envOrConfig(ID) { return process.env[ID] || config[ID]; } // If you need to use a custom username/password for gerrit, you can set them // here. Otherwise, the default cherry-pick-bot credentials will be used. const customAuth = { username: envOrConfig("MY_BOT_USER"), password: envOrConfig("MY_BOT_PASS") } // This defines the class that will be instantiated by the notifier. // The notifier will pass itself as the only argument to the constructor. // This allows the plugin to access the notifier's properties and methods. class plugin_template { constructor(notifier) { this.notifier = notifier; // /notifier.js this.logger = notifier.logger; // /logger.js this.retryProcessor = notifier.retryProcessor; // /retryProcessor.js this.requestProcessor = notifier.requestProcessor; // /requestProcessor.js // This line binds our local processPatch function to the // the `this` context of this class. This is necessary because we will // be passing this function to the server as a callback, and we want // to be able to access the class's properties and methods from within // the callback. this.processPatch = this.processPatch.bind(this); // This call to registerCustomListener binds our local processPatch // function to the "integration_monitor_process_patch" event, emitted by // 'server'. When the event is emitted, our function will be called with // any arguments passed by the "emit()" call. notifier.registerCustomListener(notifier.server, "integration_monitor_process_patch", this.processPatch); // This call to registerCustomEvent tells the server to call the inline // callback when it receives a "patchset-created" event. The callback will // always be called with the request object (incoming change data from // codereview as its only argument). notifier.server.registerCustomEvent("integration_monitor_entryPoint", "patchset-created", (req) => { // Use an arrow function to preserve the "this" context. // Do some trivial checks to see if we should do anything. if (req.change.status == "MERGED") return; // The CI created a new patchset upon change merge. Don't do anything. // Check to see if a real person uploaded the last patchset. let uploader = req.uploader.email; let pickbotIsUploader = (uploader == "cherrypick_bot@qt-project.org"); if (req.change.owner.email != "cherrypick_bot@qt-project.org" && !pickbotIsUploader) { // A real user is the uploader. // Emit the internal event we registered above. This will call our // processPatch function with the req and uploader arguments. notifier.server.emit("integration_monitor_process_patch", req, uploader); } } ); } // This is the callback function that will be called when the // "integration_monitor_process_patch" event is emitted in the event handling above. processPatch(req, uploader) { this.logger.log( `Received patchset-created by ${uploader} for cherry-picked change in ${req.change.project}`, "info", req.uuid ); // Patchset-created does not include a full change ID. Assemble one. This is needed // for avoiding conflicts in gerrit where the same change ID exists on multiple branches. req.fullChangeID = encodeURIComponent(`${req.change.project}~${req.change.branch}~${req.change.id}`); req.change.fullChangeID = req.fullChangeID; // Dip into gerritTools to get some change details. gerritTools.getChangeReviewers(req.uuid, req.change.fullChangeID, customAuth, (success, reviewers) => { if (success) this.logger.log(`Reviewers: ${reviewers}`, "info", req.uuid); else this.logger.log(`Failed to get reviewers for ${req.change.fullChangeID}`, "error", req.uuid); } ); } } module.exports = plugin_template;