The development of Open Source Software (OSS) projects is a collaborative process that heavily relies on active contributions by passionate developers. OSS projects are generally developed on social code-hosting platforms (e.g., GitHub or GitLab) which provide a set of tools to support the creation of software in a collaborative way. Creating, retaining and nurturing an active community of developers is a challenging task; and finding the appropriate expertise to drive the development process is not always easy.
To alleviate this situation, many OSS projects try to use bots to automate some development and colaboration tasks, thus helping community developers to cope with the daily workload of their projects.
Nevertheless, this has several drawbacks. To begin with, it involves manual coding and expertise on the different platform APIs. Bots are therefore platform-specific making it also very time-consuming to create any type of bot that needs to interact with projects deployed on several platforms (e.g., case of mirror repositories of projects). Furthermore, the bots are usually designed to fulfill automation tasks related to the code development, even though the community behind a project is more than just the code contributors and support for automatic community management would also be important to optimize project collaboration.
Modeling and running bots for open source projects
In this sense, we designed a tool to define and deploy bots for OSS projects. The tool includes an internal Domain-Specific Language (DSL) to define bots that can be deployed on different platforms, and that can be triggered by different events (e.g., creation of a new issue or a pull request). The set of events covered by the language is a superset of all events available on popular code-hosting platforms and their APIs, thus enabling users to define generic bots. Hence, we permit building bots in OSS in a way that is agnostic to the code-hosting platform.
With our approach, bots are defined independently with our platform-independent tool and then can be configured to interact with any specific code-hosting platform. The architecture of our proposal can be interpreted as:
As can be seen, the Tool Infrastructure includes the DSL definition and helper libraries to facilitate the definition of bots in an agnostic way (i.e., helpers provide constructs to efficiently and transparently access the code-hosting platform generically). The Runtime is responsible for listening and tracking the events in the code-hosting platforms, triggering the bots linked to those events and executing their behavior which in turn will call the connectors to interact with the corresponding code-hosting platform.
This proposal, with the title, “A Tool for the Definition and Deployment of Platform-Independent Bots on Open Source Projects” by Adem Ait, Javier Luis Cánovas Izquierdo and Jordi Cabot will be presented at SLE 2023. Keep reading to get the core idea, or get the full article.
Abstract & Concrete Syntax of our Bot Definition Language
To create the DSL, we defined its abstract and concrete syntax. The abstract syntax can be clearly organized in two main sublanguages, namely: OSS domain and bot. The former covers those key concepts of the domain (OSS community development, in our case) required to define bots in an agnostic way; while the latter defines the core language constructs to define the bots themselves.
To build the language domain, we explored existing code-hosting platforms and selected GitHub and GitLab to define a superset of features. The metamodel inferred from the analysis of the features and concepts of GitHub and Gitlab platforms is shown in the following figure:
As can be seen can be seen, the main element is the Repository class which represents the project, the central element of any code-hosting platform. Users are differentiated by their origin (i.e., users registered in the platform and users registered in the Git SCM). The rest are the elements provided by the platforms to facilitate the development of the project.
The part of the abstract syntax devoted to defining the core bot aspects of our DSL is presented as:
A BotDefinition represents a bot, which listens to a set of events of code-hosting platforms, defined by the Event class, and performs a set of actions, defined by the Behavior class. An Event has a condition (see Condition) which may query elements in the domain (see from association). The Behavior hierarchy
includes Executes and Creates, which may also query domain elements (superclass of all elements from the previous metamodel).
Regarding the concrete syntax, we designed our DSL as a textual language, and implemented it as an internal DSL in Java to leverage on the Java ecosystem and its existing libraries. As a textual language, the language definition is driven by a set of statements, which are identified by keywords. We relied on fluent interfaces using the method chaining pattern to enable the language statements. Its flow can be seen as:
The language currently includes five statements using the corresponding keywords: createBot, on, creates, executes, and validate. In the following, we present them following a function-based format (i.e., keyword name and parameters):
- createBot(name): It sets a name for the bot.
- on(event, condition): It defines the event and the optional conditional statement triggering the bot.
- creates(element): It specifies the domain element that must be created once an event triggers the bot.
- executes(code): It defines the bot behavior to be executed when it is triggered by an event. Unlike the previous statement, the executes statement accepts a lambda expression that must be executed as part of the bot behavior.
- validate(): It ends the definition of the bot and validates the bot definition.
To illustrate the use of our language, we show an example of a simple bot definition. We want to notify project contributors when a pull request is created without requested reviewers. To this, we will have to navigate into the OSS metamodel to select the elements required for defining this behaviour. The resulting DSL would be:
As it can be seen, we are using the elements presented in the tool architecture: helpers and connectors. The keywords must be declared in order, following the flow of the previous figure. The body of the keyword is defined using lambda expressions, leveraging Java, and to access to the elements of the OSS project we employ the helpers (i.e., DomainHelper), which it retrieves the OSS elements from the payload provided by the project’s platform.
This is a simple example to visualize the keywords definition, but this is a first step of a more ambitious vision towards providing every OSS project with a swarm of bots able to collaborate among them and with the community members to ensure the project’s long-term sustainability. Obviously, this simple example could also be directly coded with a platform-specific solution (such as GitHub actions) but our language, beyond being platform-agnostic (and even allowing for cross-platform bots!), will go beyond this simple scenarios. Stay tuned!