We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Continuous integration

00:00

Formale Metadaten

Titel
Continuous integration
Untertitel
Char by char - Powershell
Serientitel
Anzahl der Teile
110
Autor
Lizenz
CC-Namensnennung - keine kommerzielle Nutzung - Weitergabe unter gleichen Bedingungen 3.0 Unported:
Sie dürfen das Werk bzw. den Inhalt zu jedem legalen und nicht-kommerziellen Zweck nutzen, verändern und in unveränderter oder veränderter Form vervielfältigen, verbreiten und öffentlich zugänglich machen, sofern Sie den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen und das Werk bzw. diesen Inhalt auch in veränderter Form nur unter den Bedingungen dieser Lizenz weitergeben
Identifikatoren
Herausgeber
Erscheinungsjahr
Sprache

Inhaltliche Metadaten

Fachgebiet
Genre
Abstract
Building a simple yet flexible continuous integrated server from scratch using Powershell.During this session, we will build a continuous integrated system by using Powershell.The session will walk you through the common tasks involved in a CI-server and give some alternatives on how they can be implemented in powershell.After the session you will have a good understanding on how continuous integrated servers work and how you can leverage Powershell to create your own continuous integrated server or extending one you allready are using (e.g. CruiseControl.NET)Outline
23
63
77
SoftwareentwicklerGebäude <Mathematik>Zusammenhängender GraphIntegralLeistung <Physik>GamecontrollerGebäude <Mathematik>QuellcodeNabel <Mathematik>DifferenteDämpfungWeg <Topologie>StandardabweichungFormale SpracheUmwandlungsenthalpiePhysikalisches SystemClientCASE <Informatik>Gewicht <Ausgleichsrechnung>EINKAUF <Programm>Shape <Informatik>MultiplikationsoperatorRechenschieberCybersexMereologieVersionsverwaltungRechenwerkDemo <Programm>Problemorientierte ProgrammierspracheKontinuierliche IntegrationProgrammfehlerSchnittmengeServerComputeranimation
Physikalischer EffektBildschirmfensterSichtenkonzeptVirtuelle MaschineVirtuelle RealitätSoftwareentwicklerIndexberechnungPlastikkarteFehlermeldungVerzeichnisdienstSkriptspracheVersionsverwaltungStichprobenumfangProjektive EbeneLeistung <Physik>SoftwaretestVollständigkeitNabel <Mathematik>Gewicht <Ausgleichsrechnung>Kartesische KoordinatenMathematikWeb-ApplikationReelle ZahlTypentheoriePhysikalisches SystemSkriptspracheInformationsspeicherungQuellcodeVerkehrsinformationVerzeichnisdienstVariableElektronische PublikationComputersicherheitComputeranimation
Virtuelle RealitätVirtuelle MaschineBildschirmfensterSichtenkonzeptSoftwareentwicklerVerzeichnisdienstElektronische PublikationLokales MinimumDickeSkriptspracheProgrammGewicht <Ausgleichsrechnung>QuellcodeVariableStabVollständigkeitProgrammierumgebungSkriptspracheVerzeichnisdienstDifferenteProfil <Aerodynamik>Nabel <Mathematik>WhiteboardFramework <Informatik>RechenwerkBitComputerspielVersionsverwaltungCodeGebäude <Mathematik>Microsoft dot netVerkehrsinformationStellenringBenutzerbeteiligungBinärdatenComputeranimation
Message-PassingSichtenkonzeptBildschirmfensterElektronische PublikationCodeKlon <Mathematik>RechnernetzSoftwareentwicklerVorzeichen <Mathematik>LogarithmusVirtuelle RealitätDickeLeistung <Physik>VerzeichnisdienstSkriptspracheSpitze <Mathematik>ProgrammVisuelles SystemVirtuelle MaschineATMBimodulEndliche ModelltheorieElektronische PublikationPeer-to-Peer-NetzSkriptspracheData MiningGruppenoperationLeistung <Physik>PunktBootstrap-AggregationServerDatenbankBildschirmfensterPhysikalisches SystemNabel <Mathematik>NormalvektorStellenringProgrammierumgebungComputeranimation
DickeVerzeichnisdienstSoftwareentwicklerVirtuelle MaschineBildschirmfensterSichtenkonzeptVirtuelle RealitätVariableSkriptspracheGerade ZahlElektronische PublikationATMInformation-Retrieval-SystemFunktion <Mathematik>EreignishorizontPhysikalisches SystemGruppenoperationPay-TVServerDatenverwaltungRechenwerkObjekt <Kategorie>DateiverwaltungSkriptspracheVersionsverwaltungQuellcodeMathematikSkeleton <Programmierung>Schreiben <Datenverarbeitung>Gebäude <Mathematik>Pay-TVGewicht <Ausgleichsrechnung>IdentifizierbarkeitFunktionalEin-AusgabeCodeEinsEreignishorizontServerBootstrap-AggregationVariableElektronische PublikationInformationE-MailTypentheorieImplementierungDifferenteZweiProzess <Informatik>VerzeichnisdienstPunktObjekt <Kategorie>StrömungsrichtungReelle ZahlMultiplikationsoperatorSoftwaretestMicrosoft dot netWeb-SeiteGraphfärbungGruppenoperationRechter WinkelPhysikalisches SystemCodierungSystemaufrufComputeranimation
SoftwareentwicklerBildschirmfensterVirtuelle RealitätSichtenkonzeptVirtuelle MaschineWeg <Topologie>BootenFunktion <Mathematik>SummierbarkeitServerURLFehlermeldungViewerEreignishorizontOffene MengeGruppenoperationDokumentenserverDualitätstheorieVersionsverwaltungQuellcodeMathematikQuick-SortInformationLoginAbstimmung <Frequenz>TaskVerzeichnisdienstBitDefaultComputeranimation
SichtenkonzeptBildschirmfensterSoftwareentwicklerSpeicherabzugVirtuelle MaschineVirtuelle RealitätFunktion <Mathematik>Objekt <Kategorie>Visuelles SystemMathematikHash-AlgorithmusHackerComputersicherheitGreen-FunktionAggregatzustandBootenVerzeichnisdienstInformationMinkowski-MetrikVersionsverwaltungDickeATMBaum <Mathematik>E-MailVerhandlungs-InformationssystemSoftwareentwicklerSoftwaretestVersionsverwaltungAutomatische IndexierungLeistung <Physik>Objekt <Kategorie>QuellcodeInformationSkriptspracheVerzeichnisdienstProgrammierumgebungNabel <Mathematik>SensitivitätsanalyseKomplex <Algebra>VariableCOMComputerspielApp <Programm>Demo <Programm>Prozess <Informatik>Zusammenhängender GraphZweiForcingCodeLoopBitUngleichungWeb-ApplikationCodierungCASE <Informatik>Kontextsensitive SpracheMinkowski-MetrikSprachsyntheseInklusion <Mathematik>Computeranimation
Lokales MinimumSkriptspracheVerzeichnisdienstFunktion <Mathematik>BildschirmfensterVirtuelle MaschineVirtuelle RealitätSichtenkonzeptSoftwareentwicklerInformationBildverstehenHilfesystemMathematikVersionsverwaltungDisk-ArrayCodierung <Programmierung>DoS-AttackeStrom <Mathematik>Abstimmung <Frequenz>Regulärer Ausdruck <Textverarbeitung>DatentypHesse-MatrixVariableDemo <Programm>Objekt <Kategorie>Physikalisches SystemCodeVersionsverwaltungTermInformationResultanteParametersystemObjekt <Kategorie>Arithmetischer AusdruckReverse EngineeringKategorie <Mathematik>DateiformatMathematikAggregatzustandAutorisierungStrömungsrichtungGebäude <Mathematik>SoftwaretestServiceorientierte ArchitekturKontrollstrukturPhysikalisches SystemFlächeninhaltDatenstrukturBitTopologieTypentheorieGeradeVerzeichnisdienstQuellcodeElement <Gruppentheorie>Computeranimation
SichtenkonzeptComputerspielFunktion <Mathematik>Objekt <Kategorie>SkriptspracheSoftwareentwicklerBildschirmfensterVirtuelle RealitätVirtuelle MaschineInformationRegulärer Ausdruck <Textverarbeitung>Baum <Mathematik>Minkowski-MetrikSoftwaretestDemo <Programm>Lie-GruppeZahlenbereichProgrammfehlerMathematikQuellcodeInstantiierungGamecontrollerDokumentenserverCodePerfekte GruppeInformationProgrammfehlerProzess <Informatik>Weg <Topologie>Physikalisches SystemHinterlegungsverfahren <Kryptologie>SchlüsselverwaltungComputeranimation
MathematikBaum <Mathematik>Virtuelle MaschineSichtenkonzeptBildschirmfensterVirtuelle RealitätSoftwareentwicklerVersionsverwaltungKontrollstrukturVariableFunktion <Mathematik>SkriptspracheSinusfunktionWärmeübergangServerTablet PCProzess <Informatik>SLAM-VerfahrenNeunzehnGerade ZahlObjekt <Kategorie>EreignishorizontGreen-FunktionAggregatzustandBootenIntelVersionsverwaltungQuellcodeEreignishorizontBootstrap-AggregationMathematikProgrammfehlerServerVerzeichnisdienstIntegralNabel <Mathematik>DifferenzkernArithmetischer AusdruckSkriptspracheGüte der AnpassungInformationsspeicherungForcingMultiplikationsoperatorPaarvergleichHinterlegungsverfahren <Kryptologie>ResultanteComputeranimation
SoftwareentwicklerBildschirmfensterVirtuelle MaschineVirtuelle RealitätSichtenkonzeptMathematikChi-Quadrat-VerteilungGraphische BenutzeroberflächeGerade ZahlServerPay-TVFunktion <Mathematik>EreignishorizontSkriptspracheVerzeichnisdienstRechenwerkMenütechnikObjekt <Kategorie>Green-FunktionBaum <Mathematik>QuellcodeIntelMathematikHinterlegungsverfahren <Kryptologie>ZahlenbereichVerzeichnisdienstQuellcodeElektronische PublikationSkriptspracheRekursive FunktionMathematische LogikGebäude <Mathematik>VersionsverwaltungServerBitTexteditorParametersystemPortscannerObjekt <Kategorie>TopologiePhysikalisches SystemMereologieBitrateInklusion <Mathematik>Fächer <Mathematik>Computeranimation
BildschirmfensterVirtuelle RealitätVirtuelle MaschineSichtenkonzeptSoftwareentwicklerVerzeichnisdienstDefaultTaskMathematikServerGreen-FunktionObjekt <Kategorie>DatentypDickeDoS-AttackeGebäude <Mathematik>FehlermeldungZeichenketteKategorie <Mathematik>Framework <Informatik>VersionsverwaltungArithmetischer AusdruckGebäude <Mathematik>Kategorie <Mathematik>Radikal <Mathematik>PräkonditionierungArithmetischer AusdruckSkriptspracheKonditionszahlVorhersagbarkeitVerzeichnisdienstDifferenteFigurierte ZahlEin-AusgabeFlächeninhaltDefaultSoftwaretestTaskSchnittmengeRechter WinkelSchlüsselverwaltungParametersystemVerkehrsinformationMultiplikationsoperatorPhysikalisches SystemPunktFormale SpracheIntegralKonfigurationsraumVersionsverwaltungAbstimmung <Frequenz>HochdruckVariableDruckverlaufWhiteboardBootstrap-AggregationInformationMessage-PassingSkeleton <Programmierung>Problemorientierte ProgrammierspracheSummierbarkeitMereologieComputeranimation
SoftwareentwicklerBildschirmfensterSichtenkonzeptVirtuelle RealitätVirtuelle MaschineSpeicherabzugSpieltheorieLokales MinimumRegulärer Ausdruck <Textverarbeitung>InformationTaskFehlermeldungVersionsverwaltungZeichenketteMathematikFunktion <Mathematik>Visuelles SystemGreen-FunktionGebäude <Mathematik>BefehlsprozessorKonfigurationsraumDefaultKrümmungsmaßGebäude <Mathematik>ParametersystemOrdnung <Mathematik>AggregatzustandFehlermeldungVisualisierungGanze FunktionComputeranimation
KonfigurationsraumMetropolitan area networkDefaultGebäude <Mathematik>SichtenkonzeptVirtuelle RealitätVirtuelle MaschineBildschirmfensterSoftwareentwicklerMenütechnikSoftwaretestFehlermeldungVisuelles SystemVerzeichnisdienstVersionsverwaltungSystemplattformEinfacher RingBefehlsprozessorDualitätstheorieTaskVariableZeichenketteKategorie <Mathematik>BildschirmmaskeDämon <Informatik>VorhersagbarkeitTotal <Mathematik>DrucksondierungGebäude <Mathematik>Web ServicesMultiplikationsoperatorSystemplattformVersionsverwaltungVerzeichnisdienstPerfekte GruppeArithmetischer AusdruckTrennschärfe <Statistik>ResultanteCASE <Informatik>SkriptspracheZeichenketteBootstrap-AggregationMathematische LogikProzess <Informatik>QuellcodeMatchingLoginProjektive EbeneTouchscreenTopologieInstantiierungGraphfärbungPunktComputeranimation
SichtenkonzeptSoftwareentwicklerVakuumVirtuelle MaschineBildschirmfensterVirtuelle RealitätSLAM-VerfahrenElektronische PublikationSpieltheorieZeichenketteGebäude <Mathematik>Total <Mathematik>VerzeichnisdienstFehlermeldungObjekt <Kategorie>Konvexe HülleSmith-DiagrammDean-ZahlTaskSkriptspracheWeb ServicesE-MailWeb logGanze FunktionMomentenproblemServerPhysikalisches SystemProxy ServerURLClientNormalvektorProzess <Informatik>BenutzerbeteiligungComputeranimation
Vorzeichen <Mathematik>Klon <Mathematik>Message-PassingElektronische PublikationCodeSoftwareentwicklerZeichenketteMAPVirtuelle MaschineBildschirmfensterSichtenkonzeptVirtuelle RealitätMinkowski-MetrikServerNamensraumElement <Gruppentheorie>Gebäude <Mathematik>Objekt <Kategorie>Explosion <Stochastik>VerzeichnisdienstFehlermeldungVariableTaskFeinstrukturkonstantePhysikalisches SystemTotal <Mathematik>Proxy ServerTypentheorieDefaultCodeProzess <Informatik>Physikalisches SystemVollständigkeitRegulärer Ausdruck <Textverarbeitung>RPCNamensraumVersionsverwaltungMultiplikationsoperatorGebäude <Mathematik>Objekt <Kategorie>Web ServicesLuenberger-BeobachterMinkowski-MetrikInstantiierungRechter WinkelQuaderComputeranimation
BildschirmfensterSichtenkonzeptGebäude <Mathematik>Windows Server 2008SoftwareentwicklerComputersicherheitKonvexe HülleVirtuelle RealitätRechenschieberFormale GrammatikWeb logDatenflussBitMetropolitan area networkMereologiePunktAdressraumVersionsverwaltungStrömungsrichtungMathematikQuellcodeTwitter <Softwareplattform>Syntaktische AnalyseComputeranimation
Transkript: Englisch(automatisch erzeugt)
My name is Hadelthi Amlakin, I work for Cyber Norway and I'm here to talk about continuous integration. We're going to use PowerShell to make a process and create a continuous integrated server. You can ask yourself, why would we want to do this? Most of you have probably used TeamCity, maybe CruiseControl.net.
In some cases that is very fine, but other clients have different components well put together. And putting continuous integration up can be a real hassle. Especially if all of the components that some client you're at has different producers.
Say you're using SVN for your source control, maybe you're using JIRA for bug tracking or TRACK for that matter. You have all these different components that are going to play well together. So that can be a real hassle. And most of you have been to different talks about continuous integration before.
Most of the talks are just talking, nobody implements anything. So, we're going to build something from scratch. And how are we going to do this? We're going to use PowerShell, of course. We're going to use a set of different components here, just listed some of them.
I'm going to use SVN for the source control. You could use GitHub, you could use any other source control management system you want. I chose SVN just because it's old school and there's a lot of different companies still using it. It's fairly easy to integrate too.
But you can change it easily through GitHub, everything that has a command line shell, basically. I'm also going to use Saki, which is a domain-specific language for PowerShell. It's a component. I'm just going to show you how to use it later. Then I'm going to use standard Microsoft components like NUnits, MSBuild, that kind of things.
And for the last part, I'm going to integrate it to JIRA, so whenever your build fails, you're going to post something to a JIRA user saying, hey, my build failed, this is your fault. So that's basically what it's going to be doing. So, time for some demo.
Keeping the slides very short today. Let's see. I got this one. Okay, so this is my sample project, which I'm going to be building and committing changes to. I don't care about the content here. It's basically a real dummy web application with silly tests.
Silly tests. So, I'm going to go ahead and start PowerShell Ice. And I'm using PowerShell CTP3, which is the new community technology preview.
It has some cool new features. You could use an older version, but this one is easier to work with. It helps you autocomplete stuff, et cetera. So, I'm going to go ahead and create some directories where we're going to store all the different things we're going to be using. So, I'm going to create a CI folder.
And within this CI folder, I'm going to create a source folder. I'm going to create a build folder. I might need a reports folder. And let's see. Yes, of course, the most important one, scripts folder. So, in the scripts folder, we're going to be creating all our items for our continuous integrated system.
So, I'm going to go ahead and create an item. I'm going to call it item type file. I'm going to call it variables. This is where I'll store all my variables. I'm just going to be lazy, so I'm going to copy that path. And I'm going to open the file variables.
Here, we're going to define our different variables. So, I'm going to have a scripts directory. I'm going to have a source directory. The source directory is where we're going to check out our source code.
Source. And notice the autocompletion is very neat when you have the folders. Maybe I'll just create the folders beforehand. So, let's create. We already have the build. So, build directory.
CI build. And we have our reports directory. CI reports. That should cover the different variables we need so far. So, what I did was I have put in my profile.
I'm not sure if you're used to bash scripting. All shells have a different profile. You can put your local variables, custom code, different kind of things. What I did in my profile, I just put some different environment variables to make life a bit easier. I added the end units bin directory to my environment path.
And I added the web deployment to the path as well. And, of course, .net framework version 4. It's just so I can execute the different executables without hassling with the path beforehand.
So, just makes life a bit easier. I'm going to be using Saki for my build definitions. You can download that from Saki. GitHub. It's already there. You can just go ahead and pull down the zip file, unzip it, and put it into your PS module path.
If you know about the PS module path, let's see. PS module path. There's two paths normally in your shell environment. I put mine under my locals folder. You could put it in the systems folder as well. Basically, just to install the module,
you can copy Saki over to one of those folders. So, if I look into Windows, oh, let's see, not Windows, users. I can say documents, Windows PowerShell, modules. You see I have two modules installed in my users folder. And Saki is a neat little build script which I'll show you later.
Saki-contrib is contributed scripts for SVN helpers, database helpers, stuff like that. I really don't use them because they're not that good. You can easily write your own. So, that's what we're going to do.
So, I'm going to go to scripts again. And I'm going to say new item bootstrap.ph1. And it's a file. Our bootstrap is going to be our main entry point where we start our server. So, I'm going to open that one.
Is the text readable? You can read it from there, yeah? Okay. So, just going to close that one. And put a comment. Main entry point. I'm going to include my variables. So, now I can access my source directory, my build directory,
all the different variables I'm using. And I'm going to create another file while I'm at it. Just because we don't want to create them later. I'm going to call it notifications. Item type file. And I want one for source control.
This is the different files I'll use where I will put the functions or the methods for the different implementations I'll use later. So, for notifications, we'll put things like update JIRA, send an email to someone, and for source control, we'll put functions for fetching information about the source control.
So, for the bootstrap. I'm going to make a real simple bootstrap. I'm going to create a timer job which basically calls the method from the source control to check if there's anything new. This is going to be running periodically, say every two seconds. So, if there's a change in the source control,
something is going to happen, and this something is going to be a build script. Like pull down the latest source, build it, check the tests, are they running, deploy everything. So, I'm going to go ahead and create a timer, and that's a new object.
I can just run it and see it's running still. So, I'm going to have a timer interval. I'm going to set it to two seconds. This is milliseconds. I'm going to have an elapsed method, and this is a script block.
This is the code that will be running for each interval. Then I'm going to have a function for starting my CI server, and I've got to have a method for stopping. Stop CI server.
So, let's see. Start CI server might do something like this. I'm not sure if you're familiar with PS eventing, PowerShell eventing. You can listen to normal events like the ones you're used to in the .net framework, like elapsed method.
You can do file created. So, instead of using a timer, you can use the file systems watcher. So, if you have a custom build script that already builds your system, you can just make it pull or watch for changes in some build directory. So, I'm going to see register object event.
Input object is the timer, and event name elapsed, and the source identifier is also elapsed. This is just the name of the method we want to watch. And for the action, I'm going to say my elapsed method.
That's what I call it. So, that's a fairly easy method, and we are going to say, there we are. I can just test this one.
Start CI server. Just call it like that. Notice now we have a method registered, so I can say get event subscriber. And this one gives me all the event subscriptions
that are in the current PowerShell session. So, I can use this in my stop method to get it. So, event, get event subscriber. Then you can say unregister event.
Subscription ID. Subscription. There we are. So, now I could probably say start and stop the CI server. Let's see.
Yes, of course. I already started it, and there we go. So, now I stopped it. It complains because you can't have more than one event subscriber on the same event in the same session. Now I have my start and my stop method, but I haven't started my timer yet. So, in the start CI server,
we will put the timer start, and here I will, just to make sure everything is fine, I can say stop, and let's run it. It's starting and stopping the method.
So, now, we can start adding some code to make it all more interesting. So, we can say write host foreground colour. I'm just going to make a really green text. Running code. So, we can see that something is happening, and I'm just going to let it run for a while.
And it should, yeah, there we go. Running code, running code. So, the timer is working. I'm just going to stop it. So, that's the main skeleton for our bootstrap. So, now, we can start implementing the methods
that goes to the source control. We want to check if there's any updates for the source control. So, we will create a function like new hasChanged, hasChanges. I'm going to create a method called source hasChanges,
and it's going to take a path. This path is going to be our source directory. Then I'm going to say if hasChanged. Just going to move some code. That was not the intention.
There we go. I'm going to write hosts. Just illustrates updating from source control. Then we're going to be running build scripts.
If it hasn't changed, we won't really do anything. We will just write something just to see that something is happening. So, we need to implement this method, hasChanges. To do that, I'm going to open the file I created which was the source control.
Here, we're going to have a method called source hasChanges. It's going to take a path. We're also going to create a method for source gets version info.
Path. Maybe we will actually make a default path for these ones, so you can call them externally on the same folder you're in, just to be lazy. Get worsen info.
Maybe we should have a method to get the logs from source directory saying which user committed these changes for this revision. Source gets logs.
Just to make it a bit more funny, we're going to say notifications. Say something. Then we're going to have some text. We're going to add some fun to our build script. We're going to make our build server talk for whatever is happening we wanted to talk.
So, we can just use the speech API in Microsoft to do that. I'm just going to say s new object, comma object, sapi.spvoice. Then I can use speak text.
Just to test this, let's go to our bootstrap again. And what did I call it? Notifications. Say something. I will just scroll it there. It might be easier to read.
And say something. Let's do it outside of the loop since we haven't really implemented this yet. Just going to comment has changed.
And then we're going to do say something. Just to test it. Just going to sleep for three seconds.
See if it helps. I didn't do anything. Then I could test my method. Say something. Wasn't included. I haven't included the method. So that makes sense.
So, let's include all of our methods. Say source control, and we would probably want our notifications as well. Running. Running. Yeah. And it said run, run twice. It's the speech API built into the comma objects.
So you can use basically every API Microsoft has to offer. Just a small example to show you how you can use components very easily and make something fun. So, back to our source control. We're going to say get version info, and source has changes.
This is going to be our main method. Basically, we want to say get version info path. Then I'm going to return
return current version. Next version. And I'm not using the correct syntax. There we are. Not equals. If you're familiar with the PowerShell syntax, that's not equals. So this is going to be our main method to fetch information for the source control.
So now I'm just going to go ahead to our source directory. This is where I will check out all the different codes. So, I will say check out. As for the first step, I will check out my code. I'm going to say space demo app.
And it's case sensitive, of course. What is this? Oh, HTTPS. There we are. And it checks out everything. And it's a revision 25.
So, I have a demo web app. It's a trunk for those that are very familiar with SVN. And basically, this is my directory. So, just to make life a bit more easy, this is the path that I'm interested in.
And I've changed the variable there now just for the sake of the demo. So, I'm going to put demo web app. Let's see. And we're going back to source control. Here we are.
I'll just test my get version info. And now, in my source control, just for testing and to make the development process a bit easier, I'm just going to include the different variables here. Let's see. What is it doing? It's context sensitive.
So, that's the thing worth noting. The shell environment cares about where you are on your shell. So, now I can say I need my variables. And I want my notifications. Well, maybe not the notifications.
Basically, just the variables. And for the path. Source directory. So, what we'll do now is we'll use SVN's built-in methods for this.
So, I'm going to say command. And there's a command called SVN, of course. It takes an info parameter. There is an XML. And there's a path. Then I want the result of that command to be an XML result.
And then I want to invoke the expression command. Return results. I'm just going to test this. There we are. Now I have an XML structure. So, if I can just play with this one, I can say XML.
And there we are. I can run it, and then I can use it further. So, XML is now a fully serialised object. You can just merge your way into the structure. I'm going to say info, and there's an entry. And then there's a commit entry.
And just because I played a bit with SVN, I know that this is the current revision. So, I'm going to say version. And that's not the one I'm after. I want the result.
And we want the author. And that's also in the results author. Let's just check that there is actually an element called author here.
And there is. I wrote the last changes to the source directory. So, now I have the current version and the author of the current checked-out code. So, I want to figure out what's the latest changes in the source control. So, I'm going to issue another command.
I'm going to say info status minus U. And I want this formatted as XML as well. And I'm going to say result. And use the same syntax. And just to debug this as well.
Where did I type wrong? Oh, there it is. A little character. So, here we now have the XML status target. And target has something against.
So, I'm basically just interested in the target against revision. Which is the next version. So, next version. That's the result target. Status target against revision.
Then I'm going to create a custom object. Info object. New object. Type system object. Then I'm going to add some members.
Member type, node property. I'm going to add a name for that one. And then it's going to be a current version. And the value of this is going to be let's just merge this one. Just so we can see it here. I called it version. That's the current one. Version. Let's just.
And then I'm going to do the same for the other properties here. I'm going to say current version. Next version. That's the next version. I'm going to have one for the author as well. Just because I want to know who to blame.
If the build breaks or the test breaks. I'm going to say this one. Yep. Instead of returning the results, I'm going to return info. So, info.
So, if I run this, it should give me something failed. Next version. What failed here? Let's see.
There's a misspelled what? Let's see. I didn't get what you were saying. Line 12. There we are. Next version. Here. Results status against target revision.
Ah, thanks. There we are. Nice little typo. Still not. Let's run it. And then we're going to say info. There we are.
Perfect. Thanks. Let's scroll over here again. So, now, we have a little code that can check for the source to see if there's any changes. I'm just going to do a small change in my repository.
Just going to put that one there. So, let's do a minor change in one of my controllers, for instance. It doesn't really matter. Let's just do the fancy controller. Adding comments. And there, we're going to say commit solution changes.
Add a comment. And because I'm using Jira, I'm going to be implementing it later. I'm going to tag it. Fixed. Bug. Some key to the external system.
Which is this one. And that's the bug track one, for instance. So, you could use the process for committing as the bug tracking. You could automatically update things in Jira if you're fixing bugs, if you're introducing bugs. Just by comments and parsing everything. So, it should be committed.
And then I can say here. I'm going to say source has changes. Path source directory. Yeah. There is a change. So, what my has changes method did was just a comparison.
So, you see current version is now 25 and the next one is 26. So, we can continue using this method. So, I'm going to go back to the bootstrap here. And we're going to use this one. I'm not going to use the talk method anymore.
It will just bug us. So, if there is a change, we're going to update it. Then we're going to invoke Saki. And then we're just going to continue listening to the events. So, whenever there is a source change, we're going to stop our CI server.
So, we won't have two methods overriding each other, two builds running at the same time, et cetera. So, when everything is complete, we're going to start the CI server again. And then the middle, before we do anything else, we'll just say start sleep.
Start sleep. There we are. And I'm just going to comment away that one. I'm going to run it.
It says I haven't changed anything. Oh, of course it does. I didn't comment everything. So, we're going to do that. Let's see. Equals false. There we are. That should do the trick.
Updating from source control, running build scripts. Then it's sleeping. So, the shell is working. We have our first method for source integration. Then I'm going to stop this one. Then we need a method to update to the latest source control version.
And we're going to create that one here. Now I've tested my method so I can just remove these. So, I'm going to say source updates to latest.
And here, we're going to say command. And updates.
Path. So, we could return the result of this, but we're going to say mock expression command. So, let's go to our bootstrap.
We're going to stop it and we're going to update to latest path source directory. So, hopefully that will update our current working directory
to the latest source control. So, let's just do that. I'm going to skip the sleep. And I'm going to just make it start. Updating, running scripts.
And now it's updated. So, now we have a script that listens for changes. So, let's do another commit. Comment number two. So, we could just say commit solution changes.
And it got the change. So, basically this one listens for changes at your source control and automatically updates everything. So, that's the first step for your continuous integrated server. Now, we can start adding some more fancy logics.
So, I'm just going to stop it again. Yep. Clear. Okay. So, I will say solutions. Get child items.
I'm going to say path. It's the source directory. I'm going to filter them by all the solution files. Actually, I think I'm just going to try this one first just to see if it works. So, get all items from the path source directory.
I'm going to filter by all the solutions. There are none. Oh, of course. I'm going to add a recurse. No. Still laughing.
Maybe I should do an include. Oh, I said filter. There are. So, in this source control, there's only one solution. And it's there. This little command just iterates through all sub paths from my folder and scans for all solutions.
So, instead of filter, I'm going to use include. Then I'm going to say for each solution. For each solution in source control, I'm going to invoke my custom build script.
So, then I'm going to invoke Saki. Then I'm going to create a file called build. It takes some parameters. I never remember the correct syntax of this one.
So, let's hope solution. I'm just going to make it short. Solution and it's equals. There we are.
It's going to be the file. I'm just going to pass the file object. There we are. So, I should create my little build script. I'll say new item build.ps1.
It's a file. And this little editor is starting to get a bit too small here. Build. So, now we start with the Saki integration. So, this is a domain specific language.
You can define dependencies upon tasks. The entire language is based on tasks. So, you create a task for build. You create one for deploy. You can say deploy depends on build to run successfully. So, this is very expressful. I'm going to say task default.
And default is going to build so far. Depends on build. Then I'll actually create a clean first. And I can create a build.
I'm just going to sketch up the skeleton here. Build, clean, task, run tests. Task deploy. Deploy depends on run tests.
Run tests, well, hopefully it depends on the build. So, you can't run any tests unless the build is successful. You can build a system without the clean. So, that's probably okay. I'm going to say my default task in my build script is going to do a clean and then a build.
Then I need some properties and I'm going to say properties. The solution can be overwritten. So, basically that's the only property I'll use so far. But here you can customise default properties
and for your build script you can overwrite them with the parameters or the properties that you're passing. So, we can go to the bootstrap. So, here you see I'm using parameters. I would actually want to use properties instead. Basically that's just a dictionary.
So, for each key value item it finds, it overwrites the default one set in your build script. So, I'm going to be invoking my build script. There we are. And the clean one is fairly simple. So, let's just see that this is working.
Solution. Okay, cleaning and just for the debugging purposes we're going to use the same syntax as we did earlier. So, I'm just going to include my variables.
There we are. Of course it doesn't work that way. I will have to invoke it. So, invoke Saki. And I'm going to say build. Then I can say properties.
Then I can say solution test. So, it builds. Executing clean. Cleaning test. So, there you see my debug info. It works as you expected.
And because this is my default task, it executes clean first and then it executes build. And you see you get timed reports for all your different tasks. So, this is very, very expressible. If you need extra conditions for your different tasks, you can use the precondition. Preaction.
Well, there is a preaction as well. There is a precondition. So, you can say I have a precondition saying sum war equals true. If that sum war is not true, then this method won't be executed, whereas it will fail.
So, you can use that to overwrite different things. But we're going to use this one. I'm just going to fetch. Didn't we do this? I have my solutions. I'm just going to make my fast build version here.
Let's see what it says if I'm doing this in the for loop. Just like the bootstrap. So, for each solutions, invoke the build scripts. Yes, precondition was false. Yes, of course it was. I specified a precondition, and there we go.
There. So, the wrapping up seems fairly fine, and we can start the clean. And to use clean, I'm going to use m as build, and I'm going to say configuration.
That's a property that is suited for this one. So, I can say config. I wanted to do this for just debug mode. If you use m as build, this is the things in your Visual Studio. Debug, clean, release.
So, I'm going to say config, and then I'm going to say output. Path. Build directory. Then I'm going to say the target is clean,
and, of course, I need the inputs, which is my solution. If everything works well, let's see if it works well. Invoke expression. Command. Clear screen, and invoke.
Missing some terminator. Of course. Configuration. There, I think. Let's try it again.
Property. Not valid. Let's see. Perhaps it was there. It's the fun part with the invoke expression,
finding the right parenthesis, and these ones. Let's see. Clean. And configuration. Of course, can't run that one.
Just going to print it. Let's see.
Let's see the syntax error. I'm sure there is just a small little one there.
It should have been like that. Let's try the first one.
I have the script as well. Let's see. Property is not valid. That should have worked.
I'm just going to open one I already did. Let's see. I have it here somewhere. Let's see. Not that one. Build. The same one, basically.
Just with the right letters. Wasn't that the entire mistake? Yeah, obviously.
Yep, there we are. So, the order of the parameters is very, very important here. So, I can invoke the MSBuild and I can do the clean. And we see here that it has one error. Build failed. Of course, there is something wrong with the build.
So, if I just open it in Visual Studio, maybe it's not even building. I didn't build it earlier. Okay. So, clean. Clean should be good, but we could, after a clean, make sure that everything is clean
in case you have some custom deployment variants or build scripts that MSBuild doesn't do. So, we can say I want to delete everything under my build directory. For instance, and that's the build directory.
Let's see if that one works. Oh, let's see. Let's just do this expression here. This is a, there we are. Yeah.
So, that should remove everything from the build directory. I'm going to actually have it. So, that was the clean command. Now for the build, we can use MSBuild in the same manner. So, we could say invoke expression, expression, and command.
Now, we're not going to use clean anymore, so we're going to use this one. So, invoke expression command. Let's do this. Just invoke it, and let's see, build failed. So, let's see, platform.
There is something wrong here with my build. That's not good. That's strange. Okay. But, we can say result for this expression here.
Now we can exemplify how you can check if your build fails or not. So, as for the result, I'm going to say result, select string. Didn't succeed.
Select string. Simple match. Build succeeded. Or, actually, we're going to match for, yeah, no, build succeeded. Oh, thanks.
Okay. I called it config, didn't I? Perfect. There we are. Brilliant. Thanks. So, let's go here and do a select build succeeded. And, if not, did succeed, I will temporarily just write to the host with an awful colour.
Build failed.
So, let's do a clear screen, and let's just do this. Build failed, yep. And, what is it saying? Oh, out of path. It's not set for the project. Oh, of course it's not. Because it's build directory. Build directory.
There we are. Clear, and build. Brilliant. Now, it's building, and it's actually succeeding. If it's not succeeding, we can blame someone. So, here, we can use our source control, and we can use the get logs.
I'm just going to see how much time we have left. Let's see. We have very little time left. So, just to exemplify, our process here now is a Saki script where you can do every logic you could possibly want. You can define new steps.
Our source control can be running. Our bootstrap basically just is a timer invoking your build script. So, if you're changing your build script, you can do that on the fly, and your timer just keeps on running and invokes it every time. So, you can easily modify your build script and invoke new methods.
And, just for the sake of it, I made a little bootstrap to post to Jira. They're using web services. I can just show you the simple script. It's really easy. Let's see how you can use web services. Let's see.
Did I put it there? No, I don't think so. Jira. I posted the entire working process on my blog, so you can find it there. And you can walk through step by step how you can set it up, how you can use web services, how you can send emails using the system.net SMTP server.
Which you can do like this. System.net. New object. SMTP client.
Just the normal SMTP client you're used to. So, you can use that for sending email. Especially through Gmail, it's really easy. You can just enable SSL and you're good to go. Calling web services also is very easy. You can do a proxy. You can say new web service proxy. It takes a URL. Let's see, I have a URL here.
This is the URL for Jira. This is for our site, though. But, let's see. And it creates a web service proxy for me. And through this proxy, you can do all the web service calls you're used to. Just pure C sharp code as you're used to. The only thing worth noting here is if I'm going to create a remote issue, this proxy has its own name space.
And do not specify your own name space if you're using the web service proxy in your same session. Every time you create the proxy, the name space isn't overwritten and you get an error. So, use the default name space and instantiate using this new object.
Oh, I'm just going to say name space. That's the proxy. Oh, proxy. Get type name space. Name space. Yeah. So, really unreadable name space. But then I could see, say, remote issue on Jira.
That would be a new object of type name space remote issue. And we see I have auto completion. So, this is all the things you're used to at Jira. You can post this object to Jira.
You can update, you can move issues. And you can simply do regular expressions to fetch your logs, your source control. Basically, integrated very easily through your own systems, your own processes. Without having to learn another build system like cruise control or whatever. So, very flexible.
That's basically what I wanted to show you apart from a bit more flow, but as I said, you can play with this yourself if you want. And I have it on my blog. I'll just put up this one. And you can find the address there at some point. Let's see. Yeah.
So, if you want to walk through this on your own, you can find step by step instructions on my blog. I posted an intro here the other day. I'm going to publish the remaining posts this day.
So, you can do it yourself if you want. You can try to use Git, because the methods I created, like the source Git changes, Git current version, they should be easily mapped to Git as well. You can fetch logs, parse XML, very easily through PowerShell. So, any questions?
Then I guess that's it. So, you'll find me on Twitter.