Other names:
- DRY Build Scripts (Don’t Repeat Yourself)
- Infrastructure agnostic scripts
- Parameterized Scripts
- Fill In the Blanks
Symptoms:
- You find yourself having to change the script in many places, because a single “thing” has changed.
- For example, the name of the remote machine you are deploying to has changed, and that name has to be changed in several places in the build script.
- Another example: you want to run the same set of actions both on the debug source directory, and on the release source directory.
Problem:
- The script is breaking the “Don’t repeat yourself” rule, that many programmers know and love (sometimes they love to hate it).There is not “Single source of truth” about specific knowledge in the script. For example, there is no single location that defines what is the deployment target machine name. Instead, that machine name appears in many different places in the script.
Solution:
There are many ways to solve this problem with build scripts, but they all involve using variables inside the build script, and then “fill in the blanks” just once per script:
- Script variables as the single source of truth: You can define variables in your script. (for example, a variable that stands for the machine name to deploy to, that gets replaced in the script with its underlying value in all places it is used). The use these variables everywhere you see repetition.
- Script Configuration File: Assuming you have the ability to define script variables, you can read the value of these variables from a configuration file before running the script. This gives an added bonus of not having to much around with the script itself when your IT admin suddenly changes your deployment machine.
- Environment Variables: Much like the previous solution, environment variables have an added bonus – they are usually very easy to set from within your CI server (such as TeamCity), so that there is now a clear separation between the script knowing about the source files, and the CI build configuration knowing about the IT structure and requirements. In my own builds I use this technique a lot, and might have 10 or 20 environment variables set by the build configuration in the CI server, that are used by the build script that is in source control. That way you can have the same deploy script be used to deploy to a test, staging or production machine, with a simple environment variable change.
- Script Parameters: This is also useful when using a CI server – instead of setting env. variables, the ci build configuration calls the build script with parameters in the command line call. these are then used to set values for variables inside the build script.
Possible Side Effects:
- Unclear Script Requirements to run. It can be hard to find all the possible needed environment variables or parameters needed to run the script successfully. It is up to the script creator to maintain and document the list of needed parameters as much as possible.
- Hard to Debug.To be able to run the build script on your local machine you will have to provide all the needed env. variables or parameters locally. If the build system supports variables that can be overridden by environment variables, but that have a default value if there are no environment variables, this can ease this pain.