コード例 #1
0
        IEnumerable <ReleaseProposal> IBatchCriterion.GetProposals(ApiCatalog catalog)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);
            var pendingChangesByApi = GitHelpers.GetPendingChangesByApi(repo, catalog);

            foreach (var api in catalog.Apis)
            {
                // Don't even bother proposing package groups at the moment.
                if (api.PackageGroup is object)
                {
                    continue;
                }
                // Don't propose packages that haven't changed.
                // Note that this will also not propose a release for APIs that haven't
                // yet *been* released - which is probably fine. (We don't want to accidentally
                // launch something due to not paying attention.)
                if (pendingChangesByApi[api].Commits.Count == 0)
                {
                    continue;
                }
                var newVersion = api.StructuredVersion.AfterIncrement();

                yield return(ReleaseProposal.CreateFromHistory(repo, api.Id, newVersion));
            }
        }
コード例 #2
0
        /// <summary>
        /// Loads the service directory from service config files in the "googleapis"
        /// directory under the root layout.
        /// </summary>
        public static ServiceDirectory LoadFromGoogleapis()
        {
            var root           = DirectoryLayout.DetermineRootDirectory();
            var googleapisRoot = Path.Combine(root, "googleapis");

            return(LoadFromGoogleapis(googleapisRoot));
        }
コード例 #3
0
        public static void RewriteReadme(ApiCatalog catalog)
        {
            var root       = DirectoryLayout.DetermineRootDirectory();
            var readmePath = Path.Combine(root, "README.md");

            RewriteApiTable(readmePath, catalog, api => $"https://googleapis.dev/dotnet/{api.Id}/{api.Version}");
        }
コード例 #4
0
        private static void Execute(string id)
        {
            var catalog = ApiCatalog.Load();
            var api     = catalog[id];

            if (api.NoVersionHistory)
            {
                Console.WriteLine($"Skipping version history update for {id}");
                return;
            }
            string historyFilePath = HistoryFile.GetPathForPackage(id);

            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);
            var releases         = Release.LoadReleases(repo, catalog, api).ToList();
            var historyFile      = HistoryFile.Load(historyFilePath);
            var sectionsInserted = historyFile.MergeReleases(releases);

            if (sectionsInserted.Count != 0)
            {
                historyFile.Save(historyFilePath);
                var relativePath = Path.GetRelativePath(DirectoryLayout.DetermineRootDirectory(), historyFilePath)
                                   .Replace('\\', '/');
                Console.WriteLine($"Updated version history file: {relativePath}");
                Console.WriteLine("New content:");
                Console.WriteLine();
                foreach (var line in sectionsInserted.SelectMany(section => section.Lines))
                {
                    Console.WriteLine(line);
                }
            }
        }
コード例 #5
0
        protected override void ExecuteImpl(string[] args)
        {
            ValidateCommonHiddenProductionDependencies();
            var root    = DirectoryLayout.DetermineRootDirectory();
            var catalog = ApiCatalog.Load();

            ValidateApiCatalog(catalog);
            Console.WriteLine($"API catalog contains {catalog.Apis.Count} entries");
            // Now we know we can parse the API catalog, let's reformat it.
            ReformatApiCatalog(catalog);
            RewriteReadme(catalog);
            RewriteRenovate(catalog);
            HashSet <string> apiNames = catalog.CreateIdHashSet();

            foreach (var api in catalog.Apis)
            {
                var path = Path.Combine(root, "apis", api.Id);
                GenerateProjects(path, api, apiNames);
                GenerateSolutionFiles(path, api);
                GenerateDocumentationStub(path, api);
                GenerateSynthConfiguration(path, api);
                GenerateOwlBotConfiguration(path, api);
                GenerateMetadataFile(path, api);
            }
        }
コード例 #6
0
        static void GenerateNotes(string api, Func <string, bool> pathFilter)
        {
            var apiDirectory = $"apis\\{api}\\";
            var tagPrefix    = $"{api}-";

            Console.WriteLine($"Changes for {api}");

            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new Repository(root))
            {
                var diff    = repo.Diff;
                var apiTags = repo.Tags
                              .Where(tag => tag.FriendlyName.StartsWith(tagPrefix))
                              .ToList();
                var idToTagName = apiTags.ToDictionary(tag => tag.Target.Id, tag => tag.FriendlyName.Substring(tagPrefix.Length));

                foreach (var commit in repo.Branches["master"].Commits)
                {
                    if (idToTagName.TryGetValue(commit.Id, out string version))
                    {
                        Console.WriteLine();
                        Console.WriteLine($"Release: {version}");
                        Console.WriteLine($"---------{new string('-', version.Length)}");
                    }
                    if (CommitContainsApi(diff, commit, pathFilter))
                    {
                        Console.WriteLine($"https://github.com/googleapis/google-cloud-dotnet/commit/{commit.Sha.Substring(0, 7)}");
                        Console.WriteLine(commit.Message);
                        Console.WriteLine();
                    }
                }
            }
        }
コード例 #7
0
        protected override void ExecuteImpl(string[] args)
        {
            string id = args[0];

            var catalog = ApiCatalog.Load();

            if (catalog.Apis.Any(api => api.Id == id))
            {
                throw new UserErrorException($"API {id} already exists in the API catalog.");
            }
            var root       = DirectoryLayout.DetermineRootDirectory();
            var googleapis = Path.Combine(root, "googleapis");
            var apiIndex   = ApiIndex.V1.Index.LoadFromGoogleApis(googleapis);

            var targetApi = apiIndex.Apis.FirstOrDefault(api => api.DeriveCSharpNamespace() == id);

            if (targetApi is null)
            {
                var lowerWithoutCloud = id.Replace(".Cloud", "").ToLowerInvariant();
                var possibilities     = apiIndex.Apis
                                        .Select(api => api.DeriveCSharpNamespace())
                                        .Where(ns => ns.Replace(".Cloud", "").ToLowerInvariant() == lowerWithoutCloud);
                throw new UserErrorException(
                          $"No service found for '{id}'.{Environment.NewLine}Similar possibilities (check options?): {string.Join(", ", possibilities)}");
            }

            var api = new ApiMetadata
            {
                Id          = id,
                ProtoPath   = targetApi.Directory,
                ProductName = targetApi.Title.EndsWith(" API") ? targetApi.Title[..^ 4] : targetApi.Title,
コード例 #8
0
        private static void Execute(string id)
        {
            var catalog = ApiCatalog.Load();
            var api     = catalog[id];

            if (api.NoVersionHistory)
            {
                Console.WriteLine($"Skipping version history update for {id}");
                return;
            }
            string historyFilePath = HistoryFile.GetPathForPackage(id);

            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new Repository(root))
            {
                var releases = LoadReleases(repo, api).ToList();
                if (!File.Exists(historyFilePath))
                {
                    File.WriteAllText(historyFilePath, "# Version history\r\n\r\n");
                }
                var historyFile = HistoryFile.Load(historyFilePath);
                historyFile.MergeReleases(releases);
                historyFile.Save(historyFilePath);
            }
            var relativePath = Path.GetRelativePath(DirectoryLayout.DetermineRootDirectory(), historyFilePath)
                               .Replace('\\', '/');

            Console.WriteLine($"Updated version history file: {relativePath}");
        }
コード例 #9
0
        IEnumerable <ReleaseProposal> IBatchCriterion.GetProposals(ApiCatalog catalog)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);
            var pendingChangesByApi = GitHelpers.GetPendingChangesByApi(repo, catalog);

            foreach (var api in catalog.Apis)
            {
                var pendingChanges = pendingChangesByApi[api];
                var pendingCommits = pendingChanges.Commits.Select(commit => commit.HashPrefix);
                if (!Commits.SetEquals(pendingCommits))
                {
                    continue;
                }
                var newVersion = api.StructuredVersion.AfterIncrement();
                var proposal   = ReleaseProposal.CreateFromHistory(repo, api.Id, newVersion);

                // Potentially replace the natural history with an override
                if (!string.IsNullOrEmpty(HistoryOverride) && proposal.NewHistorySection is HistoryFile.Section newSection)
                {
                    var naturalLines  = newSection.Lines;
                    var overrideLines = HistoryOverride.Split('\n');
                    var lines         = naturalLines.Take(2).Concat(overrideLines).ToList();
                    // We always add a blank line at the end of each section.
                    lines.Add("");
                    proposal.NewHistorySection = new HistoryFile.Section(newVersion, lines);
                }
                yield return(proposal);
            }
        }
コード例 #10
0
        protected override void ExecuteImpl(string[] args)
        {
            string configFile = args[0];
            var    json       = File.ReadAllText(configFile);
            var    config     = JsonConvert.DeserializeObject <BatchReleaseConfig>(json);

            var criteria = config.GetCriteria().ToList();

            if (criteria.Count != 1)
            {
                throw new UserErrorException("Batch release config must specify exactly one criterion.");
            }

            if (!config.DryRun)
            {
                var root = DirectoryLayout.DetermineRootDirectory();
                using var repo = new Repository(root);

                if (repo.RetrieveStatus().IsDirty)
                {
                    throw new UserErrorException("In non-dry-run mode, the current branch must not have changes.");
                }
            }

            var catalog   = ApiCatalog.Load();
            var criterion = criteria[0];
            var proposals = criterion.GetProposals(catalog);

            foreach (var proposal in proposals)
            {
                // Note: This takes into account the dry-run flag.
                proposal.Execute(config);
            }
        }
コード例 #11
0
        protected override void ExecuteImpl(string[] args)
        {
            var catalog       = ApiCatalog.Load();
            var root          = DirectoryLayout.DetermineRootDirectory();
            var googleapis    = Path.Combine(root, "googleapis");
            var apiIndex      = ApiIndex.V1.Index.LoadFromGoogleApis(googleapis);
            int modifiedCount = 0;

            foreach (var api in catalog.Apis)
            {
                var indexEntry = apiIndex.Apis.FirstOrDefault(x => x.DeriveCSharpNamespace() == api.Id);
                if (indexEntry is null)
                {
                    continue;
                }

                // Change this line when introducing a new field...
                api.Json.Last.AddAfterSelf(new JProperty("serviceConfigFile", indexEntry.ConfigFile));
                modifiedCount++;
            }

            Console.WriteLine($"Modified APIs: {modifiedCount}");
            string json = catalog.FormatJson();

            // Validate that we can still load it, before saving it to disk...
            ApiCatalog.FromJson(json);

            File.WriteAllText(ApiCatalog.CatalogPath, json);
        }
コード例 #12
0
        public void Execute(string[] args)
        {
            var root    = DirectoryLayout.DetermineRootDirectory();
            var catalog = ApiCatalog.Load();
            HashSet <string> tags;

            using (var repo = new Repository(root))
            {
                tags = new HashSet <string>(repo.Tags.Select(tag => tag.FriendlyName));
            }

            List <ApiMetadata> apisToCheck = args.Length == 0
                ? catalog.Apis.Where(api => !api.Version.EndsWith("00") && !tags.Contains($"{api.Id}-{api.Version}")).ToList()
                                             // Note: this basically validates the command line arguments.
                : args.Select(arg => catalog[arg]).ToList();

            foreach (var api in apisToCheck)
            {
                if (IgnoredApis.Contains(api.Id))
                {
                    Console.WriteLine($"Skipping check for {api.Id} as it doesn't target netstandard2.0");
                    continue;
                }
                Console.WriteLine($"Checking compatibility for {api.Id} version {api.Version}");
                var prefix           = api.Id + "-";
                var previousVersions = tags
                                       .Where(tag => tag.StartsWith(prefix))
                                       .Select(tag => tag.Split(new char[] { '-' }, 2)[1])
                                       .Where(v => !v.StartsWith("0")) // We can reasonably ignore old 0.x versions
                                       .Select(StructuredVersion.FromString)
                                       .OrderBy(v => v)
                                       .ToList();

                var newVersion = api.StructuredVersion;

                // First perform a "strict" check, where necessary, failing the build if the difference
                // is inappropriate.
                var(requiredVersion, requiredLevel) = GetRequiredCompatibility(api.StructuredVersion);
                if (requiredVersion != null)
                {
                    if (!previousVersions.Contains(requiredVersion))
                    {
                        throw new UserErrorException($"Expected to check compatibility with {requiredVersion}, but no corresponding tag found");
                    }
                    var actualLevel = CheckCompatibility(api, requiredVersion);
                    if (actualLevel < requiredLevel)
                    {
                        throw new UserErrorException($"Required compatibility level: {requiredLevel}. Actual compatibility level: {actualLevel}.");
                    }
                }

                // Next log the changes compared with the previous release (if we haven't already diffed it)
                // in an informational way. (This can be used to improve or check release notes.)
                var lastRelease = previousVersions.LastOrDefault();
                if (lastRelease != null && !lastRelease.Equals(requiredVersion))
                {
                    CheckCompatibility(api, lastRelease);
                }
            }
        }
コード例 #13
0
        static int Main()
        {
            try
            {
                ValidateCommonHiddenProductionDependencies();
                var root = DirectoryLayout.DetermineRootDirectory();
                var apis = ApiMetadata.LoadApis();
                Console.WriteLine($"API catalog contains {apis.Count} entries");
                HashSet <string> apiNames = new HashSet <string>(apis.Select(api => api.Id));

                foreach (var api in apis)
                {
                    var path = Path.Combine(root, "apis", api.Id);
                    GenerateProjects(path, api, apiNames);
                    GenerateSolutionFiles(path, api);
                    GenerateDocumentationStub(path, api);
                    GenerateSynthConfiguration(path, api);
                    GenerateMetadataFile(path, api);
                }
                return(0);
            }
            catch (UserErrorException e)
            {
                Console.WriteLine($"Configuration error: {e.Message}");
                return(1);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Failed: {e}");
                return(1);
            }
        }
コード例 #14
0
        static int Main(string[] args)
        {
            var root = DirectoryLayout.DetermineRootDirectory();
            var apis = ApiMetadata.LoadApis();
            HashSet <string> tags;

            using (var repo = new Repository(root))
            {
                tags = new HashSet <string>(repo.Tags.Select(tag => tag.FriendlyName));
            }

            var changes = apis.Where(api => !api.Version.EndsWith("00") && !tags.Contains($"{api.Id}-{api.Version}"));

            foreach (var api in changes)
            {
                if (IgnoredApis.Contains(api.Id))
                {
                    Console.WriteLine($"Skipping check for {api.Id} as it doesn't target netstandard2.0");
                    continue;
                }
                Console.WriteLine($"Checking compatibility for {api.Id} version {api.Version}");
                var prefix           = api.Id + "-";
                var previousVersions = tags
                                       .Where(tag => tag.StartsWith(prefix))
                                       .Select(tag => tag.Split(new char[] { '-' }, 2)[1])
                                       .Select(v => new StructuredVersion(v))
                                       .OrderBy(v => v)
                                       .ToList();

                var newVersion = api.StructuredVersion;

                // First perform a "strict" check, where necessary, failing the build if the difference
                // is inappropriate.
                var(requiredVersion, requiredLevel) = GetRequiredCompatibility(api.StructuredVersion);
                if (requiredVersion != null)
                {
                    if (!previousVersions.Contains(requiredVersion))
                    {
                        Console.WriteLine($"Expected to check compatibility with {requiredVersion}, but no corresponding tag found");
                        return(1);
                    }
                    var actualLevel = CheckCompatibility(api, requiredVersion);
                    if (actualLevel < requiredLevel)
                    {
                        Console.WriteLine($"Required compatibility level: {requiredLevel}. Actual compatibility level: {actualLevel}.");
                        return(1);
                    }
                }

                // Next log the changes compared with the previous release (if we haven't already diffed it)
                // in an informational way. (This can be used to improve or check release notes.)
                var lastRelease = previousVersions.LastOrDefault();
                if (lastRelease != null && !lastRelease.Equals(requiredVersion))
                {
                    CheckCompatibility(api, lastRelease);
                }
            }
            return(0);
        }
コード例 #15
0
        private static List <ApiMetadata> LoadApis()
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            var json = File.ReadAllText(Path.Combine(root, "apis", "apis.json"));

            return(JsonConvert.DeserializeObject <List <ApiMetadata> >(json).OrderBy(api => api.Id).ToList());
        }
コード例 #16
0
        protected override void ExecuteImpl(string[] args)
        {
            var diffs = FindChangedVersions();

            if (diffs.Count != 1)
            {
                throw new UserErrorException($"Can only automate a single-package release commit with exactly 1 release. Found {diffs.Count}. Did you mean 'commit-multiple'?");
            }
            var diff = diffs[0];

            if (diff.NewVersion is null)
            {
                throw new UserErrorException($"Cannot automate a release commit for a deleted API.");
            }

            var historyFilePath = HistoryFile.GetPathForPackage(diff.Id);

            if (!File.Exists(historyFilePath))
            {
                throw new UserErrorException($"Cannot automate a release commit without a version history file.");
            }

            var historyFile = HistoryFile.Load(historyFilePath);
            var section     = historyFile.Sections.FirstOrDefault(s => s.Version?.ToString() == diff.NewVersion);

            if (section is null)
            {
                throw new UserErrorException($"Unable to find history file section for {diff.NewVersion}. Cannot automate a release commit in this state.");
            }

            string header  = $"Release {diff.Id} version {diff.NewVersion}";
            var    message = string.Join("\n", new[] { header, "", "Changes in this release:", "" }.Concat(section.Lines.Skip(2)));

            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new Repository(root))
            {
                RepositoryStatus status = repo.RetrieveStatus();
                // TODO: Work out whether this is enough, and whether we actually need all of these.
                // We basically want git add --all.
                AddAll(status.Modified);
                AddAll(status.Missing);
                AddAll(status.Untracked);
                repo.Index.Write();
                var signature = repo.Config.BuildSignature(DateTimeOffset.UtcNow);
                var commit    = repo.Commit(message, signature, signature);
                Console.WriteLine($"Created commit {commit.Sha}. Review the message and amend if necessary.");

                void AddAll(IEnumerable <StatusEntry> entries)
                {
                    foreach (var entry in entries)
                    {
                        repo.Index.Add(entry.FilePath);
                    }
                }
            }
        }
コード例 #17
0
        public void Execute(string[] args)
        {
            var root    = DirectoryLayout.DetermineRootDirectory();
            var catalog = ApiCatalog.Load();
            HashSet <string> tags;

            using (var repo = new Repository(root))
            {
                tags = new HashSet <string>(repo.Tags.Select(tag => tag.FriendlyName));
            }

            List <ApiMetadata> apisToCheck = args.Length == 0
                ? catalog.Apis.Where(api => !api.Version.EndsWith("00") && !tags.Contains($"{api.Id}-{api.Version}")).ToList()
                                             // Note: this basically validates the command line arguments.
                : args.Select(arg => catalog[arg]).ToList();

            foreach (var api in apisToCheck)
            {
                Console.WriteLine($"Checking compatibility for {api.Id} version {api.Version}");
                var prefix      = api.Id + "-";
                var lastVersion = tags
                                  .Where(tag => tag.StartsWith(prefix))
                                  .Select(tag => tag.Split(new char[] { '-' }, 2)[1])
                                  .Where(v => !v.StartsWith("0")) // We can reasonably ignore old 0.x versions
                                  .Select(StructuredVersion.FromString)
                                  .OrderBy(v => v)
                                  .LastOrDefault();

                if (lastVersion is null)
                {
                    Console.WriteLine("No previous versions released; ignoring.");
                    continue;
                }

                var newVersion = api.StructuredVersion;

                // If we're releasing a new version, we should check against the previous one.
                // (For example, if this PR creates 1.2.0, then check against 1.1.0.)
                // Otherwise, just expect minor changes.
                Level requiredLevel = Level.Minor;
                if (!lastVersion.Equals(newVersion))
                {
                    requiredLevel =
                        lastVersion.Major != newVersion.Major ? Level.Major   // Major version bump: anything goes
                        : lastVersion.Minor != newVersion.Minor ? Level.Minor // Minor version bump: minor changes are okay
                        : Level.Identical;                                    // Patch version bump: API should be identical
                }

                var actualLevel = CheckCompatibility(api, lastVersion);
                if (actualLevel < requiredLevel)
                {
                    throw new UserErrorException($"Required compatibility level: {requiredLevel}. Actual compatibility level: {actualLevel}.");
                }
            }
        }
コード例 #18
0
        public static void RewriteRenovate(ApiCatalog catalog)
        {
            var     root = DirectoryLayout.DetermineRootDirectory();
            string  path = Path.Combine(root, ".github", "renovate.json");
            string  json = File.ReadAllText(path);
            JObject jobj = JObject.Parse(json);

            jobj["ignorePaths"] = new JArray(catalog.Apis.Select(api => $"apis/{api.Id}/{api.Id}/**").ToArray());
            json = jobj.ToString(Formatting.Indented);
            File.WriteAllText(path, json);
        }
コード例 #19
0
        protected override void ExecuteImpl(string[] args)
        {
            var root       = DirectoryLayout.DetermineRootDirectory();
            var googleapis = Path.Combine(root, "googleapis");
            var apiIndex   = ApiIndex.V1.Index.LoadFromGoogleApis(googleapis);

            foreach (var api in apiIndex.Apis)
            {
                ReportAnomalies(api);
            }
        }
コード例 #20
0
        private static List <ApiMetadata> ComputeNewReleasesAsync(List <ApiMetadata> allApis)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new LibGit2Sharp.Repository(root))
            {
                var tags     = repo.Tags.Select(tag => tag.FriendlyName).ToList();
                var noChange = allApis.Where(api => tags.Contains($"{api.Id}-{api.Version}") || api.Version.EndsWith("00")).ToList();
                return(allApis.Except(noChange).ToList());
            }
        }
コード例 #21
0
        protected override void ExecuteImpl(string[] args)
        {
            var root    = DirectoryLayout.DetermineRootDirectory();
            var catalog = ApiCatalog.Load();

            using (var repo = new Repository(root))
            {
                var allTags = repo.Tags.OrderByDescending(GitHelpers.GetDate).ToList();
                foreach (var api in catalog.Apis)
                {
                    MaybeShowStale(repo, allTags, api);
                }
            }
        }
コード例 #22
0
        private string GetGoogleapisRoot()
        {
            if (Environment.GetEnvironmentVariable("SYNTHTOOL_PRECONFIG_FILE") is string preconfigFile && preconfigFile != "")
            {
                JObject preconfig = JObject.Parse(File.ReadAllText(preconfigFile));
                return((string)preconfig["preclonedRepos"]["https://github.com/googleapis/googleapis.git"]);
            }
            if (Environment.GetEnvironmentVariable("SYNTHTOOL_GOOGLEAPIS") is string synthtoolGoogleapis && synthtoolGoogleapis != "")
            {
                return(synthtoolGoogleapis);
            }
            var root = DirectoryLayout.DetermineRootDirectory();

            return(Path.Combine(root, "googleapis"));
        }
コード例 #23
0
        protected override void ExecuteImpl(string[] args)
        {
            Console.WriteLine($"Lagging packages (package ID, current version, date range of current version prerelease series):");
            var root    = DirectoryLayout.DetermineRootDirectory();
            var catalog = ApiCatalog.Load();

            using (var repo = new Repository(root))
            {
                var allTags = repo.Tags.OrderByDescending(GitHelpers.GetDate).ToList();
                foreach (var api in catalog.Apis)
                {
                    MaybeShowLagging(repo, allTags, api);
                }
            }
        }
コード例 #24
0
        protected ApiCatalog LoadPrimaryCatalog()
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new Repository(root))
            {
                var primary = repo.Branches.FirstOrDefault(b => b.FriendlyName == PrimaryBranch);
                if (primary == null)
                {
                    throw new UserErrorException($"Unable to find branch '{PrimaryBranch}'.");
                }

                var primaryCatalogJson = primary.Commits.First()["apis/apis.json"].Target.Peel <Blob>().GetContentText();
                return(ApiCatalog.FromJson(primaryCatalogJson));
            }
        }
コード例 #25
0
        private static List <ApiMetadata> LoadMasterCatalog()
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new Repository(root))
            {
                var master = repo.Branches.FirstOrDefault(b => b.FriendlyName == MasterBranch);
                if (master == null)
                {
                    throw new UserErrorException($"Unable to find branch '{MasterBranch}'.");
                }

                var masterCatalogJson = master.Commits.First()["apis/apis.json"].Target.Peel <Blob>().GetContentText();
                return(JsonConvert.DeserializeObject <List <ApiMetadata> >(masterCatalogJson));
            }
        }
コード例 #26
0
        public IEnumerable <ReleaseProposal> GetProposals(ApiCatalog catalog)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);

            foreach (var api in catalog.Apis)
            {
                if (!_apis.Contains(api.Id))
                {
                    continue;
                }
                var newVersion = api.StructuredVersion.AfterIncrement();

                yield return(ReleaseProposal.CreateFromHistory(repo, api.Id, newVersion));
            }
        }
コード例 #27
0
        private static void ValidateLocalRepository(GitHubCommit expectedCommit)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new LibGit2Sharp.Repository(root))
            {
                string tip = repo.Head.Tip.Sha;
                if (tip != expectedCommit.Sha)
                {
                    throw new UserErrorException($"Current local commit: {tip}. Aborting.");
                }
                var status = repo.RetrieveStatus("apis/apis.json");
                if (status != FileStatus.Unaltered)
                {
                    throw new UserErrorException($"Expected apis.json to be unaltered. Current status: {status}. Aborting.");
                }
            }
        }
コード例 #28
0
        static void Main(string[] args)
        {
            bool attentionOnly = args.Contains("--attention");

            var root    = DirectoryLayout.DetermineRootDirectory();
            var catalog = ApiCatalog.Load();

            using (var repo = new Repository(root))
            {
                var diff           = repo.Diff;
                var tags           = repo.Tags;
                var shaToTimestamp = repo.Commits.ToDictionary(commit => commit.Sha, commit => commit.Committer.When);

                foreach (var api in catalog.Apis)
                {
                    DisplayApi(attentionOnly, api, tags, shaToTimestamp);
                }
            }
        }
コード例 #29
0
        private static void Execute(string id)
        {
            var    catalog         = ApiMetadata.LoadApis();
            var    api             = catalog.FirstOrDefault(x => x.Id == id) ?? throw new UserErrorException($"Unknown API: {id}");
            string historyFilePath = Path.Combine(DirectoryLayout.ForApi(id).DocsSourceDirectory, MarkdownFile);

            var root = DirectoryLayout.DetermineRootDirectory();

            using (var repo = new Repository(root))
            {
                var releases = LoadReleases(repo, api).ToList();
                if (!File.Exists(historyFilePath))
                {
                    File.WriteAllText(historyFilePath, "# Version history\r\n\r\n");
                }
                var historyFile = HistoryFile.Load(historyFilePath);
                historyFile.MergeReleases(releases);
                historyFile.Save(historyFilePath);
            }
        }
コード例 #30
0
        public static void RewriteRenovate(ApiCatalog catalog)
        {
            var root   = DirectoryLayout.DetermineRootDirectory();
            var config = new JObject
            {
                ["extends"] = new JArray {
                    "config:base"
                },
                ["ignorePaths"]  = new JArray(catalog.Apis.Select(api => $"apis/{api.Id}/{api.Id}/**").ToArray()),
                ["packageRules"] = new JArray
                {
                    new JObject
                    {
                        ["matchPaths"] = new JArray {
                            "apis/Google.Cloud.Diagnostics.AspNetCore/**"
                        },
                        ["matchPackagePrefixes"] = new JArray {
                            "Microsoft.AspNetCore.", "Microsoft.Extensions."
                        },
                        ["allowedVersions"] = "<2.2.0"
                    },
                    new JObject
                    {
                        ["matchPaths"] = new JArray {
                            "apis/Google.Cloud.Diagnostics.AspNetCore3/**"
                        },
                        ["matchPackagePrefixes"] = new JArray {
                            "Microsoft.AspNetCore."
                        },
                        ["allowedVersions"] = "<3.2.0"
                    },
                },
                ["schedule"] = new JArray {
                    "before 8am"
                },
                ["timezone"] = "Europe/London"
            };
            string json = config.ToString(Formatting.Indented);

            File.WriteAllText(Path.Combine(root, ".github", "renovate.json"), json);
        }