feat: add server deployment, desktop builds, and CI/CD pipeline
- Add Dockerfile with adapter-node for server deployment - Add Kubernetes deployment and ingress manifests - Add GitHub Actions workflow (server build, desktop builds, K8s deploy) - Electron now loads hosted URL (https://optima.osdci.net) in production - Add macOS DMG maker and make:macos script - Switch to static imports in lib/index.ts - Add .dockerignore
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
node_modules
|
||||
.svelte-kit
|
||||
build
|
||||
out
|
||||
.vite
|
||||
.env
|
||||
.env.*
|
||||
*.dmg
|
||||
*.zip
|
||||
e2e
|
||||
electron
|
||||
forge.config.ts
|
||||
forge.env.d.ts
|
||||
vite.main.config.ts
|
||||
vite.preload.config.ts
|
||||
playwright.config.ts
|
||||
@@ -0,0 +1,133 @@
|
||||
name: Build and Publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build-server:
|
||||
name: Build Server Image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push the Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/project-optima/ttscm-ui:latest
|
||||
ghcr.io/project-optima/ttscm-ui:${{ github.event.release.tag_name }}
|
||||
|
||||
build-desktop-macos:
|
||||
name: Build Desktop (macOS)
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build macOS distributables
|
||||
run: pnpm run make:macos
|
||||
|
||||
- name: Upload macOS artifacts to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
out/make/**/*.dmg
|
||||
out/make/**/*.zip
|
||||
|
||||
build-desktop-windows:
|
||||
name: Build Desktop (Windows)
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build Windows distributables
|
||||
run: pnpm run make -- --platform win32
|
||||
|
||||
- name: Upload Windows artifacts to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
out/make/**/*.exe
|
||||
out/make/**/*.nupkg
|
||||
out/make/**/*.msi
|
||||
|
||||
deploy:
|
||||
name: Deploy
|
||||
needs: [build-server]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set the Kubernetes context
|
||||
uses: azure/k8s-set-context@v2
|
||||
with:
|
||||
method: kubeconfig
|
||||
kubeconfig: ${{ secrets.KUBECONFIG }}
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Lint Kubernetes manifests
|
||||
uses: azure/k8s-lint@v3
|
||||
with:
|
||||
lintType: dryrun
|
||||
manifests: |
|
||||
kubernetes/deployment.yaml
|
||||
kubernetes/ingress.yaml
|
||||
namespace: optima
|
||||
|
||||
- name: Deploy to the Kubernetes cluster
|
||||
uses: azure/k8s-deploy@v5
|
||||
with:
|
||||
namespace: optima
|
||||
force: true
|
||||
skip-tls-verify: true
|
||||
manifests: |
|
||||
kubernetes/deployment.yaml
|
||||
kubernetes/ingress.yaml
|
||||
images: |
|
||||
ghcr.io/project-optima/ttscm-ui:${{ github.event.release.tag_name }}
|
||||
@@ -25,3 +25,4 @@ vite.config.ts.timestamp-*
|
||||
.vite
|
||||
|
||||
out
|
||||
tailwindcss-*.log
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
FROM node:22-alpine AS base
|
||||
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
COPY patches ./patches
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build the SvelteKit app with adapter-node
|
||||
COPY . .
|
||||
RUN pnpm run build:server
|
||||
|
||||
# Production image
|
||||
FROM node:22-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=base /app/build ./build
|
||||
COPY --from=base /app/package.json ./
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
ENV ORIGIN=https://optima.osdci.net
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", "build/index.js"]
|
||||
@@ -22,6 +22,7 @@
|
||||
"@electron-forge/plugin-vite": "^7.11.1",
|
||||
"@electron/fuses": "^1.8.0",
|
||||
"@playwright/test": "^1.58.0",
|
||||
"@sveltejs/adapter-node": "^5.5.3",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.50.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.1.1",
|
||||
@@ -238,6 +239,14 @@
|
||||
|
||||
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||
|
||||
"@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@29.0.0", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ=="],
|
||||
|
||||
"@rollup/plugin-json": ["@rollup/plugin-json@6.1.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA=="],
|
||||
|
||||
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.3", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg=="],
|
||||
|
||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.41.0", "", { "os": "android", "cpu": "arm" }, "sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.41.0", "", { "os": "android", "cpu": "arm64" }, "sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ=="],
|
||||
@@ -286,6 +295,8 @@
|
||||
|
||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "8.14.1" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
||||
|
||||
"@sveltejs/adapter-node": ["@sveltejs/adapter-node@5.5.3", "", { "dependencies": { "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.0", "rollup": "^4.9.5" }, "peerDependencies": { "@sveltejs/kit": "^2.4.0" } }, "sha512-yeWbKXBL9vqDb/7R8ebvRHeuBHN4cRYYBSquNJSMQtS6rIYkXxsVSveaMTUaLvHYQsb1zNa+nH2iLTOMawBohA=="],
|
||||
|
||||
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.10", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew=="],
|
||||
|
||||
"@sveltejs/kit": ["@sveltejs/kit@2.50.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.6.2", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-XRHD2i3zC4ukhz2iCQzO4mbsts081PAZnnMAQ7LNpWeYgeBmwMsalf0FGSwhFXBbtr2XViPKnFJBDCckWqrsLw=="],
|
||||
@@ -372,6 +383,8 @@
|
||||
|
||||
"@types/node": ["@types/node@22.19.7", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw=="],
|
||||
|
||||
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
|
||||
|
||||
"@types/responselike": ["@types/responselike@1.0.3", "", { "dependencies": { "@types/node": "22.15.20" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="],
|
||||
|
||||
"@types/wrap-ansi": ["@types/wrap-ansi@3.0.0", "", {}, "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g=="],
|
||||
@@ -554,6 +567,8 @@
|
||||
|
||||
"commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
|
||||
|
||||
"commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="],
|
||||
|
||||
"compare-version": ["compare-version@0.1.2", "", {}, "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
@@ -680,7 +695,7 @@
|
||||
|
||||
"estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
|
||||
|
||||
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "1.0.7" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
|
||||
"eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
|
||||
|
||||
@@ -838,6 +853,8 @@
|
||||
|
||||
"is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="],
|
||||
|
||||
"is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="],
|
||||
|
||||
"is-my-ip-valid": ["is-my-ip-valid@1.0.1", "", {}, "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg=="],
|
||||
|
||||
"is-my-json-valid": ["is-my-json-valid@2.20.6", "", { "dependencies": { "generate-function": "2.3.1", "generate-object-property": "1.2.0", "is-my-ip-valid": "1.0.1", "jsonpointer": "5.0.1", "xtend": "4.0.2" } }, "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw=="],
|
||||
@@ -1452,6 +1469,18 @@
|
||||
|
||||
"@npmcli/move-file/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "7.2.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
|
||||
|
||||
"@rollup/plugin-commonjs/fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"@rollup/plugin-commonjs/is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="],
|
||||
|
||||
"@rollup/plugin-commonjs/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"@rollup/plugin-commonjs/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
|
||||
"@rollup/pluginutils/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@rollup/pluginutils/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
|
||||
"@tailwindcss/node/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
|
||||
@@ -1486,6 +1515,8 @@
|
||||
|
||||
"@types/yauzl/@types/node": ["@types/node@22.15.20", "", { "dependencies": { "undici-types": "6.21.0" } }, "sha512-A6BohGFRGHAscJsTslDCA9JG7qSJr/DWUvrvY8yi9IgnGtMxCyat7vvQ//MFa0DnLsyuS3wYTpLdw4Hf+Q5JXw=="],
|
||||
|
||||
"@vitest/mocker/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "1.0.7" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
|
||||
"ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
|
||||
|
||||
"cacache/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "1.0.0", "inflight": "1.0.6", "inherits": "2.0.4", "minimatch": "5.1.6", "once": "1.4.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="],
|
||||
@@ -1642,6 +1673,10 @@
|
||||
|
||||
"@inquirer/core/wrap-ansi/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "8.0.0", "is-fullwidth-code-point": "3.0.0", "strip-ansi": "6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"@rollup/plugin-commonjs/is-reference/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@rollup/plugin-commonjs/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@tailwindcss/node/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"cacache/glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
|
||||
|
||||
+5
-10
@@ -7,29 +7,24 @@ if (started) {
|
||||
app.quit();
|
||||
}
|
||||
|
||||
const PRODUCTION_URL = "https://optima.osdci.net";
|
||||
|
||||
const createWindow = () => {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
width: 1200,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
preload: path.join(import.meta.dirname, "preload.js"),
|
||||
},
|
||||
});
|
||||
|
||||
// and load the index.html of the app.
|
||||
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
mainWindow.loadURL(`${MAIN_WINDOW_VITE_DEV_SERVER_URL}/login`);
|
||||
mainWindow.webContents.on("did-frame-finish-load", () => {
|
||||
mainWindow.webContents.openDevTools({ mode: "detach" });
|
||||
});
|
||||
} else {
|
||||
mainWindow.loadFile(
|
||||
path.join(
|
||||
import.meta.dirname,
|
||||
`../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`,
|
||||
),
|
||||
);
|
||||
mainWindow.loadURL(PRODUCTION_URL);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ForgeConfig } from "@electron-forge/shared-types";
|
||||
import { MakerSquirrel } from "@electron-forge/maker-squirrel";
|
||||
import { MakerZIP } from "@electron-forge/maker-zip";
|
||||
import { MakerDMG } from "@electron-forge/maker-dmg";
|
||||
import { MakerDeb } from "@electron-forge/maker-deb";
|
||||
import { MakerRpm } from "@electron-forge/maker-rpm";
|
||||
import { VitePlugin } from "@electron-forge/plugin-vite";
|
||||
@@ -15,6 +16,7 @@ const config: ForgeConfig = {
|
||||
makers: [
|
||||
new MakerSquirrel({}),
|
||||
new MakerZIP({}, ["darwin"]),
|
||||
new MakerDMG({}),
|
||||
new MakerRpm({}),
|
||||
new MakerDeb({}),
|
||||
],
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: optima-ui
|
||||
namespace: optima
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: optima-ui
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: optima-ui
|
||||
spec:
|
||||
containers:
|
||||
- name: optima-ui
|
||||
image: ghcr.io/project-optima/ttscm-ui:latest
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: PUBLIC_API_URL
|
||||
value: "https://opt-api.osdci.net"
|
||||
- name: ORIGIN
|
||||
value: "https://optima.osdci.net"
|
||||
- name: PORT
|
||||
value: "3000"
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
imagePullSecrets:
|
||||
- name: github-container-registry
|
||||
@@ -0,0 +1,39 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: optima-ui-ingress
|
||||
namespace: optima
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- optima.osdci.net
|
||||
secretName: osdci-net-cert
|
||||
rules:
|
||||
- host: optima.osdci.net
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: optima-ui
|
||||
port:
|
||||
number: 3000
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: optima-ui
|
||||
namespace: optima
|
||||
labels:
|
||||
app: optima-ui
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 3000
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: optima-ui
|
||||
+5
-2
@@ -18,8 +18,10 @@
|
||||
"test": "npm run test:unit -- --run && npm run test:e2e",
|
||||
"test:e2e": "playwright test",
|
||||
"start": "electron-forge start",
|
||||
"package": "vite build && electron-forge package",
|
||||
"make": "vite build && electron-forge make",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make",
|
||||
"make:macos": "electron-forge make --platform darwin",
|
||||
"build:server": "vite build",
|
||||
"publish": "electron-forge publish"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -34,6 +36,7 @@
|
||||
"@electron-forge/plugin-vite": "^7.11.1",
|
||||
"@electron/fuses": "^1.8.0",
|
||||
"@playwright/test": "^1.58.0",
|
||||
"@sveltejs/adapter-node": "^5.5.3",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.50.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.1.1",
|
||||
|
||||
+16
-9
@@ -1,18 +1,25 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
||||
|
||||
import { auth } from "./optima-api/modules/auth";
|
||||
import { company } from "./optima-api/modules/companies";
|
||||
import { credential } from "./optima-api/modules/credentials";
|
||||
import { credentialType } from "./optima-api/modules/credentialTypes";
|
||||
import { role } from "./optima-api/modules/roles";
|
||||
import { permission } from "./optima-api/modules/permissions";
|
||||
import { user } from "./optima-api/modules/user";
|
||||
import { users } from "./optima-api/modules/users";
|
||||
import { unifi } from "./optima-api/modules/unifi";
|
||||
|
||||
export const optima = {
|
||||
auth: (await import("./optima-api/modules/auth")).auth,
|
||||
company: (await import("./optima-api/modules/companies")).company,
|
||||
credential: (await import("./optima-api/modules/credentials")).credential,
|
||||
credentialType: (await import("./optima-api/modules/credentialTypes"))
|
||||
.credentialType,
|
||||
role: (await import("./optima-api/modules/roles")).role,
|
||||
permission: (await import("./optima-api/modules/permissions")).permission,
|
||||
auth,
|
||||
company,
|
||||
credential,
|
||||
credentialType,
|
||||
role,
|
||||
permission,
|
||||
user,
|
||||
users: (await import("./optima-api/modules/users")).users,
|
||||
unifi: (await import("./optima-api/modules/unifi")).unifi,
|
||||
users,
|
||||
unifi,
|
||||
};
|
||||
/**
|
||||
* @TODO
|
||||
|
||||
@@ -79,6 +79,7 @@ export const user = {
|
||||
let settled = false;
|
||||
const socket = io(`${base}/auth_callback`, {
|
||||
transports: ["websocket"],
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
const timeout = setTimeout(
|
||||
() => {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const ssr = true;
|
||||
|
||||
@@ -640,9 +640,10 @@
|
||||
const updated = result?.data ?? wifiEditState;
|
||||
selectedWifi = { ...selectedWifi, ...updated } as UnifiWifiNetwork;
|
||||
// Preserve deviceMacs for "devices" mode since the API doesn't return it
|
||||
const savedDeviceMacs = wifiEditState.apGroupMode === "devices"
|
||||
? (wifiEditState.deviceMacs as string[] ?? [])
|
||||
: [];
|
||||
const savedDeviceMacs =
|
||||
wifiEditState.apGroupMode === "devices"
|
||||
? ((wifiEditState.deviceMacs as string[]) ?? [])
|
||||
: [];
|
||||
wifiEditState = { ...updated, deviceMacs: savedDeviceMacs };
|
||||
wifiOriginalState = { ...updated, deviceMacs: [...savedDeviceMacs] };
|
||||
isWifiDirty = false;
|
||||
|
||||
+2
-4
@@ -1,4 +1,4 @@
|
||||
import adapter from "@sveltejs/adapter-static";
|
||||
import adapter from "@sveltejs/adapter-node";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
|
||||
const config = {
|
||||
@@ -9,9 +9,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
pages: ".vite/renderer/main_window",
|
||||
}),
|
||||
adapter: adapter(),
|
||||
router: {
|
||||
type: "pathname",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user