Improve workflows for better reusability (#2608)
This commit is contained in:
@@ -39,15 +39,39 @@ on:
|
|||||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||||
for example icons in the `build/` directory to override the app icons.
|
for example icons in the `build/` directory to override the app icons.
|
||||||
default: "webapp"
|
default: "webapp"
|
||||||
|
test:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
description: "Whether to run the test stage after building"
|
||||||
|
test-args:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "Additional arguments to pass to playwright"
|
||||||
|
runs-on:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "The runner image to use, normally set for you, may be needed for running in private repos."
|
||||||
|
artifact-prefix:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "An optional prefix to add to the artifact name, useful for distinguishing builds in private repos."
|
||||||
|
default: ""
|
||||||
|
targets:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "List of targets to build"
|
||||||
|
default: "tar.gz deb"
|
||||||
env:
|
env:
|
||||||
SQLCIPHER_BUNDLED: ${{ inputs.sqlcipher == 'static' && '1' || '' }}
|
SQLCIPHER_BUNDLED: ${{ inputs.sqlcipher == 'static' && '1' || '' }}
|
||||||
MAX_GLIBC: 2.31 # bullseye-era glibc, used by glibc-check.sh
|
MAX_GLIBC: 2.31 # bullseye-era glibc, used by glibc-check.sh
|
||||||
permissions: {} # No permissions required
|
permissions: {} # No permissions required
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: Build Linux ${{ inputs.arch }} SQLCipher ${{ inputs.sqlcipher }}
|
||||||
# We build on native infrastructure as matrix-seshat fails to cross-compile properly
|
# We build on native infrastructure as matrix-seshat fails to cross-compile properly
|
||||||
# https://github.com/matrix-org/seshat/issues/135
|
# https://github.com/matrix-org/seshat/issues/135
|
||||||
runs-on: ${{ inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04' }}
|
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
|
||||||
env:
|
env:
|
||||||
HAK_DOCKER_IMAGE: ghcr.io/element-hq/element-desktop-dockerbuild
|
HAK_DOCKER_IMAGE: ghcr.io/element-hq/element-desktop-dockerbuild
|
||||||
steps:
|
steps:
|
||||||
@@ -109,7 +133,7 @@ jobs:
|
|||||||
|
|
||||||
- name: "Get modified files"
|
- name: "Get modified files"
|
||||||
id: changed_files
|
id: changed_files
|
||||||
if: steps.cache.outputs.cache-hit != 'true' && github.event_name == 'pull_request'
|
if: steps.cache.outputs.cache-hit != 'true' && github.event_name == 'pull_request' && github.repository == 'element-hq/element-desktop'
|
||||||
uses: tj-actions/changed-files@823fcebdb31bb35fdf2229d9f769b400309430d0 # v46
|
uses: tj-actions/changed-files@823fcebdb31bb35fdf2229d9f769b400309430d0 # v46
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
@@ -159,13 +183,11 @@ jobs:
|
|||||||
echo "USE_SYSTEM_FPM=true" >> $GITHUB_ENV
|
echo "USE_SYSTEM_FPM=true" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build App
|
- name: Build App
|
||||||
run: yarn build --publish never -l ${{ steps.config.outputs.build-args }}
|
run: yarn build --publish never ${{ steps.config.outputs.build-args }} -l ${{ inputs.targets }}
|
||||||
env:
|
env:
|
||||||
VARIANT_PATH: variant.json
|
VARIANT_PATH: variant.json
|
||||||
# Only set for Nightly builds
|
# Only set for Nightly builds
|
||||||
VERSION: ${{ inputs.version }}
|
VERSION: ${{ inputs.version }}
|
||||||
FPM_DEBUG: true # TODO
|
|
||||||
DEBUG: electron-builder # TODO
|
|
||||||
# Workaround for https://github.com/electron-userland/electron-builder/issues/5721
|
# Workaround for https://github.com/electron-userland/electron-builder/issues/5721
|
||||||
USE_HARD_LINKS: false
|
USE_HARD_LINKS: false
|
||||||
|
|
||||||
@@ -199,39 +221,46 @@ jobs:
|
|||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
name: ${{ inputs.artifact-prefix }}linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
||||||
path: |
|
path: |
|
||||||
dist
|
dist
|
||||||
!dist/*-unpacked/**
|
!dist/*-unpacked/**
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
- name: Assert all required files are present
|
- name: Assert deb is present and valid
|
||||||
|
if: contains(inputs.targets, 'deb')
|
||||||
run: |
|
run: |
|
||||||
test -f ./dist/element-desktop*$ARCH.deb
|
test -f ./dist/element-desktop*$ARCH.deb
|
||||||
test -f ./dist/element-desktop*.tar.gz
|
|
||||||
env:
|
|
||||||
ARCH: ${{ inputs.arch }}
|
|
||||||
|
|
||||||
- name: Assert no hardlinks are found
|
|
||||||
run: |
|
|
||||||
TAR_GZ_LISTING=$(tar -tvf ./dist/element-desktop*.tar.gz)
|
|
||||||
echo "tar.gz listing: "
|
|
||||||
echo "$TAR_GZ_LISTING"
|
|
||||||
! echo "$TAR_GZ_LISTING" | grep '^h'
|
|
||||||
|
|
||||||
DEB_LISTING=$(dpkg-deb --fsys-tarfile ./dist/element-desktop*.deb | tar -tv)
|
DEB_LISTING=$(dpkg-deb --fsys-tarfile ./dist/element-desktop*.deb | tar -tv)
|
||||||
echo "deb listing: "
|
echo "deb listing: "
|
||||||
echo "$DEB_LISTING"
|
echo "$DEB_LISTING"
|
||||||
! echo "$DEB_LISTING" | grep '^h'
|
! echo "$DEB_LISTING" | grep '^h'
|
||||||
|
env:
|
||||||
|
ARCH: ${{ inputs.arch }}
|
||||||
|
|
||||||
|
- name: Assert tar.gz is present
|
||||||
|
if: contains(inputs.targets, 'tar.gz')
|
||||||
|
run: |
|
||||||
|
test -f ./dist/element-desktop*.tar.gz
|
||||||
|
|
||||||
|
TAR_GZ_LISTING=$(tar -tvf ./dist/element-desktop*.tar.gz)
|
||||||
|
echo "tar.gz listing: "
|
||||||
|
echo "$TAR_GZ_LISTING"
|
||||||
|
! echo "$TAR_GZ_LISTING" | grep '^h'
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
name: Test Linux ${{ inputs.arch }} SQLCipher ${{ inputs.sqlcipher }}
|
||||||
needs: build
|
needs: build
|
||||||
|
if: inputs.test && contains(inputs.targets, 'deb')
|
||||||
uses: ./.github/workflows/build_test.yaml
|
uses: ./.github/workflows/build_test.yaml
|
||||||
with:
|
with:
|
||||||
artifact: linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
project: linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
||||||
runs-on: ${{ inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04' }}
|
artifact: ${{ inputs.artifact-prefix }}linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
||||||
|
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
|
||||||
executable: /opt/Element*/element-desktop*
|
executable: /opt/Element*/element-desktop*
|
||||||
prepare_cmd: |
|
prepare_cmd: |
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
sudo apt install ./dist/*.deb
|
sudo apt install ./dist/*.deb
|
||||||
blob_report: ${{ inputs.blob_report }}
|
blob_report: ${{ inputs.blob_report }}
|
||||||
|
args: ${{ inputs.test-args }}
|
||||||
|
|||||||
@@ -49,9 +49,29 @@ on:
|
|||||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||||
for example icons in the `build/` directory to override the app icons.
|
for example icons in the `build/` directory to override the app icons.
|
||||||
default: "webapp"
|
default: "webapp"
|
||||||
|
test:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
description: "Whether to run the test stage after building"
|
||||||
|
test-args:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "Additional arguments to pass to playwright"
|
||||||
|
artifact-prefix:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "An optional prefix to add to the artifact name, useful for distinguishing builds in private repos."
|
||||||
|
default: ""
|
||||||
|
targets:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "List of targets to build"
|
||||||
|
default: "dmg zip"
|
||||||
permissions: {} # No permissions required
|
permissions: {} # No permissions required
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: Build macOS Universal
|
||||||
runs-on: macos-14 # M1
|
runs-on: macos-14 # M1
|
||||||
environment: ${{ inputs.sign && 'packages.element.io' || '' }}
|
environment: ${{ inputs.sign && 'packages.element.io' || '' }}
|
||||||
steps:
|
steps:
|
||||||
@@ -105,7 +125,7 @@ jobs:
|
|||||||
- name: "[Signed] Build App"
|
- name: "[Signed] Build App"
|
||||||
if: inputs.sign != ''
|
if: inputs.sign != ''
|
||||||
run: |
|
run: |
|
||||||
yarn build:universal --publish never
|
yarn build:universal --publish never -m ${{ inputs.targets }}
|
||||||
env:
|
env:
|
||||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
@@ -127,7 +147,7 @@ jobs:
|
|||||||
- name: "[Unsigned] Build App"
|
- name: "[Unsigned] Build App"
|
||||||
if: inputs.sign == ''
|
if: inputs.sign == ''
|
||||||
run: |
|
run: |
|
||||||
yarn build:universal --publish never
|
yarn build:universal --publish never -m ${{ inputs.targets }}
|
||||||
env:
|
env:
|
||||||
CSC_IDENTITY_AUTO_DISCOVERY: false
|
CSC_IDENTITY_AUTO_DISCOVERY: false
|
||||||
VARIANT_PATH: variant.json
|
VARIANT_PATH: variant.json
|
||||||
@@ -162,22 +182,30 @@ jobs:
|
|||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: macos
|
name: ${{ inputs.artifact-prefix }}macos
|
||||||
path: |
|
path: |
|
||||||
dist
|
dist
|
||||||
!dist/mac-universal/**
|
!dist/mac-universal/**
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
- name: Assert all required files are present
|
- name: Assert zip is present
|
||||||
|
if: contains(inputs.targets, 'zip')
|
||||||
run: |
|
run: |
|
||||||
test -f ./dist/Element*.dmg
|
|
||||||
test -f ./dist/Element*-mac.zip
|
test -f ./dist/Element*-mac.zip
|
||||||
|
|
||||||
|
- name: Assert dmg is present
|
||||||
|
if: contains(inputs.targets, 'dmg')
|
||||||
|
run: |
|
||||||
|
test -f ./dist/Element*.dmg
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
name: Test macOS Universal
|
||||||
needs: build
|
needs: build
|
||||||
|
if: inputs.test && contains(inputs.targets, 'dmg')
|
||||||
uses: ./.github/workflows/build_test.yaml
|
uses: ./.github/workflows/build_test.yaml
|
||||||
with:
|
with:
|
||||||
artifact: macos
|
project: macos
|
||||||
|
artifact: ${{ inputs.artifact-prefix }}macos
|
||||||
runs-on: macos-14
|
runs-on: macos-14
|
||||||
executable: /Users/runner/Applications/Element*.app/Contents/MacOS/Element*
|
executable: /Users/runner/Applications/Element*.app/Contents/MacOS/Element*
|
||||||
# We need to mount the DMG and copy the app to the Applications folder as a mounted DMG is
|
# We need to mount the DMG and copy the app to the Applications folder as a mounted DMG is
|
||||||
@@ -187,3 +215,4 @@ jobs:
|
|||||||
rsync -a /Volumes/Element/Element*.app ~/Applications/ &&
|
rsync -a /Volumes/Element/Element*.app ~/Applications/ &&
|
||||||
hdiutil detach /Volumes/Element
|
hdiutil detach /Volumes/Element
|
||||||
blob_report: ${{ inputs.blob_report }}
|
blob_report: ${{ inputs.blob_report }}
|
||||||
|
args: ${{ inputs.test-args }}
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
description: "The name of the artifact to download"
|
description: "The name of the artifact to download"
|
||||||
|
project:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: "The Playwright project to use for testing"
|
||||||
executable:
|
executable:
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
@@ -22,12 +26,19 @@ on:
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
description: "Whether to upload a blob report instead of the HTML report"
|
description: "Whether to upload a blob report instead of the HTML report"
|
||||||
|
args:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "Additional arguments to pass to playwright, for e.g. skipping specific tests"
|
||||||
permissions: {}
|
permissions: {}
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
name: Test ${{ inputs.project }}
|
||||||
runs-on: ${{ inputs.runs-on }}
|
runs-on: ${{ inputs.runs-on }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||||
|
with:
|
||||||
|
repository: ${{ github.repository == 'element-hq/element-web-pro' && 'element-hq/element-desktop' || github.repository }}
|
||||||
|
|
||||||
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
|
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
|
||||||
with:
|
with:
|
||||||
@@ -69,7 +80,7 @@ jobs:
|
|||||||
uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a
|
uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
with:
|
with:
|
||||||
run: yarn test --project=${{ inputs.artifact }} ${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} ${{ inputs.blob_report == false && '--reporter=html' || '' }}
|
run: yarn test --project=${{ inputs.project }} ${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} ${{ inputs.blob_report == false && '--reporter=html' || '' }} ${{ inputs.args }}
|
||||||
env:
|
env:
|
||||||
ELEMENT_DESKTOP_EXECUTABLE: ${{ steps.executable.outputs.path }}
|
ELEMENT_DESKTOP_EXECUTABLE: ${{ steps.executable.outputs.path }}
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,33 @@ on:
|
|||||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||||
for example icons in the `build/` directory to override the app icons.
|
for example icons in the `build/` directory to override the app icons.
|
||||||
default: "webapp"
|
default: "webapp"
|
||||||
|
test:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
description: "Whether to run the test stage after building"
|
||||||
|
test-runs-on:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "The runner image to use for testing, normally set for you, may be needed for running in private repos."
|
||||||
|
test-args:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "Additional arguments to pass to playwright"
|
||||||
|
artifact-prefix:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "An optional prefix to add to the artifact name, useful for distinguishing builds in private repos."
|
||||||
|
default: ""
|
||||||
|
targets:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
description: "List of targets to build"
|
||||||
|
default: "squirrel msi"
|
||||||
permissions: {} # No permissions required
|
permissions: {} # No permissions required
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
name: Build Windows ${{ inputs.arch }}
|
||||||
runs-on: windows-2025
|
runs-on: windows-2025
|
||||||
environment: ${{ inputs.sign && 'packages.element.io' || '' }}
|
environment: ${{ inputs.sign && 'packages.element.io' || '' }}
|
||||||
env:
|
env:
|
||||||
@@ -208,7 +232,7 @@ jobs:
|
|||||||
MASTER_KEY_FILE: C:\Users\runneradmin\eSignerCKA\master.key
|
MASTER_KEY_FILE: C:\Users\runneradmin\eSignerCKA\master.key
|
||||||
|
|
||||||
- name: Build App
|
- name: Build App
|
||||||
run: yarn build --publish never -w ${{ steps.config.outputs.build-args }}
|
run: yarn build --publish never ${{ steps.config.outputs.build-args }} -w ${{ inputs.targets }}
|
||||||
env:
|
env:
|
||||||
VARIANT_PATH: variant.json
|
VARIANT_PATH: variant.json
|
||||||
# Only set for Nightly builds
|
# Only set for Nightly builds
|
||||||
@@ -236,24 +260,36 @@ jobs:
|
|||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||||
with:
|
with:
|
||||||
name: win-${{ inputs.arch }}
|
name: ${{ inputs.artifact-prefix }}win-${{ inputs.arch }}
|
||||||
path: |
|
path: |
|
||||||
dist
|
dist
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
- name: Assert all required files are present
|
- name: Assert executable is present
|
||||||
run: |
|
run: |
|
||||||
Test-Path './dist/win-*unpacked/Element*.exe'
|
Test-Path './dist/win-*unpacked/Element*.exe'
|
||||||
|
|
||||||
|
- name: Assert all Squirrel files are present
|
||||||
|
if: contains(inputs.targets, 'squirrel')
|
||||||
|
run: |
|
||||||
Test-Path './dist/squirrel-windows*/Element Setup*.exe'
|
Test-Path './dist/squirrel-windows*/Element Setup*.exe'
|
||||||
Test-Path './dist/squirrel-windows*/element-desktop-*-full.nupkg'
|
Test-Path './dist/squirrel-windows*/element-desktop-*-full.nupkg'
|
||||||
Test-Path './dist/squirrel-windows*/RELEASES'
|
Test-Path './dist/squirrel-windows*/RELEASES'
|
||||||
|
|
||||||
|
- name: Assert MSI is present
|
||||||
|
if: contains(inputs.targets, 'msi')
|
||||||
|
run: |
|
||||||
Test-Path './dist/Element*.msi'
|
Test-Path './dist/Element*.msi'
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
name: Test Windows ${{ inputs.arch }}
|
||||||
needs: build
|
needs: build
|
||||||
|
if: inputs.test
|
||||||
uses: ./.github/workflows/build_test.yaml
|
uses: ./.github/workflows/build_test.yaml
|
||||||
with:
|
with:
|
||||||
artifact: win-${{ inputs.arch }}
|
project: win-${{ inputs.arch }}
|
||||||
runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2022' }}
|
artifact: ${{ inputs.artifact-prefix }}win-${{ inputs.arch }}
|
||||||
|
runs-on: ${{ inputs.test-runs-on || (inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2022') }}
|
||||||
executable: ./dist/win*-unpacked/Element*.exe
|
executable: ./dist/win*-unpacked/Element*.exe
|
||||||
blob_report: ${{ inputs.blob_report }}
|
blob_report: ${{ inputs.blob_report }}
|
||||||
|
args: ${{ inputs.test-args }}
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ const config: Omit<Writable<Configuration>, "electronFuses"> & {
|
|||||||
fpm: ["--deb-pre-depends", "libc6 (>= 2.31)"],
|
fpm: ["--deb-pre-depends", "libc6 (>= 2.31)"],
|
||||||
},
|
},
|
||||||
mac: {
|
mac: {
|
||||||
|
target: ["dmg", "zip"],
|
||||||
category: "public.app-category.social-networking",
|
category: "public.app-category.social-networking",
|
||||||
darkModeSupport: true,
|
darkModeSupport: true,
|
||||||
hardenedRuntime: true,
|
hardenedRuntime: true,
|
||||||
|
|||||||
+60
-45
@@ -169,59 +169,74 @@ function loadLocalConfigFile(): Json {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let loadConfigPromise: Promise<void> | undefined;
|
||||||
// Loads the config from asar, and applies a config.json from userData atop if one exists
|
// Loads the config from asar, and applies a config.json from userData atop if one exists
|
||||||
// Writes config to `global.vectorConfig`. Does nothing if `global.vectorConfig` is already set.
|
// Writes config to `global.vectorConfig`. Idempotent, returns the same promise on subsequent calls.
|
||||||
async function loadConfig(): Promise<void> {
|
function loadConfig(): Promise<void> {
|
||||||
if (global.vectorConfig) return;
|
if (loadConfigPromise) return loadConfigPromise;
|
||||||
|
|
||||||
const asarPath = await getAsarPath();
|
async function actuallyLoadConfig(): Promise<void> {
|
||||||
|
const asarPath = await getAsarPath();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`Loading app config: ${path.join(asarPath, LocalConfigFilename)}`);
|
console.log(`Loading app config: ${path.join(asarPath, LocalConfigFilename)}`);
|
||||||
global.vectorConfig = loadJsonFile(asarPath, LocalConfigFilename);
|
global.vectorConfig = loadJsonFile(asarPath, LocalConfigFilename);
|
||||||
} catch {
|
} catch {
|
||||||
// it would be nice to check the error code here and bail if the config
|
// it would be nice to check the error code here and bail if the config
|
||||||
// is unparsable, but we get MODULE_NOT_FOUND in the case of a missing
|
// is unparsable, but we get MODULE_NOT_FOUND in the case of a missing
|
||||||
// file or invalid json, so node is just very unhelpful.
|
// file or invalid json, so node is just very unhelpful.
|
||||||
// Continue with the defaults (ie. an empty config)
|
// Continue with the defaults (ie. an empty config)
|
||||||
global.vectorConfig = {};
|
global.vectorConfig = {};
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Load local config and use it to override values from the one baked with the build
|
|
||||||
const localConfig = loadLocalConfigFile();
|
|
||||||
|
|
||||||
// If the local config has a homeserver defined, don't use the homeserver from the build
|
|
||||||
// config. This is to avoid a problem where Riot thinks there are multiple homeservers
|
|
||||||
// defined, and panics as a result.
|
|
||||||
if (Object.keys(localConfig).find((k) => homeserverProps.includes(<any>k))) {
|
|
||||||
// Rip out all the homeserver options from the vector config
|
|
||||||
global.vectorConfig = Object.keys(global.vectorConfig)
|
|
||||||
.filter((k) => !homeserverProps.includes(<any>k))
|
|
||||||
.reduce(
|
|
||||||
(obj, key) => {
|
|
||||||
obj[key] = global.vectorConfig[key];
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
{} as Omit<Partial<(typeof global)["vectorConfig"]>, keyof typeof homeserverProps>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global.vectorConfig = Object.assign(global.vectorConfig, localConfig);
|
try {
|
||||||
} catch (e) {
|
// Load local config and use it to override values from the one baked with the build
|
||||||
if (e instanceof SyntaxError) {
|
const localConfig = loadLocalConfigFile();
|
||||||
void dialog.showMessageBox({
|
|
||||||
type: "error",
|
// If the local config has a homeserver defined, don't use the homeserver from the build
|
||||||
title: `Your ${global.vectorConfig.brand || "Element"} is misconfigured`,
|
// config. This is to avoid a problem where Riot thinks there are multiple homeservers
|
||||||
message:
|
// defined, and panics as a result.
|
||||||
`Your custom ${global.vectorConfig.brand || "Element"} configuration contains invalid JSON. ` +
|
if (Object.keys(localConfig).find((k) => homeserverProps.includes(<any>k))) {
|
||||||
`Please correct the problem and reopen ${global.vectorConfig.brand || "Element"}.`,
|
// Rip out all the homeserver options from the vector config
|
||||||
detail: e.message || "",
|
global.vectorConfig = Object.keys(global.vectorConfig)
|
||||||
|
.filter((k) => !homeserverProps.includes(<any>k))
|
||||||
|
.reduce(
|
||||||
|
(obj, key) => {
|
||||||
|
obj[key] = global.vectorConfig[key];
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
{} as Omit<Partial<(typeof global)["vectorConfig"]>, keyof typeof homeserverProps>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
global.vectorConfig = Object.assign(global.vectorConfig, localConfig);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof SyntaxError) {
|
||||||
|
void dialog.showMessageBox({
|
||||||
|
type: "error",
|
||||||
|
title: `Your ${global.vectorConfig.brand || "Element"} is misconfigured`,
|
||||||
|
message:
|
||||||
|
`Your custom ${global.vectorConfig.brand || "Element"} configuration contains invalid JSON. ` +
|
||||||
|
`Please correct the problem and reopen ${global.vectorConfig.brand || "Element"}.`,
|
||||||
|
detail: e.message || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Could not load local config, this is expected in most cases.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tweak modules paths as they assume the root is at the same level as webapp, but for `vector://vector/webapp` it is not.
|
||||||
|
if (Array.isArray(global.vectorConfig.modules)) {
|
||||||
|
global.vectorConfig.modules = global.vectorConfig.modules.map((m) => {
|
||||||
|
if (m.startsWith("/")) {
|
||||||
|
return "/webapp" + m;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Could not load local config, this is expected in most cases.
|
|
||||||
}
|
}
|
||||||
|
loadConfigPromise = actuallyLoadConfig();
|
||||||
|
return loadConfigPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure Electron Sentry and crashReporter using sentry.dsn in config.json if one is present.
|
// Configure Electron Sentry and crashReporter using sentry.dsn in config.json if one is present.
|
||||||
|
|||||||
Reference in New Issue
Block a user