We’re running into an issue where if we merge to multiple branches at the same time (or relatively quickly), this creates a race condition where we don’t know which commit’s CI/CD pipeline will finish last - and overwrite the package uploaded to Octopus.
E.g if we merge to develop and master at the same time and the CI/CD pipelines start at the same time, then sometimes develop artifact overwrites the master package - and gets incorrectly deployed to the staging environment (or vice versa - the master package gets deployed to the dev environment)
Is there a way to:
a) Configure octopus to tell it to not deploy any package to certain environments if the string ‘-SNAPSHOT’ is in the package version - or to only deploy packages that contain this string?
or
b) Create multiple octopus package registries corresponding to different environments - one registry per environment. Then in the deployment step, we can choose the correct feed based on the environment, as described here: Dynamically selecting packages at deployment time - Octopus Deploy
I think your best bet is to go with option A and use a combination of Channels and Package Versioning Rules.
You will want to have 2 channels, one for Staging, and one for your other environments. As you said, your Staging packages would have a pre-release tag of -SNAPSHOT, which your Staging channel would key off of with its Version Rule of ^SNAPSHOT
To go along with this, you would want to assign a lifecycle that only has the environments that you want to deploy -SNAPSHOT packages to. In my case, I’ve created a Staging Only lifecycle that only has the Staging environment.
Here is an example of what your Staging channel might look like:
To go along with this your other channel would have a lifecycle, for instance Production Only, and a version rule of ^$ (if you do not need any metadata at all) which means “Official releases are filtered to have nothing other than core version components (e.g. 1.0.0 )”.
You can check to make sure your Version Rules are working with your packages by clicking Design Rule at the bottom of the Version Rule section.
In your CI/CD pipeline you would then either supply --channel or --package(or both) which will help create the correct release based on the package being created in the pipeline.
If I understand correctly - this means that each channel will need to have a 1-1 correlation to the environment?
I.e we currently have 4 environments, dev, qa, staging, prod
So we’d need 4 corresponding channels - each with the corresponding pre-release tag?
And we’d no longer be able to use the same release to all the environments just by clicking the ‘Deploy to ’ button - instead we’d need to make a new release for each environment?
Yes we’re using Azure devops. The delay function will be helpful in the race condition scenario - please feel free to share any details.
But also, for some projects e.g front-end, we need to create different builds based on the environment - where at compile time, it needs different backend URLs which are baked into the project - so you end up with 4 different artifacts - one per environment.
It’d be really helpful if packages had a way to specify tags / environment per version. That’d solve both scenarios - race condition as well as multiple environment specific artifacts of a version.
That’s another method to have “different” packages based on your environment. You would have variables scoped to the environment and then the appropriate values get used when deployed to that specific environment.