version:2.1orbs:python:circleci/python@2.1.1workflows:main:jobs:- python/test- deploy:name:Deploy Devrequires:[python/test ]context:[cera-boa-dev ]#Feature and Dev work use a dev context available to any branch- deploy:name:Deploy Productionrequires:[Deploy Dev ]context:[cera-boa-prod ]#Prod releases use a dedicated contextfilters:branches:only:[main, dev123 ]# Tat should only ever be used on main branch, this is a violation!## Jobs included for valid config, replace with your own.#jobs:deploy:executor:python/defaultsteps:- run:echo "Hello Governance!"
packageorgimportfuture.keywords#Eachfileisasinglepolicypolicy_name["prod_context_protection"]#Mayactivate1tomanyrulesenable_rule["use_prod_context_on_main"]#RulesdefaulttoSOFT_FAIL/WARNING,butcanbeahard_fail/BLOCKhard_fail["use_prod_context_on_main"]#Customruleisaregofunctionthatiteratesconfig.ymlobjecttocomparebranchwithcontextuse.use_prod_context_on_main[reason]{somewfName,workflowininput.workflowssomejobinworkflow.jobssomejobName,jobInfoinjobsomecontextinto_array(jobInfo.context)#Ifthejobisusingany'prod'contextsregex.match("prod",context)#butisnotexclusivetomainbranchnotjob_is_only_main(jobInfo)#displaythisfailurereasontouser.reason:=sprintf("You may not use production context: %s outside of main branch. Offending workflow.job: `%s.%s` %s",[context,wfName,job_name(jobName,jobInfo),reason_contact_footer])}#Helperfunctions#Convertvaluetoarayifitisn'toneto_array(value):=[value]if{notis_array(value)}else:=value#Use`name`ifprovided,otherwiseusekeynamejob_name(jobName,jobInfo):=jobInfo.nameif{jobInfo.name}else:=jobName#returnstrueifjobonlyhasbranch.onlyanditismainjob_is_only_main(job):=true{only:=to_array(job.filters.branches.only)count(only)==1only[0]=="main"}else:=false
Advanced: Apply Policy as Pipeline
We highly recommend all policy live in a protected repository applied through a strongly managed lifecycle including approvals and automated testing and promotion.