Skip to content

Commit cab3cc6

Browse files
committed
when the latest gh release contains a link to a changelog.md the changelog info endpoint will return ChangelogMarkdownInfo instead of ChangelogReleaseInfo
1 parent f2d5f2b commit cab3cc6

4 files changed

Lines changed: 88 additions & 36 deletions

File tree

app/pages/package/[[org]]/[name].vue

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,6 @@ const { data: packageAnalysis } = usePackageAnalysis(packageName, requestedVersi
195195
const { data: moduleReplacement } = useModuleReplacement(packageName)
196196
const { data: changelog } = usePackageChangelog(packageName, requestedVersion)
197197
198-
const hasChangelog = computed(
199-
() => changelog.value?.type == 'release' || changelog.value?.type == 'md',
200-
)
201-
202198
const {
203199
data: resolvedVersion,
204200
status: versionStatus,

server/utils/changelog/detectChangelog.ts

Lines changed: 83 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
import type { ChangelogReleaseInfo, ChangelogMarkdownInfo } from '~~/shared/types/changelog'
2-
import { ERROR_CHANGELOG_NOT_FOUND } from '~~/shared/utils/constants'
1+
import type {
2+
ChangelogMarkdownInfo,
3+
ChangelogInfo,
4+
ChangelogReleaseInfo,
5+
} from '~~/shared/types/changelog'
36
import { type RepoRef, parseRepoUrl } from '~~/shared/utils/git-providers'
47
import type { ExtendedPackageJson } from '~~/shared/utils/package-analysis'
8+
import { ERROR_CHANGELOG_NOT_FOUND } from '~~/shared/utils/constants'
9+
import * as v from 'valibot'
10+
import { GithubReleaseSchama } from '~~/shared/schemas/changelog/release'
11+
512
// ChangelogInfo
613

714
/**
@@ -39,44 +46,88 @@ export async function detectChangelog(
3946
* check whether releases are being used with this repo
4047
* @returns true if in use
4148
*/
42-
async function checkReleases(ref: RepoRef): Promise<ChangelogReleaseInfo | false> {
43-
const checkUrls = getLatestReleaseUrl(ref)
44-
45-
for (const checkUrl of checkUrls ?? []) {
46-
const exists = await fetch(checkUrl, {
47-
headers: {
48-
// GitHub API requires User-Agent
49-
'User-Agent': 'npmx.dev',
50-
},
51-
method: 'HEAD', // we just need to know if it exists or not
52-
})
53-
.then(r => r.ok)
54-
.catch(() => false)
55-
if (exists) {
56-
return {
57-
provider: ref.provider,
58-
type: 'release',
59-
repo: `${ref.owner}/${ref.repo}`,
60-
}
49+
async function checkReleases(ref: RepoRef): Promise<ChangelogInfo | false> {
50+
switch (ref.provider) {
51+
case 'github': {
52+
return checkLatestGithubRelease(ref)
6153
}
6254
}
55+
56+
// const checkUrls = getLatestReleaseUrl(ref)
57+
58+
// for (const checkUrl of checkUrls ?? []) {
59+
// const exists = await fetch(checkUrl, {
60+
// headers: {
61+
// // GitHub API requires User-Agent
62+
// 'User-Agent': 'npmx.dev',
63+
// },
64+
// method: 'HEAD', // we just need to know if it exists or not
65+
// })
66+
// .then(r => r.ok)
67+
// .catch(() => false)
68+
// if (exists) {
69+
// return {
70+
// provider: ref.provider,
71+
// type: 'release',
72+
// repo: `${ref.owner}/${ref.repo}`,
73+
// }
74+
// }
75+
// }
6376
return false
6477
}
6578

66-
/**
67-
* get the url to check if releases are being used.
68-
*
69-
* @returns returns an array so that if providers don't have a latest that we can check for versions
70-
*/
71-
function getLatestReleaseUrl(ref: RepoRef): null | string[] {
72-
switch (ref.provider) {
73-
case 'github':
74-
return [`https://ungh.cc/repos/${ref.owner}/${ref.repo}/releases/latest`]
75-
}
79+
/// releases
7680

77-
return null
81+
// /**
82+
// * get the url to check if releases are being used.
83+
// *
84+
// * @returns returns an array so that if providers don't have a latest that we can check for versions
85+
// */
86+
// function getLatestReleaseUrl(ref: RepoRef): null | string[] {
87+
// switch (ref.provider) {
88+
// case 'github':
89+
// return [`https://ungh.cc/repos/${ref.owner}/${ref.repo}/releases/latest`]
90+
// }
91+
92+
// return null
93+
// }
94+
95+
const MD_REGEX = /(?<=\[.*?(changelog|releases|changes|history|news)\.md.*?\]\()(.*?)(?=\))/i
96+
97+
function checkLatestGithubRelease(ref: RepoRef): Promise<ChangelogInfo | false> {
98+
return $fetch(`https://ungh.cc/repos/${ref.owner}/${ref.repo}/releases/latest`)
99+
.then(r => {
100+
console.log(r)
101+
const { release } = v.parse(v.object({ release: GithubReleaseSchama }), r)
102+
103+
const matchedChangelog = release.markdown?.match(MD_REGEX)?.at(0)
104+
105+
// if no changelog.md or the url doesn't contain /blob/
106+
if (!matchedChangelog || !matchedChangelog.includes('/blob/')) {
107+
return {
108+
provider: ref.provider,
109+
type: 'release',
110+
repo: `${ref.owner}/${ref.repo}`,
111+
} satisfies ChangelogReleaseInfo
112+
}
113+
114+
const path = matchedChangelog.replace(/^.*\/blob\/[^/]+\//i, '')
115+
return {
116+
provider: ref.provider,
117+
type: 'md',
118+
path,
119+
repo: `${ref.owner}/${ref.repo}`,
120+
link: matchedChangelog,
121+
} satisfies ChangelogMarkdownInfo
122+
})
123+
.catch(e => {
124+
console.log('changelog error', e)
125+
return false
126+
})
78127
}
79128

129+
/// changelog markdown
130+
80131
const EXTENSIONS = ['.md', ''] as const
81132

82133
const CHANGELOG_FILENAMES = ['changelog', 'releases', 'changes', 'history', 'news']

shared/types/changelog.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export interface ChangelogMarkdownInfo {
1515
*/
1616
path: string
1717
repo: `${string}/${string}`
18+
/**
19+
* link to a rendered changelog markdown file
20+
*/
21+
link?: string
1822
}
1923

2024
export type ChangelogInfo = ChangelogReleaseInfo | ChangelogMarkdownInfo

test/unit/a11y-component-coverage.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const SKIPPED_COMPONENTS: Record<string, string> = {
4747
'SkeletonInline.vue': 'Already covered indirectly via other component tests',
4848
'Button/Group.vue': "Wrapper component, tests wouldn't make much sense here",
4949
'Changelog/Releases.vue': 'Requires API calls',
50+
'Changelog/Markdown.vue': 'Requires API call & only renders markdown html',
5051
}
5152

5253
/**

0 commit comments

Comments
 (0)