@reventlessdev/reventless-aws 3.0.0-alpha.273 → 3.0.0-alpha.274
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.274 (2026-08-08)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **aws:** scope a managed log group by project as well as stack ([f3ea01a](https://github.com/ReventlessDev/reventless-core/commit/f3ea01a254465012becf6a27b401f10382439864))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
# 3.0.0-alpha.273 (2026-08-08)
|
|
7
14
|
|
|
8
15
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-aws",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.274",
|
|
4
4
|
"description": "AWS adapters for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"dependencies": {
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
"sury": "11.0.0-alpha.4",
|
|
14
14
|
"uuid": "^13.0.0",
|
|
15
15
|
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.4",
|
|
16
|
-
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
17
|
-
"@reventlessdev/rescript-pulumi-aws": "2.4.0-alpha.67",
|
|
18
16
|
"@reventlessdev/rescript-node": "2.0.0-alpha.2",
|
|
19
17
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
18
|
+
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
19
|
+
"@reventlessdev/rescript-pulumi-aws": "2.4.0-alpha.67",
|
|
20
20
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.18",
|
|
21
|
-
"@reventlessdev/
|
|
21
|
+
"@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
|
|
22
22
|
"@reventlessdev/reventless-core": "3.0.0-alpha.217",
|
|
23
23
|
"@reventlessdev/reventless-interop": "3.0.0-alpha.30",
|
|
24
|
-
"@reventlessdev/
|
|
24
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.128",
|
|
25
25
|
"@reventlessdev/reventless-postgres": "3.0.0-alpha.81",
|
|
26
26
|
"@reventlessdev/reventless-spec": "3.0.0-alpha.102"
|
|
27
27
|
},
|
|
@@ -51,11 +51,21 @@ let applyLogLevelDefault = (variables: dict<Pulumi.Input.t<string>>) =>
|
|
|
51
51
|
- **stable**: it carries no `-<7hex>` Pulumi suffix, so replacing a function
|
|
52
52
|
keeps its group instead of stranding the old one as an orphan nothing
|
|
53
53
|
tears down.
|
|
54
|
-
- **
|
|
55
|
-
reason the physical name was used before.
|
|
54
|
+
- **deployment-scoped**: deployments sharing an account cannot collide, which
|
|
55
|
+
was the reason the physical name was used before.
|
|
56
|
+
|
|
57
|
+
The scope is `project`/`stack`, and **both halves are load-bearing**. A stack
|
|
58
|
+
name alone is not a discriminator: every plugin of one platform is deployed as
|
|
59
|
+
its own Pulumi project under the *same* stack name (`alpha`, `beta`, …), and
|
|
60
|
+
the components inside them are named by role rather than by owner — so several
|
|
61
|
+
projects each host an `AllStateViewSlices`, an `AllReadModels`, an
|
|
62
|
+
`AllAggregatesCmdHandler`. Scoping on the stack alone gives all of them one
|
|
63
|
+
name, and every deployment after the first fails with
|
|
64
|
+
`ResourceAlreadyExistsException`.
|
|
56
65
|
|
|
57
66
|
Pure, so the naming is decidable without Pulumi. */
|
|
58
|
-
let logGroupNameFor = (~stack: string, ~name: string): string =>
|
|
67
|
+
let logGroupNameFor = (~project: string, ~stack: string, ~name: string): string =>
|
|
68
|
+
`/aws/lambda/${project}-${stack}-${name}`
|
|
59
69
|
|
|
60
70
|
// Create the managed CloudWatch log group for a Lambda **before** the function
|
|
61
71
|
// that writes to it, so the function can be pointed at it via `loggingConfig`
|
|
@@ -101,7 +111,11 @@ let makeManagedLogGroup = (
|
|
|
101
111
|
Cloudwatch.LogGroup.make(
|
|
102
112
|
~name=`${name}LogGroup`,
|
|
103
113
|
~args={
|
|
104
|
-
name: logGroupNameFor(
|
|
114
|
+
name: logGroupNameFor(
|
|
115
|
+
~project=Pulumi.Pulumi.getProjectName(),
|
|
116
|
+
~stack,
|
|
117
|
+
~name,
|
|
118
|
+
)->Pulumi.Input.make,
|
|
105
119
|
retentionInDays: days->Pulumi.Input.make,
|
|
106
120
|
tags,
|
|
107
121
|
},
|
|
@@ -36,8 +36,8 @@ function applyLogLevelDefault(variables) {
|
|
|
36
36
|
variables[match[0]] = match[1];
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
function logGroupNameFor(stack, name) {
|
|
40
|
-
return `/aws/lambda/` + stack + `-` + name;
|
|
39
|
+
function logGroupNameFor(project, stack, name) {
|
|
40
|
+
return `/aws/lambda/` + project + `-` + stack + `-` + name;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function makeManagedLogGroup(name, retentionDaysOverride, tags, opts, param) {
|
|
@@ -48,7 +48,7 @@ function makeManagedLogGroup(name, retentionDaysOverride, tags, opts, param) {
|
|
|
48
48
|
match$1 ? Util_LogRetention$ReventlessAws.retentionDaysFor(stack, match[1], Stdlib_Option.flatMap(Util_LocalConfig$ReventlessAws.get("logRetentionDays"), s => Stdlib_Int.fromString(s, undefined))) : undefined
|
|
49
49
|
);
|
|
50
50
|
return Stdlib_Option.map(retentionDays, days => new (Aws.cloudwatch.LogGroup)(name + `LogGroup`, {
|
|
51
|
-
name: logGroupNameFor(stack, name),
|
|
51
|
+
name: logGroupNameFor(Pulumi.getProject(), stack, name),
|
|
52
52
|
retentionInDays: days,
|
|
53
53
|
tags: tags
|
|
54
54
|
}, opts !== undefined ? Primitive_option.valFromOption(opts) : undefined));
|
|
@@ -5,32 +5,44 @@ open JestGlobals
|
|
|
5
5
|
// (the group can be created before the function, and pointed at from
|
|
6
6
|
// `loggingConfig`), so the properties it has to keep are worth pinning.
|
|
7
7
|
describe("Util_LambdaLogging.logGroupNameFor", () => {
|
|
8
|
+
let nameFor = (~project="online-shop-catalog-aws", ~stack="alpha", ~name) =>
|
|
9
|
+
Util_LambdaLogging.logGroupNameFor(~project, ~stack, ~name)
|
|
10
|
+
|
|
8
11
|
testSync("is the conventional Lambda group prefix", () =>
|
|
9
|
-
expect(
|
|
10
|
-
"/aws/lambda/alpha-AllReadModels",
|
|
12
|
+
expect(nameFor(~name="AllReadModels"))->toBe(
|
|
13
|
+
"/aws/lambda/online-shop-catalog-aws-alpha-AllReadModels",
|
|
11
14
|
)
|
|
12
15
|
)
|
|
13
16
|
|
|
14
17
|
testSync("carries no Pulumi physical-name suffix, so a replaced function keeps its group", () => {
|
|
15
|
-
let before =
|
|
16
|
-
let afterReplacement =
|
|
18
|
+
let before = nameFor(~name="AllReadModels")
|
|
19
|
+
let afterReplacement = nameFor(~name="AllReadModels")
|
|
17
20
|
expect(before)->toBe(afterReplacement)
|
|
18
21
|
})
|
|
19
22
|
|
|
20
|
-
testSync("is stack-scoped, so
|
|
21
|
-
expect(
|
|
22
|
-
|
|
23
|
+
testSync("is stack-scoped, so environments of one project cannot collide", () =>
|
|
24
|
+
expect(nameFor(~stack="pr-42", ~name="AllReadModels"))->not_->toBe(
|
|
25
|
+
nameFor(~stack="alpha", ~name="AllReadModels"),
|
|
23
26
|
)
|
|
24
27
|
)
|
|
25
28
|
|
|
29
|
+
// The regression this scoping exists for. Every plugin of one platform is its
|
|
30
|
+
// own Pulumi PROJECT deployed under the SAME stack name, and components are
|
|
31
|
+
// named by role rather than by owner — so several projects each host an
|
|
32
|
+
// `AllStateViewSlices`. Scoping on the stack alone gave them one name, and
|
|
33
|
+
// every deploy after the first failed with ResourceAlreadyExistsException.
|
|
34
|
+
testSync("is project-scoped, so one platform's plugins cannot collide", () =>
|
|
35
|
+
expect(nameFor(~project="online-shop-catalog-aws", ~name="AllStateViewSlices"))
|
|
36
|
+
->not_
|
|
37
|
+
->toBe(nameFor(~project="online-shop-ordering-aws", ~name="AllStateViewSlices"))
|
|
38
|
+
)
|
|
39
|
+
|
|
26
40
|
testSync("differs from the group Lambda would auto-create for the same function", () => {
|
|
27
41
|
// Lambda auto-creates `/aws/lambda/<physical name>`, and the physical name
|
|
28
42
|
// always carries Pulumi's `-<7hex>` suffix. Not colliding with it is what
|
|
29
43
|
// makes the create unconditionally safe on a stack whose groups AWS already
|
|
30
44
|
// made.
|
|
31
45
|
let autoCreated = "/aws/lambda/AllReadModels-0287438"
|
|
32
|
-
expect(
|
|
33
|
-
autoCreated,
|
|
34
|
-
)
|
|
46
|
+
expect(nameFor(~name="AllReadModels"))->not_->toBe(autoCreated)
|
|
35
47
|
})
|
|
36
48
|
})
|
|
@@ -3,19 +3,27 @@
|
|
|
3
3
|
import * as Util_LambdaLogging$ReventlessAws from "../src/util/Util_LambdaLogging.res.mjs";
|
|
4
4
|
|
|
5
5
|
globalThis.describe("Util_LambdaLogging.logGroupNameFor", () => {
|
|
6
|
+
let nameFor = (projectOpt, stackOpt, name) => {
|
|
7
|
+
let project = projectOpt !== undefined ? projectOpt : "online-shop-catalog-aws";
|
|
8
|
+
let stack = stackOpt !== undefined ? stackOpt : "alpha";
|
|
9
|
+
return Util_LambdaLogging$ReventlessAws.logGroupNameFor(project, stack, name);
|
|
10
|
+
};
|
|
6
11
|
globalThis.test("is the conventional Lambda group prefix", () => {
|
|
7
|
-
globalThis.expect(
|
|
12
|
+
globalThis.expect(nameFor(undefined, undefined, "AllReadModels")).toBe("/aws/lambda/online-shop-catalog-aws-alpha-AllReadModels");
|
|
8
13
|
});
|
|
9
14
|
globalThis.test("carries no Pulumi physical-name suffix, so a replaced function keeps its group", () => {
|
|
10
|
-
let before =
|
|
11
|
-
let afterReplacement =
|
|
15
|
+
let before = nameFor(undefined, undefined, "AllReadModels");
|
|
16
|
+
let afterReplacement = nameFor(undefined, undefined, "AllReadModels");
|
|
12
17
|
globalThis.expect(before).toBe(afterReplacement);
|
|
13
18
|
});
|
|
14
|
-
globalThis.test("is stack-scoped, so
|
|
15
|
-
globalThis.expect(
|
|
19
|
+
globalThis.test("is stack-scoped, so environments of one project cannot collide", () => {
|
|
20
|
+
globalThis.expect(nameFor(undefined, "pr-42", "AllReadModels")).not.toBe(nameFor(undefined, "alpha", "AllReadModels"));
|
|
21
|
+
});
|
|
22
|
+
globalThis.test("is project-scoped, so one platform's plugins cannot collide", () => {
|
|
23
|
+
globalThis.expect(nameFor("online-shop-catalog-aws", undefined, "AllStateViewSlices")).not.toBe(nameFor("online-shop-ordering-aws", undefined, "AllStateViewSlices"));
|
|
16
24
|
});
|
|
17
25
|
globalThis.test("differs from the group Lambda would auto-create for the same function", () => {
|
|
18
|
-
globalThis.expect(
|
|
26
|
+
globalThis.expect(nameFor(undefined, undefined, "AllReadModels")).not.toBe("/aws/lambda/AllReadModels-0287438");
|
|
19
27
|
});
|
|
20
28
|
});
|
|
21
29
|
|