If you're here because you desperately need to go back a step template version and don't have a copy saved anywhere except within Octopus, and you haven't got time to read up on my two cents, scroll down to the “I Didn't Come Here For A Lecture On Communism” section. But be warned; this is not a tried and trusted method, but a hack. I accept no responsibility for this not working or breaking your Octopus Deployment application. Not saying that this will cause issues as we're doing nothing but reading a field from one table in Octopus. However it would be remiss for me to suggest that this was anything other than a method I've stumbled upon out of trial and error.
Life Before Octopus
When I first started the whole build/deploy gig I saw a huge hole in the market for a tool that could automate the deployments of software. In some of our MSBuild proj files we had automated some of the deployments in our Test/Dev environments, but in our PreProd/Prod environments it was considered too risky to run this stuff. So releases were largely a manual affair, were never the same in any two environments, and always caused unknown unknowns.
Octopus: The Problem, and Solution To, All of Life's Problems
But then a few years ago Octopus Deploy came along and ran with the idea of automating deployments in a repeatable manner throughout all environments. I was really excited by this, and liked how they had sat down and thought about the whole release process, like promoting to environments to run the same release etc. And how great is the UI! It's so simple that non-tech people can use, which is really important because then we can enable anyone to release software, providing they have the permissions. People laugh at me when I say “the UI is a good reason to use Octopus”, but it legitimately is! Whilst there is nothing you can do in Octopus that cannot be done in TeamCity or Jenkins, it still helps enforce a flow and process to deployments.
Another reason why Octopus is so successful is because of it's great API. It's lightweight, structured well, makes use of JSON which is far easier to read than XML, and is very well documented. The UI itself uses the API, and because this means that all the data and operations you execute from the UI make use of the API, you can automate and use with confidence. So all these factors meant that at first it was very much of a love story between me and Octopus Deploy.
However, over the past year or so, this love affair has gone a little sour. What I first thought of as shortcomings of no great significance have manifested themselves into massive problems. You want me to give solid examples? OK, here's two:
- You can't source control step templates or script modules.
- The versioning of step templates is primitive at best, and non existent for script modules.
Still not concrete examples? Let's expand upon these:
OK, you can technically source control your own step templates/script modules in something like TFS or GitHub, and then either manually update the scripts in the Octopus UI. Or, if you're really clever and have the time and resources, you can manipulate the aforementioned admittedly awesome API to post updates to these objects. But it's far from ideal.
The choice you have for upgrading step templates across projects are “the version you're currently on”, or “the latest version”. And there's no way to force a project to use the latest version. So if you make changes to a script module that is invoked via step template, you have to be sure you can support all previous versions of the step templates work with that script module. Not fun. There is of course a way around this: use NuGet to package up script modules, so that you can control the versioning of them, and call them via step templates.
I Didn't Come Here for a Lecture On Communism
Coming back to problem #1 for a minute, this lack of source control within Octopus can very bad. And I got stung by this recently: I had accidentally deleted the script content of a step template and saved it. And there's no way back out of this. Or so I thought. I actually managed to retrieve the PowerShell script out of a previous release by querying and hacking away at the database, and so I thought I'd share it here.
Abrogation of Responsibility
Let me be clear about something: this is a method that I found successful in getting the script back. Any attempt by yourselves to do this on your own database is entirely at your own risk. I accept no responsibility for any issues you have in trying this, be it not working for you, or worse.
With that out of the way, let's kick off.
You need access to the SQL Server Instance that the Octopus database is on. I reckon read only permissions to the database will do, but I've not tested.
As a point of interest, you can check the table “dbo.ActionTemplate” to see that, yes indeed, there is only one version of your step template. The “Id” column is the unique column. Obviously if you had more step templates this would have a row per step template. Not entirely sure why they couldn't have stored previous versions, doesn't look like it would be that hard to store previous version in a column. That way it would be possible to rollback. But anyway, I digress….
The table that will store a version of the step template we want is “dbo.DeploymentProcess”. Depending on how many projects/releases you have, it can be fairly easy or a complete nightmare to find the deployment we want. Of course you can narrow down by project by finding the Project Id you want by looking in the “Project” table.
When it came to finding the correct Version, for me it was pretty straightforward: it was the latest deployment process that had the version of the step template I wanted. This is because I had yet to update the deployment process via the UI. Had I done this then it would've been the release prior. But the key point here is that you can go back in time with your step templates to any prior deployment process that you have saved. So in theory you can get any custom step template's PowerShell back and save it back to a step template.
In order to locate the step template, the column that we're looking for is the JSON column, which stores the complete deployment process. And yup, it's all JSON of all the steps you have in one deployment process. So again, If you have many steps then it will be very difficult to find your step template in amongst all this. We can make this easier for us however. Be advised that the JSON column output may be larger than what SQL can cope with displaying in a grid or text, so right click and save as a csv then open that and save as a JSON file. Use an online formatter to tidy up the format. This should make it a lot easier for you to find what it is you're looking for.
At this point, you should now have a document that would pass for JSON were it not for all the “new line” etc breaking up the document. So let's tidy this up and then the document should be easier to navigate. Open up the JSON file in NotePad++. If you don't have NotePad++, go and download it and then go thank them publicly on Twitter. Even if you have NotePad++, go and thank them anyway.
Press CTRL+H to open up the “Replace” dialogue window. Select Extended in Search Mode. In the find enter “\r\n” and in the replace enter “\r\n”. Do the same for “\t” and replace with “\t”. now you should end up with a JSON formatted document. You should not be able to find your original step template before you made the changes to it. Extract, save as PowerShell and test that it works. If everything has gone to plan you will have a previous copy of your step template.
If anyone has any issues or better workarounds let me know in the comments section. I can't promise that I'll help you out of you get stuck, it really depends on the issue you have.