Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/infra/docs-lambda-changelog-scrubber/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ async Task CopyPassThrough(IAmazonS3 s3Client, string sourceBucket, string key,

async Task<string> ScrubContent(string key, string content, ILambdaContext context)
{
var isBundlePath = key.Contains("/bundles/", StringComparison.OrdinalIgnoreCase);
var isBundlePath = key.Contains("/bundle/", StringComparison.OrdinalIgnoreCase);

if (isBundlePath)
return await ScrubBundle(content, context);
Expand Down
4 changes: 2 additions & 2 deletions src/infra/docs-lambda-changelog-scrubber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ The `bootstrap` binary should be available under:

## Scrubbing logic

- **Bundle files** (`{product}/bundles/*.yaml`): `LinkAllowlistSanitizer.TryApplyBundle` scrubs `prs`/`issues` lists
- **Changelog entries** (`{product}/changelogs/*.yaml`): `LinkAllowlistSanitizer.TryApplyChangelogEntry` scrubs `prs`, `issues`, `description`, `impact`, `action`
- **Bundle files** (`{product}/bundle/*.yaml`): `LinkAllowlistSanitizer.TryApplyBundle` scrubs `prs`/`issues` lists
- **Changelog entries** (`{product}/changelog/*.yaml`): `LinkAllowlistSanitizer.TryApplyChangelogEntry` scrubs `prs`, `issues`, `description`, `impact`, `action`
- The allowlist is built once at cold start from the embedded `assembler.yml` via `BuildAllowReposFromAssembler`
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ internal IReadOnlyList<UploadTarget> DiscoverUploadTargets(IDiagnosticsCollector
continue;
}

var s3Key = $"{product}/changelogs/{fileName}";
var s3Key = $"{product}/changelog/{fileName}";
targets.Add(new UploadTarget(filePath, s3Key));
}
}
Expand Down Expand Up @@ -200,7 +200,7 @@ internal IReadOnlyList<UploadTarget> DiscoverBundleUploadTargets(IDiagnosticsCol
continue;
}

var s3Key = $"{product}/bundles/{fileName}";
var s3Key = $"{product}/bundle/{fileName}";
targets.Add(new UploadTarget(filePath, s3Key));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ public void TryApplyChangelogEntry_NullFields_PreservesNulls()
public void TryApplyChangelogEntry_BarePrNumberWithoutDefaultRepo_KeptWithWarning()
{
// The scrubber Lambda calls TryApplyChangelogEntry with defaultRepo=null because per-entry
// YAMLs uploaded under {product}/changelogs/*.yaml carry no embedded repo context. A bare
// YAMLs uploaded under {product}/changelog/*.yaml carry no embedded repo context. A bare
// numeric PR ref ("155500") must be tolerated rather than failing the whole entry — the
// reference carries no repo identity so it cannot leak a private link, and downstream
// rendering supplies the owner/repo from runtime context.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void DiscoverUploadTargets_SingleProduct_MapsToCorrectS3Key()

targets.Should().HaveCount(1);
targets[0].LocalPath.Should().Be(path);
targets[0].S3Key.Should().Be("elasticsearch/changelogs/entry.yaml");
targets[0].S3Key.Should().Be("elasticsearch/changelog/entry.yaml");
_collector.Errors.Should().Be(0);
}

Expand All @@ -88,8 +88,8 @@ public void DiscoverUploadTargets_MultipleProducts_CreatesTargetPerProduct()
var targets = _service.DiscoverUploadTargets(_collector, _changelogDir);

targets.Should().HaveCount(2);
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelogs/fix.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/changelogs/fix.yaml");
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelog/fix.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/changelog/fix.yaml");
}

[Fact]
Expand Down Expand Up @@ -154,8 +154,8 @@ public void DiscoverUploadTargets_MixedValidAndInvalidProducts_FiltersCorrectly(
var targets = _service.DiscoverUploadTargets(_collector, _changelogDir);

targets.Should().HaveCount(2);
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelogs/mixed.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/changelogs/mixed.yaml");
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelog/mixed.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/changelog/mixed.yaml");
_collector.Warnings.Should().BeGreaterThan(0);
}

Expand Down Expand Up @@ -184,8 +184,8 @@ public void DiscoverUploadTargets_MultipleFiles_DiscoversBoth()
var targets = _service.DiscoverUploadTargets(_collector, _changelogDir);

targets.Should().HaveCount(2);
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelogs/first.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/changelogs/second.yaml");
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelog/first.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/changelog/second.yaml");
}

[Fact]
Expand All @@ -205,8 +205,8 @@ public void DiscoverUploadTargets_ProductWithHyphensAndUnderscores_Accepted()
var targets = _service.DiscoverUploadTargets(_collector, _changelogDir);

targets.Should().HaveCount(2);
targets.Should().Contain(t => t.S3Key == "elastic-agent/changelogs/hyphen.yaml");
targets.Should().Contain(t => t.S3Key == "cloud_hosted/changelogs/hyphen.yaml");
targets.Should().Contain(t => t.S3Key == "elastic-agent/changelog/hyphen.yaml");
targets.Should().Contain(t => t.S3Key == "cloud_hosted/changelog/hyphen.yaml");
_collector.Errors.Should().Be(0);
_collector.Warnings.Should().Be(0);
}
Expand Down Expand Up @@ -245,7 +245,7 @@ public async Task Upload_WithValidChangelogs_UploadsToS3()
_collector.Errors.Should().Be(0);

A.CallTo(() => _s3Client.PutObjectAsync(
A<PutObjectRequest>.That.Matches(r => r.Key == "elasticsearch/changelogs/entry.yaml" && r.BucketName == "test-bucket"),
A<PutObjectRequest>.That.Matches(r => r.Key == "elasticsearch/changelog/entry.yaml" && r.BucketName == "test-bucket"),
A<CancellationToken>._
)).MustHaveHappenedOnceExactly();
}
Expand Down Expand Up @@ -375,7 +375,7 @@ public async Task Upload_BundleArtifactType_UploadsToS3()
_collector.Errors.Should().Be(0);

A.CallTo(() => _s3Client.PutObjectAsync(
A<PutObjectRequest>.That.Matches(r => r.Key == "elasticsearch/bundles/elasticsearch-9.2.0.yaml" && r.BucketName == "test-bucket"),
A<PutObjectRequest>.That.Matches(r => r.Key == "elasticsearch/bundle/elasticsearch-9.2.0.yaml" && r.BucketName == "test-bucket"),
A<CancellationToken>._
)).MustHaveHappenedOnceExactly();
}
Expand Down Expand Up @@ -405,7 +405,7 @@ public void DiscoverBundleUploadTargets_MapsToCorrectS3Key()
var targets = _service.DiscoverBundleUploadTargets(_collector, bundleDir);

targets.Should().HaveCount(1);
targets[0].S3Key.Should().Be("elasticsearch/bundles/elasticsearch-9.2.0.yaml");
targets[0].S3Key.Should().Be("elasticsearch/bundle/elasticsearch-9.2.0.yaml");
_collector.Errors.Should().Be(0);
}

Expand Down Expand Up @@ -436,8 +436,8 @@ public void DiscoverBundleUploadTargets_MultipleProducts_CreatesTargetPerProduct
var targets = _service.DiscoverBundleUploadTargets(_collector, bundleDir);

targets.Should().HaveCount(2);
targets.Should().Contain(t => t.S3Key == "elasticsearch/bundles/stack-9.2.0.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/bundles/stack-9.2.0.yaml");
targets.Should().Contain(t => t.S3Key == "elasticsearch/bundle/stack-9.2.0.yaml");
targets.Should().Contain(t => t.S3Key == "kibana/bundle/stack-9.2.0.yaml");
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ public async Task Upload_NewFile_UploadsSuccessfully()

var uploader = CreateUploader();
var ct = TestContext.Current.CancellationToken;
var result = await uploader.Upload([new UploadTarget(path, "elasticsearch/changelogs/entry.yaml")], ct);
var result = await uploader.Upload([new UploadTarget(path, "elasticsearch/changelog/entry.yaml")], ct);

result.Uploaded.Should().Be(1);
result.Skipped.Should().Be(0);
result.Failed.Should().Be(0);

A.CallTo(() => _s3Client.PutObjectAsync(
A<PutObjectRequest>.That.Matches(r => r.Key == "elasticsearch/changelogs/entry.yaml" && r.BucketName == BucketName),
A<PutObjectRequest>.That.Matches(r => r.Key == "elasticsearch/changelog/entry.yaml" && r.BucketName == BucketName),
A<Cancel>._
)).MustHaveHappenedOnceExactly();
}
Expand All @@ -67,7 +67,7 @@ public async Task Upload_UnchangedFile_SkipsUpload()

var uploader = CreateUploader();
var ct = TestContext.Current.CancellationToken;
var result = await uploader.Upload([new UploadTarget(path, "kibana/changelogs/entry.yaml")], ct);
var result = await uploader.Upload([new UploadTarget(path, "kibana/changelog/entry.yaml")], ct);

result.Uploaded.Should().Be(0);
result.Skipped.Should().Be(1);
Expand All @@ -91,7 +91,7 @@ public async Task Upload_ChangedFile_UploadsNewVersion()

var uploader = CreateUploader();
var ct = TestContext.Current.CancellationToken;
var result = await uploader.Upload([new UploadTarget(path, "elasticsearch/changelogs/entry.yaml")], ct);
var result = await uploader.Upload([new UploadTarget(path, "elasticsearch/changelog/entry.yaml")], ct);

result.Uploaded.Should().Be(1);
result.Skipped.Should().Be(0);
Expand All @@ -112,7 +112,7 @@ public async Task Upload_S3PutFails_CountsAsFailure()

var uploader = CreateUploader();
var ct = TestContext.Current.CancellationToken;
var result = await uploader.Upload([new UploadTarget(path, "elasticsearch/changelogs/entry.yaml")], ct);
var result = await uploader.Upload([new UploadTarget(path, "elasticsearch/changelog/entry.yaml")], ct);

result.Uploaded.Should().Be(0);
result.Skipped.Should().Be(0);
Expand All @@ -129,12 +129,12 @@ public async Task Upload_MixedTargets_ReportsCorrectCounts()
var unchangedEtag = Convert.ToHexStringLower(MD5.HashData("unchanged"u8.ToArray()));

A.CallTo(() => _s3Client.GetObjectMetadataAsync(
A<GetObjectMetadataRequest>.That.Matches(r => r.Key == "es/changelogs/new.yaml"),
A<GetObjectMetadataRequest>.That.Matches(r => r.Key == "es/changelog/new.yaml"),
A<Cancel>._
)).Throws(new AmazonS3Exception("Not Found") { StatusCode = HttpStatusCode.NotFound });

A.CallTo(() => _s3Client.GetObjectMetadataAsync(
A<GetObjectMetadataRequest>.That.Matches(r => r.Key == "es/changelogs/unchanged.yaml"),
A<GetObjectMetadataRequest>.That.Matches(r => r.Key == "es/changelog/unchanged.yaml"),
A<Cancel>._
)).Returns(new GetObjectMetadataResponse { ETag = $"\"{unchangedEtag}\"" });

Expand All @@ -144,8 +144,8 @@ public async Task Upload_MixedTargets_ReportsCorrectCounts()
var uploader = CreateUploader();
var ct = TestContext.Current.CancellationToken;
var result = await uploader.Upload([
new UploadTarget(newPath, "es/changelogs/new.yaml"),
new UploadTarget(unchangedPath, "es/changelogs/unchanged.yaml")
new UploadTarget(newPath, "es/changelog/new.yaml"),
new UploadTarget(unchangedPath, "es/changelog/unchanged.yaml")
], ct);

result.Uploaded.Should().Be(1);
Expand Down
Loading