mirror of
https://github.com/ever-co/ever-gauzy.git
synced 2026-10-02 01:54:50 +08:00
The desktop update origin `ever.sfo3.cdn.digitaloceanspaces.com` died with the locked
DigitalOcean account (CDN host NXDOMAIN, origin bucket returns NoSuchBucket). Every shipped
Electron app defaulted to that dead feed and, on failure, had no fallback — so installs were
silently stranded with no path to a new version.
GitHub Releases is already a live, current feed (each app repo carries v111.0.12 with the
`latest*.yml` metadata electron-updater needs). This makes GitHub the default everywhere:
- packages/desktop-lib/src/lib/desktop-updater.ts: the active update strategy now defaults to
GithubCdn (was DigitalOceanCdn). This is the load-bearing fix — apps that never call
checkUpdate() explicitly (e.g. agent) rely solely on the automatic loop, which used the
hardcoded DigitalOcean constructor default. The automatic loop now starts only after the
GitHub strategy's async initialize() resolves its feed URL. The deprecated `digitalOcean`
option in both the settings path and the change_update_strategy IPC now resolves to GitHub,
so a persisted `digitalOcean: true` (the old shipped default) can no longer pin an install
to the dead CDN. The DigitalOceanCdn class is retained (unused) for reversibility.
- packages/desktop-core/.../application-setting-store.service.ts: shipped default cdnUpdater
flipped to { github: true, digitalOcean: false } so fresh installs seed the live feed.
- apps/{desktop,desktop-timer,server,server-api,agent,server-mcp}/src/package.json: removed the
dead `spaces` publish provider (bucket "ever"/sfo3); the `github` provider remains, so
`yarn build:desktop:*:release` no longer targets the dead bucket.
- .github/workflows/*: dropped the now-unused DO_KEY_ID/DO_SECRET_KEY env (86 pairs across 18
app workflows) that fed the removed Spaces upload.
Note: already-installed apps persist their update-source setting in Electron userData, which
survives reinstalls — so this fix reaches new installs and manual reinstalls-over-existing-data
(the runtime change ignores the dead persisted flag), but cannot reach installs that can no
longer update at all. Those require the DO CDN to be revived or a manual reinstall.
Windows Authenticode signing (GHSA-j75p-23jm-f83g) remains open — it needs a certificate that
does not exist yet; build.win is deliberately left unchanged (adding publisherName without a
real signature would make electron-updater verification fail closed). Runtime update flow was
verified statically (no Electron runtime available locally); CI validates build/lint/typecheck.
Refs: knowledge/infrastructure/DESKTOP_SIGNING_HANDOFF_PROMPT.md (Task 1), issue #9753
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
258 lines
11 KiB
YAML
258 lines
11 KiB
YAML
name: Agent App Build Demo
|
|
|
|
# The packaged desktop & server demo apps are built ONLY when 'develop' is promoted to the
|
|
# 'local-apps' branch. The build version is resolved at build time
|
|
# (.scripts/bump-version-electron.js) from the release tag of the promoted commit (on HEAD, or on the merge parent for PR-merge promotions), which
|
|
# 'Release Demo' creates on every merge to 'develop'.
|
|
on:
|
|
push:
|
|
branches:
|
|
- local-apps
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: ${{ github.ref }}-${{ github.workflow }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
check-release-tag:
|
|
# Only build when the promoted commit carries a release tag (the version stamped into the
|
|
# packages - see header comment). 'local-apps' is promoted from 'develop' either by
|
|
# fast-forwarding to the tagged 'develop' commit (tag on HEAD) or by merging the
|
|
# 'develop' -> 'local-apps' promotion PR (the tag then points at the merged
|
|
# 'develop' tip, HEAD^2). Retries absorb the short delay until 'Release Demo' tags
|
|
# the 'develop' commit.
|
|
runs-on: ${{ vars.RUNNER_LINUX_X64_4 || 'ubuntu-latest' }}
|
|
timeout-minutes: 30
|
|
permissions:
|
|
contents: read
|
|
outputs:
|
|
# The resolved vX.Y.Z release tag; the build jobs stamp exactly this version.
|
|
tag: ${{ steps.resolve.outputs.tag }}
|
|
steps:
|
|
- name: Check out Git repository
|
|
uses: actions/checkout@v5
|
|
with:
|
|
persist-credentials: false
|
|
# Depth 2 so HEAD^2 resolves on merge-commit promotions
|
|
fetch-depth: 2
|
|
|
|
- name: Verify a release tag points at the promoted commit
|
|
id: resolve
|
|
shell: bash
|
|
run: |
|
|
if [ "$GITHUB_REF_NAME" != "local-apps" ]; then
|
|
echo "::error::This workflow only releases from the 'local-apps' branch (got '$GITHUB_REF_NAME')."
|
|
exit 1
|
|
fi
|
|
HEAD_SHA=$(git rev-parse HEAD)
|
|
# Present only when the promotion PR was merged as a merge commit; the release tag
|
|
# then points at the merged 'develop' tip, not at the merge commit itself.
|
|
PARENT2_SHA=$(git rev-parse --verify --quiet 'HEAD^2' || true)
|
|
resolve_tag() {
|
|
# Highest vX.Y.Z tag pointing at $1 in the remote listing (peeled '^{}' entries
|
|
# carry the commit sha of annotated tags); empty when none match.
|
|
printf '%s\n' "$REMOTE_REFS" | awk -v sha="$1" '
|
|
$1 == sha && $2 ~ /^refs\/tags\/v[0-9]+\.[0-9]+\.[0-9]+(\^\{\})?$/ {
|
|
t = $2
|
|
sub(/^refs\/tags\//, "", t)
|
|
sub(/\^\{\}$/, "", t)
|
|
print t
|
|
}' | sort -V | tail -n 1
|
|
}
|
|
for i in $(seq 1 20); do
|
|
if REMOTE_REFS=$(git ls-remote origin refs/heads/develop 'refs/tags/*'); then
|
|
SRC_TIP=$(printf '%s\n' "$REMOTE_REFS" | awk -v ref="refs/heads/develop" '$2 == ref { print $1 }')
|
|
TAG=$(resolve_tag "$HEAD_SHA")
|
|
# Accept the merge-parent tag only when HEAD^2 is the current 'develop' tip -
|
|
# i.e. this is the promotion merge of 'develop', not an arbitrary tagged branch
|
|
# merged in, nor a fast-forward racing 'Release Demo' (whose tag lands on HEAD).
|
|
if [ -z "$TAG" ] && [ -n "$PARENT2_SHA" ] && [ "$PARENT2_SHA" = "$SRC_TIP" ]; then
|
|
TAG=$(resolve_tag "$PARENT2_SHA")
|
|
fi
|
|
if [ -n "$TAG" ]; then
|
|
echo "Release tag on the promoted commit: $TAG"
|
|
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
else
|
|
echo "git ls-remote failed (attempt $i); will retry"
|
|
fi
|
|
echo "No release tag points at this commit or its merge parent yet (attempt $i/20); retrying in 30s..."
|
|
sleep 30
|
|
done
|
|
echo "::error::No release tag points at this commit, and its merge parent does not match the tagged 'develop' tip. Promote by merging the 'develop' -> 'local-apps' PR (or fast-forwarding: git push origin origin/develop:local-apps) after 'Release Demo' has created the tag; if 'develop' has moved since the promotion PR was opened, re-promote."
|
|
exit 1
|
|
|
|
release-windows:
|
|
needs: check-release-tag
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 300
|
|
|
|
strategy:
|
|
matrix:
|
|
os: [[self-hosted, Windows, X64]]
|
|
|
|
steps:
|
|
- name: Check out Git repository
|
|
uses: actions/checkout@v5
|
|
with:
|
|
clean: false
|
|
|
|
- name: Selective cleanup (preserve .nx/cache)
|
|
shell: powershell
|
|
run: |
|
|
$ErrorActionPreference = 'SilentlyContinue'
|
|
# Stop NX daemon first to release file locks before cleanup (guard for fresh runners without Node)
|
|
if (Get-Command npx -ErrorAction SilentlyContinue) { npx nx daemon --stop 2>&1 | Out-Null }
|
|
# Remove build artifacts but keep NX cache for faster rebuilds
|
|
if (Test-Path "dist") { Remove-Item -Recurse -Force "dist" }
|
|
if (Test-Path "node_modules") { Remove-Item -Recurse -Force "node_modules" }
|
|
exit 0
|
|
|
|
- name: Install Node.js, NPM and Yarn
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24.17.0
|
|
|
|
- name: Install Visual Studio 2022 Build Tools (VCTools)
|
|
shell: powershell
|
|
run: |
|
|
choco install -y visualstudio2022buildtools --execution-timeout=21600 --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --includeOptional --passive --norestart"
|
|
|
|
- name: Configure node-gyp to use VS 2022
|
|
shell: powershell
|
|
run: |
|
|
"GYP_MSVS_VERSION=2022" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
"npm_config_msvs_version=2022" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
|
|
- name: Fix node-gyp and Python
|
|
run: python3 -m pip install packaging setuptools
|
|
|
|
- name: Setup MSVC (VS 2022 dev env)
|
|
uses: ilammy/msvc-dev-cmd@v1
|
|
with:
|
|
arch: x64
|
|
|
|
- name: Install latest version of NPM
|
|
run: 'npm install -g npm@11.6.2'
|
|
|
|
- name: Install globally node-gyp, ts-node and nx packages
|
|
run: 'npm install --quiet -g node-gyp@10.2.0 ts-node@10.9.2 nx@^22.5.2'
|
|
|
|
- name: Configure npm python for node-gyp
|
|
shell: powershell
|
|
run: |
|
|
$py = (Get-Command python.exe).Source
|
|
Write-Host "python is: $py"
|
|
"npm_config_python=$py" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
"PYTHON=$py" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
|
|
- name: Configure Registry
|
|
shell: bash
|
|
run: |
|
|
if [ -n "${{ secrets.VERDACCIO_TOKEN }}" ]; then
|
|
echo "//packages.ever.co/:_authToken=${{ secrets.VERDACCIO_TOKEN }}" >> .npmrc
|
|
echo "registry=https://packages.ever.co/" >> .npmrc
|
|
echo "always-auth=true" >> .npmrc
|
|
echo 'registry "https://packages.ever.co/"' >> .yarnrc
|
|
sed -i.bak 's|https://registry.yarnpkg.com|https://packages.ever.co|g' yarn.lock
|
|
sed -i.bak 's|https://registry.npmjs.org|https://packages.ever.co|g' yarn.lock
|
|
rm -f yarn.lock.bak
|
|
fi
|
|
|
|
- name: Install Yarn dependencies
|
|
run: 'yarn install --network-timeout 1000000 --frozen-lockfile --ignore-scripts'
|
|
|
|
- name: Run Postinstall Manually
|
|
run: 'yarn postinstall.manual'
|
|
|
|
- name: Bump Agent version
|
|
uses: actions/github-script@v8
|
|
with:
|
|
script: |
|
|
const script = require('./.scripts/bump-version-electron.js')
|
|
console.log(script.agent(false))
|
|
env:
|
|
GAUZY_RELEASE_TAG: ${{ needs.check-release-tag.outputs.tag }}
|
|
PROJECT_REPO: 'https://github.com/ever-co/ever-gauzy.git'
|
|
AGENT_APP_NAME: 'gauzy-agent'
|
|
# Demo electron releases go to the same repo
|
|
AGENT_APP_REPO_NAME: 'ever-gauzy'
|
|
AGENT_APP_REPO_OWNER: 'ever-co'
|
|
COMPANY_SITE_LINK: 'https://gauzy.co'
|
|
AGENT_APP_DESCRIPTION: 'Gauzy Agent'
|
|
AGENT_APP_ID: 'com.ever.gauzyagent'
|
|
|
|
- name: Fix Node.js PATH for child processes
|
|
shell: powershell
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
$nodeExe = (Get-Command node -ErrorAction Stop).Source
|
|
$nodePath = Split-Path $nodeExe -Parent
|
|
$npmGlobalBin = & npm config get prefix
|
|
$localBin = Join-Path $PWD "node_modules\.bin"
|
|
$yarnCmd = Get-Command yarn -ErrorAction SilentlyContinue
|
|
$yarnPath = if ($yarnCmd) { Split-Path $yarnCmd.Source -Parent } else { "" }
|
|
|
|
$npmNodeExe = Join-Path $npmGlobalBin "node.exe"
|
|
if (-not (Test-Path $npmNodeExe)) { Copy-Item $nodeExe $npmNodeExe -Force }
|
|
|
|
$localNodeExe = Join-Path $localBin "node.exe"
|
|
if (-not (Test-Path $localNodeExe)) { Copy-Item $nodeExe $localNodeExe -Force }
|
|
|
|
$newPath = "$nodePath;$npmGlobalBin;$localBin;$yarnPath;$($env:PATH)"
|
|
"PATH=$newPath" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
|
|
@($nodePath, $npmGlobalBin, $localBin, $yarnPath) | Where-Object { $_ } | ForEach-Object {
|
|
$_ | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8
|
|
}
|
|
|
|
"NODE=$nodeExe" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
"NODE_PATH=$nodePath" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
|
|
$env:PATH = $newPath
|
|
[System.Environment]::SetEnvironmentVariable("PATH", $newPath, "Process")
|
|
|
|
- name: Ensure dist directory exists
|
|
shell: bash
|
|
run: mkdir -p dist/packages
|
|
|
|
- name: Increase file handle limits
|
|
shell: powershell
|
|
run: |
|
|
# Increase Node.js UV threadpool for parallel I/O (default is 4)
|
|
"UV_THREADPOOL_SIZE=32" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
# Patch graceful-fs to retry EMFILE errors with backoff
|
|
node -e "try { var gfs = require('graceful-fs'); gfs.gracefulify(require('fs')); console.log('graceful-fs patched'); } catch(e) { console.log('graceful-fs not available, skipping'); }"
|
|
|
|
- name: Reset NX
|
|
shell: powershell
|
|
run: npx nx reset
|
|
|
|
- name: Build Agent
|
|
shell: cmd
|
|
run: 'yarn build:agent:windows:release:gh:x64'
|
|
env:
|
|
USE_HARD_LINKS: false
|
|
ELECTRON_BUILDER_CACHE: ${{ github.workspace }}\.cache\electron-builder
|
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
EP_GH_IGNORE_TIME: true
|
|
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
|
SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}'
|
|
SENTRY_PROFILE_SAMPLE_RATE: '${{ secrets.SENTRY_PROFILE_SAMPLE_RATE }}'
|
|
SENTRY_HTTP_TRACING_ENABLED: '${{ secrets.SENTRY_HTTP_TRACING_ENABLED }}'
|
|
SENTRY_POSTGRES_TRACKING_ENABLED: '${{ secrets.SENTRY_POSTGRES_TRACKING_ENABLED }}'
|
|
SENTRY_PROFILING_ENABLED: '${{ secrets.SENTRY_PROFILING_ENABLED }}'
|
|
NX_NO_CLOUD: true
|
|
NX_PLUGIN_NO_TIMEOUTS: true
|
|
NX_DAEMON: false
|
|
PROJECT_REPO: 'https://github.com/ever-co/ever-gauzy.git'
|
|
# Demo electron releases go to the same repo
|
|
AGENT_APP_REPO_OWNER: 'ever-co'
|
|
AGENT_APP_REPO_NAME: 'ever-gauzy'
|
|
AGENT_APP_NAME: 'gauzy-agent'
|
|
AGENT_APP_DESCRIPTION: 'Gauzy Agent'
|
|
AGENT_APP_ID: 'com.ever.gauzyagent'
|
|
COMPANY_SITE_LINK: 'https://gauzy.co'
|