remix-project mirror
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
remix-project/apps/remix-ide/ci/update_desktop_release_asse...

244 lines
7.2 KiB

8 months ago
import { Octokit } from 'octokit'
10 months ago
import * as fs from 'fs'
import * as path from 'path'
10 months ago
import YAML from 'yaml'
import crypto from 'crypto'
10 months ago
7 months ago
const owner = 'remix-project-org'
6 months ago
let repo = 'remix-desktop'
10 months ago
const headers = {
10 months ago
'X-GitHub-Api-Version': '2022-11-28',
10 months ago
}
6 months ago
const version = getVersionFromPackageJson()
let channel = 'latest'
if(version.includes('beta')) {
channel = 'beta'
}
if(version.includes('alpha')) {
channel = 'alpha'
}
if(version.includes('insiders')) {
channel = 'insiders'
}
6 months ago
if(channel !== 'latest') repo = `remix-desktop-${channel}`
6 months ago
10 months ago
const octokit = new Octokit({
7 months ago
auth: process.env.GH_TOKEN_DESKTOP_PUBLISH,
10 months ago
})
async function getAllReleases() {
10 months ago
const releases = await octokit.request('GET /repos/{owner}/{repo}/releases', {
owner: owner,
repo: repo,
10 months ago
headers: headers,
10 months ago
})
return releases.data
10 months ago
}
10 months ago
async function uploadReleaseAsset(release, name, file) {
const upload_url = release.upload_url
10 months ago
console.log(`Uploading ${name} to ${upload_url}`)
8 months ago
if (fs.existsSync(file)) {
octokit.request({
method: "POST",
url: upload_url,
headers: {
"content-type": "text/plain",
},
data: fs.readFileSync(file),
name,
label: name
});
}else{
console.log(`File ${file} does not exist. Skipping...`)
}
10 months ago
}
6 months ago
function getVersionFromPackageJson() {
10 months ago
// ignore ts error
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageJson = require(__dirname + '/../../../apps/remixdesktop/package.json')
return packageJson.version
10 months ago
}
10 months ago
async function readReleaseFilesFromLocalDirectory() {
const directoryPath = path.join(__dirname, '../../../release')
const files = fs.readdirSync(directoryPath)
return files
10 months ago
}
10 months ago
async function removeAsset(asset) {
await octokit.request('DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}', {
10 months ago
owner: owner,
repo: repo,
10 months ago
asset_id: asset.id,
headers: headers,
10 months ago
})
10 months ago
}
10 months ago
10 months ago
async function hashFile(file): Promise<string> {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha512').setEncoding('base64');
// hash.on('error', reject).setEncoding(encoding);
fs.createReadStream(
file,
Object.assign({}, {}, {
highWaterMark: 1024 * 1024,
/* better to use more memory but hash faster */
})
)
.on('error', reject)
.on('end', () => {
hash.end();
console.log('hash done');
console.log(hash.read());
resolve(hash.digest('base64'));
})
.pipe(
hash,
{
end: false,
}
);
});
}
10 months ago
async function main() {
6 months ago
10 months ago
const allReleases = await getAllReleases()
6 months ago
10 months ago
console.log(`preparing release version: ${version}`)
let release
allReleases.find((r) => {
if (r.tag_name === `v${version}`) {
release = r
}
})
if (!release) {
console.log('No release found.')
10 months ago
// create release
console.log(`Creating release ${version}`)
10 months ago
const r = await octokit.request('POST /repos/{owner}/{repo}/releases', {
10 months ago
owner: owner,
repo: repo,
tag_name: `v${version}`,
name: `${version}`,
draft: true,
6 months ago
prerelease: true,
10 months ago
headers: headers,
})
10 months ago
release = r.data
10 months ago
}
10 months ago
10 months ago
let ymlFiles = await readReleaseFilesFromLocalDirectory()
6 months ago
ymlFiles = ymlFiles.filter((file) => file.endsWith('.yml') && file.startsWith('latest'))
10 months ago
console.log(`Found ${ymlFiles.length} yml files to upload`)
// read and parse yml latest files
// the yml files contain the sha512 hash and file size of the executable
// we need to recalculate the hash and file size of the executable
// and update the yml files
// this is because the executable is resigned after the yml files are created
for (const file of ymlFiles) {
const content = fs.readFileSync(path.join(__dirname, '../../../release', file), 'utf8')
const parsed = YAML.parse(content)
8 months ago
const hashes: {
10 months ago
url: string,
sha512: string,
size: number
}[] = []
8 months ago
if (parsed.files) {
10 months ago
console.log(`Found`, parsed.files)
for (const f of parsed.files) {
const executable = f.url
const exists = fs.existsSync(path.join(__dirname, '../../../release', executable))
if (!exists) {
console.log(`File ${executable} does not exist on local fs. Skipping...`)
continue
8 months ago
} else {
10 months ago
console.log(`File ${executable} exists on local fs. Recalculating hash...`)
// calculate sha512 hash of executable
8 months ago
const hash: string = await hashFile(path.join(__dirname, '../../../release', executable))
10 months ago
console.log(hash)
// calculate file size of executable
const stats = fs.statSync(path.join(__dirname, '../../../release', executable))
const fileSizeInBytes = stats.size
console.log(fileSizeInBytes)
hashes.push({
url: executable,
sha512: hash,
size: fileSizeInBytes
})
8 months ago
if (parsed.path === executable) {
10 months ago
parsed.sha512 = hash
parsed.size = fileSizeInBytes
}
}
}
}
console.log(hashes)
parsed.files = hashes
const newYml = YAML.stringify(parsed)
fs.writeFileSync(path.join(__dirname, '../../../release', file), newYml)
}
10 months ago
let files = await readReleaseFilesFromLocalDirectory()
10 months ago
8 months ago
try {
6 months ago
if (fs.existsSync(path.join(__dirname, '../../../release', `latest-mac-arm64.yml`)) && fs.existsSync(path.join(__dirname, '../../../release', `latest-mac-x64.yml`))) {
8 months ago
// combine the two files
6 months ago
const macArm64 = fs.readFileSync(path.join(__dirname, '../../../release', `latest-mac-arm64.yml`), 'utf8')
const mac = fs.readFileSync(path.join(__dirname, '../../../release', `latest-mac-x64.yml`), 'utf8')
8 months ago
const parsedMacArm64 = YAML.parse(macArm64)
const parsedMac = YAML.parse(mac)
8 months ago
console.log(parsedMacArm64)
console.log(parsedMac)
8 months ago
const combined = {
...parsedMac,
8 months ago
files: [
8 months ago
...parsedMac.files,
...parsedMacArm64.files
8 months ago
]
8 months ago
}
console.log(combined)
const newYml = YAML.stringify(combined)
6 months ago
fs.writeFileSync(path.join(__dirname, '../../../release', `latest-mac.yml`), newYml)
8 months ago
// remove the arm64 file
6 months ago
fs.unlinkSync(path.join(__dirname, '../../../release', `latest-mac-arm64.yml`))
fs.unlinkSync(path.join(__dirname, '../../../release', `latest-mac-x64.yml`))
8 months ago
}
} catch (e) {
console.log(e)
}
8 months ago
files = await readReleaseFilesFromLocalDirectory()
6 months ago
files = files.filter((file) => file.endsWith('.zip') || file.endsWith('.dmg') || file.endsWith('.exe') || file.endsWith('.AppImage') || file.endsWith('.snap') || file.endsWith('.deb') || file.startsWith(`latest`))
10 months ago
console.log(`Found ${files.length} files to upload`)
10 months ago
console.log(files)
if (!release.draft) {
10 months ago
console.log(`Release ${version} is not a draft. Aborting...`)
10 months ago
return
}
10 months ago
// upload files
for (const file of files) {
// check if it is already uploaded
const asset = release.assets.find((a) => a.label === file)
if (asset) {
console.log(`Asset ${file} already uploaded... replacing it`)
// remove it first
await removeAsset(asset)
}
await uploadReleaseAsset(release, file, path.join(__dirname, '../../../release', file))
}
10 months ago
}
10 months ago
main()