mirror of
https://github.com/desktop/desktop
synced 2024-11-05 20:49:32 +00:00
160 lines
4.7 KiB
TypeScript
160 lines
4.7 KiB
TypeScript
/* eslint-disable no-sync */
|
|
|
|
import * as cp from 'child_process'
|
|
import * as path from 'path'
|
|
import * as electronInstaller from 'electron-winstaller'
|
|
import { getProductName, getCompanyName } from '../app/package-info'
|
|
import {
|
|
getDistPath,
|
|
getOSXZipPath,
|
|
getWindowsIdentifierName,
|
|
getWindowsStandaloneName,
|
|
getWindowsInstallerName,
|
|
shouldMakeDelta,
|
|
getUpdatesURL,
|
|
getIconFileName,
|
|
isPublishable,
|
|
getBundleSizes,
|
|
getDistRoot,
|
|
getDistArchitecture,
|
|
} from './dist-info'
|
|
import { isGitHubActions } from './build-platforms'
|
|
import { existsSync, rmSync, writeFileSync } from 'fs'
|
|
import { getVersion } from '../app/package-info'
|
|
import { rename } from 'fs/promises'
|
|
import { join } from 'path'
|
|
import { assertNonNullable } from '../app/src/lib/fatal-error'
|
|
|
|
const distPath = getDistPath()
|
|
const productName = getProductName()
|
|
const outputDir = getDistRoot()
|
|
|
|
const assertExistsSync = (path: string) => {
|
|
if (!existsSync(path)) {
|
|
throw new Error(`Expected ${path} to exist`)
|
|
}
|
|
}
|
|
|
|
if (process.platform === 'darwin') {
|
|
packageOSX()
|
|
} else if (process.platform === 'win32') {
|
|
packageWindows()
|
|
} else {
|
|
console.error(`I don't know how to package for ${process.platform} :(`)
|
|
process.exit(1)
|
|
}
|
|
|
|
console.log('Writing bundle size info…')
|
|
writeFileSync(
|
|
path.join(getDistRoot(), 'bundle-size.json'),
|
|
JSON.stringify(getBundleSizes())
|
|
)
|
|
|
|
function packageOSX() {
|
|
const dest = getOSXZipPath()
|
|
rmSync(dest, { recursive: true, force: true })
|
|
|
|
console.log('Packaging for macOS…')
|
|
cp.execSync(
|
|
`ditto -ck --keepParent "${distPath}/${productName}.app" "${dest}"`
|
|
)
|
|
}
|
|
|
|
function packageWindows() {
|
|
const iconSource = path.join(
|
|
__dirname,
|
|
'..',
|
|
'app',
|
|
'static',
|
|
'logos',
|
|
`${getIconFileName()}.ico`
|
|
)
|
|
|
|
if (!existsSync(iconSource)) {
|
|
console.error(`expected setup icon not found at location: ${iconSource}`)
|
|
process.exit(1)
|
|
}
|
|
|
|
const splashScreenPath = path.resolve(
|
|
__dirname,
|
|
'../app/static/logos/win32-installer-splash.gif'
|
|
)
|
|
|
|
if (!existsSync(splashScreenPath)) {
|
|
console.error(
|
|
`expected setup splash screen gif not found at location: ${splashScreenPath}`
|
|
)
|
|
process.exit(1)
|
|
}
|
|
|
|
const iconUrl =
|
|
'https://desktop.githubusercontent.com/github-desktop/app-icon.ico'
|
|
|
|
const nugetPkgName = getWindowsIdentifierName()
|
|
const options: electronInstaller.Options = {
|
|
name: nugetPkgName,
|
|
appDirectory: distPath,
|
|
outputDirectory: outputDir,
|
|
authors: getCompanyName(),
|
|
iconUrl: iconUrl,
|
|
setupIcon: iconSource,
|
|
loadingGif: splashScreenPath,
|
|
exe: `${nugetPkgName}.exe`,
|
|
title: productName,
|
|
setupExe: getWindowsStandaloneName(),
|
|
setupMsi: getWindowsInstallerName(),
|
|
}
|
|
|
|
if (shouldMakeDelta()) {
|
|
const url = new URL(getUpdatesURL())
|
|
// Make sure Squirrel.Windows isn't affected by partially or completely
|
|
// disabled releases.
|
|
url.searchParams.set('bypassStaggeredRelease', '1')
|
|
options.remoteReleases = url.toString()
|
|
}
|
|
|
|
if (isGitHubActions() && isPublishable()) {
|
|
assertNonNullable(process.env.RUNNER_TEMP, 'Missing RUNNER_TEMP env var')
|
|
|
|
const acsPath = join(process.env.RUNNER_TEMP, 'acs')
|
|
const dlibPath = join(acsPath, 'bin', 'x64', 'Azure.CodeSigning.Dlib.dll')
|
|
|
|
assertExistsSync(dlibPath)
|
|
|
|
const metadataPath = join(acsPath, 'metadata.json')
|
|
const acsMetadata = {
|
|
Endpoint: 'https://eus.codesigning.azure.net/',
|
|
CodeSigningAccountName: 'github-desktop',
|
|
CertificateProfileName: 'desktop',
|
|
CorrelationId: `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`,
|
|
}
|
|
writeFileSync(metadataPath, JSON.stringify(acsMetadata))
|
|
|
|
options.signWithParams = `/v /fd SHA256 /tr "http://timestamp.acs.microsoft.com" /td SHA256 /dlib "${dlibPath}" /dmdf "${metadataPath}"`
|
|
}
|
|
|
|
console.log('Packaging for Windows…')
|
|
electronInstaller
|
|
.createWindowsInstaller(options)
|
|
.then(() => console.log(`Installers created in ${outputDir}`))
|
|
.then(async () => {
|
|
// electron-winstaller (more specifically Squirrel.Windows) doesn't let
|
|
// us control the name of the nuget packages but we want them to include
|
|
// the architecture similar to how the setup exe and msi do so we'll just
|
|
// have to rename them here after the fact.
|
|
const arch = getDistArchitecture()
|
|
const prefix = `${getWindowsIdentifierName()}-${getVersion()}`
|
|
|
|
for (const kind of shouldMakeDelta() ? ['full', 'delta'] : ['full']) {
|
|
const from = join(outputDir, `${prefix}-${kind}.nupkg`)
|
|
const to = join(outputDir, `${prefix}-${arch}-${kind}.nupkg`)
|
|
|
|
console.log(`Renaming ${from} to ${to}`)
|
|
await rename(from, to)
|
|
}
|
|
})
|
|
.catch(e => {
|
|
console.error(`Error packaging: ${e}`)
|
|
process.exit(1)
|
|
})
|
|
}
|