Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions docs/design/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Do not set `Version`, `FileVersion` or `InformationalVersion` in `Bravo.csproj`:

| Value | Shape | Authoritative for |
| --- | --- | --- |
| `AssemblyFileVersion` | `X.Y.Z.{height}` | ordering two builds; MSI `ProductVersion` |
| `AssemblyFileVersion` | `X.Y.Z.{height}` | ordering two builds; MSI `ProductVersion`; the update feed `version` |
| `AssemblyInformationalVersion` | `X.Y.Z.{height}[-tag]+{commit}` | diagnostics |
| `AssemblyVersion` | `X.Y.0.0` | assembly identity (`assemblyVersion.precision: minor`) |
| `NBGV_SemVer2` | `X.Y.Z[-tag]` | artifact names, git tag, `AppVersion.SemanticVersion`, WiX `-dVersion` |
Expand All @@ -29,9 +29,15 @@ every build uniquely identifiable and orders builds that share the same `X.Y.Z`.

## Rules

- **The update feed `version` is the four-field `AssemblyFileVersion` of the release.** Installed clients compare it
with their own file version through `Version.Parse`. A three-field value compares lower than every build of the same
`X.Y.Z`, so a preview user is never told about the release that follows it; a non-numeric value makes the check fail
in every installed client ([ADR 0001](../adr/0001-releases-without-update-channels.md)).

- **The prerelease tag never reaches a numeric field.** `AssemblyFileVersion` stays numeric in every state, so
Windows Installer and `System.Version` keep working unchanged. WiX `-dVersion` carries the tag but feeds the
installer telemetry only: the MSI `ProductVersion` is bound to the file version of `Bravo.exe`.
installer telemetry only: the MSI `ProductVersion` is bound to the file version of `Bravo.exe`. Local builds made with
`publish.cmd` pass `0.0.0`, so their installer telemetry is not mistaken for a release.

- **`SemVer2` is the version that the application, the installer and the artifacts report.** The
application reads it as `ThisAssembly.NuGetPackageVersion`, which equals `SemVer2` only while
Expand Down
2 changes: 1 addition & 1 deletion publish.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ IF %ERRORLEVEL% NEQ 0 (
SET arch=x64
SET selfcontained=true
SET configuration=Release
SET version="0.0.0.999-DEV"& :: Do not change, see also <InformationalVersion> on Bravo.csproj
SET version="0.0.0"& :: 0.0.0 keeps local builds apart from releases
SET verbosity="Minimal"& :: Minimal,Normal,Diagnostic,Detailed
SET wixheat="%WIX%bin\heat.exe"
SET wixlight="%WIX%bin\light.exe"
Expand Down
6 changes: 3 additions & 3 deletions src/Controllers/ApplicationController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public IActionResult GetDiagnostics(long after = 0, int max = DiagnosticLogStore
}

/// <summary>
/// Gets the current application version for the specified <see cref="UpdateChannelType"/>
/// Gets the latest released version of the application
/// </summary>
/// <response code="200">Status200OK - Success</response>
[HttpGet]
Expand All @@ -221,9 +221,9 @@ public IActionResult GetDiagnostics(long after = 0, int max = DiagnosticLogStore
[Produces(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BravoUpdate))]
[ProducesDefaultResponseType]
public async Task<IActionResult> GetCurrentVersion(UpdateChannelType updateChannel, CancellationToken cancellationToken)
public async Task<IActionResult> GetCurrentVersion(CancellationToken cancellationToken)
{
var bravoUpdate = await CommonHelper.CheckForUpdateAsync(updateChannel, _logger, cancellationToken);
var bravoUpdate = await CommonHelper.CheckForUpdateAsync(_logger, cancellationToken);
if (bravoUpdate.IsNewerVersion)
System.Media.SystemSounds.Beep.Play();

Expand Down
29 changes: 0 additions & 29 deletions src/Infrastructure/Configuration/Settings/UserSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public interface IUserSettings

DiagnosticLevelType DiagnosticLevel { get; set; }

UpdateChannelType UpdateChannel { get; set; }

bool UpdateCheckEnabled { get; set; }

ThemeType Theme { get; set; }
Expand All @@ -28,7 +26,6 @@ public class UserSettings : IUserSettings
{
public const bool DefaultTelemetryEnabled = true;
public const DiagnosticLevelType DefaultDiagnosticLevel = DiagnosticLevelType.None;
public const UpdateChannelType DefaultUpdateChannel = UpdateChannelType.Stable;
public const bool DefaultUpdateCheckEnabled = true;
public const ThemeType DefaultTheme = ThemeType.Auto;
public const bool DefaultUseSystemBrowserForAuthentication = false;
Expand All @@ -40,9 +37,6 @@ public class UserSettings : IUserSettings
[JsonPropertyName("diagnosticLevel")]
public DiagnosticLevelType DiagnosticLevel { get; set; } = DefaultDiagnosticLevel;

[JsonPropertyName("updateChannel")]
public UpdateChannelType UpdateChannel { get; set; } = DefaultUpdateChannel;

[JsonPropertyName("updateCheckEnabled")]
public bool UpdateCheckEnabled { get; set; } = DefaultUpdateCheckEnabled;

Expand All @@ -69,29 +63,6 @@ public enum ThemeType
Dark = 2
}

public enum UpdateChannelType
{
/// <summary>
/// (Default) Stable builds are the best ones to use, they are a result of the code being built in Canary, tested in Dev and bug fixed in Beta
/// </summary>
Stable = 0,

///// <summary>
///// Beta channel is the best build to get if you’re interested in being the first one to know about upcoming features
///// </summary>
//Beta = 1,

/// <summary>
/// Dev build will carry the improvements made to the application and tested by the developers, it’s still not recommended to use it because it can have bugs
/// </summary>
Dev = 2,

///// <summary>
///// Canary build carries features that are released as soon as they’re built and are not tested or used
///// </summary>
//Canary = 3,
}

public enum DiagnosticLevelType
{
None = 0,
Expand Down
13 changes: 2 additions & 11 deletions src/Infrastructure/Helpers/CommonHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Extensions.Logging;
using Sqlbi.Bravo.Infrastructure.Configuration.Settings;
using Sqlbi.Bravo.Infrastructure.Extensions;
using Sqlbi.Bravo.Infrastructure.Windows.Interop;
using Sqlbi.Bravo.Models;
Expand Down Expand Up @@ -91,17 +90,10 @@ public static string NormalizeUriString(string uriString)
return directoryName;
}

public static async Task<BravoUpdate> CheckForUpdateAsync(UpdateChannelType updateChannel, ILogger logger, CancellationToken cancellationToken)
public static async Task<BravoUpdate> CheckForUpdateAsync(ILogger logger, CancellationToken cancellationToken)
{
var channelPath = updateChannel switch
{
UpdateChannelType.Stable => "bravo-public",
UpdateChannelType.Dev => "bravo-internal",
_ => throw new BravoUnexpectedInvalidOperationException($"Unhandled {nameof(UpdateChannelType)} value ({updateChannel})")
};

using var httpClient = new HttpClient();
var requestUri = $"https://bravorelease.blob.core.windows.net/{channelPath}/currentversion.json?nocache={DateTimeOffset.Now.ToUnixTimeSeconds()}";
var requestUri = $"https://bravorelease.blob.core.windows.net/bravo-public/currentversion.json?nocache={DateTimeOffset.Now.ToUnixTimeSeconds()}";
var json = await httpClient.GetStringAsync(requestUri, cancellationToken).ConfigureAwait(false);
LogUpdateFeedReceived(logger, json);

Expand All @@ -113,7 +105,6 @@ public static async Task<BravoUpdate> CheckForUpdateAsync(UpdateChannelType upda

return new BravoUpdate
{
UpdateChannel = updateChannel,
IsNewerVersion = availableVersion > installedVersion,
Version = availableVersion.ToString(3),
DownloadUrl = GetDownloadUrl(rootElement.GetProperty("download").GetString()!),
Expand Down
11 changes: 0 additions & 11 deletions src/Infrastructure/Policies/IPolicySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,5 @@ internal static class PolicySourceExtensions
_ => null, // Invalid policy value
};
}

/// <remarks>
/// TEnum must have int as its underlying type.
/// </remarks>
public TEnum? GetEnum<TEnum>(string name) where TEnum : struct, Enum
{
if (source.GetInt(name) is { } value && Enum.IsDefined(typeof(TEnum), value))
return (TEnum)(object)value;

return null; // Policy not set or invalid
}
}
}
7 changes: 2 additions & 5 deletions src/Infrastructure/Policies/PolicySnapshot.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Sqlbi.Bravo.Infrastructure.Configuration.Settings;

namespace Sqlbi.Bravo.Infrastructure.Policies;
namespace Sqlbi.Bravo.Infrastructure.Policies;

/// <summary>
/// Contains the effective policy values from one read of the configured sources.
Expand All @@ -10,12 +8,11 @@ namespace Sqlbi.Bravo.Infrastructure.Policies;
/// </remarks>
public sealed record PolicySnapshot(
bool? TelemetryEnabled,
UpdateChannelType? UpdateChannel,
bool? UpdateCheckEnabled,
bool? UseSystemBrowserForAuthentication,
bool? BuiltInTemplatesEnabled,
bool? CustomTemplatesEnabled,
string? CustomTemplatesOrganizationRepositoryPath)
{
public static PolicySnapshot NotConfigured { get; } = new(null, null, null, null, null, null, null);
public static PolicySnapshot NotConfigured { get; } = new(null, null, null, null, null, null);
}
6 changes: 1 addition & 5 deletions src/Infrastructure/Policies/RegistryPolicyReader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Sqlbi.Bravo.Infrastructure.Configuration.Settings;

namespace Sqlbi.Bravo.Infrastructure.Policies;
namespace Sqlbi.Bravo.Infrastructure.Policies;

internal sealed class RegistryPolicyReader(IPolicySourceFactory sourceFactory) : IPolicyReader
{
Expand All @@ -19,7 +17,6 @@ public PolicySnapshot Read()

internal static PolicySnapshot FromSource(IPolicySource source) => new(
TelemetryEnabled: source.GetBool("TelemetryEnabled"),
UpdateChannel: source.GetEnum<UpdateChannelType>("UpdateChannel"),
UpdateCheckEnabled: source.GetBool("UpdateCheckEnabled"),
UseSystemBrowserForAuthentication: source.GetBool("UseSystemBrowserForAuthentication"),
BuiltInTemplatesEnabled: source.GetBool("BuiltInTemplatesEnabled"),
Expand All @@ -31,7 +28,6 @@ internal static PolicySnapshot Merge(PolicySnapshot machinePolicies, PolicySnaps
// LocalMachine takes precedence over CurrentUser when both are configured
return new PolicySnapshot(
TelemetryEnabled: machinePolicies.TelemetryEnabled ?? userPolicies.TelemetryEnabled,
UpdateChannel: machinePolicies.UpdateChannel ?? userPolicies.UpdateChannel,
UpdateCheckEnabled: machinePolicies.UpdateCheckEnabled ?? userPolicies.UpdateCheckEnabled,
UseSystemBrowserForAuthentication: machinePolicies.UseSystemBrowserForAuthentication ?? userPolicies.UseSystemBrowserForAuthentication,
BuiltInTemplatesEnabled: machinePolicies.BuiltInTemplatesEnabled ?? userPolicies.BuiltInTemplatesEnabled,
Expand Down
21 changes: 1 addition & 20 deletions src/Infrastructure/Policies/Templates/bravo.admx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- (c) SQLBI Corporation -->
<policyDefinitions revision="1.0" schemaVersion="1.0">
<policyDefinitions revision="1.1" schemaVersion="1.0">

<policyNamespaces>
<target prefix="bravo" namespace="SQLBI.Policies.Bravo" />
Expand Down Expand Up @@ -45,25 +45,6 @@
</disabledValue>
</policy>

<policy name="UpdateChannel" class="Both" displayName="$(string.UpdateChannel)" explainText="$(string.UpdateChannel_explanation)" key="Software\Policies\SQLBI\Bravo\OptionSettings" presentation="$(presentation.UpdateChannel)">
<parentCategory ref="OptionSettings" />
<supportedOn ref="windows:SUPPORTED_Windows7" />
<elements>
<enum id="UpdateChannel" valueName="UpdateChannel">
<item displayName="$(string.UpdateChannel_Stable)">
<value>
<decimal value="0"/>
</value>
</item>
<item displayName="$(string.UpdateChannel_Dev)">
<value>
<decimal value="2"/>
</value>
</item>
</enum>
</elements>
</policy>

<policy name="UpdateCheckEnabled" class="Both" displayName="$(string.UpdateCheckEnabled)" explainText="$(string.UpdateCheckEnabled_explanation)" key="Software\Policies\SQLBI\Bravo\OptionSettings" valueName="UpdateCheckEnabled">
<parentCategory ref="OptionSettings" />
<supportedOn ref="windows:SUPPORTED_Windows7" />
Expand Down
19 changes: 1 addition & 18 deletions src/Infrastructure/Policies/Templates/en-US/bravo.adml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- (c) SQLBI Corporation -->
<policyDefinitionResources revision="1.0" schemaVersion="1.0">
<policyDefinitionResources revision="1.1" schemaVersion="1.0">
<displayName></displayName>
<description></description>
<resources>
Expand Down Expand Up @@ -29,15 +29,6 @@
If the status is set to Disabled, the application uses an embedded web browser for for interactive authentication.
</string>

<string id="UpdateChannel">Configure the release channel to be used when checking for updates</string>
<string id="UpdateChannel_Stable">STABLE - stable build release channel</string>
<string id="UpdateChannel_Dev">DEV - internal development build release channel</string>
<string id="UpdateChannel_explanation">
If the status is set to Not Configured or Disabled, the stable channel are used by default and this setting is configured according to user preferences.

If the status is set to Enabled, the selected update channel is forcibly used.
</string>

<string id="UpdateCheckEnabled">Configure update checking and update notifications</string>
<string id="UpdateCheckEnabled_explanation">
If the status is set to Not Configured, this setting is configured according to user preferences.
Expand All @@ -58,13 +49,5 @@

</stringTable>

<presentationTable>

<presentation id="UpdateChannel">
<dropdownList refId="UpdateChannel" noSort="true">Channels</dropdownList>
</presentation>

</presentationTable>

</resources>
</policyDefinitionResources>
5 changes: 0 additions & 5 deletions src/Models/BravoOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ private BravoOptions(IUserSettings userSettings)
{
TelemetryEnabled = userSettings.TelemetryEnabled;
DiagnosticLevel = userSettings.DiagnosticLevel;
UpdateChannel = userSettings.UpdateChannel;
UpdateCheckEnabled = userSettings.UpdateCheckEnabled;
Theme = userSettings.Theme;
Proxy = userSettings.Proxy;
Expand All @@ -30,9 +29,6 @@ private BravoOptions(IUserSettings userSettings)
[JsonPropertyName("diagnosticLevel")]
public DiagnosticLevelType DiagnosticLevel { get; set; } = UserSettings.DefaultDiagnosticLevel;

[JsonPropertyName("updateChannel")]
public UpdateChannelType UpdateChannel { get; set; } = UserSettings.DefaultUpdateChannel;

[JsonPropertyName("updateCheckEnabled")]
public bool UpdateCheckEnabled { get; set; } = UserSettings.DefaultUpdateCheckEnabled;

Expand Down Expand Up @@ -65,7 +61,6 @@ public void SaveToUserPreferences()
{
settings.TelemetryEnabled = TelemetryEnabled;
settings.DiagnosticLevel = DiagnosticLevel;
settings.UpdateChannel = UpdateChannel;
settings.UpdateCheckEnabled = UpdateCheckEnabled;
settings.Theme = Theme;
settings.Proxy = Proxy;
Expand Down
21 changes: 2 additions & 19 deletions src/Models/BravoUpdate.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
using System.Text.Json.Serialization;
using Sqlbi.Bravo.Infrastructure.Configuration.Settings;

namespace Sqlbi.Bravo.Models;

public interface IUpdateInfo
public class BravoUpdate
{
UpdateChannelType? UpdateChannel { get; set; }

bool IsNewerVersion { get; set; }

string? Version { get; set; }

string? DownloadUrl { get; set; }

string? ChangelogUrl { get; set; }
}

public class BravoUpdate : IUpdateInfo
{
[JsonPropertyName("updateChannel")]
public UpdateChannelType? UpdateChannel { get; set; }

[JsonPropertyName("isNewerVersion")]
public bool IsNewerVersion { get; set; } = false;
public bool IsNewerVersion { get; set; }

[JsonPropertyName("version")]
public string? Version { get; set; }
Expand Down
4 changes: 2 additions & 2 deletions src/Scripts/controllers/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,11 @@ export class App {

if (automatic && !optionsController.getOption("updateCheckEnabled")) return;

return host.getCurrentVersion(optionsController.getOption("updateChannel"))
return host.getCurrentVersion()
.then(data => {

let newVersion = null;
if (data.updateChannel == optionsController.getOption("updateChannel") && data.isNewerVersion) {
if (data.isNewerVersion) {
newVersion = new AppVersion({
version: data.version,
downloadUrl: data.downloadUrl,
Expand Down
7 changes: 3 additions & 4 deletions src/Scripts/controllers/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { /*TokenUpdateWebMessage,*/ WebMessage, WebMessageType } from '../model/
import { PBICloudDataset, PBICloudDatasetConnectionMode } from '../model/pbi-dataset';
import { FormattedMeasure, TabularDatabase, TabularDatabaseServer, TabularMeasure, TabularTable } from '../model/tabular';
import { Account, SignInRequest } from './auth';
import { DiagnosticLevelType, FormatDaxOptions, Options, UpdateChannelType } from './options';
import { DiagnosticLevelType, FormatDaxOptions, Options } from './options';
import { PBIDesktopReport, PBIDesktopReportConnectionMode } from '../model/pbi-report';
import { ThemeType } from './theme';
import { i18n } from '../model/i18n';
Expand Down Expand Up @@ -190,7 +190,6 @@ export interface CreateDateTemplateRequest {
}

export interface BravoUpdate {
updateChannel: UpdateChannelType
version?: string
downloadUrl?: string
changelogUrl?: string
Expand Down Expand Up @@ -625,8 +624,8 @@ export class Host extends Dispatchable {
return <Promise<DiagnosticLogPage>>this.apiCall("api/GetDiagnostics", { after: after, max: max });
}

getCurrentVersion(updateChannel: UpdateChannelType) {
return <Promise<BravoUpdate>>this.apiCall("api/GetCurrentVersion", { updateChannel: updateChannel });
getCurrentVersion() {
return <Promise<BravoUpdate>>this.apiCall("api/GetCurrentVersion");
}

fileSystemOpen(path: string) {
Expand Down
Loading
Loading