public void retrieveApiCatalog() { Hammock.Authentication.OAuth.OAuthCredentials credentials = OAuthWorkFlow.createOAuthCredentials(OAuthType.ProtectedResource, ApiCredentials.TOKEN.token, ApiCredentials.TOKEN.secret, null, null); Hammock.RestClient client = new Hammock.RestClient() { Authority = "", Credentials = credentials }; Hammock.RestRequest request = new Hammock.RestRequest() { Path = "https://apicert.soa-proxy.deere.com/platform/" }; request.AddHeader("Accept", "application/vnd.deere.axiom.v3+json"); Hammock.RestResponse response = client.Request(request); ApiCatalog apiCatalog = Deserialise <ApiCatalog>(response.ContentStream); links = OAuthWorkFlow.linksFrom(apiCatalog); getFiles(); retrieveMetadataForFile(); downloadFileContentsAndComputeMd5(); downloadFileInPiecesAndComputeMd5(); }
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 serviceDirectory = ServiceDirectory.LoadFromGoogleapis(); var service = serviceDirectory.Services.FirstOrDefault(service => service.CSharpNamespaceFromProtos == id); if (service is null) { var lowerWithoutCloud = id.Replace(".Cloud", "").ToLowerInvariant(); var possibilities = serviceDirectory.Services .Select(svc => svc.CSharpNamespaceFromProtos) .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 = service.ServiceDirectory, ProductName = service.Title.EndsWith(" API") ? service.Title[..^ 4] : service.Title,
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); } } }
private static void MaybeShowStale(Repository repo, List <Tag> allTags, ApiCatalog catalog, ApiMetadata api) { string expectedTagName = $"{api.Id}-{api.Version}"; var latestRelease = allTags.FirstOrDefault(tag => tag.FriendlyName == expectedTagName); // If we don't have any releases for the API (or couldn't find the tag), skip it. if (latestRelease is null) { return; } var laterCommits = repo.Commits.TakeWhile(commit => commit.Sha != latestRelease.Target.Sha); var relevantCommits = laterCommits .Where(GitHelpers.CreateCommitPredicate(repo, catalog, api)) .Where(commit => !CommitOverrides.IsSkipped(commit)) .ToList(); // No changes if (relevantCommits.Count == 0) { return; } string changes = relevantCommits.Count == 1 ? "change" : "changes"; Console.WriteLine($"{api.Id,-50} {latestRelease.GetDate():yyyy-MM-dd}: {api.Version} + {relevantCommits.Count} {changes}"); }
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)); } }
public void retrieveApiCatalogToEstablishOAuthProviderDetails() { Hammock.Authentication.OAuth.OAuthCredentials credentials = createOAuthCredentials(OAuthType.ProtectedResource, null, null, null, null); Hammock.RestClient client = new Hammock.RestClient() { Authority = "https://apicert.soa-proxy.deere.com/platform/", Credentials = credentials }; Hammock.RestRequest request = new Hammock.RestRequest() { Path = "" }; request.AddHeader("Accept", "application/vnd.deere.axiom.v3+json"); Hammock.RestResponse response = client.Request(request); MemoryStream stream1 = new MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ApiCatalog)); stream1.Position = 0; ApiCatalog apiCatalog = (ApiCatalog)ser.ReadObject(response.ContentStream); links = linksFrom(apiCatalog); }
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); } }
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); } } }
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}"); }
private static void SetVersion(string id, string version) { var catalog = ApiCatalog.Load(); var api = catalog[id]; string oldVersion = api.Version; api.Version = version; var layout = DirectoryLayout.ForApi(id); var apiNames = catalog.CreateIdHashSet(); ProjectGenerator.Program.GenerateMetadataFile(layout.SourceDirectory, api); ProjectGenerator.Program.GenerateProjects(layout.SourceDirectory, api, apiNames); ProjectGenerator.Program.RewriteReadme(catalog); ProjectGenerator.Program.RewriteDocsRootIndex(catalog); // Update the parsed JObject associated with the ID, and write it back to apis.json. api.Json["version"] = version; string formatted = catalog.FormatJson(); File.WriteAllText(ApiCatalog.CatalogPath, formatted); Console.WriteLine("Updated apis.json"); Console.WriteLine(); Console.WriteLine(new ApiVersionPair(id, oldVersion, version)); }
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,
public void retrieveApiCatalogToEstablishOAuthProviderDetails(string endPoint) { //Hammock.Authentication.OAuth.OAuthCredentials credentials = createOAuthCredentials(OAuthType.ProtectedResource, null, null, null, null); Hammock.RestClient client = new Hammock.RestClient() { Authority = endPoint, //Credentials = credentials }; client.AddHeader("Accept", "application/json"); client.AddHeader("authorization", $"Basic {GetBase64EncodedClientCredentials()}"); Hammock.RestRequest request = new Hammock.RestRequest() { Path = "" }; request.AddHeader("Accept", "application/vnd.deere.axiom.v3+json"); using (Hammock.RestResponse response = client.Request(request)) { //Logger.Log(response); MemoryStream stream1 = new MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ApiCatalog)); stream1.Position = 0; ApiCatalog apiCatalog = (ApiCatalog)ser.ReadObject(response.ContentStream); links = linksFrom(apiCatalog); } }
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); } }
/// <summary> /// Updates the dependencies in an API for known packages, but only if the default /// version is later than the current one, with the same major version number. /// </summary> public static void UpdateDependencies(ApiCatalog catalog, ApiMetadata api) { // Update any previously-defaulted versions to be explicit, if the new version is GA. // (This only affects production dependencies, so is not performed in UpdateDependencyDictionary.) // Implicit dependencies are always present in DefaultPackageVersions, so we don't need to worry about // "internal" dependencies. if (api.IsReleaseVersion && PackageTypeToImplicitDependencies.TryGetValue(api.Type, out var implicitDependencies)) { foreach (var implicitDependency in implicitDependencies) { if (!api.Dependencies.ContainsKey(implicitDependency)) { api.Dependencies[implicitDependency] = DefaultPackageVersions[implicitDependency]; } } } UpdateDependencyDictionary(api.Dependencies, "dependencies"); UpdateDependencyDictionary(api.TestDependencies, "testDependencies"); void UpdateDependencyDictionary(SortedDictionary <string, string> dependencies, string jsonName) { if (dependencies.Count == 0) { return; } // We want to update any dependencies to "external" packages as listed in DefaultPackageVersions, // but also "internal" packages such as Google.LongRunning. Dictionary <string, string> allDefaultPackageVersions = DefaultPackageVersions .Concat(catalog.Apis.Select(api => new KeyValuePair <string, string>(api.Id, api.Version))) .ToDictionary(pair => pair.Key, pair => pair.Value); foreach (var package in dependencies.Keys.ToList()) { if (allDefaultPackageVersions.TryGetValue(package, out var defaultVersion)) { var currentVersion = dependencies[package]; if (currentVersion == DefaultVersionValue || currentVersion == ProjectVersionValue || defaultVersion == currentVersion) { continue; } var structuredDefaultVersion = StructuredVersion.FromString(defaultVersion); var structuredCurrentVersion = StructuredVersion.FromString(currentVersion); if (structuredDefaultVersion.CompareTo(structuredCurrentVersion) > 0 && structuredDefaultVersion.Major == structuredCurrentVersion.Major) { dependencies[package] = defaultVersion; } } } if (api.Json is object) { api.Json[jsonName] = new JObject(dependencies.Select(pair => new JProperty(pair.Key, pair.Value))); } } }
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); } }
/// <summary> /// Generates the docfx-devsite.json file used to generate just the metadata for DevSite. /// </summary> private static void CreateDevsiteDocfxJson(ApiCatalog catalog, ApiMetadata rootApi, string outputDirectory) { // Pick whichever framework is listed first. (This could cause problems if a dependency // doesn't target the given framework, but that seems unlikely.) // Default to netstandard2.0 if nothing is listed. string targetFramework = rootApi.TargetFrameworks?.Split(';').First() ?? "netstandard2.0"; var json = new JObject { ["metadata"] = new JArray { new JObject { ["src"] = new JObject { ["files"] = new JArray { $"{rootApi.Id}/{rootApi.Id}.csproj" }, ["cwd"] = $"../../../apis/{rootApi.Id}" }, ["dest"] = "obj/bareapi", ["filter"] = "filterConfig.yml", ["properties"] = new JObject { ["TargetFramework"] = targetFramework } }, } }; File.WriteAllText(Path.Combine(outputDirectory, "docfx-devsite.json"), json.ToString()); }
protected override void ExecuteImpl(string[] args) { string id = args[0]; string version = args[1]; var catalog = ApiCatalog.Load(); var api = catalog[id]; string oldVersion = api.Version; api.Version = version; var layout = DirectoryLayout.ForApi(id); var apiNames = catalog.CreateIdHashSet(); GenerateProjectsCommand.GenerateMetadataFile(layout.SourceDirectory, api); GenerateProjectsCommand.GenerateProjects(layout.SourceDirectory, api, apiNames); GenerateProjectsCommand.RewriteReadme(catalog); GenerateProjectsCommand.RewriteDocsRootIndex(catalog); // Update the parsed JObject associated with the ID, and write it back to apis.json. api.Json["version"] = version; string formatted = catalog.FormatJson(); File.WriteAllText(ApiCatalog.CatalogPath, formatted); Console.WriteLine("Updated apis.json"); Console.WriteLine(); Console.WriteLine(new ApiVersionPair(id, oldVersion, version)); }
/// <summary> /// Given a set of APIs we're generating docs for, find transitive external dependencies that we need to include in the doc set (if we have them). /// </summary> private static IEnumerable <string> GetExternalDependencies(ApiCatalog catalog, IEnumerable <string> apiIds) { var directExternalDependencies = apiIds .Select(id => catalog[id]) .SelectMany(api => api.Dependencies.Keys) .Intersect(s_externalDependencies.Keys); HashSet <string> set = new HashSet <string>(); Queue <string> processingQueue = new Queue <string>(); foreach (var directDependency in directExternalDependencies) { processingQueue.Enqueue(directDependency); } while (processingQueue.TryDequeue(out var next)) { if (set.Add(next)) { if (s_externalDependencies.TryGetValue(next, out var childDependencies)) { foreach (var child in childDependencies) { processingQueue.Enqueue(child); } } } } return(set); }
public static void RewriteDocsRootIndex(ApiCatalog catalog) { var root = DirectoryLayout.ForRootDocs().DocsSourceDirectory; var indexPath = Path.Combine(root, "index.md"); RewriteApiTable(indexPath, catalog, api => $"{api.Id}/index.html"); }
internal void InternalExecute(string id, string version, bool quiet) { var catalog = ApiCatalog.Load(); var api = catalog[id]; string oldVersion = api.Version; api.Version = version; if (api.StructuredVersion.Patch == 0) { GenerateProjectsCommand.UpdateDependencies(catalog, api); } var layout = DirectoryLayout.ForApi(id); var apiNames = catalog.CreateIdHashSet(); // This will still write output, even if "quiet" is true, but that's probably // okay for batch releasing. GenerateProjectsCommand.GenerateMetadataFile(layout.SourceDirectory, api); GenerateProjectsCommand.GenerateProjects(layout.SourceDirectory, api, apiNames); GenerateProjectsCommand.RewriteReadme(catalog); // Update the parsed JObject associated with the ID, and write it back to apis.json. api.Json["version"] = version; string formatted = catalog.FormatJson(); File.WriteAllText(ApiCatalog.CatalogPath, formatted); if (!quiet) { Console.WriteLine("Updated apis.json"); Console.WriteLine(); Console.WriteLine(new ApiVersionPair(id, oldVersion, version)); } }
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}"); }
private static int MainImpl(string[] args) { if (args.Length != 1) { throw new UserErrorException("Please specify the API name"); } string api = args[0]; var layout = DirectoryLayout.ForApi(api); var apiCatalog = ApiCatalog.Load(); var apiMetadata = apiCatalog[api]; string output = layout.DocsOutputDirectory; if (Directory.Exists(output)) { Directory.Delete(output, true); } Directory.CreateDirectory(output); CreateGoogleApisDevDocfxJson(apiCatalog, apiMetadata, output); CreateDevsiteDocfxJson(apiCatalog, apiMetadata, output); CopyAndGenerateArticles(apiMetadata, layout.DocsSourceDirectory, output); CreateToc(api, output); return(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); }
private async Task <ApiCatalog> LoadCatalog() { var allContents = await _client.Repository.Content.GetAllContentsByRef(RepositoryOwner, RepositoryName, ApiCatalog.RelativeCatalogPath, _config.Committish); var json = allContents.Single().Content; return(ApiCatalog.FromJson(json)); }
protected override void ExecuteImpl(string[] args) { string id = args[0]; var catalog = ApiCatalog.Load(); var api = catalog[id]; Console.WriteLine($"Current version of {id} in the API catalog: {api.Version}"); }
private Program(string apiId) { DirectoryLayout layout = DirectoryLayout.ForApi(apiId); _apiId = apiId; _outputRoot = layout.DocsOutputDirectory; _devSiteRoot = Path.Combine(_outputRoot, "devsite"); _apiCatalog = ApiCatalog.Load(); _apiIds = _apiCatalog.CreateIdHashSet(); }
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}."); } } }
protected override void ExecuteImpl(string[] args) { var catalog = ApiCatalog.Load(); var lagging = catalog.Apis.Where(api => api.CanHaveGaRelease && api.StructuredVersion.Prerelease is string); Console.WriteLine($"Lagging packages:"); foreach (var api in lagging) { Console.WriteLine($"{api.Id} ({api.Version})"); } }
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); }
private static void ReformatApiCatalog(ApiCatalog catalog) { string path = ApiCatalog.CatalogPath; string existing = File.ReadAllText(path); string formatted = catalog.FormatJson(); if (existing != formatted) { File.WriteAllText(path, formatted); Console.WriteLine("Reformatted apis.json"); } }
public ApiBootstrapper( IEnumerable<KeyValuePair<Type, Func<IHttpApiRequestContext, INancyModule>>> nancyModules) { _apiCatalog = new ApiCatalog(nancyModules); }