Compare commits

...

15 commits

Author SHA1 Message Date
Gareth Parker
fa3dd8448d
Merge e348689be6 into 1d2c1a35e3 2025-01-09 12:50:12 +01:00
Pierre Cavin
1d2c1a35e3
feat(mix): add depType support (#33310)
Some checks are pending
Build / coverage-threshold (push) Blocked by required conditions
Build / setup (push) Waiting to run
Build / setup-build (push) Waiting to run
Build / prefetch (push) Blocked by required conditions
Build / lint-eslint (push) Blocked by required conditions
Build / lint-prettier (push) Blocked by required conditions
Build / lint-docs (push) Blocked by required conditions
Build / lint-other (push) Blocked by required conditions
Build / (push) Blocked by required conditions
Build / codecov (push) Blocked by required conditions
Build / test-success (push) Blocked by required conditions
Build / build (push) Blocked by required conditions
Build / build-docs (push) Blocked by required conditions
Build / test-e2e (push) Blocked by required conditions
Build / release (push) Blocked by required conditions
Code scanning / CodeQL-Build (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
whitesource-scan / WS_SCAN (push) Waiting to run
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
2025-01-09 10:38:35 +00:00
Maxime Brunet
84017e05cc
refactor: refactor Google Auth util (#33486) 2025-01-09 10:35:47 +00:00
Johannes Feichtner
6cf23f2bf1
refactor(gradle): extract redundant functions and remove snapshot (#33430) 2025-01-09 07:22:45 +00:00
Alessandro Vinciguerra
6bb68782b8
feat: extract artifactory timestamps from columns (#33187) 2025-01-09 07:21:56 +00:00
Johannes Feichtner
6e8b70ed07
fix(gradle): correct handling of heuristically matched dependency triples (#33487)
Some checks are pending
Build / setup (push) Waiting to run
Build / setup-build (push) Waiting to run
Build / prefetch (push) Blocked by required conditions
Build / lint-eslint (push) Blocked by required conditions
Build / lint-prettier (push) Blocked by required conditions
Build / lint-docs (push) Blocked by required conditions
Build / lint-other (push) Blocked by required conditions
Build / (push) Blocked by required conditions
Build / codecov (push) Blocked by required conditions
Build / coverage-threshold (push) Blocked by required conditions
Build / test-success (push) Blocked by required conditions
Build / build (push) Blocked by required conditions
Build / build-docs (push) Blocked by required conditions
Build / test-e2e (push) Blocked by required conditions
Build / release (push) Blocked by required conditions
Code scanning / CodeQL-Build (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
whitesource-scan / WS_SCAN (push) Waiting to run
2025-01-08 22:14:44 +00:00
renovate[bot]
adede1d309
chore(deps): update otel/opentelemetry-collector-contrib docker tag to v0.117.0 (#33483)
Some checks are pending
Build / setup (push) Waiting to run
Build / setup-build (push) Waiting to run
Build / prefetch (push) Blocked by required conditions
Build / lint-eslint (push) Blocked by required conditions
Build / lint-prettier (push) Blocked by required conditions
Build / lint-docs (push) Blocked by required conditions
Build / lint-other (push) Blocked by required conditions
Build / (push) Blocked by required conditions
Build / codecov (push) Blocked by required conditions
Build / coverage-threshold (push) Blocked by required conditions
Build / test-success (push) Blocked by required conditions
Build / build (push) Blocked by required conditions
Build / build-docs (push) Blocked by required conditions
Build / test-e2e (push) Blocked by required conditions
Build / release (push) Blocked by required conditions
Code scanning / CodeQL-Build (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
whitesource-scan / WS_SCAN (push) Waiting to run
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 19:16:59 +00:00
renovate[bot]
2eca39ad90
chore(deps): update dependency memfs to v4.15.3 (#33482)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 19:11:29 +00:00
renovate[bot]
88e2336945
fix(deps): update ghcr.io/renovatebot/base-image docker tag to v9.29.1 (#33480)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 18:10:27 +00:00
Gareth Parker
e348689be6 feat(nodejs-lambda-versioning): Add another test with a different date to check for support date comparison 2024-11-12 15:22:27 +00:00
Gareth Parker
797e73e496 feat(nodejs-lambda-versioning): Format the static data when generating 2024-11-12 15:19:32 +00:00
Gareth Parker
d267a98904 feat(nodejs-lambda-versioning): Run the data files through prettier for linting 2024-11-12 15:17:40 +00:00
Gareth Parker
86b389eb37
Merge branch 'main' into feat/lambda-node-versioning 2024-11-12 16:00:57 +01:00
Gareth Parker
8a24372a66 feat(nodejs-lambda-versioning): Add documentation for the new versioning module 2024-11-12 14:42:15 +00:00
Gareth Parker
7e46916b01 feat(nodejs-lambda-versioning): Add a NodeJS Lambda Versioning module 2024-11-12 14:29:04 +00:00
30 changed files with 643 additions and 213 deletions

View file

@ -0,0 +1,56 @@
{
"10": {
"cycle": "nodejs10.x",
"releaseLabel": "Node.js 10",
"releaseDate": "2019-05-15",
"eol": "2022-02-14",
"link": "https://aws.amazon.com/about-aws/whats-new/2019/05/aws_lambda_adds_support_for_node_js_v10/",
"lts": false,
"support": "2021-07-30"
},
"12": {
"cycle": "nodejs12.x",
"releaseLabel": "Node.js 12",
"releaseDate": "2019-11-18",
"eol": "2023-04-30",
"link": "https://aws.amazon.com/blogs/compute/node-js-12-x-runtime-now-available-in-aws-lambda/",
"lts": false,
"support": "2023-03-31"
},
"14": {
"cycle": "nodejs14.x",
"releaseLabel": "Node.js 14",
"releaseDate": "2021-02-03",
"eol": "2025-02-28",
"link": "https://aws.amazon.com/blogs/compute/node-js-14-x-runtime-now-available-in-aws-lambda/",
"lts": false,
"support": "2023-12-04"
},
"16": {
"cycle": "nodejs16.x",
"releaseLabel": "Node.js 16",
"releaseDate": "2022-05-12",
"eol": "2025-03-31",
"link": "https://aws.amazon.com/blogs/compute/node-js-16-x-runtime-now-available-in-aws-lambda/",
"lts": false,
"support": "2024-06-12"
},
"18": {
"cycle": "nodejs18.x",
"releaseLabel": "Node.js 18",
"releaseDate": "2022-11-18",
"eol": "2025-10-01",
"link": "https://aws.amazon.com/blogs/compute/node-js-18-x-runtime-now-available-in-aws-lambda/",
"lts": false,
"support": "2025-07-31"
},
"20": {
"cycle": "nodejs20.x",
"releaseLabel": "Node.js 20",
"releaseDate": "2023-11-15",
"eol": false,
"link": "https://aws.amazon.com/blogs/compute/node-js-20-x-runtime-now-available-in-aws-lambda/",
"lts": false,
"support": true
}
}

View file

@ -36,7 +36,7 @@ services:
otel-collector:
# Using the Contrib version to access the spanmetrics connector.
# If you don't need the spanmetrics connector, you can use the standard version
image: otel/opentelemetry-collector-contrib:0.116.1
image: otel/opentelemetry-collector-contrib:0.117.0
volumes:
- ./otel-collector-config.yml:/etc/otelcol-contrib/config.yaml
ports:

View file

@ -11,9 +11,9 @@
<pre>
<a href="..">..</a>
<a href="1.0.0">1.0.0</a> 21-Jul-2021 20:08 -
<a href="1.0.1">1.0.1</a> 23-Aug-2021 20:03 -
<a href="1.0.2">1.0.2</a> 21-Jul-2021 20:09 -
<a href="1.0.3">1.0.3</a> 06-Feb-2021 09:54 -
<a href="1.0.1">1.0.1</a> 23-Aug-2021 20:03 12 MB
<a href="1.0.2">1.0.2</a> 21-Jul-2021 20:09 123.45 GB
<a href="1.0.3">1.0.3</a> 06-Feb-2021 09:54 9.0 KB
</pre>
<hr/>
<address style="font-size:small;">Artifactory Port 8080</address>

View file

@ -114,6 +114,9 @@ export class ArtifactoryDatasource extends Datasource {
}
private static parseReleaseTimestamp(rawText: string): string {
return rawText.trim().replace(regEx(/ ?-$/), '') + 'Z';
return (
rawText.split(regEx(/\s{2,}/)).filter((e) => !isNaN(Date.parse(e)))[0] +
'Z'
);
}
}

View file

@ -1,6 +1,7 @@
import is from '@sindresorhus/is';
import { GoogleAuth } from 'google-auth-library';
import { logger } from '../../logger';
import type { HostRule } from '../../types';
import type { HttpResponse } from '../../util/http/types';
import { addSecretForSanitizing } from '../../util/sanitize';
@ -12,7 +13,7 @@ export function isArtifactoryServer<T = unknown>(
return is.string(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);
}
export async function getGoogleAuthTokenRaw(): Promise<string | null> {
export async function getGoogleAuthHostRule(): Promise<HostRule | null> {
try {
const googleAuth: GoogleAuth = new GoogleAuth({
scopes: 'https://www.googleapis.com/auth/cloud-platform',
@ -21,7 +22,10 @@ export async function getGoogleAuthTokenRaw(): Promise<string | null> {
if (accessToken) {
// sanitize token
addSecretForSanitizing(accessToken);
return accessToken;
return {
username: 'oauth2accesstoken',
password: accessToken,
};
} else {
logger.warn(
'Could not retrieve access token using google-auth-library getAccessToken',
@ -38,9 +42,13 @@ export async function getGoogleAuthTokenRaw(): Promise<string | null> {
}
export async function getGoogleAuthToken(): Promise<string | null> {
const accessToken = await getGoogleAuthTokenRaw();
if (accessToken) {
return Buffer.from(`oauth2accesstoken:${accessToken}`).toString('base64');
const rule = await getGoogleAuthHostRule();
if (rule) {
const token = Buffer.from(`${rule.username}:${rule.password}`).toString(
'base64',
);
addSecretForSanitizing(token);
return token;
}
return null;
}

View file

@ -1,103 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`modules/manager/gradle/parser calculations parses fixture from "gradle" manager 1`] = `
[
{
"currentValue": "1.5.2.RELEASE",
"depName": "org.springframework.boot:spring-boot-gradle-plugin",
"groupName": "springBootVersion",
"managerData": {
"fileReplacePosition": 53,
"packageFile": "build.gradle",
},
},
{
"currentValue": "1.2.3",
"depName": "com.github.jengelman.gradle.plugins:shadow",
"managerData": {
"fileReplacePosition": 417,
"packageFile": "build.gradle",
},
},
{
"currentValue": "0.1",
"depName": "com.fkorotkov:gradle-libraries-plugin",
"managerData": {
"fileReplacePosition": 481,
"packageFile": "build.gradle",
},
},
{
"currentValue": "0.2.3",
"depName": "gradle.plugin.se.patrikerdes:gradle-use-latest-versions-plugin",
"managerData": {
"fileReplacePosition": 568,
"packageFile": "build.gradle",
},
},
{
"currentValue": "3.1.1",
"depName": "org.apache.openjpa:openjpa",
"managerData": {
"fileReplacePosition": 621,
"packageFile": "build.gradle",
},
},
{
"currentValue": "0.13.0",
"depName": "com.gradle.publish:plugin-publish-plugin",
"managerData": {
"fileReplacePosition": 688,
"packageFile": "build.gradle",
},
},
{
"currentValue": "6.0.9.RELEASE",
"depName": "org.grails:gorm-hibernate5-spring-boot",
"managerData": {
"fileReplacePosition": 1882,
"packageFile": "build.gradle",
},
},
{
"currentValue": "6.0.5",
"depName": "mysql:mysql-connector-java",
"managerData": {
"fileReplacePosition": 1938,
"packageFile": "build.gradle",
},
},
{
"currentValue": "1.0-groovy-2.4",
"depName": "org.spockframework:spock-spring",
"managerData": {
"fileReplacePosition": 1996,
"packageFile": "build.gradle",
},
},
{
"currentValue": "1.3",
"depName": "org.hamcrest:hamcrest-core",
"managerData": {
"fileReplacePosition": 2101,
"packageFile": "build.gradle",
},
},
{
"currentValue": "3.1",
"depName": "cglib:cglib-nodep",
"managerData": {
"fileReplacePosition": 2189,
"packageFile": "build.gradle",
},
},
{
"currentValue": "3.1.1",
"depName": "org.apache.openjpa:openjpa",
"managerData": {
"fileReplacePosition": 2295,
"packageFile": "build.gradle",
},
},
]
`;

View file

@ -770,6 +770,17 @@ describe('modules/manager/gradle/parser', () => {
const { deps } = parseGradle(input);
expect(deps).toMatchObject([output].filter(is.truthy));
});
it('handles 3 independent dependencies mismatched as groupId, artifactId, version', () => {
const { deps } = parseGradle(
'someConfig("foo:bar:1.2.3", "foo:baz:4.5.6", "foo:qux:7.8.9")',
);
expect(deps).toMatchObject([
{ depName: 'foo:bar', currentValue: '1.2.3' },
{ depName: 'foo:baz', currentValue: '4.5.6' },
{ depName: 'foo:qux', currentValue: '7.8.9' },
]);
});
});
describe('calculations', () => {
@ -792,7 +803,106 @@ describe('modules/manager/gradle/parser', () => {
content.slice(managerData!.fileReplacePosition).indexOf(currentValue!),
);
expect(replacementIndices.every((idx) => idx === 0)).toBeTrue();
expect(deps).toMatchSnapshot();
expect(deps).toMatchObject([
{
currentValue: '1.5.2.RELEASE',
depName: 'org.springframework.boot:spring-boot-gradle-plugin',
groupName: 'springBootVersion',
managerData: {
fileReplacePosition: 53,
packageFile: 'build.gradle',
},
},
{
currentValue: '1.2.3',
depName: 'com.github.jengelman.gradle.plugins:shadow',
managerData: {
fileReplacePosition: 417,
packageFile: 'build.gradle',
},
},
{
currentValue: '0.1',
depName: 'com.fkorotkov:gradle-libraries-plugin',
managerData: {
fileReplacePosition: 481,
packageFile: 'build.gradle',
},
},
{
currentValue: '0.2.3',
depName:
'gradle.plugin.se.patrikerdes:gradle-use-latest-versions-plugin',
managerData: {
fileReplacePosition: 568,
packageFile: 'build.gradle',
},
},
{
currentValue: '3.1.1',
depName: 'org.apache.openjpa:openjpa',
managerData: {
fileReplacePosition: 621,
packageFile: 'build.gradle',
},
},
{
currentValue: '0.13.0',
depName: 'com.gradle.publish:plugin-publish-plugin',
managerData: {
fileReplacePosition: 688,
packageFile: 'build.gradle',
},
},
{
currentValue: '6.0.9.RELEASE',
depName: 'org.grails:gorm-hibernate5-spring-boot',
managerData: {
fileReplacePosition: 1882,
packageFile: 'build.gradle',
},
},
{
currentValue: '6.0.5',
depName: 'mysql:mysql-connector-java',
managerData: {
fileReplacePosition: 1938,
packageFile: 'build.gradle',
},
},
{
currentValue: '1.0-groovy-2.4',
depName: 'org.spockframework:spock-spring',
managerData: {
fileReplacePosition: 1996,
packageFile: 'build.gradle',
},
},
{
currentValue: '1.3',
depName: 'org.hamcrest:hamcrest-core',
managerData: {
fileReplacePosition: 2101,
packageFile: 'build.gradle',
},
},
{
currentValue: '3.1',
depName: 'cglib:cglib-nodep',
managerData: {
fileReplacePosition: 2189,
packageFile: 'build.gradle',
},
},
{
currentValue: '3.1.1',
depName: 'org.apache.openjpa:openjpa',
managerData: {
fileReplacePosition: 2295,
packageFile: 'build.gradle',
},
},
]);
});
});

View file

@ -321,7 +321,6 @@ export const qDotOrBraceExpr = (
matcher: q.QueryBuilder<Ctx, parser.Node>,
): q.QueryBuilder<Ctx, parser.Node> =>
q.sym<Ctx>(symValue).alt(
q.alt<Ctx>(
q.op<Ctx>('.').join(matcher),
q.tree({
type: 'wrapped-tree',
@ -330,5 +329,16 @@ export const qDotOrBraceExpr = (
endsWith: '}',
search: matcher,
}),
),
);
export const qGroupId = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'groupId'),
);
export const qArtifactId = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'artifactId'),
);
export const qVersion = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'version'),
);

View file

@ -4,9 +4,12 @@ import type { Ctx } from '../types';
import {
GRADLE_PLUGINS,
cleanupTempVars,
qArtifactId,
qDotOrBraceExpr,
qGroupId,
qTemplateString,
qValueMatcher,
qVersion,
storeInTokenMap,
storeVarToken,
} from './common';
@ -17,18 +20,6 @@ import {
handleLongFormDep,
} from './handlers';
const qGroupId = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'groupId'),
);
const qArtifactId = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'artifactId'),
);
const qVersion = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'version'),
);
// "foo:bar:1.2.3"
// "foo:bar:$baz"
// "foo" + "${bar}" + baz

View file

@ -6,7 +6,7 @@ import { regEx } from '../../../../util/regex';
import type { PackageDependency } from '../../types';
import type { parseGradle as parseGradleCallback } from '../parser';
import type { Ctx, GradleManagerData } from '../types';
import { parseDependencyString } from '../utils';
import { isDependencyString, parseDependencyString } from '../utils';
import {
GRADLE_PLUGINS,
REGISTRY_URLS,
@ -169,6 +169,22 @@ export function handleLongFormDep(ctx: Ctx): Ctx {
return ctx;
}
// Special handling: 3 independent dependencies mismatched as groupId, artifactId, version
if (
isDependencyString(groupId) &&
isDependencyString(artifactId) &&
isDependencyString(version)
) {
ctx.tokenMap.templateStringTokens = groupIdTokens;
handleDepString(ctx);
ctx.tokenMap.templateStringTokens = artifactIdTokens;
handleDepString(ctx);
ctx.tokenMap.templateStringTokens = versionTokens;
handleDepString(ctx);
return ctx;
}
const dep = parseDependencyString([groupId, artifactId, version].join(':'));
if (!dep) {
return ctx;

View file

@ -4,16 +4,12 @@ import type { Ctx } from '../types';
import {
cleanupTempVars,
qStringValue,
qValueMatcher,
qVersion,
storeInTokenMap,
storeVarToken,
} from './common';
import { handlePlugin } from './handlers';
const qVersion = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'version'),
);
export const qPlugins = q
.sym(regEx(/^(?:id|kotlin)$/), storeVarToken)
.handler((ctx) => storeInTokenMap(ctx, 'methodName'))

View file

@ -32,6 +32,7 @@ const qUri = q
// mavenCentral { ... }
const qPredefinedRegistries = q
.sym(regEx(`^(?:${Object.keys(REGISTRY_URLS).join('|')})$`), storeVarToken)
.handler((ctx) => storeInTokenMap(ctx, 'registryUrl'))
.alt(
q.tree({
type: 'wrapped-tree',
@ -45,23 +46,11 @@ const qPredefinedRegistries = q
endsWith: '}',
}),
)
.handler((ctx) => storeInTokenMap(ctx, 'registryUrl'))
.handler(handlePredefinedRegistryUrl)
.handler(cleanupTempVars);
// maven(url = uri("https://foo.bar/baz"))
// maven { name = some; url = "https://foo.bar/${name}" }
const qCustomRegistryUrl = q
.sym<Ctx>('maven')
.alt(
q.tree<Ctx>({
type: 'wrapped-tree',
maxDepth: 1,
startsWith: '(',
endsWith: ')',
search: q.begin<Ctx>().opt(q.sym<Ctx>('url').op('=')).join(qUri).end(),
}),
q.tree({
// { url = "https://some.repo" }
const qMavenArtifactRegistry = q.tree({
type: 'wrapped-tree',
maxDepth: 1,
startsWith: '{',
@ -80,7 +69,21 @@ const qCustomRegistryUrl = q
search: q.begin<Ctx>().join(qUri).end(),
}),
),
});
// maven(url = uri("https://foo.bar/baz"))
// maven { name = some; url = "https://foo.bar/${name}" }
const qCustomRegistryUrl = q
.sym<Ctx>('maven')
.alt(
q.tree<Ctx>({
type: 'wrapped-tree',
maxDepth: 1,
startsWith: '(',
endsWith: ')',
search: q.begin<Ctx>().opt(q.sym<Ctx>('url').op('=')).join(qUri).end(),
}),
qMavenArtifactRegistry,
)
.handler(handleCustomRegistryUrl)
.handler(cleanupTempVars);

View file

@ -2,6 +2,8 @@ import { query as q } from 'good-enough-parser';
import type { Ctx } from '../types';
import {
cleanupTempVars,
qArtifactId,
qGroupId,
qStringValue,
qStringValueAsSymbol,
qValueMatcher,
@ -10,14 +12,6 @@ import {
} from './common';
import { handleLibraryDep, handlePlugin } from './handlers';
const qGroupId = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'groupId'),
);
const qArtifactId = qValueMatcher.handler((ctx) =>
storeInTokenMap(ctx, 'artifactId'),
);
const qVersionCatalogVersion = q
.op<Ctx>('.')
.alt(

View file

@ -27,13 +27,19 @@ defmodule MyProject.MixProject do
{:secret, "~> 1.0", organization: "acme"},
{:also_secret, "~> 1.0", only: [:dev, :test], organization: "acme", runtime: false},
{:metrics, ">0.2.0 and <=1.0.0"},
{:jason, ">= 1.0.0"},
{:jason, ">= 1.0.0", only: :prod},
{:hackney, "~> 1.0",
optional: true},
{:hammer_backend_redis, "~> 6.1"},
{:hammer_backend_redis, "~> 6.1", only: [:dev, :prod, :test]},
{:castore, "== 1.0.10"},
{:gun, "~> 2.0.0", hex: "grpc_gun"},
{:another_gun, "~> 0.4.0", hex: :raygun},
{:credo, "~> 1.7", only:
[:test,
# prod,
:dev],
runtime: false},
{:floki, "== 0.37.0", only: :test},
]
end
end

View file

@ -1,13 +1,17 @@
%{
"another_gun": {:hex, :raygun, "0.4.0", "7744e99dd695f61e78ad5e047cce0affb3edfc6f93a92278598ab553b9c5091f", [:mix], [{:httpoison, "~> 0.8 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:plug, "~> 1.1", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "eee4b891e6e65c6a4b15386dc7b7a72b717f3c123cc0012cfd19e8f2ab21116d"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"castore": {:hex, :castore, "1.0.10", "43bbeeac820f16c89f79721af1b3e092399b3a1ecc8df1a472738fd853574911", [:mix], [], "hexpm", "1b0b7ea14d889d9ea21202c43a4fa015eb913021cb535e8ed91946f4b77a8848"},
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
"cowboy": {:git, "https://github.com/ninenines/cowboy.git", "0c2e2224e372f01e6cf51a8e12d4856edb4cb8ac", [tag: "0.6.0"]},
"cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"},
"credo": {:hex, :credo, "1.7.10", "6e64fe59be8da5e30a1b96273b247b5cf1cc9e336b5fd66302a64b25749ad44d", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "71fbc9a6b8be21d993deca85bf151df023a3097b01e09a2809d460348561d8cd"},
"decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
"ecto": {:git, "https://github.com/elixir-ecto/ecto.git", "795036d997c7503b21fb64d6bf1a89b83c44f2b5", [ref: "795036d997c7503b21fb64d6bf1a89b83c44f2b5"]},
"secret": {:hex, :secret, "1.5.0", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"},
"also_secret": {:hex, :also_secret, "1.3.4", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"},
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
"floki": {:hex, :floki, "0.37.0", "b83e0280bbc6372f2a403b2848013650b16640cd2470aea6701f0632223d719e", [:mix], [], "hexpm", "516a0c15a69f78c47dc8e0b9b3724b29608aa6619379f91b1ffa47109b5d0dd3"},
"gun": {:hex, :grpc_gun, "2.0.1", "221b792df3a93e8fead96f697cbaf920120deacced85c6cd3329d2e67f0871f8", [:rebar3], [{:cowlib, "~> 2.11", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "795a65eb9d0ba16697e6b0e1886009ce024799e43bb42753f0c59b029f592831"},
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
"hammer": {:hex, :hammer, "6.2.1", "5ae9c33e3dceaeb42de0db46bf505bd9c35f259c8defb03390cd7556fea67ee2", [:mix], [{:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b9476d0c13883d2dc0cc72e786bac6ac28911fba7cc2e04b70ce6a6d9c4b2bdc"},

View file

@ -20,12 +20,14 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 0.8.1',
datasource: 'hex',
depName: 'postgrex',
depType: 'prod',
packageName: 'postgrex',
},
{
currentValue: '<1.7.0 or ~>1.7.1',
datasource: 'hex',
depName: 'ranch',
depType: 'prod',
packageName: 'ranch',
},
{
@ -33,6 +35,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '0.6.0',
datasource: 'github-tags',
depName: 'cowboy',
depType: 'prod',
packageName: 'ninenines/cowboy',
},
{
@ -40,6 +43,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: 'main',
datasource: 'git-tags',
depName: 'phoenix',
depType: 'prod',
packageName: 'https://github.com/phoenixframework/phoenix.git',
},
{
@ -47,42 +51,49 @@ describe('modules/manager/mix/extract', () => {
currentValue: undefined,
datasource: 'github-tags',
depName: 'ecto',
depType: 'prod',
packageName: 'elixir-ecto/ecto',
},
{
currentValue: '~> 1.0',
datasource: 'hex',
depName: 'secret',
depType: 'prod',
packageName: 'secret:acme',
},
{
currentValue: '~> 1.0',
datasource: 'hex',
depName: 'also_secret',
depType: 'dev',
packageName: 'also_secret:acme',
},
{
currentValue: '>0.2.0 and <=1.0.0',
datasource: 'hex',
depName: 'metrics',
depType: 'prod',
packageName: 'metrics',
},
{
currentValue: '>= 1.0.0',
datasource: 'hex',
depName: 'jason',
depType: 'prod',
packageName: 'jason',
},
{
currentValue: '~> 1.0',
datasource: 'hex',
depName: 'hackney',
depType: 'prod',
packageName: 'hackney',
},
{
currentValue: '~> 6.1',
datasource: 'hex',
depName: 'hammer_backend_redis',
depType: 'prod',
packageName: 'hammer_backend_redis',
},
{
@ -90,20 +101,38 @@ describe('modules/manager/mix/extract', () => {
currentVersion: '1.0.10',
datasource: 'hex',
depName: 'castore',
depType: 'prod',
packageName: 'castore',
},
{
currentValue: '~> 2.0.0',
datasource: 'hex',
depName: 'gun',
depType: 'prod',
packageName: 'grpc_gun',
},
{
currentValue: '~> 0.4.0',
datasource: 'hex',
depName: 'another_gun',
depType: 'prod',
packageName: 'raygun',
},
{
currentValue: '~> 1.7',
datasource: 'hex',
depName: 'credo',
depType: 'dev',
packageName: 'credo',
},
{
currentValue: '== 0.37.0',
currentVersion: '0.37.0',
datasource: 'hex',
depName: 'floki',
depType: 'dev',
packageName: 'floki',
},
]);
});
@ -116,6 +145,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 0.8.1',
datasource: 'hex',
depName: 'postgrex',
depType: 'prod',
packageName: 'postgrex',
lockedVersion: '0.8.4',
},
@ -123,6 +153,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '<1.7.0 or ~>1.7.1',
datasource: 'hex',
depName: 'ranch',
depType: 'prod',
packageName: 'ranch',
lockedVersion: '1.7.1',
},
@ -131,6 +162,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '0.6.0',
datasource: 'github-tags',
depName: 'cowboy',
depType: 'prod',
packageName: 'ninenines/cowboy',
lockedVersion: '0.6.0',
},
@ -139,6 +171,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: 'main',
datasource: 'git-tags',
depName: 'phoenix',
depType: 'prod',
packageName: 'https://github.com/phoenixframework/phoenix.git',
lockedVersion: undefined,
},
@ -147,6 +180,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: undefined,
datasource: 'github-tags',
depName: 'ecto',
depType: 'prod',
packageName: 'elixir-ecto/ecto',
lockedVersion: undefined,
},
@ -154,6 +188,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 1.0',
datasource: 'hex',
depName: 'secret',
depType: 'prod',
packageName: 'secret:acme',
lockedVersion: '1.5.0',
},
@ -161,6 +196,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 1.0',
datasource: 'hex',
depName: 'also_secret',
depType: 'dev',
packageName: 'also_secret:acme',
lockedVersion: '1.3.4',
},
@ -168,6 +204,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '>0.2.0 and <=1.0.0',
datasource: 'hex',
depName: 'metrics',
depType: 'prod',
packageName: 'metrics',
lockedVersion: '1.0.0',
},
@ -175,6 +212,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '>= 1.0.0',
datasource: 'hex',
depName: 'jason',
depType: 'prod',
packageName: 'jason',
lockedVersion: '1.4.4',
},
@ -182,6 +220,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 1.0',
datasource: 'hex',
depName: 'hackney',
depType: 'prod',
packageName: 'hackney',
lockedVersion: '1.20.1',
},
@ -189,6 +228,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 6.1',
datasource: 'hex',
depName: 'hammer_backend_redis',
depType: 'prod',
packageName: 'hammer_backend_redis',
lockedVersion: '6.2.0',
},
@ -197,6 +237,7 @@ describe('modules/manager/mix/extract', () => {
currentVersion: '1.0.10',
datasource: 'hex',
depName: 'castore',
depType: 'prod',
packageName: 'castore',
lockedVersion: '1.0.10',
},
@ -204,6 +245,7 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 2.0.0',
datasource: 'hex',
depName: 'gun',
depType: 'prod',
packageName: 'grpc_gun',
lockedVersion: '2.0.1',
},
@ -211,9 +253,27 @@ describe('modules/manager/mix/extract', () => {
currentValue: '~> 0.4.0',
datasource: 'hex',
depName: 'another_gun',
depType: 'prod',
packageName: 'raygun',
lockedVersion: '0.4.0',
},
{
currentValue: '~> 1.7',
datasource: 'hex',
depName: 'credo',
depType: 'dev',
packageName: 'credo',
lockedVersion: '1.7.10',
},
{
currentValue: '== 0.37.0',
currentVersion: '0.37.0',
datasource: 'hex',
depName: 'floki',
depType: 'dev',
lockedVersion: '0.37.0',
packageName: 'floki',
},
]);
});
});

View file

@ -20,6 +20,8 @@ const lockedVersionRegExp = regEx(
/^\s+"(?<app>\w+)".*?"(?<lockedVersion>\d+\.\d+\.\d+)"/,
);
const hexRegexp = regEx(/hex:\s*(?:"(?<strValue>[^"]+)"|:(?<atomValue>\w+))/);
const onlyValueRegexp = regEx(/only:\s*(?<only>\[[^\]]*\]|:\w+)/);
const onlyEnvironmentsRegexp = regEx(/:(\w+)/gm);
export async function extractPackageFile(
content: string,
@ -48,22 +50,28 @@ export async function extractPackageFile(
const hexGroups = hexRegexp.exec(opts)?.groups;
const hex = hexGroups?.strValue ?? hexGroups?.atomValue;
let dep: PackageDependency;
const onlyValue = onlyValueRegexp.exec(opts)?.groups?.only;
const onlyEnvironments = [];
let match;
if (onlyValue) {
while ((match = onlyEnvironmentsRegexp.exec(onlyValue)) !== null) {
onlyEnvironments.push(match[1]);
}
}
const dep: PackageDependency = {
depName: app,
depType: 'prod',
};
if (git ?? github) {
dep = {
depName: app,
currentDigest: ref,
currentValue: branchOrTag,
datasource: git ? GitTagsDatasource.id : GithubTagsDatasource.id,
packageName: git ?? github,
};
dep.currentDigest = ref;
dep.currentValue = branchOrTag;
dep.datasource = git ? GitTagsDatasource.id : GithubTagsDatasource.id;
dep.packageName = git ?? github;
} else {
dep = {
depName: app,
currentValue: requirement,
datasource: HexDatasource.id,
};
dep.currentValue = requirement;
dep.datasource = HexDatasource.id;
if (organization) {
dep.packageName = `${app}:${organization}`;
} else if (hex) {
@ -71,11 +79,16 @@ export async function extractPackageFile(
} else {
dep.packageName = app;
}
if (requirement?.startsWith('==')) {
dep.currentVersion = requirement.replace(regEx(/^==\s*/), '');
}
}
if (onlyValue !== undefined && !onlyEnvironments.includes('prod')) {
dep.depType = 'dev';
}
deps.set(app, dep);
logger.trace({ dep }, `setting ${app}`);
depMatchGroups = depMatchRegExp.exec(depBuffer)?.groups;

View file

@ -1,3 +1,8 @@
The `mix` manager extracts dependencies for the `hex` datasource and uses Renovate's implementation of Hex SemVer to evaluate updates.
The `mix` manager uses Renovate's implementation of [Elixir SemVer](https://hexdocs.pm/elixir/Version.html#module-requirements) to evaluate update ranges.
The `mix` package manager itself is also used to keep the lock file up-to-date.
The `mix` package manager itself is used to keep the lock file up-to-date.
The following `depTypes` are currently supported by the `mix` manager :
- `prod`: all dependencies by default
- `dev`: dependencies with [`:only` option](https://hexdocs.pm/mix/Mix.Tasks.Deps.html#module-dependency-definition-options) not containing `:prod`

View file

@ -11,7 +11,7 @@ import { find } from '../../../../util/host-rules';
import { Result } from '../../../../util/result';
import { parseUrl } from '../../../../util/url';
import { PypiDatasource } from '../../../datasource/pypi';
import { getGoogleAuthTokenRaw } from '../../../datasource/util';
import { getGoogleAuthHostRule } from '../../../datasource/util';
import type {
PackageDependency,
UpdateArtifact,
@ -265,12 +265,9 @@ async function getUsernamePassword(
}
if (url.hostname.endsWith('.pkg.dev')) {
const accessToken = await getGoogleAuthTokenRaw();
if (accessToken) {
return {
username: 'oauth2accesstoken',
password: accessToken,
};
const hostRule = await getGoogleAuthHostRule();
if (hostRule) {
return hostRule;
} else {
logger.once.debug({ url }, 'Could not get Google access token');
}

View file

@ -19,7 +19,7 @@ import { Result } from '../../../util/result';
import { parse as parseToml } from '../../../util/toml';
import { parseUrl } from '../../../util/url';
import { PypiDatasource } from '../../datasource/pypi';
import { getGoogleAuthTokenRaw } from '../../datasource/util';
import { getGoogleAuthHostRule } from '../../datasource/util';
import type { UpdateArtifact, UpdateArtifactsResult } from '../types';
import { Lockfile, PoetrySchemaToml } from './schema';
import type { PoetryFile, PoetrySource } from './types';
@ -131,12 +131,9 @@ async function getMatchingHostRule(url: string | undefined): Promise<HostRule> {
}
if (parsedUrl.hostname.endsWith('.pkg.dev')) {
const accessToken = await getGoogleAuthTokenRaw();
if (accessToken) {
return {
username: 'oauth2accesstoken',
password: accessToken,
};
const hostRule = await getGoogleAuthHostRule();
if (hostRule) {
return hostRule;
}
logger.once.debug(`Could not get Google access token (url=${url})`);
}

View file

@ -18,6 +18,7 @@ import * as hermit from './hermit';
import * as hex from './hex';
import * as ivy from './ivy';
import * as kubernetesApi from './kubernetes-api';
import * as lambdaNode from './lambda-node';
import * as loose from './loose';
import * as maven from './maven';
import * as nixpkgs from './nixpkgs';
@ -65,6 +66,7 @@ api.set(hermit.id, hermit.api);
api.set(hex.id, hex.api);
api.set(ivy.id, ivy.api);
api.set(kubernetesApi.id, kubernetesApi.api);
api.set(lambdaNode.id, lambdaNode.api);
api.set(loose.id, loose.api);
api.set(maven.id, maven.api);
api.set(nixpkgs.id, nixpkgs.api);

View file

@ -0,0 +1,118 @@
import { DateTime } from 'luxon';
import { api as lambdaVer } from '.';
describe('modules/versioning/lambda-node/index', () => {
let dtLocal: any;
beforeEach(() => {
dtLocal = DateTime.local;
});
afterEach(() => {
DateTime.local = dtLocal;
});
it.each`
currentValue | rangeStrategy | currentVersion | newVersion | expected
${'1.0.0'} | ${'replace'} | ${'1.0.0'} | ${'v1.1.0'} | ${'1.1.0'}
${'~8.0.0'} | ${'replace'} | ${'8.0.2'} | ${'v8.2.0'} | ${'~8.2.0'}
${'erbium'} | ${'replace'} | ${'12.0.0'} | ${'v14.1.4'} | ${'fermium'}
${'Fermium'} | ${'replace'} | ${'14.0.0'} | ${'v16.1.6'} | ${'gallium'}
${'gallium'} | ${'pin'} | ${'16.1.6'} | ${'v16.1.6'} | ${'16.1.6'}
${'gallium'} | ${'bump'} | ${'16.0.0'} | ${'v16.1.6'} | ${'gallium'}
${'gallium'} | ${'auto'} | ${'16.1.6'} | ${'v16.1.6'} | ${'gallium'}
`(
'getNewValue($currentValue, $rangeStrategy, $currentVersion, $newVersion, $expected) === $expected',
({ currentValue, rangeStrategy, currentVersion, newVersion, expected }) => {
const res = lambdaVer.getNewValue({
currentValue,
rangeStrategy,
currentVersion,
newVersion,
});
expect(res).toBe(expected);
},
);
const t1 = DateTime.fromISO('2024-09-01');
const t2 = DateTime.fromISO('2024-03-01');
it.each`
version | time | expected
${'v18.0.3'} | ${t1} | ${true}
${'v18.0.0'} | ${t1} | ${true}
${'18.0.0'} | ${t1} | ${true}
${'18.0.0a'} | ${t1} | ${false}
${'16.0.0'} | ${t2} | ${true}
${'16.0.0'} | ${t1} | ${false}
${'15.0.0'} | ${t1} | ${false}
${'14.9.0'} | ${t1} | ${false}
${'14.0.0'} | ${t1} | ${false}
${'12.0.3'} | ${t1} | ${false}
${'v12.0.3'} | ${t1} | ${false}
${'12.0.3a'} | ${t1} | ${false}
${'11.0.0'} | ${t1} | ${false}
${'10.0.0'} | ${t1} | ${false}
${'10.0.999'} | ${t1} | ${false}
${'10.1.0'} | ${t1} | ${false}
${'10.0.0a'} | ${t1} | ${false}
${'9.0.0'} | ${t1} | ${false}
`('isStable("$version") === $expected', ({ version, time, expected }) => {
DateTime.local = (...args: any[]) =>
args.length ? dtLocal.apply(DateTime, args) : time;
expect(lambdaVer.isStable(version as string)).toBe(expected);
});
it.each`
version | expected
${'16.0.0'} | ${true}
${'erbium'} | ${true}
${'bogus'} | ${false}
${'^10.0.0'} | ${true}
${'10.x'} | ${true}
${'10.9.8.7'} | ${false}
`('isValid("$version") === $expected', ({ version, expected }) => {
expect(lambdaVer.isValid(version as string)).toBe(expected);
});
it.each`
version | range | expected
${'16.0.0'} | ${'gallium'} | ${true}
${'16.0.0'} | ${'fermium'} | ${false}
`(
'matches("$version", "$range") === $expected',
({ version, range, expected }) => {
expect(lambdaVer.matches(version as string, range as string)).toBe(
expected,
);
},
);
it.each`
versions | range | expected
${['16.0.0']} | ${'gallium'} | ${'16.0.0'}
${['16.0.0', '14.0.0', '16.9.9']} | ${'gallium'} | ${'16.9.9'}
${['15.0.0', '14.0.0']} | ${'gallium'} | ${null}
`(
'getSatisfyingVersion("$versions", "$range") === $expected',
({ versions, range, expected }) => {
expect(
lambdaVer.getSatisfyingVersion(versions as string[], range as string),
).toBe(expected);
},
);
it.each`
versions | range | expected
${['16.0.0']} | ${'gallium'} | ${'16.0.0'}
${['16.0.0', '14.0.0', '16.9.9']} | ${'gallium'} | ${'16.0.0'}
${['15.0.0', '14.0.0']} | ${'gallium'} | ${null}
`(
'minSatisfyingVersion("$versions", "$range") === $expected',
({ versions, range, expected }) => {
expect(
lambdaVer.minSatisfyingVersion(versions as string[], range as string),
).toBe(expected);
},
);
});

View file

@ -0,0 +1,58 @@
import { DateTime } from 'luxon';
import {
getNewValue,
getSatisfyingVersion,
isStable as isNodeStable,
isValid,
matches,
minSatisfyingVersion,
} from '../node';
import { findScheduleForCodename } from '../node/schedule';
import npm from '../npm';
import type { VersioningApi } from '../types';
import { findLambdaScheduleForVersion } from './schedule';
export const id = 'lambda-node';
export const displayName = 'Lambda Node.js Runtime';
export const urls = [];
export const supportsRanges = false;
function normalizeValue(value: string): string {
const schedule = findScheduleForCodename(value);
if (schedule) {
const major = schedule.version.replace('v', '');
return `^${major}`;
}
return value;
}
export function isStable(version: string): boolean {
if (!isNodeStable(version)) {
return false;
}
const schedule = findLambdaScheduleForVersion(normalizeValue(version));
if (!schedule) {
return false;
}
if (typeof schedule.support === 'string') {
return DateTime.local() < DateTime.fromISO(schedule.support);
}
return true;
}
export const api: VersioningApi = {
...npm,
isStable,
getNewValue,
isValid,
matches,
getSatisfyingVersion,
minSatisfyingVersion,
allowUnstableMajorUpgrades: false,
};
export default api;

View file

@ -0,0 +1,12 @@
Renovate's Lambda Node.js versioning is a wrapper around the existing Node.js Versioning module with the only difference being
that it lists versions not currently supported by AWS as being unstable. This is intended to be a drop-in replacement
for dependencies that follow the `node` versioning schedule if you need to keep them in line with Lambda Runtime
releases.
Its primary purpose is to add Node Runtime support awareness, e.g.:
- Old Runtimes that cannot be updated will be marked as unstable
- Node.js LTS releases that do not have Runtimes released for them will be marked as unstable
You can _not_ use `lambda-node` versioning to replace `docker` versioning if you are using node tags with suffixes like
`-alpine`. This is because npm versioning treats these suffixes as implying pre-releases/instability.

View file

@ -0,0 +1,29 @@
import dataFiles from '../../../data-files.generated';
interface LambdaSchedule {
cycle: string;
releaseLabel: string;
/**
* Either `true` if currently in support or a string indicating the date at which support will end
*/
support: true | string;
}
export type LambdaData = Record<string, LambdaSchedule>;
const lambdaSchedule: LambdaData = JSON.parse(
dataFiles.get('data/lambda-node-js-schedule.json')!,
);
export function findLambdaScheduleForVersion(
version: string,
): LambdaSchedule | null {
const majorVersionMatch = version.match(/^v?([0-9]+)\./);
if (!majorVersionMatch?.[1]) {
return null;
}
return lambdaSchedule[majorVersionMatch[1]];
}

View file

@ -18,7 +18,7 @@ function normalizeValue(value: string): string {
return value;
}
function getNewValue({
export function getNewValue({
currentValue,
rangeStrategy,
currentVersion,

View file

@ -58,7 +58,8 @@
"type-check": "run-s 'generate:*' 'tsc --noEmit {@}' --",
"update-static-data": "run-s 'update-static-data:*'",
"update-static-data:distro-info": "node tools/static-data/generate-distro-info.mjs",
"update-static-data:node-schedule": "node tools/static-data/generate-node-schedule.mjs"
"update-static-data:node-schedule": "node tools/static-data/generate-node-schedule.mjs",
"update-static-data:lambda-node-schedule": "node tools/static-data/generate-lambda-node-schedule.mjs"
},
"repository": {
"type": "git",
@ -336,7 +337,7 @@
"jest-mock-extended": "3.0.7",
"jest-snapshot": "29.7.0",
"markdownlint-cli2": "0.17.1",
"memfs": "4.15.2",
"memfs": "4.15.3",
"nock": "13.5.6",
"npm-run-all2": "7.0.2",
"nyc": "17.1.0",

View file

@ -581,8 +581,8 @@ importers:
specifier: 0.17.1
version: 0.17.1
memfs:
specifier: 4.15.2
version: 4.15.2
specifier: 4.15.3
version: 4.15.3
nock:
specifier: 13.5.6
version: 13.5.6
@ -4555,8 +4555,8 @@ packages:
mdurl@2.0.0:
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
memfs@4.15.2:
resolution: {integrity: sha512-n8/qP8AT6CtY6kxCPYgYVusT5rS6axaT66dD3tYi2lm+l1iMH7YYpmW8H/qL5bfV4YvInCCgUDAWIRvrNS7kbQ==}
memfs@4.15.3:
resolution: {integrity: sha512-vR/g1SgqvKJgAyYla+06G4p/EOcEmwhYuVb1yc1ixcKf8o/sh7Zngv63957ZSNd1xrZJoinmNyDf2LzuP8WJXw==}
engines: {node: '>= 4.0.0'}
memorystream@0.3.1:
@ -11769,7 +11769,7 @@ snapshots:
mdurl@2.0.0: {}
memfs@4.15.2:
memfs@4.15.3:
dependencies:
'@jsonjoy.com/json-pack': 1.1.1(tslib@2.8.1)
'@jsonjoy.com/util': 1.5.0(tslib@2.8.1)

View file

@ -5,19 +5,19 @@ ARG BASE_IMAGE_TYPE=slim
# --------------------------------------
# slim image
# --------------------------------------
FROM ghcr.io/renovatebot/base-image:9.29.0@sha256:10e27273241a0ba63d3a298a7b1e178dbb75b84da6bc2ea7a71db7c9d1a4971c AS slim-base
FROM ghcr.io/renovatebot/base-image:9.29.1@sha256:db4b70c00fb197babca9dd92be612bef044d7a35d933d19c668864f84b52d1f8 AS slim-base
# --------------------------------------
# full image
# --------------------------------------
FROM ghcr.io/renovatebot/base-image:9.29.0-full@sha256:7b2353855c0f59b9efdb93ce9356aff5dad7d5102f8947c4ebc906855be9177c AS full-base
FROM ghcr.io/renovatebot/base-image:9.29.1-full@sha256:4880c7aae10ed892d49c6c5573418014605ce2824c978dbcc04382a2c26bb0df AS full-base
ENV RENOVATE_BINARY_SOURCE=global
# --------------------------------------
# build image
# --------------------------------------
FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:9.29.0@sha256:10e27273241a0ba63d3a298a7b1e178dbb75b84da6bc2ea7a71db7c9d1a4971c AS build
FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:9.29.1@sha256:db4b70c00fb197babca9dd92be612bef044d7a35d933d19c668864f84b52d1f8 AS build
# We want a specific node version here
# renovate: datasource=node-version

View file

@ -0,0 +1,44 @@
import got from 'got';
import { updateJsonFile } from './utils.mjs';
/**
* @typedef RuntimeDefinition
* @type {object}
* @property {string} cycle - The ID of the Runtime.
* @property {boolean|string} support - Either `true` if in support or a string denoting when support for this Runtime
* will end. 0.10.x is a sole exception which has `false` and will be filtered out.
*/
const lambdaDataUrl = 'https://endoflife.date/api/aws-lambda.json';
await (async () => {
console.log('Generating node schedule');
const { body } = await got(lambdaDataUrl);
/**
* @type Array<RuntimeDefinition>
*/
const lambdas = JSON.parse(body);
const nodeRuntimes = lambdas
// Filter Runtimes down to only NodeJS Runtimes
.filter((lambda) => lambda.cycle.startsWith('nodejs'))
// The only Runtime where support is not either `true` or a Date as a string is `0.10.x`, which we don't need
.filter((lambda) => lambda.support !== false)
.reduce((schedule, lambda) => {
const versionMatch = lambda.cycle.match(/^nodejs([0-9]+)\.x$/);
if (!versionMatch?.[1]) {
return schedule;
}
return {
...schedule,
[versionMatch[1]]: lambda,
};
}, {});
await updateJsonFile(
'./data/lambda-node-js-schedule.json',
JSON.stringify(nodeRuntimes, null, 2),
);
})();