How can I reduce redundancy when using Contexts?

When env variables are configured for a project they can be accessed anywhere in the project. This is unfortunately not the case for contexts. You have to specify the context required for each job individually. If you have a lot of jobs that use this context this creates a lot of redundancy. Ex:
workflows:
build:
jobs:
- job1
context:
- dockerhub-creds
- job2
context:
- dockerhub-creds
- job3
context:
- dockerhub-creds
- job4
context:
- dockerhub-creds

Can we optionally allow contexts to apply to all jobs in a workflow to avoid this? Thanks!

3 Likes

Hi Stephen,

Welcome to CircleCI Discuss!

Currently, there is no way to configure workflows or pipelines this way. Also, I could not find a feature request for this, so please feel free to create one on our idea page under “Cloud Feature Requests”. A good title for this would be along the lines of “Pipeline Level Contexts” or “Workflow Level Contexts” depending what you feel fits your request best. Pipeline level would be for the entire configuration, while workflow level would probably be more realistic.

For now, you could use a built-in functionality of YAML, which are anchors and aliases. At the top of your configuration (or anywhere you find suitable) you could define a custom block that you could reuse anywhere in your configuration.

default-context: &default-context
  context:
    - dockerhub-cred
...
jobs:
   - test2:
       *default-context

That at least reduces the two lines down to one, but still isn’t exactly the best case. Another option would be to implement the dockerhub-creds into the environment variable for that project. Let me know if you create the feature request and I will happily support it!

1 Like

Hello, is this still the case? Or is there now a better way to set a default context that will be used for all jobs? I’d also like to be able to configure some default authentication to use for all Docker pulls. (My use-case is also for Docker Hub authentication.)

Hi Nathan!

Sorry for the late reply. There have not been any new changes to contexts as far as I know, outside of being able to provide more than one.

However, my colleague and I have been developing a config SDK, which gives you the ability to generate your workflow with dynamic config. Here’s a link to the repo if you’re interested: GitHub - CircleCI-Public/circleci-config-sdk-ts: Generate CircleCI Configuration YAML from JavaScript or TypeScript. Use Dynamic Configuration and the Config SDK together for live generative config.

You could achieve this with the SDK in many ways.
Create a helper function to return a new WorkflowJob with the default context
or
Create your own extension of WorkflowJob, and override the generate function to ensure the default context is in the list of contexts.

Then, if you wanted to take this to the next level, you could publish an npm package to reuse the function. Admittedly, it’s a bit of an extreme measure to achieve just this functionality, but the SDK unlocks a lot of power in how you conduct your config.

I have tried this approach, but it doesn’t work if there are more parameters passed to the job:

      - deploy-to-qa:
          *default-context
          requires:
            - quality-gate
          filters: 
            tags: # Ignore this job for all triggers coming from a tag webhook
              ignore:
                - /.*/

Validation will fail with invalid YML

You can use the << operator instead:

      - deploy-to-qa:
          <<: *default-context
          requires:
            - quality-gate
          filters: 
            tags: # Ignore this job for all triggers coming from a tag webhook
              ignore:
                - /.*/

Ref: YAML anchors | Bitbucket Cloud | Atlassian Support

I also wish for this feature!

One way around this is to integrate a third-party Key/Value service into your CI process.

I use a solution from the vendor Doppler to do this. Within CircleCI I have to manage the access tokens needed to provide access to the set of values used by a certain job, but all the other values are held in Doppler, which supports a Hierarchical Structure, so common values across configurations/contexts have to only be entered once.