Als ontwikkelaars willen we vooral bezig zijn met het schrijven van toffe code. Helaas zijn we een flink deel van onze tijd kwijt aan allerlei saaie randzaken. In dit artikel nemen we daarom het Atomist platform onder de loep. Atomist neemt een groot deel van het saaie werk voor zijn rekening, zodat jij je weer kan concentreren op wat je leuk vindt: gave code schrijven!
Michel Schudel
Hoeveel uur per dag ben je nu eigenlijk bezig met het daadwerkelijk leveren van toegevoegde waarde voor je klanten? Naast coderen ben je bezig met het onderhouden van je build pipeline, het upgraden van library dependencies over meerdere componenten, het met terugwerkende kracht integreren van die nieuwe NoSQL store in elk component van je project, het heen en weer switchen van je IDE naar chat naar webbrowser, ad inifinitum. Behalve dat die werkzaamheden vaak saai zijn, heb je elke keer weer te maken met een context switch. Elke keer dat je terugkeert naar je IDE, moet je weer even ‘op gang’ komen.
Atomist
Atomist (https://atomist.com), bedacht door Rod “Spring Framework” Johnson, is een platform dat ontwikkelwerk vergaand automatiseert. Zelf automatiseren we natuurlijk al veel in onze buildstraten, maar sommige taken zijn lastiger te automatiseren. Denk aan library upgrades, de daarbij benodigde code-wijzigingen, het sluiten van issues wanneer fixes zijn uitgerold naar productie of een rollback op productie wanneer die mooie nieuwe feature toch onverwachts problemen geeft.
De belangrijkste onderdelen van Atomist zijn:
• Single point of interaction om context switches tegen te gaan.
• Automatisering van bekende werkzaamheden als issue tracking, het opzetten van nieuwe componenten en wijzigingen op bestaande code.
• Project context-awareness. Atomist is op de hoogte van de context van het project, bijvoorbeeld de architectuur, procesafspraken en de gebruikte programmeertalen.
• API voor het schrijven van je eigen automatiseringscode.
Architectuur
Een overzicht van de globale werking van Atomist vind je in afbeelding 1.
Afbeelding 1: werking van Atomist
De belangrijkste onderdelen van Atomist zijn:
• Atomist Bot. Deze Slack Bot is je toegangspunt tot Atomist en is je single point of interaction. Via de bot stuur je commando’s naar Atomist om taken uit te voeren, zoals het genereren van een project, het vastleggen van een issue in GitHub of het starten van een build in je build server. De Bot biedt tweerichtingsverkeer: je kunt notificaties die vanuit je buildstraat binnenkomen, ook direct zien. Omdat alles in Slack samenkomt, neemt interactie weinig tijd in beslag en blijf je beter in je workflow zitten.
• Automation clients. Elk Bot commando start een automation client. Dit is een TypeScript-applicatie die één specifieke automatiseringstaak implementeert. Naast aanroepen van meegeleverde clients kan je ook zelf clients schrijven.
• Het platform zelf draait in de cloud en wordt ontsloten door een API. Automation clients communiceren met Atomist via deze API door het sturen van commands en het ontvangen van events.
• De tooling in je buildstraat wordt door Atomist aangestuurd. Om wijzigingen te kunnen maken, moet Atomist geautoriseerd worden tot bijvoorbeeld je Git repositories. Dit wordt tijdens de installatie geregeld. Omgekeerd worden http callbacks (webhooks) gebruikt om Atomist op de hoogte te stellen van events.
Installatie
Via de website van Atomist installeer je een Bot in Slack. Je kunt dan direct aan de slag. De Slack Bot @atomist zorgt voor communicatie met het platform. Je nodigt deze uit in het Slack channel met het commando:
/invite @atomist
Daarna kan je met het commando:
@atomist help
alle commando’s opvragen. De opties die je dan krijgt, zijn out-of-the-box automation clients. Een paar voorbeelden:
• create issue. Maakt een nieuw issue aan in GitHub.
• list skills. Geeft een uitgebreide lijst van alle ingebouwde automation clients die aanwezig zijn.
• repo. Koppelt een GitHub repository aan het huidige Slack channel. Eventuele notificaties van GitHub zullen dan in dat channel verschijnen.
Afbeelding 2: interactie met Atomist in Slack
Zie een interactie voorbeeld in Afbeelding 2. Hier zijn de volgende zaken te zien:
• Atomist is als Slack Bot actief in het channel #devstuff.
• Met de opdracht @atomist generate springboot-rest wordt een generator automation client gestart die een nieuwe Spring Boot-applicatie genereert. De conversatie over de details, zoals root package, target repository en dergelijke, staat rechts in de conversatie thread.
Generators
Een generator is een automation client die op basis van een aantal parameters nieuwe code voor je genereert. Nu is dit op zich niet zo bijzonder; een tool als Spring Initializr (https://start.spring.io/) kan dit ook. Deze tools zijn meestal template-based. Op dat punt onderscheidt Atomist zich: Generators werken altijd op basis van een seed, wat een werkend prototype is. Op dit prototype worden vervolgens een aantal transformaties losgelaten om zo tot jouw specifieke project te komen. Een Atomist generator bestaat dan ook altijd uit werkende code én transformatieregels.
Listing 1: generator voor het genereren van een Spring Boot applicatie
De transformatieregels van de Spring Boot generator staan in listing 1 (hier te vinden). De Spring Boot seed staat in een andere repository en is hier weggelaten. Een paar interessante transformaties in deze generator:
• doUpdatePom (met de parameters die via Slack aan de gebruiker zijn gevraagd) – zorgt voor invulling van een Maven pom.
• inferStructureAndMovePackage – zorgt voor transformatie van het standaard package in de seed naar jouw eigen root package, meegegeven via de rootPackage parameter (te zien in Afbeelding 2).
Het voordeel van generatie op basis van een werkend prototype is duidelijk. Je prototype is je werkende referentie-architectuur. Je maakt daar wijzigingen in. Vervolgens gebruik je Atomist om op basis van de nieuwste inzichten nieuwe projecten te starten… of te wijzigen. Dit laatste doe je met een ander soort automation client, genaamd een editor.
Editors
Niet-triviale code-wijzigingen op meerdere plekken tegelijk is meestal handwerk. Om dit te automatiseren gebruikt Atomist editors, automation clients die bestaande code transformeren. Denk aan het upgraden van library-versies over meerdere subprojecten of het verwijderen van onnodige code. Een voorbeeld van dit laatste staat in listing 2. Deze out-of-the-box editor spoort alle Spring beans op en verwijdert de @Autowired annotatie van de default constructor als dat de enige constructor op die bean is.
Listing 2: editor voor verwijderen van overbodige annotaties in een Spring applicatie
De editor bestaat uit twee delen:
• De actie: in dit geval verwijderen van constructors met de functie removeAutowiredOnSoleConstructor. Je ziet hier Java termen gebruikt worden als JavaSourceFiles en Constructors; deze editor is language-aware en maakt gebruik van de Abstract Syntax Tree (AST) van Java. Je kan dus wijzigingen in je code maken zonder allerlei lastige string parsing. En er zijn ook parsers voor andere talen als Kotlin en TypeScript.
• Definitie van een command handler, in dit geval removeAutowiredOnSoleConstructorCommand. Dit zorgt voor de integratie met Slack; door de Atomist bot in Slack de opdracht
@atomist remove unnecessary autowired
te geven (de intent property verwijst naar de naam van het commando) start je deze editor. Voor de complete code verwijzen we naar het Spring automation project in de referenties.
Je eigen automation clients bouwen
Tot nu toe hebben we alleen twee out-of-the-box automation clients gezien. Het creëren van je eigen automation client is eenvoudig. Geef Atomist in Slack de opdracht:
@atomist generate automation
Dit zet een out-of-the-box generator aan het werk die in een nieuwe GitHub repository de basis voor jouw nieuwe automation client neerzet. Het project kun je nu clonen en bouwen met npm install. Het resultaat dat in de repository landt, staat in listing 3.
Listing 3: gegenereerde automation client
Deze client haalt op basis van een GraphQL query (“graphql/person”), getoond in listing 4, extra informatie op over de gebruiker die de client aanroept. Hierna checkt de client of deze persoon inderdaad bekend is in Slack. Als laatste stap wordt de messageClient API aangeroepen met een bericht “Hello…” met daarin de naam die als parameter meegegeven is, samen met de voor- en achternaam van de gebruiker die het commando @atomist hello <name> heeft gegeven.
GraphQL is een querytaal die Atomist gebruikt om met je buildstraat te praten. In de query in listing 4 worden de variabelen $teamId en $slackUser gebruikt om meer informatie uit Slack te halen over de gebruiker die de hello automation client heeft aangeroepen. Voor meer informatie over de mogelijkheden van GraphQL, zie de tutorial op de GraphQL-site.
Listing 4: GraphQL query graphql/person
Je start de automation client lokaal met npm start. De automation client registreert zichzelf als skill op jouw Slack channels via security tokens. Die bepreken we hier verder niet, maar op de site van Atomist worden deze uitgebreid besproken. Clients kunnen ook draaien in Cloud Foundry, of in een Docker container.
Events
Er zijn ook gebeurtenissen in je buildstraat die geen gevolg zijn van een commando van een gebruiker, maar die plaatsvinden door een extern event. Event handlers zijn automation clients die dergelijke events afhandelen.
Listing 5: event handler
In listing 5 staat een event handler die als gevolg van een GitHub push event een notificatie naar Slack stuurt. Met een GraphQL event (verwijzing via “graphql/push”, vergelijkbaar met de GraphQL query in listing 4) stelt de eerdergenoemde messageClient API het Slack channel op de hoogte met een notificatie.
Tot besluit
De highlights nog even samengevat:
• Atomist ondersteunt het automatiseren van ontwikkeltaken waarvoor tot nu toe nog geen hapklare tools waren.
• Dankzij 1 point of interaction (Slack) brengt de focus terug en reduceert het voortdurend switchen van context.
• Atomist versnelt het genereren van nieuwe projecten op basis van werkende code.
• Het biedt een groot aantal out-of-the-box automation clients voor issue management en veel voorkomende code-wijzigingen.
• Biedt een TypeScript-based programming model voor je eigen automatisering.
Een uitgebreide lijst met op dit moment ondersteunde buildstraat tools is te vinden hier.
Referenties
Atomist platform en documentatie
Spring automation project
Custom editor voorbeeld
Jessica Kerr, “develop your development automation”