From 930781cccf042ff113ac01b15daa8ebe20c4468f Mon Sep 17 00:00:00 2001 From: Johannes Faltermeier Date: Thu, 18 Jan 2024 12:25:09 +0100 Subject: [PATCH] Introduce Update Channels #278 * adapt main build Jenkinsfile to not publish at the release location "theia/ide" but at "theia/ide-preview" * create dedicated * add a preference for selecting an update channel * add additional method to updater that allows passing the channel --- Jenkinsfile | 24 +++--- releng/promote/Jenkinsfile | 73 +++++++++++++++++++ .../src/common/updater/theia-updater.ts | 1 + .../theia-updater-frontend-contribution.ts | 7 ++ .../updater/theia-updater-preferences.ts | 7 +- .../update/theia-updater-impl.ts | 26 +++++++ 6 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 releng/promote/Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile index 0df04b7d2..8aab7a0ec 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -399,12 +399,12 @@ def uploadInstaller(String platform) { def packageJSON = readJSON file: "package.json" String version = "${packageJSON.version}" sshagent(['projects-storage.eclipse.org-bot-ssh']) { - sh "ssh genie.theia@projects-storage.eclipse.org rm -rf /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}" - sh "ssh genie.theia@projects-storage.eclipse.org mkdir -p /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}" - sh "scp ${distFolder}/*.* genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}" - sh "ssh genie.theia@projects-storage.eclipse.org rm -rf /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}" - sh "ssh genie.theia@projects-storage.eclipse.org mkdir -p /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}" - sh "scp ${distFolder}/*.* genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}" + sh "ssh genie.theia@projects-storage.eclipse.org rm -rf /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}" + sh "ssh genie.theia@projects-storage.eclipse.org mkdir -p /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}" + sh "scp ${distFolder}/*.* genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}" + sh "ssh genie.theia@projects-storage.eclipse.org rm -rf /home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}" + sh "ssh genie.theia@projects-storage.eclipse.org mkdir -p /home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}" + sh "scp ${distFolder}/*.* genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}" } } else { echo "Skipped upload for branch ${env.BRANCH_NAME}" @@ -421,16 +421,16 @@ def copyInstallerAndUpdateLatestYml(String platform, String installer, String ex def packageJSON = readJSON file: "package.json" String version = "${packageJSON.version}" sshagent(['projects-storage.eclipse.org-bot-ssh']) { - sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}/${installer}.${extension} /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}/${installer}-${version}.${extension}" - sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}/${installer}.${extension} /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}/${installer}-${version}.${extension}" - sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}/${installer}.${extension}.blockmap /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}/${installer}-${version}.${extension}.blockmap" - sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}/${installer}.${extension}.blockmap /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}/${installer}-${version}.${extension}.blockmap" + sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}/${installer}.${extension} /home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}/${installer}-${version}.${extension}" + sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/${installer}.${extension} /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/${installer}-${version}.${extension}" + sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}/${installer}.${extension}.blockmap /home/data/httpd/download.eclipse.org/theia/ide-preview/latest/${platform}/${installer}-${version}.${extension}.blockmap" + sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/${installer}.${extension}.blockmap /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/${installer}-${version}.${extension}.blockmap" } if (UPDATABLE_VERSIONS.length() != 0) { for (oldVersion in UPDATABLE_VERSIONS.split(",")) { sshagent(['projects-storage.eclipse.org-bot-ssh']) { - sh "ssh genie.theia@projects-storage.eclipse.org rm -f /home/data/httpd/download.eclipse.org/theia/ide/${oldVersion}/${platform}/${yaml}" - sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}/${yaml} /home/data/httpd/download.eclipse.org/theia/ide/${oldVersion}/${platform}/${yaml}" + sh "ssh genie.theia@projects-storage.eclipse.org rm -f /home/data/httpd/download.eclipse.org/theia/ide-preview/${oldVersion}/${platform}/${yaml}" + sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/${yaml} /home/data/httpd/download.eclipse.org/theia/ide-preview/${oldVersion}/${platform}/${yaml}" } } } else { diff --git a/releng/promote/Jenkinsfile b/releng/promote/Jenkinsfile new file mode 100644 index 000000000..11bd64c45 --- /dev/null +++ b/releng/promote/Jenkinsfile @@ -0,0 +1,73 @@ +/** + * This Jenkinsfile promotes a given version of the Theia IDE from /theia/ide-preview to /theia/ide + */ + +/* groovylint-disable NestedBlockDepth */ +import groovy.json.JsonSlurper + +pipeline { + agent none + options { + timeout(time: 3, unit: 'HOURS') + disableConcurrentBuilds() + } + environment { + } + stages { + + stage('Setup parameters') { + steps { + script { + properties([ + parameters([ + string( + defaultValue: 'latest', + name: 'VERSION', + trim: true + ) + ]) + ]) + } + } + } + + stage('Promote') { + agent any + steps { + script { + promote('linux', params.VERSION) + promote('macos', params.VERSION) + promote('windows', params.VERSION) + + // update latest.yaml on windows for differential updater + updateLatestYaml('windows', params.VERSION, 'TheiaIDESetup', 'exe', 'latest.yml', '') //'1.41.0,1.42.1,1.43.0') + } + } + } + } +} + +def promote(String platform, String version) { + sshagent(['projects-storage.eclipse.org-bot-ssh']) { + sh "ssh genie.theia@projects-storage.eclipse.org rm -rf /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}" + sh "ssh genie.theia@projects-storage.eclipse.org mkdir -p /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}" + sh "scp genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/*.* genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}" + + sh "ssh genie.theia@projects-storage.eclipse.org rm -rf /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}" + sh "ssh genie.theia@projects-storage.eclipse.org mkdir -p /home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}" + sh "scp genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide-preview/${version}/${platform}/*.* genie.theia@projects-storage.eclipse.org:/home/data/httpd/download.eclipse.org/theia/ide/latest/${platform}" + } +} + +def updateLatestYaml(String platform, String version, String installer, String extension, String yaml, String UPDATABLE_VERSIONS) { + if (UPDATABLE_VERSIONS.length() != 0) { + for (oldVersion in UPDATABLE_VERSIONS.split(",")) { + sshagent(['projects-storage.eclipse.org-bot-ssh']) { + sh "ssh genie.theia@projects-storage.eclipse.org rm -f /home/data/httpd/download.eclipse.org/theia/ide/${oldVersion}/${platform}/${yaml}" + sh "ssh genie.theia@projects-storage.eclipse.org cp /home/data/httpd/download.eclipse.org/theia/ide/${version}/${platform}/${yaml} /home/data/httpd/download.eclipse.org/theia/ide/${oldVersion}/${platform}/${yaml}" + } + } + } else { + echo "No updateable versions" + } +} diff --git a/theia-extensions/updater/src/common/updater/theia-updater.ts b/theia-extensions/updater/src/common/updater/theia-updater.ts index ac7f33132..91c419404 100644 --- a/theia-extensions/updater/src/common/updater/theia-updater.ts +++ b/theia-extensions/updater/src/common/updater/theia-updater.ts @@ -16,6 +16,7 @@ export interface TheiaUpdater extends JsonRpcServer { downloadUpdate(): void; onRestartToUpdateRequested(): void; disconnectClient(client: TheiaUpdaterClient): void; + setUpdateChannel(channel: string): void; } export const TheiaUpdaterClient = Symbol('TheiaUpdaterClient'); diff --git a/theia-extensions/updater/src/electron-browser/updater/theia-updater-frontend-contribution.ts b/theia-extensions/updater/src/electron-browser/updater/theia-updater-frontend-contribution.ts index ae17e27d1..b7d3fce42 100644 --- a/theia-extensions/updater/src/electron-browser/updater/theia-updater-frontend-contribution.ts +++ b/theia-extensions/updater/src/electron-browser/updater/theia-updater-frontend-contribution.ts @@ -136,6 +136,13 @@ export class TheiaUpdaterFrontendContribution implements CommandContribution, Me @postConstruct() protected init(): void { + this.preferenceService.ready.then(() => this.updater.setUpdateChannel(this.preferenceService.get('updates.channel', 'stable'))); + this.preferenceService.onPreferenceChanged(e => { + if (e.preferenceName === 'updates.channel') { + this.updater.setUpdateChannel(this.preferenceService.get('updates.channel', 'stable')); + } + }); + this.updaterClient.onUpdateAvailable(available => { if (available) { this.handleDownloadUpdate(); diff --git a/theia-extensions/updater/src/electron-browser/updater/theia-updater-preferences.ts b/theia-extensions/updater/src/electron-browser/updater/theia-updater-preferences.ts index befbb7eca..335a53ba8 100644 --- a/theia-extensions/updater/src/electron-browser/updater/theia-updater-preferences.ts +++ b/theia-extensions/updater/src/electron-browser/updater/theia-updater-preferences.ts @@ -16,6 +16,11 @@ export const theiaUpdaterPreferenceSchema: PreferenceSchema = { type: 'boolean', description: 'Report available updates after application start.', default: true - } + }, + 'updates.channel': { + type: 'string', + enum: ['stable', 'preview'], // once we have a nightly/next build, we can add a third channel + default: 'stable' + }, } }; diff --git a/theia-extensions/updater/src/electron-main/update/theia-updater-impl.ts b/theia-extensions/updater/src/electron-main/update/theia-updater-impl.ts index fdc5298e0..6496b6ce7 100644 --- a/theia-extensions/updater/src/electron-main/update/theia-updater-impl.ts +++ b/theia-extensions/updater/src/electron-main/update/theia-updater-impl.ts @@ -14,6 +14,15 @@ import * as path from 'path'; import { ElectronMainApplication, ElectronMainApplicationContribution } from '@theia/core/lib/electron-main/electron-main-application'; import { TheiaUpdater, TheiaUpdaterClient } from '../../common/updater/theia-updater'; import { injectable } from '@theia/core/shared/inversify'; +import { isOSX, isWindows } from '@theia/core'; + +const STABLE_CHANNEL_WINDOWS = 'https://download.eclipse.org/theia/ide/version/windows'; +const STABLE_CHANNEL_MACOS = 'https://download.eclipse.org/theia/ide/latest/macos'; +const STABLE_CHANNEL_LINUX = 'https://download.eclipse.org/theia/ide/latest/linux'; + +const PREVIEW_CHANNEL_WINDOWS = 'https://download.eclipse.org/theia/ide-preview/version/windows'; +const PREVIEW_CHANNEL_MACOS = 'https://download.eclipse.org/theia/ide-preview/latest/macos'; +const PREVIEW_CHANNEL_LINUX = 'https://download.eclipse.org/theia/ide-preview/latest/linux'; const { autoUpdater } = require('electron-updater'); @@ -102,6 +111,23 @@ export class TheiaUpdaterImpl implements TheiaUpdater, ElectronMainApplicationCo } } + setUpdateChannel(channel: string): void { + const feedURL = this.getFeedURL(channel); + console.log('JF' + channel + '. ' + feedURL); + autoUpdater.setFeedURL(feedURL); + } + + protected getFeedURL(channel: string): string { + if (isWindows) { + const curVersion = autoUpdater.currentVersion.toString(); + return (channel === 'preview') ? PREVIEW_CHANNEL_WINDOWS.replace('version', curVersion) : STABLE_CHANNEL_WINDOWS.replace('version', curVersion); + } else if (isOSX) { + return (channel === 'preview') ? PREVIEW_CHANNEL_MACOS : STABLE_CHANNEL_MACOS; + } else { + return (channel === 'preview') ? PREVIEW_CHANNEL_LINUX : STABLE_CHANNEL_LINUX; + } + } + disconnectClient(client: TheiaUpdaterClient): void { const index = this.clients.indexOf(client); if (index !== -1) {