Skip to content

Commit 8b5311c

Browse files
committed
added better checks/detecting for monorepos using changelog.md
1 parent 133aa39 commit 8b5311c

1 file changed

Lines changed: 33 additions & 29 deletions

File tree

server/utils/changelog/detectChangelog.ts

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { ExtendedPackageJson } from '~~/shared/utils/package-analysis'
88
import { ERROR_CHANGELOG_NOT_FOUND } from '~~/shared/utils/constants'
99
import * as v from 'valibot'
1010
import { GithubReleaseSchama } from '~~/shared/schemas/changelog/release'
11+
import { resolveURL } from 'ufo'
1112

1213
/**
1314
* Detect whether changelogs/releases are available for this package
@@ -28,7 +29,9 @@ export async function detectChangelog(
2829
return false
2930
}
3031

31-
const changelog = (await checkReleases(repoRef)) || (await checkChangelogFile(repoRef))
32+
const changelog =
33+
(await checkReleases(repoRef, pkg.repository.directory)) ||
34+
(await checkChangelogFile(repoRef, pkg.repository.directory))
3235

3336
if (changelog) {
3437
return changelog
@@ -44,41 +47,25 @@ export async function detectChangelog(
4447
* check whether releases are being used with this repo
4548
* @returns true if in use
4649
*/
47-
async function checkReleases(ref: RepoRef): Promise<ChangelogInfo | false> {
50+
async function checkReleases(ref: RepoRef, directory?: string): Promise<ChangelogInfo | false> {
4851
switch (ref.provider) {
4952
case 'github': {
50-
return checkLatestGithubRelease(ref)
53+
return checkLatestGithubRelease(ref, directory)
5154
}
5255
}
5356

54-
// const checkUrls = getLatestReleaseUrl(ref)
55-
56-
// for (const checkUrl of checkUrls ?? []) {
57-
// const exists = await fetch(checkUrl, {
58-
// headers: {
59-
// // GitHub API requires User-Agent
60-
// 'User-Agent': 'npmx.dev',
61-
// },
62-
// method: 'HEAD', // we just need to know if it exists or not
63-
// })
64-
// .then(r => r.ok)
65-
// .catch(() => false)
66-
// if (exists) {
67-
// return {
68-
// provider: ref.provider,
69-
// type: 'release',
70-
// repo: `${ref.owner}/${ref.repo}`,
71-
// }
72-
// }
73-
// }
7457
return false
7558
}
7659

7760
/// releases
7861

7962
const MD_REGEX = /(?<=\[.*?(changelog|releases|changes|history|news)\.md.*?\]\()(.*?)(?=\))/i
63+
const ROOT_ONLY_REGEX = /^\/[^/]+$/
8064

81-
function checkLatestGithubRelease(ref: RepoRef): Promise<ChangelogInfo | false> {
65+
function checkLatestGithubRelease(
66+
ref: RepoRef,
67+
directory?: string,
68+
): Promise<ChangelogInfo | false> {
8269
return $fetch(`https://ungh.cc/repos/${ref.owner}/${ref.repo}/releases/latest`)
8370
.then(r => {
8471
const { release } = v.parse(v.object({ release: GithubReleaseSchama }), r)
@@ -96,6 +83,10 @@ function checkLatestGithubRelease(ref: RepoRef): Promise<ChangelogInfo | false>
9683
}
9784

9885
const path = matchedChangelog.replace(/^.*\/blob\/[^/]+\//i, '')
86+
87+
if (directory && !(path.startsWith(directory) || ROOT_ONLY_REGEX.test(path))) {
88+
return false as const
89+
}
9990
return {
10091
provider: ref.provider,
10192
type: 'md',
@@ -105,7 +96,7 @@ function checkLatestGithubRelease(ref: RepoRef): Promise<ChangelogInfo | false>
10596
} satisfies ChangelogMarkdownInfo
10697
})
10798
.catch(() => {
108-
return false
99+
return false as const
109100
})
110101
}
111102

@@ -120,14 +111,27 @@ const CHANGELOG_FILENAMES = ['changelog', 'releases', 'changes', 'history', 'new
120111
})
121112
.flat(3)
122113

123-
async function checkChangelogFile(ref: RepoRef): Promise<ChangelogMarkdownInfo | false> {
114+
async function checkChangelogFile(
115+
ref: RepoRef,
116+
directory?: string,
117+
): Promise<ChangelogMarkdownInfo | false> {
124118
const baseUrl = getBaseFileUrl(ref)
125119
if (!baseUrl) {
126120
return false
127121
}
128122

123+
if (directory) {
124+
const inDir = await checkFiles(ref, baseUrl, directory)
125+
if (inDir) {
126+
return inDir
127+
}
128+
}
129+
return checkFiles(ref, baseUrl)
130+
}
131+
132+
async function checkFiles(ref: RepoRef, baseUrl: RepoFileUrl, dir?: string) {
129133
for (const fileName of CHANGELOG_FILENAMES) {
130-
const exists = await fetch(`${baseUrl.raw}/${fileName}`, {
134+
const exists = await fetch(resolveURL(baseUrl.raw, dir ?? '', fileName), {
131135
headers: {
132136
// GitHub API requires User-Agent
133137
'User-Agent': 'npmx.dev',
@@ -140,9 +144,9 @@ async function checkChangelogFile(ref: RepoRef): Promise<ChangelogMarkdownInfo |
140144
return {
141145
type: 'md',
142146
provider: ref.provider,
143-
path: fileName,
147+
path: resolveURL(dir ?? '', fileName),
144148
repo: `${ref.owner}/${ref.repo}`,
145-
link: `${baseUrl.blob}/${fileName}`,
149+
link: resolveURL(baseUrl.blob, dir ?? '', fileName),
146150
} satisfies ChangelogMarkdownInfo
147151
}
148152
}

0 commit comments

Comments
 (0)