mirror of https://github.com/langgenius/dify.git
feat: refactor GitHub releases fetching and update handling with improved error notifications
This commit is contained in:
parent
d3fe6fd303
commit
87b23a1fac
|
|
@ -1,26 +1,16 @@
|
|||
import Toast from '@/app/components/base/toast'
|
||||
import Toast, { type IToastProps } from '@/app/components/base/toast'
|
||||
import { uploadGitHub } from '@/service/plugins'
|
||||
import { Octokit } from '@octokit/core'
|
||||
import { GITHUB_ACCESS_TOKEN } from '@/config'
|
||||
import { compareVersion, getLatestVersion } from '@/utils/semver'
|
||||
import type { GitHubRepoReleaseResponse } from '../types'
|
||||
|
||||
export const useGitHubReleases = () => {
|
||||
const fetchReleases = async (owner: string, repo: string) => {
|
||||
try {
|
||||
const octokit = new Octokit({
|
||||
auth: GITHUB_ACCESS_TOKEN,
|
||||
})
|
||||
const res = await octokit.request('GET /repos/{owner}/{repo}/releases', {
|
||||
owner,
|
||||
repo,
|
||||
headers: {
|
||||
'X-GitHub-Api-Version': '2022-11-28',
|
||||
},
|
||||
})
|
||||
if (res.status !== 200) throw new Error('Failed to fetch releases')
|
||||
const res = await fetch(`/repos/${owner}/${repo}/releases`)
|
||||
const bodyJson = await res.json()
|
||||
if (bodyJson.status !== 200) throw new Error(bodyJson.data.message)
|
||||
|
||||
const formattedReleases = res.data.map((release: any) => ({
|
||||
const formattedReleases = bodyJson.data.map((release: any) => ({
|
||||
tag_name: release.tag_name,
|
||||
assets: release.assets.map((asset: any) => ({
|
||||
browser_download_url: asset.browser_download_url,
|
||||
|
|
@ -31,26 +21,46 @@ export const useGitHubReleases = () => {
|
|||
return formattedReleases
|
||||
}
|
||||
catch (error) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: 'Failed to fetch repository releases',
|
||||
})
|
||||
if (error instanceof Error) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: error.message,
|
||||
})
|
||||
}
|
||||
else {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: 'Failed to fetch repository releases',
|
||||
})
|
||||
}
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const checkForUpdates = (fetchedReleases: GitHubRepoReleaseResponse[], currentVersion: string) => {
|
||||
if (fetchedReleases.length === 0) throw new Error('No releases found')
|
||||
let needUpdate = false
|
||||
const toastProps: IToastProps = {
|
||||
type: 'info',
|
||||
message: 'No new version available',
|
||||
}
|
||||
if (fetchedReleases.length === 0) {
|
||||
toastProps.type = 'error'
|
||||
toastProps.message = 'Input releases is empty'
|
||||
return { needUpdate, toastProps }
|
||||
}
|
||||
const versions = fetchedReleases.map(release => release.tag_name)
|
||||
const latestVersion = getLatestVersion(versions)
|
||||
let res = false
|
||||
try {
|
||||
res = compareVersion(latestVersion, currentVersion) === 1
|
||||
needUpdate = compareVersion(latestVersion, currentVersion) === 1
|
||||
if (needUpdate)
|
||||
toastProps.message = `New version available: ${latestVersion}`
|
||||
}
|
||||
catch {
|
||||
throw new Error('Failed to compare versions, please check the version format.')
|
||||
needUpdate = false
|
||||
toastProps.type = 'error'
|
||||
toastProps.message = 'Fail to compare versions, please check the version format'
|
||||
}
|
||||
return res
|
||||
return { needUpdate, toastProps }
|
||||
}
|
||||
|
||||
return { fetchReleases, checkForUpdates }
|
||||
|
|
|
|||
|
|
@ -88,47 +88,28 @@ const DetailHeader = ({
|
|||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const fetchedReleases = await fetchReleases(author, name)
|
||||
if (checkForUpdates(fetchedReleases, meta!.version)) {
|
||||
setShowUpdatePluginModal({
|
||||
onSaveCallback: () => {
|
||||
onUpdate()
|
||||
},
|
||||
payload: {
|
||||
type: PluginSource.github,
|
||||
github: {
|
||||
originalPackageInfo: {
|
||||
id: detail.plugin_unique_identifier,
|
||||
repo: meta!.repo,
|
||||
version: meta!.version,
|
||||
package: meta!.package,
|
||||
releases: fetchedReleases,
|
||||
},
|
||||
const fetchedReleases = await fetchReleases(author, name)
|
||||
if (fetchedReleases.length === 0) return
|
||||
const { needUpdate, toastProps } = checkForUpdates(fetchedReleases, meta!.version)
|
||||
Toast.notify(toastProps)
|
||||
if (needUpdate) {
|
||||
setShowUpdatePluginModal({
|
||||
onSaveCallback: () => {
|
||||
onUpdate()
|
||||
},
|
||||
payload: {
|
||||
type: PluginSource.github,
|
||||
github: {
|
||||
originalPackageInfo: {
|
||||
id: detail.plugin_unique_identifier,
|
||||
repo: meta!.repo,
|
||||
version: meta!.version,
|
||||
package: meta!.package,
|
||||
releases: fetchedReleases,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
else {
|
||||
Toast.notify({
|
||||
type: 'info',
|
||||
message: 'No new version available',
|
||||
})
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof Error) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: error.message,
|
||||
})
|
||||
}
|
||||
else {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: 'Failed to compare versions',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,47 +54,28 @@ const Action: FC<Props> = ({
|
|||
const invalidateInstalledPluginList = useInvalidateInstalledPluginList()
|
||||
|
||||
const handleFetchNewVersion = async () => {
|
||||
try {
|
||||
const fetchedReleases = await fetchReleases(author, pluginName)
|
||||
if (checkForUpdates(fetchedReleases, meta!.version)) {
|
||||
setShowUpdatePluginModal({
|
||||
onSaveCallback: () => {
|
||||
invalidateInstalledPluginList()
|
||||
},
|
||||
payload: {
|
||||
type: PluginSource.github,
|
||||
github: {
|
||||
originalPackageInfo: {
|
||||
id: pluginUniqueIdentifier,
|
||||
repo: meta!.repo,
|
||||
version: meta!.version,
|
||||
package: meta!.package,
|
||||
releases: fetchedReleases,
|
||||
},
|
||||
const fetchedReleases = await fetchReleases(author, pluginName)
|
||||
if (fetchReleases.length === 0) return
|
||||
const { needUpdate, toastProps } = checkForUpdates(fetchedReleases, meta!.version)
|
||||
Toast.notify(toastProps)
|
||||
if (needUpdate) {
|
||||
setShowUpdatePluginModal({
|
||||
onSaveCallback: () => {
|
||||
invalidateInstalledPluginList()
|
||||
},
|
||||
payload: {
|
||||
type: PluginSource.github,
|
||||
github: {
|
||||
originalPackageInfo: {
|
||||
id: pluginUniqueIdentifier,
|
||||
repo: meta!.repo,
|
||||
version: meta!.version,
|
||||
package: meta!.package,
|
||||
releases: fetchedReleases,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
else {
|
||||
Toast.notify({
|
||||
type: 'info',
|
||||
message: 'No new version available',
|
||||
})
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof Error) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: error.message,
|
||||
})
|
||||
}
|
||||
else {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: 'Failed to compare versions',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
import { type NextRequest, NextResponse } from 'next/server'
|
||||
import { Octokit } from '@octokit/core'
|
||||
import { RequestError } from '@octokit/request-error'
|
||||
import { GITHUB_ACCESS_TOKEN } from '@/config'
|
||||
|
||||
type Params = {
|
||||
owner: string,
|
||||
repo: string,
|
||||
}
|
||||
|
||||
const octokit = new Octokit({
|
||||
auth: GITHUB_ACCESS_TOKEN,
|
||||
})
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<Params> },
|
||||
) {
|
||||
const { owner, repo } = (await params)
|
||||
try {
|
||||
const releasesRes = await octokit.request('GET /repos/{owner}/{repo}/releases', {
|
||||
owner,
|
||||
repo,
|
||||
headers: {
|
||||
'X-GitHub-Api-Version': '2022-11-28',
|
||||
},
|
||||
})
|
||||
return NextResponse.json(releasesRes)
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof RequestError)
|
||||
return NextResponse.json(error.response)
|
||||
else
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
"@monaco-editor/react": "^4.6.0",
|
||||
"@next/mdx": "^14.0.4",
|
||||
"@octokit/core": "^6.1.2",
|
||||
"@octokit/request-error": "^6.1.5",
|
||||
"@remixicon/react": "^4.3.0",
|
||||
"@sentry/react": "^7.54.0",
|
||||
"@sentry/utils": "^7.54.0",
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ importers:
|
|||
'@octokit/core':
|
||||
specifier: ^6.1.2
|
||||
version: 6.1.2
|
||||
'@octokit/request-error':
|
||||
specifier: ^6.1.5
|
||||
version: 6.1.5
|
||||
'@remixicon/react':
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.0(react@18.2.0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue