• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 25441711719

06 May 2026 02:31PM UTC coverage: 92.915%. Remained the same
25441711719

push

github

web-flow
use sha pin (with comment) format for generated actions (#23312)

Per the GitHub Action best practices we recently enabled at #23249, we
should pin each action to a SHA so that the reference is actually
immutable.

This will -- I hope -- knock out a large chunk of the 421 alerts we
currently get from zizmor. The next followup would then be upgrades and
harmonizing the generated and none-generated pins.

Notice: This idea was suggested by Claude while going over pinact output
and I was surprised to see that post processing the yaml wasn't too
gross.

92206 of 99237 relevant lines covered (92.91%)

4.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/python/pants/backend/terraform/goals/deploy.py
1
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3
from __future__ import annotations
3✔
4

5
import logging
3✔
6
from dataclasses import dataclass
3✔
7

8
from pants.backend.terraform.dependencies import TerraformInitRequest, prepare_terraform_invocation
3✔
9
from pants.backend.terraform.dependency_inference import (
3✔
10
    TerraformDeploymentInvocationFilesRequest,
11
    get_terraform_backend_and_vars,
12
)
13
from pants.backend.terraform.target_types import TerraformDeploymentFieldSet
3✔
14
from pants.backend.terraform.tool import (
3✔
15
    TerraformCommand,
16
    TerraformProcess,
17
    TerraformTool,
18
    setup_terraform_process,
19
)
20
from pants.backend.terraform.utils import terraform_arg, terraform_relpath
3✔
21
from pants.core.goals.deploy import DeployFieldSet, DeployProcess, DeploySubsystem
3✔
22
from pants.core.util_rules.source_files import SourceFilesRequest, determine_source_files
3✔
23
from pants.engine.engine_aware import EngineAwareParameter
3✔
24
from pants.engine.internals.native_engine import MergeDigests
3✔
25
from pants.engine.intrinsics import merge_digests
3✔
26
from pants.engine.process import InteractiveProcess
3✔
27
from pants.engine.rules import collect_rules, implicitly, rule
3✔
28
from pants.engine.target import SourcesField
3✔
29
from pants.engine.unions import UnionRule
3✔
30
from pants.option.global_options import KeepSandboxes
3✔
31
from pants.util.logging import LogLevel
3✔
32

33
logger = logging.getLogger(__name__)
3✔
34

35

36
@dataclass(frozen=True)
3✔
37
class DeployTerraformFieldSet(TerraformDeploymentFieldSet, DeployFieldSet):
3✔
38
    pass
3✔
39

40

41
@dataclass(frozen=True)
3✔
42
class TerraformDeploymentRequest(EngineAwareParameter):
3✔
43
    field_set: TerraformDeploymentFieldSet
3✔
44

45

46
@rule
3✔
47
async def prepare_terraform_deployment(
3✔
48
    request: TerraformDeploymentRequest,
49
    terraform_subsystem: TerraformTool,
50
    deploy_subsystem: DeploySubsystem,
51
    keep_sandboxes: KeepSandboxes,
52
) -> InteractiveProcess:
53
    deployment = await prepare_terraform_invocation(
1✔
54
        TerraformInitRequest(
55
            request.field_set.root_module,
56
            request.field_set.dependencies,
57
            initialise_backend=True,
58
        )
59
    )
60

61
    terraform_command = "plan" if deploy_subsystem.dry_run else "apply"
1✔
62
    args = [terraform_command]
1✔
63

64
    invocation_files = await get_terraform_backend_and_vars(
1✔
65
        TerraformDeploymentInvocationFilesRequest(
66
            request.field_set.dependencies.address, request.field_set.dependencies
67
        )
68
    )
69
    var_files = await determine_source_files(
1✔
70
        SourceFilesRequest(e.get(SourcesField) for e in invocation_files.vars_files)
71
    )
72
    for var_file in var_files.files:
1✔
73
        args.append(terraform_arg("-var-file", terraform_relpath(deployment.chdir, var_file)))
1✔
74

75
    with_vars = await merge_digests(
1✔
76
        MergeDigests(
77
            [
78
                var_files.snapshot.digest,
79
                deployment.terraform_sources.snapshot.digest,
80
                deployment.dependencies_files.snapshot.digest,
81
            ]
82
        )
83
    )
84

85
    if terraform_subsystem.args:
1✔
86
        args.extend(terraform_subsystem.args)
1✔
87

88
    process = await setup_terraform_process(
1✔
89
        TerraformProcess(
90
            cmds=(
91
                deployment.init_cmd.to_args(),
92
                TerraformCommand(tuple(args)),
93
            ),
94
            input_digest=with_vars,
95
            description=f"Terraform {terraform_command}",
96
            chdir=deployment.chdir,
97
        ),
98
        **implicitly(),
99
    )
100
    return InteractiveProcess.from_process(process, keep_sandboxes=keep_sandboxes)
1✔
101

102

103
@rule(desc="Run Terraform deploy process", level=LogLevel.DEBUG)
3✔
104
async def run_terraform_deploy(field_set: DeployTerraformFieldSet) -> DeployProcess:
3✔
105
    interactive_process = await prepare_terraform_deployment(
1✔
106
        TerraformDeploymentRequest(field_set=field_set), **implicitly()
107
    )
108

109
    return DeployProcess(
1✔
110
        name=field_set.address.spec,
111
        process=interactive_process,
112
    )
113

114

115
def rules():
3✔
116
    return [*collect_rules(), UnionRule(DeployFieldSet, DeployTerraformFieldSet)]
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc