Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/v1.16/BUG FIXES-20260804-172309.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: BUG FIXES
body: 'stacks: Fixed validation to ensure the provider versions in the lock file and configuration are compatible.'
time: 2026-08-04T17:23:09.662989-04:00
custom:
Issue: "38829"
34 changes: 17 additions & 17 deletions internal/rpcapi/stacks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,8 @@ func TestStacksPlanStackChanges_noPolicies(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -580,8 +580,8 @@ func TestStacksPlanStackChanges_withPolicies(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -661,8 +661,8 @@ func TestStacksApplyStackChanges_noPolicies(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -781,8 +781,8 @@ func TestStacksApplyStackChanges_withPolicies(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -1424,8 +1424,8 @@ func TestStackChangeProgressDuringPlanNormal(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -1651,8 +1651,8 @@ func TestStackChangeProgressDuringPlanDestroy(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -1905,8 +1905,8 @@ func TestStackChangeProgressDuringApply(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
stacksServer.providerDependencyLockOverride = lock
Expand Down Expand Up @@ -2392,8 +2392,8 @@ func TestStacksMigrateTerraformState(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
lockHandle := handles.NewDependencyLocks(lock)
Expand Down Expand Up @@ -2610,7 +2610,7 @@ func policyEvaluationTestClient(t *testing.T) policy.Client {
Alias: "default",
Namespace: "hashicorp",
Source: "registry.terraform.io/hashicorp/testing",
Version: "0.0.0",
Version: "0.1.0",
}
if diff := cmp.Diff(req.Meta, expectedMeta, protocmp.Transform()); diff != "" {
t.Fatalf("unexpected provider metadata\n%s", diff)
Expand Down
12 changes: 12 additions & 0 deletions internal/stacks/stackconfig/provider_requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,15 @@ func (pr *ProviderRequirements) LocalNameForProvider(providerAddr addrs.Provider
}
return "", false
}

func (pr *ProviderRequirements) VersionConstraintsForProvider(providerAddr addrs.Provider) (constraints.IntersectionSpec, bool) {
if pr == nil {
return nil, false
}
for _, obj := range pr.Requirements {
if obj.Provider == providerAddr {
return obj.VersionConstraints, true
}
}
return nil, false
}
4 changes: 2 additions & 2 deletions internal/stacks/stackruntime/apply_destroy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1762,8 +1762,8 @@ func TestApplyDestroy(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down
68 changes: 34 additions & 34 deletions internal/stacks/stackruntime/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2309,8 +2309,8 @@ After applying this plan, Terraform will no longer manage these objects. You wil
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -2518,8 +2518,8 @@ func TestApplyWithMovedResource(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -2696,8 +2696,8 @@ func TestApplyWithSensitivePropagation(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
req := PlanRequest{
Expand Down Expand Up @@ -3078,8 +3078,8 @@ func TestApplyWithFailedComponent(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
req := PlanRequest{
Expand Down Expand Up @@ -3200,8 +3200,8 @@ func TestApplyWithFailedProviderLinkedComponent(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
req := PlanRequest{
Expand Down Expand Up @@ -3317,8 +3317,8 @@ func TestApplyWithStateManipulation(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -3849,8 +3849,8 @@ func TestApplyWithChangedInputValues(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
req := PlanRequest{
Expand Down Expand Up @@ -3977,8 +3977,8 @@ func TestApplyAutomaticInputConversion(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
req := PlanRequest{
Expand Down Expand Up @@ -4146,8 +4146,8 @@ func TestApply_DependsOnComponentWithNoInstances(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4243,8 +4243,8 @@ func TestApply_WithProviderFunctions(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4478,8 +4478,8 @@ func TestApplyFailedDependencyWithResourceInState(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4648,8 +4648,8 @@ func TestApplyManuallyRemovedResource(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4809,8 +4809,8 @@ func TestApply_WithPolicyResults(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4858,8 +4858,8 @@ func TestApply_WithPolicyResults_EmbeddedStack(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4907,8 +4907,8 @@ func TestApply_WithPolicyResultsOnRefresh(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -4979,8 +4979,8 @@ func TestApply_WithPolicyResultsOnDestroy(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down Expand Up @@ -5030,8 +5030,8 @@ func TestApply_WithPolicyResultsOnRemovedComponent(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.1.0"),
providerreqs.MustParseVersionConstraints("0.1.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down
24 changes: 24 additions & 0 deletions internal/stacks/stackruntime/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/depsfile"
"github.com/hashicorp/terraform/internal/getproviders/providerreqs"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/stacks/stackaddrs"
Expand Down Expand Up @@ -618,3 +619,26 @@ func providerFunctionHashResult(value cty.Value) []byte {
bytes := sha256.Sum256([]byte(value.GoString()))
return bytes[:]
}

// buildVersionMismatchLock returns a Locks value with provider "testing"
// locked at 0.2.0, used to exercise version-mismatch diagnostics in tests.
func buildVersionMismatchLock() depsfile.Locks {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.2.0"),
providerreqs.MustParseVersionConstraints("0.2.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)
return *lock
}

// hasDiagSummary reports whether any diagnostic in diags has the given summary.
func hasDiagSummary(diags tfdiags.Diagnostics, summary string) bool {
for _, diag := range diags {
if diag.Description().Summary == summary {
return true
}
}
return false
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func TestNamedPromisesPlan(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
providerAddrs,
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("1.0.0"),
providerreqs.MustParseVersionConstraints("1.0.0"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -941,8 +941,8 @@ func TestPlanning_LocalsDataSource(t *testing.T) {
lock := depsfile.NewLocks()
lock.SetProvider(
addrs.NewDefaultProvider("testing"),
providerreqs.MustParseVersion("0.0.0"),
providerreqs.MustParseVersionConstraints("=0.0.0"),
providerreqs.MustParseVersion("0.0.1"),
providerreqs.MustParseVersionConstraints("0.0.1"),
providerreqs.PreferredHashes([]providerreqs.Hash{}),
)

Expand Down
Loading