build(scripts): cleanup
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
// @ts-check
|
||||
import builder from "electron-builder"
|
||||
import { notarize } from "./notarize.js"
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
|
||||
// Detect channel
|
||||
|
||||
if (!args.includes("--stable") && !args.includes("--prerelease")) {
|
||||
throw new TypeError(`Missing channel argument (either "--stable" or "--prerelease")`)
|
||||
}
|
||||
|
||||
const isPrerelease = args.includes("--prerelease")
|
||||
|
||||
console.log(`Detected channel: ${isPrerelease ? "prerelease" : "stable"}`)
|
||||
|
||||
// Detect OS
|
||||
|
||||
let osKey
|
||||
let osName
|
||||
|
||||
if (process.argv.includes("--linux") || process.platform === "linux") {
|
||||
osKey = /** @type {const} */ ("LINUX")
|
||||
osName = "Linux"
|
||||
} else if (process.argv.includes("--mac") || process.platform === "darwin") {
|
||||
osKey = /** @type {const} */ ("MAC")
|
||||
osName = "macOS"
|
||||
} else if (process.argv.includes("--win") || process.platform === "win32") {
|
||||
osKey = /** @type {const} */ ("WINDOWS")
|
||||
osName = "Windows"
|
||||
} else {
|
||||
throw new TypeError(`The target operating system cannot be inferred from the environment.`)
|
||||
}
|
||||
|
||||
console.log(`Detected operating system: ${osName}`)
|
||||
|
||||
// Prepare electron-builder configuration
|
||||
|
||||
/**
|
||||
* @type {import("electron-builder").Configuration}
|
||||
*/
|
||||
const config = {
|
||||
appId: isPrerelease ? "com.lukasobermann.optolithinsider" : "com.lukasobermann.optolith",
|
||||
productName: isPrerelease ? "Optolith Insider" : "Optolith",
|
||||
copyright:
|
||||
"© 2017–present Lukas Obermann. This product was created under a license. Das Schwarze Auge and its logo as well as Aventuria, Dere, Myranor, Riesland, Tharun and Uthuria and their logos are trademarks of Significant GbR. The title and contents of this book are protected under the copyright laws of the United States of America. No part of this publication may be reproduced, stored in retrieval systems or transmitted, in any form or by any means, whether electronic, mechanical, photocopy, recording, or otherwise, without prior written consent by Ulisses Spiele GmbH, Waldems. This publication includes material that is protected under copyright laws by Ulisses Spiele and/or other authors. Such material is used under the Community Content Agreement for the SCRIPTORIUM AVENTURIS. All other original materials in this work is copyright 2017-present by Lukas Obermann and published under the Community Content Agreement for the SCRIPTORIUM AVENTURIS.",
|
||||
files: [
|
||||
".webpack/**",
|
||||
"LICENSE",
|
||||
"node_modules/optolith-database-schema/schema/**",
|
||||
"src/database/contents/cache/**",
|
||||
"src/database/contents/Compatibility/**",
|
||||
"src/database/contents/Data/**",
|
||||
],
|
||||
asar: false, // otherwise optolith-database-schema package is not properly resolved
|
||||
asarUnpack: [
|
||||
"node_modules/optolith-character-schema/**",
|
||||
"node_modules/optolith-database-schema/**",
|
||||
"src/database/contents/**",
|
||||
],
|
||||
directories: {
|
||||
output: isPrerelease ? "dist/insider" : "dist",
|
||||
},
|
||||
win: {
|
||||
target: [
|
||||
{
|
||||
target: "nsis",
|
||||
arch: ["x64", "ia32"],
|
||||
},
|
||||
],
|
||||
icon: isPrerelease ? "src/assets/icon/AppList.targetsize-512.pre.png" : "src/assets/icon/icon.ico",
|
||||
artifactName: isPrerelease ? "OptolithInsiderSetup_${version}.${ext}" : "OptolithSetup_${version}.${ext}",
|
||||
},
|
||||
nsis: {
|
||||
perMachine: true,
|
||||
differentialPackage: true,
|
||||
deleteAppDataOnUninstall: false,
|
||||
},
|
||||
linux: {
|
||||
category: "RolePlaying",
|
||||
target: [
|
||||
{
|
||||
target: "AppImage",
|
||||
arch: ["x64"],
|
||||
},
|
||||
{
|
||||
target: "tar.gz",
|
||||
arch: ["x64"],
|
||||
},
|
||||
],
|
||||
executableName: isPrerelease ? "OptolithInsider" : "Optolith",
|
||||
icon: isPrerelease ? "src/assets/icon/icon.pre.png" : "src/assets/icon/AppList.targetsize-512.png",
|
||||
artifactName: isPrerelease ? "OptolithInsider_${version}.${ext}" : "Optolith_${version}.${ext}",
|
||||
},
|
||||
mac: {
|
||||
category: "public.app-category.role-playing-games",
|
||||
type: "distribution",
|
||||
target: [
|
||||
{
|
||||
target: "default",
|
||||
arch: "universal",
|
||||
},
|
||||
],
|
||||
icon: isPrerelease ? "src/assets/icon/AppIcon.pre.icns" : "src/assets/icon/AppIcon.icns",
|
||||
artifactName: isPrerelease ? "OptolithInsider_${version}.${ext}" : "Optolith_${version}.${ext}",
|
||||
mergeASARs: false,
|
||||
darkModeSupport: true,
|
||||
gatekeeperAssess: true,
|
||||
},
|
||||
publish: {
|
||||
provider: "generic",
|
||||
url: isPrerelease ? `${process.env.UPDATE_URL}/insider/\${os}` : `${process.env.UPDATE_URL}/\${os}`,
|
||||
channel: "latest",
|
||||
},
|
||||
afterSign: osKey === "MAC" ? notarize : undefined,
|
||||
}
|
||||
|
||||
await builder.build({
|
||||
config,
|
||||
targets: builder.Platform[osKey].createTarget(),
|
||||
})
|
||||
|
||||
console.log(`Build finished successfully.`)
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.debugger</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,16 +1,22 @@
|
||||
// @ts-check
|
||||
import { notarize as electronNotarize } from '@electron/notarize'
|
||||
import { notarize as electronNotarize } from "@electron/notarize"
|
||||
|
||||
/**
|
||||
* Notarizes the app package after it has been built. It detects the
|
||||
* authentication method from the environment variables.
|
||||
* @param context {import("electron-builder").AfterPackContext}
|
||||
*/
|
||||
export const notarize = async (context) => {
|
||||
export const notarize = async context => {
|
||||
const { electronPlatformName, appOutDir } = context
|
||||
|
||||
if (electronPlatformName === 'darwin') {
|
||||
if (electronPlatformName === "darwin") {
|
||||
const appName = context.packager.appInfo.productFilename
|
||||
|
||||
if (typeof process.env.APPLEID === "string" && typeof process.env.APPLEIDPASS === "string" && typeof process.env.TEAMID === "string") {
|
||||
if (
|
||||
typeof process.env.APPLEID === "string" &&
|
||||
typeof process.env.APPLEIDPASS === "string" &&
|
||||
typeof process.env.TEAMID === "string"
|
||||
) {
|
||||
console.log(`Notarizing "${appName}.app" via Apple ID ...`)
|
||||
await electronNotarize({
|
||||
tool: "notarytool",
|
||||
@@ -20,7 +26,11 @@ export const notarize = async (context) => {
|
||||
teamId: process.env.TEAMID,
|
||||
})
|
||||
console.log(`Notarization successful`)
|
||||
} else if (typeof process.env.APPLEAPIKEY === "string" && typeof process.env.APPLEAPIKEYID === "string" && typeof process.env.APPLEAPIISSUER === "string") {
|
||||
} else if (
|
||||
typeof process.env.APPLEAPIKEY === "string" &&
|
||||
typeof process.env.APPLEAPIKEYID === "string" &&
|
||||
typeof process.env.APPLEAPIISSUER === "string"
|
||||
) {
|
||||
console.log(`Notarizing "${appName}.app" via App Store Connect API ...`)
|
||||
await electronNotarize({
|
||||
tool: "notarytool",
|
||||
@@ -40,7 +50,9 @@ export const notarize = async (context) => {
|
||||
})
|
||||
console.log(`Notarization successful`)
|
||||
} else {
|
||||
throw new Error(`Notarization failed: No valid authentication method found in environment. Please provide either APPLEID and APPLEIDPASS, or APPLEAPIKEY, APPLEAPIKEYID and APPLEAPIISSUER, or (optional) KEYCHAIN and KEYCHAINPROFILE.`)
|
||||
throw new Error(
|
||||
`Notarization failed: No valid authentication method found in environment. Please provide either APPLEID and APPLEIDPASS, or APPLEAPIKEY, APPLEAPIKEYID and APPLEAPIISSUER, or (optional) KEYCHAIN and KEYCHAINPROFILE.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* @param {"prerelease" | "stable"} channel
|
||||
*/
|
||||
const channelSuffix = channel => {
|
||||
switch (channel) {
|
||||
case "prerelease": return "Insider"
|
||||
case "stable": return ""
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("./platform.js").System} os
|
||||
* @param {"prerelease" | "stable"} channel
|
||||
*/
|
||||
const prefix = (os, channel) => {
|
||||
switch (os) {
|
||||
case "win": return `Optolith${channelSuffix(channel)}Setup`
|
||||
case "linux":
|
||||
case "mac": return `Optolith${channelSuffix(channel)}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("./platform.js").System} os
|
||||
*/
|
||||
const extensions = os => {
|
||||
switch (os) {
|
||||
case "win": return [".exe", ".exe.blockmap"]
|
||||
case "linux": return [".AppImage", ".tar.gz"]
|
||||
case "mac": return [".dmg", ".dmg.blockmap", ".zip", ".zip.blockmap"]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("./platform.js").System} os
|
||||
* @param {"prerelease" | "stable"} channel
|
||||
* @param {string} version
|
||||
*/
|
||||
export const getApplicationFileNames = (os, channel, version) =>
|
||||
extensions(os).map(ext => `${prefix(os, channel)}_${version}${ext}`)
|
||||
|
||||
/**
|
||||
* @param {"win" | "mac" | "linux"} os
|
||||
*/
|
||||
export const getUpdateFileName = os => {
|
||||
switch (os) {
|
||||
case "win": return "latest.yml"
|
||||
case "linux": return "latest-linux.yml"
|
||||
default: return "latest-mac.yml"
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// @ts-check
|
||||
import { notarize } from "./notarize.js"
|
||||
|
||||
/**
|
||||
* @type {import("electron-builder").Configuration}
|
||||
*/
|
||||
export const baseConfig = {
|
||||
copyright:
|
||||
"© 2017–present Lukas Obermann. This product was created under a license. Das Schwarze Auge and its logo as well as Aventuria, Dere, Myranor, Riesland, Tharun and Uthuria and their logos are trademarks of Significant GbR. The title and contents of this book are protected under the copyright laws of the United States of America. No part of this publication may be reproduced, stored in retrieval systems or transmitted, in any form or by any means, whether electronic, mechanical, photocopy, recording, or otherwise, without prior written consent by Ulisses Spiele GmbH, Waldems. This publication includes material that is protected under copyright laws by Ulisses Spiele and/or other authors. Such material is used under the Community Content Agreement for the SCRIPTORIUM AVENTURIS. All other original materials in this work is copyright 2017-present by Lukas Obermann and published under the Community Content Agreement for the SCRIPTORIUM AVENTURIS.",
|
||||
files: [
|
||||
".webpack/**",
|
||||
"LICENSE",
|
||||
"node_modules/optolith-database-schema/schema/**",
|
||||
"src/database/contents/cache/**",
|
||||
"src/database/contents/Compatibility/**",
|
||||
"src/database/contents/Data/**",
|
||||
],
|
||||
asar: false, // otherwise optolith-database-schema package is not properly resolved
|
||||
asarUnpack: [
|
||||
"node_modules/optolith-character-schema/**",
|
||||
"node_modules/optolith-database-schema/**",
|
||||
"src/database/contents/**",
|
||||
],
|
||||
win: {
|
||||
target: [
|
||||
{
|
||||
target: "nsis",
|
||||
arch: ["x64", "ia32"],
|
||||
},
|
||||
],
|
||||
},
|
||||
nsis: {
|
||||
perMachine: true,
|
||||
differentialPackage: true,
|
||||
deleteAppDataOnUninstall: false,
|
||||
},
|
||||
linux: {
|
||||
category: "RolePlaying",
|
||||
target: [
|
||||
{
|
||||
target: "AppImage",
|
||||
arch: ["x64"],
|
||||
},
|
||||
{
|
||||
target: "tar.gz",
|
||||
arch: ["x64"],
|
||||
},
|
||||
],
|
||||
},
|
||||
mac: {
|
||||
category: "public.app-category.role-playing-games",
|
||||
type: "distribution",
|
||||
target: [
|
||||
{
|
||||
target: "default",
|
||||
arch: "universal",
|
||||
},
|
||||
],
|
||||
entitlements: "deploy/entitlements.mac.plist",
|
||||
entitlementsInherit: "deploy/entitlements.mac.plist",
|
||||
mergeASARs: false,
|
||||
darkModeSupport: true,
|
||||
gatekeeperAssess: true,
|
||||
},
|
||||
afterSign: async context => {
|
||||
if (context.electronPlatformName === "darwin") {
|
||||
await notarize(context)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// @ts-check
|
||||
import builder from "electron-builder"
|
||||
import { getSystem } from "./platform.js"
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
|
||||
if (!args.includes("--stable") && !args.includes("--prerelease")) {
|
||||
throw new TypeError(`build requires a specified channel ("--stable" or "--prerelease")`)
|
||||
}
|
||||
|
||||
const config = args.includes("--prerelease")
|
||||
? (await import("./build.prerelease.config.js")).prereleaseConfig
|
||||
: (await import("./build.stable.config.js")).stableConfig
|
||||
|
||||
process.on("unhandledRejection", error => {
|
||||
throw new Error(`Unhandled promise rejection: ${/** @type {Error} */ (error).toString()}`)
|
||||
})
|
||||
|
||||
const os = getSystem()
|
||||
|
||||
const plaformKey = os === "linux" ? "LINUX" : os === "mac" ? "MAC" : "WINDOWS"
|
||||
|
||||
await builder.build({
|
||||
config,
|
||||
targets: builder.Platform[plaformKey].createTarget(),
|
||||
})
|
||||
@@ -1,35 +0,0 @@
|
||||
// @ts-check
|
||||
import { baseConfig } from "./build.base.config.js"
|
||||
|
||||
/**
|
||||
* @type {import("electron-builder").Configuration}
|
||||
*/
|
||||
export const prereleaseConfig = {
|
||||
...baseConfig,
|
||||
appId: "com.lukasobermann.optolithinsider",
|
||||
productName: "Optolith Insider",
|
||||
directories: {
|
||||
output: "dist/insider",
|
||||
},
|
||||
win: {
|
||||
...baseConfig.win,
|
||||
icon: "src/assets/icon/AppList.targetsize-512.pre.png",
|
||||
artifactName: "OptolithInsiderSetup_${version}.${ext}",
|
||||
},
|
||||
linux: {
|
||||
...baseConfig.linux,
|
||||
executableName: "OptolithInsider",
|
||||
icon: "src/assets/icon/icon.pre.png",
|
||||
artifactName: "OptolithInsider_${version}.${ext}",
|
||||
},
|
||||
mac: {
|
||||
...baseConfig.mac,
|
||||
icon: "src/assets/icon/AppIcon.pre.icns",
|
||||
artifactName: "OptolithInsider_${version}.${ext}",
|
||||
},
|
||||
publish: {
|
||||
provider: "generic",
|
||||
url: `${process.env.UPDATE_URL}/insider/\${os}`,
|
||||
channel: "latest",
|
||||
},
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// @ts-check
|
||||
import { baseConfig } from "./build.base.config.js"
|
||||
|
||||
/**
|
||||
* @type {import("electron-builder").Configuration}
|
||||
*/
|
||||
export const stableConfig = {
|
||||
...baseConfig,
|
||||
appId: "com.lukasobermann.optolith",
|
||||
productName: "Optolith",
|
||||
directories: {
|
||||
output: "dist",
|
||||
},
|
||||
win: {
|
||||
...baseConfig.win,
|
||||
icon: "src/assets/icon/icon.ico",
|
||||
artifactName: "OptolithSetup_${version}.${ext}",
|
||||
},
|
||||
linux: {
|
||||
...baseConfig.linux,
|
||||
executableName: "Optolith",
|
||||
icon: "src/assets/icon/AppList.targetsize-512.png",
|
||||
artifactName: "Optolith_${version}.${ext}",
|
||||
},
|
||||
mac: {
|
||||
...baseConfig.mac,
|
||||
icon: "src/assets/icon/AppIcon.icns",
|
||||
artifactName: "Optolith_${version}.${ext}",
|
||||
},
|
||||
publish: {
|
||||
provider: "generic",
|
||||
url: `${process.env.UPDATE_URL}/\${os}`,
|
||||
channel: "latest",
|
||||
},
|
||||
}
|
||||
+63
-25
@@ -1,10 +1,7 @@
|
||||
// @ts-check
|
||||
import { join } from "node:path"
|
||||
import packageJson from "../package.json" assert { type: "json" }
|
||||
import { getApplicationFileNames, getUpdateFileName } from "./assetNames.js"
|
||||
import { getLocalPath } from "./localPath.js"
|
||||
import { getSystem, getSystemName } from "./platform.js"
|
||||
import { run, upload } from "./remoteConnection.js"
|
||||
import { getRemotePath } from "./remotePath.js"
|
||||
import { run, upload } from "./uploader.js"
|
||||
|
||||
/**
|
||||
* Needed env variables:
|
||||
@@ -16,40 +13,81 @@ import { getRemotePath } from "./remotePath.js"
|
||||
* Optional env variables:
|
||||
* - `CI`
|
||||
*/
|
||||
const {
|
||||
HOST,
|
||||
USERNAME,
|
||||
PASSWORD,
|
||||
ROOT = "/",
|
||||
CI,
|
||||
} = process.env
|
||||
const { HOST, USERNAME, PASSWORD, ROOT = "/", CI } = process.env
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
const os = getSystem()
|
||||
|
||||
// Detect channel
|
||||
|
||||
if (!args.includes("--stable") && !args.includes("--prerelease")) {
|
||||
throw new TypeError(`publishToServer requires a specified channel ("--stable" or "--prerelease")`)
|
||||
throw new TypeError(`Missing channel argument (either "--stable" or "--prerelease")`)
|
||||
}
|
||||
|
||||
const channel = args.includes("--prerelease") ? "prerelease" : "stable"
|
||||
const isPrerelease = args.includes("--prerelease")
|
||||
|
||||
console.log(`Preparing to upload update files for "${getSystemName(os)}" on "${channel}" channel...`)
|
||||
console.log(`Detected channel: ${isPrerelease ? "prerelease" : "stable"}`)
|
||||
|
||||
const localDir = getLocalPath(channel)
|
||||
const remoteDir = getRemotePath(ROOT, channel, os)
|
||||
// Detect OS
|
||||
|
||||
const updateFileName = getUpdateFileName(os)
|
||||
const applicationFileNames = getApplicationFileNames(os, channel, packageJson.version)
|
||||
let os
|
||||
let osName
|
||||
|
||||
console.log(`Files to upload: ${[updateFileName, ...applicationFileNames] .join (", ")}.`)
|
||||
if (process.argv.includes("--linux") || process.platform === "linux") {
|
||||
os = /** @type {const} */ ("linux")
|
||||
osName = "Linux"
|
||||
} else if (process.argv.includes("--mac") || process.platform === "darwin") {
|
||||
os = /** @type {const} */ ("mac")
|
||||
osName = "macOS"
|
||||
} else if (process.argv.includes("--win") || process.platform === "win32") {
|
||||
os = /** @type {const} */ ("win")
|
||||
osName = "Windows"
|
||||
} else {
|
||||
throw new TypeError(`The target operating system cannot be inferred from the environment.`)
|
||||
}
|
||||
|
||||
console.log(`Detected operating system: ${osName}`)
|
||||
|
||||
// Infer files to upload
|
||||
|
||||
let fileExtensions
|
||||
let updateInfoFileName
|
||||
|
||||
switch (os) {
|
||||
case "win":
|
||||
fileExtensions = [".exe", ".exe.blockmap"]
|
||||
updateInfoFileName = "latest.yml"
|
||||
break
|
||||
case "linux":
|
||||
fileExtensions = [".AppImage", ".tar.gz"]
|
||||
updateInfoFileName = "latest-linux.yml"
|
||||
break
|
||||
case "mac":
|
||||
fileExtensions = [".dmg", ".dmg.blockmap", ".zip", ".zip.blockmap"]
|
||||
updateInfoFileName = "latest-mac.yml"
|
||||
break
|
||||
}
|
||||
|
||||
const fileNames = [
|
||||
...fileExtensions.map(ext => {
|
||||
const chPart = isPrerelease ? "Insider" : ""
|
||||
const osPart = os === "win" ? "Setup" : ""
|
||||
return `Optolith${chPart}${osPart}_${packageJson.version}${ext}`
|
||||
}),
|
||||
updateInfoFileName,
|
||||
]
|
||||
|
||||
console.log(`Files to upload: ${fileNames.join(", ")}.`)
|
||||
|
||||
// Upload files
|
||||
|
||||
const localDir = isPrerelease ? join("dist", "insider") : join("dist")
|
||||
const remoteDir = join(ROOT, isPrerelease ? "insider" : ".", os)
|
||||
|
||||
await run({ host: HOST, username: USERNAME, password: PASSWORD }, async client => {
|
||||
for (const applicationFileName of applicationFileNames) {
|
||||
await upload(client, localDir, remoteDir, applicationFileName)
|
||||
for (const fileName of fileNames) {
|
||||
console.log(`Uploading ${fileName} ...`)
|
||||
await upload(client, localDir, remoteDir, fileName)
|
||||
}
|
||||
|
||||
await upload(client, localDir, remoteDir, updateFileName)
|
||||
})
|
||||
|
||||
console.log(`Uploading files finished successfully.`)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// @ts-check
|
||||
import { join } from "path"
|
||||
|
||||
/**
|
||||
* @param {"prerelease" | "stable"} channel
|
||||
*/
|
||||
export const getLocalPath = channel => {
|
||||
switch (channel) {
|
||||
case "prerelease": return join("dist", "insider")
|
||||
case "stable": return join("dist")
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// @ts-check
|
||||
import { platform } from "os"
|
||||
|
||||
const [_channel, ...args] = process.argv.slice(2)
|
||||
|
||||
/**
|
||||
* @typedef {"win" | "mac" | "linux"} System
|
||||
* @returns {System}
|
||||
*/
|
||||
export const getSystem = () => {
|
||||
if (args.includes("--linux")) {
|
||||
return "linux"
|
||||
} else if (args.includes("--mac")) {
|
||||
return "mac"
|
||||
} else if (args.includes("--win")) {
|
||||
return "win"
|
||||
}
|
||||
|
||||
switch (platform()) {
|
||||
case "win32": return "win"
|
||||
case "darwin": return "mac"
|
||||
default: return "linux"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {System} system
|
||||
*/
|
||||
export const getSystemName = system => {
|
||||
switch (system) {
|
||||
case "win": return "Windows"
|
||||
case "mac": return "macOS"
|
||||
case "linux": return "Linux"
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// @ts-check
|
||||
import { join } from "path"
|
||||
import { join as joinPosix } from "path/posix"
|
||||
import Client from "ssh2-sftp-client"
|
||||
|
||||
/**
|
||||
* @param {Client.ConnectOptions} options
|
||||
* @param {(client: Client) => Promise<void>} action
|
||||
*/
|
||||
export const run = async (options, action) => {
|
||||
const client = new Client()
|
||||
console.log("Connecting to server ...")
|
||||
await client.connect(options)
|
||||
console.log(`Server connection established.`)
|
||||
await action(client)
|
||||
await client.end ()
|
||||
console.log("Closed server connection.")
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Client} client
|
||||
* @param {string} localDir
|
||||
* @param {string} remoteDir
|
||||
* @param {string} fileName
|
||||
*/
|
||||
export const upload = async (client, localDir, remoteDir, fileName) => {
|
||||
console.log(`Uploading ${fileName} ...`);
|
||||
|
||||
await client.fastPut (
|
||||
join (localDir, fileName),
|
||||
joinPosix (remoteDir, fileName),
|
||||
{
|
||||
step: !process.env.CI ? (totalTransferred, _, total) => {
|
||||
const percent = Math.floor (totalTransferred / total * 100)
|
||||
console.log(`Progress: ${percent}%`);
|
||||
} : undefined
|
||||
}
|
||||
)
|
||||
|
||||
console.log(`Upload done: ${fileName}.`);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// @ts-check
|
||||
import { join } from "path/posix"
|
||||
|
||||
/**
|
||||
* @param {"prerelease" | "stable"} channel
|
||||
*/
|
||||
const remoteChannelPath = channel => {
|
||||
switch (channel) {
|
||||
case "prerelease": return "insider"
|
||||
case "stable": return "."
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("./platform.js").System} os
|
||||
*/
|
||||
const remoteOsPath = os => {
|
||||
switch (os) {
|
||||
case "win": return "win"
|
||||
case "linux": return "linux"
|
||||
default: return "mac"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} root
|
||||
* @param {"prerelease" | "stable"} channel
|
||||
* @param {import("./platform.js").System} os
|
||||
*/
|
||||
export const getRemotePath = (root, channel, os) =>
|
||||
join(root, remoteChannelPath(channel), remoteOsPath(os))
|
||||
@@ -0,0 +1,51 @@
|
||||
// @ts-check
|
||||
import { join } from "path"
|
||||
import { join as joinPosix } from "path/posix"
|
||||
import Client from "ssh2-sftp-client"
|
||||
|
||||
/**
|
||||
* Create a new sftp/ssh client and use it for the callback. The connection will
|
||||
* be cleaned up afterwards.
|
||||
* @param {Client.ConnectOptions} options
|
||||
* @param {(client: Client) => Promise<void>} action
|
||||
*/
|
||||
export const run = async (options, action) => {
|
||||
const client = new Client()
|
||||
console.log("Connecting to server ...")
|
||||
await client.connect(options)
|
||||
console.log(`Server connection established.`)
|
||||
await action(client)
|
||||
await client.end()
|
||||
console.log("Closed server connection.")
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a file from a local directory to a remote directory using the given
|
||||
* client.
|
||||
* @param {Client} client
|
||||
* @param {string} localDir
|
||||
* @param {string} remoteDir
|
||||
* @param {string} fileName
|
||||
*/
|
||||
export const upload = async (client, localDir, remoteDir, fileName) => {
|
||||
console.log(`Uploading ${fileName} ...`)
|
||||
|
||||
let didStep = false
|
||||
|
||||
await client.fastPut(join(localDir, fileName), joinPosix(remoteDir, fileName), {
|
||||
step: !process.env.CI
|
||||
? (totalTransferred, _, total) => {
|
||||
if (didStep) {
|
||||
process.stdout.clearLine(0)
|
||||
process.stdout.cursorTo(0)
|
||||
} else {
|
||||
didStep = true
|
||||
}
|
||||
const percent = Math.floor((totalTransferred / total) * 100)
|
||||
process.stdout.write(`Progress: ${percent}%`)
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
|
||||
console.log(`Upload done: ${fileName}`)
|
||||
}
|
||||
Generated
+57
@@ -41,6 +41,7 @@
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/react-redux": "^7.1.28",
|
||||
"@types/semver": "^7.5.4",
|
||||
"@types/ssh2-sftp-client": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
||||
"@typescript-eslint/parser": "^6.9.1",
|
||||
"css-loader": "^6.8.1",
|
||||
@@ -1520,6 +1521,33 @@
|
||||
"integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/ssh2": {
|
||||
"version": "1.11.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.11.15.tgz",
|
||||
"integrity": "sha512-QFPpT9Gamh+oOKWH6uDUxe8izo8NaCJaN5HdYcbCIiS3hs7fB65KAfyGWBVXaXxXLj7IhFam5Q/ZxQ4eIPc/1Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^18.11.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ssh2-sftp-client": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2-sftp-client/-/ssh2-sftp-client-9.0.2.tgz",
|
||||
"integrity": "sha512-Ryi6McklD4aiNpRhYvWxPYFJHVGxrR3ojsTp4HBg/NFnmKOD0iShSKH1b10uO7/UTPS0MH9o5MjuHle2WQQtdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/ssh2": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ssh2/node_modules/@types/node": {
|
||||
"version": "18.18.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz",
|
||||
"integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
|
||||
@@ -12959,6 +12987,35 @@
|
||||
"integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/ssh2": {
|
||||
"version": "1.11.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.11.15.tgz",
|
||||
"integrity": "sha512-QFPpT9Gamh+oOKWH6uDUxe8izo8NaCJaN5HdYcbCIiS3hs7fB65KAfyGWBVXaXxXLj7IhFam5Q/ZxQ4eIPc/1Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "^18.11.18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "18.18.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz",
|
||||
"integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/ssh2-sftp-client": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2-sftp-client/-/ssh2-sftp-client-9.0.2.tgz",
|
||||
"integrity": "sha512-Ryi6McklD4aiNpRhYvWxPYFJHVGxrR3ojsTp4HBg/NFnmKOD0iShSKH1b10uO7/UTPS0MH9o5MjuHle2WQQtdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/ssh2": "*"
|
||||
}
|
||||
},
|
||||
"@types/unist": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/react-redux": "^7.1.28",
|
||||
"@types/semver": "^7.5.4",
|
||||
"@types/ssh2-sftp-client": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
||||
"@typescript-eslint/parser": "^6.9.1",
|
||||
"css-loader": "^6.8.1",
|
||||
|
||||
Reference in New Issue
Block a user