Files
Sebastian Poxhofer a473e73b3e fix(linters): forbid inert counts in v8 coverage-ignore comments (#45287)
Adds a custom oxlint rule renovate/v8-ignore-no-count that flags the
count form '/* v8 ignore next <N> */'. The count is not honored by
vitest's ast-v8-to-istanbul hint parser, which captures only the
keyword (if/else/next/file); 'next' always exempts exactly the next
AST node. Trailing counts therefore suggest a line range that is never
applied and mislead readers.

The rule is autofixable (drops the count, preserving actual behavior)
and has been applied to all existing occurrences.
2026-08-22 11:25:31 +00:00

140 lines
4.2 KiB
TypeScript

import { isArray } from '@sindresorhus/is';
import { logger } from '../../../logger/index.ts';
import { withCache } from '../../../util/cache/package/with-cache.ts';
import { detectPlatform } from '../../../util/common.ts';
import { parseGitUrl } from '../../../util/git/url.ts';
import { GithubHttp } from '../../../util/http/github.ts';
import { fromBase64 } from '../../../util/string.ts';
import { joinUrlParts } from '../../../util/url.ts';
import { GithubContentResponse } from '../../platform/github/schema.ts';
import semver from '../../versioning/semver/index.ts';
import { Datasource } from '../datasource.ts';
import type { GetReleasesConfig, ReleaseResult } from '../types.ts';
import { BitriseStepFile } from './schema.ts';
export class BitriseDatasource extends Datasource {
static readonly id = 'bitrise';
override readonly http: GithubHttp;
constructor() {
super(BitriseDatasource.id);
this.http = new GithubHttp(this.id);
}
override readonly customRegistrySupport = true;
override readonly defaultRegistryUrls = [
'https://github.com/bitrise-io/bitrise-steplib.git',
];
override readonly releaseTimestampSupport = true;
override readonly releaseTimestampNote =
'The release timestamp is determined from the `published_at` field in the results.';
override readonly sourceUrlSupport = 'release';
override readonly sourceUrlNote =
'The source URL is determined from the `source_code_url` field of the release object in the results.';
private async _getReleases({
packageName,
registryUrl,
}: GetReleasesConfig): Promise<ReleaseResult | null> {
/* v8 ignore next -- should never happen */
if (!registryUrl) {
return null;
}
const parsedUrl = parseGitUrl(registryUrl);
if (detectPlatform(registryUrl) !== 'github') {
logger.once.warn(
{ source: parsedUrl.source },
'Unsupported Git hoster for this datasource',
);
return null;
}
const result: ReleaseResult = {
releases: [],
};
const massagedPackageName = encodeURIComponent(packageName);
const baseApiURL =
parsedUrl.resource === 'github.com'
? 'https://api.github.com'
: `https://${parsedUrl.resource}/api/v3`;
const packageUrl = joinUrlParts(
baseApiURL,
'repos',
parsedUrl.full_name,
'contents/steps',
massagedPackageName,
);
const { body: packageRaw } = await this.http.getJson(
packageUrl,
GithubContentResponse,
);
if (!isArray(packageRaw)) {
logger.warn(
{ data: packageRaw, url: packageUrl },
'Got unexpected response for Bitrise package location',
);
return null;
}
for (const versionDir of packageRaw.filter((element) =>
semver.isValid(element.name),
)) {
const stepUrl = joinUrlParts(packageUrl, versionDir.name, 'step.yml');
// TODO use getRawFile when ready #30155
const { body } = await this.http.getJson(stepUrl, GithubContentResponse);
if (!('content' in body)) {
logger.warn(
{ data: body, url: stepUrl },
'Got unexpected response for Bitrise step location',
);
return null;
}
if (body.encoding !== 'base64') {
logger.warn(
{ encoding: body.encoding, data: body, url: stepUrl },
`Got unexpected encoding for Bitrise step location`,
);
return null;
}
const content = fromBase64(body.content);
const { published_at, source_code_url } = BitriseStepFile.parse(content);
result.releases.push({
version: versionDir.name,
releaseTimestamp: published_at,
sourceUrl: source_code_url,
});
}
// if we have no releases return null
if (!result.releases.length) {
return null;
}
return {
...result,
homepage: `https://bitrise.io/integrations/steps/${packageName}`,
};
}
getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {
return withCache(
{
namespace: `datasource-${BitriseDatasource.id}`,
key: `${config.registryUrl}/${config.packageName}`,
fallback: true,
},
() => this._getReleases(config),
);
}
}