-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Apple Silicon macOS test/builds (#3077)
- Loading branch information
Showing
13 changed files
with
974 additions
and
321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,8 @@ jobs: | |
if: ${{ needs.check_latest.outputs.latest_sha != github.sha }} | ||
strategy: | ||
matrix: | ||
platform: [windows-2019, macos-12, ubuntu-20.04] | ||
# macos-12 is is Intel-based (x64), macos-14 is Apple Silicon (arm64) | ||
platform: [windows-2019, macos-12, macos-14, ubuntu-20.04] | ||
|
||
runs-on: ${{ matrix.platform }} | ||
steps: | ||
|
@@ -67,6 +68,14 @@ jobs: | |
cert_p12: ${{ secrets.APPLE_DEVELOPER_ID_CERT_P12_BASE64 }} | ||
cert_passphrase: ${{ secrets.APPLE_DEVELOPER_ID_CERT_PASSPHRASE }} | ||
|
||
- name: Merge latest-mac.yml Mac release files for x64/arm64 | ||
if: runner.os == 'macOS' | ||
run: | | ||
node apps/zui/scripts/merge-mac-release-files.mjs | ||
env: | ||
GH_TOKEN: ${{ secrets.PAT_TOKEN }} | ||
shell: bash | ||
|
||
- name: Inform Slack users of failure | ||
uses: tiloio/[email protected] | ||
if: ${{ failure() }} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?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/> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
// Based on https://github.com/electron-userland/electron-builder/issues/5592#issuecomment-2004803764 | ||
import { Octokit } from "octokit" | ||
import pkg from '../package.json' assert {type: 'json'} | ||
import { TextDecoder } from 'node:util' | ||
import fs from 'node:fs' | ||
import { Readable } from 'node:stream' | ||
import { Buffer } from 'node:buffer' | ||
import yaml from 'js-yaml' | ||
|
||
const token = process.env.GH_TOKEN | ||
|
||
const client = new Octokit({ | ||
auth: token | ||
}) | ||
|
||
// These are derived from settings in package.json so the script will work on | ||
// both regular Zui and Zui Insiders. | ||
const OWNER = pkg.repository.split('/')[3] | ||
const REPO = pkg.repository.split('/')[4] | ||
const PRODUCT_NAME= pkg.productName.replaceAll(' ', '-') | ||
const URL = `/repos/${OWNER}/${REPO}/releases` | ||
const VERSION = pkg.version | ||
const RELEASE_NAME = (PRODUCT_NAME == 'Zui') ? 'v' + VERSION : VERSION | ||
const FILE_NAME = 'latest-mac.yml' | ||
const LOCAL_FILE_PATH = `dist/apps/zui/${FILE_NAME}` | ||
|
||
const mergeFiles = (intel, arm) => { | ||
const intelObject = yaml.load(intel) | ||
const armObject = yaml.load(arm) | ||
|
||
const mergedObject = { | ||
...intelObject, | ||
files: [...intelObject.files, ...armObject.files] | ||
} | ||
|
||
// avoids moving the sha512 checksum into its own line | ||
const dumpOptions = { lineWidth: -1 } | ||
|
||
return yaml.dump(mergedObject, dumpOptions) | ||
} | ||
|
||
const getPlatformFromLatestMacYml = (content) => { | ||
const intelRe = `${PRODUCT_NAME}-${VERSION}-x64.dmg` | ||
const armRe = `${PRODUCT_NAME}-${VERSION}-arm64.dmg` | ||
const isIntel = content.includes(intelRe) | ||
const isArm = content.includes(armRe) | ||
|
||
if (isIntel && isArm) return 'both' | ||
if (isIntel && !isArm) return 'intel' | ||
if (!isIntel && isArm) return 'arm' | ||
|
||
return 'none' | ||
} | ||
|
||
(async () => { | ||
const allReleases = await client.request(`GET ${URL}`) | ||
const currentRelease = allReleases.data.find(release => { | ||
return release.name === RELEASE_NAME | ||
}) | ||
|
||
if (!currentRelease) { | ||
console.log('No release found. Skipping merge') | ||
return | ||
} | ||
console.log('Release found') | ||
|
||
if (!fs.existsSync(LOCAL_FILE_PATH)) { | ||
console.log(`[local] could not find ${FILE_NAME}. Skipping merge`) | ||
return | ||
} | ||
console.log(`[local] ${FILE_NAME} found`) | ||
|
||
const localLatestMacYmlContent = fs.readFileSync(LOCAL_FILE_PATH, { encoding: 'utf8' }) | ||
|
||
const localPlatform = getPlatformFromLatestMacYml(localLatestMacYmlContent) | ||
|
||
if (localPlatform === 'none' || localPlatform === 'both') { | ||
console.log(`[local] ${FILE_NAME} invalid. Platform: ${localPlatform}. Skipping merge`) | ||
return | ||
} | ||
console.log(`[local] ${FILE_NAME} valid: Platform: ${localPlatform}`) | ||
|
||
const localPlatformPresentRemotely = currentRelease.assets.find(asset => asset.name === `latest-mac-${localPlatform}.yml`) | ||
|
||
if (localPlatformPresentRemotely) { | ||
try { | ||
await client.request(`DELETE ${URL}/assets/${localPlatformPresentRemotely.id}`) | ||
console.log(`[remote] deleted latest-mac-${localPlatform}.yml`) | ||
} catch(e) { | ||
console.log(`[remote] error deleting latest-mac-${localPlatform}.yml. Skipping merge`) | ||
console.log(e) | ||
return | ||
} | ||
} | ||
|
||
const uploadUrl = currentRelease.upload_url | ||
try { | ||
await client.rest.repos.uploadReleaseAsset({ | ||
url: uploadUrl, | ||
headers: { | ||
'content-type': 'application/octet-stream', | ||
'content-length': Buffer.byteLength(localLatestMacYmlContent), | ||
}, | ||
name: `latest-mac-${localPlatform}.yml`, | ||
data: Readable.from(localLatestMacYmlContent), | ||
}) | ||
console.log(`[remote] latest-mac-${localPlatform}.yml uploaded`) | ||
} catch(e) { | ||
console.log(`[remote] error uploading latest-mac-${localPlatform}.yml. Skipping merge`) | ||
console.log(e) | ||
return | ||
} | ||
|
||
const remotePlatform = localPlatform === 'intel' ? 'arm' : 'intel' | ||
|
||
const remotePlatformFileExists = currentRelease.assets.find(asset => asset.name === `latest-mac-${remotePlatform}.yml`) | ||
|
||
if (!remotePlatformFileExists) { | ||
console.log(`[remote] latest-mac-${remotePlatform}.yml does not exist. Skipping merge`) | ||
return | ||
} | ||
console.log(`[remote] latest-mac-${remotePlatform}.yml found`) | ||
|
||
let remotePlatformFile | ||
|
||
try { | ||
remotePlatformFile = await client.request(`GET ${URL}/assets/${remotePlatformFileExists.id}`, { | ||
headers: { | ||
accept: 'application/octet-stream' | ||
} | ||
}) | ||
console.log(`[remote] latest-mac-${remotePlatform}.yml downloaded`) | ||
} catch(e) { | ||
console.log(`[remote] error downloading latest-mac-${remotePlatform}.yml. Skipping merge`) | ||
console.log(e) | ||
return | ||
} | ||
|
||
const remoteLatestMacYmlContent = new TextDecoder().decode(remotePlatformFile.data) | ||
|
||
const originalAsset = currentRelease.assets.find(asset => asset.name === FILE_NAME) | ||
|
||
if (!originalAsset) { | ||
console.log(`[remote] ${FILE_NAME} not found. Skipping merge`) | ||
return | ||
} | ||
console.log(`[remote] ${FILE_NAME} found`) | ||
|
||
try { | ||
await client.request(`DELETE ${URL}/assets/${originalAsset.id}`) | ||
console.log(`[remote] deleted ${FILE_NAME}`) | ||
} catch(e) { | ||
console.log(`[remote] error deleting ${FILE_NAME}. Skipping merge`) | ||
console.log(e) | ||
return | ||
} | ||
|
||
const mergedContent = remotePlatform === 'intel' ? mergeFiles(remoteLatestMacYmlContent, localLatestMacYmlContent) : mergeFiles(localLatestMacYmlContent, remoteLatestMacYmlContent) | ||
|
||
try { | ||
await client.rest.repos.uploadReleaseAsset({ | ||
url: uploadUrl, | ||
headers: { | ||
'content-type': 'application/octet-stream', | ||
'content-length': Buffer.byteLength(mergedContent), | ||
}, | ||
name: FILE_NAME, | ||
data: Readable.from(mergedContent), | ||
}) | ||
console.log(`[remote] uploaded merged ${FILE_NAME}`) | ||
} catch(e) { | ||
console.log(`[remote] error uploading merged ${FILE_NAME}. Skipping merge`) | ||
console.log(e) | ||
return | ||
} | ||
|
||
// cleanup | ||
const updatedRelease = await client.request(`GET ${URL}`) | ||
const updatedCurrentRelease = updatedRelease.data.find(release => release.name === RELEASE_NAME) | ||
|
||
const assetsToClean = updatedCurrentRelease.assets.filter(asset => { | ||
return asset.name === `latest-mac-arm.yml` || asset.name === `latest-mac-intel.yml` | ||
}) | ||
|
||
for (const assetToClean of assetsToClean) { | ||
try { | ||
await client.request(`DELETE ${URL}/assets/${assetToClean.id}`) | ||
console.log(`[remote:cleanup] deleted ${assetToClean.name}`) | ||
} catch(e) { | ||
console.log(`[remote:cleanup] error deleting ${assetToClean.name}`) | ||
console.log(e) | ||
} | ||
} | ||
|
||
console.log('Merge complete') | ||
})() |
Oops, something went wrong.