cumulusci-plus 5.0.26__py3-none-any.whl → 5.0.27__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cumulusci-plus might be problematic. Click here for more details.

cumulusci/__about__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "5.0.26"
1
+ __version__ = "5.0.27"
@@ -53,6 +53,7 @@ Option values/overrides can be passed in at a number of levels, in increasing or
53
53
 
54
54
  import copy
55
55
  import logging
56
+ import os
56
57
  from collections import defaultdict
57
58
  from operator import attrgetter
58
59
  from typing import (
@@ -543,6 +544,7 @@ class FlowCoordinator:
543
544
  self._jinja2_context = {
544
545
  "project_config": project_config,
545
546
  "org_config": org_config,
547
+ "env": dict(os.environ),
546
548
  }
547
549
  self._context_project_config = project_config
548
550
  self._context_org_config = org_config
@@ -542,6 +542,106 @@ class TestSimpleTestFlowCoordinator(AbstractFlowCoordinatorTest):
542
542
  flow.run(self.org_config)
543
543
  assert len(flow.results) == 0
544
544
 
545
+ def test_run__when_condition_with_env_var_true(self):
546
+ """A flow step runs when env var condition evaluates to True"""
547
+ import os
548
+
549
+ with mock.patch.dict(os.environ, {"RUN_TASK": "true"}):
550
+ flow_config = FlowConfig(
551
+ {
552
+ "steps": {
553
+ 1: {
554
+ "task": "pass_name",
555
+ "when": "env.get('RUN_TASK') == 'true'",
556
+ }
557
+ }
558
+ }
559
+ )
560
+ flow = FlowCoordinator(self.project_config, flow_config)
561
+ flow.run(self.org_config)
562
+ assert len(flow.results) == 1
563
+
564
+ def test_run__when_condition_with_env_var_false(self):
565
+ """A flow step is skipped when env var condition evaluates to False"""
566
+ import os
567
+
568
+ with mock.patch.dict(os.environ, {"RUN_TASK": "false"}):
569
+ flow_config = FlowConfig(
570
+ {
571
+ "steps": {
572
+ 1: {
573
+ "task": "pass_name",
574
+ "when": "env.get('RUN_TASK') == 'true'",
575
+ }
576
+ }
577
+ }
578
+ )
579
+ flow = FlowCoordinator(self.project_config, flow_config)
580
+ flow.run(self.org_config)
581
+ assert len(flow.results) == 0
582
+
583
+ def test_run__when_condition_with_env_var_default(self):
584
+ """A flow step uses default value when env var is not set"""
585
+ import os
586
+
587
+ # Make sure the env var is not set
588
+ if "UNDEFINED_VAR" in os.environ:
589
+ del os.environ["UNDEFINED_VAR"]
590
+ flow_config = FlowConfig(
591
+ {
592
+ "steps": {
593
+ 1: {
594
+ "task": "pass_name",
595
+ "when": "env.get('UNDEFINED_VAR', 'default') == 'default'",
596
+ }
597
+ }
598
+ }
599
+ )
600
+ flow = FlowCoordinator(self.project_config, flow_config)
601
+ flow.run(self.org_config)
602
+ assert len(flow.results) == 1
603
+
604
+ def test_run__when_condition_with_env_var_and_org_config(self):
605
+ """A flow step can combine env vars with org_config in when condition"""
606
+ import os
607
+
608
+ with mock.patch.dict(os.environ, {"DEPLOY_TO_SCRATCH": "true"}):
609
+ flow_config = FlowConfig(
610
+ {
611
+ "steps": {
612
+ 1: {
613
+ "task": "pass_name",
614
+ "when": "org_config.scratch and env.get('DEPLOY_TO_SCRATCH') == 'true'",
615
+ }
616
+ }
617
+ }
618
+ )
619
+ flow = FlowCoordinator(self.project_config, flow_config)
620
+ # Set org_config.scratch to True
621
+ self.org_config.config["scratch"] = True
622
+ flow.run(self.org_config)
623
+ assert len(flow.results) == 1
624
+
625
+ def test_run__when_condition_with_missing_env_var_is_none(self):
626
+ """A flow step can check if env var exists using 'is not none'"""
627
+ import os
628
+
629
+ # Test when var is set
630
+ with mock.patch.dict(os.environ, {"MY_VAR": "value"}):
631
+ flow_config = FlowConfig(
632
+ {
633
+ "steps": {
634
+ 1: {
635
+ "task": "pass_name",
636
+ "when": "env.get('MY_VAR') is not none",
637
+ }
638
+ }
639
+ }
640
+ )
641
+ flow = FlowCoordinator(self.project_config, flow_config)
642
+ flow.run(self.org_config)
643
+ assert len(flow.results) == 1
644
+
545
645
  def test_run__task_raises_exception_fail(self):
546
646
  """A flow aborts when a task raises an exception"""
547
647
 
@@ -224,7 +224,7 @@ class CredentialManager:
224
224
  env_secrets_type = "CUMULUSCI_SECRETS_TYPE"
225
225
 
226
226
  @staticmethod
227
- def _load_secrets_type_from_environment() -> str:
227
+ def load_secrets_type_from_environment() -> str:
228
228
  """Load any secrets specified by environment variables"""
229
229
  provider_type = os.getenv(CredentialManager.env_secrets_type)
230
230
 
@@ -240,7 +240,7 @@ class CredentialManager:
240
240
  """
241
241
  if not provider_type:
242
242
  # If no config is provided, load the secrets from the environment
243
- provider_type = CredentialManager._load_secrets_type_from_environment()
243
+ provider_type = CredentialManager.load_secrets_type_from_environment()
244
244
 
245
245
  # Check if the requested provider type exists in our registry
246
246
  if provider_type not in CredentialProvider._registry:
@@ -19,8 +19,8 @@ class SecretsToEnv(BaseTask):
19
19
  class Options(CCIOptions):
20
20
  env_path: Path = Field("./.env", description="Path to the .env file")
21
21
  secrets_provider: str = Field(
22
- "local",
23
- description="Secrets provider type i.e local, ado_variables, aws_secrets. Defaults to 'local'",
22
+ None,
23
+ description='Secrets provider type i.e local, ado_variables, aws_secrets. Default value is None, which will use the secrets type from the environment variable CUMULUSCI_SECRETS_TYPE if it is set, otherwise it will use the "local" provider.',
24
24
  )
25
25
  provider_options: MappingOption = Field({}, description="Provider options")
26
26
  secrets: Union[ListOfStringsOption, MappingOption] = Field(
@@ -33,7 +33,9 @@ class SecretsToEnv(BaseTask):
33
33
  def _init_options(self, kwargs):
34
34
  super()._init_options(kwargs)
35
35
  self.provider = CredentialManager.get_provider(
36
- self.parsed_options.secrets_provider, **self.parsed_options.provider_options
36
+ self.parsed_options.secrets_provider
37
+ or CredentialManager.load_secrets_type_from_environment(),
38
+ **self.parsed_options.provider_options,
37
39
  )
38
40
  self.env_values = dotenv_values(self.parsed_options.env_path)
39
41
 
@@ -427,19 +427,19 @@ class TestCredentialManager:
427
427
  @mock.patch.dict(os.environ, {"CUMULUSCI_SECRETS_TYPE": "local"})
428
428
  def test_load_secrets_type_from_environment(self):
429
429
  """Test loading secrets type from environment variable."""
430
- provider_type = CredentialManager._load_secrets_type_from_environment()
430
+ provider_type = CredentialManager.load_secrets_type_from_environment()
431
431
  assert provider_type == "local"
432
432
 
433
433
  @mock.patch.dict(os.environ, {"CUMULUSCI_SECRETS_TYPE": "AWS_SECRETS"})
434
434
  def test_load_secrets_type_case_insensitive(self):
435
435
  """Test loading secrets type is case insensitive."""
436
- provider_type = CredentialManager._load_secrets_type_from_environment()
436
+ provider_type = CredentialManager.load_secrets_type_from_environment()
437
437
  assert provider_type == "aws_secrets"
438
438
 
439
439
  @mock.patch.dict(os.environ, {}, clear=True)
440
440
  def test_load_secrets_type_defaults_to_local(self):
441
441
  """Test loading secrets type defaults to 'local' when not set."""
442
- provider_type = CredentialManager._load_secrets_type_from_environment()
442
+ provider_type = CredentialManager.load_secrets_type_from_environment()
443
443
  assert provider_type == "local"
444
444
 
445
445
  @mock.patch.dict(os.environ, {"CUMULUSCI_SECRETS_TYPE": "environment"})
@@ -29,7 +29,7 @@ class TestSecretsToEnvOptions:
29
29
  )
30
30
 
31
31
  assert task.parsed_options.env_path == Path(env_path)
32
- assert task.parsed_options.secrets_provider == "local"
32
+ assert task.parsed_options.secrets_provider is None
33
33
  assert task.parsed_options.provider_options == {}
34
34
  assert task.parsed_options.secrets == []
35
35
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cumulusci-plus
3
- Version: 5.0.26
3
+ Version: 5.0.27
4
4
  Summary: Build and release tools for Salesforce developers
5
5
  Project-URL: Homepage, https://github.com/jorgesolebur/CumulusCI
6
6
  Project-URL: Changelog, https://cumulusci.readthedocs.io/en/stable/history.html
@@ -129,14 +129,13 @@ license](https://github.com/SFDO-Tooling/CumulusCI/blob/main/LICENSE)
129
129
  and is not covered by the Salesforce Master Subscription Agreement.
130
130
 
131
131
  <!-- Changelog -->
132
- ## v5.0.26 (2025-10-14)
132
+ ## v5.0.27 (2025-10-24)
133
133
  <!-- Release notes generated using configuration in .github/release.yml at main -->
134
134
 
135
135
  ## What's Changed
136
136
  ### Changes
137
- * Fix lint issues. by [@rupeshjSFDC](https://github.com/rupeshjSFDC) in [#95](https://github.com/jorgesolebur/CumulusCI/pull/95)
138
- * Fix failing test on Mac with Python 3.11 and 3.13 by [@rupeshjSFDC](https://github.com/rupeshjSFDC) in [#97](https://github.com/jorgesolebur/CumulusCI/pull/97)
139
- * Feature/secret manager by [@rupeshjSFDC](https://github.com/rupeshjSFDC) in [#99](https://github.com/jorgesolebur/CumulusCI/pull/99)
137
+ * Fix default secret provider to load from env when not set. by [@rupeshjSFDC](https://github.com/rupeshjSFDC) in [#103](https://github.com/jorgesolebur/CumulusCI/pull/103)
138
+ * PM-2264 - Supporting env variables in when conditions in tasks by [@jorgesolebur](https://github.com/jorgesolebur) in [#102](https://github.com/jorgesolebur/CumulusCI/pull/102)
140
139
 
141
140
 
142
- **Full Changelog**: https://github.com/jorgesolebur/CumulusCI/compare/v5.0.25...v5.0.26
141
+ **Full Changelog**: https://github.com/jorgesolebur/CumulusCI/compare/v5.0.26...v5.0.27
@@ -1,4 +1,4 @@
1
- cumulusci/__about__.py,sha256=ZVNJcSyXHBMkob2w7pyAhX0LNnYHO7scPU_ovQgdwtw,23
1
+ cumulusci/__about__.py,sha256=00l3VpAmIUGtJpCaTdCh0uWz16QeTxQS7eXpUbMsZpw,23
2
2
  cumulusci/__init__.py,sha256=jdanFQ_i8vbdO7Eltsf4pOfvV4mwa_Osyc4gxWKJ8ng,764
3
3
  cumulusci/__main__.py,sha256=kgRH-n5AJrH_daCK_EJwH7azAUxdXEmpi-r-dPGMR6Y,43
4
4
  cumulusci/conftest.py,sha256=AIL98BDwNAQtdo8YFmLKwav0tmrQ5dpbw1cX2FyGouQ,5108
@@ -37,7 +37,7 @@ cumulusci/core/datasets.py,sha256=cd0cWe8y2cJ1xHhLz06mzEF-efqywnQSM8vZ_6FzNGE,10
37
37
  cumulusci/core/debug.py,sha256=SB2FZXzeI5XSXiQtwyrpzdxFWqSHLj2vjCddMMRibXM,839
38
38
  cumulusci/core/enums.py,sha256=cG7qgegc5EAmwBzxLbociJ1zsG_fbbVZ29g5zywk908,272
39
39
  cumulusci/core/exceptions.py,sha256=7LxVFnalXG_9IU_fKmWhk_O1Gmxv4GolUW1jycaFcl8,6696
40
- cumulusci/core/flowrunner.py,sha256=mzNP_ErqLzO0xmEwWtJLPM5j8GeveP_L1hMWt1NeHck,35426
40
+ cumulusci/core/flowrunner.py,sha256=Zt2WBWn86ecH8zIx55-ZpD0AkX_dtEO7XJEhvd0blYw,35477
41
41
  cumulusci/core/github.py,sha256=Q9w_ECBhB7Lnlh4aUzlHp3-fHavz00Dj-26hSOQxaRM,23457
42
42
  cumulusci/core/runtime.py,sha256=H2e3YN2i_nPiB2oVB_0V0rLsmTqBs8CdajdGOA4gsB0,3776
43
43
  cumulusci/core/sfdx.py,sha256=dx0TXLioR8p6DNOiEzrFUiFbSH5dZGmpFZLkdW83z-4,4790
@@ -98,7 +98,7 @@ cumulusci/core/source_transforms/tests/test_transforms.py,sha256=jOAGdvTziU0GsAH
98
98
  cumulusci/core/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
99
  cumulusci/core/tests/test_datasets_e2e.py,sha256=QoLCA6qmjQ_av7k0Ar-KgIf2ORrJ1VUhavpMFWwsTrg,13648
100
100
  cumulusci/core/tests/test_exceptions.py,sha256=fFGAOYPQpFKHOi0VCX9oDM_APj6DK6vKMHFCiKhtiS8,460
101
- cumulusci/core/tests/test_flowrunner.py,sha256=rcJyGp7WTWMA3JP64HDtDa9OpUSOPtbISkvELkklDXM,30912
101
+ cumulusci/core/tests/test_flowrunner.py,sha256=C1vn1AizlpD5Tt5gzxnesJvFum5_ua-sphAbUU6zEpQ,34539
102
102
  cumulusci/core/tests/test_github.py,sha256=cXsCAMzub2EUAI0_x2CYBR-bn4FE_OYe72zZOMdt-WY,34462
103
103
  cumulusci/core/tests/test_sfdx.py,sha256=-pC6oGVF5H_OQfZxUG_YbPCYddxWhBS6gPImKO-XqN4,4540
104
104
  cumulusci/core/tests/test_source.py,sha256=m66vXcgMwc92R1OotTdMzd6Mg6gAHj5QrYJMDnL_i5s,24468
@@ -626,14 +626,14 @@ cumulusci/tasks/tests/test_pushfails.py,sha256=9JG9D0iD4dR-1fKheaRN7BEy3lzzuOKeR
626
626
  cumulusci/tasks/tests/test_salesforce.py,sha256=yCGtuHapxyAEmXQhuF2g2fh2naknTu7Md4OfEJQvGAA,2594
627
627
  cumulusci/tasks/tests/test_sfdx.py,sha256=oUbHo28d796m5RuskXMLitJw2rCLjjXIfxggzr4gsso,3545
628
628
  cumulusci/tasks/tests/test_util.py,sha256=SHNXQdfo3pxH7oFGvd-IpJS9noEoL4lm2b3CqW3KNws,9212
629
- cumulusci/tasks/utility/credentialManager.py,sha256=QsXKzal4ubPZBEWWWkuL-my8ngDTGj06wX4ov4gxmK4,9262
629
+ cumulusci/tasks/utility/credentialManager.py,sha256=wXCCsmGSMyoLjZF_4ONnZpLY1C-OuRA5d1RRigbqhjs,9260
630
630
  cumulusci/tasks/utility/directoryRecreator.py,sha256=PjUBOOxJy2DQbjimkp1XYScdH07TtutZ_1CYLlHK1YA,934
631
631
  cumulusci/tasks/utility/env_management.py,sha256=hJX6ySEiXD2oFW38JqbGQKMj89ucxdSBsPwytSdkgO8,6591
632
- cumulusci/tasks/utility/secretsToEnv.py,sha256=RBJZQrwEa_geDrK8znyZh7iwWW2Xt2hgRYiwuCKNHsI,4427
633
- cumulusci/tasks/utility/tests/test_credentialManager.py,sha256=jXBTzxoMdIBWsjCrlRmssJv38lteg9dA7jXT9F0nxXI,24088
632
+ cumulusci/tasks/utility/secretsToEnv.py,sha256=uqGsms7YpCVIbZ_NjsPZC242EkpzTJfvSxPnGipP60Q,4653
633
+ cumulusci/tasks/utility/tests/test_credentialManager.py,sha256=lm9MtaPw54VxvXIX91hDVkFdwWJiyTs1BSpicB-Tbd4,24085
634
634
  cumulusci/tasks/utility/tests/test_directoryRecreator.py,sha256=zfBf_CMWHTGCKeHyoWPZ_kcu0rcU1H3e2MavqpJXabo,15488
635
635
  cumulusci/tasks/utility/tests/test_env_management.py,sha256=fw34meWGOe1YYZO449MMCi2O7BgSaOA_I_wScrIr1Uk,8702
636
- cumulusci/tasks/utility/tests/test_secretsToEnv.py,sha256=2xDHERPWViSHdMXqzI8pIxZCJji9JiILlVzvgOw9m3M,35646
636
+ cumulusci/tasks/utility/tests/test_secretsToEnv.py,sha256=rKj1jNJlFZIOBGpRPtHlV54x__p_YCYQEW1nA2NV5wU,35643
637
637
  cumulusci/tasks/vcs/__init__.py,sha256=ZzpMZnhooXZ6r_ywBVTS3UNw9uMcXW6h33LylRqTDK0,700
638
638
  cumulusci/tasks/vcs/commit_status.py,sha256=hgPUVHeQyIfMsCuwrw2RI-ufnbjdRARc6HI3BEgdcxI,2332
639
639
  cumulusci/tasks/vcs/create_commit_status.py,sha256=kr_OFM3J32jxusS1og-K91Kl1F_Nr7SlevRsJKBhifs,1565
@@ -759,9 +759,9 @@ cumulusci/vcs/tests/dummy_service.py,sha256=RltOUpMIhSDNrfxk0LhLqlH4ppC0sK6NC2cO
759
759
  cumulusci/vcs/tests/test_vcs_base.py,sha256=9mp6uZ3lTxY4onjUNCucp9N9aB3UylKS7_2Zu_hdAZw,24331
760
760
  cumulusci/vcs/tests/test_vcs_bootstrap.py,sha256=N0NA48-rGNIIjY3Z7PtVnNwHObSlEGDk2K55TQGI8g4,27954
761
761
  cumulusci/vcs/utils/__init__.py,sha256=py4fEcHM7Vd0M0XWznOlywxaeCtG3nEVGmELmEKVGU8,869
762
- cumulusci_plus-5.0.26.dist-info/METADATA,sha256=f-lYlolfi4S3DpMQ7zPvRmVCeNCmCat1-WoxIUiNJpo,6102
763
- cumulusci_plus-5.0.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
764
- cumulusci_plus-5.0.26.dist-info/entry_points.txt,sha256=nTtu04b9iLXhzADcTrb5PwmdXE6e2MTUAMh9OK6Z2pg,80
765
- cumulusci_plus-5.0.26.dist-info/licenses/AUTHORS.rst,sha256=PvewjKImdKPhhJ6xR2EEZ4T7GbpY2ZeAeyWm2aLtiMQ,676
766
- cumulusci_plus-5.0.26.dist-info/licenses/LICENSE,sha256=NFsF_s7RVXk2dU6tmRAN8wF45pnD98VZ5IwqOsyBcaU,1499
767
- cumulusci_plus-5.0.26.dist-info/RECORD,,
762
+ cumulusci_plus-5.0.27.dist-info/METADATA,sha256=PDgZ2P1Jq-AhjR7HzIBlPv9fWcq9zo2wJQRpUdTcens,6028
763
+ cumulusci_plus-5.0.27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
764
+ cumulusci_plus-5.0.27.dist-info/entry_points.txt,sha256=nTtu04b9iLXhzADcTrb5PwmdXE6e2MTUAMh9OK6Z2pg,80
765
+ cumulusci_plus-5.0.27.dist-info/licenses/AUTHORS.rst,sha256=PvewjKImdKPhhJ6xR2EEZ4T7GbpY2ZeAeyWm2aLtiMQ,676
766
+ cumulusci_plus-5.0.27.dist-info/licenses/LICENSE,sha256=NFsF_s7RVXk2dU6tmRAN8wF45pnD98VZ5IwqOsyBcaU,1499
767
+ cumulusci_plus-5.0.27.dist-info/RECORD,,