Beispiel #1
0
        static BuildInfo()
        {
            if (!ReleaseVersion.TryParse(VersionString, out Version))
            {
                Version = new ReleaseVersion(0, 0, 0, ReleaseCandidateLevel.Local);
            }

            DateTime.TryParse("@PACKAGE_BUILD_DATE@", out Date);

            #if DEBUG
            IsLocalDebugBuild = Version.CandidateLevel == ReleaseCandidateLevel.Local;
            #else
            IsLocalDebugBuild = false;
            #endif
        }
        public void ValidVersion(
            string expectedSemVer,
            string expectedWindowsFileVersion,
            string expectedCFBundleVersion,
            string expectedCFBundleShortVersionString)
        {
            ReleaseVersion version;

            // parse and assert the semver format
            ReleaseVersion.TryParse(expectedSemVer, out version).ShouldBeTrue();
            version.ToString().ShouldEqual(expectedSemVer);

            // parse and assert the windows file version format
            var windowsFileVersion = version.ToWindowsFileVersion();

            windowsFileVersion.ToString().ShouldEqual(expectedWindowsFileVersion);
            version.WithBuild(0).ShouldEqual(ReleaseVersion.FromWindowsFileVersion(windowsFileVersion));

            if (expectedCFBundleVersion == null)
            {
                Assert.Throws <FormatException> (
                    () => version.ToString(ReleaseVersionFormat.AppleCFBundleVersion));
            }
            else
            {
                version.ToString(ReleaseVersionFormat.AppleCFBundleVersion)
                .ShouldEqual(expectedCFBundleVersion);
            }

            if (expectedCFBundleShortVersionString == null)
            {
                Assert.Throws <FormatException> (
                    () => version.ToString(ReleaseVersionFormat.AppleCFBundleShortVersion));
            }
            else
            {
                version.ToString(ReleaseVersionFormat.AppleCFBundleShortVersion)
                .ShouldEqual(expectedCFBundleShortVersionString);
            }
        }
Beispiel #3
0
        Task <UpdateItem> CheckForUpdatesAsync(
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var targetChannel = UpdateChannel;

            return(Task.Run(async() => {
                var uri = new StringBuilder("https://software.xamarin.com/Service/Updates?v=2&pv")
                          .Append(productId)
                          .Append('=')
                          .Append(BuildInfo.UpdateVersion)
                          .Append("&m=").Append(productId)
                          .Append("&level=").Append(targetChannel)
                          .Append("&alevel=").Append(targetChannel)
                          .Append("&os=").Append(operatingSystem);

                Log.Debug(TAG, $"querying update service: {uri}");

                var httpClient = CreateHttpClient();
                var response = (await httpClient.GetAsync(
                                    uri.ToString(),
                                    HttpCompletionOption.ResponseContentRead,
                                    cancellationToken)).EnsureSuccessStatusCode();

                // NOTE: the await expression to produce 'manifest' is pulled out
                // of the null-coalescing expression that follows due to a bug in
                // mcs that results in an NRE if one object in the query is null
                // when the await is a subexpression of the null-coalescing chain
                var manifest = UpdateManifest
                               .Deserialize(await response.Content.ReadAsStreamAsync());

                var update = manifest
                             ?.Applications
                             ?.FirstOrDefault()
                             ?.Updates
                             ?.FirstOrDefault();

                if (update != null && !update.IsValid)
                {
                    throw new Exception(Catalog.GetString(
                                            "Update service returned an update but it could not be parsed."));
                }

                updateChecksPerformed++;

                MainThread.Post(() => Prefs.Updater.LastQuery.SetValue(DateTime.UtcNow));

                if (update == null)
                {
                    return null;
                }

                Log.Debug(TAG, $"update service returned update: {update.Version} published {update.Date}");

                var releaseNotesUrl = $"https://dl.xamarin.com/interactive/updater-release-notes-{update.Version}.html";

                try {
                    httpClient = CreateHttpClient();
                    response = (await httpClient.GetAsync(
                                    releaseNotesUrl,
                                    HttpCompletionOption.ResponseContentRead,
                                    cancellationToken)).EnsureSuccessStatusCode();
                    update.ReleaseNotes = await response.Content.ReadAsStringAsync();
                } catch (Exception e) when(!(e is TaskCanceledException || e is OperationCanceledException))
                {
                    Log.Warning(TAG, $"{update.Version} update available but release notes are missing: {releaseNotesUrl}", e);
                }

                ReleaseVersion.TryParse(update.Version, out var semver);

                return new UpdateItem(
                    semver,
                    update.Version,
                    update.ReleaseNotes,
                    targetChannel,
                    update.Url,
                    update.Hash);
            }));
        }
Beispiel #4
0
        internal static void GetInstalledWorkloads(IWorkloadResolver workloadResolver, SdkFeatureBand sdkFeatureBand,
                                                   InstalledWorkloadsCollection installedWorkloads)
        {
            IEnumerable <string> visualStudioWorkloadIds     = GetAvailableVisualStudioWorkloads(workloadResolver);
            HashSet <string>     installedWorkloadComponents = new();

            // Visual Studio instances contain a large set of packages and we have to perform a linear
            // search to determine whether a matching SDK was installed and look for each installable
            // workload from the SDK. The search is optimized to only scan each set of packages once.
            foreach (ISetupInstance2 instance in GetVisualStudioInstances())
            {
                ISetupPackageReference[] packages = instance.GetPackages();
                bool hasMatchingSdk = false;
                installedWorkloadComponents.Clear();

                for (int i = 0; i < packages.Length; i++)
                {
                    string packageId = packages[i].GetId();

                    if (string.IsNullOrWhiteSpace(packageId))
                    {
                        // Visual Studio already verifies the setup catalog at build time. If the package ID is empty
                        // the catalog is likely corrupted.
                        continue;
                    }

                    if (packageId.StartsWith(s_visualStudioSdkPackageIdPrefix))
                    {
                        // After trimming the package prefix we should be left with a valid semantic version. If we can't
                        // parse the version we'll skip this instance.
                        if (!ReleaseVersion.TryParse(packageId.Substring(s_visualStudioSdkPackageIdPrefix.Length),
                                                     out ReleaseVersion visualStudioSdkVersion))
                        {
                            break;
                        }

                        SdkFeatureBand visualStudioSdkFeatureBand = new SdkFeatureBand(visualStudioSdkVersion);

                        // The feature band of the SDK in VS must match that of the SDK on which we're running.
                        if (!visualStudioSdkFeatureBand.Equals(sdkFeatureBand))
                        {
                            break;
                        }

                        hasMatchingSdk = true;

                        continue;
                    }

                    if (visualStudioWorkloadIds.Contains(packageId, StringComparer.OrdinalIgnoreCase))
                    {
                        // Normalize back to an SDK style workload ID.
                        installedWorkloadComponents.Add(packageId.Replace('.', '-'));
                    }
                }

                if (hasMatchingSdk)
                {
                    foreach (string id in installedWorkloadComponents)
                    {
                        installedWorkloads.Add(id, $"VS {instance.GetInstallationVersion()}");
                    }
                }
            }
        }
Beispiel #5
0
        void ProcessReleaseFile(ReleaseFile releaseFile)
        {
            var relativePath         = releaseFile.PublishUri;
            var relativePathFileName = Path.GetFileName(relativePath);

            var updaterItem = updaterFileRegex.Match(relativePathFileName);

            if (updaterItem == null || !updaterItem.Success)
            {
                return;
            }

            releaseFile.ProductType = 11; // no idea!
            releaseFile.ProductName = ProductName;

            releaseFile.UpdaterProduct = new XamarinUpdaterProduct {
                Version = updaterItem.Groups ["version"].Value
            };

            if (UpdateInfoFile != null)
            {
                releaseFile.UpdaterProduct.PopulateFromUpdateinfoFile(UpdateInfoFile);
            }

            if (UpdaterReleaseNotes != null)
            {
                releaseFile.UpdaterProduct.Blurb = string
                                                   .Join("\n", UpdaterReleaseNotes)
                                                   .Trim();
            }

            if (!ReleaseVersion.TryParse(releaseFile.UpdaterProduct.Version, out var version))
            {
                return;
            }

            if (version.CandidateLevel == ReleaseCandidateLevel.Stable &&
                updaterItem.Groups ["extension"].Value == ".pkg")
            {
                releaseFile.UploadEnvironments |= UploadEnvironments.XamarinInstaller;
            }

            releaseFile.UploadEnvironments |= UploadEnvironments.XamarinUpdater;

            switch (version.CandidateLevel)
            {
            case ReleaseCandidateLevel.Alpha:
                releaseFile.UpdaterProduct.Channels =
                    XamarinUpdaterChannels.Alpha;
                break;

            case ReleaseCandidateLevel.Beta:
            case ReleaseCandidateLevel.StableCandidate:
                releaseFile.UpdaterProduct.Channels =
                    XamarinUpdaterChannels.Alpha |
                    XamarinUpdaterChannels.Beta;
                break;

            case ReleaseCandidateLevel.Stable:
                releaseFile.UpdaterProduct.Channels =
                    XamarinUpdaterChannels.Alpha |
                    XamarinUpdaterChannels.Beta |
                    XamarinUpdaterChannels.Stable;
                break;
            }
        }
Beispiel #6
0
        PublicationItem ProcessItem(PublicationItem item)
        {
            var relativePath         = item.RelativePublishUrl.ToString();
            var relativePathFileName = Path.GetFileName(relativePath);

            if (pdbArchiveRegex.IsMatch(relativePathFileName))
            {
                item.RelativePublishUrl = null;
                return(item);
            }

            var updaterItem = updaterFileRegex.Match(relativePathFileName);

            if (updaterItem == null || !updaterItem.Success)
            {
                return(item);
            }

            if (string.IsNullOrEmpty(ReleaseName))
            {
                ReleaseName = $"{updaterItem.Groups ["name"]}-{updaterItem.Groups ["version"]}";
            }

            if (UpdateInfoFile != null)
            {
                item.UpdaterProduct = UpdaterProduct.FromUpdateInfo(
                    File.ReadAllText(UpdateInfoFile));
            }
            else
            {
                item.UpdaterProduct = new UpdaterProduct();
            }

            item.UpdaterProduct.Size    = item.Size;
            item.UpdaterProduct.Version = updaterItem.Groups ["version"].Value;

            if (UpdaterReleaseNotes != null)
            {
                item.UpdaterProduct.ReleaseNotes = string
                                                   .Join("\n", UpdaterReleaseNotes)
                                                   .Trim();
            }

            if (ReleaseVersion.TryParse(item.UpdaterProduct.Version, out var version))
            {
                if (version.CandidateLevel == ReleaseCandidateLevel.Stable)
                {
                    item.RelativePublishEvergreenUrl = new Uri(
                        Path.GetDirectoryName(relativePath) + "/" +
                        updaterItem.Groups ["name"].Value +
                        updaterItem.Groups ["extension"].Value,
                        UriKind.Relative);
                }

                switch (version.CandidateLevel)
                {
                case ReleaseCandidateLevel.Alpha:
                    item.UpdaterProduct.IsAlpha = true;
                    break;

                case ReleaseCandidateLevel.Beta:
                case ReleaseCandidateLevel.StableCandidate:
                    item.UpdaterProduct.IsAlpha = true;
                    item.UpdaterProduct.IsBeta  = true;
                    break;

                case ReleaseCandidateLevel.Stable:
                    item.UpdaterProduct.IsAlpha  = true;
                    item.UpdaterProduct.IsBeta   = true;
                    item.UpdaterProduct.IsStable = true;
                    break;
                }
            }

            return(item);
        }