Skip to content

Commit

Permalink
Merge branch 'main' into feature/fix-inline-code-in-left-navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
reakaleek authored Jan 23, 2025
2 parents 9131b38 + 62f580a commit 910bb55
Show file tree
Hide file tree
Showing 13 changed files with 541 additions and 17 deletions.
43 changes: 43 additions & 0 deletions .github/actions/aws-auth/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: AWS Auth

description: |
This is an opinionated action to authenticate with AWS.
It will generate a role ARN based on the repository name and the AWS account ID.
inputs:
aws_account_id:
description: 'The AWS account ID to generate the role ARN for'
required: true
default: '197730964718' # elastic-web
aws_region:
description: 'The AWS region to use'
required: false
default: 'us-east-1'
aws_role_name_prefix:
description: 'The prefix for the role name'
required: false
default: 'elastic-docs-v3-preview-'

runs:
using: composite
steps:
- name: Generate AWS Role ARN
id: role_arn
shell: python
env:
AWS_ACCOUNT_ID: ${{ inputs.aws_account_id }}
ROLE_NAME_PREFIX: ${{ inputs.aws_role_name_prefix }}
run: |
import hashlib
import os
prefix = os.environ["ROLE_NAME_PREFIX"]
m = hashlib.sha256()
m.update(os.environ["GITHUB_REPOSITORY"].encode('utf-8'))
hash = m.hexdigest()[:64-len(prefix)]
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write(f"result=arn:aws:iam::{os.environ["AWS_ACCOUNT_ID"]}:role/{prefix}{hash}")
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ steps.role_arn.outputs.result }}
aws-region: ${{ inputs.aws_region }}
19 changes: 14 additions & 5 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
permissions:
contents: read
packages: read
id-token: write
pull-requests: write
deployments: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -32,8 +35,14 @@ jobs:

- name: Publish AOT
run: ./build.sh publishbinaries

# we run our artifact directly please use the prebuild
# elastic/docs-builder@main GitHub Action for all other repositories!
- name: Build documentation
run: .artifacts/publish/docs-builder/release/docs-builder --strict

- uses: actions/upload-artifact@v4
with:
name: docs-builder-binary
path: .artifacts/publish/docs-builder/release/docs-builder
if-no-files-found: error
retention-days: 1

preview:
needs: build
uses: ./.github/workflows/preview.yml
49 changes: 49 additions & 0 deletions .github/workflows/preview-cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: preview-cleanup

on:
pull_request_target:
types: [closed]

permissions:
deployments: write
id-token: write

jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/aws-auth
- name: Delete s3 objects
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
aws s3 rm "s3://elastic-docs-v3-website-preview/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" --recursive
- name: Delete GitHub environment
uses: actions/github-script@v7
with:
script: |
const { owner, repo } = context.repo;
const deployments = await github.rest.repos.listDeployments({
owner,
repo,
environment: `preview-${context.issue.number}`
});
for (const deployment of deployments.data) {
await github.rest.repos.createDeploymentStatus({
owner,
repo,
deployment_id: deployment.id,
state: 'inactive',
description: 'Marking deployment as inactive'
});
await github.rest.repos.deleteDeployment({
owner,
repo,
deployment_id: deployment.id
});
}

93 changes: 93 additions & 0 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: preview

on:
workflow_call: ~

permissions:
id-token: write
pull-requests: write
deployments: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Create Deployment
uses: actions/github-script@v7
id: deployment
with:
result-encoding: string
script: |
const { owner, repo } = context.repo;
const deployment = await github.rest.repos.createDeployment({
issue_number: context.issue.number,
owner,
repo,
ref: context.payload.pull_request.head.ref,
environment: `preview-${context.issue.number}`,
description: `Preview deployment for PR ${context.issue.number}`,
auto_merge: false,
required_contexts: [],
})
await github.rest.repos.createDeploymentStatus({
deployment_id: deployment.data.id,
owner,
repo,
state: "in_progress",
description: "Deployment created",
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}?pr=${context.issue.number}`,
})
return deployment.data.id
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: docs-builder-binary

# we run our artifact directly please use the prebuild
# elastic/docs-builder@main GitHub Action for all other repositories!
- name: Build documentation
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
chmod +x ./docs-builder
./docs-builder --strict --path-prefix "/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}"
- uses: ./.github/actions/aws-auth

- name: Upload to S3
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
aws s3 sync .artifacts/docs/html "s3://elastic-docs-v3-website-preview/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" --delete
aws cloudfront create-invalidation --distribution-id EKT7LT5PM8RKS --paths "/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}/*"
- name: Update deployment status
uses: actions/github-script@v7
if: steps.deployment.outputs.result
with:
script: |
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: ${{ steps.deployment.outputs.result }},
state: "success",
description: "Deployment completed",
environment_url: `https://docs-v3-preview.elastic.dev/${context.repo.owner}/${context.repo.repo}/pull/${context.issue.number}`,
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}?pr=${context.issue.number}`,
})
- name: Update Deployment Status on Failure
if: failure() && steps.deployment.outputs.result
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: ${{ steps.deployment.outputs.result }},
state: "failure",
description: "Deployment failed",
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}?pr=${context.issue.number}`,
})
13 changes: 12 additions & 1 deletion docs/syntax/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,15 @@ Do note that these inline anchors will be normalized.
## This Is A Header [What about this for an anchor!]
```

Will result in the anchor `what-about-this-for-an-anchor`.
Will result in the anchor `what-about-this-for-an-anchor`.


## Inline anchors

Docsbuilder temporary supports the abbility to create a linkable anchor anywhere on any document.

```markdown
This is text and $$$this-is-an-inline-anchor$$$
```

This feature exists to aid with migration however is scheduled for removal and new content should **NOT** utilize this feature.
16 changes: 16 additions & 0 deletions src/Elastic.Markdown/Helpers/SlugExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 Slugify;

namespace Elastic.Markdown.Helpers;

public static class SlugExtensions
{
private static readonly SlugHelper _slugHelper = new();


public static string Slugify(this string? text) => _slugHelper.GenerateSlug(text);

}
11 changes: 5 additions & 6 deletions src/Elastic.Markdown/IO/MarkdownFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@
using Elastic.Markdown.Myst;
using Elastic.Markdown.Myst.Directives;
using Elastic.Markdown.Myst.FrontMatter;
using Elastic.Markdown.Myst.InlineParsers;
using Elastic.Markdown.Slices;
using Markdig;
using Markdig.Extensions.Yaml;
using Markdig.Syntax;
using Slugify;

namespace Elastic.Markdown.IO;


public record MarkdownFile : DocumentationFile
{
private readonly SlugHelper _slugHelper = new();
private string? _navigationTitle;

public MarkdownFile(IFileInfo sourceFile, IDirectoryInfo rootPath, MarkdownParser parser, BuildContext context)
Expand Down Expand Up @@ -162,16 +161,14 @@ private void ReadDocumentInstructions(MarkdownDocument document)
Collector.EmitWarning(FilePath, "Document has no title, using file name as title.");
}



var contents = document
.Where(block => block is HeadingBlock { Level: >= 2 })
.Cast<HeadingBlock>()
.Select(h => (h.GetData("header") as string, h.GetData("anchor") as string))
.Select(h => new PageTocItem
{
Heading = h.Item1!.StripMarkdown(),
Slug = _slugHelper.GenerateSlug(h.Item2 ?? h.Item1)
Slug = (h.Item2 ?? h.Item1).Slugify()
})
.ToList();
_tableOfContent.Clear();
Expand All @@ -181,8 +178,10 @@ private void ReadDocumentInstructions(MarkdownDocument document)
var labels = document.Descendants<DirectiveBlock>()
.Select(b => b.CrossReferenceName)
.Where(l => !string.IsNullOrWhiteSpace(l))
.Select(_slugHelper.GenerateSlug)
.Select(s => s.Slugify())
.Concat(document.Descendants<InlineAnchor>().Select(a => a.Anchor))
.ToArray();

foreach (var label in labels)
{
if (!string.IsNullOrEmpty(label))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public override bool Close(BlockProcessor processor, Block block)

var newSlice = new StringSlice(header.ToString());
headerBlock.Lines.Lines[0] = new StringLine(ref newSlice);

if (header.IndexOf('$') >= 0)
anchor = HeadingAnchorParser.MatchAnchor().Replace(anchor.ToString(), "");

headerBlock.SetData("anchor", anchor.ToString());
headerBlock.SetData("header", header.ToString());
return base.Close(processor, block);
Expand All @@ -67,4 +71,7 @@ public static partial class HeadingAnchorParser

[GeneratedRegex(@"(?:\[[^[]+\])\s*$", RegexOptions.IgnoreCase, "en-US")]
public static partial Regex MatchAnchor();

[GeneratedRegex(@"\$\$\$[^\$]+\$\$\$", RegexOptions.IgnoreCase, "en-US")]
public static partial Regex InlineAnchors();
}
Loading

0 comments on commit 910bb55

Please sign in to comment.