Skip to content

Commit

Permalink
fix(datasource/go): support go proxy with abortOnError (#29823)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
ahippler and viceice committed Jul 15, 2024
1 parent d6c6d83 commit 38582c1
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 82 deletions.
184 changes: 105 additions & 79 deletions lib/modules/datasource/go/releases-goproxy.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { codeBlock } from 'common-tags';
import { mockDeep } from 'jest-mock-extended';
import { Fixtures } from '../../../../test/fixtures';
import * as httpMock from '../../../../test/http-mock';
import { mocked } from '../../../../test/util';
import * as _hostRules from '../../../util/host-rules';
import { GithubReleasesDatasource } from '../github-releases';
import { GithubTagsDatasource } from '../github-tags';
import { GoProxyDatasource } from './releases-goproxy';

const hostRules = mocked(_hostRules);
jest.mock('../../../util/host-rules', () => mockDeep());

const datasource = new GoProxyDatasource();

describe('modules/datasource/go/releases-goproxy', () => {
Expand All @@ -18,6 +24,10 @@ describe('modules/datasource/go/releases-goproxy', () => {
'getReleases',
);

beforeEach(() => {
hostRules.find.mockReturnValue({});
});

it('encodeCase', () => {
expect(datasource.encodeCase('foo')).toBe('foo');
expect(datasource.encodeCase('Foo')).toBe('!foo');
Expand Down Expand Up @@ -195,46 +205,54 @@ describe('modules/datasource/go/releases-goproxy', () => {
});
});

it('handles pipe fallback', async () => {
process.env.GOPROXY = `https://example.com|${baseUrl}`;

httpMock
.scope('https://example.com/github.com/google/btree')
.get('/@v/list')
.replyWithError('unknown');

httpMock
.scope(`${baseUrl}/github.com/google/btree`)
.get('/@v/list')
.reply(
200,
codeBlock`
it.each<{ abortOnError: boolean }>`
abortOnError
${true}
${false}
`(
'handles pipe fallback when abortOnError is $abortOnError',
async ({ abortOnError }) => {
process.env.GOPROXY = `https://example.com|${baseUrl}`;
hostRules.find.mockReturnValue({ abortOnError });

httpMock
.scope('https://example.com/github.com/google/btree')
.get('/@v/list')
.replyWithError('unknown');

httpMock
.scope(`${baseUrl}/github.com/google/btree`)
.get('/@v/list')
.reply(
200,
codeBlock`
v1.0.0
v1.0.1
`,
)
.get('/@v/v1.0.0.info')
.reply(200, { Version: 'v1.0.0', Time: '2018-08-13T15:31:12Z' })
.get('/@v/v1.0.1.info')
.reply(200, { Version: 'v1.0.1', Time: '2019-10-16T16:15:28Z' })
.get('/@latest')
.reply(200, { Version: 'v1.0.1' })
.get('/v2/@v/list')
.reply(404);

const res = await datasource.getReleases({
packageName: 'github.com/google/btree',
});

expect(res).toEqual({
releases: [
{ releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' },
{ releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' },
],
sourceUrl: 'https://github.com/google/btree',
tags: { latest: 'v1.0.1' },
});
});
)
.get('/@v/v1.0.0.info')
.reply(200, { Version: 'v1.0.0', Time: '2018-08-13T15:31:12Z' })
.get('/@v/v1.0.1.info')
.reply(200, { Version: 'v1.0.1', Time: '2019-10-16T16:15:28Z' })
.get('/@latest')
.reply(200, { Version: 'v1.0.1' })
.get('/v2/@v/list')
.reply(404);

const res = await datasource.getReleases({
packageName: 'github.com/google/btree',
});

expect(res).toEqual({
releases: [
{ releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' },
{ releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' },
],
sourceUrl: 'https://github.com/google/btree',
tags: { latest: 'v1.0.1' },
});
},
);

it('handles comma fallback', async () => {
process.env.GOPROXY = [
Expand Down Expand Up @@ -406,53 +424,61 @@ describe('modules/datasource/go/releases-goproxy', () => {
});
});

it('handles major releases', async () => {
process.env.GOPROXY = baseUrl;

httpMock
.scope(`${baseUrl}/github.com/google/btree`)
.get('/@v/list')
.reply(
200,
codeBlock`
it.each<{ abortOnError: boolean }>`
abortOnError
${true}
${false}
`(
'handles major releases with abortOnError is $abortOnError',
async ({ abortOnError }) => {
process.env.GOPROXY = baseUrl;
hostRules.find.mockReturnValue({ abortOnError });

httpMock
.scope(`${baseUrl}/github.com/google/btree`)
.get('/@v/list')
.reply(
200,
codeBlock`
v1.0.0
v1.0.1
`,
)
.get('/@v/v1.0.0.info')
.reply(200, { Version: 'v1.0.0', Time: '2018-08-13T15:31:12Z' })
.get('/@v/v1.0.1.info')
.reply(200, { Version: 'v1.0.1', Time: '2019-10-16T16:15:28Z' })
.get('/@latest')
.reply(200, { Version: 'v1.0.1' })
.get('/v2/@v/list')
.reply(
200,
codeBlock`
)
.get('/@v/v1.0.0.info')
.reply(200, { Version: 'v1.0.0', Time: '2018-08-13T15:31:12Z' })
.get('/@v/v1.0.1.info')
.reply(200, { Version: 'v1.0.1', Time: '2019-10-16T16:15:28Z' })
.get('/@latest')
.reply(200, { Version: 'v1.0.1' })
.get('/v2/@v/list')
.reply(
200,
codeBlock`
v2.0.0
`,
)
.get('/v2/@v/v2.0.0.info')
.reply(200, { Version: 'v2.0.0', Time: '2020-10-16T16:15:28Z' })
.get('/v2/@latest')
.reply(200, { Version: 'v2.0.0' })
.get('/v3/@v/list')
.reply(404);

const res = await datasource.getReleases({
packageName: 'github.com/google/btree',
});

expect(res).toEqual({
releases: [
{ releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' },
{ releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' },
{ releaseTimestamp: '2020-10-16T16:15:28Z', version: 'v2.0.0' },
],
sourceUrl: 'https://github.com/google/btree',
tags: { latest: 'v2.0.0' },
});
});
)
.get('/v2/@v/v2.0.0.info')
.reply(200, { Version: 'v2.0.0', Time: '2020-10-16T16:15:28Z' })
.get('/v2/@latest')
.reply(200, { Version: 'v2.0.0' })
.get('/v3/@v/list')
.reply(404);

const res = await datasource.getReleases({
packageName: 'github.com/google/btree',
});

expect(res).toEqual({
releases: [
{ releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' },
{ releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' },
{ releaseTimestamp: '2020-10-16T16:15:28Z', version: 'v2.0.0' },
],
sourceUrl: 'https://github.com/google/btree',
tags: { latest: 'v2.0.0' },
});
},
);

it('handles gopkg.in major releases', async () => {
process.env.GOPROXY = baseUrl;
Expand Down
11 changes: 8 additions & 3 deletions lib/modules/datasource/go/releases-goproxy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import is from '@sindresorhus/is';
import { DateTime } from 'luxon';
import { logger } from '../../../logger';
import { ExternalHostError } from '../../../types/errors/external-host-error';
import { cache } from '../../../util/cache/package/decorator';
import { filterMap } from '../../../util/filter-map';
import { HttpError } from '../../../util/http';
Expand Down Expand Up @@ -88,7 +89,9 @@ export class GoProxyDatasource extends Datasource {
break;
}
} catch (err) {
const statusCode = err?.response?.statusCode;
const potentialHttpError =
err instanceof ExternalHostError ? err.err : err;
const statusCode = potentialHttpError?.response?.statusCode;
const canFallback =
fallback === '|' ? true : statusCode === 404 || statusCode === 410;
const msg = canFallback
Expand Down Expand Up @@ -213,9 +216,11 @@ export class GoProxyDatasource extends Datasource {
});
result.releases.push(...releases);
} catch (err) {
const potentialHttpError =
err instanceof ExternalHostError ? err.err : err;
if (
err instanceof HttpError &&
err.response?.statusCode === 404 &&
potentialHttpError instanceof HttpError &&
potentialHttpError.response?.statusCode === 404 &&
major !== packageMajor
) {
break;
Expand Down

0 comments on commit 38582c1

Please sign in to comment.