Skip to content

Commit 8d81400

Browse files
cotticursoragent
andauthored
changelog: use singular S3 key prefixes for changelog/bundle artifacts (#3434)
Align the S3 object key prefixes with the singular entity naming used throughout the codebase (ArtifactType.Changelog / ArtifactType.Bundle). Uploads now land under {product}/changelog/ and {product}/bundle/ instead of the plural {product}/changelogs/ and {product}/bundles/, and the scrubber Lambda detects bundles via the /bundle/ path segment. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent bc1b00c commit 8d81400

6 files changed

Lines changed: 29 additions & 29 deletions

File tree

src/infra/docs-lambda-changelog-scrubber/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ async Task CopyPassThrough(IAmazonS3 s3Client, string sourceBucket, string key,
181181

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

186186
if (isBundlePath)
187187
return await ScrubBundle(content, context);

src/infra/docs-lambda-changelog-scrubber/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ The `bootstrap` binary should be available under:
3737

3838
## Scrubbing logic
3939

40-
- **Bundle files** (`{product}/bundles/*.yaml`): `LinkAllowlistSanitizer.TryApplyBundle` scrubs `prs`/`issues` lists
41-
- **Changelog entries** (`{product}/changelogs/*.yaml`): `LinkAllowlistSanitizer.TryApplyChangelogEntry` scrubs `prs`, `issues`, `description`, `impact`, `action`
40+
- **Bundle files** (`{product}/bundle/*.yaml`): `LinkAllowlistSanitizer.TryApplyBundle` scrubs `prs`/`issues` lists
41+
- **Changelog entries** (`{product}/changelog/*.yaml`): `LinkAllowlistSanitizer.TryApplyChangelogEntry` scrubs `prs`, `issues`, `description`, `impact`, `action`
4242
- The allowlist is built once at cold start from the embedded `assembler.yml` via `BuildAllowReposFromAssembler`

src/services/Elastic.Changelog/Uploading/ChangelogUploadService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ internal IReadOnlyList<UploadTarget> DiscoverUploadTargets(IDiagnosticsCollector
133133
continue;
134134
}
135135

136-
var s3Key = $"{product}/changelogs/{fileName}";
136+
var s3Key = $"{product}/changelog/{fileName}";
137137
targets.Add(new UploadTarget(filePath, s3Key));
138138
}
139139
}
@@ -200,7 +200,7 @@ internal IReadOnlyList<UploadTarget> DiscoverBundleUploadTargets(IDiagnosticsCol
200200
continue;
201201
}
202202

203-
var s3Key = $"{product}/bundles/{fileName}";
203+
var s3Key = $"{product}/bundle/{fileName}";
204204
targets.Add(new UploadTarget(filePath, s3Key));
205205
}
206206
}

tests/Elastic.Changelog.Tests/Changelogs/LinkAllowlistSanitizerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ public void TryApplyChangelogEntry_NullFields_PreservesNulls()
534534
public void TryApplyChangelogEntry_BarePrNumberWithoutDefaultRepo_KeptWithWarning()
535535
{
536536
// The scrubber Lambda calls TryApplyChangelogEntry with defaultRepo=null because per-entry
537-
// YAMLs uploaded under {product}/changelogs/*.yaml carry no embedded repo context. A bare
537+
// YAMLs uploaded under {product}/changelog/*.yaml carry no embedded repo context. A bare
538538
// numeric PR ref ("155500") must be tolerated rather than failing the whole entry — the
539539
// reference carries no repo identity so it cannot leak a private link, and downstream
540540
// rendering supplies the owner/repo from runtime context.

tests/Elastic.Changelog.Tests/Uploading/ChangelogUploadServiceTests.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void DiscoverUploadTargets_SingleProduct_MapsToCorrectS3Key()
6565

6666
targets.Should().HaveCount(1);
6767
targets[0].LocalPath.Should().Be(path);
68-
targets[0].S3Key.Should().Be("elasticsearch/changelogs/entry.yaml");
68+
targets[0].S3Key.Should().Be("elasticsearch/changelog/entry.yaml");
6969
_collector.Errors.Should().Be(0);
7070
}
7171

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

9090
targets.Should().HaveCount(2);
91-
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelogs/fix.yaml");
92-
targets.Should().Contain(t => t.S3Key == "kibana/changelogs/fix.yaml");
91+
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelog/fix.yaml");
92+
targets.Should().Contain(t => t.S3Key == "kibana/changelog/fix.yaml");
9393
}
9494

9595
[Fact]
@@ -154,8 +154,8 @@ public void DiscoverUploadTargets_MixedValidAndInvalidProducts_FiltersCorrectly(
154154
var targets = _service.DiscoverUploadTargets(_collector, _changelogDir);
155155

156156
targets.Should().HaveCount(2);
157-
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelogs/mixed.yaml");
158-
targets.Should().Contain(t => t.S3Key == "kibana/changelogs/mixed.yaml");
157+
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelog/mixed.yaml");
158+
targets.Should().Contain(t => t.S3Key == "kibana/changelog/mixed.yaml");
159159
_collector.Warnings.Should().BeGreaterThan(0);
160160
}
161161

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

186186
targets.Should().HaveCount(2);
187-
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelogs/first.yaml");
188-
targets.Should().Contain(t => t.S3Key == "kibana/changelogs/second.yaml");
187+
targets.Should().Contain(t => t.S3Key == "elasticsearch/changelog/first.yaml");
188+
targets.Should().Contain(t => t.S3Key == "kibana/changelog/second.yaml");
189189
}
190190

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

207207
targets.Should().HaveCount(2);
208-
targets.Should().Contain(t => t.S3Key == "elastic-agent/changelogs/hyphen.yaml");
209-
targets.Should().Contain(t => t.S3Key == "cloud_hosted/changelogs/hyphen.yaml");
208+
targets.Should().Contain(t => t.S3Key == "elastic-agent/changelog/hyphen.yaml");
209+
targets.Should().Contain(t => t.S3Key == "cloud_hosted/changelog/hyphen.yaml");
210210
_collector.Errors.Should().Be(0);
211211
_collector.Warnings.Should().Be(0);
212212
}
@@ -245,7 +245,7 @@ public async Task Upload_WithValidChangelogs_UploadsToS3()
245245
_collector.Errors.Should().Be(0);
246246

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

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

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

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

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

443443
[Fact]

tests/Elastic.Documentation.Integrations.Tests/S3/S3IncrementalUploaderTests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ public async Task Upload_NewFile_UploadsSuccessfully()
4242

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

4747
result.Uploaded.Should().Be(1);
4848
result.Skipped.Should().Be(0);
4949
result.Failed.Should().Be(0);
5050

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

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

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

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

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

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

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

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

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

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

151151
result.Uploaded.Should().Be(1);

0 commit comments

Comments
 (0)