66// ones which have changed.
77
88import * as fs from "fs" ;
9- import { join , dirname } from "path" ;
9+ import { join , dirname , basename } from "path" ;
1010import { fileURLToPath } from "url" ;
11- import fetch from "node-fetch" ;
12- import { spawnSync } from "child_process" ;
11+ import { spawnSync , execSync } from "child_process" ;
1312import { Octokit } from "@octokit/core" ;
1413import printDiff from "print-diff" ;
14+ import { generateChangelogFrom } from "../lib/changelog.js" ;
15+ import { packages } from "./createTypesPackages.mjs" ;
1516
1617// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1718// @ts -ignore
1819const __filename = fileURLToPath ( import . meta. url ) ;
1920const __dirname = dirname ( __filename ) ;
2021
21- const verify = ( ) => {
22- const authToken = process . env . GITHUB_TOKEN || process . env . GITHUB_API_TOKEN ;
23- if ( ! authToken )
24- throw new Error (
25- "There isn't an ENV var set up for creating a GitHub release, expected GITHUB_TOKEN."
22+ verify ( ) ;
23+
24+ const uploaded = [ ] ;
25+
26+ // Loop through generated packages, deploying versions for anything which has different
27+ // .d.ts files from the version available on npm.
28+ const generatedDir = join ( __dirname , "generated" ) ;
29+ for ( const dirName of fs . readdirSync ( generatedDir ) ) {
30+ console . log ( `Looking at ${ dirName } ` ) ;
31+ const localPackageJSONPath = join ( generatedDir , dirName , "package.json" ) ;
32+ const newTSConfig = fs . readFileSync ( localPackageJSONPath , "utf-8" ) ;
33+ const pkgJSON = JSON . parse ( newTSConfig ) ;
34+
35+ // We'll need to map back from the filename in the npm package to the
36+ // generated file in baselines inside the git tag
37+ const thisPackageMeta = packages . find ( ( p ) => p . name === pkgJSON . name ) ;
38+
39+ const dtsFiles = fs
40+ . readdirSync ( join ( generatedDir , dirName ) )
41+ . filter ( ( f ) => f . endsWith ( ".d.ts" ) ) ;
42+
43+ /** @type {string[] } */
44+ let releaseNotes = [ ] ;
45+
46+ // Look through each .d.ts file included in a package to
47+ // determine if anything has changed
48+ let upload = false ;
49+ for ( const file of dtsFiles ) {
50+ const originalFilename = basename (
51+ thisPackageMeta . files . find ( ( f ) => f . to === file ) . from
2652 ) ;
27- } ;
28-
29- const go = async ( ) => {
30- verify ( ) ;
31-
32- const uploaded = [ ] ;
33-
34- // Loop through generated packages, deploying versions for anything which has different
35- // .d.ts files from the version available on npm.
36- const generatedDir = join ( __dirname , "generated" ) ;
37- for ( const dirName of fs . readdirSync ( generatedDir ) ) {
38- console . log ( `Looking at ${ dirName } ` ) ;
39- const localPackageJSONPath = join ( generatedDir , dirName , "package.json" ) ;
40- const newTSConfig = fs . readFileSync ( localPackageJSONPath , "utf-8" ) ;
41- const pkgJSON = JSON . parse ( newTSConfig ) ;
42-
43- const dtsFiles = fs
44- . readdirSync ( join ( generatedDir , dirName ) )
45- . filter ( ( f ) => f . endsWith ( ".d.ts" ) ) ;
46-
47- // Look through each .d.ts file included in a package to
48- // determine if anything has changed
49- let upload = false ;
50- for ( const file of dtsFiles ) {
51- const generatedDTSPath = join ( generatedDir , dirName , file ) ;
52- const generatedDTSContent = fs . readFileSync ( generatedDTSPath , "utf8" ) ;
53- const unpkgURL = `https://unpkg.com/${ pkgJSON . name } /${ file } ` ;
54- try {
55- const npmDTSReq = await fetch ( unpkgURL ) ;
56- const npmDTSText = await npmDTSReq . text ( ) ;
57- console . log ( `Comparing ${ file } from unpkg, to generated version:` ) ;
58- printDiff ( npmDTSText , generatedDTSContent ) ;
59-
60- upload = upload || npmDTSText !== generatedDTSContent ;
61- } catch ( error ) {
62- // Could not find a previous build
63- console . log ( `
64- Could not get the file ${ file } inside the npm package ${ pkgJSON . name } from unpkg at ${ unpkgURL }
53+
54+ const generatedDTSPath = join ( generatedDir , dirName , file ) ;
55+ const generatedDTSContent = fs . readFileSync ( generatedDTSPath , "utf8" ) ;
56+
57+ // This assumes we'll only _ever_ ship patches, which may change in the
58+ // future someday.
59+ const [ maj , min , patch ] = pkgJSON . version . split ( "." ) ;
60+ const olderVersion = `${ maj } .${ min } .${ patch - 1 } ` ;
61+
62+ try {
63+ const oldFile = gitShowFile (
64+ `${ pkgJSON . name } @${ olderVersion } ` ,
65+ `baselines/${ originalFilename } `
66+ ) ;
67+ console . log ( `Comparing ${ file } from ${ olderVersion } , to now:` ) ;
68+ printDiff ( oldFile , generatedDTSContent ) ;
69+
70+ const title = `\n## \`${ file } \`\n` ;
71+ const notes = generateChangelogFrom ( oldFile , generatedDTSContent ) ;
72+ releaseNotes . push ( title ) ;
73+ releaseNotes . push ( notes . trim ( ) === "" ? "No changes" : notes ) ;
74+
75+ upload = upload || oldFile !== generatedDTSContent ;
76+ } catch ( error ) {
77+ // Could not find a previous build
78+ console . log ( `
79+ Could not get the file ${ file } inside the npm package ${ pkgJSON . name } from tag ${ olderVersion } .
6580Assuming that this means we need to upload this package.` ) ;
66- upload = true ;
67- }
81+ upload = true ;
6882 }
83+ }
6984
70- // Publish via npm
71- if ( upload ) {
72- if ( process . env . NODE_AUTH_TOKEN ) {
73- const publish = spawnSync ( "npm" , [ "publish" , "--access" , "public" ] , {
74- cwd : join ( generatedDir , dirName ) ,
75- stdio : "inherit" ,
76- } ) ;
77-
78- if ( publish . status ) {
79- console . log ( publish . stdout ?. toString ( ) ) ;
80- console . log ( publish . stderr ?. toString ( ) ) ;
81- process . exit ( publish . status ) ;
82- } else {
83- console . log ( publish . stdout ?. toString ( ) ) ;
84-
85- await createRelease ( `${ pkgJSON . name } @${ pkgJSON . version } ` ) ;
86- }
85+ // Publish via npm
86+ if ( upload ) {
87+ if ( process . env . NODE_AUTH_TOKEN ) {
88+ const publish = spawnSync ( "npm" , [ "publish" , "--access" , "public" ] , {
89+ cwd : join ( generatedDir , dirName ) ,
90+ stdio : "inherit" ,
91+ } ) ;
92+
93+ if ( publish . status ) {
94+ console . log ( publish . stdout ?. toString ( ) ) ;
95+ console . log ( publish . stderr ?. toString ( ) ) ;
96+ process . exit ( publish . status ) ;
8797 } else {
88- console . log (
89- "Wanting to run: 'npm publish --access public' in " +
90- join ( generatedDir , dirName )
91- ) ;
92- }
98+ console . log ( publish . stdout ?. toString ( ) ) ;
9399
94- uploaded . push ( dirName ) ;
100+ await createRelease ( `${ pkgJSON . name } @${ pkgJSON . version } ` ) ;
101+ }
102+ } else {
103+ console . log (
104+ "Wanting to run: 'npm publish --access public' in " +
105+ join ( generatedDir , dirName )
106+ ) ;
95107 }
96- }
97108
98- // Warn if we did a dry run.
99- if ( ! process . env . NODE_AUTH_TOKEN ) {
100- console . log (
101- "Did a dry run because process.env.NODE_AUTH_TOKEN is not set."
102- ) ;
109+ uploaded . push ( dirName ) ;
103110 }
104111
105- if ( uploaded . length ) {
106- console . log ( "Uploaded: " , uploaded . join ( ", " ) ) ;
107- } else {
108- console . log ( "No uploads" ) ;
109- }
110- } ;
112+ console . log ( "\n# Release notes:" ) ;
113+ console . log ( releaseNotes . join ( "\n" ) , "\n\n" ) ;
114+ }
115+ // Warn if we did a dry run.
116+ if ( ! process . env . NODE_AUTH_TOKEN ) {
117+ console . log ( "Did a dry run because process.env.NODE_AUTH_TOKEN is not set." ) ;
118+ }
119+
120+ if ( uploaded . length ) {
121+ console . log ( "Uploaded: " , uploaded . join ( ", " ) ) ;
122+ } else {
123+ console . log ( "No uploads" ) ;
124+ }
111125
112- async function createRelease ( tag ) {
126+ async function createRelease ( tag , body ) {
113127 const authToken = process . env . GITHUB_TOKEN || process . env . GITHUB_API_TOKEN ;
114128 const octokit = new Octokit ( { auth : authToken } ) ;
115129
@@ -119,6 +133,8 @@ async function createRelease(tag) {
119133 repo : "TypeScript-DOM-lib-generator" ,
120134 tag_name : tag ,
121135 target_commitish : process . env . GITHUB_SHA ,
136+ name : tag ,
137+ body,
122138 } ) ;
123139 } catch ( error ) {
124140 console . error (
@@ -127,4 +143,14 @@ async function createRelease(tag) {
127143 }
128144}
129145
130- go ( ) ;
146+ function verify ( ) {
147+ const authToken = process . env . GITHUB_TOKEN || process . env . GITHUB_API_TOKEN ;
148+ if ( ! authToken )
149+ throw new Error (
150+ "There isn't an ENV var set up for creating a GitHub release, expected GITHUB_TOKEN."
151+ ) ;
152+ }
153+
154+ function gitShowFile ( commitish , path ) {
155+ return execSync ( `git show "${ commitish } ":${ path } ` , { encoding : "utf-8" } ) ;
156+ }
0 commit comments