2017-10-23 15:02:50 +00:00
#!/usr/bin/env node
2018-07-19 18:48:13 +00:00
if ( ! process . env . CI ) require ( 'dotenv-safe' ) . load ( ) ;
2019-08-29 14:46:54 +00:00
2018-12-20 03:36:01 +00:00
const args = require ( 'minimist' ) ( process . argv . slice ( 2 ) , {
boolean : [
'validateRelease' ,
2019-01-23 19:47:36 +00:00
'verboseNugget'
] ,
2020-03-20 15:12:18 +00:00
default : { verboseNugget : false }
2018-12-20 03:36:01 +00:00
} ) ;
2017-10-23 15:02:50 +00:00
const fs = require ( 'fs' ) ;
const { execSync } = require ( 'child_process' ) ;
2019-01-23 19:47:36 +00:00
const got = require ( 'got' ) ;
2019-06-24 17:18:04 +00:00
const pkg = require ( '../../package.json' ) ;
2017-10-23 15:02:50 +00:00
const pkgVersion = ` v ${ pkg . version } ` ;
const path = require ( 'path' ) ;
const temp = require ( 'temp' ) . track ( ) ;
const { URL } = require ( 'url' ) ;
2022-04-04 09:32:57 +00:00
const { BlobServiceClient } = require ( '@azure/storage-blob' ) ;
2020-08-05 15:59:52 +00:00
const { Octokit } = require ( '@octokit/rest' ) ;
2020-03-20 20:28:31 +00:00
2019-08-29 14:46:54 +00:00
require ( 'colors' ) ;
const pass = '✓' . green ;
const fail = '✗' . red ;
2020-03-20 20:28:31 +00:00
2019-06-24 17:18:04 +00:00
const { ELECTRON _DIR } = require ( '../lib/utils' ) ;
2021-05-11 16:30:35 +00:00
const getUrlHash = require ( './get-url-hash' ) ;
2019-06-24 17:18:04 +00:00
2020-08-05 15:59:52 +00:00
const octokit = new Octokit ( {
2019-05-08 01:48:40 +00:00
auth : process . env . ELECTRON _GITHUB _TOKEN
2017-10-23 15:02:50 +00:00
} ) ;
2019-01-08 20:05:58 +00:00
const targetRepo = pkgVersion . indexOf ( 'nightly' ) > 0 ? 'nightlies' : 'electron' ;
let failureCount = 0 ;
2017-10-23 15:02:50 +00:00
async function getDraftRelease ( version , skipValidation ) {
2019-01-08 20:05:58 +00:00
const releaseInfo = await octokit . repos . listReleases ( {
owner : 'electron' ,
repo : targetRepo
} ) ;
const versionToCheck = version || pkgVersion ;
const drafts = releaseInfo . data . filter ( release => {
return release . tag _name === versionToCheck && release . draft === true ;
} ) ;
2017-10-23 15:02:50 +00:00
const draft = drafts [ 0 ] ;
if ( ! skipValidation ) {
failureCount = 0 ;
2019-01-23 19:47:36 +00:00
check ( drafts . length === 1 , 'one draft exists' , true ) ;
2018-01-31 00:35:16 +00:00
if ( versionToCheck . indexOf ( 'beta' ) > - 1 ) {
2019-01-23 19:47:36 +00:00
check ( draft . prerelease , 'draft is a prerelease' ) ;
2017-10-23 15:02:50 +00:00
}
2019-01-23 19:47:36 +00:00
check ( draft . body . length > 50 && ! draft . body . includes ( '(placeholder)' ) , 'draft has release notes' ) ;
2020-03-20 15:12:18 +00:00
check ( ( failureCount === 0 ) , 'Draft release looks good to go.' , true ) ;
2017-10-23 15:02:50 +00:00
}
return draft ;
}
2018-01-31 23:40:38 +00:00
async function validateReleaseAssets ( release , validatingRelease ) {
const requiredAssets = assetsForVersion ( release . tag _name , validatingRelease ) . sort ( ) ;
2017-10-23 15:02:50 +00:00
const extantAssets = release . assets . map ( asset => asset . name ) . sort ( ) ;
2021-05-11 16:30:35 +00:00
const downloadUrls = release . assets . map ( asset => ( { url : asset . browser _download _url , file : asset . name } ) ) . sort ( ( a , b ) => a . file . localeCompare ( b . file ) ) ;
2017-10-23 15:02:50 +00:00
failureCount = 0 ;
requiredAssets . forEach ( asset => {
check ( extantAssets . includes ( asset ) , asset ) ;
} ) ;
2020-03-20 15:12:18 +00:00
check ( ( failureCount === 0 ) , 'All required GitHub assets exist for release' , true ) ;
2017-10-23 15:02:50 +00:00
2018-02-22 13:53:32 +00:00
if ( ! validatingRelease || ! release . draft ) {
if ( release . draft ) {
2021-05-11 16:30:35 +00:00
await verifyDraftGitHubReleaseAssets ( release ) ;
2018-02-22 13:53:32 +00:00
} else {
2021-05-11 16:30:35 +00:00
await verifyShasumsForRemoteFiles ( downloadUrls )
2018-02-22 13:53:32 +00:00
. catch ( err => {
console . log ( ` ${ fail } error verifyingShasums ` , err ) ;
} ) ;
}
2021-05-11 16:30:35 +00:00
const s3RemoteFiles = s3RemoteFilesForVersion ( release . tag _name ) ;
await verifyShasumsForRemoteFiles ( s3RemoteFiles , true ) ;
2022-04-04 09:32:57 +00:00
const azRemoteFiles = azRemoteFilesForVersion ( release . tag _name ) ;
await verifyShasumsForRemoteFiles ( s3RemoteFiles , true ) ;
2017-10-23 15:02:50 +00:00
}
}
function check ( condition , statement , exitIfFail = false ) {
if ( condition ) {
console . log ( ` ${ pass } ${ statement } ` ) ;
} else {
failureCount ++ ;
console . log ( ` ${ fail } ${ statement } ` ) ;
if ( exitIfFail ) process . exit ( 1 ) ;
}
}
2018-01-31 23:40:38 +00:00
function assetsForVersion ( version , validatingRelease ) {
2017-10-23 15:02:50 +00:00
const patterns = [
2019-09-04 18:24:46 +00:00
` chromedriver- ${ version } -darwin-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` chromedriver- ${ version } -darwin-arm64.zip ` ,
2019-09-04 18:24:46 +00:00
` chromedriver- ${ version } -linux-arm64.zip ` ,
` chromedriver- ${ version } -linux-armv7l.zip ` ,
` chromedriver- ${ version } -linux-ia32.zip ` ,
` chromedriver- ${ version } -linux-x64.zip ` ,
` chromedriver- ${ version } -mas-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` chromedriver- ${ version } -mas-arm64.zip ` ,
2019-09-04 18:24:46 +00:00
` chromedriver- ${ version } -win32-ia32.zip ` ,
` chromedriver- ${ version } -win32-x64.zip ` ,
` chromedriver- ${ version } -win32-arm64.zip ` ,
2017-10-23 15:02:50 +00:00
` electron- ${ version } -darwin-x64-dsym.zip ` ,
2022-03-07 23:47:58 +00:00
` electron- ${ version } -darwin-x64-dsym-snapshot.zip ` ,
2017-10-23 15:02:50 +00:00
` electron- ${ version } -darwin-x64-symbols.zip ` ,
` electron- ${ version } -darwin-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` electron- ${ version } -darwin-arm64-dsym.zip ` ,
2022-03-07 23:47:58 +00:00
` electron- ${ version } -darwin-arm64-dsym-snapshot.zip ` ,
2020-07-21 11:55:00 +00:00
` electron- ${ version } -darwin-arm64-symbols.zip ` ,
` electron- ${ version } -darwin-arm64.zip ` ,
2019-01-22 21:14:01 +00:00
` electron- ${ version } -linux-arm64-symbols.zip ` ,
` electron- ${ version } -linux-arm64.zip ` ,
` electron- ${ version } -linux-armv7l-symbols.zip ` ,
` electron- ${ version } -linux-armv7l.zip ` ,
2017-10-23 15:02:50 +00:00
` electron- ${ version } -linux-ia32-symbols.zip ` ,
` electron- ${ version } -linux-ia32.zip ` ,
2019-11-21 01:21:44 +00:00
` electron- ${ version } -linux-x64-debug.zip ` ,
2017-10-23 15:02:50 +00:00
` electron- ${ version } -linux-x64-symbols.zip ` ,
` electron- ${ version } -linux-x64.zip ` ,
` electron- ${ version } -mas-x64-dsym.zip ` ,
2022-03-07 23:47:58 +00:00
` electron- ${ version } -mas-x64-dsym-snapshot.zip ` ,
2017-10-23 15:02:50 +00:00
` electron- ${ version } -mas-x64-symbols.zip ` ,
` electron- ${ version } -mas-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` electron- ${ version } -mas-arm64-dsym.zip ` ,
2022-03-07 23:47:58 +00:00
` electron- ${ version } -mas-arm64-dsym-snapshot.zip ` ,
2020-07-21 11:55:00 +00:00
` electron- ${ version } -mas-arm64-symbols.zip ` ,
` electron- ${ version } -mas-arm64.zip ` ,
2017-10-23 15:02:50 +00:00
` electron- ${ version } -win32-ia32-pdb.zip ` ,
` electron- ${ version } -win32-ia32-symbols.zip ` ,
` electron- ${ version } -win32-ia32.zip ` ,
` electron- ${ version } -win32-x64-pdb.zip ` ,
` electron- ${ version } -win32-x64-symbols.zip ` ,
` electron- ${ version } -win32-x64.zip ` ,
2019-09-04 18:24:46 +00:00
` electron- ${ version } -win32-arm64-pdb.zip ` ,
` electron- ${ version } -win32-arm64-symbols.zip ` ,
` electron- ${ version } -win32-arm64.zip ` ,
2020-03-20 15:12:18 +00:00
'electron-api.json' ,
'electron.d.ts' ,
'hunspell_dictionaries.zip' ,
2021-05-22 18:48:38 +00:00
'libcxx_headers.zip' ,
'libcxxabi_headers.zip' ,
` libcxx-objects- ${ version } -linux-arm64.zip ` ,
` libcxx-objects- ${ version } -linux-armv7l.zip ` ,
` libcxx-objects- ${ version } -linux-ia32.zip ` ,
` libcxx-objects- ${ version } -linux-x64.zip ` ,
2017-10-23 15:02:50 +00:00
` ffmpeg- ${ version } -darwin-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` ffmpeg- ${ version } -darwin-arm64.zip ` ,
2019-01-22 21:14:01 +00:00
` ffmpeg- ${ version } -linux-arm64.zip ` ,
` ffmpeg- ${ version } -linux-armv7l.zip ` ,
2017-10-23 15:02:50 +00:00
` ffmpeg- ${ version } -linux-ia32.zip ` ,
` ffmpeg- ${ version } -linux-x64.zip ` ,
` ffmpeg- ${ version } -mas-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` ffmpeg- ${ version } -mas-arm64.zip ` ,
2017-10-23 15:02:50 +00:00
` ffmpeg- ${ version } -win32-ia32.zip ` ,
2019-09-04 18:24:46 +00:00
` ffmpeg- ${ version } -win32-x64.zip ` ,
` ffmpeg- ${ version } -win32-arm64.zip ` ,
` mksnapshot- ${ version } -darwin-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` mksnapshot- ${ version } -darwin-arm64.zip ` ,
2019-09-04 18:24:46 +00:00
` mksnapshot- ${ version } -linux-arm64-x64.zip ` ,
` mksnapshot- ${ version } -linux-armv7l-x64.zip ` ,
` mksnapshot- ${ version } -linux-ia32.zip ` ,
` mksnapshot- ${ version } -linux-x64.zip ` ,
` mksnapshot- ${ version } -mas-x64.zip ` ,
2020-07-21 11:55:00 +00:00
` mksnapshot- ${ version } -mas-arm64.zip ` ,
2019-09-04 18:24:46 +00:00
` mksnapshot- ${ version } -win32-ia32.zip ` ,
` mksnapshot- ${ version } -win32-x64.zip ` ,
2020-01-13 20:40:13 +00:00
` mksnapshot- ${ version } -win32-arm64-x64.zip ` ,
2020-01-14 22:10:08 +00:00
` electron- ${ version } -win32-ia32-toolchain-profile.zip ` ,
` electron- ${ version } -win32-x64-toolchain-profile.zip ` ,
` electron- ${ version } -win32-arm64-toolchain-profile.zip `
2017-10-23 15:02:50 +00:00
] ;
2018-01-31 23:40:38 +00:00
if ( ! validatingRelease ) {
patterns . push ( 'SHASUMS256.txt' ) ;
}
2017-10-23 15:02:50 +00:00
return patterns ;
}
2022-04-04 09:32:57 +00:00
const cloudStoreFilePaths = ( version ) => [
` iojs- ${ version } -headers.tar.gz ` ,
` iojs- ${ version } .tar.gz ` ,
` node- ${ version } .tar.gz ` ,
'node.lib' ,
'x64/node.lib' ,
'win-x64/iojs.lib' ,
'win-x86/iojs.lib' ,
'win-arm64/iojs.lib' ,
'win-x64/node.lib' ,
'win-x86/node.lib' ,
'win-arm64/node.lib' ,
'arm64/node.lib' ,
'SHASUMS.txt' ,
'SHASUMS256.txt'
] ;
2021-05-11 16:30:35 +00:00
function s3RemoteFilesForVersion ( version ) {
2020-03-20 15:12:18 +00:00
const bucket = 'https://gh-contractor-zcbenz.s3.amazonaws.com/' ;
2021-05-11 16:30:35 +00:00
const versionPrefix = ` ${ bucket } atom-shell/dist/ ${ version } / ` ;
2022-04-04 09:32:57 +00:00
return cloudStoreFilePaths ( version ) . map ( ( filePath ) => ( {
file : filePath ,
url : ` ${ versionPrefix } ${ filePath } `
} ) ) ;
}
function azRemoteFilesForVersion ( version ) {
const azCDN = 'https://artifacts.electronjs.org/headers/' ;
const versionPrefix = ` ${ azCDN } dist/ ${ version } / ` ;
return cloudStoreFilePaths ( version ) . map ( ( filePath ) => ( {
2021-05-11 16:30:35 +00:00
file : filePath ,
url : ` ${ versionPrefix } ${ filePath } `
} ) ) ;
2017-10-23 15:02:50 +00:00
}
function runScript ( scriptName , scriptArgs , cwd ) {
2018-10-02 01:56:31 +00:00
const scriptCommand = ` ${ scriptName } ${ scriptArgs . join ( ' ' ) } ` ;
const scriptOptions = {
2017-10-23 15:02:50 +00:00
encoding : 'UTF-8'
} ;
2019-01-08 20:05:58 +00:00
if ( cwd ) scriptOptions . cwd = cwd ;
2017-10-23 15:02:50 +00:00
try {
return execSync ( scriptCommand , scriptOptions ) ;
} catch ( err ) {
console . log ( ` ${ fail } Error running ${ scriptName } ` , err ) ;
process . exit ( 1 ) ;
}
}
function uploadNodeShasums ( ) {
2022-04-04 09:32:57 +00:00
console . log ( 'Uploading Node SHASUMS file to artifacts.electronjs.org.' ) ;
2019-06-24 17:18:04 +00:00
const scriptPath = path . join ( ELECTRON _DIR , 'script' , 'release' , 'uploaders' , 'upload-node-checksums.py' ) ;
2017-10-23 15:02:50 +00:00
runScript ( scriptPath , [ '-v' , pkgVersion ] ) ;
2022-04-04 09:32:57 +00:00
console . log ( ` ${ pass } Done uploading Node SHASUMS file to artifacts.electronjs.org. ` ) ;
2017-10-23 15:02:50 +00:00
}
function uploadIndexJson ( ) {
2022-04-04 09:32:57 +00:00
console . log ( 'Uploading index.json to artifacts.electronjs.org.' ) ;
2019-06-24 17:18:04 +00:00
const scriptPath = path . join ( ELECTRON _DIR , 'script' , 'release' , 'uploaders' , 'upload-index-json.py' ) ;
2018-08-17 05:23:46 +00:00
runScript ( scriptPath , [ pkgVersion ] ) ;
2022-04-04 09:32:57 +00:00
console . log ( ` ${ pass } Done uploading index.json to artifacts.electronjs.org. ` ) ;
2017-10-23 15:02:50 +00:00
}
2020-09-30 20:30:10 +00:00
async function mergeShasums ( pkgVersion ) {
2022-04-04 09:32:57 +00:00
// Download individual checksum files for Electron zip files from artifact storage,
2020-09-30 20:30:10 +00:00
// concatenate them, and upload to GitHub.
2022-04-04 09:32:57 +00:00
const connectionString = process . env . ELECTRON _ARTIFACTS _BLOB _STORAGE ;
if ( ! connectionString ) {
throw new Error ( 'Please set the $ELECTRON_ARTIFACTS_BLOB_STORAGE environment variable' ) ;
2020-09-30 20:30:10 +00:00
}
2022-04-04 09:32:57 +00:00
const blobServiceClient = BlobServiceClient . fromConnectionString ( connectionString ) ;
const containerClient = blobServiceClient . getContainerClient ( 'checksums-scratchpad' ) ;
const blobsIter = containerClient . listBlobsFlat ( {
prefix : ` ${ pkgVersion } / `
2020-09-30 20:30:10 +00:00
} ) ;
const shasums = [ ] ;
2022-04-04 09:32:57 +00:00
for await ( const blob of blobsIter ) {
if ( blob . name . endsWith ( '.sha256sum' ) ) {
const blobClient = containerClient . getBlockBlobClient ( blob . name ) ;
const response = await blobClient . downloadToBuffer ( ) ;
shasums . push ( response . toString ( 'ascii' ) . trim ( ) ) ;
2020-09-30 20:30:10 +00:00
}
}
return shasums . join ( '\n' ) ;
}
2017-10-23 15:02:50 +00:00
async function createReleaseShasums ( release ) {
2018-10-02 01:56:31 +00:00
const fileName = 'SHASUMS256.txt' ;
const existingAssets = release . assets . filter ( asset => asset . name === fileName ) ;
2017-10-23 15:02:50 +00:00
if ( existingAssets . length > 0 ) {
console . log ( ` ${ fileName } already exists on GitHub; deleting before creating new file. ` ) ;
2019-01-08 20:05:58 +00:00
await octokit . repos . deleteReleaseAsset ( {
2017-10-23 15:02:50 +00:00
owner : 'electron' ,
2018-08-16 15:57:12 +00:00
repo : targetRepo ,
2019-01-08 20:05:58 +00:00
asset _id : existingAssets [ 0 ] . id
2017-10-23 15:02:50 +00:00
} ) . catch ( err => {
console . log ( ` ${ fail } Error deleting ${ fileName } on GitHub: ` , err ) ;
} ) ;
}
console . log ( ` Creating and uploading the release ${ fileName } . ` ) ;
2020-09-30 20:30:10 +00:00
const checksums = await mergeShasums ( pkgVersion ) ;
2019-01-08 20:05:58 +00:00
2017-10-23 15:02:50 +00:00
console . log ( ` ${ pass } Generated release SHASUMS. ` ) ;
2018-10-02 01:56:31 +00:00
const filePath = await saveShaSumFile ( checksums , fileName ) ;
2019-01-08 20:05:58 +00:00
2017-10-23 15:02:50 +00:00
console . log ( ` ${ pass } Created ${ fileName } file. ` ) ;
2019-01-08 20:05:58 +00:00
await uploadShasumFile ( filePath , fileName , release . id ) ;
2017-10-23 15:02:50 +00:00
console . log ( ` ${ pass } Successfully uploaded ${ fileName } to GitHub. ` ) ;
}
2019-01-08 20:05:58 +00:00
async function uploadShasumFile ( filePath , fileName , releaseId ) {
const uploadUrl = ` https://uploads.github.com/repos/electron/ ${ targetRepo } /releases/ ${ releaseId } /assets{?name,label} ` ;
return octokit . repos . uploadReleaseAsset ( {
url : uploadUrl ,
headers : {
'content-type' : 'text/plain' ,
2019-01-11 17:53:13 +00:00
'content-length' : fs . statSync ( filePath ) . size
2019-01-08 20:05:58 +00:00
} ,
2020-08-07 19:00:12 +00:00
data : fs . createReadStream ( filePath ) ,
2017-10-23 15:02:50 +00:00
name : fileName
2019-01-08 20:05:58 +00:00
} ) . catch ( err => {
console . log ( ` ${ fail } Error uploading ${ filePath } to GitHub: ` , err ) ;
process . exit ( 1 ) ;
} ) ;
2017-10-23 15:02:50 +00:00
}
function saveShaSumFile ( checksums , fileName ) {
return new Promise ( ( resolve , reject ) => {
temp . open ( fileName , ( err , info ) => {
if ( err ) {
console . log ( ` ${ fail } Could not create ${ fileName } file ` ) ;
process . exit ( 1 ) ;
} else {
fs . writeFileSync ( info . fd , checksums ) ;
fs . close ( info . fd , ( err ) => {
if ( err ) {
console . log ( ` ${ fail } Could close ${ fileName } file ` ) ;
process . exit ( 1 ) ;
}
resolve ( info . path ) ;
} ) ;
}
} ) ;
} ) ;
}
async function publishRelease ( release ) {
2019-01-08 20:05:58 +00:00
return octokit . repos . updateRelease ( {
2017-10-23 15:02:50 +00:00
owner : 'electron' ,
2018-08-16 15:57:12 +00:00
repo : targetRepo ,
2019-01-08 20:05:58 +00:00
release _id : release . id ,
2017-10-23 15:02:50 +00:00
tag _name : release . tag _name ,
draft : false
2019-01-08 20:05:58 +00:00
} ) . catch ( err => {
console . log ( ` ${ fail } Error publishing release: ` , err ) ;
process . exit ( 1 ) ;
} ) ;
2017-10-23 15:02:50 +00:00
}
async function makeRelease ( releaseToValidate ) {
if ( releaseToValidate ) {
2018-01-31 23:40:38 +00:00
if ( releaseToValidate === true ) {
releaseToValidate = pkgVersion ;
} else {
console . log ( 'Release to validate !=== true' ) ;
}
console . log ( ` Validating release ${ releaseToValidate } ` ) ;
2018-10-02 01:56:31 +00:00
const release = await getDraftRelease ( releaseToValidate ) ;
2018-01-31 23:40:38 +00:00
await validateReleaseAssets ( release , true ) ;
2017-10-23 15:02:50 +00:00
} else {
let draftRelease = await getDraftRelease ( ) ;
uploadNodeShasums ( ) ;
2018-08-17 05:23:46 +00:00
uploadIndexJson ( ) ;
2018-08-16 23:15:00 +00:00
2017-10-23 15:02:50 +00:00
await createReleaseShasums ( draftRelease ) ;
2019-01-08 20:05:58 +00:00
2017-10-23 15:02:50 +00:00
// Fetch latest version of release before verifying
draftRelease = await getDraftRelease ( pkgVersion , true ) ;
await validateReleaseAssets ( draftRelease ) ;
await publishRelease ( draftRelease ) ;
console . log ( ` ${ pass } SUCCESS!!! Release has been published. Please run ` +
2020-03-20 15:12:18 +00:00
'"npm run publish-to-npm" to publish release to npm.' ) ;
2017-10-23 15:02:50 +00:00
}
}
async function makeTempDir ( ) {
return new Promise ( ( resolve , reject ) => {
temp . mkdir ( 'electron-publish' , ( err , dirPath ) => {
if ( err ) {
reject ( err ) ;
} else {
resolve ( dirPath ) ;
}
} ) ;
} ) ;
}
2021-05-11 16:30:35 +00:00
const SHASUM _256 _FILENAME = 'SHASUMS256.txt' ;
const SHASUM _1 _FILENAME = 'SHASUMS.txt' ;
2019-01-08 20:05:58 +00:00
2021-05-11 16:30:35 +00:00
async function verifyDraftGitHubReleaseAssets ( release ) {
console . log ( 'Fetching authenticated GitHub artifact URLs to verify shasums' ) ;
2019-01-08 20:05:58 +00:00
2021-05-11 16:30:35 +00:00
const remoteFilesToHash = await Promise . all ( release . assets . map ( async asset => {
2021-08-12 17:34:49 +00:00
const requestOptions = octokit . repos . getReleaseAsset . endpoint ( {
2019-01-08 20:05:58 +00:00
owner : 'electron' ,
repo : targetRepo ,
2019-01-23 19:47:36 +00:00
asset _id : asset . id ,
headers : {
Accept : 'application/octet-stream'
}
2019-01-08 20:05:58 +00:00
} ) ;
2019-01-23 19:47:36 +00:00
const { url , headers } = requestOptions ;
headers . authorization = ` token ${ process . env . ELECTRON _GITHUB _TOKEN } ` ;
const response = await got ( url , {
followRedirect : false ,
method : 'HEAD' ,
headers
} ) ;
2021-05-11 16:30:35 +00:00
return { url : response . headers . location , file : asset . name } ;
2017-10-23 15:02:50 +00:00
} ) ) . catch ( err => {
console . log ( ` ${ fail } Error downloading files from GitHub ` , err ) ;
process . exit ( 1 ) ;
} ) ;
2019-01-08 20:05:58 +00:00
2021-05-11 16:30:35 +00:00
await verifyShasumsForRemoteFiles ( remoteFilesToHash ) ;
2017-10-23 15:02:50 +00:00
}
2021-05-11 16:30:35 +00:00
async function getShaSumMappingFromUrl ( shaSumFileUrl , fileNamePrefix ) {
const response = await got ( shaSumFileUrl ) ;
const raw = response . body ;
return raw . split ( '\n' ) . map ( line => line . trim ( ) ) . filter ( Boolean ) . reduce ( ( map , line ) => {
2021-05-12 08:49:16 +00:00
const [ sha , file ] = line . replace ( ' ' , ' ' ) . split ( ' ' ) ;
2021-05-11 16:30:35 +00:00
map [ file . slice ( fileNamePrefix . length ) ] = sha ;
return map ;
} , { } ) ;
2017-10-23 15:02:50 +00:00
}
2021-05-11 16:30:35 +00:00
async function validateFileHashesAgainstShaSumMapping ( remoteFilesWithHashes , mapping ) {
for ( const remoteFileWithHash of remoteFilesWithHashes ) {
check ( remoteFileWithHash . hash === mapping [ remoteFileWithHash . file ] , ` Release asset ${ remoteFileWithHash . file } should have hash of ${ mapping [ remoteFileWithHash . file ] } but found ${ remoteFileWithHash . hash } ` , true ) ;
2017-10-23 15:02:50 +00:00
}
}
2021-05-11 16:30:35 +00:00
async function verifyShasumsForRemoteFiles ( remoteFilesToHash , filesAreNodeJSArtifacts = false ) {
console . log ( ` Generating SHAs for ${ remoteFilesToHash . length } files to verify shasums ` ) ;
// Only used for node.js artifact uploads
const shaSum1File = remoteFilesToHash . find ( ( { file } ) => file === SHASUM _1 _FILENAME ) ;
// Used for both node.js artifact uploads and normal electron artifacts
const shaSum256File = remoteFilesToHash . find ( ( { file } ) => file === SHASUM _256 _FILENAME ) ;
remoteFilesToHash = remoteFilesToHash . filter ( ( { file } ) => file !== SHASUM _1 _FILENAME && file !== SHASUM _256 _FILENAME ) ;
const remoteFilesWithHashes = await Promise . all ( remoteFilesToHash . map ( async ( file ) => {
return {
hash : await getUrlHash ( file . url , 'sha256' ) ,
... file
} ;
} ) ) ;
await validateFileHashesAgainstShaSumMapping ( remoteFilesWithHashes , await getShaSumMappingFromUrl ( shaSum256File . url , filesAreNodeJSArtifacts ? '' : '*' ) ) ;
if ( filesAreNodeJSArtifacts ) {
const remoteFilesWithSha1Hashes = await Promise . all ( remoteFilesToHash . map ( async ( file ) => {
return {
hash : await getUrlHash ( file . url , 'sha1' ) ,
... file
} ;
} ) ) ;
await validateFileHashesAgainstShaSumMapping ( remoteFilesWithSha1Hashes , await getShaSumMappingFromUrl ( shaSum1File . url , filesAreNodeJSArtifacts ? '' : '*' ) ) ;
}
2017-10-23 15:02:50 +00:00
}
2021-07-21 07:45:57 +00:00
makeRelease ( args . validateRelease )
. catch ( ( err ) => {
console . error ( 'Error occurred while making release:' , err ) ;
process . exit ( 1 ) ;
} ) ;