mirror of
https://github.com/ivabus/gui
synced 2025-04-23 14:07:14 +03:00
dev builds with own publishing endpoint (#578)
* #576 test dev builds cd * #576 dynamically set auto-update publish url * unminify code * #576 different dev build from release build --------- Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
ea21cc9962
commit
f1d9433fa1
13 changed files with 1560 additions and 1050 deletions
48
.github/get-dev-version.js
vendored
Normal file
48
.github/get-dev-version.js
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
const {Firestore} = require('@google-cloud/firestore');
|
||||||
|
const firestore = new Firestore();
|
||||||
|
const [commitHash, pkgVersion] = process.argv.slice(2);
|
||||||
|
|
||||||
|
async function getBumpVersion(pkg_version, hash) {
|
||||||
|
const pairsCollection = firestore.collection('pairs');
|
||||||
|
let bump_version;
|
||||||
|
|
||||||
|
await firestore.runTransaction(async (t) => {
|
||||||
|
const query = pairsCollection.where('pkg_version', '==', pkg_version).where('hash', '==', hash);
|
||||||
|
const querySnapshot = await t.get(query);
|
||||||
|
|
||||||
|
if (!querySnapshot.empty) {
|
||||||
|
// Pairing exists
|
||||||
|
bump_version = querySnapshot.docs[0].data().bump_version;
|
||||||
|
} else {
|
||||||
|
// Pairing does not exist
|
||||||
|
const latestDocSnapshot = await t.get(pairsCollection.where('pkg_version', '==', pkg_version).orderBy('created_at', 'desc').limit(1));
|
||||||
|
if (!latestDocSnapshot.empty) {
|
||||||
|
const latestDoc = latestDocSnapshot.docs[0];
|
||||||
|
const latestBumpVersion = latestDoc.data().bump_version;
|
||||||
|
const parts = latestBumpVersion.split('.');
|
||||||
|
parts[2] = String(Number(parts[2]) + 1); // Bump the version
|
||||||
|
bump_version = parts.join('.');
|
||||||
|
} else {
|
||||||
|
// Collection is empty, start with default bump_version
|
||||||
|
bump_version = pkg_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the new pairing
|
||||||
|
await t.set(pairsCollection.doc(), {
|
||||||
|
pkg_version: pkg_version,
|
||||||
|
hash: hash,
|
||||||
|
created_at: Firestore.Timestamp.now(),
|
||||||
|
bump_version: bump_version
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return bump_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the function
|
||||||
|
getBumpVersion(pkgVersion, commitHash).then(bump_version => {
|
||||||
|
console.log(`::set-output name=version::${bump_version}`);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
48
.github/workflows/build-sign-notarize.yml
vendored
48
.github/workflows/build-sign-notarize.yml
vendored
|
@ -22,35 +22,21 @@ on:
|
||||||
s3-custom-notarized-installers-key:
|
s3-custom-notarized-installers-key:
|
||||||
description: 'The S3 build key includes the installer files: [zip, dmg, etc, yml] from notarization strategy done outside of electron'
|
description: 'The S3 build key includes the installer files: [zip, dmg, etc, yml] from notarization strategy done outside of electron'
|
||||||
value: ${{ jobs.notarize-mac-installers.outputs.s3-installers-key }}
|
value: ${{ jobs.notarize-mac-installers.outputs.s3-installers-key }}
|
||||||
|
build-version:
|
||||||
|
description: 'The version of the build generated for dev'
|
||||||
|
value: ${{ jobs.build.outputs.build-version }}
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
outputs:
|
outputs:
|
||||||
s3-artifacts-key: ${{ steps.s3-artifact-uploader.outputs.key }}
|
s3-artifacts-key: ${{ steps.s3-artifact-uploader.outputs.key }}
|
||||||
|
build-version: ${{ steps.gui-version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: teaxyz/setup@v0
|
- uses: teaxyz/setup@v0
|
||||||
with:
|
with:
|
||||||
version: 0.26.2
|
version: 0.26.2
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: get gui version
|
|
||||||
id: gui-version
|
|
||||||
run: |
|
|
||||||
tea +stedolan.github.io/jq
|
|
||||||
export version=$(echo $(cat modules/desktop/package.json) | jq --raw-output .version)
|
|
||||||
export postfix=
|
|
||||||
release="release"
|
|
||||||
if [ $prefix == $release ];
|
|
||||||
then
|
|
||||||
echo "no postfix"
|
|
||||||
else
|
|
||||||
echo "dev"
|
|
||||||
export postfix=-dev
|
|
||||||
fi
|
|
||||||
echo "version=$version$postfix" >> $GITHUB_OUTPUT
|
|
||||||
env:
|
|
||||||
prefix: ${{ inputs.s3-prefix }}
|
|
||||||
|
|
||||||
- name: cache node_modules build
|
- name: cache node_modules build
|
||||||
# TODO: cache issue in our self-hosted macos runner ESPIPE: invalid seek, read
|
# TODO: cache issue in our self-hosted macos runner ESPIPE: invalid seek, read
|
||||||
# but its ok to ignore, its still the fastest builder
|
# but its ok to ignore, its still the fastest builder
|
||||||
|
@ -73,9 +59,32 @@ jobs:
|
||||||
./modules/desktop/.svelte-kit
|
./modules/desktop/.svelte-kit
|
||||||
./modules/desktop/build
|
./modules/desktop/build
|
||||||
|
|
||||||
|
- name: get gui version
|
||||||
|
id: gui-version
|
||||||
|
run: |
|
||||||
|
tea +stedolan.github.io/jq
|
||||||
|
export version=$(echo $(cat modules/desktop/package.json) | jq --raw-output .version)
|
||||||
|
export postfix=
|
||||||
|
release="release"
|
||||||
|
if [ $prefix == $release ];
|
||||||
|
then
|
||||||
|
echo "no postfix"
|
||||||
|
else
|
||||||
|
echo $google_service_account > sa.json
|
||||||
|
export GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/sa.json"
|
||||||
|
tea -E pnpm install
|
||||||
|
tea node .github/get-dev-version.js $hash $version
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
prefix: ${{ inputs.s3-prefix }}
|
||||||
|
google_service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}
|
||||||
|
hash: ${{ github.sha }}
|
||||||
|
|
||||||
- name: build dev
|
- name: build dev
|
||||||
if: inputs.s3-prefix != 'release'
|
if: inputs.s3-prefix != 'release'
|
||||||
run: tea -SE xc dist
|
run: |
|
||||||
|
jq ".version=\"$PUBLIC_VERSION\"" modules/desktop/package.json > temp.json && mv temp.json modules/desktop/package.json
|
||||||
|
tea -SE xc dist
|
||||||
env:
|
env:
|
||||||
SYNC_I18N: 1
|
SYNC_I18N: 1
|
||||||
PUBLIC_MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_PROJECT_TOKEN }}
|
PUBLIC_MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_PROJECT_TOKEN }}
|
||||||
|
@ -86,6 +95,7 @@ jobs:
|
||||||
CSC_LINK: ${{ secrets.GUI_APPLE_CERTIFICATE }}
|
CSC_LINK: ${{ secrets.GUI_APPLE_CERTIFICATE }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.GUI_APPLE_CERTIFICATE_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.GUI_APPLE_CERTIFICATE_PASSWORD }}
|
||||||
CSC_NAME: ${{ secrets.APPLE_IDENTITY_NO_PREFIX }}
|
CSC_NAME: ${{ secrets.APPLE_IDENTITY_NO_PREFIX }}
|
||||||
|
PUBLISH_URL: "https://gui.tea.xyz/dev"
|
||||||
|
|
||||||
# slower build but dmg output is much nicer looking
|
# slower build but dmg output is much nicer looking
|
||||||
- name: build release
|
- name: build release
|
||||||
|
|
19
.github/workflows/main.yml
vendored
19
.github/workflows/main.yml
vendored
|
@ -119,12 +119,9 @@ jobs:
|
||||||
arm64: ${{ steps.app_files.outputs.dmg_arm64 }}
|
arm64: ${{ steps.app_files.outputs.dmg_arm64 }}
|
||||||
x86: ${{ steps.app_files.outputs.dmg_x86 }}
|
x86: ${{ steps.app_files.outputs.dmg_x86 }}
|
||||||
run: |
|
run: |
|
||||||
aws s3 cp \
|
cd dist && \
|
||||||
"dist/$arm64" \
|
aws s3 sync . \
|
||||||
"s3://preview.gui.tea.xyz/main/$arm64"
|
"s3://preview.gui.tea.xyz/dev/"
|
||||||
aws s3 cp \
|
|
||||||
"dist/$x86" \
|
|
||||||
"s3://preview.gui.tea.xyz/main/$x86"
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
@ -136,7 +133,8 @@ jobs:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
PLATFORM: darwin-aarch64
|
PLATFORM: darwin-aarch64
|
||||||
EXT: dmg
|
EXT: dmg
|
||||||
DOWNLOAD_URL: http://preview.gui.tea.xyz.s3-website-us-east-1.amazonaws.com/main/${{ steps.app_files.outputs.dmg_arm64 }}
|
VERSION: ${{ needs.build_desktop.outputs.build-version }}-dev
|
||||||
|
DOWNLOAD_URL: http://preview.gui.tea.xyz.s3-website-us-east-1.amazonaws.com/dev/${{ steps.app_files.outputs.dmg_arm64 }}
|
||||||
|
|
||||||
- name: Slack Notification X86
|
- name: Slack Notification X86
|
||||||
run: ./.github/notify-slack.js
|
run: ./.github/notify-slack.js
|
||||||
|
@ -144,4 +142,9 @@ jobs:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
PLATFORM: darwin-x86+64
|
PLATFORM: darwin-x86+64
|
||||||
EXT: dmg
|
EXT: dmg
|
||||||
DOWNLOAD_URL: http://preview.gui.tea.xyz.s3-website-us-east-1.amazonaws.com/main/${{ steps.app_files.outputs.dmg_x86 }}
|
VERSION: ${{ needs.build_desktop.outputs.build-version }}-dev
|
||||||
|
DOWNLOAD_URL: http://preview.gui.tea.xyz.s3-website-us-east-1.amazonaws.com/dev/${{ steps.app_files.outputs.dmg_x86 }}
|
||||||
|
- run: |
|
||||||
|
aws cloudfront create-invalidation \
|
||||||
|
--distribution-id ${{ secrets.AWS_CF_GUI_RELEASE_ID }} \
|
||||||
|
--paths '/dev/latest-mac.yml'
|
|
@ -56,6 +56,6 @@ module.exports = {
|
||||||
// this determines the configuration of the auto-update feature
|
// this determines the configuration of the auto-update feature
|
||||||
publish: {
|
publish: {
|
||||||
provider: "generic",
|
provider: "generic",
|
||||||
url: "https://gui.tea.xyz/release"
|
url: process.env.PUBLISH_URL || "https://gui.tea.xyz/release"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { type AppUpdater, autoUpdater } from "electron-updater";
|
import { type AppUpdater, autoUpdater } from "electron-updater";
|
||||||
import log from "./logger";
|
import log from "./logger";
|
||||||
import { MainWindowNotifier } from "./types";
|
import { MainWindowNotifier } from "./types";
|
||||||
|
import { getTeaPath } from "./tea-dir";
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
type AutoUpdateStatus = {
|
type AutoUpdateStatus = {
|
||||||
status: "up-to-date" | "available" | "ready";
|
status: "up-to-date" | "available" | "ready";
|
||||||
|
@ -30,6 +33,8 @@ export function checkUpdater(notifier: MainWindowNotifier): AppUpdater {
|
||||||
checkForUpdates();
|
checkForUpdates();
|
||||||
}, 1000 * 60 * 30); // check for updates every 30 minutes
|
}, 1000 * 60 * 30); // check for updates every 30 minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPublishURL();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
|
@ -103,3 +108,15 @@ autoUpdater.on("update-downloaded", (info) => {
|
||||||
log.info("update-downloaded");
|
log.info("update-downloaded");
|
||||||
sendStatusToWindow({ status: "ready", version: info.version });
|
sendStatusToWindow({ status: "ready", version: info.version });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const isDev = () => fs.existsSync(path.join(getTeaPath(), "tea.xyz/gui/dev"));
|
||||||
|
|
||||||
|
async function setPublishURL() {
|
||||||
|
try {
|
||||||
|
const feedUrl = `https://gui.tea.xyz/${isDev() ? "dev" : "release"}`;
|
||||||
|
log.info(`feedUrl$: ${feedUrl}`);
|
||||||
|
autoUpdater.setFeedURL(feedUrl);
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { installPackage, openPackageEntrypointInTerminal, syncPantry } from "./c
|
||||||
|
|
||||||
import { initializeTeaCli, cliInitializationState } from "./initialize";
|
import { initializeTeaCli, cliInitializationState } from "./initialize";
|
||||||
|
|
||||||
import { getAutoUpdateStatus, getUpdater } from "./auto-updater";
|
import { getAutoUpdateStatus, getUpdater, isDev } from "./auto-updater";
|
||||||
|
|
||||||
import { loadPackageCache, writePackageCache } from "./package";
|
import { loadPackageCache, writePackageCache } from "./package";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
@ -217,4 +217,13 @@ export default function initializeHandlers({ notifyMainWindow }: HandlerOptions)
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("is-dev", async () => {
|
||||||
|
try {
|
||||||
|
return isDev();
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export const getTeaPath = () => {
|
||||||
teaPath = execSync("tea --prefix", { encoding: "utf8" }).trim();
|
teaPath = execSync("tea --prefix", { encoding: "utf8" }).trim();
|
||||||
log.info(teaPath);
|
log.info(teaPath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.info("Could not run tea --prefix. Using default path.", info);
|
log.info("Could not run tea --prefix. Using default path.");
|
||||||
teaPath = path.join(homePath, "./.tea");
|
teaPath = path.join(homePath, "./.tea");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ const config = {
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
outDir: "dist",
|
outDir: "dist",
|
||||||
assetsDir: ".",
|
assetsDir: ".",
|
||||||
minify: process.env.MODE !== "development",
|
minify: false,
|
||||||
lib: {
|
lib: {
|
||||||
entry: "electron.ts",
|
entry: "electron.ts",
|
||||||
formats: ["cjs"]
|
formats: ["cjs"]
|
||||||
|
|
|
@ -5,9 +5,15 @@
|
||||||
import { t } from "$libs/translations";
|
import { t } from "$libs/translations";
|
||||||
|
|
||||||
import TopBarMenu from "./top-bar-menu.svelte";
|
import TopBarMenu from "./top-bar-menu.svelte";
|
||||||
import { topbarDoubleClick } from "$libs/native-electron";
|
import { isDev, topbarDoubleClick } from "$libs/native-electron";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
let { nextPath, prevPath } = navStore;
|
let { nextPath, prevPath } = navStore;
|
||||||
|
|
||||||
|
let dev = false;
|
||||||
|
onMount(async () => {
|
||||||
|
dev = await isDev();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header
|
<header
|
||||||
|
@ -21,7 +27,7 @@
|
||||||
<i class="icon-tea-logo-iconasset-1" />
|
<i class="icon-tea-logo-iconasset-1" />
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<p class="px-2 text-gray">beta</p>
|
<p class="px-2 text-gray">{dev ? "dev" : "beta"}</p>
|
||||||
<button
|
<button
|
||||||
on:click={navStore.back}
|
on:click={navStore.back}
|
||||||
class:active={$prevPath}
|
class:active={$prevPath}
|
||||||
|
|
|
@ -269,3 +269,12 @@ export const pollDeviceSession = async () => {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isDev = async () => {
|
||||||
|
try {
|
||||||
|
return await ipcRenderer.invoke("is-dev");
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -334,6 +334,8 @@ export const getSession = async (): Promise<Session | null> => {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isDev = async () => true;
|
||||||
|
|
||||||
export const updateSession = async (session: Partial<Session>) => {
|
export const updateSession = async (session: Partial<Session>) => {
|
||||||
console.log(session);
|
console.log(session);
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@crowdin/ota-client": "^0.7.0",
|
"@crowdin/ota-client": "^0.7.0",
|
||||||
|
"@google-cloud/firestore": "^6.5.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"yaml": "^2.2.1"
|
"yaml": "^2.2.1"
|
||||||
}
|
}
|
||||||
|
|
2439
pnpm-lock.yaml
2439
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue