renderESCStep in provider-ci/internal/pkg/generate.go:457 hardcodes pulumi/esc-action@9eb774255b1a4afb7855678ae8d4a77359da0d9b as a Go string literal. The pin Renovate manages lives in provider-ci/internal/pkg/action-versions.yml:60 and is currently 3af4859af8a73a362fb599b944124097d4bb80c5 (v3.1.0). Renovate cannot see a string literal in Go source, so the generate.go pin has not changed since #1705 in September 2025. That SHA is v1.5.0-2-g9eb7742 in pulumi/esc-action, two commits past v1.5.0 and contained in no release tag.
The two pins now disagree inside a single generated file: provider-ci/test-providers/terraform-module/.github/workflows/test.yml uses the hardcoded pin on line 47 and the managed one on line 85. Across provider-ci/test-providers/, 159 files carry the hardcoded pin against 22 with the managed one, and every provider repo I sampled (pulumi-aws, pulumi-gcp, pulumi-random, pulumi-kubernetes, pulumi-docker) has the hardcoded pin checked in.
action.yml at that SHA declares runs: using: 'node20', so provider workflow runs emit "Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24", per https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/. esc-action moved to node24 in v2.0.0.
The contract renderESCStep depends on is unchanged in v3: the action still calls core.setOutput over the environmentVariables map so steps.esc-secrets.outputs.NAME resolves, and getInput still falls back to ESC_ACTION_* for the five env vars the step sets. The v3 change that masks only values marked secret leaves these environments masked, since pulumi/esc-export-secrets-action writes every exported value as fn::secret. ci-mgmt's own workflows already run esc-action v3 with the same env var and step output pattern.
The mechanism worth fixing is the Renovate blind spot: if renderESCStep read config.ActionVersions.ESCAction, both paths would come from action-versions.yml. Note that config.go appends a trailing line comment to that value, so it needs stripping or raw emission rather than passing through toYAML as a map value.
renderESCStepinprovider-ci/internal/pkg/generate.go:457hardcodespulumi/esc-action@9eb774255b1a4afb7855678ae8d4a77359da0d9bas a Go string literal. The pin Renovate manages lives inprovider-ci/internal/pkg/action-versions.yml:60and is currently3af4859af8a73a362fb599b944124097d4bb80c5(v3.1.0). Renovate cannot see a string literal in Go source, so thegenerate.gopin has not changed since #1705 in September 2025. That SHA isv1.5.0-2-g9eb7742inpulumi/esc-action, two commits past v1.5.0 and contained in no release tag.The two pins now disagree inside a single generated file:
provider-ci/test-providers/terraform-module/.github/workflows/test.ymluses the hardcoded pin on line 47 and the managed one on line 85. Acrossprovider-ci/test-providers/, 159 files carry the hardcoded pin against 22 with the managed one, and every provider repo I sampled (pulumi-aws, pulumi-gcp, pulumi-random, pulumi-kubernetes, pulumi-docker) has the hardcoded pin checked in.action.ymlat that SHA declaresruns: using: 'node20', so provider workflow runs emit "Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24", per https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/. esc-action moved to node24 in v2.0.0.The contract
renderESCStepdepends on is unchanged in v3: the action still callscore.setOutputover theenvironmentVariablesmap sosteps.esc-secrets.outputs.NAMEresolves, andgetInputstill falls back toESC_ACTION_*for the five env vars the step sets. The v3 change that masks only values marked secret leaves these environments masked, sincepulumi/esc-export-secrets-actionwrites every exported value asfn::secret. ci-mgmt's own workflows already run esc-action v3 with the same env var and step output pattern.The mechanism worth fixing is the Renovate blind spot: if
renderESCStepreadconfig.ActionVersions.ESCAction, both paths would come fromaction-versions.yml. Note thatconfig.goappends a trailing line comment to that value, so it needs stripping or raw emission rather than passing throughtoYAMLas a map value.