2023-08-11 17:23:56 +02:00
/ *
* Copyright ( C ) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at https : //mozilla.org/MPL/2.0/.
* /
import yargs from 'yargs' ;
import githubToken from './github_token.json' ;
type GithubCommit = {
sha : string ;
html_url : string ;
commit : {
message : string ;
2023-12-13 23:48:35 +01:00
author : {
name : string ;
} ;
2023-08-11 17:23:56 +02:00
} ;
author : { login : string } | null ;
} ;
type Commit = {
repoUrl : string ;
revision : number ;
url : string ;
githubUser : string | undefined ;
author : string ;
title : string ;
} ;
const { sha } = yargs
. options ( {
sha : {
description : 'The hash of the last commit of the previous release' ,
type : 'string' ,
demandOption : true ,
} ,
} )
. parseSync ( ) ;
2023-12-13 23:48:35 +01:00
const getHeaderWithAuth = ( ) = > ( {
headers : {
// token is optional, might be needed in case of getting rate-limited - to provide a token create a "github_token.json" (see "github_token.template.json") and add your token in there
Authorization : githubToken.token ? ` token ${ githubToken . token } ` : '' ,
} ,
} ) ;
const fetchTotalCommitCount = async ( owner : string , repo : string , branch : string = 'master' ) = > {
const response = await fetch (
` https://api.github.com/repos/ ${ owner } / ${ repo } /commits?sha= ${ branch } &per_page=1&page=1 ` ,
getHeaderWithAuth ( ) ,
) ;
const linkHeader = response . headers . get ( 'Link' ) ;
const pageCountMatch = linkHeader ? . match ( /page=(\d+)>; rel="last"/ ) ;
if ( ! pageCountMatch ) {
throw new Error ( 'Page count not found in Link header' ) ;
}
return parseInt ( pageCountMatch [ 1 ] , 10 ) ;
} ;
2023-08-11 17:23:56 +02:00
/ * *
* Fetches and returns all commits after the provided commit hash
* /
const fetchCommits = async (
owner : string ,
repo : string ,
loadUntilSha : string ,
page : number = 1 ,
) : Promise < GithubCommit [ ] > = > {
const commitList = ( await (
2023-12-13 23:48:35 +01:00
await fetch ( ` https://api.github.com/repos/ ${ owner } / ${ repo } /commits?page= ${ page } ` , getHeaderWithAuth ( ) )
2023-08-11 17:23:56 +02:00
) . json ( ) ) as GithubCommit [ ] ;
const indexOfOldestCommitToLoad = commitList . findIndex ( ( commit ) = > commit . sha === loadUntilSha ) ;
const loadedAllCommits = indexOfOldestCommitToLoad !== - 1 ;
if ( loadedAllCommits ) {
return commitList . slice ( 0 , indexOfOldestCommitToLoad ) ;
}
return [ . . . commitList , . . . ( await fetchCommits ( owner , repo , loadUntilSha , page + 1 ) ) ] ;
} ;
const createChangelogCommitLine = ( commit : Commit ) : string = > {
const author = commit . githubUser ? ? commit . author ;
const credit = ` by @ ${ author } ` ;
const revision = ` ([r ${ commit . revision } ]( ${ commit . url } )) ` ;
const includesPrId = commit . title . match ( /.*\(#[0-9]+\)$/g ) ;
if ( ! includesPrId ) {
return ` ${ revision } ${ commit . title } ( ${ credit } ) ` ;
}
const splitTitle = commit . title . split ( '#' ) ;
const rawPrId = splitTitle [ splitTitle . length - 1 ] ; // = <prId>) e.g. 420)
const prId = rawPrId . substring ( 0 , rawPrId . length - 1 ) ;
const prUrl = ` ${ commit . repoUrl } /pull/ ${ prId } ` ;
const authorCredit = ` [# ${ prId } ]( ${ prUrl } ) ${ credit } ` ;
return ` ${ revision } ${ splitTitle . slice ( 0 , splitTitle . length - 1 ) . join ( '#' ) } ${ authorCredit } ) ` ;
} ;
const createChangelog = async ( prevReleaseLastCommitSha : string ) = > {
const owner = 'Suwayomi' ;
const repo = 'Tachidesk-WebUI' ;
2023-12-13 23:48:35 +01:00
const numberOfCommits = await fetchTotalCommitCount ( owner , repo ) ;
2023-08-11 17:23:56 +02:00
const githubCommits = await fetchCommits ( owner , repo , prevReleaseLastCommitSha ) ;
const commits : Commit [ ] = githubCommits . map ( ( githubCommit , index ) = > ( {
repoUrl : ` https://github.com/ ${ owner } / ${ repo } ` ,
revision : numberOfCommits - index ,
url : githubCommit.html_url ,
githubUser : githubCommit.author?.login ,
2023-12-13 23:48:35 +01:00
author : githubCommit.commit.author.name ,
2023-08-11 17:23:56 +02:00
title : githubCommit.commit.message.split ( '\n' ) [ 0 ] ,
} ) ) ;
const commitChangelogLines = commits . map ( createChangelogCommitLine ) ;
commitChangelogLines . forEach ( ( commit ) = > console . log ( '-' , commit ) ) ;
} ;
createChangelog ( sha ) . catch ( ( error ) = > {
console . error ( 'Failed due to' , error ) ;
process . exit ( 1 ) ;
} ) ;