Skip to content

Commit 2d487b4

Browse files
authored
Merge pull request #1193 from nextcloud/chore/build-config
chore: build config
2 parents 38b98ac + 3891cd9 commit 2d487b4

22 files changed

+364
-93
lines changed

REUSE.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,13 @@ SPDX-FileCopyrightText = "2017 Feandesign https://soundcloud.com/feandesign"
5555
SPDX-License-Identifier = "CC0-1.0"
5656

5757
[[annotations]]
58-
path = ["img/talk-**.svg", "img/icons/**", "img/squirrel-install-loading.gif", "Nextcloud-Talk-light.png", "Nextcloud-Talk-dark.png"]
58+
path = ["img/talk-**.svg", "img/icons/**", "img/squirrel-install-loading.gif", "img/server-logo-plain.svg", "Nextcloud-Talk-light.png", "Nextcloud-Talk-dark.png"]
5959
precedence = "aggregate"
6060
SPDX-FileCopyrightText = "Nextcloud GmbH <https://nextcloud.com/trademarks/>"
6161
SPDX-License-Identifier = "LicenseRef-NextcloudTrademarks"
62+
63+
[[annotations]]
64+
path = ["build/config.json"]
65+
precedence = "aggregate"
66+
SPDX-FileCopyrightText = "2025 Nextcloud GmbH and Nextcloud contributors"
67+
SPDX-License-Identifier = "AGPL-3.0-or-later"

build/BuildConfig.types.ts

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
export type BuildConfigFile = {
7+
/***********
8+
* General *
9+
***********/
10+
11+
/**
12+
* Application name.
13+
* Used in executable file name, installer, shortcuts, window title, etc.
14+
* Default: 'Nextcloud Talk'
15+
*/
16+
applicationName: string
17+
18+
19+
/**
20+
* Description.
21+
* Used in metadata and help.
22+
* Default: 'Official Desktop client for {applicationName}'
23+
*/
24+
description: string,
25+
26+
/**
27+
* Default: null
28+
*/
29+
domain: string | null
30+
31+
/**
32+
* Default: false
33+
*/
34+
enforceDomain: boolean
35+
36+
/**
37+
* Whether multi account is enabled.
38+
* NOT IMPLEMENTED
39+
* Default: false
40+
*/
41+
multiAccount: boolean
42+
43+
/**
44+
* Brand color.
45+
* NOT IMPLEMENTED
46+
* Default: '#0082C9'
47+
*/
48+
brandColor: string
49+
50+
/**
51+
* Brand font color.
52+
* NOT IMPLEMENTED
53+
*/
54+
brandFontColor: string
55+
56+
/**
57+
* URL providing users with more information about the product and how to use it.
58+
* NOT IMPLEMENTED
59+
* Default: 'https://help.nextcloud.com/'
60+
*/
61+
helpUrl: string
62+
63+
/**
64+
* URL providing users with more information about the privacy policy of service.
65+
* Default: 'https://nextcloud.com/privacy' for app menu and Nextcloud theming settings on the help.
66+
*/
67+
privacyUrl: string
68+
69+
/****************
70+
* Distribution *
71+
****************/
72+
73+
/**
74+
* Windows one-click single-user installer via Squirrel.Windows.
75+
* Default: true
76+
*/
77+
windowsExe: boolean
78+
79+
/**
80+
* Windows machine-wide classic installer via WiX v3.
81+
* Recommended for administrative environments.
82+
* Default: true
83+
*/
84+
windowsMsi: boolean
85+
86+
/**
87+
* macOS DMG installer.
88+
* Default: true
89+
*/
90+
macosDmg: boolean
91+
92+
/**
93+
* Linux Flatpak single-file installer.
94+
* Default: true
95+
*/
96+
linuxFlatpak: boolean
97+
98+
/**
99+
* Linux .zip archive.
100+
* Default: true
101+
*/
102+
linuxZip: boolean
103+
104+
/***************
105+
* OS-Specific *
106+
***************/
107+
108+
/**
109+
* Apple AppBundleID for macOS.
110+
* Default: 'com.nextcloud.talk.mac'
111+
*/
112+
appleAppBundleId: string
113+
114+
/**
115+
* Windows AppUserModelId.
116+
* Default: 'com.nextcloud.talk'
117+
*/
118+
winAppId: string
119+
120+
/**
121+
* Linux AppId.
122+
* Default: 'com.nextcloud.talk'
123+
*/
124+
linuxAppId: string
125+
}
126+
127+
/**
128+
* Computed configs, that cannot be overridden
129+
*/
130+
export type BuildConfigInferred = {
131+
/**
132+
* Whether it is a branded build with a custom config.
133+
* Default: false
134+
*/
135+
isBranded: boolean
136+
137+
/**
138+
* Application name without non-alphanumeral characters
139+
*/
140+
applicationNameSanitized: string
141+
142+
/**
143+
* Windows.Squirrel AppUserModelId suffix for Windows.
144+
* It must be Sanitized application name.
145+
* Squirrel then will use com.squirrel.{AppId}.{AppId} as AppUserModelId.
146+
* Default: 'NextcloudTalk'
147+
*/
148+
winSquirrelAppId: string
149+
150+
/**
151+
* Copyright string.
152+
* Used in metadata. Cannot be empty.
153+
* Copyright (c) {year} Nextcloud GmbH
154+
*/
155+
copyright: string
156+
157+
/**
158+
* Company name.
159+
* Used in metadata and help.
160+
*/
161+
companyName: string
162+
}
163+
164+
export type BuildConfig = BuildConfigFile & BuildConfigInferred

build/config.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"applicationName": "Nextcloud Talk",
3+
"domain": null,
4+
"enforceDomain": false,
5+
"brandColor": "#0082C9",
6+
"brandFontColor": "#FFFFFF",
7+
"helpUrl": "https://nextcloud.com/talk/",
8+
"privacyUrl": "https://nextcloud.com/privacy/",
9+
"windowsExe": true,
10+
"windowsMsi": true,
11+
"macosDmg": true,
12+
"linuxFlatpak": true,
13+
"linuxZip": true
14+
}

build/resolveBuildConfig.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
const path = require('node:path')
7+
const fs = require('node:fs')
8+
const defaultConfig = require('./config.json')
9+
10+
/**
11+
* Resolve the build configuration
12+
*
13+
* @param {string} [customConfigPath] - Path to the custom configuration file
14+
* @return {import('./BuildConfig.types.ts').BuildConfig} - Resolved configuration object
15+
*/
16+
function resolveBuildConfig(customConfigPath = process.env.CUSTOM_CONFIG) {
17+
/** @type {Partial<import('./BuildConfig.types.ts').BuildConfigFile>} */
18+
const customConfig = customConfigPath ? JSON.parse(fs.readFileSync(customConfigPath, 'utf-8')) : {}
19+
20+
// Remove all undefined values
21+
// TODO: check if undefiend values can be empty strings or only null
22+
for (const key in customConfig) {
23+
if (customConfig[key] === null) {
24+
delete customConfig[key]
25+
}
26+
}
27+
28+
/** @type {import('./BuildConfig.types.ts').BuildConfigFile} */
29+
const config = {
30+
...defaultConfig,
31+
...customConfig,
32+
}
33+
34+
// Sanitized name - application name without non-alphanumeral characters
35+
const applicationNameSanitized = config.applicationName.replace(/[^a-z0-9]/gi, '')
36+
37+
// Generate appId in DNS notation from domain
38+
const appIdHost = config.domain
39+
? new URL(config.domain).host.split('.').reverse().join('.')
40+
: 'com.nextcloud'
41+
42+
return {
43+
// Default inferred values - can be overridden by the custom config
44+
appleAppBundleId: `${appIdHost}.talk.mac`,
45+
linuxAppId: `${appIdHost}.talk`,
46+
winAppId: `${appIdHost}.talk`,
47+
description: `Official desktop client for ${config.applicationName}`,
48+
49+
// Custom config with defaults
50+
...config,
51+
52+
// Inferred values, cannot be overridden by the custom config
53+
isBranded: Boolean(customConfigPath),
54+
companyName: 'Nextcloud GmbH',
55+
copyright: 'Copyright (c) {year} Nextcloud GmbH'.replace('{year}', new Date().getFullYear()),
56+
applicationNameSanitized,
57+
winSquirrelAppId: applicationNameSanitized, // Special case for Squirrel.Windows
58+
}
59+
}
60+
61+
module.exports = {
62+
resolveConfig: resolveBuildConfig,
63+
}

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export default [
3838
__CHANNEL__: 'readonly',
3939
__VERSION_TAG__: 'readonly',
4040
__TALK_VERSION_TAG__: 'readonly',
41+
__BUILD_CONFIG__: 'readonly',
4142
// Electron
4243
...globals.node,
4344
},

0 commit comments

Comments
 (0)