From 76e40123eb64d662c471b99e535bf6a716a2f451 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 27 Oct 2024 00:32:22 -0400 Subject: [PATCH 1/8] add field for specifying dependencies that need to be published --- src/python/pants/core/goals/deploy.py | 39 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/python/pants/core/goals/deploy.py b/src/python/pants/core/goals/deploy.py index d3190508da8..b363f399a93 100644 --- a/src/python/pants/core/goals/deploy.py +++ b/src/python/pants/core/goals/deploy.py @@ -11,6 +11,7 @@ from pants.core.goals.package import PackageFieldSet from pants.core.goals.publish import PublishFieldSet, PublishProcesses, PublishProcessesRequest +from pants.engine.addresses import UnparsedAddressInputs from pants.engine.console import Console from pants.engine.environment import EnvironmentName from pants.engine.goal import Goal, GoalSubsystem @@ -22,17 +23,33 @@ FieldSetsPerTarget, FieldSetsPerTargetRequest, NoApplicableTargetsBehavior, + SpecialCasedDependencies, Target, TargetRootsToFieldSets, TargetRootsToFieldSetsRequest, + Targets, ) from pants.engine.unions import union from pants.option.option_types import BoolOption -from pants.util.strutil import pluralize, softwrap +from pants.util.docutil import bin_name +from pants.util.strutil import help_text, pluralize, softwrap logger = logging.getLogger(__name__) +class DeploymentPublishDependencies(SpecialCasedDependencies): + alias = "publish_dependencies" + help = help_text( + f""" + Addresses to targets that should be packaged with the `{bin_name()} experimental-deploy` goal + and whose resulting artifacts should be published. + Pants will publish the artifacts as if you had run `{bin_name()} publish`. + + For example, this will allow you to publish Docker images that will be used when deploying a Helm chart. + """ + ) + + @union(in_scope_types=[EnvironmentName]) @dataclass(frozen=True) class DeployFieldSet(FieldSet, metaclass=ABCMeta): @@ -42,6 +59,8 @@ class DeployFieldSet(FieldSet, metaclass=ABCMeta): result of the deploy rule. """ + publish_dependencies: DeploymentPublishDependencies + @dataclass(frozen=True) class DeployProcess: @@ -199,12 +218,28 @@ async def run_deploy(console: Console, deploy_subsystem: DeploySubsystem) -> Dep for field_set in target_roots_to_deploy_field_sets.field_sets ) - publish_targets = ( + deploy_publish_dependencies = await MultiGet( + Get( + Targets, + UnparsedAddressInputs, + field_set.publish_dependencies.to_unparsed_address_inputs(), + ) + for field_set in target_roots_to_deploy_field_sets.field_sets + ) + specified_publish_targets = ( + set(chain.from_iterable(deploy_publish_dependencies)) + if deploy_subsystem.publish_dependencies + else set() + ) + + inferred_publish_targets = ( set(chain.from_iterable([deploy.publish_dependencies for deploy in deploy_processes])) if deploy_subsystem.publish_dependencies else set() ) + publish_targets = inferred_publish_targets | specified_publish_targets + logger.debug(f"Found {pluralize(len(publish_targets), 'dependency')}") publish_processes = await _all_publish_processes(publish_targets) From 65efc6e95b297f29ff0922085b8a8495b7e1a96b Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 27 Oct 2024 00:33:41 -0400 Subject: [PATCH 2/8] fix test involves putting `echo` bin into the sandbox --- src/python/pants/core/goals/deploy_test.py | 36 +++++++++++++------ .../pants/core/util_rules/system_binaries.py | 13 +++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/python/pants/core/goals/deploy_test.py b/src/python/pants/core/goals/deploy_test.py index 892845bc579..b855876a5d3 100644 --- a/src/python/pants/core/goals/deploy_test.py +++ b/src/python/pants/core/goals/deploy_test.py @@ -15,6 +15,7 @@ PublishRequest, ) from pants.core.register import rules as core_rules +from pants.core.util_rules.system_binaries import BinaryShims, BinaryShimsRequest, EchoBinary from pants.engine import process from pants.engine.fs import EMPTY_DIGEST from pants.engine.internals.scheduler import ExecutionError @@ -30,7 +31,7 @@ Targets, ) from pants.engine.unions import UnionRule -from pants.testutil.rule_runner import RuleRunner +from pants.testutil.rule_runner import RuleRunner, mock_console class MockDestinationField(StringField): @@ -57,6 +58,7 @@ class MockDeployTarget(Target): alias = "mock_deploy" core_fields = ( *COMMON_TARGET_FIELDS, + *DeployFieldSet.fields.values(), MockDestinationField, MockDependenciesField, ) @@ -104,10 +106,16 @@ async def mock_package(request: MockPackageFieldSet) -> BuiltPackage: @rule -async def mock_publish(request: MockPublishRequest) -> PublishProcesses: +async def mock_publish(request: MockPublishRequest, echo_binary: EchoBinary) -> PublishProcesses: if not request.field_set.repositories.value: return PublishProcesses() + echo = await Get( + BinaryShims, + BinaryShimsRequest, + BinaryShimsRequest.for_paths(echo_binary, rationale="echo the repo during testing"), + ) + return PublishProcesses( PublishPackages( names=tuple( @@ -116,7 +124,9 @@ async def mock_publish(request: MockPublishRequest) -> PublishProcesses: for artifact in pkg.artifacts if artifact.relpath ), - process=None if repo == "skip" else InteractiveProcess(["echo", repo]), + process=None + if repo == "skip" + else InteractiveProcess(["echo", repo], input_digest=echo.digest), description="(requested)" if repo == "skip" else repo, ) for repo in request.field_set.repositories.value @@ -124,19 +134,25 @@ async def mock_publish(request: MockPublishRequest) -> PublishProcesses: @rule -async def mock_deploy(field_set: MockDeployFieldSet) -> DeployProcess: +async def mock_deploy(field_set: MockDeployFieldSet, echo_binary: EchoBinary) -> DeployProcess: if not field_set.destination.value: return DeployProcess(name="test-deploy", publish_dependencies=(), process=None) + echo = await Get( + BinaryShims, + BinaryShimsRequest, + BinaryShimsRequest.for_paths(echo_binary, rationale="echo the repo during testing"), + ) + dependencies = await Get(Targets, DependenciesRequest(field_set.dependencies)) dest = field_set.destination.value return DeployProcess( - name="test-deploy", + name=field_set.address.spec, publish_dependencies=tuple(dependencies), description="(requested)" if dest == "skip" else None, process=None if dest == "skip" - else InteractiveProcess(["echo", dest], run_in_workspace=True), + else InteractiveProcess(["echo", dest], run_in_workspace=True, input_digest=echo.digest), ) @@ -186,11 +202,9 @@ def test_skip_deploy(rule_runner: RuleRunner) -> None: result = rule_runner.run_goal_rule(Deploy, args=("src:inst",)) assert result.exit_code == 0 - assert "test-deploy skipped (requested)." in result.stderr + assert "inst skipped (requested)." in result.stderr -@pytest.mark.skip("Can not run interactive process from test..?") -@pytest.mark.no_error_if_skipped def test_mocked_deploy(rule_runner: RuleRunner) -> None: rule_runner.write_files( { @@ -211,8 +225,10 @@ def test_mocked_deploy(rule_runner: RuleRunner) -> None: } ) - result = rule_runner.run_goal_rule(Deploy, args=("src:main",)) + with mock_console(rule_runner.options_bootstrapper): + result = rule_runner.run_goal_rule(Deploy, args=("src:main",)) assert result.exit_code == 0 assert "https://www.example.com" in result.stderr + assert "main" in result.stderr assert "production" in result.stderr diff --git a/src/python/pants/core/util_rules/system_binaries.py b/src/python/pants/core/util_rules/system_binaries.py index bb9e332ce0a..b96cf869fb8 100644 --- a/src/python/pants/core/util_rules/system_binaries.py +++ b/src/python/pants/core/util_rules/system_binaries.py @@ -406,6 +406,10 @@ class DuBinary(BinaryPath): pass +class EchoBinary(BinaryPath): + pass + + class ExprBinary(BinaryPath): pass @@ -944,6 +948,15 @@ async def find_du(system_binaries: SystemBinariesSubsystem.EnvironmentAware) -> return DuBinary(first_path.path, first_path.fingerprint) +@rule(desc="Finding the `echo` binary", level=LogLevel.DEBUG) +async def find_echo(system_binaries: SystemBinariesSubsystem.EnvironmentAware) -> EchoBinary: + """Useful for tests.""" + request = BinaryPathRequest(binary_name="echo", search_path=system_binaries.system_binary_paths) + paths = await Get(BinaryPaths, BinaryPathRequest, request) + first_path = paths.first_path_or_raise(request, rationale="echo file") + return EchoBinary(first_path.path, first_path.fingerprint) + + @rule(desc="Finding the `expr` binary", level=LogLevel.DEBUG) async def find_expr(system_binaries: SystemBinariesSubsystem.EnvironmentAware) -> ExprBinary: request = BinaryPathRequest(binary_name="expr", search_path=system_binaries.system_binary_paths) From 9a328ddefd451cf53c18f70dd80bd910bc6f24e9 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 27 Oct 2024 00:34:07 -0400 Subject: [PATCH 3/8] add tests for depoyment processing publishable dependencies --- src/python/pants/core/goals/deploy_test.py | 61 +++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/python/pants/core/goals/deploy_test.py b/src/python/pants/core/goals/deploy_test.py index b855876a5d3..efd9554d96d 100644 --- a/src/python/pants/core/goals/deploy_test.py +++ b/src/python/pants/core/goals/deploy_test.py @@ -231,4 +231,63 @@ def test_mocked_deploy(rule_runner: RuleRunner) -> None: assert result.exit_code == 0 assert "https://www.example.com" in result.stderr assert "main" in result.stderr - assert "production" in result.stderr + + +def test_mocked_deploy_rule_infer_publish_dependency(rule_runner: RuleRunner) -> None: + """Test that a rule can add publish dependencies from the infered dependencies.""" + rule_runner.write_files( + { + "src/BUILD": dedent( + """\ + mock_package( + name="dependency", + repositories=["https://www.example.com"], + ) + + mock_deploy( + name="main", + dependencies=[":dependency"], + destination="production", + ) + """ + ) + } + ) + + with mock_console(rule_runner.options_bootstrapper): + result = rule_runner.run_goal_rule(Deploy, args=("src:main",)) + + assert result.exit_code == 0 + assert "https://www.example.com" in result.stderr + assert "main" in result.stderr + + +def test_deploy_publishes_dependencies(rule_runner: RuleRunner) -> None: + """Test that the generic `publish_dependencies` results in published dependencies.""" + rule_runner.write_files( + { + "src/BUILD": dedent( + """\ + mock_package( + name="dependency", + repositories=["https://www.example.com"], + ) + + mock_deploy( + name="main", + publish_dependencies=[":dependency"], + destination="production", + ) + """ + ) + } + ) + + with mock_console(rule_runner.options_bootstrapper) as (console, stdio_reader): + result = rule_runner.run_goal_rule(Deploy, args=("src:main",)) + + assert result.exit_code == 0 + assert ( + "dependency" in result.stderr and "https://www.example.com" in result.stderr + ), "dependency was not published" + assert "main" in result.stderr, "was not deployed" From f2a31d237af20105542272153fb77b6d04ce5c43 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 27 Oct 2024 00:41:18 -0400 Subject: [PATCH 4/8] wire in for providers --- src/python/pants/backend/helm/target_types.py | 2 ++ src/python/pants/backend/terraform/goals/deploy.py | 2 +- src/python/pants/backend/terraform/target_types.py | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/python/pants/backend/helm/target_types.py b/src/python/pants/backend/helm/target_types.py index 8cf3ee07079..922afd995cd 100644 --- a/src/python/pants/backend/helm/target_types.py +++ b/src/python/pants/backend/helm/target_types.py @@ -8,6 +8,7 @@ from pants.backend.helm.resolve.remotes import ALL_DEFAULT_HELM_REGISTRIES from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior +from pants.core.goals.deploy import DeployFieldSet from pants.core.goals.package import OutputPathField from pants.core.goals.test import TestTimeoutField from pants.engine.internals.native_engine import AddressInput @@ -526,6 +527,7 @@ class HelmDeploymentTarget(Target): alias = "helm_deployment" core_fields = ( *COMMON_TARGET_FIELDS, + *DeployFieldSet.fields.values(), HelmDeploymentChartField, HelmDeploymentReleaseNameField, HelmDeploymentDependenciesField, diff --git a/src/python/pants/backend/terraform/goals/deploy.py b/src/python/pants/backend/terraform/goals/deploy.py index 9b9e3219d13..ac36c68d27f 100644 --- a/src/python/pants/backend/terraform/goals/deploy.py +++ b/src/python/pants/backend/terraform/goals/deploy.py @@ -29,7 +29,7 @@ @dataclass(frozen=True) -class DeployTerraformFieldSet(TerraformDeploymentFieldSet, DeployFieldSet): +class DeployTerraformFieldSet(TerraformDeploymentFieldSet): pass diff --git a/src/python/pants/backend/terraform/target_types.py b/src/python/pants/backend/terraform/target_types.py index 408262f223b..55d3baa5bc8 100644 --- a/src/python/pants/backend/terraform/target_types.py +++ b/src/python/pants/backend/terraform/target_types.py @@ -5,6 +5,7 @@ from dataclasses import dataclass +from pants.core.goals.deploy import DeployFieldSet from pants.engine.internals.native_engine import AddressInput from pants.engine.rules import collect_rules, rule from pants.engine.target import ( @@ -117,6 +118,7 @@ class TerraformDeploymentTarget(Target): alias = "terraform_deployment" core_fields = ( *COMMON_TARGET_FIELDS, + *DeployFieldSet.fields.values(), TerraformDependenciesField, TerraformRootModuleField, ) @@ -124,7 +126,7 @@ class TerraformDeploymentTarget(Target): @dataclass(frozen=True) -class TerraformDeploymentFieldSet(FieldSet): +class TerraformDeploymentFieldSet(DeployFieldSet): required_fields = ( TerraformDependenciesField, TerraformRootModuleField, From d3a945a38ee70eadd8ca286ac4611e412420ee7f Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 27 Oct 2024 19:25:27 -0400 Subject: [PATCH 5/8] document using `publish_dependencies` and add release notes --- docs/docs/helm/deployments.mdx | 16 +++++++++++++++- docs/docs/terraform/index.mdx | 20 ++++++++++++++++---- docs/notes/2.24.x.md | 4 ++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/docs/helm/deployments.mdx b/docs/docs/helm/deployments.mdx index 9d6f11cdbbb..a0baa8dc665 100644 --- a/docs/docs/helm/deployments.mdx +++ b/docs/docs/helm/deployments.mdx @@ -87,7 +87,9 @@ There are quite a few things to notice in the previous example: The `helm_deployment` target has many additional fields including the target kubernetes namespace, adding inline override values (similar to using helm's `--set` arg) and many others. Please run `pants help helm_deployment` to see all the possibilities. -## Dependencies with `docker_image` targets +## Dependencies + +### With `docker_image` targets A Helm deployment will in most cases deploy one or more Docker images into Kubernetes. Furthermore, it's quite likely there is going to be at least a few first party Docker images among those. Pants is capable of analysing the Helm chart being used in a deployment to detect those required first-party Docker images using Pants' target addresses to those Docker images. @@ -156,6 +158,18 @@ Pants' will rely on the behaviour of the `docker_image` target when it comes dow It's good practice to publish your Docker images using tags other than `latest` and Pants preferred behaviour is to choose those as this guarantees that the _version_ of the Docker image being deployed is the expected one. ::: +### Other publish dependencies + +You can automatically `publish` items before deploying. Add the publishable target to the `publish_dependencies` field. This is useful if Pants cannot infer the dependency on a `docker_image` target. + +```python tab={"label":"BUILD"} +docker_image(name="my_container") + +helm_chart(name="my_chart") + +helm_deployment(name="my_deployment", chart=":my_chart", publish_dependencies=[":my_container"]) +``` + ## Value files It's very common that Helm deployments use a series of files providing with values that customise the given chart. When using deployments that may have more than one YAML file as the source of configuration values, the Helm backend needs to sort the file names in a way that is consistent across different machines, as the order in which those files are passed to the Helm command is relevant. The final order depends on the same order in which those files are specified in the `sources` field of the `helm_deployment` target. For example, given the following `BUILD` file: diff --git a/docs/docs/terraform/index.mdx b/docs/docs/terraform/index.mdx index 6f69c2fffe2..9cfb70c6348 100644 --- a/docs/docs/terraform/index.mdx +++ b/docs/docs/terraform/index.mdx @@ -129,9 +129,9 @@ Pants can generate multi-platform lockfiles for Terraform. The setting `[downloa platforms = ["windows_amd64", "darwin_amd64", "linux_amd64"] ``` -### Basic Operations +## Basic Operations -#### Formatting +### Formatting Run `terraform fmt` as part of the `fix`, `fmt`, or `lint` goals. @@ -142,7 +142,7 @@ pants fix :: ✓ terraform-fmt made no changes. ``` -#### Validate +### Validate Run `terraform validate` as part of the `check` goal. @@ -161,7 +161,7 @@ Success! The configuration is valid. terraform_module(skip_terraform_validate=True) ``` -#### Deploying +### Deploying :::caution Terraform deployment support is in alpha stage Many options and features aren't supported yet. @@ -192,3 +192,15 @@ To run `terraform plan`, use the `--dry-run` flag of the `experimental-deploy` g ``` pants experimental-deploy --dry-run :: ``` + +#### Publishing before deploying + +You can automatically `publish` items before deploying. Add the publishable target to the `publish_dependencies` field. An example usecase is publishing a Docker image before deploying resources that will use it. + +```python tab={"label":"BUILD"} +docker_image(name="my_container") + +terraform_module(name="my_terraform") + +terraform_deployment(name="my_deployment", root_module=":my_terraform", publish_dependencies=[":my_container"]) +``` diff --git a/docs/notes/2.24.x.md b/docs/notes/2.24.x.md index 1c795cd127f..3f260960ac0 100644 --- a/docs/notes/2.24.x.md +++ b/docs/notes/2.24.x.md @@ -40,6 +40,10 @@ The "legacy" system will be removed in the 2.25.x series. Many tools that Pants downloads can now be exported using [the new `export --bin` option](https://www.pantsbuild.org/2.24/reference/goals/export#bin). For example, `pants export --bin="helm"` will export the `helm` binary to `dist/export/bin/helm`. For each tool, all the files are exported to a subfolder in `dist/export/bins/`, and the main executable is linked to `dist/export/bin/`. +#### Experimental-deploy + +The new field `publish_dependencies` allows for specifying dependencies that should be published before the deployment is run. Publishing dependencies before deploying can still be temporarily suppressed with the `--no-experimental-deploy-publish-dependencies` option. + ### Backends #### JVM From 1c84857d403c34a5e8727e48a284a3ff82f4b13e Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 27 Oct 2024 22:42:24 -0400 Subject: [PATCH 6/8] document creating a deployable target --- .../adding-a-deployment.mdx | 119 ++++++++++++++++++ .../common-plugin-tasks/index.mdx | 1 + .../common-plugin-tasks/plugin-lockfiles.mdx | 2 +- 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx diff --git a/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx b/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx new file mode 100644 index 00000000000..872e63b1ef2 --- /dev/null +++ b/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx @@ -0,0 +1,119 @@ +--- + title: Adding a Deployment + sidebar_position: 11 +--- + +How to create a custom deployment that is deployed with the `experimental-deploy` goal + +--- + +The `experimental-deploy` goal is experimental. Changes may be sudden, frequent, and breaking. + +This guide will walk you through implementing a target that supports being deployed. The advantage of this over implementing a `run` goal are sandboxed execution and the pre-publishing dependent targets. + +## 1. Create target and fieldsets for the target + +These allow for specifying the target in the BUILD file and referencing its contents + +```python tab={"label": "pants-plugins/my_deployment/target_types.py"} +from dataclasses import dataclass + +from pants.core.goals.deploy import DeployFieldSet +from pants.engine.target import COMMON_TARGET_FIELDS, Dependencies, DescriptionField, Target + + +# Example for fields your deployment might have +class MyDeploymentDependenciesField(Dependencies): + pass + + +@dataclass(frozen=True) +class MyDeploymentTarget(Target): + alias = "my_deployment" + core_fields = { + *COMMON_TARGET_FIELDS, + MyDeploymentDependenciesField + } + + +@dataclass(frozen=True) +class MyDeploymentFieldSet(DeployFieldSet): + required_fields = ( + MyDeploymentDependenciesField, + ) + description: DescriptionField + dependencies: MyDeploymentDependenciesField +``` + +## 2. Create a DeployFieldSet subclass + +A subclass of DeployFieldSet will ensure that it has the general fields of a deployment. + +```python tab={"label": "pants-plugins/my_deployment/deploy.py"} +@dataclass(frozen=True) +class DeployMyDeploymentFieldSet(MyDeploymentFieldSet, DeployFieldSet): + pass +``` + + +## 3. Rules to deploy + +Create a rule from the `DeployFieldSet` subclass to `DeployProcess` to actually deploy + +```python tab={"label": "pants-plugins/my_deployment/deploy.py"} +from pants.core.goals.deploy import DeployProcess, DeploySubsystem +from pants.engine.process import InteractiveProcess, Process +from pants.option.global_options import KeepSandboxes + +@rule(desc="Deploy my deployment") +async def run_my_deploy( + field_set: DeployMyDeploymentFieldSet, + deploy_subsystem: DeploySubsystem, + keep_sandboxes: KeepSandboxes, +) -> DeployProcess: + # If your deployment supports dry-run, you can hook into the flag here + if deploy_subsystem.dry_run: + ... + else: + ... + + deploy_process = InteractiveProcess.from_process( + Process(...), # Implementation of the command invocation + keep_sandboxes=keep_sandboxes + ) + + publish_dependencies = ... # you can infer dependencies that need to be published before the deployment + + return DeployProcess( + name=field_set.address.spec, + process=deploy_process, + publish_dependencies=publish_dependencies, # these will be published before the deployment + ) +``` + +## 4. Register rules + +At the bottom of the file, let Pants know what your rules and types do. Update your plugin's `register.py` to tell Pants about them. + +```python tab={"label": "pants-plugins/my_deployment/deploy.py"} +from pants.core.goals.deploy import DeployFieldSet +from pants.engine.rules import collect_rules +from pants.engine.unions import UnionRule + + +def rules(): + return ( + *collect_rules(), + UnionRule(DeployFieldSet, DeployMyDeploymentFieldSet) + ) +``` + +```python tab={"label": "pants-plugins/my_deployment/register.py"} +from my_deployment import deploy + +def rules(): + return [ + ..., + *deploy.rules() + ] +``` diff --git a/docs/docs/writing-plugins/common-plugin-tasks/index.mdx b/docs/docs/writing-plugins/common-plugin-tasks/index.mdx index 3a45674ffd8..6f47086b915 100644 --- a/docs/docs/writing-plugins/common-plugin-tasks/index.mdx +++ b/docs/docs/writing-plugins/common-plugin-tasks/index.mdx @@ -13,4 +13,5 @@ - [Add Tests](./run-tests.mdx) - [Add lockfile support](./plugin-lockfiles.mdx) - [Custom `setup-py` kwargs](./custom-python-artifact-kwargs.mdx) +- [Adding a deployment](./adding-a-deployment.mdx) - [Plugin upgrade guide](./plugin-upgrade-guide.mdx) \ No newline at end of file diff --git a/docs/docs/writing-plugins/common-plugin-tasks/plugin-lockfiles.mdx b/docs/docs/writing-plugins/common-plugin-tasks/plugin-lockfiles.mdx index 87da9be2e27..d0f97d9631c 100644 --- a/docs/docs/writing-plugins/common-plugin-tasks/plugin-lockfiles.mdx +++ b/docs/docs/writing-plugins/common-plugin-tasks/plugin-lockfiles.mdx @@ -100,7 +100,7 @@ async def generate_lockfile_from_sources( ## 4. Register rules -At the bottom of the file, let Pants know what your rules and types do. Update your plugin's `register.py` to tell Pants about them/ +At the bottom of the file, let Pants know what your rules and types do. Update your plugin's `register.py` to tell Pants about them. ```python tab={"label": "pants-plugins/fortran/lockfiles.py"} From 2f47e8862fc462eace34dbeaf546d06f85d96660 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Mon, 28 Oct 2024 00:00:58 -0400 Subject: [PATCH 7/8] directly use DeploymentPublishDependencies instead of including all fields of DeployFieldSet --- src/python/pants/backend/helm/target_types.py | 4 ++-- src/python/pants/backend/terraform/target_types.py | 4 ++-- src/python/pants/core/goals/deploy_test.py | 9 +++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/python/pants/backend/helm/target_types.py b/src/python/pants/backend/helm/target_types.py index 922afd995cd..a60cd2e0bfc 100644 --- a/src/python/pants/backend/helm/target_types.py +++ b/src/python/pants/backend/helm/target_types.py @@ -8,7 +8,7 @@ from pants.backend.helm.resolve.remotes import ALL_DEFAULT_HELM_REGISTRIES from pants.base.glob_match_error_behavior import GlobMatchErrorBehavior -from pants.core.goals.deploy import DeployFieldSet +from pants.core.goals.deploy import DeploymentPublishDependencies from pants.core.goals.package import OutputPathField from pants.core.goals.test import TestTimeoutField from pants.engine.internals.native_engine import AddressInput @@ -527,7 +527,7 @@ class HelmDeploymentTarget(Target): alias = "helm_deployment" core_fields = ( *COMMON_TARGET_FIELDS, - *DeployFieldSet.fields.values(), + DeploymentPublishDependencies, HelmDeploymentChartField, HelmDeploymentReleaseNameField, HelmDeploymentDependenciesField, diff --git a/src/python/pants/backend/terraform/target_types.py b/src/python/pants/backend/terraform/target_types.py index 55d3baa5bc8..38ba222aa10 100644 --- a/src/python/pants/backend/terraform/target_types.py +++ b/src/python/pants/backend/terraform/target_types.py @@ -5,7 +5,7 @@ from dataclasses import dataclass -from pants.core.goals.deploy import DeployFieldSet +from pants.core.goals.deploy import DeployFieldSet, DeploymentPublishDependencies from pants.engine.internals.native_engine import AddressInput from pants.engine.rules import collect_rules, rule from pants.engine.target import ( @@ -118,7 +118,7 @@ class TerraformDeploymentTarget(Target): alias = "terraform_deployment" core_fields = ( *COMMON_TARGET_FIELDS, - *DeployFieldSet.fields.values(), + DeploymentPublishDependencies, TerraformDependenciesField, TerraformRootModuleField, ) diff --git a/src/python/pants/core/goals/deploy_test.py b/src/python/pants/core/goals/deploy_test.py index efd9554d96d..4d82386c6e5 100644 --- a/src/python/pants/core/goals/deploy_test.py +++ b/src/python/pants/core/goals/deploy_test.py @@ -6,7 +6,12 @@ import pytest -from pants.core.goals.deploy import Deploy, DeployFieldSet, DeployProcess +from pants.core.goals.deploy import ( + Deploy, + DeployFieldSet, + DeploymentPublishDependencies, + DeployProcess, +) from pants.core.goals.package import BuiltPackage, BuiltPackageArtifact, PackageFieldSet from pants.core.goals.publish import ( PublishFieldSet, @@ -58,7 +63,7 @@ class MockDeployTarget(Target): alias = "mock_deploy" core_fields = ( *COMMON_TARGET_FIELDS, - *DeployFieldSet.fields.values(), + DeploymentPublishDependencies, MockDestinationField, MockDependenciesField, ) From f371525430cd0c6a9c84eb40a85afa9bb05d1988 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Mon, 28 Oct 2024 00:01:16 -0400 Subject: [PATCH 8/8] add doc on creating deployable targets --- .../common-plugin-tasks/adding-a-deployment.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx b/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx index 872e63b1ef2..885b63fd354 100644 --- a/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx +++ b/docs/docs/writing-plugins/common-plugin-tasks/adding-a-deployment.mdx @@ -18,7 +18,7 @@ These allow for specifying the target in the BUILD file and referencing its cont ```python tab={"label": "pants-plugins/my_deployment/target_types.py"} from dataclasses import dataclass -from pants.core.goals.deploy import DeployFieldSet +from pants.core.goals.deploy import DeployFieldSet, DeploymentPublishDependencies from pants.engine.target import COMMON_TARGET_FIELDS, Dependencies, DescriptionField, Target @@ -32,7 +32,8 @@ class MyDeploymentTarget(Target): alias = "my_deployment" core_fields = { *COMMON_TARGET_FIELDS, - MyDeploymentDependenciesField + DeploymentPublishDependencies, # This enables manually specifying dependencies to publish before deploying + MyDeploymentDependenciesField, }