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
21 changes: 9 additions & 12 deletions .cursor/rules/git-flow.mdc
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
---
description: Git flow — develop for work, main for production; releases via tags.
description: Git flow — PRs only; topic → develop → main; tags from main
alwaysApply: true
---

# Git flow (GitHub): develop → main and tagged releases
# Git flow (GitHub): PRs into develop, then develop → main, then tags

- **Branches**: Day-to-day work happens on `develop`. The `main` branch is production and must only be updated from `develop` (merge or squash) when the code is ready for release.
- **Releases**: Before publishing to GitHub or releasing a version:
1. Ensure everything is committed on `develop` and **all tests pass** (`make test` or `go test ./...`).
2. Merge `develop` into `main` (or open a Pull Request develop → main).
3. On `main`, create an annotated tag with the version number (e.g. `v1.0.0`):
`git tag -a v1.0.0 -m "Release 1.0.0"`
and push the tag:
`git push origin v1.0.0`
- **Versions**: Use semantic versioning (MAJOR.MINOR.PATCH) for tags, e.g. `v1.2.3`.
- **Never** commit directly to `main` for features or fixes; everything must go through `develop`, then merge into `main` at release time.
- **No direct pushes** to `develop` or `main`. Do not `git push origin develop` or `git push origin main`. Do not commit on those branches.
- **Day-to-day:** From an **up-to-date `develop`**, create a topic branch (`feature/…`, `fix/…`, `chore/…`, `security/…`, `docs/…`). Commit there, push **that** branch, open a **PR into `develop`**. Wait for **green CI**, merge, **delete** the topic branch. Pull `develop`. Never PR a topic branch into `main`.
- **Ship / production:** Only when releasing: open a **PR `develop` → `main`**, wait for **green CI**, merge. Pull `main`.
- **Tags:** After `main` has the merge, create an **annotated** semver tag on `main` (e.g. `v1.2.3`) and push the tag (`git push origin v1.2.3`). Tagging `develop` or a topic branch is wrong. A merge to `main` without a tag does not publish GHCR/GoReleaser.
- **Release checks:** Before the develop → main PR / tag, **`make release-check`** must pass (see `release-tests.mdc`). Do not push a release tag if CI or Security is red.
- **Afterward:** checkout `develop` and pull. If `main` diverged (e.g. squash merge), sync with a **PR `main` → `develop`**, not a direct push.
- **Versions:** Semantic versioning for tags (`vMAJOR.MINOR.PATCH`). The version cut is a **dedicated PR** (`chore/release-X.Y.Z` → `develop`) — **do not mix** with features, fixes, or dependency bumps. Never bump version on `main`. That PR must include: `VERSION`, CHANGELOG `[Unreleased]` → `[X.Y.Z]`, README badge (and install URLs that pin the tag), **VHS** `docs/demo.gif` (`make install && bash -c "vhs docs/demo.tape"`), man **`.TH`** (`contrib/man/man1/pgwd.1`), **`make port-freebsd-sync`** and **`make port-openbsd-sync`**. Official ports-tree filings (Bugzilla, ports@) are **out of this flow** — personal follow-up, not a release step.
2 changes: 1 addition & 1 deletion .cursor/rules/release-tests.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Before merging to `main` or creating a release (tag and `make release`), run **`

**These are NOT optional.** `make release` depends on `release-check`; if any step fails, the release is blocked.

**When VERSION changes:** (1) Regenerate `docs/demo.gif` with `make install && bash -c "vhs docs/demo.tape"` (run from repo root). The demo shows `pgwd -version`; the GIF must reflect the new version. See `docs/README.md` for VHS setup. (2) Update `contrib/man/man1/pgwd.1` — `.TH` line (date and version). See `.cursor/rules/man-page-sync.mdc`.
**When VERSION changes** (same `chore/release-*` PR): (1) Regenerate `docs/demo.gif` with `make install && bash -c "vhs docs/demo.tape"` from repo root (`bash -c` so zsh does not break VHS). The demo shows `pgwd -version`. See `docs/README.md`. (2) Update `contrib/man/man1/pgwd.1` — `.TH` date and version. See `man-page-sync.mdc`. (3) **`make port-freebsd-sync`** and **`make port-openbsd-sync`** so this repo’s BSD port Makefiles match `VERSION`. Do **not** treat Bugzilla or ports@ as part of the release.

CI runs lint and tests. The Security workflow runs govulncheck and Grype on the image; both must pass (no `continue-on-error`). Do not push a release tag if CI or Security is red.

Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ Context and instructions for AI coding agents working on **pgwd** (Postgres Watc

## Git flow

- **Branches:** Work on `develop`. `main` is production and is only updated from `develop` at release time (see `.cursor/rules/git-flow.mdc`).
- **Branches:** No direct pushes to `develop` or `main`. Topic branch → **PR into `develop`** (green CI, merge, delete branch). Production: **PR `develop` → `main`**, then annotated **`v*`** tag on `main` (see `.cursor/rules/git-flow.mdc` and skill `pgwd-release`).
- **Commits:** Always show the proposed commit message and wait for user approval before running `git commit`. See `.cursor/rules/commit-message-review.mdc`.
- **Releases:** Before releasing: run **`make release-check`** (validates **`VERSION`** semver, then lint, test, **cover-check**, test-integration, test-e2e-kube, **`make docker-scan`**). All must pass — they are MANDATORY.
- **Versioning:** Semantic versioning (MAJOR.MINOR.PATCH) for tags.
- **Versioning:** Semantic versioning (MAJOR.MINOR.PATCH) for tags. The version cut is a **solo PR** into `develop` (`chore/release-X.Y.Z`): `VERSION`, CHANGELOG, README badge, **VHS** `docs/demo.gif`, man **`.TH`**, **`make port-freebsd-sync`** / **`port-openbsd-sync`**. Do not mix with other changes.

## Docker

- Build image with version info: `make docker-build` (passes VERSION, COMMIT, BUILDDATE; without it the binary reports `dev`/`unknown`). For **linux/amd64** only (e.g. push to a private registry from another arch): `make docker-buildx-amd64` (`pgwd:amd64` locally) or `make docker-buildx-amd64-push DOCKER_IMAGE=registry/repo:tag` after `docker login`.
- Build context is whitelisted via `.dockerignore`: only `go.mod`, `go.sum`, `cmd/`, and `internal/` are sent.
- Dockerfile: multi-stage (Go 1.26.5 build; **distroless/static-debian13:nonroot** runtime), non-root user, no shell/OS packages (HTTPS via bundled CA certs in static image).
- Dockerfile: multi-stage (Go 1.26.6 build; **distroless/static-debian13:nonroot** runtime), non-root user, no shell/OS packages (HTTPS via bundled CA certs in static image).

## Repository structure

Expand Down
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Releas

## [Unreleased]

## [1.1.1] - 2026-08-31

Security patch for operators pulling the published binary and GHCR image (Go stdlib + `x/net`). Remaining [plan-1.1.1](docs/plan-1.1.1.md) contract-repair work (daemon latch without store, SPEC, YAML examples) is not in this tag.

### Security

- **Go toolchain:** bump minimum/build Go to **1.26.6** (stdlib fixes: [GO-2026-6218](https://pkg.go.dev/vuln/GO-2026-6218), [GO-2026-6090](https://pkg.go.dev/vuln/GO-2026-6090), [GO-2026-6089](https://pkg.go.dev/vuln/GO-2026-6089), [GO-2026-6088](https://pkg.go.dev/vuln/GO-2026-6088), [GO-2026-5972](https://pkg.go.dev/vuln/GO-2026-5972), [GO-2026-5026](https://pkg.go.dev/vuln/GO-2026-5026)).
- **Dependencies:** bump transitive `golang.org/x/net` to **v0.56.0** ([GO-2026-5942](https://pkg.go.dev/vuln/GO-2026-5942)) so Grype on the image no longer fails `--fail-on high`.

### Docs

- **README / ports:** version badge and install examples → **1.1.1**; FreeBSD/OpenBSD port Makefiles synced from `VERSION`; man `.TH` and `docs/demo.gif`.

## [1.1.0] - 2026-08-10

Incident hygiene for on-call: PagerDuty incident lifecycle and quieter threshold alerts by default.
Expand Down Expand Up @@ -528,7 +541,8 @@ Pre-1.0 security and operator polish: removes insecure Kubernetes password disco

---

[Unreleased]: https://github.com/hrodrig/pgwd/compare/v1.1.0...HEAD
[Unreleased]: https://github.com/hrodrig/pgwd/compare/v1.1.1...HEAD
[1.1.1]: https://github.com/hrodrig/pgwd/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/hrodrig/pgwd/compare/v1.0.1...v1.1.0
[1.0.1]: https://github.com/hrodrig/pgwd/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/hrodrig/pgwd/compare/v0.9.0...v1.0.0
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Local / CI image: compile inside Docker (make docker-build, security workflow Grype scan).
# Release images: GoReleaser builds static binaries, then Dockerfile.release packages them (distroless).
FROM golang:1.26.5-alpine AS build
FROM golang:1.26.6-alpine AS build
ARG VERSION=dev
ARG COMMIT=unknown
ARG BUILDDATE=unknown
Expand Down
Loading
Loading