From 0029ac9d68bc27ae9bbf9f6b1f85c5c4b3769f42 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Mon, 31 Aug 2026 17:06:17 +0200 Subject: [PATCH] Fix changelog block hiding links for private:true skip:true repos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChangelogBlock.LoadPrivateRepositories` read `PrivateRepositories.Keys`, which excludes repos with `skip: true` set. That excluded all ten existing team repos (`kibana-team`, `search-team`, etc.) from render-time link hiding, so a local `{changelog}` render printed their PR links. The root cause was that `AssemblyConfiguration.PrivateRepositories` serves two consumers with different needs: - `AssemblerCrossLinkFetcher` needs repos whose cross-links can actually be fetched; `skip:true` means no link index exists, so the `!Skip` filter is correct there. - `ChangelogBlock` needs repos whose links must be hidden; `skip:true` means "does not publish docs", not "is public", so the filter is wrong there. The fix adds `AllPrivateRepositoryNames` — all repos marked `private: true` regardless of `skip: true`, derived from the same pre-removal snapshot. `LoadPrivateRepositories` switches to this set; `PrivateRepositories` and its cross-link consumer are unchanged. The `:cdn:` publication path was already safe (the scrubber strips those refs before publication), but a local bundle render leaked them. Co-Authored-By: Claude --- .../Assembler/AssemblyConfiguration.cs | 14 ++++++++++++++ .../Myst/Directives/Changelog/ChangelogBlock.cs | 8 ++++++-- .../Directives/ChangelogHideLinksTests.cs | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs b/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs index 2390f5a273..f9f4b94bd7 100644 --- a/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs +++ b/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs @@ -60,6 +60,13 @@ public static AssemblyConfiguration Deserialize(string yaml, bool skipPrivateRep .ToDictionary(kvp => kvp.Name, kvp => kvp); config.PrivateRepositories = privateRepositories.Where(r => !r.Value.Skip).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + // All repos marked private: true, regardless of skip: true. Skip means "does not publish + // docs", not "is not private". This set is used for render-time link visibility so that + // entries like kibana-team (private: true, skip: true) still have their links hidden. + config.AllPrivateRepositoryNames = new HashSet( + privateRepositories.Select(r => r.Key), + StringComparer.OrdinalIgnoreCase + ); return config; } catch (Exception e) @@ -119,6 +126,13 @@ public static AssemblyConfiguration Deserialize(string yaml, bool skipPrivateRep [YamlIgnore] public IReadOnlyDictionary PrivateRepositories { get; private set; } = new Dictionary(); + /// All repository names marked private: true, regardless of skip: true. + /// skip: true means a repo does not publish docs, not that it is publicly visible. + /// Use this set for render-time link visibility rather than , + /// which excludes skipped repos because the cross-link fetcher has no link index for them. + [YamlIgnore] + public IReadOnlySet AllPrivateRepositoryNames { get; private set; } = new HashSet(StringComparer.OrdinalIgnoreCase); + [YamlMember(Alias = "environments")] public Dictionary Environments { get; set; } = []; diff --git a/src/Elastic.Markdown/Myst/Directives/Changelog/ChangelogBlock.cs b/src/Elastic.Markdown/Myst/Directives/Changelog/ChangelogBlock.cs index 75ecb59666..5caa9a86cf 100644 --- a/src/Elastic.Markdown/Myst/Directives/Changelog/ChangelogBlock.cs +++ b/src/Elastic.Markdown/Myst/Directives/Changelog/ChangelogBlock.cs @@ -484,9 +484,13 @@ private void LoadPrivateRepositories() { try { - // Try to load assembler configuration to get private repositories + // Try to load assembler configuration to get private repositories. + // Use AllPrivateRepositoryNames rather than PrivateRepositories.Keys: PrivateRepositories + // excludes skip:true entries (because the cross-link fetcher has no link index for them), + // but skip:true means "does not publish docs", not "is public". Repos like kibana-team + // (private:true, skip:true) must still have their links hidden at render time. var assemblerConfig = AssemblyConfiguration.Create(Build.ConfigurationFileProvider); - foreach (var repoName in assemblerConfig.PrivateRepositories.Keys) + foreach (var repoName in assemblerConfig.AllPrivateRepositoryNames) _ = PrivateRepositories.Add(repoName); } catch diff --git a/tests/Elastic.Markdown.Tests/Directives/ChangelogHideLinksTests.cs b/tests/Elastic.Markdown.Tests/Directives/ChangelogHideLinksTests.cs index d2d23d8d13..39f7dd567d 100644 --- a/tests/Elastic.Markdown.Tests/Directives/ChangelogHideLinksTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/ChangelogHideLinksTests.cs @@ -130,6 +130,15 @@ public void PrivateRepositoriesPropertyIsAccessible() => // (may contain repos from embedded assembler.yml) Block!.PrivateRepositories.Should().NotBeNull(); + [Fact] + public void LoadPrivateRepositories_IncludesSkipTruePrivateRepos() + { + // kibana-team is marked private: true, skip: true in the embedded assembler.yml. + // skip: true means "does not publish docs", not "is public". LoadPrivateRepositories + // must include it so that its links are hidden at render time. + Block!.PrivateRepositories.Should().Contain("kibana-team"); + } + [Fact] public void RendersPrLinksForPublicRepo() {