public async Task <ProjectResource> GetProjectByName(string projectName)
        {
            commandOutputProvider.Debug("Finding project: {Project:l}", projectName);
            var project = await repository.Projects.FindByName(projectName).ConfigureAwait(false);

            if (project == null)
            {
                throw new CouldNotFindException("a project named", projectName);
            }
            return(project);
        }
Ejemplo n.º 2
0
        IEnumerable <TMachineResource> FilterByProvidedStatus <TMachineResource>(IEnumerable <TMachineResource> machines) where TMachineResource : MachineBasedResource
        {
            var statusFilter = new List <MachineModelStatus>();

            if (statuses.Count > 0)
            {
                commandOutputProvider.Debug("Loading statuses...");
                statusFilter.AddRange(statuses);
            }

            return(statusFilter.Any()
                ? machines.Where(p => statusFilter.Contains(p.Status))
                : machines);
        }
Ejemplo n.º 3
0
        public DummyApiCommand(IOctopusAsyncRepositoryFactory repositoryFactory, IOctopusFileSystem fileSystem, IOctopusClientFactory clientFactory, ICommandOutputProvider commandOutputProvider)
            : base(clientFactory, repositoryFactory, fileSystem, commandOutputProvider)
        {
            var options = Options.For("Dummy");

            options.Add <string>("pill=", "Red or Blue. Blue, the story ends. Red, stay in Wonderland and see how deep the rabbit hole goes.", v => pill = v);
            commandOutputProvider.Debug("Pill: " + pill);
        }
Ejemplo n.º 4
0
        public void BuildPackage(string basePath,
                                 IList <string> includes,
                                 ManifestMetadata metadata,
                                 string outFolder,
                                 bool overwrite,
                                 bool verboseInfo)
        {
            var filename = metadata.Id + "." + metadata.Version + ".zip";
            var output   = fileSystem.GetFullPath(Path.Combine(outFolder, filename));

            if (fileSystem.FileExists(output) && !overwrite)
            {
                throw new CommandException("The package file already exists and --overwrite was not specified");
            }

            commandOutputProvider.Information("Saving {Filename} to {OutFolder}...", filename, outFolder);

            fileSystem.EnsureDirectoryExists(outFolder);

            var basePathLength = fileSystem.GetFullPath(basePath).Length;

            using (var stream = fileSystem.OpenFile(output, FileAccess.Write))
                using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
                {
                    foreach (var pattern in includes)
                    {
                        commandOutputProvider.Debug("Adding files from {Path} matching pattern {Pattern}", basePath, pattern);
                        foreach (var file in PathResolver.PerformWildcardSearch(basePath, pattern))
                        {
                            var fullFilePath = fileSystem.GetFullPath(file);
                            if (string.Equals(fullFilePath, output, StringComparison.CurrentCultureIgnoreCase))
                            {
                                continue;
                            }

                            var relativePath = UseCrossPlatformDirectorySeparator(
                                fullFilePath.Substring(basePathLength).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));

                            if (verboseInfo)
                            {
                                commandOutputProvider.Information($"Added file: {relativePath}");
                            }

                            files.Add(relativePath);

                            var entry = archive.CreateEntry(relativePath, compressionLevel);
                            UpdateLastWriteTime(file, entry);

                            using (var entryStream = entry.Open())
                                using (var sourceStream = File.OpenRead(file))
                                {
                                    sourceStream.CopyTo(entryStream);
                                }
                        }
                    }
                }
        }
        IEnumerable <TMachineResource> FilterByProvidedStatus <TMachineResource>(IEnumerable <TMachineResource> machines) where TMachineResource : MachineBasedResource
        {
            var statusFilter = new List <MachineModelStatus>();

            if (statuses.Count > 0)
            {
                commandOutputProvider.Debug("Loading statuses...");
                foreach (var status in statuses)
                {
                    MachineModelStatus result;
                    if (Enum.TryParse(status, true, out result))
                    {
                        statusFilter.Add(result);
                    }
                }
            }

            return(statusFilter.Any()
                ? machines.Where(p => statusFilter.Contains(p.Status))
                : machines);
        }
Ejemplo n.º 6
0
        async Task <ReleasePlan> BuildReleaseFromVersionControl(IOctopusAsyncRepository repository,
                                                                ProjectResource project,
                                                                ChannelResource channel,
                                                                string versionPreReleaseTag,
                                                                string gitReference)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (!project.IsVersionControlled)
            {
                throw new CommandException(GitReferenceSuppliedForDatabaseProjectErrorMessage(gitReference));
            }
            commandOutputProvider.Debug($"Finding deployment process at git reference {gitReference}...");
            var deploymentProcess = await repository.DeploymentProcesses.Beta().Get(project, gitReference);

            if (deploymentProcess == null)
            {
                throw new CouldNotFindException(
                          $"a deployment process for project {project.Name} and git reference {gitReference}");
            }

            commandOutputProvider.Debug($"Finding release template at git reference {gitReference}...");
            var releaseTemplate = await repository.DeploymentProcesses.GetTemplate(deploymentProcess, channel).ConfigureAwait(false);

            if (releaseTemplate == null)
            {
                throw new CouldNotFindException(
                          $"a release template for project {project.Name}, channel {channel.Name} and git reference {gitReference}");
            }

            return(await Build(repository,
                               project,
                               channel,
                               versionPreReleaseTag,
                               releaseTemplate,
                               deploymentProcess));
        }
Ejemplo n.º 7
0
        public async Task <ReleasePlan> Build(IOctopusAsyncRepository repository, ProjectResource project, ChannelResource channel, string versionPreReleaseTag)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            commandOutputProvider.Debug("Finding deployment process...");
            var deploymentProcess = await repository.DeploymentProcesses.Get(project.DeploymentProcessId).ConfigureAwait(false);

            commandOutputProvider.Debug("Finding release template...");
            var releaseTemplate = await repository.DeploymentProcesses.GetTemplate(deploymentProcess, channel).ConfigureAwait(false);

            var plan = new ReleasePlan(project, channel, releaseTemplate, deploymentProcess, versionResolver);

            if (plan.UnresolvedSteps.Any())
            {
                commandOutputProvider.Debug("The package version for some steps was not specified. Going to try and resolve those automatically...");
                foreach (var unresolved in plan.UnresolvedSteps)
                {
                    if (!unresolved.IsResolveable)
                    {
                        commandOutputProvider.Error("The version number for step '{Step:l}' cannot be automatically resolved because the feed or package ID is dynamic.", unresolved.ActionName);
                        continue;
                    }

                    if (!string.IsNullOrEmpty(versionPreReleaseTag))
                    {
                        commandOutputProvider.Debug("Finding latest package with pre-release '{Tag:l}' for step: {StepName:l}", versionPreReleaseTag, unresolved.ActionName);
                    }
                    else
                    {
                        commandOutputProvider.Debug("Finding latest package for step: {StepName:l}", unresolved.ActionName);
                    }

                    var feed = await repository.Feeds.Get(unresolved.PackageFeedId).ConfigureAwait(false);

                    if (feed == null)
                    {
                        throw new CommandException(string.Format("Could not find a feed with ID {0}, which is used by step: " + unresolved.ActionName, unresolved.PackageFeedId));
                    }

                    var filters = BuildChannelVersionFilters(unresolved.ActionName, channel);
                    filters["packageId"] = unresolved.PackageId;
                    if (!string.IsNullOrWhiteSpace(versionPreReleaseTag))
                    {
                        filters["preReleaseTag"] = versionPreReleaseTag;
                    }

                    var packages = await repository.Client.Get <List <PackageResource> >(feed.Link("SearchTemplate"), filters).ConfigureAwait(false);

                    var latestPackage = packages.FirstOrDefault();

                    if (latestPackage == null)
                    {
                        commandOutputProvider.Error("Could not find any packages with ID '{PackageId:l}' in the feed '{FeedUri:l}'", unresolved.PackageId, feed.Name);
                    }
                    else
                    {
                        commandOutputProvider.Debug("Selected '{PackageId:l}' version '{Version:l}' for '{StepName:l}'", latestPackage.PackageId, latestPackage.Version, unresolved.ActionName);
                        unresolved.SetVersionFromLatest(latestPackage.Version);
                    }
                }
            }

            // Test each step in this plan satisfies the channel version rules
            if (channel != null)
            {
                foreach (var step in plan.PackageSteps)
                {
                    // Note the rule can be null, meaning: anything goes
                    var rule   = channel.Rules.SingleOrDefault(r => r.Actions.Any(s => s.Equals(step.ActionName, StringComparison.OrdinalIgnoreCase)));
                    var result = await versionRuleTester.Test(repository, rule, step.Version).ConfigureAwait(false);

                    step.SetChannelVersionRuleTestResult(result);
                }
            }

            return(plan);
        }
Ejemplo n.º 8
0
        public async Task <ReleasePlan> Build(IOctopusAsyncRepository repository, ProjectResource project, ChannelResource channel, string versionPreReleaseTag, string versionPreReleaseTagFallBacks, string softDefaultPackageVersion, bool LatestByPublishDate)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            commandOutputProvider.Debug("Finding deployment process...");
            var deploymentProcess = await repository.DeploymentProcesses.Get(project.DeploymentProcessId).ConfigureAwait(false);

            commandOutputProvider.Debug("Finding release template...");
            var releaseTemplate = await repository.DeploymentProcesses.GetTemplate(deploymentProcess, channel).ConfigureAwait(false);

            var plan = new ReleasePlan(project, channel, releaseTemplate, deploymentProcess, versionResolver);

            if (plan.UnresolvedSteps.Any())
            {
                commandOutputProvider.Debug("The package version for some steps was not specified. Going to try and resolve those automatically...");

                foreach (var unresolved in plan.UnresolvedSteps)
                {
                    if (!unresolved.IsResolveable)
                    {
                        commandOutputProvider.Error("The version number for step '{Step:l}' cannot be automatically resolved because the feed or package ID is dynamic.", unresolved.ActionName);
                        continue;
                    }


                    var feed = await repository.Feeds.Get(unresolved.PackageFeedId).ConfigureAwait(false);

                    if (feed == null)
                    {
                        throw new CommandException(string.Format("Could not find a feed with ID {0}, which is used by step: " + unresolved.ActionName, unresolved.PackageFeedId));
                    }
                    var             packages = new System.Collections.Generic.List <Octopus.Client.Model.PackageResource>();
                    PackageResource latestPackage;
                    String          versionSource = "Latest available";

                    var filters = BuildChannelVersionFilters(unresolved.ActionName, unresolved.PackageReferenceName, channel);
                    filters["packageId"] = unresolved.PackageId;

                    commandOutputProvider.Debug("------------------------------------------\r\n");
                    commandOutputProvider.Debug("Step: '{StepName:l}', Package: '{PackageId:l}':\r\n", unresolved.ActionName, unresolved.PackageId);


                    //look for exact version of package specified softDefaultPackageVersion, bypass all further version-seeking heurstics if succeed
                    if (!string.IsNullOrWhiteSpace(softDefaultPackageVersion))
                    {
                        filters["versionRange"] = "[" + softDefaultPackageVersion + "]";
                        packages = await repository.Client.Get <List <PackageResource> >(feed.Link("SearchTemplate"), filters).ConfigureAwait(false);

                        latestPackage = packages.FirstOrDefault();
                        if (latestPackage != null)
                        {
                            commandOutputProvider.Debug("Version '{Version:l}' was found using softDefaultPackageVersion specified. Any further version-seeking heurstics will be bypassed.", latestPackage.Version);
                            versionSource = "softDefaultPackageVersion";
                            unresolved.SetVersionFromLatest(latestPackage.Version, versionSource);
                            continue;
                        }
                        else
                        {
                            filters.Remove("versionRange");
                            commandOutputProvider.Debug("Could not find package with softDefaultPackageVersion: '{softDefaultPackageVersion:l}', falling back to search with another specified methods (versionPreReleaseTag,versionPreReleaseTagFallBacks)", softDefaultPackageVersion);
                        }
                    }



                    if (!string.IsNullOrWhiteSpace(versionPreReleaseTag))
                    {
                        filters["preReleaseTag"] = versionPreReleaseTag;
                        versionSource            = "versionPreReleaseTag";
                        commandOutputProvider.Debug("versionPreReleaseTag: '{Tag:l}' was specified. Looking for latest package with this tag.'", versionPreReleaseTag);
                    }



                    bool ResolverLooksForPreReleasePackage = !(string.IsNullOrWhiteSpace(versionPreReleaseTag) || versionPreReleaseTag == "^$");


                    //As we can't sort by publishing date on the server side, we have to take all packages and sort them on the client side
                    if (LatestByPublishDate && ResolverLooksForPreReleasePackage)
                    {
                        filters["take"] = 10000;
                    }
                    else
                    {
                        //AIR-1533. Speed-up package choosing
                        filters["take"] = 1;
                    }


                    packages = await repository.Client.Get <List <PackageResource> >(feed.Link("SearchTemplate"), filters).ConfigureAwait(false);



                    //Get the latest published package for release instead of the package has the biggest SemVer
                    //Only for pre-release packages and only if LatestByPublishDate prop specified
                    //Using latest published package is inappropriate for release packages, because hotfix releases for old versions may be pushed after main major versions.
                    if (LatestByPublishDate && ResolverLooksForPreReleasePackage)
                    {
                        latestPackage = packages.OrderByDescending(o => o.Published).FirstOrDefault();
                        if (latestPackage != null)
                        {
                            commandOutputProvider.Debug("'--latestbypublishdate' flag was specified. Package resolver will choose version of package by the latest publishing date instead of the higest SemVer version.");
                        }
                    }
                    else
                    {
                        latestPackage = packages.FirstOrDefault();
                    }



                    if (latestPackage == null && !string.IsNullOrWhiteSpace(versionPreReleaseTag) && !string.IsNullOrWhiteSpace(versionPreReleaseTagFallBacks))
                    {
                        commandOutputProvider.Debug("Could not find latest package with pre-release '{Tag:l}', falling back to search with pre-release tags '{FallBackTags:l}' ", versionPreReleaseTag, versionPreReleaseTagFallBacks);
                        //trim values and remove empty ones
                        List <string> versionPreReleaseTagFallBacksList = versionPreReleaseTagFallBacks.Split(',').ToList().Select(s => s.Trim()).ToList();
                        versionPreReleaseTagFallBacksList = versionPreReleaseTagFallBacksList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();

                        foreach (string versionPreReleaseTagFallBack in versionPreReleaseTagFallBacksList)
                        {
                            //similar beahaviour as for general versionPreReleaseTag
                            //Get the latest published package for release instead of the package has the biggest SemVer
                            filters.Remove("take");

                            filters["preReleaseTag"] = versionPreReleaseTagFallBack;

                            ResolverLooksForPreReleasePackage = !(versionPreReleaseTagFallBack == "^$");


                            //As we can't sort by publishing date on the server side, we have to take all packages and sort them on the client side
                            if (LatestByPublishDate && ResolverLooksForPreReleasePackage)
                            {
                                filters["take"] = 10000;
                            }
                            else
                            {
                                //AIR-1533. Speed-up package choosing
                                filters["take"] = 1;
                            }

                            packages = await repository.Client.Get <List <PackageResource> >(feed.Link("SearchTemplate"), filters).ConfigureAwait(false);

                            if (LatestByPublishDate && ResolverLooksForPreReleasePackage)
                            {
                                latestPackage = packages.OrderByDescending(o => o.Published).FirstOrDefault();
                                if (latestPackage != null)
                                {
                                    commandOutputProvider.Debug("'--latestbypublishdate' flag was specified. Package resolver will choose version by the latest publishing date instead of the higest SemVer version.");
                                }
                            }
                            else
                            {
                                latestPackage = packages.FirstOrDefault();
                            }

                            if (latestPackage != null)
                            {
                                versionSource = "versionPreReleaseTagFallBacks";
                                break;
                            }
                        }
                    }


                    if (latestPackage == null)
                    {
                        commandOutputProvider.Error("Could not find any packages with this ID in the feed '{FeedUri:l}'", feed.Name);
                    }
                    else
                    {
                        commandOutputProvider.Debug("Selected version '{Version:l}'", latestPackage.Version);
                        unresolved.SetVersionFromLatest(latestPackage.Version, versionSource);
                    }
                }
            }

            // Test each step in this plan satisfies the channel version rules
            if (channel != null)
            {
                foreach (var step in plan.PackageSteps)
                {
                    // Note the rule can be null, meaning: anything goes
                    var rule   = channel.Rules.SingleOrDefault(r => r.ActionPackages.Any(pkg => pkg.DeploymentActionNameMatches(step.ActionName) && pkg.PackageReferenceNameMatches(step.PackageReferenceName)));
                    var result = await versionRuleTester.Test(repository, rule, step.Version).ConfigureAwait(false);

                    step.SetChannelVersionRuleTestResult(result);
                }
            }

            return(plan);
        }