@@ -5,6 +5,7 @@ import { RequestOptions } from "http"
55import * as path from "path"
66import { parse as parseUrl } from "url"
77import { FileInfo , formatUrl , getChannelFilename , getCurrentPlatform , getDefaultChannelName , Provider } from "./api"
8+ import { AppUpdater } from "./AppUpdater"
89import { validateUpdateInfo } from "./GenericProvider"
910
1011export abstract class BaseGitHubProvider < T extends UpdateInfo > extends Provider < T > {
@@ -24,23 +25,50 @@ export abstract class BaseGitHubProvider<T extends UpdateInfo> extends Provider<
2425}
2526
2627export class GitHubProvider extends BaseGitHubProvider < UpdateInfo > {
27- constructor ( protected readonly options : GithubOptions ) {
28+ constructor ( protected readonly options : GithubOptions , private readonly updater : AppUpdater ) {
2829 super ( options , "github.com" )
2930 }
3031
3132 async getLatestVersion ( ) : Promise < UpdateInfo > {
3233 const basePath = this . basePath
3334 const cancellationToken = new CancellationToken ( )
34- const version = await this . getLatestVersionString ( basePath , cancellationToken )
35+
36+ const xElement = require ( "xelement" )
37+ const feedXml = await request ( Object . assign ( {
38+ path : `${ basePath } .atom` ,
39+ headers : Object . assign ( { } , this . requestHeaders , { Accept : "application/xml" } )
40+ } , this . baseUrl ) , cancellationToken )
41+
42+ const feed = new xElement . Parse ( feedXml )
43+ const latestRelease = feed . element ( "entry" )
44+ if ( latestRelease == null ) {
45+ throw new Error ( `No published versions on GitHub` )
46+ }
47+
48+ let version : string
49+ try {
50+ if ( this . updater . allowPrerelease ) {
51+ version = latestRelease . element ( "link" ) . getAttr ( "href" ) . match ( / \/ t a g \/ v ? ( [ ^ \/ ] + ) $ / ) [ 1 ]
52+ }
53+ else {
54+ version = await this . getLatestVersionString ( basePath , cancellationToken )
55+ }
56+ }
57+ catch ( e ) {
58+ throw new Error ( `Cannot parse releases feed: ${ e . stack || e . message } ,\nXML:\n${ feedXml } ` )
59+ }
60+
3561 let result : any
3662 const channelFile = getChannelFilename ( getDefaultChannelName ( ) )
3763 const requestOptions = Object . assign ( { path : this . getBaseDownloadPath ( version , channelFile ) , headers : this . requestHeaders || undefined } , this . baseUrl )
3864 try {
3965 result = await request < UpdateInfo > ( requestOptions , cancellationToken )
4066 }
4167 catch ( e ) {
42- if ( e instanceof HttpError && e . response . statusCode === 404 ) {
43- throw new Error ( `Cannot find ${ channelFile } in the latest release artifacts (${ formatUrl ( < any > requestOptions ) } ): ${ e . stack || e . message } ` )
68+ if ( ! this . updater . allowPrerelease ) {
69+ if ( e instanceof HttpError && e . response . statusCode === 404 ) {
70+ throw new Error ( `Cannot find ${ channelFile } in the latest release artifacts (${ formatUrl ( < any > requestOptions ) } ): ${ e . stack || e . message } ` )
71+ }
4472 }
4573 throw e
4674 }
@@ -49,13 +77,20 @@ export class GitHubProvider extends BaseGitHubProvider<UpdateInfo> {
4977 if ( getCurrentPlatform ( ) === "darwin" ) {
5078 result . releaseJsonUrl = `${ githubUrl ( this . options ) } /${ requestOptions . path } `
5179 }
80+
81+ if ( result . releaseName == null ) {
82+ result . releaseName = latestRelease . getElementValue ( "title" )
83+ }
84+ if ( result . releaseNotes == null ) {
85+ result . releaseNotes = latestRelease . getElementValue ( "content" )
86+ }
5287 return result
5388 }
5489
5590 private async getLatestVersionString ( basePath : string , cancellationToken : CancellationToken ) : Promise < string > {
5691 const requestOptions : RequestOptions = Object . assign ( {
5792 path : `${ basePath } /latest` ,
58- headers : Object . assign ( { Accept : "application/json" } , this . requestHeaders )
93+ headers : Object . assign ( { } , this . requestHeaders , { Accept : "application/json" } )
5994 } , this . baseUrl )
6095 try {
6196 // do not use API to avoid limit
0 commit comments