@@ -17,7 +17,6 @@ const rename = require('gulp-rename');
1717const replace = require ( 'gulp-replace' ) ;
1818const filter = require ( 'gulp-filter' ) ;
1919const { getProductionDependencies } = require ( './lib/dependencies' ) ;
20- const { assetFromGithub } = require ( './lib/github' ) ;
2120const vfs = require ( 'vinyl-fs' ) ;
2221const packageJson = require ( '../package.json' ) ;
2322const flatmap = require ( 'gulp-flatmap' ) ;
@@ -43,7 +42,6 @@ const BUILD_TARGETS = [
4342 { platform : 'win32' , arch : 'x64' } ,
4443 { platform : 'darwin' , arch : 'x64' } ,
4544 { platform : 'darwin' , arch : 'arm64' } ,
46- { platform : 'linux' , arch : 'ia32' } ,
4745 { platform : 'linux' , arch : 'x64' } ,
4846 { platform : 'linux' , arch : 'armhf' } ,
4947 { platform : 'linux' , arch : 'arm64' } ,
@@ -131,6 +129,33 @@ function getNodeVersion() {
131129 return target ;
132130}
133131
132+ function getNodeChecksum ( nodeVersion , platform , arch ) {
133+ let expectedName ;
134+ switch ( platform ) {
135+ case 'win32' :
136+ expectedName = `win-${ arch } /node.exe` ;
137+ break ;
138+
139+ case 'darwin' :
140+ case 'linux' :
141+ expectedName = `node-v${ nodeVersion } -${ platform } -${ arch } .tar.gz` ;
142+ break ;
143+
144+ case 'alpine' :
145+ expectedName = `${ platform } -${ arch } /node` ;
146+ break ;
147+ }
148+
149+ const nodeJsChecksums = fs . readFileSync ( path . join ( REPO_ROOT , 'build' , 'checksums' , 'nodejs.txt' ) , 'utf8' ) ;
150+ for ( const line of nodeJsChecksums . split ( '\n' ) ) {
151+ const [ checksum , name ] = line . split ( / \s + / ) ;
152+ if ( name === expectedName ) {
153+ return checksum ;
154+ }
155+ }
156+ return undefined ;
157+ }
158+
134159const nodeVersion = getNodeVersion ( ) ;
135160
136161BUILD_TARGETS . forEach ( ( { platform, arch } ) => {
@@ -155,40 +180,57 @@ if (defaultNodeTask) {
155180}
156181
157182function nodejs ( platform , arch ) {
158- const { remote } = require ( './lib/gulpRemoteSource ' ) ;
183+ const { fetchUrls , fetchGithub } = require ( './lib/fetch ' ) ;
159184 const untar = require ( 'gulp-untar' ) ;
185+ const crypto = require ( 'crypto' ) ;
160186
161187 if ( arch === 'ia32' ) {
162188 arch = 'x86' ;
189+ } else if ( arch === 'armhf' ) {
190+ arch = 'armv7l' ;
191+ } else if ( arch === 'alpine' ) {
192+ platform = 'alpine' ;
193+ arch = 'x64' ;
163194 }
164195
165- if ( platform === 'win32' ) {
166- if ( product . nodejsRepository ) {
167- log ( `Downloading node.js ${ nodeVersion } ${ platform } ${ arch } from ${ product . nodejsRepository } ...` ) ;
168- return assetFromGithub ( product . nodejsRepository , nodeVersion , name => name === `win-${ arch } -node-patched.exe` )
169- . pipe ( rename ( 'node.exe' ) ) ;
170- }
171- log ( `Downloading node.js ${ nodeVersion } ${ platform } ${ arch } from https://nodejs.org` ) ;
172- return remote ( `/dist/v${ nodeVersion } /win-${ arch } /node.exe` , { base : 'https://nodejs.org' , verbose : true } )
173- . pipe ( rename ( 'node.exe' ) ) ;
174- }
196+ log ( `Downloading node.js ${ nodeVersion } ${ platform } ${ arch } from ${ product . nodejs . repository } ...` ) ;
175197
176- if ( arch === 'alpine' || platform === 'alpine' ) {
177- const imageName = arch === 'arm64' ? 'arm64v8/node' : 'node' ;
178- log ( `Downloading node.js ${ nodeVersion } ${ platform } ${ arch } from docker image ${ imageName } ` ) ;
179- const contents = cp . execSync ( `docker run --rm ${ imageName } :${ nodeVersion } -alpine /bin/sh -c 'cat \`which node\`'` , { maxBuffer : 100 * 1024 * 1024 , encoding : 'buffer' } ) ;
180- return es . readArray ( [ new File ( { path : 'node' , contents, stat : { mode : parseInt ( '755' , 8 ) } } ) ] ) ;
198+ const checksumSha256 = getNodeChecksum ( nodeVersion , platform , arch ) ;
199+
200+ if ( checksumSha256 ) {
201+ log ( `Using SHA256 checksum for checking integrity: ${ checksumSha256 } ` ) ;
202+ } else {
203+ log . warn ( `Unable to verify integrity of downloaded node.js binary because no SHA256 checksum was found!` ) ;
181204 }
182205
183- if ( arch === 'armhf' ) {
184- arch = 'armv7l' ;
206+ switch ( platform ) {
207+ case 'win32' :
208+ return ( product . nodejs . repository !== 'https://nodejs.org' ?
209+ fetchGithub ( product . nodejs . repository , { version : product . nodejs . version , name : `win-${ arch } -node.exe` , checksumSha256 } ) :
210+ fetchUrls ( `/dist/v${ nodeVersion } /win-${ arch } /node.exe` , { base : 'https://nodejs.org' , checksumSha256 } ) )
211+ . pipe ( rename ( 'node.exe' ) ) ;
212+ case 'darwin' :
213+ case 'linux' :
214+ return ( product . nodejs . repository !== 'https://nodejs.org' ?
215+ fetchGithub ( product . nodejs . repository , { version : product . nodejs . version , name : `node-v${ nodeVersion } -${ platform } -${ arch } .tar.gz` , checksumSha256 } ) :
216+ fetchUrls ( `/dist/v${ nodeVersion } /node-v${ nodeVersion } -${ platform } -${ arch } .tar.gz` , { base : 'https://nodejs.org' , checksumSha256 } )
217+ ) . pipe ( flatmap ( stream => stream . pipe ( gunzip ( ) ) . pipe ( untar ( ) ) ) )
218+ . pipe ( filter ( '**/node' ) )
219+ . pipe ( util . setExecutableBit ( '**' ) )
220+ . pipe ( rename ( 'node' ) ) ;
221+ case 'alpine' : {
222+ const imageName = arch === 'arm64' ? 'arm64v8/node' : 'node' ;
223+ log ( `Downloading node.js ${ nodeVersion } ${ platform } ${ arch } from docker image ${ imageName } ` ) ;
224+ const contents = cp . execSync ( `docker run --rm ${ imageName } :${ nodeVersion } -alpine /bin/sh -c 'cat \`which node\`'` , { maxBuffer : 100 * 1024 * 1024 , encoding : 'buffer' } ) ;
225+ if ( checksumSha256 ) {
226+ const actualSHA256Checksum = crypto . createHash ( 'sha256' ) . update ( contents ) . digest ( 'hex' ) ;
227+ if ( actualSHA256Checksum !== checksumSha256 ) {
228+ throw new Error ( `Checksum mismatch for node.js from docker image (expected ${ options . checksumSha256 } , actual ${ actualSHA256Checksum } ))` ) ;
229+ }
230+ }
231+ return es . readArray ( [ new File ( { path : 'node' , contents, stat : { mode : parseInt ( '755' , 8 ) } } ) ] ) ;
232+ }
185233 }
186- log ( `Downloading node.js ${ nodeVersion } ${ platform } ${ arch } from https://nodejs.org` ) ;
187- return remote ( `/dist/v${ nodeVersion } /node-v${ nodeVersion } -${ platform } -${ arch } .tar.gz` , { base : 'https://nodejs.org' , verbose : true } )
188- . pipe ( flatmap ( stream => stream . pipe ( gunzip ( ) ) . pipe ( untar ( ) ) ) )
189- . pipe ( filter ( '**/node' ) )
190- . pipe ( util . setExecutableBit ( '**' ) )
191- . pipe ( rename ( 'node' ) ) ;
192234}
193235
194236function packageTask ( type , platform , arch , sourceFolderName , destinationFolderName ) {
0 commit comments