test(manager/github-actions): update pinned version of `gh-actions-lock` via Renovate
So we can get dependency updates for the extension, without needing
manual code changes.
* test(manager/github-actions): cover digest pinned `renovate-image`
As noted in #46969, if `renovatebot/github-action`'s `renovate-image`
was tag+digest pinned, we would not correctly generate an update for it.
We can add test coverage for this scenario first, documenting the
current (incorrect) behaviour, so we have a clear regression test for
the fix in the next commit.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fix(manager/github-actions): handle digest pinned `renovate-image`
Previously we split on `@` which would result in `packageName:
ghcr.io/renovatebot/renovate:44.104.2`, which was incorrectly extracted,
and so if no `renovate-version` was set, this would lead to `skipReason:
'unspecified-version'`.
We can instead reuse `splitImageParts`, already used for
Dockerfile-style `image:tag@digest` parsing, so a tag embedded in
`renovate-image` is extracted correctly. Its own tag takes priority over
the separate `renovate-version` input when both are set, matching how
the action itself resolves the image to pull.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
---------
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* feat(manager/github-actions): extract `slsa-framework/actions/*`' `with`s
As there are a few `with` inputs that are dependency versions, we should
support extracting and updating them.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* fixup! feat(manager/github-actions): extract `slsa-framework/actions/*`' `with`s
---------
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
* refactor(manager/helmv3): share generateHelmEnvs with kustomize
Move kustomize's generateHelmEnvs into helmv3/common.ts and delete the
kustomize copy. The merged function always sets the three HELM_*
path variables and sets HELM_EXPERIMENTAL_OCI unless a helm
constraint is present and proves helm >= 3.8 (which ignores the
variable).
Behaviour change: kustomize now sets HELM_EXPERIMENTAL_OCI when the
helm constraint is unknown (previously it only set it for a known
constraint below 3.8). helmv3 and helmfile now omit the variable
once a resolved helm constraint proves helm >= 3.8.
* refactor(manager/helmv3): share OCI registry login helper with helmfile
Extract a shared generateRegistryLoginCmd(name, registry) helper in
helmv3/common.ts that strips the oci:// prefix, derives the host and
looks up the matching host rule before delegating to generateLoginCmd.
helmv3/artifacts.ts and helmfile/artifacts.ts now both call this
helper instead of each building a RepositoryRule inline, removing the
stale oci:// TODO. helmfile/utils.ts loses its duplicate
generateRegistryLoginCmd, and its unrelated isOCIRegistry(repository)
(checking the oci flag) is renamed to isOciRepositoryFlagSet so it no
longer collides in name with helmv3/oci.ts's prefix-based
isOCIRegistry(string), which helmfile/extract.ts also imports.
Addresses audit finding M8. Generated `helm registry login` commands
are unchanged, proved by the existing artifacts specs passing with
their original expectations untouched.
* fix(manager): share one local Helm chart path check
helmfile, flux, fleet and terraform each decided differently whether a Helm chart reference points at a local path. fleet and terraform used terraform's checkIfStringIsPath, whose regex was unanchored with unescaped dots, so it matched any string containing a slash followed by a non-slash character.
Add isLocalChartPath to helmv3/utils.ts with helmfile's prefix check and use it in all four managers. This drops the fleet to terraform dependency and removes checkIfStringIsPath, which had no other users.
* refactor(manager/helm-requirements): reuse helmv3 alias and repository helpers
Replace the duplicated alias-resolution and repository-classification logic in helm-requirements/extract.ts with the shared isAlias, resolveAlias and parseRepository helpers from helmv3/utils.ts (audit finding M9). Behaviour is unchanged: same skipReasons, same registryUrls, same handling of a missing repository or missing registryAliases config.
* refactor(manager/dockerfile): add an options form of getDep for CI managers
`getDep()` gains an overload taking a `GetDepOptions` object with
`specifyReplaceString`, `registryAliases` and `depType`, replacing the
opaque boolean second positional argument at the CI manager call sites.
The positional form keeps working for all other callers.
Migrated: bitbucket-pipelines, droneci, circleci, github-actions,
azure-pipelines and woodpecker.
Behaviour changes:
- azure-pipelines container resources now honour `registryAliases`, which
`extractContainer()` previously ignored
- woodpecker dependencies now carry `depType: 'docker'`, matching the
other CI managers
* refactor(manager/woodpecker): do not set depType on docker image deps
* refactor(manager/dockerfile): drop the positional getDep signature
* refactor(manager/helm-requirements): reuse helmv3 alias and repository helpers
Replace the duplicated alias-resolution and repository-classification logic in helm-requirements/extract.ts with the shared isAlias, resolveAlias and parseRepository helpers from helmv3/utils.ts (audit finding M9). Behaviour is unchanged: same skipReasons, same registryUrls, same handling of a missing repository or missing registryAliases config.
* refactor(constants): add a platform family capability table
Every consumer of `detectPlatform` carried its own mapping from the
detected platform to a tags datasource or a web UI path, and the seven
`*_API_USING_HOST_TYPES` arrays were checked one by one to produce that
platform in the first place.
Introduce `PLATFORM_FAMILIES`, one record keyed by family holding the
host types, the hostnames which identify the family outright, the tags
datasource, the API base URL derivation and the web UI path to a
directory at the default branch. A family is a group of platforms, so
the ids are checked against `PlatformId`: a family which is not a
platform is a compile error. Not every platform is a family, because
codecommit, gerrit, local and scm-manager are never recognized from a
URL.
`detectPlatform` loops the table for both its hostname and its hostType
matching, and the consumers look their answers up:
- `github-actions` and `pre-commit` read `tagsDatasource` instead of
importing the tags datasource classes.
- The PR body reads `webDirPath` instead of special-casing Bitbucket and
Bitbucket Server.
`apiBaseUrl` has no consumer yet; the changelog sources pick it up in
the next commit.
`lib/util/http/auth.ts` and `lib/util/http/host-rules.ts` still read six
of the old arrays by name, so those stay as aliases of the table and are
migrated in a follow-up. `AZURE_API_USING_HOST_TYPES` had no other
consumer and is dropped.
Behaviour changes: none. `detectPlatform` now tests every known hostname
before its name heuristics instead of interleaving the two, which is
equivalent because the hostname lists are pairwise disjoint and no known
hostname contains the name of another family.
* Apply suggestion from @secustor
While looking at the fix for `actions/setup-java`, we noticed that
`erlef/setup-beam` may also be affected, as it notes:
> values like `22.x`, or even `>22`, are also accepted, and we attempt
> to resolve them according to semantic versioning rules
As these fall back to `semver-coerced`, Renovate then raises a PR
rewriting the range into a full version, which isn't the intent.
We can use `npm` versioning for the Elixir, Gleam and rebar3
dependencies.
This deliberately leaves `otp-version` alone: Erlang/OTP releases
4-component versions (e.g. `26.2.5.3`) which aren't valid semver, so
`npm` versioning would discard those releases entirely. Resolving that
needs a versioning which handles both the 4-component versions and the
ranges, which is left as a follow-up.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`golangci/golangci-lint-action` may also be affected, as it notes for
its default `binary` install mode:
> the value can be v2.3, v2.3.4, or `latest` to use the latest version.
As the value falls back to `semver-coerced`, `v2.3` is treated as a
pinned version, so Renovate then raises a PR to bump to a full version,
which isn't the intent.
Unlike the other Actions looked at here, the partial versions are
`v`-prefixed, so we need to widen the partial-version check to allow
that. `semver-partial` versioning preserves the prefix, so `v2.5` is
bumped to `v2.6` rather than to a full `v2.6.0`.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`crystal-lang/install-crystal` may also be affected, as it notes for
both its `crystal` and `shards` inputs:
> Install a particular release of Crystal (if the full version is
> specified), or the latest patch version of a release series.
As these fall back to `semver-coerced`, a partial version such as `1.21`
is treated as a pinned version, so Renovate then raises a PR to bump to
a full version, which isn't the intent.
We can reuse the same `semver-partial` handling to keep the value's
precision.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`swift-actions/setup-swift` may also be affected, as it notes:
> YAML interprets eg. 5.0 as a float, this action will then interpret
> that as 5 which will result in eg. Swift 5.5 being resolved.
As the value falls back to `semver-coerced`, a partial `swift-version`
is treated as a pinned version, so Renovate then raises a PR to bump to
a full version, which isn't the intent.
Unlike the other Actions looked at here, no ranges are documented, so
`semver-partial` versioning is enough to keep a partial version's
precision.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`GitTools/actions/gitversion/setup` may also be affected, as it
documents `versionSpec` as:
> Required version in the form of 6.8.x or exact version like 6.0.0.
with its own examples using the `6.8.x` form throughout.
As the value falls back to `semver-coerced`, Renovate then raises a PR
rewriting `6.8.x` into a full version, which isn't the intent.
We can use `npm` versioning here too.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`subosito/flutter-action` may also be affected. It doesn't describe
`flutter-version` in prose, but its examples use x-ranges to pick the
latest release of a line:
> flutter-version: 1.22.x
> flutter-version: 3.x
As these fall back to `semver-coerced`, Renovate then raises a PR
rewriting `3.24.x` into a full version, which isn't the intent.
We can use `npm` versioning here too.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`jwlawson/actions-setup-cmake` may also be affected, as it notes:
> This can be a fully specified verison `3.3.0`, partly specified `3.2`,
> a wildcard version `3.2.x`.
As the value falls back to `semver-coerced`, Renovate then raises a PR
rewriting `3.2.x` into a full version, which isn't the intent.
We can use `npm` versioning here too, which understands both the partly
specified and the wildcard forms.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`hashicorp/setup-terraform` and `opentofu/setup-opentofu` may also be
affected, as both note:
> Instead of a full version string, you can also specify a constraint
> string (see Semver Ranges for available range specifications).
As these fall back to `semver-coerced`, which coerces `~1.1.0` to
`1.1.0`, Renovate then raises a PR rewriting the constraint into a full
version, which isn't the intent.
We can use `npm` versioning, which handles the constraint strings the
Actions document, and leaves `latest` alone as a value we have no
version to bump it to.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`julia-actions/setup-julia` may also be affected, as it notes:
> Internally the action uses node's semver package to resolve version
> ranges.
Its documented values therefore include `1.0`, which "matches the
highest available version starting with that prefix", as well as
`^1.3.0-rc1` and `~1.3.0-rc1`.
As these fall back to `semver-coerced`, Renovate then raises a PR to
bump `1.10` to the full-precision tag `v1.11.7`, which isn't the intent.
We can instead use `npm` versioning, as we already do for
`goreleaser/goreleaser-action` and `j178/prek-action`.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`actions/setup-dotnet` may also be affected, as it notes:
> - **A.B** or **A.B.x** installs the latest patch version of .NET SDK
> on the channel
> - **A** or **A.x** installs the latest minor version of the specified
> major tag
alongside `A.B.Cxx` for "the latest version of the specific SDK release"
and `latest` for "the highest active .NET SDK version".
As these fall back to `semver-coerced`, which happily coerces `8.0.x` to
`8.0.0`, Renovate then raises a PR to bump to a full version such as
`9.0.100`, which isn't the intent.
Rather than the `semver-partial` versioning used for the other Actions,
here we can use `npm` versioning, which understands the x-range form
too, and safely rejects `8.0.4xx`/`latest` as values we have no version
to bump them to.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that
`dart-lang/setup-dart` may also be affected, as it notes:
> An SDK release version - e.g. `2.19` or `3.1`. This will install the
> latest patch release for that specific release version.
As the `sdk` value falls back to `semver-coerced`, `3.5` is treated as a
pinned version, so Renovate then raises a PR to bump to a full version
such as `3.9.5`, which isn't the intent.
We can reuse the same `semver-partial` handling to keep the value's
precision.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
While looking at the fix for `actions/setup-java`, we noticed that the
`ruby/setup-ruby` may also be affected, as it notes:
> short version like '2.6', automatically using the latest release
> matching that version
As Ruby versioning treats `3.4` as a pinned version rather than a range,
we'd propose a patch upgrade rewriting it to `3.4.7`, losing the rolling
behaviour the workflow asked for.
We can reuse the `semver-partial` handling as a `partialValSchema`
helper, so short versions keep their precision and only exact versions
are looked up as pinned.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As noted in #46249, `actions/setup-java` documents `java-version` as:
> Java version to install. Supports whole versions, semver ranges,
> early-access versions, and latest.
When the Java version is parsed using the versioning in
`workarounds:javaLTSVersions`, this leads to `11` looking older than
`11.0.32+101`, so Renovate then raises a PR to bump to a full version,
which isn't the intent.
Similar to the fix for mise in
5f5e58b822, we can use `semver-partial`
versioning for whole versions, so `11` stays `11` and only a new major
bumps it to `25`, and exempt `github-actions` from the preset rule that
would otherwise force the Java regex versioning back on.
The remaining documented forms (`21.x`, `>=21`, `21-ea`, `latest`) have
no version we could bump them to, so we skip them as
`unsupported-version` rather than mangling them.
`graalvm/setup-graalvm` reads the same datasource from its own
`java-version` input, so it gets the same treatment.
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
As noted in #46242, the `known-actions.ts` file was getting a bit big.
Where we have dynamic extractions, using `transform`, we split these
into a `<datasource>-dynamic.ts` file.
Where we have multiple packages extracted from the same Action, we use
`multiple.ts`.
Per suggestion from Sebastian, we can break this down by the datasource
used by the Action's inputs.
We can also try to enforce the structure of the directories by adding a
test in each file.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As the graalvm Action doesn't actually use the `datasource`, given it is
dynamic based on the dependencies extracted, we should note this more
clearly with a sentinel string.
We could alternatively make `datasource` optional, but given this is the
only case right now, this is simpler.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As a follow-up to 4b5a64e6e1, we should
make sure that we document the fact that `latest` is a valid version to
Conda.
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
version has a default (latest), so real workflows commonly omit it
from with: entirely rather than passing an empty string.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
graalvm/graalvm-ce-builds still alternates between jdk- and graal-
prefixed tags for current-era releases, so extractVersion matches both
rather than jdk- alone.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
As the repo publishes per-SDK/component release tags i.e.
`sdk/typescript/v0.21.9`, `helm/chart/v0.21.9`), we need to specify
`extractVersion` to extract the version as we need.
Co-Authored-By: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>