import { isBoolean } from '@sindresorhus/is'; import { logger } from '../../../logger/index.ts'; import { queryReleases } from '../../../util/github/graphql/index.ts'; import { findCommitOfTag } from '../../../util/github/tags.ts'; import { getSourceUrl } from '../../../util/github/url.ts'; import { GithubHttp } from '../../../util/http/github.ts'; import { Datasource } from '../datasource.ts'; import type { DigestConfig, GetReleasesConfig, Release, ReleaseResult, } from '../types.ts'; export const cacheNamespace = 'datasource-github-releases'; export class GithubReleasesDatasource extends Datasource { static readonly id = 'github-releases'; override readonly defaultRegistryUrls = ['https://github.com']; override http: GithubHttp; override readonly releaseTimestampSupport = true; // Note: not sure override readonly releaseTimestampNote = 'The release timestamp is determined from the `releaseTimestamp` field from the response.'; override readonly sourceUrlSupport = 'package'; override readonly sourceUrlNote = 'The source URL is determined by using the `packageName` and `registryUrl`.'; constructor() { super(GithubReleasesDatasource.id); this.http = new GithubHttp(GithubReleasesDatasource.id); } /** * Attempts to resolve the digest for the specified package. * * The `newValue` supplied here should be a valid tag for the GitHub release. The digest * of a GitHub release will be the underlying SHA of the release tag. * * Some managers like Bazel will deal with individual artifacts from releases and handle * the artifact checksum computation separately. This data-source does not know about * specific artifacts being used, as that could vary per manager */ override getDigest( { packageName: repo, currentValue, currentDigest, registryUrl, }: DigestConfig, newValue: string, ): Promise { logger.debug( { repo, currentValue, currentDigest, registryUrl, newValue }, 'getDigest', ); return findCommitOfTag(registryUrl, repo, newValue, this.http); } /** * This function can be used to fetch releases with a customizable versioning * (e.g. semver) and with releases. * * This function will: * - Fetch all releases * - Sanitize the versions if desired (e.g. strip out leading 'v') * - Return a dependency object containing sourceUrl string and releases array */ async getReleases(config: GetReleasesConfig): Promise { const releasesResult = await queryReleases(config, this.http); const releases = releasesResult.map((item) => { const { version, releaseTimestamp, isStable } = item; const result: Release = { version, gitRef: version, releaseTimestamp, }; if (isBoolean(isStable)) { result.isStable = isStable; } return result; }); const sourceUrl = getSourceUrl(config.packageName, config.registryUrl); return { sourceUrl, releases }; } }