Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions source/features/latest-tag-button.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import './latest-tag-button.css';
import React from 'dom-chef';
import cache from 'webext-storage-cache';
import select from 'select-dom';
import TagIcon from 'octicon/tag.svg';
import elementReady from 'element-ready';
import * as pageDetect from 'github-url-detection';
Expand Down Expand Up @@ -65,23 +66,42 @@ const getRepoPublishState = cache.function(async (): Promise<RepoPublishState> =
}, {
maxAge: 1 / 24, // One hour
staleWhileRevalidate: 2,
shouldRevalidate: value => typeof value === 'string',
cacheKey: () => __filebasename + ':' + getRepoURL()
});

const getAheadByCount = cache.function(async (latestTag: string): Promise<string | undefined> => {
const aheadCount = await fetchDom(
`/${getRepoURL()}/releases/tag/${latestTag}`,
'.release-header relative-time + a[href*="/compare/"]'
);
// This text is "4 commits to master since this tag"
return aheadCount?.textContent!.replace(/\D/g, '');
const getAheadByCount = cache.function(async (latestTag: string): Promise<number> => {
const tagPage = await fetchDom(`/${getRepoURL()}/releases/tag/${latestTag}`);
const aheadCountOrTimeStamp = select.last('.release-header relative-time + a[href*="/compare/"], .release-header relative-time', tagPage)!;

return aheadCountOrTimeStamp instanceof HTMLAnchorElement ?
// This text is "4 commits to master since this tag"
Number(aheadCountOrTimeStamp.textContent!.replace(/\D/g, '')) :
// Github sometimes does not have the ahead count in the dom
getAheadCountApi(aheadCountOrTimeStamp.attributes.datetime.value);
}, {
maxAge: 1 / 24, // One hour
staleWhileRevalidate: 2,
cacheKey: ([latestTag]) => `tag-ahead-by:${getRepoURL()}/${latestTag}`
});

const getAheadCountApi = async (timeStamp: string): Promise<number> => {
const {repository} = await api.v4(`
repository(${getRepoGQL()}) {
defaultBranchRef {
target {
... on Commit {
history(first: 1, since: "${timeStamp}") {
totalCount
}
}
}
}
}
`);

return repository.defaultBranchRef.target.history.totalCount;
};

async function init(): Promise<false | void> {
const {latestTag, isUpToDate} = await getRepoPublishState();
if (!latestTag) {
Expand Down Expand Up @@ -120,9 +140,6 @@ async function init(): Promise<false | void> {
const defaultBranch = await getDefaultBranch();
if (currentBranch === defaultBranch) {
const aheadBy = await getAheadByCount(latestTag);
if (!aheadBy) {
return;
}

link.setAttribute('aria-label', `${defaultBranch} is ${aheadBy} commits ahead of the latest release`);
link.append(' ', <sup>+{aheadBy}</sup>);
Expand Down