Skip to content

Commit b7cfe2e

Browse files
committed
chore: governance pack — security policy, contributing, dependabot, version single-source, CI hardening
- SECURITY.md: private vulnerability reporting (enabled on repo), SLA, scope - CONTRIBUTING.md: build/test setup, test conventions, AOT constraints, PR expectations - Issue templates (bug/feature/config), PR template, dependabot.yml (weekly, grouped NuGet minor+patch) - Version single source: version.txt -> Directory.Build.props (core+client csproj), release workflow reads it per job (hardcoded RELEASE_VERSION removed), npm-publish syncs package.json, postinstall.js derives download URL from its own package version - RELEASING.md: full release checklist, version model, secrets, hotfix procedure - CI: PostgreSQL 15/16/17 matrix in test.yml; AOT smoke test (--version + --validate against live PostgreSQL) in build-linux before asset upload - README: Contributing and Security sections link the new docs
1 parent 99c4cee commit b7cfe2e

17 files changed

Lines changed: 327 additions & 12 deletions
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Bug report
2+
description: Something doesn't work as documented
3+
labels: ["bug"]
4+
body:
5+
- type: input
6+
id: version
7+
attributes:
8+
label: Version
9+
description: NpgsqlRest version (binary `--version`, NuGet package, Docker tag, or npm version)
10+
placeholder: "3.17.0 (npgsqlrest-linux64)"
11+
validations:
12+
required: true
13+
- type: textarea
14+
id: repro
15+
attributes:
16+
label: Minimal reproduction
17+
description: The SQL (create function + comment annotations, or the .sql file) and the relevant config section
18+
placeholder: |
19+
```sql
20+
create function my_func(_id int) returns text language sql as $$ select 'x' $$;
21+
comment on function my_func is 'HTTP GET';
22+
```
23+
```json
24+
{ "NpgsqlRest": { ... } }
25+
```
26+
validations:
27+
required: true
28+
- type: textarea
29+
id: request
30+
attributes:
31+
label: Request and actual response
32+
description: The HTTP request you made and the full response you got (status + body)
33+
validations:
34+
required: true
35+
- type: textarea
36+
id: expected
37+
attributes:
38+
label: Expected response
39+
validations:
40+
required: true
41+
- type: textarea
42+
id: logs
43+
attributes:
44+
label: Relevant log output
45+
render: text

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: Security vulnerability
4+
url: https://github.com/NpgsqlRest/NpgsqlRest/security/advisories/new
5+
about: Please report security issues privately - do NOT open a public issue. See SECURITY.md.
6+
- name: Documentation
7+
url: https://npgsqlrest.com
8+
about: Guides, config reference, and annotation reference.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Feature request
2+
description: Suggest a new capability or improvement
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: What problem does this solve?
9+
description: Describe the use case, not just the mechanism
10+
validations:
11+
required: true
12+
- type: textarea
13+
id: proposal
14+
attributes:
15+
label: Proposed solution
16+
description: If you have a shape in mind (annotation, config key, behavior), sketch it
17+
- type: textarea
18+
id: alternatives
19+
attributes:
20+
label: Workarounds you've considered

.github/dependabot.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "nuget"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
groups:
8+
nuget-minor-patch:
9+
update-types: ["minor", "patch"]
10+
open-pull-requests-limit: 5
11+
12+
- package-ecosystem: "github-actions"
13+
directory: "/"
14+
schedule:
15+
interval: "weekly"
16+
17+
- package-ecosystem: "npm"
18+
directory: "/npm"
19+
schedule:
20+
interval: "weekly"

.github/pull_request_template.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## What does this PR do?
2+
3+
4+
5+
## Test plan
6+
7+
<!-- New/updated tests, and what you ran locally (full suite needs PostgreSQL on localhost:5432). -->
8+
9+
- [ ] Tests added/updated (full-string response assertions, SQL setup co-located — see CONTRIBUTING.md)
10+
- [ ] `dotnet test` green locally
11+
12+
## Checklist
13+
14+
- [ ] Changelog entry added to `changelog/v<next-version>.md` (user-facing changes)
15+
- [ ] Breaking change? → called out in the changelog under "Breaking Changes"
16+
- [ ] AOT/trim-safe (no reflection-based serialization or libraries)

.github/workflows/build-test-publish.yml

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ on:
77
branches: [ master ]
88
workflow_dispatch:
99

10-
env:
11-
RELEASE_VERSION: v3.16.3
12-
1310
# Add workflow-level permissions
1411
permissions:
1512
contents: write
@@ -58,6 +55,8 @@ jobs:
5855
steps:
5956
- name: Checkout code
6057
uses: actions/checkout@v4
58+
- name: Set release version from version.txt
59+
run: echo "RELEASE_VERSION=v$(cat version.txt)" >> "$GITHUB_ENV"
6160
- name: Extract changelog for this version
6261
id: changelog
6362
run: |
@@ -136,6 +135,20 @@ jobs:
136135
runs-on: ubuntu-22.04
137136
permissions:
138137
contents: write
138+
services:
139+
postgres:
140+
image: postgres:17
141+
env:
142+
POSTGRES_USER: postgres
143+
POSTGRES_PASSWORD: postgres
144+
POSTGRES_DB: postgres
145+
ports:
146+
- 5432:5432
147+
options: >-
148+
--health-cmd pg_isready
149+
--health-interval 10s
150+
--health-timeout 5s
151+
--health-retries 5
139152
steps:
140153
- uses: actions/checkout@v4
141154
- name: Setup .NET10
@@ -144,6 +157,18 @@ jobs:
144157
dotnet-version: 10.0.x
145158
- name: Build Linux AOT
146159
run: dotnet publish ./NpgsqlRestClient/NpgsqlRestClient.csproj -r linux-x64 -c Release
160+
- name: AOT smoke test (config validation + database connection)
161+
run: |
162+
cat > smoke.appsettings.json <<'SMOKE'
163+
{
164+
"ConnectionStrings": {
165+
"Default": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=postgres"
166+
}
167+
}
168+
SMOKE
169+
BIN=./NpgsqlRestClient/bin/Release/net10.0/linux-x64/publish/NpgsqlRestClient
170+
"$BIN" --version
171+
"$BIN" smoke.appsettings.json --validate
147172
- name: Upload Linux executable
148173
uses: actions/upload-release-asset@v1
149174
env:
@@ -219,6 +244,8 @@ jobs:
219244
steps:
220245
- name: Checkout code
221246
uses: actions/checkout@v4
247+
- name: Set release version from version.txt
248+
run: echo "RELEASE_VERSION=v$(cat version.txt)" >> "$GITHUB_ENV"
222249
- name: Download Linux executable artifact
223250
uses: actions/download-artifact@v4
224251
with:
@@ -256,6 +283,8 @@ jobs:
256283
steps:
257284
- name: Checkout code
258285
uses: actions/checkout@v4
286+
- name: Set release version from version.txt
287+
run: echo "RELEASE_VERSION=v$(cat version.txt)" >> "$GITHUB_ENV"
259288
- name: Set up Docker Buildx
260289
uses: docker/setup-buildx-action@v3
261290
- name: Login to Docker Hub
@@ -284,6 +313,8 @@ jobs:
284313
steps:
285314
- name: Checkout code
286315
uses: actions/checkout@v4
316+
- name: Set release version from version.txt
317+
run: echo "RELEASE_VERSION=v$(cat version.txt)" >> "$GITHUB_ENV"
287318
- name: Download Linux ARM64 executable artifact
288319
uses: actions/download-artifact@v4
289320
with:
@@ -321,6 +352,8 @@ jobs:
321352
steps:
322353
- name: Checkout code
323354
uses: actions/checkout@v4
355+
- name: Set release version from version.txt
356+
run: echo "RELEASE_VERSION=v$(cat version.txt)" >> "$GITHUB_ENV"
324357
- name: Download Linux executable artifact
325358
uses: actions/download-artifact@v4
326359
with:
@@ -360,6 +393,8 @@ jobs:
360393
uses: actions/setup-node@v4
361394
with:
362395
node-version: '24'
396+
- name: Sync npm package version from version.txt
397+
run: cd npm && npm version "$(cat ../version.txt)" --no-git-tag-version --allow-same-version
363398
- name: Publish to npm with OIDC
364399
uses: JS-DevTools/npm-publish@v4
365400
with:

.github/workflows/test.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ on:
1212
jobs:
1313
test:
1414
runs-on: ubuntu-22.04
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
postgres-version: [15, 16, 17]
1519
steps:
1620
- name: Install PostgreSQL
1721
uses: vb-consulting/postgresql-action@v1
1822
with:
19-
postgresql version: '17'
23+
postgresql version: '${{ matrix.postgres-version }}'
2024
postgresql user: 'postgres'
2125
postgresql password: 'postgres'
2226
- uses: actions/checkout@v4

CONTRIBUTING.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Contributing to NpgsqlRest
2+
3+
Thank you for considering a contribution! Bug reports, documentation fixes, tests, and features are all welcome.
4+
5+
## Quick orientation
6+
7+
| Part | Path | What it is |
8+
|---|---|---|
9+
| Core library | `NpgsqlRest/` | The middleware: PostgreSQL routines/SQL files → REST endpoints (NuGet) |
10+
| Client app | `NpgsqlRestClient/` | The shipped binary: config-driven host (auth, caching, static files, …) |
11+
| Plugins | `plugins/` | TsClient, SqlFileSource, CrudSource, OpenApi, HttpFiles, Mcp (independent NuGet versions) |
12+
| Tests | `NpgsqlRestTests/` | Integration tests against a real PostgreSQL |
13+
| Docs | [npgsqlrest-docs](https://github.com/NpgsqlRest/npgsqlrest-docs) | Documentation website (separate repo) |
14+
15+
## Building and testing
16+
17+
Prerequisites: **.NET 10 SDK** and a local **PostgreSQL** (any recent version; CI tests 15/16/17) listening on `localhost:5432` with user `postgres` / password `postgres`. The test run creates and drops its own database (`npgsql_rest_test`); connection constants live in `NpgsqlRestTests/Setup/Database.cs`.
18+
19+
```sh
20+
dotnet build
21+
dotnet test NpgsqlRestTests/NpgsqlRestTests.csproj
22+
```
23+
24+
## Test conventions (please follow these — PRs that don't will be asked to change)
25+
26+
- **Assert full response strings**, not fragments. A test pins the exact wire output.
27+
- **SQL setup lives in the same file as the assertions**: add a `public static void YourTests()` method on the `Database` partial class appending your `create function …` to the shared script (it is auto-registered via reflection), with the `[Collection("TestFixture")]` test class below it. Copy the pattern from any file in `NpgsqlRestTests/BodyTests/`.
28+
- Pitfalls: don't name test routines after PostgreSQL built-ins (`to_date`, …); `NameSimilarTo` treats `_` as a wildcard; response JSON keys are camelCase.
29+
- Tests must be deterministic — no fixed sleeps; await observable conditions with timeouts.
30+
31+
## Code constraints
32+
33+
- **AOT/trim-safe only.** The client publishes with `PublishAot=true` + `TrimMode=full`: no reflection-based serialization or libraries, JSON via source-generated/`System.Text.Json.Nodes` patterns. (Note: `JsonArray.Add(x)` needs an explicit `(JsonNode?)` cast.)
34+
- Match the surrounding code's style and comment density. Comments explain constraints, not narrate lines.
35+
- Public API of the core library is a published NuGet surface — breaking changes need a strong justification and a changelog entry under "Breaking Changes".
36+
37+
## Pull requests
38+
39+
1. Open an issue first for anything non-trivial — agreeing on the approach saves everyone time.
40+
2. Include tests for behavior changes (see conventions above).
41+
3. Add a changelog entry to `changelog/v<next-version>.md` describing the change in user-facing terms.
42+
4. Keep PRs focused — one logical change per PR.
43+
5. CI must be green (build + full test suite on PostgreSQL 15/16/17).
44+
45+
## Reporting bugs
46+
47+
Use the bug-report issue template. The single most useful thing you can provide is a **minimal reproduction**: the SQL (`create function …` + comment annotations or `.sql` file), the relevant config section, the request, and the expected vs. actual full response.
48+
49+
## Security issues
50+
51+
**Do not open public issues for vulnerabilities** — see [SECURITY.md](SECURITY.md).
52+
53+
## Labels
54+
55+
- `good-first-issue` — small, well-scoped, a good entry point
56+
- `help-wanted` — larger items looking for a contributor
57+
- `roadmap` — planned by the maintainer

Directory.Build.props

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project>
2+
<!--
3+
Single source of truth for the product version (core library + NpgsqlRestClient + npm package + release tag).
4+
Edit version.txt in the repo root - everything else derives from it (see RELEASING.md).
5+
Plugins under plugins/ version independently and do NOT use this property.
6+
-->
7+
<PropertyGroup>
8+
<NpgsqlRestProductVersion>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)version.txt').Trim())</NpgsqlRestProductVersion>
9+
</PropertyGroup>
10+
</Project>

NpgsqlRest/NpgsqlRest.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
<GenerateDocumentationFile>true</GenerateDocumentationFile>
3030
<PackageReadmeFile>README.MD</PackageReadmeFile>
3131
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).xml</DocumentationFile>
32-
<Version>3.16.2</Version>
33-
<AssemblyVersion>3.16.2</AssemblyVersion>
34-
<FileVersion>3.16.2</FileVersion>
35-
<PackageVersion>3.16.2</PackageVersion>
32+
<Version>$(NpgsqlRestProductVersion)</Version>
33+
<AssemblyVersion>$(NpgsqlRestProductVersion)</AssemblyVersion>
34+
<FileVersion>$(NpgsqlRestProductVersion)</FileVersion>
35+
<PackageVersion>$(NpgsqlRestProductVersion)</PackageVersion>
3636
<EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>
3737
</PropertyGroup>
3838

0 commit comments

Comments
 (0)