diff --git a/lib/modules/datasource/github-releases/cache/cache-base.spec.ts b/lib/modules/datasource/github-releases/cache/cache-base.spec.ts
index 20166e40a844f20d3e7ad561745c0d5edf5353b2..407ca669dd6c146c8eb4c9d205529944159b0963 100644
--- a/lib/modules/datasource/github-releases/cache/cache-base.spec.ts
+++ b/lib/modules/datasource/github-releases/cache/cache-base.spec.ts
@@ -2,8 +2,8 @@ import { DateTime } from 'luxon';
 import { mocked } from '../../../../../test/util';
 import * as _packageCache from '../../../../util/cache/package';
 import type {
-  QueryResponse,
-  StoredItemBase,
+  GithubCachedItem,
+  GithubGraphqlRepoResponse,
 } from '../../../../util/github/types';
 import {
   GithubGraphqlResponse,
@@ -20,14 +20,14 @@ interface FetchedItem {
   foo: string;
 }
 
-interface StoredItem extends StoredItemBase {
+interface StoredItem extends GithubCachedItem {
   bar: string;
 }
 
 type GraphqlDataResponse = {
   statusCode: 200;
   headers: Record<string, string>;
-  body: GithubGraphqlResponse<QueryResponse<FetchedItem>>;
+  body: GithubGraphqlResponse<GithubGraphqlRepoResponse<FetchedItem>>;
 };
 
 type GraphqlResponse = GraphqlDataResponse | Error;
diff --git a/lib/modules/datasource/github-releases/cache/cache-base.ts b/lib/modules/datasource/github-releases/cache/cache-base.ts
index ec2db09f54bdb92ec6d21f76cc5f069d72f290f8..a105abd8a9975e273a4a57e6a4408f1670889103 100644
--- a/lib/modules/datasource/github-releases/cache/cache-base.ts
+++ b/lib/modules/datasource/github-releases/cache/cache-base.ts
@@ -6,10 +6,10 @@ import * as packageCache from '../../../../util/cache/package';
 import type {
   CacheOptions,
   ChangelogRelease,
+  GithubCachedItem,
   GithubDatasourceCache,
-  GithubQueryParams,
-  QueryResponse,
-  StoredItemBase,
+  GithubGraphqlRepoParams,
+  GithubGraphqlRepoResponse,
 } from '../../../../util/github/types';
 import { getApiBaseUrl } from '../../../../util/github/url';
 import type {
@@ -100,7 +100,7 @@ function isExpired(
 }
 
 export abstract class AbstractGithubDatasourceCache<
-  StoredItem extends StoredItemBase,
+  CachedItem extends GithubCachedItem,
   FetchedItem = unknown
 > {
   private updateDuration: DurationLikeObject;
@@ -163,16 +163,18 @@ export abstract class AbstractGithubDatasourceCache<
    * Transform `fetchedItem` for storing in the package cache.
    * @param fetchedItem Node obtained from GraphQL response
    */
-  abstract coerceFetched(fetchedItem: FetchedItem): StoredItem | null;
+  abstract coerceFetched(fetchedItem: FetchedItem): CachedItem | null;
 
   private async queryPayload(
     baseUrl: string,
-    variables: GithubQueryParams,
+    variables: GithubGraphqlRepoParams,
     options: GithubHttpOptions
-  ): Promise<QueryResponse<FetchedItem>['repository']['payload'] | Error> {
+  ): Promise<
+    GithubGraphqlRepoResponse<FetchedItem>['repository']['payload'] | Error
+  > {
     try {
       const graphqlRes = await this.http.postJson<
-        GithubGraphqlResponse<QueryResponse<FetchedItem>>
+        GithubGraphqlResponse<GithubGraphqlRepoResponse<FetchedItem>>
       >('/graphql', {
         ...options,
         baseUrl,
@@ -222,14 +224,14 @@ export abstract class AbstractGithubDatasourceCache<
   async getItemsImpl(
     releasesConfig: GetReleasesConfig,
     changelogRelease?: ChangelogRelease
-  ): Promise<StoredItem[]> {
+  ): Promise<CachedItem[]> {
     const { packageName, registryUrl } = releasesConfig;
 
     // The time meant to be used across the function
     const now = DateTime.now();
 
     // Initialize items and timestamps for the new cache
-    let cacheItems: Record<string, StoredItem> = {};
+    let cacheItems: Record<string, CachedItem> = {};
 
     // Add random minutes to the creation date in order to
     // provide back-off time during mass cache invalidation.
@@ -244,7 +246,7 @@ export abstract class AbstractGithubDatasourceCache<
     if (owner && name) {
       const baseUrl = this.getBaseUrl(registryUrl);
       const cacheKey = this.getCacheKey(registryUrl, packageName);
-      const cache = await packageCache.get<GithubDatasourceCache<StoredItem>>(
+      const cache = await packageCache.get<GithubDatasourceCache<CachedItem>>(
         this.cacheNs,
         cacheKey
       );
@@ -280,7 +282,7 @@ export abstract class AbstractGithubDatasourceCache<
           cacheItems
         )
       ) {
-        const variables: GithubQueryParams = {
+        const variables: GithubGraphqlRepoParams = {
           owner,
           name,
           cursor: null,
@@ -386,7 +388,7 @@ export abstract class AbstractGithubDatasourceCache<
           .diff(now, ['minutes'])
           .toObject();
         if (ttlMinutes && ttlMinutes > 0) {
-          const cacheValue: GithubDatasourceCache<StoredItem> = {
+          const cacheValue: GithubDatasourceCache<CachedItem> = {
             items: cacheItems,
             createdAt: cacheCreatedAt,
             updatedAt: now.toISO(),
@@ -413,12 +415,12 @@ export abstract class AbstractGithubDatasourceCache<
   getItems(
     releasesConfig: GetReleasesConfig,
     changelogRelease?: ChangelogRelease
-  ): Promise<StoredItem[]> {
+  ): Promise<CachedItem[]> {
     const { packageName, registryUrl } = releasesConfig;
     const cacheKey = this.getCacheKey(registryUrl, packageName);
     const promiseKey = `github-datasource-cache:${this.cacheNs}:${cacheKey}`;
     const res =
-      memCache.get<Promise<StoredItem[]>>(promiseKey) ??
+      memCache.get<Promise<CachedItem[]>>(promiseKey) ??
       this.getItemsImpl(releasesConfig, changelogRelease);
     memCache.set(promiseKey, res);
     return res;
@@ -430,7 +432,7 @@ export abstract class AbstractGithubDatasourceCache<
   }
 
   public getLastReleaseTimestamp(
-    items: Record<string, StoredItem>
+    items: Record<string, CachedItem>
   ): string | null {
     let result: string | null = null;
     let latest: DateTime | null = null;
@@ -454,7 +456,7 @@ export abstract class AbstractGithubDatasourceCache<
     changelogRelease: ChangelogRelease | undefined,
     now: DateTime,
     updateDuration: DurationLikeObject,
-    cacheItems: Record<string, StoredItem>
+    cacheItems: Record<string, CachedItem>
   ): boolean {
     if (!changelogRelease?.date) {
       return false;
diff --git a/lib/modules/datasource/github-releases/cache/index.spec.ts b/lib/modules/datasource/github-releases/cache/index.spec.ts
index 9839f49432109f69cf7ab1781e9074cf35d03949..2e5c70cf29c52b1338a080f3febf4aa33103246f 100644
--- a/lib/modules/datasource/github-releases/cache/index.spec.ts
+++ b/lib/modules/datasource/github-releases/cache/index.spec.ts
@@ -1,11 +1,12 @@
+import type { GithubGraphqlRelease } from '../../../../util/github/types';
 import { GithubHttp } from '../../../../util/http/github';
-import { CacheableGithubReleases, FetchedRelease } from '.';
+import { CacheableGithubReleases } from '.';
 
 describe('modules/datasource/github-releases/cache/index', () => {
   const http = new GithubHttp();
   const cache = new CacheableGithubReleases(http, { resetDeltaMinutes: 0 });
 
-  const fetchedItem: FetchedRelease = {
+  const fetchedItem: GithubGraphqlRelease = {
     version: '1.2.3',
     releaseTimestamp: '2020-04-09T10:00:00.000Z',
     isDraft: false,
diff --git a/lib/modules/datasource/github-releases/cache/index.ts b/lib/modules/datasource/github-releases/cache/index.ts
index 01da1bc6bbd1c00df6dd6fd514ba6d93c9ec4cb4..1c63e040a9d760b4f55540b3aff8ea06bcfc1d3f 100644
--- a/lib/modules/datasource/github-releases/cache/index.ts
+++ b/lib/modules/datasource/github-releases/cache/index.ts
@@ -1,6 +1,7 @@
 import type {
   CacheOptions,
-  StoredItemBase,
+  GithubCachedRelease,
+  GithubGraphqlRelease,
 } from '../../../../util/github/types';
 import type { GithubHttp } from '../../../../util/http/github';
 import { AbstractGithubDatasourceCache } from './cache-base';
@@ -32,28 +33,9 @@ query ($owner: String!, $name: String!, $cursor: String, $count: Int!) {
 }
 `;
 
-export interface FetchedRelease {
-  version: string;
-  releaseTimestamp: string;
-  isDraft: boolean;
-  isPrerelease: boolean;
-  url: string;
-  id: number;
-  name: string;
-  description: string;
-}
-
-export interface StoredRelease extends StoredItemBase {
-  isStable?: boolean;
-  url: string;
-  id: number;
-  name: string;
-  description: string;
-}
-
 export class CacheableGithubReleases extends AbstractGithubDatasourceCache<
-  StoredRelease,
-  FetchedRelease
+  GithubCachedRelease,
+  GithubGraphqlRelease
 > {
   cacheNs = 'github-datasource-graphql-releases';
   graphqlQuery = query;
@@ -62,7 +44,7 @@ export class CacheableGithubReleases extends AbstractGithubDatasourceCache<
     super(http, opts);
   }
 
-  coerceFetched(item: FetchedRelease): StoredRelease | null {
+  coerceFetched(item: GithubGraphqlRelease): GithubCachedRelease | null {
     const {
       version,
       releaseTimestamp,
@@ -78,7 +60,7 @@ export class CacheableGithubReleases extends AbstractGithubDatasourceCache<
       return null;
     }
 
-    const result: StoredRelease = {
+    const result: GithubCachedRelease = {
       version,
       releaseTimestamp,
       url,
diff --git a/lib/modules/datasource/github-releases/digest.spec.ts b/lib/modules/datasource/github-releases/digest.spec.ts
index 3a14f7a218a754489545024e672e0f9feefe68c5..35fff7e25297ff82587da7e267113e453f07c9d6 100644
--- a/lib/modules/datasource/github-releases/digest.spec.ts
+++ b/lib/modules/datasource/github-releases/digest.spec.ts
@@ -1,6 +1,6 @@
 import hasha from 'hasha';
 import * as httpMock from '../../../../test/http-mock';
-import type { DigestAsset } from '../../../util/github/types';
+import type { GithubDigestFile } from '../../../util/github/types';
 import { GitHubReleaseMocker } from './test';
 
 import { GithubReleasesDatasource } from '.';
@@ -77,7 +77,7 @@ describe('modules/datasource/github-releases/digest', () => {
 
   describe('mapDigestAssetToRelease', () => {
     describe('with digest file', () => {
-      const digestAsset: DigestAsset = {
+      const digestAsset: GithubDigestFile = {
         assetName: 'SHASUMS.txt',
         currentVersion: 'v1.0.0',
         currentDigest: 'old-digest',
@@ -136,7 +136,7 @@ describe('modules/datasource/github-releases/digest', () => {
     });
 
     describe('with digested file', () => {
-      const digestAsset: DigestAsset = {
+      const digestAsset: GithubDigestFile = {
         assetName: 'asset.zip',
         currentVersion: 'v1.0.0',
         currentDigest: '0'.repeat(64),
diff --git a/lib/modules/datasource/github-releases/index.ts b/lib/modules/datasource/github-releases/index.ts
index aff1caabd70b8e0c71a07d7ccfe71b836eafc136..19726031233960136713aa92910e13d7dfa2fe95 100644
--- a/lib/modules/datasource/github-releases/index.ts
+++ b/lib/modules/datasource/github-releases/index.ts
@@ -2,9 +2,9 @@
 import hasha from 'hasha';
 import { logger } from '../../../logger';
 import type {
-  DigestAsset,
-  GithubRelease,
-  GithubReleaseAsset,
+  GithubDigestFile,
+  GithubRestAsset,
+  GithubRestRelease,
 } from '../../../util/github/types';
 import { getApiBaseUrl, getSourceUrl } from '../../../util/github/url';
 import { GithubHttp } from '../../../util/http/github';
@@ -37,20 +37,20 @@ export class GithubReleasesDatasource extends Datasource {
   }
 
   async findDigestFile(
-    release: GithubRelease,
+    release: GithubRestRelease,
     digest: string
-  ): Promise<DigestAsset | null> {
+  ): Promise<GithubDigestFile | null> {
     const smallAssets = release.assets.filter(
-      (a: GithubReleaseAsset) => a.size < 5 * 1024
+      (a: GithubRestAsset) => a.size < 5 * 1024
     );
     for (const asset of smallAssets) {
       const res = await this.http.get(asset.browser_download_url);
       for (const line of res.body.split(newlineRegex)) {
-        const [lineDigest, lineFn] = line.split(regEx(/\s+/), 2);
+        const [lineDigest, lineFilename] = line.split(regEx(/\s+/), 2);
         if (lineDigest === digest) {
           return {
             assetName: asset.name,
-            digestedFileName: lineFn,
+            digestedFileName: lineFilename,
             currentVersion: release.tag_name,
             currentDigest: lineDigest,
           };
@@ -61,7 +61,7 @@ export class GithubReleasesDatasource extends Datasource {
   }
 
   async downloadAndDigest(
-    asset: GithubReleaseAsset,
+    asset: GithubRestAsset,
     algorithm: string
   ): Promise<string> {
     const res = this.http.stream(asset.browser_download_url);
@@ -70,12 +70,12 @@ export class GithubReleasesDatasource extends Datasource {
   }
 
   async findAssetWithDigest(
-    release: GithubRelease,
+    release: GithubRestRelease,
     digest: string
-  ): Promise<DigestAsset | null> {
+  ): Promise<GithubDigestFile | null> {
     const algorithm = inferHashAlg(digest);
     const assetsBySize = release.assets.sort(
-      (a: GithubReleaseAsset, b: GithubReleaseAsset) => {
+      (a: GithubRestAsset, b: GithubRestAsset) => {
         if (a.size < b.size) {
           return -1;
         }
@@ -101,9 +101,9 @@ export class GithubReleasesDatasource extends Datasource {
 
   /** Identify the asset associated with a known digest. */
   async findDigestAsset(
-    release: GithubRelease,
+    release: GithubRestRelease,
     digest: string
-  ): Promise<DigestAsset | null> {
+  ): Promise<GithubDigestFile | null> {
     const digestFile = await this.findDigestFile(release, digest);
     if (digestFile) {
       return digestFile;
@@ -115,8 +115,8 @@ export class GithubReleasesDatasource extends Datasource {
 
   /** Given a digest asset, find the equivalent digest in a different release. */
   async mapDigestAssetToRelease(
-    digestAsset: DigestAsset,
-    release: GithubRelease
+    digestAsset: GithubDigestFile,
+    release: GithubRestRelease
   ): Promise<string | null> {
     const current = digestAsset.currentVersion.replace(regEx(/^v/), '');
     const next = release.tag_name.replace(regEx(/^v/), '');
@@ -125,7 +125,7 @@ export class GithubReleasesDatasource extends Datasource {
       next
     );
     const releaseAsset = release.assets.find(
-      (a: GithubReleaseAsset) => a.name === releaseChecksumAssetName
+      (a: GithubRestAsset) => a.name === releaseChecksumAssetName
     );
     if (!releaseAsset) {
       return null;
@@ -183,7 +183,7 @@ export class GithubReleasesDatasource extends Datasource {
     }
 
     const apiBaseUrl = getApiBaseUrl(registryUrl);
-    const { body: currentRelease } = await this.http.getJson<GithubRelease>(
+    const { body: currentRelease } = await this.http.getJson<GithubRestRelease>(
       `${apiBaseUrl}repos/${repo}/releases/tags/${currentValue}`
     );
     const digestAsset = await this.findDigestAsset(
@@ -194,7 +194,7 @@ export class GithubReleasesDatasource extends Datasource {
     if (!digestAsset || newValue === currentValue) {
       newDigest = currentDigest;
     } else {
-      const { body: newRelease } = await this.http.getJson<GithubRelease>(
+      const { body: newRelease } = await this.http.getJson<GithubRestRelease>(
         `${apiBaseUrl}repos/${repo}/releases/tags/${newValue}`
       );
       newDigest = await this.mapDigestAssetToRelease(digestAsset, newRelease);
@@ -216,7 +216,7 @@ export class GithubReleasesDatasource extends Datasource {
     const { packageName: repo, registryUrl } = config;
     const apiBaseUrl = getApiBaseUrl(registryUrl);
     const url = `${apiBaseUrl}repos/${repo}/releases?per_page=100`;
-    const res = await this.http.getJson<GithubRelease[]>(url, {
+    const res = await this.http.getJson<GithubRestRelease[]>(url, {
       paginate: true,
     });
     const githubReleases = res.body;
diff --git a/lib/modules/datasource/github-releases/test/index.ts b/lib/modules/datasource/github-releases/test/index.ts
index 4343fff599b16621988343ee2cb7aa18f8aaecc9..e7dfcc82c91828b57e1f8c753aecb5103beb8cdf 100644
--- a/lib/modules/datasource/github-releases/test/index.ts
+++ b/lib/modules/datasource/github-releases/test/index.ts
@@ -1,6 +1,6 @@
 import * as httpMock from '../../../../../test/http-mock';
 import { partial } from '../../../../../test/util';
-import type { GithubRelease } from '../../../../util/github/types';
+import type { GithubRestRelease } from '../../../../util/github/types';
 
 export class GitHubReleaseMocker {
   constructor(
@@ -8,15 +8,15 @@ export class GitHubReleaseMocker {
     private readonly packageName: string
   ) {}
 
-  release(version: string): GithubRelease {
+  release(version: string): GithubRestRelease {
     return this.withAssets(version, {});
   }
 
   withAssets(
     version: string,
     assets: { [key: string]: string }
-  ): GithubRelease {
-    const releaseData = partial<GithubRelease>({
+  ): GithubRestRelease {
+    const releaseData = partial<GithubRestRelease>({
       tag_name: version,
       published_at: '2020-03-09T11:00:00Z',
       prerelease: false,
@@ -46,7 +46,10 @@ export class GitHubReleaseMocker {
     return releaseData;
   }
 
-  withDigestFileAsset(version: string, ...digests: string[]): GithubRelease {
+  withDigestFileAsset(
+    version: string,
+    ...digests: string[]
+  ): GithubRestRelease {
     return this.withAssets(version, { 'SHASUMS.txt': digests.join('\n') });
   }
 }
diff --git a/lib/modules/datasource/github-tags/cache.spec.ts b/lib/modules/datasource/github-tags/cache.spec.ts
index 9e87272f9d88eb45779e2ed49c6d482ea89a4902..18f61aecdf667bdd26c081d8de280bfdd70b23ff 100644
--- a/lib/modules/datasource/github-tags/cache.spec.ts
+++ b/lib/modules/datasource/github-tags/cache.spec.ts
@@ -1,11 +1,12 @@
+import type { GithubGraphqlTag } from '../../../util/github/types';
 import { GithubHttp } from '../../../util/http/github';
-import { CacheableGithubTags, FetchedTag } from './cache';
+import { CacheableGithubTags } from './cache';
 
 describe('modules/datasource/github-tags/cache', () => {
   const http = new GithubHttp();
   const cache = new CacheableGithubTags(http, { resetDeltaMinutes: 0 });
 
-  const fetchedItem: FetchedTag = {
+  const fetchedItem: GithubGraphqlTag = {
     version: '1.2.3',
     target: {
       type: 'Commit',
diff --git a/lib/modules/datasource/github-tags/cache.ts b/lib/modules/datasource/github-tags/cache.ts
index 00d271354792a1caa57769ff69813e3fa9846823..6f7469e4c6a5dd55acc7d3c062d5a57f96c83132 100644
--- a/lib/modules/datasource/github-tags/cache.ts
+++ b/lib/modules/datasource/github-tags/cache.ts
@@ -1,4 +1,8 @@
-import type { CacheOptions, StoredItemBase } from '../../../util/github/types';
+import type {
+  CacheOptions,
+  GithubCachedTag,
+  GithubGraphqlTag,
+} from '../../../util/github/types';
 import type { GithubHttp } from '../../../util/http/github';
 import { AbstractGithubDatasourceCache } from '../github-releases/cache/cache-base';
 
@@ -40,33 +44,9 @@ query ($owner: String!, $name: String!, $cursor: String, $count: Int!) {
 }
 `;
 
-export interface FetchedTag {
-  version: string;
-  target:
-    | {
-        type: 'Commit';
-        hash: string;
-        releaseTimestamp: string;
-      }
-    | {
-        type: 'Tag';
-        target: {
-          hash: string;
-        };
-        tagger: {
-          releaseTimestamp: string;
-        };
-      };
-}
-
-export interface StoredTag extends StoredItemBase {
-  hash: string;
-  releaseTimestamp: string;
-}
-
 export class CacheableGithubTags extends AbstractGithubDatasourceCache<
-  StoredTag,
-  FetchedTag
+  GithubCachedTag,
+  GithubGraphqlTag
 > {
   readonly cacheNs = 'github-datasource-graphql-tags-v2';
   readonly graphqlQuery = query;
@@ -75,7 +55,7 @@ export class CacheableGithubTags extends AbstractGithubDatasourceCache<
     super(http, opts);
   }
 
-  coerceFetched(item: FetchedTag): StoredTag | null {
+  coerceFetched(item: GithubGraphqlTag): GithubCachedTag | null {
     const { version, target } = item;
     if (target.type === 'Commit') {
       const { hash, releaseTimestamp } = target;
diff --git a/lib/modules/datasource/github-tags/index.ts b/lib/modules/datasource/github-tags/index.ts
index 65b057dc1ea7aa212eddd8d65ed342355c5bcedf..83c6f5ebe62f8a1aca149219701fff39622f983b 100644
--- a/lib/modules/datasource/github-tags/index.ts
+++ b/lib/modules/datasource/github-tags/index.ts
@@ -1,5 +1,5 @@
 import { logger } from '../../../logger';
-import type { GitHubTag, TagResponse } from '../../../util/github/types';
+import type { GithubRestRef, GithubRestTag } from '../../../util/github/types';
 import { getApiBaseUrl, getSourceUrl } from '../../../util/github/url';
 import { GithubHttp } from '../../../util/http/github';
 import { Datasource } from '../datasource';
@@ -26,11 +26,11 @@ export class GithubTagsDatasource extends Datasource {
     let digest: string | null = null;
     try {
       const url = `${apiBaseUrl}repos/${githubRepo}/git/refs/tags/${tag}`;
-      const res = (await this.http.getJson<TagResponse>(url)).body.object;
+      const res = (await this.http.getJson<GithubRestRef>(url)).body.object;
       if (res.type === 'commit') {
         digest = res.sha;
       } else if (res.type === 'tag') {
-        digest = (await this.http.getJson<TagResponse>(res.url)).body.object
+        digest = (await this.http.getJson<GithubRestRef>(res.url)).body.object
           .sha;
       } else {
         logger.warn({ res }, 'Unknown git tag refs type');
@@ -88,7 +88,7 @@ export class GithubTagsDatasource extends Datasource {
     const url = `${apiBaseUrl}repos/${repo}/tags?per_page=100`;
 
     const versions = (
-      await this.http.getJson<GitHubTag[]>(url, {
+      await this.http.getJson<GithubRestTag[]>(url, {
         paginate: true,
       })
     ).body.map((o) => o.name);
diff --git a/lib/modules/datasource/hermit/index.ts b/lib/modules/datasource/hermit/index.ts
index 3ea3f975b711a49569e4787c82dddd164be65eb3..6afdd997ff81bf4b0a08a3972569b80fe248d672 100644
--- a/lib/modules/datasource/hermit/index.ts
+++ b/lib/modules/datasource/hermit/index.ts
@@ -1,6 +1,6 @@
 import { logger } from '../../../logger';
 import { cache } from '../../../util/cache/package/decorator';
-import type { GithubRelease } from '../../../util/github/types';
+import type { GithubRestRelease } from '../../../util/github/types';
 import { getApiBaseUrl } from '../../../util/github/url';
 import { GithubHttp } from '../../../util/http/github';
 import { regEx } from '../../../util/regex';
@@ -118,7 +118,7 @@ export class HermitDatasource extends Datasource {
 
     const apiBaseUrl = getApiBaseUrl(`https://${host}`);
 
-    const indexRelease = await this.http.getJson<GithubRelease>(
+    const indexRelease = await this.http.getJson<GithubRestRelease>(
       `${apiBaseUrl}repos/${owner}/${repo}/releases/tags/index`
     );
 
diff --git a/lib/util/github/types.ts b/lib/util/github/types.ts
index b58fe4572bc37989b6c4d482747b014cb28cc6c9..40c65b805aa80fefea95b2b7cb43a0cd05f87e6d 100644
--- a/lib/util/github/types.ts
+++ b/lib/util/github/types.ts
@@ -1,31 +1,27 @@
-export interface GithubRelease {
+/**
+ * REST responses
+ */
+export interface GithubRestRelease {
   id: number;
   tag_name: string;
   published_at: string;
   prerelease: boolean;
   draft?: boolean;
-  assets: GithubReleaseAsset[];
+  assets: GithubRestAsset[];
 
   html_url: string;
   name: string;
   body: string;
 }
 
-export interface GithubReleaseAsset {
+export interface GithubRestAsset {
   name: string;
   url: string;
   browser_download_url: string;
   size: number;
 }
 
-export interface DigestAsset {
-  assetName: string;
-  currentVersion: string;
-  currentDigest: string;
-  digestedFileName?: string;
-}
-
-export interface TagResponse {
+export interface GithubRestRef {
   object: {
     type: string;
     url: string;
@@ -33,16 +29,24 @@ export interface TagResponse {
   };
 }
 
-export interface GitHubTag {
+export interface GithubRestTag {
   name: string;
 }
 
 /**
- * Every `AbstractGithubDatasourceCache` implementation
- * should have `graphqlQuery` that uses parameters
- * defined this interface.
+ * Release asset
+ */
+export interface GithubDigestFile {
+  assetName: string;
+  currentVersion: string;
+  currentDigest: string;
+  digestedFileName?: string;
+}
+
+/**
+ * Parameters used for GraphQL queries with pagination
  */
-export interface GithubQueryParams {
+export interface GithubGraphqlRepoParams {
   owner: string;
   name: string;
   cursor: string | null;
@@ -50,11 +54,9 @@ export interface GithubQueryParams {
 }
 
 /**
- * Every `AbstractGithubDatasourceCache` implementation
- * should have `graphqlQuery` that resembles the structure
- * of this interface.
+ * Common shape for GraphQL responses for repository items
  */
-export interface QueryResponse<T = unknown> {
+export interface GithubGraphqlRepoResponse<T = unknown> {
   repository: {
     payload: {
       nodes: T[];
@@ -67,35 +69,80 @@ export interface QueryResponse<T = unknown> {
 }
 
 /**
- * Base interface meant to be extended by all implementations.
- * Must have `version` and `releaseTimestamp` fields.
+ * GraphQL shape for releases
+ */
+export interface GithubGraphqlRelease {
+  version: string;
+  releaseTimestamp: string;
+  isDraft: boolean;
+  isPrerelease: boolean;
+  url: string;
+  id: number;
+  name: string;
+  description: string;
+}
+
+/**
+ * GraphQL shape for tags
+ */
+export interface GithubGraphqlTag {
+  version: string;
+  target:
+    | {
+        type: 'Commit';
+        hash: string;
+        releaseTimestamp: string;
+      }
+    | {
+        type: 'Tag';
+        target: {
+          hash: string;
+        };
+        tagger: {
+          releaseTimestamp: string;
+        };
+      };
+}
+
+/**
+ * The structures being stored with long-term caching
  */
-export interface StoredItemBase {
-  /** The values of `version` field meant to be unique. */
+export interface GithubCachedItem {
   version: string;
+  releaseTimestamp: string;
+}
+
+export interface GithubCachedRelease extends GithubCachedItem {
+  isStable?: boolean;
+  url: string;
+  id: number;
+  name: string;
+  description: string;
+}
 
-  /** The `releaseTimestamp` field meant to be ISO-encoded date. */
+export interface GithubCachedTag extends GithubCachedItem {
+  hash: string;
   releaseTimestamp: string;
 }
 
 /**
- * The data structure stored in the package cache.
+ * The common structure of datasource cache
  */
-export interface GithubDatasourceCache<StoredItem extends StoredItemBase> {
-  items: Record<string, StoredItem>;
+export interface GithubDatasourceCache<CachedItem extends GithubCachedItem> {
+  items: Record<string, CachedItem>;
 
-  /** Cache full reset decision is based on `createdAt` value. */
+  /** Used for determining hard reset time */
   createdAt: string;
 
-  /** Cache soft updates are performed depending on `updatedAt` value. */
+  /** Used for determining soft reset time */
   updatedAt: string;
 
-  /** Latest release timestamp (`releaseTimestamp`) of all releases. */
+  /** The most fresh `releaseTimestamp` of all items */
   lastReleasedAt?: string;
 }
 
 /**
- * The configuration for cache.
+ * The configuration for datasource cache
  */
 export interface CacheOptions {
   /**
@@ -160,6 +207,17 @@ export interface CacheOptions {
   maxUpdatePages?: number;
 }
 
+/**
+ * This type is used to handle the following edge-case:
+ *
+ *   1. Package is being released on both NPM and GitHub
+ *   2. Renovate know there is new release in NPM
+ *   3. Renovate didn't update it's cache for GitHub datasource
+ *   4. We can't obtain release notes from GitHub because of this
+ *
+ * By providing this additional structure, we can soft reset cache
+ * once we know it's released for NPM or any other package manager.
+ */
 export interface ChangelogRelease {
   date: string | Date;
   version: string;
diff --git a/lib/workers/repository/update/pr/changelog/github/index.ts b/lib/workers/repository/update/pr/changelog/github/index.ts
index cd4706b6ed60410883b9f92f64581079f78c9316..693794e27670ccf9c957b746b2a38ab151d79ce3 100644
--- a/lib/workers/repository/update/pr/changelog/github/index.ts
+++ b/lib/workers/repository/update/pr/changelog/github/index.ts
@@ -6,8 +6,8 @@ import type {
   GithubGitTreeNode,
 } from '../../../../../../types/platform/github';
 import type {
-  GitHubTag,
-  GithubRelease,
+  GithubRestRelease,
+  GithubRestTag,
 } from '../../../../../../util/github/types';
 import { GithubHttp } from '../../../../../../util/http/github';
 import { fromBase64 } from '../../../../../../util/string';
@@ -29,7 +29,7 @@ export async function getTags(
   logger.trace('github.getTags()');
   try {
     const url = `${endpoint}repos/${repository}/tags?per_page=100`;
-    const res = await http.getJson<GitHubTag[]>(url, {
+    const res = await http.getJson<GithubRestTag[]>(url, {
       paginate: true,
     });
     const tags = res.body;
@@ -121,7 +121,7 @@ export async function getReleaseList(
   const apiBaseUrl = project.apiBaseUrl!;
   const repository = project.repository;
   const url = `${ensureTrailingSlash(apiBaseUrl)}repos/${repository}/releases`;
-  const res = await http.getJson<GithubRelease[]>(`${url}?per_page=100`, {
+  const res = await http.getJson<GithubRestRelease[]>(`${url}?per_page=100`, {
     paginate: true,
   });