Joel on Software

Joel on Software   Joel over Software

 

Andere "Joel on Software" artikelen in het Nederlands

Andere "Joel on Software" artikels in het Engels

Email de auteur (uitsluitend in het Engels)

 

Dagelijkse builds zijn je vriend


Door Joel Spolsky
Vertaald door Bernard Vander Beken
27 january 2001

In 1982 ontving mijn familie de allereerste IBM-PC in Israël. We gingen werkelijk naar het warenhuis om te wachten terwijl onze PC uit de laadzone geleverd werd.  Op de een of andere manier wist ik mijn vader te overtuigen de volledig uitgeruste versie aan te schaffen, met twee floppy disks, 128 K geheugen, en zowel een dot-matrix printer (voor snelle proefdrukken) als eenBrother typemachine-kwaliteit  letterwiel printer, die net als een machinegeweer klinkt tijdens het gebruik, maar dan luider. Ik geloof dat we zowat alle beschikbare toebehoren genomen hadden: PC-DOS 1.0, de $75 technische handleiding met een listing van de volledige BIOS-broncode, Macro Assembler, en het wonderbaarlijke IBM monochroom scherm met maar liefst 80 kolommen en ... kleine letters! Het geheel koste zo'n $10,000 inclusief Israel's toen belachelijke invoerrechten. Extravagant!

Nu wist "iedereen" dat BASIC een speelgoedtaal was die het gebruik van spaghetticode vereist en je brein reduceert tot Camembert kaas.  Dus betaalden we $600 voor IBM Pascal, die op drie floppy diskettes geleverd werd. De compiler's eerste pass stond op de eerste diskette, the tweede pass op de tweede diskette, en de linker op de derde diskette. Ik schreef een eenvoudig "hello, world" programma en compileerde het. Totaal verstreken tijd: 8 minuten.

Hmm. Dat is lang. Ik schreef een batch file om het proces te automatiseren en and beperkte het naar zeveneneenhalve minuten. Beter zo. Maar wanneer ik lange programma's probeerde te schrijven, zoals mijn verbazende versie van Othello die altijd van me won, ging de meeste tijd naar het wachten op de compilatie. "Tja," vertelde een professionele programmeur me, "we hadden een sit-up hoek op kantoor en deden sit-ups tijdens de compilatie. Na enkele maanden programmeren had ik indrukwekkende buikbspieren."

Op een dag verscheen Compas Pascal, een ingenieus programma uit Denemarken.  Philippe Kahn kocht het en herdoopte het Borland Turbo Pascal. Turbo Pascal was baanbrekend, aangezien het alles deed wat IBM Pascal kon, maar slechts 33K geheugen gebruikte inclusief de text editor. Dit was ronduit verbazingwekkend. Nog verbazingwekkender was dat je een klein programma kon compileren in minder dan één seconde. Het is alsof een bedrijf waar je nog nooit van gehoord had een kopie van de Ferrari Testarossalanceerde die 1.000.000 km/h deed en de wereld rond kon rijden met zo weinig benzine dat een mier het op zou krijgen zonder ziek te worden.

Plotseling werd ik heel wat productiever.

Ik begreep toen het concept van de LET lus. LET staat voor "Lees, Evalueer, Toon", en het beschrijft wat een list interpreter doet: het "leest" je invoer, evalueert het en toont het resultaat. Een voorbeeld van de LET lus wordt hieronder getoond: Ik typ iets en de lisp interpreter leest het, evalueert het en toont het resultaat.

picture-reploop:

Op een iets hoger niveau ben je in een macro-versie van de LET lus wanneer je code schrijft. Het wordt dan de Bewerk-Compileer-Test lus genoemd. Je bewerkt je code, compileert het, test het en kijkt hoe goed het werkt.

Een cruciaal punt is dat je de lus telkens weer moet doorlopen om een programma te schrijven.  Het gevolg is dat hoe sneller de Bewerk-Compileer-Test lus verloopt, hoe productiever je wordt, tot aan een natuurlijke limiet van ogenblikkelijke compilaties. Dat is de formele, computer-wetenschappelijke reden dat programmeurs bijzonder snelle hardware wensen en compiler-ontwikkelaars alles doen wat ze kunnen om supersnelle Bewerk-Compileer-Test lussen te verkrijgen. Visual Basic doet het door elke ingetypte lijn gaandeweg te parsen en lex-en, zodat de uiteindelijke compilatie supersnel kan gebeuren. Visual C++ doet het door incrementele compilatie te voorzien, geprecompileerde headers en incrementeel linken.

Maar zodra je in een groter team werkt met meerdere ontwikkelaars en testers, zie je opnieuw de zelfde lus, maar dan groter (het is fractal, kerel!). Een tester vindt een bug in de code en rapporteert de bug. De programmeur lost de bug op. Hoe lang duurt het vooraleer de tester de aangepaste code krijgt? In sommige software-organisaties kan deze Rapporteer-Los op-Controleer lus enkele weken duren, waardoor de hele organisatie onproductief is. Om het hele ontwikkelingsproces vlot te doen verlopen, moet je je aandacht besteden aan het inkorten van de Rapporteer-Los op-Controleer lus.

Een goede aanpak zijn dagelijkse builds. Een dagelijkse build is een automatische, dagelijkse, volledige build van alle broncode.

Automatisch - omdat je ervoor zorgt dat de code elke dag op een vastgelegd tijdstip gecompileerd wordt, met cron jobs (op UNIX) of de Scheduler Service (op Windows).

Dagelijks - of zelfs vaker. Het is verleidelijk om continu builds te laten lopen, maar dat is waarschijnlijk niet mogelijk wegens versiebeheer problemen waar ik het straks zal over hebben.

Volledig - het is mogelijk dat je code meerdere versies heeft. Meerdere talen, meerdere besturingssystemen, of een high-end/low-end versie. De dagelijkse build moet ze allemaal builden. En het moet elke file vanaf nul builden, zonder gebruik te maken van de mogelijkerwijs imperfecte incrementele build mogelijkheden van de compiler.

Hier zijn enkele van de vele voordelen van dagelijkse builds:

  1. Wanneer een bug opgelost is, kunnen testers snel de aangepaste versie testen om te controleren of de bug effectief is opgelost.
  2. Ontwikkelaars kunnen zich geruster voelen dat een wijziging niet één van de 1024 variaties van het systeem breekt, zonder dat ze een OS/2 machine in de buurt hebben om te testen.
  3. Ontwikkelaars die hun wijzigingen net voor de geplande dagelijkse build aanpassen in het versiebeheersysteem, weten dat ze niet voor alle andere collega's de "build zullen breken" -- dat wil zeggen, iets wijzigen waardoor niemand nog kan compileren. Dit komt overeen met een "Blue Screen of Death" voor een volledig ontwikkelingsteam, en gebeurt vaak wanneer een programmeur een nieuw bestand vergeet toe te voegen aan het versiebeheersysteem. De build werkt goed op hun machines, maar wanneer een ander de code ophaalt krijgen ze linker-fouten en kunnen niets meer verder ontwikkelen.
  4. Externe groepen zoals marketing, beta sites voor klanten, etc. die een onafgewerkt product moeten gebruiken, kunnen een relatief stabiele build kiezen en die gedurende een tijd blijven gebruiken.
  5. Een archief van alle dagelijkse builds bijhouden heeft nog een voordeel. Wanneer je een werkelijk bizarre bug ontdekt en je vindt de oorzaak niet, dan kan je binair zoeken in het archief naar het moment waarop de bug voor het eerst verscheen. In combinatie met degelijk versiebeheer, kan je wellicht nagaan welke code-update het probleem veroorzaakte.
  6. Wanneer een tester een probleem rapporteert waarvan de programmeur denkt dat het opgelost is, dan kan de tester zeggen in welke build het probleem zich voordeed.  Vervolgens kijkt de programmeur wanneer het probleem aangepakt werd om te bepalen of het werkelijk opgelost is.

Zo ga je te werk. Je hebt een dagelijkse build server nodig, wellicht de snelste computer die je te pakken kan krijgen. Schrijf een script dat eerst een volledige kopie van de actuele broncode uit je versiebeheersysteem ophaalt (je gebruikt toch versiebeheer, of niet soms?).  Vervolgens doet het script vanaf nul een build van elke versie van je code die je levert. Indien je een installatie-programma hebt, voeg het toe aan de build. Alles wat je naar klanten stuurt zou door de dagelijkse build aangemaakt moeten worden. Plaats elke build in een aparte directory op basis van de datum. Voer je script elke dag op een vast tijdstip uit.

  • Het is cruciaal dat alles wat nodig is voor de definitieve build uitgevoerd wordt door het dagelijkse build script, gaande van het ophalen van de code uit versiebeheer tot en met het online plaatsen van de software op een web server zodat het publiek het kan afhalen (ook al zal dit uiteraard een test server zijn tijdens de ontwikkeling). Dit is de enige manier om te garanderen dat er niets is over het build-proces dat slechts "gedocumenteerd" is in het hoofd van één persoon. Je krijg nooit de situatie waar je een product niet kunt uitbrengen omdat enkel Shaniqua weet hoe de installer gemaakt wordt en ze door een bus werd aangereden. Op het Juno team moest je slechts het volgende weten om een volledige build vanaf nul te starten: waar de build server was, en hoe je moest dubbelklikken op het "Dagelijkse Build" icoontje.
  • Er is niets erger voor je gezondheid dan het volgende: je probeert je code op te leveren en er is nog een klein bugje.  Dus je lost het bugje op op de dagelijkse build server zelf zelf en levert het.  De gulden regel zegt: lever enkel code die door een volledige build vanaf nul werd gemaakt, op basis van de volledige code uit versiebeheer.
  • Stel je compilers in zodat ze het maximum aan waarschuwingen geven (-W4 in de Microsoft wereld; -Wall in gcc-land) en zorg dat ze stoppen bij de geringste waarschuwing.
  • Indien een dagelijkse build gebroken is, riskeer je het hele team stil te leggen. Stop alles en build opnieuw tot het probleem opgelost is. Er zijn dagen waar je meerdere dagelijkse builds kunt hebben.
  • Je dagelijkse build mailt best foutrapporten naar het volledige team van ontwikkelaars.  Het is niet moeilijk om de logs te doorzoeken naar "error" of "warning" en die informatie in de mail te voegen. Het script kan ook een statusrapport toevoegen aan een site die zichtbaar is voor iedereen.  Zo kunnen programmeurs en testers snel bepalen welke builds succesvol waren.
  • Een regel die we in het Microsoft Excel team met spectaculair effect toepasten: de persoon die de build brak werd babysitter van de build totdat iemand anders die brak.  Het was een slimme aanmoediging om de build draaiend te houden.  Daarnaast zorgde het ervoor dat zowat iedereen eens de job als buildmaster kreeg, zodat iedereen leerde hoe builds gemaakt worden.
  • Indien je team in één tijdzone werkt dan is de middagpauze een goed moment voor de builds.  Zo kan iedereen net voor het eten zijn laatste code aan het versiebeheer toevoegen. De build loopt terwijl ze eten, en wanneer ze terug zijn is iedereen in de buurt om een eventuele gebroken build op te lossen. Zodra de build werkt kan iedereen de recentste versie uit versiebeheer ophalen, zonder bang te zijn voor een onwerkbare ontwikkelingsomgeving.
  • Indien je team in twee tijdzones werkt, plan de dagelijkse build zodat mensen in de ene tijdzone de mensen in de andere tijdzone niet pesten. Op het Juno team deden de mensen in New York aanpassingen in versiebeheer om 19 uur en gingen dan naar huis. Indien ze de build braken kwam het andere team in Hyderabad, Indië toe (rond 20 uur New Yorkse tijd) en zat volledig vast gedurende een hele dag. We zijn gestart met twee dagelijkse builds, zowat een uur voor elk team huiswaarts ging, en daarmee was het probleem van de baan.

Voor meer informatie:

  • Wat discussie over tools voor dagelijkse builds.
  • Een dagelijkse build is belangrijk genoeg om een van de 12 stappen naar betere code te zijn.
  • Er zijn heel wat interessante weetjes te vinden over de (wekelijkse) builds bij het Windows NT team in G. Pascal Zachary's boek Showstopper.
  • Steve McConnell schrijft hier over dagelijkse builds.


De originele versie van dit artikel verscheen in het Engels onder de naam Daily Builds Are Your Friend  

Joel Spolsky is de oprichter van Fog Creek Software, een klein softwarebedrijf in New York. Hij studeerde af aan de Yale universiteit, en heeft als programmeur en manager gewerkt bij Microsoft, Viacom en Juno.


De inhoud van deze pagina's vertegenwoordigt de mening van één persoon.
Alle inhoud Copyright ©1999-2005 door Joel Spolsky. Alle rechten voorbehouden.

FogBUGZ | CityDesk | Fog Creek Software | Joel Spolsky