diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml index ff35ca016..59e14f241 100644 --- a/.github/workflows/preview-build.yml +++ b/.github/workflows/preview-build.yml @@ -117,10 +117,10 @@ jobs: outputs: any_modified: ${{ steps.check-files.outputs.any_modified }} all_changed_files: ${{ steps.check-files.outputs.all_changed_files }} - added_files: ${{ steps.check-files.outputs.added_files }} - modified_files: ${{ steps.check-files.outputs.modified_files }} - deleted_files: ${{ steps.check-files.outputs.deleted_files }} - renamed_files: ${{ steps.check-files.outputs.renamed_files }} + added_files: ${{ steps.check-modified-file-detail.outputs.added_files }} + modified_files: ${{ steps.check-modified-file-detail.outputs.modified_files }} + deleted_files: ${{ steps.check-modified-file-detail.outputs.deleted_files }} + renamed_files: ${{ steps.check-modified-file-detail.outputs.renamed_files }} steps: - name: Checkout if: contains(fromJSON('["push", "merge_group", "workflow_dispatch"]'), github.event_name) @@ -138,6 +138,48 @@ jobs: ${{ inputs.path-pattern-ignore != '' && inputs.path-pattern-ignore || '' }} .github/** README.md + - name: Get modified file detail + if: contains(fromJSON('["merge_group", "pull_request", "pull_request_target"]'), github.event_name) + id: check-modified-file-detail + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + script: | + const { owner, repo } = context.repo; + const pull_number = context.payload.pull_request.number; + + const files = await github.paginate(github.rest.pulls.listFiles, { + owner, + repo, + pull_number, + }); + + const added = []; + const modified = []; + const deleted = []; + const renamed = []; + const all_changed = []; + + for (const file of files) { + switch (file.status) { + case 'added': + added.push(file.filename); + break; + case 'modified': + modified.push(file.filename); + break; + case 'removed': + deleted.push(file.filename); + break; + case 'renamed': + renamed.push(`${file.previous_filename}:${file.filename}`); + break; + } + } + + core.setOutput('added_files', added.join(' ')); + core.setOutput('modified_files', modified.join(' ')); + core.setOutput('deleted_files', deleted.join(' ')); + core.setOutput('renamed_files', renamed.join(' ')); build: if: github.event.repository.fork == false # Skip running the job on the fork itself (It still runs on PRs on the upstream from forks) diff --git a/docs/_docset.yml b/docs/_docset.yml index 31b325c65..e151ede9e 100644 --- a/docs/_docset.yml +++ b/docs/_docset.yml @@ -34,8 +34,7 @@ toc: - file: index.md - file: locally.md - file: on-the-web.md - - file: move.md - - file: redirects.md + - file: move-new.md - file: cumulative-docs.md - file: branching-strategy.md - file: add-repo.md diff --git a/docs/contribute/move.md b/docs/contribute/move-new.md similarity index 100% rename from docs/contribute/move.md rename to docs/contribute/move-new.md diff --git a/docs/contribute/redirects.md b/docs/contribute/redirects.md deleted file mode 100644 index 086d3a811..000000000 --- a/docs/contribute/redirects.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -navigation_title: "Redirects" ---- - -# Manage redirects across doc sets - -When you [move](move.md) or delete pages, other [documentation sets](../configure/content-set/index.md) might still link to them. This can lead to a chicken-and-egg problem: you can't publish your changes without breaking links elsewhere. - -Redirects let you map old links to new targets across documentation sets, so you can publish changes while updating other doc sets. - -## Limitations - -Redirects only work within Elastic Docs V3 content sets. You cannot use this method to redirect to external destinations like [API docs](https://www.elastic.co/docs/api/). - -For API redirects, consult with the documentation engineering team on Slack (#elastic-docs-v3). - -For elastic.co/guide redirects, open a [web team request](http://ela.st/web-request). - -## File location. - -Redirects are configured at the content set-level. -The configuration file should be located next to your `docset.yml` file: - -* `redirects.yml` if you use `docset.yml` -* `_redirects.yml` if you use `_docset.yml` - -## Syntax - -Example syntax: - -```yaml -redirects: - 'testing/redirects/4th-page.md': 'testing/redirects/5th-page.md' - 'testing/redirects/9th-page.md': '!testing/redirects/5th-page.md' - 'testing/redirects/6th-page.md': - 'testing/redirects/7th-page.md': - to: 'testing/redirects/5th-page.md' - anchors: '!' - 'testing/redirects/first-page-old.md': - to: 'testing/redirects/second-page.md' - anchors: - 'old-anchor': 'active-anchor' - 'removed-anchor': - 'testing/redirects/second-page-old.md': - many: - - to: "testing/redirects/second-page.md" - anchors: - "aa": "zz" - "removed-anchor": - - to: "testing/redirects/third-page.md" - anchors: - "bb": "yy" - 'testing/redirects/third-page.md': - anchors: - 'removed-anchor': - 'testing/redirects/cross-repo-page.md': 'other-repo://reference/section/new-cross-repo-page.md' - 'testing/redirects/8th-page.md': - to: 'other-repo://reference/section/new-cross-repo-page.md' - anchors: '!' - many: - - to: 'testing/redirects/second-page.md' - anchors: - 'item-a': 'yy' - - to: 'testing/redirects/third-page.md' - anchors: - 'item-b': - - -``` - -### Redirect preserving all anchors - -This example redirects `4th-page.md#anchor` to `5th-page.md#anchor`: - -```yaml -redirects: - 'testing/redirects/4th-page.md': 'testing/redirects/5th-page.md' -``` -### Redirect stripping all anchors - -This example strips all anchors from the source page. -Any remaining links resolving to anchors on `7th-page.md` will fail link validation. - -```yaml -redirects - 'testing/redirects/7th-page.md': - to: 'testing/redirects/5th-page.md' - anchors: '!' -``` - -Alternate syntax: - -```yaml -redirects: - 'testing/redirects/7th-page.md': '!testing/redirects/5th-page.md' -``` - -To handle removed anchors on a page that still exists, omit the `to:` field: - -```yaml - 'testing/redirects/third-page.md': - anchors: - 'removed-anchor': -``` - -### Redirect with renamed anchors - -This example redirects: - -- `first-page-old.md#old-anchor` → `second-page.md#active-anchor` -- `first-page-old.md#removed-anchor` → `second-page.md` -- Any other anchor is passed through and validated normally. - -```yaml -redirects: - 'testing/redirects/first-page-old.md': - to: 'testing/redirects/second-page.md' - anchors: - 'old-anchor': 'active-anchor' - 'removed-anchor': -``` - -### Redirecting to other repositories - -Use the `repo://path/to/page.md` syntax to redirect across repositories. - -```yaml -redirects: - 'testing/redirects/cross-repo-page.md': 'other-repo://reference/section/new-cross-repo-page.md' -``` - -### Managing complex scenarios with anchors - -* `to`, `anchor` and `many` can be used together to support more complex scenarios. -* Setting `to` at the top level determines the default case, which can be used for partial redirects. -* Cross-repository links are supported, with the same syntax as in the previous example. -* The existing rules for `anchors` also apply here. To define a catch-all redirect, use `{}`. - -```yaml -redirects: - # In this first scenario, the default redirection target remains the same page, with anchors being preserved. - # Omitting the ``anchors`` tag or explicitly setting it as empty are both supported. - 'testing/redirects/8th-page.md': - to: 'testing/redirects/8th-page.md' - many: - - to: 'testing/redirects/second-page.md' - anchors: - 'item-a': 'yy' - - to: 'testing/redirects/third-page.md' - anchors: - 'item-b': - - # In this scenario, the default redirection target is a different page, and anchors are dropped. - 'testing/redirects/deleted-page.md': - to: 'testing/redirects/5th-page.md' - anchors: '!' - many: - - to: "testing/redirects/second-page.md" - anchors: - "aa": "zz" - "removed-anchor": - - to: "other-repo://reference/section/partial-content.md" - anchors: - "bb": "yy" -``` diff --git a/src/tooling/docs-builder/Cli/DiffCommands.cs b/src/tooling/docs-builder/Cli/DiffCommands.cs index 664e9fdbd..b3b2ba26d 100644 --- a/src/tooling/docs-builder/Cli/DiffCommands.cs +++ b/src/tooling/docs-builder/Cli/DiffCommands.cs @@ -57,10 +57,10 @@ public async Task ValidateRedirects([Argument] string? path = null, Cancel } IRepositoryTracker tracker = runningOnCi ? new IntegrationGitRepositoryTracker(path) : new LocalGitRepositoryTracker(collector, root, path); - var changed = tracker.GetChangedFiles() as GitChange[] ?? []; + var changed = tracker.GetChangedFiles(); - if (changed.Length > 0) - _log.LogInformation($"Found {changed.Length} changes to files related to documentation in the current branch."); + if (changed.Any()) + _log.LogInformation($"Found {changed.Count()} changes to files related to documentation in the current branch."); foreach (var notFound in changed.DistinctBy(c => c.FilePath).Where(c => c.ChangeType is GitChangeType.Deleted or GitChangeType.Renamed && !redirects.ContainsKey(c is RenamedGitChange renamed ? renamed.OldFilePath : c.FilePath))) @@ -68,9 +68,7 @@ public async Task ValidateRedirects([Argument] string? path = null, Cancel if (notFound is RenamedGitChange renamed) { collector.EmitError(redirectFileInfo.Name, - runningOnCi - ? $"A file was renamed to '{renamed.NewFilePath}' but it has no redirect configuration set." - : $"File '{renamed.OldFilePath}' was renamed to '{renamed.NewFilePath}' but it has no redirect configuration set."); + $"File '{renamed.OldFilePath}' was renamed to '{renamed.NewFilePath}' but it has no redirect configuration set."); } else if (notFound.ChangeType is GitChangeType.Deleted) { diff --git a/src/tooling/docs-builder/Tracking/IntegrationGitRepositoryTracker.cs b/src/tooling/docs-builder/Tracking/IntegrationGitRepositoryTracker.cs index 04f83c840..81c2718d2 100644 --- a/src/tooling/docs-builder/Tracking/IntegrationGitRepositoryTracker.cs +++ b/src/tooling/docs-builder/Tracking/IntegrationGitRepositoryTracker.cs @@ -2,6 +2,8 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using Microsoft.Extensions.Logging; + namespace Documentation.Builder.Tracking; public class IntegrationGitRepositoryTracker(string lookupPath) : IRepositoryTracker @@ -33,8 +35,12 @@ public IEnumerable GetChangedFiles() var renamedFiles = Environment.GetEnvironmentVariable("RENAMED_FILES"); if (!string.IsNullOrEmpty(renamedFiles)) { - foreach (var file in renamedFiles.Split(' ', StringSplitOptions.RemoveEmptyEntries).Where(f => f.StartsWith(LookupPath))) - yield return new RenamedGitChange(string.Empty, file, GitChangeType.Renamed); + foreach (var pair in renamedFiles.Split(' ', StringSplitOptions.RemoveEmptyEntries).Where(f => f.StartsWith(LookupPath))) + { + var parts = pair.Split(':'); + if (parts.Length == 2) + yield return new RenamedGitChange(parts[0], parts[1], GitChangeType.Renamed); + } } } }