Running commands

As 'The basics' section explained, each of the main sections within a configuration file allows commands you define to be run.

These commands are just normal bash commands that you would normally have to run if you were doing a full manual install of your software. For example, enabling a service after your package has been installed:

To be able to use commands in deploys you will need a good understanding of each part of this document:

Command sections

Each of the following key-value sections within the configuration file can have commands specified within them. For a full description of these key-values please see our full reference.

  • build -> commmands
  • install -> commands
  • before_install
  • before_upgrade
  • after_install
  • after_upgrade
  • before_uninstall
  • after_uninstall

The build and install sections have an explicit commands key-value due to both of these sections having other possible key-values within them.

  commands: |
    python3.6 -m venv ./venv/
    ./venv/bin/pip install -r requirements.txt

Each of the before_install, before_upgrade, after_install, after_upgrade, before_uninstall, after_uninstall are all implicitly command sections and don't require a commands key:

after_install: |
  systemctl enable myapp
  systemctl start myapp

How to specify commands

Commands can be added in a few different ways, you can choose whichever one is easier for you.

A commands field value data type can be either a string (single or multi-line) or a list with several different key-value options.

Single line strings

after_install: systemctl enable myapp --now

Multiline strings

It is advised to use a pipe (|) to indicate multi-line strings instead of a right angle bracket (>) if you want one command per line. A pipe will keep newlines indicating each line is a new command whereas a right angle bracket will cause the line to be folded and each line added together. See for more information.

after_upgrade: |
  systemctl daemon-reload
  systemctl restart myapp

:ist of key-values

You can use a list of key-values with the keys run or files.

run will simply run each line in order:

  - run: systemctl daemon-reload
  - run: systemctl restart myapp

The file key takes a string value which is a relative path to a file in your git repository, meaning the same commands can be used across multiple configuration files:

  - file: ./  # Relative path from the git repo root

The path to the file needs to be relative from the repository root and it is not required for the file to be copied to the end-user machine on install.

In the above example the parser will take each line in the file ./ and run them one after another. This does mean things like shebangs and set may not be respected.

You can use a mix of file and run in the same commands list (or multiples of each):

  - file: ./
  - file: ./app_commands.txt
  - run: systemctl start myapp

When command sections are run

Due to when the different sections are run in the install process, you need to be careful with CLI's and files could exist at the time the command will run.

For example, trying to use the script your package installs in the before_install section will obviously fail as your software has not been installed yet.

  • build commands - run during the build on a PKG Deploy server, not on the end-user machine. This means no absolute paths can be used as you can't assume the file will exist on the build server. Be careful with paths here
  • before_install commands - run before any of the install section has ever been run. After the dependencies stated in requires have been checked but before they have been installed
  • before_upgrade commands - run before the install section but your software must have been installed before. Don't assume the user is upgrading the version directly before, it could be a while since they upgraded
  • install commands - Commands needed to actually install the software on the end-user machine. Any commands here can't assume installed files exist yet. Be careful with paths here
  • after_install commands - Run after the install section has finished. You can assume all of the files are in their installed location.
  • after_upgrade commands - Run after the install section has finished. You can assume all of the files are in their installed location.
  • before_uninstall commands - Run before installed files are removed from the end-users machine
  • after_uninstall commands - Run after all the packaged files are removed from the end-users machine

Paths within commands

Due to timings of when commands outlined above are run, you need to be careful writing commands which interact with files.

There are a few other times when you need to be careful when running commands which interact with files due to where commands are run and where files are located at the time.

Please ensure you use relative paths when referring to files or directories located in your git repository in the build and install sections. The relative path starts at the root of the git repository.

Use absolute paths when referring to files or directories on the end-user machine. This includes files and directories that have been installed via your package.

Build section

Not run on the end-user machine. Assume totally blank server except for the git repository you are installing.

Install section

As mentioned above when talking about copying files, install instructions don't use normal paths on the end-user machine. That means it's generally not a good idea to use absolute paths within the commands part of the install section.

As a general rule, if one of your commands assumes a file is in its installed location or modifies a file put in place by a dependency please use the after_install or after_upgrade sections.

Staging area paths

WARNING this is not advised. Please be VERY sure you can't put the commands in the after_install or after_upgrade keys

It should be mentioned it is possible to define the correct path to any file in the staging area is needed. Below are the paths you can use depending on the package format you are creating:

  • rpm - File path must start with %{buildroot}. For example:
    • rm %{buildroot}/var/lib/myapp/file.txt
  • deb - File path must start with %{buildroot}. For example:
    • rm ${DESTDIR}/var/lib/myapp/file.txt

No user input

Any commands you run that require a prompt / user input will cause the build to fail. You need to ensure that any command you use does not prompt for user input.

E.g. Use rm -f file.txt instead of rm file.txt