diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3511d90..adb20d8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,6 +51,8 @@ jobs: $hash = CertUtil -hashfile $_.FullName SHA256 | Select-String -Pattern "^[0-9a-fA-F]{64}$" $hash -replace "\s+", "" | Out-File "$($_.FullName).sha256.txt" } + - name: Generate update hashes + run: npm run build:hashes - name: Attach artifacts to release uses: softprops/action-gh-release@v2 with: @@ -114,6 +116,8 @@ jobs: sha256sum "$file" | awk '{print $1}' > "$file.sha256.txt" fi done + - name: Generate update hashes + run: npm run build:hashes - name: Attach artifacts to release uses: softprops/action-gh-release@v2 with: @@ -195,6 +199,8 @@ jobs: shasum -a 256 "$file" | awk '{print $1}' > "$file.sha256.txt" fi done + - name: Generate update hashes + run: npm run build:hashes - name: Attach artifacts to release uses: softprops/action-gh-release@v2 with: diff --git a/build/hashes.ts b/build/hashes.ts new file mode 100644 index 0000000..1c9c4a3 --- /dev/null +++ b/build/hashes.ts @@ -0,0 +1,122 @@ +import crypto from "crypto" +import fs from "fs-extra" +import pathModule from "path" +import YAML from "yaml" +import { pipeline } from "stream" +import { promisify } from "util" + +export const pipelineAsync = promisify(pipeline) + +export const artifacts = [ + "Filen_win.exe", + "Filen_win_arm64.exe", + "Filen_win_x64.exe", + "Filen_linux_arm64.AppImage", + "Filen_linux_amd64.deb", + "Filen_linux_x86_64.rpm", + "Filen_linux_x86_64.AppImage", + "Filen_linux_amd64.deb", + "Filen_linux_x86_64.rpm", + "Filen_mac_x64.zip", + "Filen_mac_arm64.zip", + "Filen_mac_x64.dmg", + "Filen_mac_arm64.dmg" +] + +export const ymls = ["latest-mac.yml", "latest-linux-arm64.yml", "latest-linux.yml", "latest.yml"] + +export type LatestFile = { + version: string + files: { + url: string + sha512: string + size: number + isAdminRightsRequired?: boolean + }[] + path: string + sha512: string + releaseDate: string +} + +export async function hashFile(path: string): Promise { + const hasher = crypto.createHash("sha512") + + await pipelineAsync(fs.createReadStream(path), hasher) + + return hasher.digest("base64") +} + +export default async function main(): Promise { + const existingArtifacts = artifacts.filter(artifact => { + return fs.existsSync(pathModule.join(__dirname, "..", "prod", artifact)) + }) + + const existingYMLs = ymls.filter(yml => { + return fs.existsSync(pathModule.join(__dirname, "..", "prod", yml)) + }) + + console.log("Listing YAML files") + + for (const file of existingYMLs) { + const path = pathModule.join(__dirname, "..", "prod", file) + const content: LatestFile = YAML.parse(fs.readFileSync(path, "utf-8")) + + console.log("Listing files inside", file) + + for (let i = 0; i < content.files.length; i++) { + if (existingArtifacts.includes(content.files[i].url)) { + console.log("Found", content.files[i].url, ", hashing...") + + const artifactPath = pathModule.join(__dirname, "..", "prod", content.files[i].url) + const hash = await hashFile(artifactPath) + + console.log(content.files[i].url, hash) + + console.log("Old", content.files[i].sha512) + console.log("New", hash) + + content.files[i].sha512 = hash + + console.log(content.files[i].url, "writing...") + + fs.writeFileSync(path, YAML.stringify(content)) + + console.log(content.files[i].url, "done!") + } + } + + console.log("Modifying root entry of", file) + + if (existingArtifacts.includes(content.path)) { + console.log("Found", content.path, ", hashing...") + + const artifactPath = pathModule.join(__dirname, "..", "prod", content.path) + const hash = await hashFile(artifactPath) + + console.log(content.path, hash) + + console.log("Old", content.sha512) + console.log("New", hash) + + content.sha512 = hash + + console.log(content.path, "writing...") + + fs.writeFileSync(path, YAML.stringify(content)) + + console.log(content.path, "done!") + } + } + + console.log("Done") +} + +main() + .then(() => { + process.exit(0) + }) + .catch(err => { + console.error(err) + + process.exit(1) + }) diff --git a/package-lock.json b/package-lock.json index 9e22343..ad8cd57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,8 @@ "ts-node": "^10.9.2", "tsx": "^4.19.2", "typescript": "^5.3.3", - "wait-on": "^8.0.1" + "wait-on": "^8.0.1", + "yaml": "^2.6.0" }, "engines": { "node": ">=20" @@ -20803,7 +20804,6 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index e488322..fcbb55a 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "build:mac": "npm run build && electron-builder -m --publish never", "build:win": "npm run build && electron-builder -w --publish never", "build:linux": "npm run build && electron-builder -l --publish never", + "build:hashes": "tsx ./build/hashes.js", "install:filen": "npm install @filen/web@latest @filen/s3@latest @filen/webdav@latest @filen/sdk@latest @filen/sync@latest @filen/network-drive@latest" }, "repository": { @@ -60,7 +61,8 @@ "ts-node": "^10.9.2", "tsx": "^4.19.2", "typescript": "^5.3.3", - "wait-on": "^8.0.1" + "wait-on": "^8.0.1", + "yaml": "^2.6.0" }, "dependencies": { "@filen/network-drive": "^0.9.28",