Skip to content

Commit 354953c

Browse files
committed
chore(workflows): enhance permissions for future artifact publication and clarify comments
docs(readme): add advanced usage section for route pattern matching and dynamic segment mismatches docs(metrics): refine build tag guidance for Prometheus and Datadog exporters fix(eventlogger): clarify ShutdownDrainTimeout behavior for graceful shutdown
1 parent b19b9ab commit 354953c

6 files changed

Lines changed: 51 additions & 17 deletions

File tree

.github/workflows/cli-release.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ env:
2525
GO_VERSION: '^1.25'
2626

2727
permissions:
28-
contents: write
28+
contents: write # tagging & attaching release assets
29+
packages: write # allow publishing to registries if added later
2930

3031
jobs:
3132
prepare:

.github/workflows/module-release.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
name: Module Release
22
run-name: Module Release for ${{ inputs.module || github.event.inputs.module }} - ${{ inputs.releaseType || github.event.inputs.releaseType }}
33

4+
# Minimal global permissions; individual jobs do not request escalation beyond content/package writes.
5+
permissions:
6+
contents: write # create tags & push version bumps
7+
packages: write # future-proof for publishing module artifacts
8+
49
on:
510
workflow_dispatch:
611
inputs:

.github/workflows/release-all.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ on:
1212
default: patch
1313

1414
permissions:
15-
# Need contents write for tagging/releases, actions write for workflow dispatches,
16-
# pull-requests & checks write are required by the called auto-bump-modules workflow
17-
contents: write
18-
actions: write
19-
pull-requests: write
20-
checks: write
15+
# Principle of least privilege: core orchestration requires these scopes. No others granted globally.
16+
contents: write # create tags/releases
17+
actions: write # dispatch called workflows
18+
pull-requests: write # create/update bump PRs
19+
checks: write # update status checks from composite jobs
20+
packages: write # allow future artifact/package publication without further scope changes
2121

2222
jobs:
2323

modules/chimux/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,33 @@ The chimux module will automatically discover and use any registered `Middleware
196196

197197
## Advanced Usage
198198

199+
### Route Pattern Matching & Dynamic Segment Mismatches
200+
201+
The underlying Chi router matches the *pattern shape* – a registered route with a
202+
dynamic segment (e.g. `/api/users/{id}`) matches `/api/users/123` as expected, but a
203+
request to `/api/users/` (trailing slash, missing segment) or `/api/users` (no trailing
204+
slash, missing segment) will **not** invoke that handler. This is intentional: Chi treats
205+
`/api/users` and `/api/users/` as distinct from `/api/users/{id}` to avoid accidental
206+
shadowing and ambiguous parameter extraction.
207+
208+
If you want both collection and entity semantics, register both patterns explicitly:
209+
210+
```go
211+
router.Route("/api/users", func(r chimux.Router) {
212+
r.Get("/", listUsers) // GET /api/users
213+
r.Post("/", createUser) // POST /api/users
214+
r.Route("/{id}", func(r chimux.Router) { // GET /api/users/{id}
215+
r.Get("/", getUser) // (Chi normalizes without extra segment; trailing slash optional when calling)
216+
r.Put("/", updateUser)
217+
r.Delete("/", deleteUser)
218+
})
219+
})
220+
```
221+
222+
For optional trailing segments, prefer explicit duplication instead of relying on
223+
middleware redirects. Keeping patterns explicit makes route introspection, dynamic
224+
enable/disable operations, and emitted routing events deterministic.
225+
199226
### Adding custom middleware to specific routes
200227

201228
```go

modules/eventbus/metrics_exporters.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ package eventbus
2727
// prometheus_collector_stub.go -> //go:build !prometheus
2828
// This keeps mainline source simple while letting consumers tailor binaries without forking.
2929
//
30-
// Build tag guidance: To exclude Prometheus support, supply -tags "!prometheus" (assuming
31-
// you split the collector into tagged files as described). Similarly a datadog specific
32-
// exporter could live behind a datadog build tag. We keep a unified file here until a
33-
// concrete need for binary size reduction or dependency trimming warrants the split.
30+
// Build tag guidance: To exclude Prometheus support, supply -tags "!prometheus" (after
31+
// splitting into prometheus_collector.go / prometheus_collector_stub.go). Likewise a
32+
// Datadog exporter can live behind a `datadog` tag. We intentionally keep everything in a
33+
// single file until (a) dependency graph or (b) binary size pressure justifies tag split.
34+
// This documents the approach so consumers understand the future direction without
35+
// misinterpreting current unified source as a lack of modularity.
3436

3537
import (
3638
"context"

modules/eventlogger/config.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,11 @@ type EventLoggerConfig struct {
4141
// When false, the module will not emit com.modular.eventlogger.stopped to avoid races with shutdown.
4242
ShutdownEmitStopped bool `yaml:"shutdownEmitStopped" default:"true" desc:"Emit logger stopped operational event on Stop"`
4343

44-
// ShutdownDrainTimeout specifies how long Stop() should wait for in-flight events to drain.
45-
// Zero or negative duration means "wait indefinitely" (Stop blocks until all events processed).
46-
// This allows operators to explicitly choose between a bounded shutdown and a fully
47-
// lossless drain. A very large positive value is NOT treated specially—only <=0 triggers
48-
// the indefinite behavior.
49-
ShutdownDrainTimeout time.Duration `yaml:"shutdownDrainTimeout" default:"2s" desc:"Maximum time to wait for draining event queue on Stop. Zero or negative = unlimited wait."`
44+
// ShutdownDrainTimeout controls graceful shutdown behavior for in‑flight events.
45+
// If > 0: Stop() waits up to the specified duration then returns (remaining events may be dropped).
46+
// If <= 0: Stop() waits indefinitely for a full drain (lossless shutdown) unless the parent context cancels.
47+
// This explicit <= 0 contract avoids ambiguous huge timeouts and lets operators choose bounded vs. lossless.
48+
ShutdownDrainTimeout time.Duration `yaml:"shutdownDrainTimeout" default:"2s" desc:"Max drain wait on Stop; <=0 = wait indefinitely for all events"`
5049
}
5150

5251
// OutputTargetConfig configures a specific output target for event logs.

0 commit comments

Comments
 (0)