Skip to content

Commit

Permalink
Merge branch 'main' into feat/github-action/retain-spaces/31360
Browse files Browse the repository at this point in the history
  • Loading branch information
rarkins authored Nov 28, 2024
2 parents 1f1eb15 + bde1849 commit ceec00c
Show file tree
Hide file tree
Showing 28 changed files with 667 additions and 211 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
FROM ghcr.io/containerbase/devcontainer:13.0.21
FROM ghcr.io/containerbase/devcontainer:13.0.22
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ jobs:
os: ${{ runner.os }}

- name: Lint markdown
uses: DavidAnson/markdownlint-cli2-action@db43aef879112c3119a410d69f66701e0d530809 # v17.0.0
uses: DavidAnson/markdownlint-cli2-action@eb5ca3ab411449c66620fe7f1b3c9e10547144b0 # v18.0.0

- name: Lint fenced code blocks
run: pnpm doc-fence-check
Expand Down Expand Up @@ -592,7 +592,7 @@ jobs:
os: ${{ runner.os }}

- name: Setup PDM
uses: pdm-project/setup-pdm@568ddd69406b30de1774ec0044b73ae06e716aa4 # v4.1
uses: pdm-project/setup-pdm@b2472ca4258a9ea3aee813980a0100a2261a42fc # v4.2
with:
python-version-file: .python-version
version: ${{ env.PDM_VERSION }}
Expand Down Expand Up @@ -684,7 +684,7 @@ jobs:
show-progress: false

- name: docker-config
uses: containerbase/internal-tools@0b2d87b3f40e59986fc748c902bff40119629435 # v3.5.0
uses: containerbase/internal-tools@e386c8e7bd305d803e0874abccbe153ec1d33a6d # v3.5.2
with:
command: docker-config

Expand Down
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ if (process.env.SCHEDULE_TEST_SHARDS) {
};

if (process.env.ALL_PLATFORMS === 'true') {
shardGrouping['windows-latest'] = scheduleItems(shardKeys, 8);
// shardGrouping['windows-latest'] = scheduleItems(shardKeys, 8);
shardGrouping['macos-latest'] = scheduleItems(shardKeys, 4);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ const options: RenovateOptions[] = [
description:
'Change this value to override the default Renovate sidecar image.',
type: 'string',
default: 'ghcr.io/containerbase/sidecar:13.0.21',
default: 'ghcr.io/containerbase/sidecar:13.0.22',
globalOnly: true,
},
{
Expand Down
149 changes: 149 additions & 0 deletions lib/config/presets/internal/schedule.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { isScheduledNow } from '../../../workers/repository/update/branch/schedule';
import type { RenovateConfig } from '../../types';
import { presets } from './schedule';

describe('config/presets/internal/schedule', () => {
let config: RenovateConfig;

beforeAll(() => {
jest.useFakeTimers();
});

beforeEach(() => {
jest.setSystemTime(new Date('2017-06-30T10:50:00.000')); // Locally 2017-06-30 10:50am

config = {};
});

describe('daily', () => {
it.each`
datetime | expected
${'2017-06-30T00:50:00.000'} | ${true}
${'2017-06-30T01:50:00.000'} | ${true}
${'2017-06-30T02:50:00.000'} | ${true}
${'2017-06-30T03:50:00.000'} | ${true}
${'2017-06-30T04:50:00.000'} | ${false}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.daily.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

describe('earlyMondays', () => {
it.each`
datetime | expected
${'2017-06-26T00:50:00.000'} | ${true}
${'2017-06-26T01:50:00.000'} | ${true}
${'2017-06-26T02:50:00.000'} | ${true}
${'2017-06-26T03:50:00.000'} | ${true}
${'2017-06-26T04:50:00.000'} | ${false}
${'2017-06-30T00:50:00.000'} | ${false}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.earlyMondays.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

describe('monthly', () => {
it.each`
datetime | expected
${'2017-06-01T00:50:00.000'} | ${true}
${'2017-06-01T01:50:00.000'} | ${true}
${'2017-06-01T02:50:00.000'} | ${true}
${'2017-06-01T03:50:00.000'} | ${true}
${'2017-06-01T04:50:00.000'} | ${false}
${'2017-06-02T00:50:00.000'} | ${false}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.monthly.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

describe('nonOfficeHours', () => {
it.each`
datetime | expected
${'2017-06-01T00:50:00.000'} | ${true}
${'2017-06-01T01:50:00.000'} | ${true}
${'2017-06-01T02:50:00.000'} | ${true}
${'2017-06-01T03:50:00.000'} | ${true}
${'2017-06-01T04:50:00.000'} | ${true}
${'2017-06-01T10:50:00.000'} | ${false}
${'2017-06-01T11:50:00.000'} | ${false}
${'2017-06-01T22:50:00.000'} | ${true}
${'2017-06-01T23:50:00.000'} | ${true}
${'2017-06-03T09:50:00.000'} | ${true}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.nonOfficeHours.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

// const weekdays = ['every weekday'];
// const weekends = ['every weekend'];
// const yearly = ['every 12 months on the first day of the month'];
describe('quarterly', () => {
it.each`
datetime | expected
${'2017-01-01T00:50:00.000'} | ${true}
${'2017-04-01T01:50:00.000'} | ${true}
${'2017-07-01T02:50:00.000'} | ${true}
${'2017-10-01T03:50:00.000'} | ${true}
${'2017-02-01T04:50:00.000'} | ${false}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.quarterly.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

describe('weekdays', () => {
it.each`
datetime | expected
${'2017-06-01T00:50:00.000'} | ${true}
${'2017-06-02T01:50:00.000'} | ${true}
${'2017-06-03T02:50:00.000'} | ${false}
${'2017-06-04T03:50:00.000'} | ${false}
${'2017-06-05T04:50:00.000'} | ${true}
${'2017-06-06T10:50:00.000'} | ${true}
${'2017-06-07T11:50:00.000'} | ${true}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.weekdays.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

describe('weekends', () => {
it.each`
datetime | expected
${'2017-06-01T00:50:00.000'} | ${false}
${'2017-06-02T01:50:00.000'} | ${false}
${'2017-06-03T02:50:00.000'} | ${true}
${'2017-06-04T03:50:00.000'} | ${true}
${'2017-06-05T04:50:00.000'} | ${false}
${'2017-06-06T10:50:00.000'} | ${false}
${'2017-06-07T11:50:00.000'} | ${false}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.weekends.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});

describe('yearly', () => {
it.each`
datetime | expected
${'2017-01-01T00:50:00.000'} | ${true}
${'2017-02-02T01:50:00.000'} | ${false}
${'2018-01-01T02:50:00.000'} | ${true}
`('$datetime', ({ datetime, expected }) => {
config.schedule = presets.yearly.schedule;
jest.setSystemTime(new Date(datetime));
expect(isScheduledNow(config)).toBe(expected);
});
});
});
1 change: 1 addition & 0 deletions lib/data/monorepo.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@
"https://github.com/dotnet/aspnetcore",
"https://github.com/dotnet/efcore",
"https://github.com/dotnet/extensions",
"https://github.com/dotnet/fsharp",
"https://github.com/dotnet/maui",
"https://github.com/dotnet/roslyn",
"https://github.com/dotnet/runtime",
Expand Down
42 changes: 0 additions & 42 deletions lib/modules/datasource/pypi/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,47 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`modules/datasource/pypi/index getReleases fall back from json and process data from simple endpoint 1`] = `
{
"registryUrl": "https://custom.pypi.net/foo",
"releases": [
{
"version": "0.1.2",
},
{
"version": "0.1.3",
},
{
"version": "0.1.4",
},
{
"version": "0.2.0",
},
{
"version": "0.2.1",
},
{
"version": "0.2.2",
},
{
"version": "0.3.0",
},
{
"version": "0.4.0",
},
{
"version": "0.4.1",
},
{
"version": "0.4.2",
},
{
"isDeprecated": true,
"version": "0.5.0",
},
],
}
`;

exports[`modules/datasource/pypi/index getReleases parses data-requires-python and respects constraints from simple endpoint 1`] = `
{
"registryUrl": "https://some.registry.org/simple",
Expand Down
50 changes: 31 additions & 19 deletions lib/modules/datasource/pypi/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ describe('modules/datasource/pypi/index', () => {
.scope('https://custom.pypi.net/foo')
.get('/azure-cli-monitor/json')
.replyWithError('error');
httpMock
.scope('https://custom.pypi.net/foo')
.get('/azure-cli-monitor/')
.replyWithError('error');
httpMock
.scope('https://second-index/foo')
.get('/azure-cli-monitor/json')
Expand Down Expand Up @@ -308,6 +312,11 @@ describe('modules/datasource/pypi/index', () => {
.get('/not-normalized-package/json')
.reply(200, htmlResponse);

httpMock
.scope(baseUrl)
.get('/not-normalized-package/')
.reply(200, htmlResponse);

await getPkgReleases({
datasource,
registryUrls: [baseUrl],
Expand Down Expand Up @@ -716,25 +725,28 @@ describe('modules/datasource/pypi/index', () => {
).toBeNull();
});

it('fall back from json and process data from simple endpoint', async () => {
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/json')
.reply(404);
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/')
.reply(200, htmlResponse);
const config = {
registryUrls: ['https://custom.pypi.net/foo'],
};
const result = await getPkgReleases({
datasource,
...config,
packageName: 'dj-database-url',
});
expect(result).toMatchSnapshot();
});
it.each([404, 403])(
'fall back from json and process data from simple endpoint',
async (code: number) => {
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/json')
.reply(code);
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/')
.reply(200, htmlResponse);
const config = {
registryUrls: ['https://custom.pypi.net/foo'],
};
const result = await getPkgReleases({
datasource,
...config,
packageName: 'dj-database-url',
});
expect(result).not.toBeNull();
},
);

it('parses data-requires-python and respects constraints from simple endpoint', async () => {
httpMock
Expand Down
6 changes: 1 addition & 5 deletions lib/modules/datasource/pypi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,9 @@ export class PypiDatasource extends Datasource {
// we need to resolve early here so we can catch any 404s and fallback to a simple lookup
dependency = await this.getDependency(normalizedLookupName, hostUrl);
} catch (err) {
if (err.statusCode !== 404) {
throw err;
}

// error contacting json-style api -- attempt to fallback to a simple-style api
logger.trace(
{ packageName, hostUrl },
{ packageName, hostUrl, err },
'Looking up pypi simple dependency via fallback',
);
dependency = await this.getSimpleDependency(
Expand Down
6 changes: 6 additions & 0 deletions lib/modules/datasource/pypi/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
This datasource uses the following logic to determine lookup URLs:

- If the normalized registryUrl ends in `/simple/` or `/+simple/` then only the simple API will be tried
- Otherwise, the JSON API will be tried first
- If the JSON API returns a result, it will be used
- If the JSON API throws an error (e.g. 403, 404) then the simple API will be tried
34 changes: 34 additions & 0 deletions lib/modules/manager/dockerfile/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,40 @@ describe('modules/manager/dockerfile/extract', () => {
]);
});

it('handles run --mount=from', () => {
const res = extractPackageFile(
'FROM scratch as build\n' +
'FROM scratch as final\n' +
'RUN --mount=from=ghcr.io/astral-sh/uv,source=/uv,target=/bin/uv uv pip install numpy\n' +
'RUN --mount=type=cache,from=example.com/cache/image,target=/root/.cache pip install numpy\n' +
'RUN --mount=type=bind,from=build,source=/project/dist/lib.whl,target=/dist/lib.whl pip install /dist/lib.whl\n',
'',
{},
)?.deps;
expect(res).toEqual([
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: undefined,
datasource: 'docker',
depName: 'ghcr.io/astral-sh/uv',
depType: 'stage',
replaceString: 'ghcr.io/astral-sh/uv',
},
{
autoReplaceStringTemplate:
'{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: undefined,
datasource: 'docker',
depName: 'example.com/cache/image',
depType: 'final',
replaceString: 'example.com/cache/image',
},
]);
});

it('is case insensitive', () => {
const res = extractPackageFile('From node\n', '', {})?.deps;
expect(res).toEqual([
Expand Down
Loading

0 comments on commit ceec00c

Please sign in to comment.