Skip to content

feat: automated CI/CD with GitHub native release notes#1

Merged
namastex888 merged 5 commits into
mainfrom
feat/github-native-release-notes
Dec 6, 2025
Merged

feat: automated CI/CD with GitHub native release notes#1
namastex888 merged 5 commits into
mainfrom
feat/github-native-release-notes

Conversation

@namastex888

Copy link
Copy Markdown
Contributor

Summary

  • Add PR label-triggered releases (rc@next, stable@latest)
  • Add cross-platform Bun builds (Linux x64/arm64, macOS x64/arm64, Windows x64)
  • Add GitHub native release notes via .github/release.yml
  • Remove custom changelog generation from release script
  • Update README with benchmark results (vs competitors + Bun migration)
  • Update Makefile with release-rc, release-stable, release-dry targets

GitHub Configuration Required

Before testing, configure in repo settings:

  1. Create environment: npm-publish
  2. Add secret: NPM_TOKEN (npm access token)
  3. Create labels: rc, stable

Test Plan

  • Add rc label to this PR and merge
  • Verify GitHub Actions builds all 5 platforms
  • Verify npm publish with @next tag
  • Verify GitHub Release has auto-generated release notes

The @embedded-postgres binaries are compiled against ICU 60, but modern
Linux distros (Ubuntu 22.04+, Debian 12+) ship with ICU 70+. The binaries
have RUNPATH=$ORIGIN/../lib, but this fails when package managers (pnpm,
yarn PnP) use symlinks/hardlinks that break the relative path resolution.

Solution: Explicitly set LD_LIBRARY_PATH (Linux) and DYLD_LIBRARY_PATH
(macOS) to include the bundled ICU libraries from @embedded-postgres.

This ensures pgserve works across:
- npm, pnpm, yarn, and yarn PnP installations
- Ubuntu 22.04+, 24.04, Debian 12+
- Any Linux distro with ICU 70+
Bun migration:
- Use bun:test for test runner
- Update Makefile to use bun install/test
- Add GitHub Actions CI with Bun
- Add bun.lock for dependency pinning
- Update README with Bun installation

RAM mode (--ram flag):
- Use /dev/shm for true RAM storage on Linux
- 2x performance improvement over disk mode
- Updated benchmarks to show RAM mode results

Fixes:
- Add password auth to test clients
- Update multi-tenant test assertions
- Add PR label-triggered releases (rc → @next, stable → @latest)
- Add cross-platform Bun builds (Linux, macOS, Windows)
- Add GitHub native release notes via .github/release.yml
- Remove custom changelog generation from release script
- Update README with benchmark results
- Update Makefile with release-rc, release-stable, release-dry targets
- Fix deadcode check (remove unused export, update knip config)
@gitguardian

gitguardian Bot commented Dec 6, 2025

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
18760271 Triggered Generic Password 2c8812a tests/multi-tenant.test.js View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @namastex888, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the project's CI/CD pipeline by introducing automated release management and native GitHub release notes. It also improves developer experience and runtime performance by migrating to Bun for various tasks and introducing a new RAM-based storage option for PostgreSQL on Linux. These changes streamline the release process, provide better insights into changes, and offer substantial speed improvements for users.

Highlights

  • Automated CI/CD Releases: Implemented GitHub Actions workflows for automated releases, triggered by PR labels. Merging a PR with the 'rc' label publishes to npm with the '@next' tag, while the 'stable' label promotes to '@latest'.
  • GitHub Native Release Notes: Configured .github/release.yml to leverage GitHub's native release notes generation, providing structured and automatic changelogs for releases.
  • Cross-Platform Bun Builds: Added new Makefile targets and build configurations to generate standalone executables for various platforms, including Linux (x64/arm64), macOS (x64/arm64), and Windows (x64), all powered by Bun.
  • Bun Runtime Integration and Performance: Migrated core development scripts (install, test, bench) from npm/Node.js to Bun, and updated the pgserve CLI to support a new --ram flag for Linux, enabling significantly faster PostgreSQL operations by utilizing /dev/shm.
  • Updated Benchmarks and Documentation: The README has been updated with new benchmark results showcasing the performance gains from the Bun migration and the --ram mode, providing clear comparisons against other database solutions.
Ignored Files
  • Ignored by pattern: .github/workflows/** (3)
    • .github/workflows/build-all-platforms.yml
    • .github/workflows/ci.yml
    • .github/workflows/release.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a sophisticated CI/CD pipeline using GitHub Actions and Bun, which is a significant improvement. The migration to Bun for builds and scripting, along with the new --ram feature, brings impressive performance gains that are well-documented in the README. The new release process based on PR labels is a great step towards automation. The code is well-structured, and the changes are thoughtfully implemented. I've provided a few suggestions to improve maintainability and robustness. Overall, this is an excellent contribution.

Comment thread Makefile
Comment on lines +170 to +198
.PHONY: build build-linux build-macos build-windows build-all clean-dist

build: ## Build standalone executable for current platform
@echo "$(CYAN)🔨 Building standalone executable...$(RESET)"
@mkdir -p $(DIST_DIR)
@bun build --compile bin/pglite-server.js --outfile $(DIST_DIR)/pgserve
@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve$(RESET)"

build-linux: ## Build for Linux (x64 + arm64)
@echo "$(CYAN)🐧 Building for Linux...$(RESET)"
@mkdir -p $(DIST_DIR)
@bun build --compile --target=bun-linux-x64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-linux-x64
@bun build --compile --target=bun-linux-arm64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-linux-arm64
@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-linux-x64$(RESET)"
@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-linux-arm64$(RESET)"

build-macos: ## Build for macOS (x64 + arm64)
@echo "$(CYAN)🍎 Building for macOS...$(RESET)"
@mkdir -p $(DIST_DIR)
@bun build --compile --target=bun-darwin-x64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-darwin-x64
@bun build --compile --target=bun-darwin-arm64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-darwin-arm64
@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-darwin-x64$(RESET)"
@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-darwin-arm64$(RESET)"

build-windows: ## Build for Windows (x64)
@echo "$(CYAN)🪟 Building for Windows...$(RESET)"
@mkdir -p $(DIST_DIR)
@bun build --compile --target=bun-windows-x64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-windows-x64.exe
@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-windows-x64.exe$(RESET)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To avoid repeating mkdir -p $(DIST_DIR) in each build target (build, build-linux, build-macos, build-windows), you can use a prerequisite target. This makes the Makefile cleaner and easier to maintain.

By creating a target for $(DIST_DIR), you can ensure the directory is created once before any build commands that need it are run.

.PHONY: build build-linux build-macos build-windows build-all clean-dist

$(DIST_DIR):
	@mkdir -p $(DIST_DIR)

build: $(DIST_DIR) ## Build standalone executable for current platform
	@echo "$(CYAN)🔨 Building standalone executable...$(RESET)"
	@bun build --compile bin/pglite-server.js --outfile $(DIST_DIR)/pgserve
	@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve$(RESET)"

build-linux: $(DIST_DIR) ## Build for Linux (x64 + arm64)
	@echo "$(CYAN)🐧 Building for Linux...$(RESET)"
	@bun build --compile --target=bun-linux-x64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-linux-x64
	@bun build --compile --target=bun-linux-arm64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-linux-arm64
	@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-linux-x64$(RESET)"
	@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-linux-arm64$(RESET)"

build-macos: $(DIST_DIR) ## Build for macOS (x64 + arm64)
	@echo "$(CYAN)🍎 Building for macOS...$(RESET)"
	@bun build --compile --target=bun-darwin-x64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-darwin-x64
	@bun build --compile --target=bun-darwin-arm64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-darwin-arm64
	@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-darwin-x64$(RESET)"
	@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-darwin-arm64$(RESET)"

build-windows: $(DIST_DIR) ## Build for Windows (x64)
	@echo "$(CYAN)🪟 Building for Windows...$(RESET)"
	@bun build --compile --target=bun-windows-x64 bin/pglite-server.js --outfile $(DIST_DIR)/pgserve-windows-x64.exe
	@echo "$(GREEN)✅ Built: $(DIST_DIR)/pgserve-windows-x64.exe$(RESET)"

Comment thread bin/pglite-server.js
Comment on lines +215 to +217
const storageType = options.dataDir
? options.dataDir
: (options.useRam ? '/dev/shm (RAM)' : '(temp directory)');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This storageType logic is duplicated on line 255. To keep the code DRY (Don't Repeat Yourself), you could define storageType once at a higher scope within the main function, for example, after memoryMode is defined on line 187.

Comment thread scripts/release.cjs Outdated
}

// Stage and commit
exec('git add -A');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using git add -A is a bit broad and could potentially stage unrelated files if any are present in the working directory during the release process. To make the script more robust and explicit, it's better to stage only the file that is expected to change, which is package.json.

  exec('git add package.json');

- Makefile: use prerequisite target for dist directory
- release.cjs: use explicit git add package.json instead of -A
@namastex888 namastex888 merged commit dacdfc9 into main Dec 6, 2025
0 of 5 checks passed
@namastex888 namastex888 deleted the feat/github-native-release-notes branch December 6, 2025 20:08
namastex888 added a commit that referenced this pull request May 8, 2026
…2.4 dream-readiness

V2.4 cohort framing:
- Status row: peer wish (one of three) for v2.4; separate branch + PR + /dream slot.
- v2.4 cohort field cross-linking sibling wishes (pgserve-singleton-no-proxy,
  canonical-pgserve-pm2-supervision).
- Date row notes 2026-05-08 refinement adding G19/G20 + cohort framing.
- Branch row notes active WIP branch (wish/autopg-cutover-transport-absorb)
  vs canonical wish branch (wish/autopg-distribution-cutover).

Group renumbering for lint compliance:
- Decimal numbers (Group 11.5, Group 11.6) rejected by genie wish lint.
- Renumbered: 11.5 → 19 (autopg serve), 11.6 → 20 (autopg service install).
- Existing G1-G18 commit history preserved (WIP commits #1-#11 remain valid).
- Strategy table annotated: "ships between G11 and G12; numbered 19 to preserve
  audit trail; depends-on graph drives execution order, not group numbers".
- depends-on lines on G12 + G13 updated: 11.5 → 19.

Cross-wish dependencies block expanded:
- Added paired-with section listing v2.4 cohort siblings.
- Added blocks entry for pgserve/autopg-service-install-system (parked
  next-version wish that extends G20's --user mode to --system mode).

genie wish lint: clean (no violations).

Felipe directives baked in (2026-05-08):
  1) Separate /dream slot per cohort wish.
  2) Separate branches/wishes/PRs.
  3) Tier B systemd-user only in v2.4; --system mode parked.
  4) doctor reports passively + service install MUST migrate (already in G20).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
namastex888 added a commit that referenced this pull request May 9, 2026
…installer

Felipe directive: don't deprecate, replace. Single install.sh.

The earlier shape (3 files: install.sh shim + install-autopg.sh +
install-pgserve-legacy.sh) was the wrong tradeoff. Replacing
in-place is cleaner — operators with bookmarked
`curl … main/install.sh | bash` invocations get the new behavior
directly, no migration step. The npm + pm2 install path is preserved
via the existing `pgserve install` CLI verb (operators who want it
do `npm install -g pgserve && pgserve install`).

Changes:
  - install-autopg.sh: deleted (its body became install.sh).
  - install-pgserve-legacy.sh: deleted (no legacy file kept).
  - install.sh: replaced with the GitHub Releases + gh-attestation
    body. 74 lines (≤80 spec ✓), shellcheck clean,
    `bash install.sh --dry-run` resolves the latest version via the
    GitHub releases API and prints the fetch URL + verify command
    without executing.
  - README.md: install section references install.sh (no autopg
    name, no legacy note).

Wish-side note: this overrides Decision #1 in the merged
autopg-distribution-cutover-finalize wish, which prescribed the
3-file split. Decision needs an update — separate follow-up commit
to the wish file.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
namastex888 added a commit that referenced this pull request May 9, 2026
…tation

D5 of pgserve create-app + manifest LOCK 1
(autopg-distribution-cutover-finalize wish G3).

Round-trip integration smoke that exercises the lock-vs-live trust
differential — the WHOLE point of the manifest LOCK 1 design.

Pipeline:
  1) Start ephemeral postgres on a high port (mirrors
     gc-provision.test.sh setup).
  2) `pgserve create-app demo --port $PORT` — registers slug; freezes
     live TRUSTED_IDENTITIES into autopg_meta.locked_roots.
  3) Direct UPDATE replaces the freshly frozen list with a SYNTHETIC
     single-entry locked_roots ({"id":"frozen-test", regex
     "^FROZEN-LOCK$"}). This is the test's stand-in for "operator
     rotated live; the slug's lock is now divergent". When verify
     --slug demo loads locked_roots, it gets THIS list.
  4) Stub cosign on PATH succeeds ONLY when --certificate-identity-regexp
     is exactly `^FROZEN-LOCK$` AND the binary's first bytes are
     `FROZEN-LOCK`. Anything else: exit non-zero.
  5) Three verify scenarios:
        a) FROZEN-LOCK binary + --slug demo  → exit 0 (lock matched)
        b) LIVE-IDENTITY binary + --slug demo → exit ≥2 (lock rejected)
        c) any binary + --slug nonexistent_slug → exit 3 (loader rejected
           BEFORE cosign — invocation error)
  6) Idempotent re-run preserves locked_roots — the synthetic
     'frozen-test' id stays after a second create-app demo invocation,
     proving BRIEF v5 A6 lock preservation is live.

Together those steps cover acceptance criteria #1, #3, #4, #5 from
WISH L142-L147 (idempotent re-run, verify rejection, verify success
against frozen lock, upgrade-after-trust-rotation).

Skips gracefully on hosts without initdb/pg_ctl/psql on PATH (mirrors
gc-provision.test.sh's contract). Wired into .github/workflows/ci.yml
as a new continue-on-error job — non-blocking until the GHA postgres
cache warms, identical to gc-provision job's policy.

Local skip path verified on this dev host (no initdb installed):

  $ bash tests/integration/verify-slug-rotation.test.sh
      • initdb not on PATH — skipping (suite needs a postgres install)
namastex888 added a commit that referenced this pull request May 10, 2026
…d + tag-creation gap + stale comment

Addresses 4 of 5 bot review comments. All three HIGH-severity findings
would have broken the workflow at runtime; the MEDIUM defensive nit (semver
validation on workflow_run.head_branch) is deferred to PR-A3 since the
current build-tarballs.yml tag-only producer trigger makes branch refs
impossible on the workflow_run path today.

codex P1 #1 — Add `actions: read` to permissions block
  - release-publish.yml: cross-workflow `actions/download-artifact@v4` with
    `run-id` + `github-token` requires `actions: read`. When ANY permissions
    are listed explicitly, unlisted scopes are denied. The pre-fix block had
    contents/id-token/attestations but not actions, so the download would
    have failed at runtime before the release upload step. Bot caught this
    cleanly; trivial fix with explanatory comment.

coderabbit major — Manual dispatch path can't download signed bundle
  - release-publish.yml: workflow_dispatch fallback `run-id: github.run_id`
    resolves to the CURRENT release-publish run, not the upstream sign-attest
    run where the bundle actually exists. Bot's analysis is correct.
  - Fix per bot's suggested diff: add required `sign_run_id` input to
    workflow_dispatch, and switch `run-id:` expression to
    `${{ github.event_name == 'workflow_run' && github.event.workflow_run.id
       || inputs.sign_run_id }}`. Manual operators get a clear required-input
    with discovery instructions in the description.

codex P1 #2 — Push-to-main releases lose tag-creation path
  - release.yml: the dropped `release` job's `gh release create` was the
    ONLY tag-creation path on the push event (workflow_dispatch path is
    fine — bump job creates and pushes the tag). Push-to-main runs of
    release.yml will now npm-publish but produce no tag → no build-tarballs
    → no sign-attest → no GitHub Release.
  - Operational reality: all recent v2.x releases (v2.6.0, v2.6.1, etc.)
    were cut via workflow_dispatch per Felipe's release practice. The
    push-to-main release path was de-facto deprecated already.
  - Fix: document the known limitation prominently in the build job
    comments + the release-job-removed comment. Operators routing through
    workflow_dispatch are unaffected; push-path operators get a clear
    upgrade-path pointer (use workflow_dispatch).
  - A future PR-A3 D7 can re-add tag creation in the prepare/bump job if
    push-path releases need to be reinstated.

coderabbit minor — release.yml:261 stale comment about release-publish trigger
  - Comment still referenced `on: push: tags: ['v*']` which is what
    release-publish.yml USED to have (pre-PR-A2). After this PR-A2 it
    triggers on `workflow_run` from sign-attest. Same-PR text drift;
    updated to describe the new chain accurately.

NOT fixed (deferred):
  coderabbit minor — Validate workflow_run.head_branch as semver before use
    - Defensive only. build-tarballs.yml currently has `push: tags: ['v*',
      'autopg-v*']` so the workflow_run chain ONLY fires from tag pushes;
      head_branch is always a tag name in practice. Worth adding as a
      defense-in-depth guard for future producer changes (e.g. if
      build-tarballs ever grows a branch-push trigger), but doesn't
      cause incorrect behavior today. Defer to PR-A3.

Tests: 100 cosign tests pass, zero regressions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
namastex888 added a commit that referenced this pull request May 18, 2026
…serve → automagik-dev/autopg) (#129)

Repo transferred namastexlabs/pgserve → automagik-dev/autopg + renamed.
Makes the codebase consistent with the new identity and repairs the
fresh-host bootstrap, broken independent of the transfer.

Org rewrite (10 code files + ~14 docs):
- src/cosign/trust-list.js single-flip to automagik-dev/autopg (v3 binary
  verifies v3+ releases; per POST-TRANSFER-RUNBOOK)
- scripts/, .github/workflows/release-publish.yml, package.json,
  src/security, src/update, tests/cosign fixtures
- bin/autopg-wrapper.cjs — MISSED by runbook's 9-file inventory; caught
  by the zero-stray-ref gate (10th non-doc file)

install.sh — full rewrite (sed-insufficient; 5 bugs, only #1 in runbook):
  1. REPO → automagik-dev/autopg
  2. tarball name pgserve-*-linux-x64 → autopg-*-linux-x64-{glibc,musl}
     with libc detection (matched real release assets)
  3. latest-resolution: unauth curl|sed empty → gh api primary, curl fb
  4. extracted layout autopg/autopg (not bin/pgserve) + ~/.local/bin symlink
  5. gh attestation hard-dep (gh<2.49) → cosign verify-blob fallback with
     DUAL-org identity regexp (asymmetric-cohort: bootstrap consumer
     accepts both orgs; latest v2.6.10 signed pre-transfer). Proven:
     cosign verify-blob "Verified OK" vs real old-org-signed v2.6.10.

Verification: lint clean; 692 pass / 3 skip / 0 fail; trust-list 11/11.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant