Skip to content
Closed
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
59 changes: 58 additions & 1 deletion .github/workflows/release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,65 @@ jobs:
release-please:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Compute release-as (align to premain RC)
id: version
run: |
set -euo pipefail

release_as="$(
python3 - <<'PY'
import json
from pathlib import Path


def parse_base(v: str) -> tuple[int, int, int]:
v = v.strip()
if v.startswith("v"):
v = v[1:]
v = v.split("+", 1)[0]
base = v.split("-", 1)[0]
parts = base.split(".")
if len(parts) != 3:
raise ValueError(f"invalid semver base: {v}")
return (int(parts[0]), int(parts[1]), int(parts[2]))


stable = json.loads(Path(".release-please-manifest.json").read_text(encoding="utf-8")).get(".", "")
premain = json.loads(Path(".release-please-manifest.premain.json").read_text(encoding="utf-8")).get(".", "")

if not stable or not premain:
raise SystemExit("")

premain_base = premain.split("+", 1)[0].split("-", 1)[0]

# If premain is already on a higher major/minor/patch line (e.g., 1.3.0-rc.1),
# force the stable Release PR to promote that baseline (e.g., 1.3.0).
if parse_base(premain_base) > parse_base(stable):
print(premain_base)
PY
)"

echo "release_as=${release_as}" >> "${GITHUB_OUTPUT}"
echo "release-as: ${release_as:-<none>}"

- name: Release Please (PR only) (aligned)
if: steps.version.outputs.release_as != ''
id: release_aligned
uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
target-branch: main
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
release-as: ${{ steps.version.outputs.release_as }}
skip-github-release: true

- name: Release Please (PR only)
id: release
if: steps.version.outputs.release_as == ''
id: release_default
uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@ py/coverage-*.json
docs/development/notes/*
!docs/development/notes/template-notes.md
/notes/
.pai
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.2.0"
".": "1.2.1"
}
28 changes: 28 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,31 @@ Single test example: `go test -v -run TestName ./pkg/query`
- Branch naming commonly uses `feature/...`, `fix/...`, `chore/...`.
- Prefer Conventional Commit-style subjects (`feat:`, `fix:`, `docs:`, `test:`) and keep the first line ≤72 chars.
- PRs: describe intent and scope, link issues, list commands run, add/adjust tests, and update `CHANGELOG.md` + relevant docs when public APIs change (see `CONTRIBUTING.md`).

## Release / Versioning (immutable GitHub releases)

TableTheory publishes **immutable** GitHub releases (no retagging / no overwriting release assets). Any change that must be
published requires:

- **staging → premain**: merge a PR from `staging` into `premain` to start the prerelease pipeline (RCs)
- **premain → main**: merge a PR from `premain` into `main` to start the stable release pipeline
- **post-release sync**: back-merge `main` into `staging` so the next cycle starts from the latest stable baseline

Branch roles:

- **`staging`**: integration branch (all work lands here first)
- **`premain`**: prerelease branch (RCs like `vX.Y.Z-rc.N`)
- **`main`**: stable release branch (releases like `vX.Y.Z`)

Multi-language versioning:

- **Stable manifest**: `.release-please-manifest.json`
- **Prerelease manifest**: `.release-please-manifest.premain.json`
- **TypeScript**: `ts/package.json`, `ts/package-lock.json`
- **Python**: `py/src/theorydb_py/version.json`

Release automation must keep these files coherent so the stable line never lags the prerelease line on promotion.
The rubric enforces this via:

- `bash scripts/verify-branch-release-supply-chain.sh`
- `bash scripts/verify-branch-version-sync.sh`
Loading
Loading