|
|
@ -11,7 +11,8 @@ export class CodeFeed {
|
|
|
|
constructor(baseUrl: string, token?: string, lastRunTimestamp?: string) {
|
|
|
|
constructor(baseUrl: string, token?: string, lastRunTimestamp?: string) {
|
|
|
|
this.baseUrl = baseUrl;
|
|
|
|
this.baseUrl = baseUrl;
|
|
|
|
this.token = token;
|
|
|
|
this.token = token;
|
|
|
|
this.lastRunTimestamp = lastRunTimestamp || new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
|
|
this.lastRunTimestamp =
|
|
|
|
|
|
|
|
lastRunTimestamp || new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
|
|
console.log('CodeFeed initialized with last run timestamp:', this.lastRunTimestamp);
|
|
|
|
console.log('CodeFeed initialized with last run timestamp:', this.lastRunTimestamp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -28,7 +29,9 @@ export class CodeFeed {
|
|
|
|
const response = await fetch(url, { headers });
|
|
|
|
const response = await fetch(url, { headers });
|
|
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
console.error(`Could not fetch CHANGELOG.md from ${owner}/${repo}: ${response.status} ${response.statusText}`);
|
|
|
|
console.error(
|
|
|
|
|
|
|
|
`Could not fetch CHANGELOG.md from ${owner}/${repo}: ${response.status} ${response.statusText}`
|
|
|
|
|
|
|
|
);
|
|
|
|
this.changelogContent = '';
|
|
|
|
this.changelogContent = '';
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -91,8 +94,8 @@ export class CodeFeed {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async fetchOrgRssFeed(optionsArg: {
|
|
|
|
private async fetchOrgRssFeed(optionsArg: {
|
|
|
|
orgName: string,
|
|
|
|
orgName: string;
|
|
|
|
repoName?: string,
|
|
|
|
repoName?: string;
|
|
|
|
}): Promise<any[]> {
|
|
|
|
}): Promise<any[]> {
|
|
|
|
let rssUrl: string;
|
|
|
|
let rssUrl: string;
|
|
|
|
if (optionsArg.orgName && !optionsArg.repoName) {
|
|
|
|
if (optionsArg.orgName && !optionsArg.repoName) {
|
|
|
@ -105,7 +108,9 @@ export class CodeFeed {
|
|
|
|
|
|
|
|
|
|
|
|
const response = await fetch(rssUrl);
|
|
|
|
const response = await fetch(rssUrl);
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error(`Failed to fetch RSS feed for organization ${optionsArg.orgName}/${optionsArg.repoName}: ${response.statusText}`);
|
|
|
|
throw new Error(
|
|
|
|
|
|
|
|
`Failed to fetch RSS feed for organization ${optionsArg.orgName}/${optionsArg.repoName}: ${response.statusText}`
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const rssText = await response.text();
|
|
|
|
const rssText = await response.text();
|
|
|
@ -114,8 +119,8 @@ export class CodeFeed {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async hasNewActivity(optionsArg: {
|
|
|
|
private async hasNewActivity(optionsArg: {
|
|
|
|
orgName: string,
|
|
|
|
orgName: string;
|
|
|
|
repoName?: string,
|
|
|
|
repoName?: string;
|
|
|
|
}): Promise<boolean> {
|
|
|
|
}): Promise<boolean> {
|
|
|
|
const entries = await this.fetchOrgRssFeed(optionsArg);
|
|
|
|
const entries = await this.fetchOrgRssFeed(optionsArg);
|
|
|
|
|
|
|
|
|
|
|
@ -135,7 +140,7 @@ export class CodeFeed {
|
|
|
|
url.searchParams.set('page', page.toString());
|
|
|
|
url.searchParams.set('page', page.toString());
|
|
|
|
|
|
|
|
|
|
|
|
const resp = await fetch(url.href, {
|
|
|
|
const resp = await fetch(url.href, {
|
|
|
|
headers: this.token ? { 'Authorization': `token ${this.token}` } : {},
|
|
|
|
headers: this.token ? { Authorization: `token ${this.token}` } : {},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.ok) {
|
|
|
|
if (!resp.ok) {
|
|
|
@ -164,11 +169,13 @@ export class CodeFeed {
|
|
|
|
url.searchParams.set('page', page.toString());
|
|
|
|
url.searchParams.set('page', page.toString());
|
|
|
|
|
|
|
|
|
|
|
|
const resp = await fetch(url.href, {
|
|
|
|
const resp = await fetch(url.href, {
|
|
|
|
headers: this.token ? { 'Authorization': `token ${this.token}` } : {},
|
|
|
|
headers: this.token ? { Authorization: `token ${this.token}` } : {},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.ok) {
|
|
|
|
if (!resp.ok) {
|
|
|
|
console.error(`Failed to fetch tags for ${owner}/${repo}: ${resp.status} ${resp.statusText} at ${url.href}`);
|
|
|
|
console.error(
|
|
|
|
|
|
|
|
`Failed to fetch tags for ${owner}/${repo}: ${resp.status} ${resp.statusText} at ${url.href}`
|
|
|
|
|
|
|
|
);
|
|
|
|
throw new Error(`Failed to fetch tags for ${owner}/${repo}: ${resp.statusText}`);
|
|
|
|
throw new Error(`Failed to fetch tags for ${owner}/${repo}: ${resp.statusText}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -191,7 +198,10 @@ export class CodeFeed {
|
|
|
|
return taggedCommitShas;
|
|
|
|
return taggedCommitShas;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async fetchRecentCommitsForRepo(owner: string, repo: string): Promise<plugins.interfaces.ICommit[]> {
|
|
|
|
private async fetchRecentCommitsForRepo(
|
|
|
|
|
|
|
|
owner: string,
|
|
|
|
|
|
|
|
repo: string
|
|
|
|
|
|
|
|
): Promise<plugins.interfaces.ICommit[]> {
|
|
|
|
const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
|
|
const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
|
|
let page = 1;
|
|
|
|
let page = 1;
|
|
|
|
const recentCommits: plugins.interfaces.ICommit[] = [];
|
|
|
|
const recentCommits: plugins.interfaces.ICommit[] = [];
|
|
|
@ -202,11 +212,13 @@ export class CodeFeed {
|
|
|
|
url.searchParams.set('page', page.toString());
|
|
|
|
url.searchParams.set('page', page.toString());
|
|
|
|
|
|
|
|
|
|
|
|
const resp = await fetch(url.href, {
|
|
|
|
const resp = await fetch(url.href, {
|
|
|
|
headers: this.token ? { 'Authorization': `token ${this.token}` } : {},
|
|
|
|
headers: this.token ? { Authorization: `token ${this.token}` } : {},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.ok) {
|
|
|
|
if (!resp.ok) {
|
|
|
|
console.error(`Failed to fetch commits for ${owner}/${repo}: ${resp.status} ${resp.statusText} at ${url.href}`);
|
|
|
|
console.error(
|
|
|
|
|
|
|
|
`Failed to fetch commits for ${owner}/${repo}: ${resp.status} ${resp.statusText} at ${url.href}`
|
|
|
|
|
|
|
|
);
|
|
|
|
throw new Error(`Failed to fetch commits for ${owner}/${repo}: ${resp.statusText}`);
|
|
|
|
throw new Error(`Failed to fetch commits for ${owner}/${repo}: ${resp.statusText}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -265,7 +277,10 @@ export class CodeFeed {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error: any) {
|
|
|
|
} catch (error: any) {
|
|
|
|
console.error(`Error fetching activity for repository ${orgName}/${r.name}:`, error.message);
|
|
|
|
console.error(
|
|
|
|
|
|
|
|
`Error fetching activity for repository ${orgName}/${r.name}:`,
|
|
|
|
|
|
|
|
error.message
|
|
|
|
|
|
|
|
);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -286,12 +301,14 @@ export class CodeFeed {
|
|
|
|
org,
|
|
|
|
org,
|
|
|
|
repo,
|
|
|
|
repo,
|
|
|
|
timestamp: c.commit.author.date,
|
|
|
|
timestamp: c.commit.author.date,
|
|
|
|
prettyAgoTime: plugins.smarttime.getMilliSecondsAsHumanReadableAgoTime(new Date(c.commit.author.date).getTime()),
|
|
|
|
prettyAgoTime: plugins.smarttime.getMilliSecondsAsHumanReadableAgoTime(
|
|
|
|
|
|
|
|
new Date(c.commit.author.date).getTime()
|
|
|
|
|
|
|
|
),
|
|
|
|
hash: c.sha,
|
|
|
|
hash: c.sha,
|
|
|
|
commitMessage: c.commit.message,
|
|
|
|
commitMessage: c.commit.message,
|
|
|
|
tagged: taggedCommitShas.has(c.sha),
|
|
|
|
tagged: taggedCommitShas.has(c.sha),
|
|
|
|
publishedOnNpm: false,
|
|
|
|
publishedOnNpm: false,
|
|
|
|
changelog: undefined
|
|
|
|
changelog: undefined,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
return commit;
|
|
|
|
return commit;
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -306,15 +323,23 @@ export class CodeFeed {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (correspondingVersion) {
|
|
|
|
if (correspondingVersion) {
|
|
|
|
commitResult.publishedOnNpm = true;
|
|
|
|
commitResult.publishedOnNpm = true;
|
|
|
|
const changelogEntry = this.getChangelogForVersion(versionCandidate);
|
|
|
|
|
|
|
|
if (changelogEntry) {
|
|
|
|
|
|
|
|
commitResult.changelog = changelogEntry;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error: any) {
|
|
|
|
} catch (error: any) {
|
|
|
|
console.error(`Failed to fetch package info for ${org}/${repo}:`, error.message);
|
|
|
|
console.error(`Failed to fetch package info for ${org}/${repo}:`, error.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
for (const commitResult of commitResults.filter((c) => c.tagged)) {
|
|
|
|
|
|
|
|
const versionCandidate = commitResult.commitMessage.replace('\n', '').trim();
|
|
|
|
|
|
|
|
const changelogEntry = this.getChangelogForVersion(versionCandidate);
|
|
|
|
|
|
|
|
if (changelogEntry) {
|
|
|
|
|
|
|
|
commitResult.changelog = changelogEntry;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
|
|
console.error(`Failed to fetch changelog info for ${org}/${repo}:`, error.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
allCommits.push(...commitResults);
|
|
|
|
allCommits.push(...commitResults);
|
|
|
@ -326,7 +351,9 @@ export class CodeFeed {
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`Processed ${allCommits.length} commits in total.`);
|
|
|
|
console.log(`Processed ${allCommits.length} commits in total.`);
|
|
|
|
|
|
|
|
|
|
|
|
allCommits = allCommits.filter(commitArg => commitArg.tagged).sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
|
|
allCommits = allCommits
|
|
|
|
|
|
|
|
.filter((commitArg) => commitArg.tagged)
|
|
|
|
|
|
|
|
.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`Filtered to ${allCommits.length} commits with tagged statuses.`);
|
|
|
|
console.log(`Filtered to ${allCommits.length} commits with tagged statuses.`);
|
|
|
|
|
|
|
|
|
|
|
@ -337,9 +364,9 @@ export class CodeFeed {
|
|
|
|
${c.commitMessage}
|
|
|
|
${c.commitMessage}
|
|
|
|
Published on npm: ${c.publishedOnNpm}
|
|
|
|
Published on npm: ${c.publishedOnNpm}
|
|
|
|
${c.changelog ? `Changelog:\n${c.changelog}\n` : ''}
|
|
|
|
${c.changelog ? `Changelog:\n${c.changelog}\n` : ''}
|
|
|
|
`);
|
|
|
|
`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return allCommits;
|
|
|
|
return allCommits;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|