Global project settings - best practices?

I’m looking to implement a solution for configuration variables that would apply globally across a project for all engines. Specifically, I’m looking to add an enable_ocio boolean to the project, so that I can check if it has been set to true or false and code accordingly. I could probably just add a string to templates.yml and be done with it, but I wonder if there is a way to add such a variable to the info.yml for the pipeline config? Or possibly to project.yml? Surely someone has done this before!

You can add fields to project entities and then pull them with the core hooks and store them in environment variables for later pickup in tools?
I’d not considered adding them as code before, so it would be interesting to hear other approaches. I imagine you can just stick them in a hook or arbitrary file and just parse that file as required?
I typically add this kind of config to the db, although I appreciate that this brings its own problems.

1 Like

Theres a lot of ways to add this.

A couple:

  • project field tickbox
  • project field poiting to an OCIO config
  • use a package manager like CPENV or REZ
  • make the pipeline check a project folder and if an config.ocio file exists, set the OCIO environment

etc

The solution that I used was to add a template named “enable_ocio” to the strings section of templates.yml, and set the definition to “true” or “false”. The code looks something like:

cb = sgtk.platform.current_bundle()
eot = cb.get_template_by_name("enable_ocio")
if eot and eot.definition.lower() in ['yes', 'y', 'true', '1']:
    # do some stuff

@Patrick I had considered adding a field to the project entity, but I was worried about the overhead of making a separate DB query every time I needed the parameter value. Although, if this is returned in context.project that would eliminate the need for the call.

@Ricardo do you know if the SG Toolkit developers had any thoughts as to where we would store these types of configuration parameters? It seems like templates.yml would work, as would your suggestions. However, templates.yml is really for, like, templates… it seems like this isn’t quite the use case they had in mind.

We have such a field in projects, specifically for ocio config path. True, it adds some overhead, but it is not really “hot” code, that is called 60 times a second, so a tenth of a second overall is not so bad.
It does add up though, so if possible, bunch up all fields needed from the project in one call.

Yup, what mmoshev says… also worth noting the call only needs to happen once on initial launch of a dcc. You never change project once in a dcc, so you can assume you don’t need to call the values more than once.
I also find it not advisable to put per-project settings in your pipeline config if you can avoid it. My aim has always been to attempt to have a single pipeline config across all projects, with any project specific configurations set on the project entity. This way, code (eg pipeline config) maintenance becomes MUCH simpler to manage as your studio scales up. You can ofcourse have a pipeline-config entity per-project to allow you to perform pipeline-config releases on a per-project level (eg to avoid upgrading the config during delivery of a project), but in general I update the descriptor of all my projects at the same time to the same uploaded pipeline config.

@Patrick so where do you keep the global configuration… in a non-project entity?

I’ve used both PipelineConfiguration entities, and more recently, software_bundle custom entities (the latter just so I can use the same CI/CD processes for releasing, and so I don’t pollute the pipelineConfiguration entities with every release).
I just have a single custom entity for pipeline configs that I upload any new releases to. I automatically generate a descriptor that gets updated on a field on the entity which allows me to easily copy-paste a new descriptor to the projects’ descriptors that need updated.
It’s easy to roll out change and to roll them back.