Skip to content

feat(infra): add release versioning system - #337

Merged
jlunder00 merged 57 commits into
mainfrom
feature/release-versioning
May 10, 2026
Merged

feat(infra): add release versioning system#337
jlunder00 merged 57 commits into
mainfrom
feature/release-versioning

Conversation

@jlunder00

Copy link
Copy Markdown
Owner

Summary

  • Dockerfile: adds ARG TETHER_VERSION=dev + ENV TETHER_VERSION=${TETHER_VERSION} so every service in the image can read the deployed tag at runtime
  • fly-deploy.yml: computes v{YYYY-MM-DD}-{sha7} (prod) / v{YYYY-MM-DD}-{sha7}-dev (dev) per deploy, passes it as --build-arg TETHER_VERSION, pushes a matching git tag after successful deploy; bumps permissions: contents to write
  • api/main.py: adds unauthenticated GET /api/version{"version": "v2026-05-09-abc1234"} for easy runtime verification

Note: Pi build workflows (pi-build.yml, pi-build-dev.yml) are under .github/workflows/archive/ and not active — GitHub Actions ignores subdirectory files. Skipped for now; can be updated if reactivated. See companion PR in tether-premium for __version__ wiring.

How to verify after deploy

curl https://tether-prod.fly.dev/api/version
# → {"version":"v2026-05-09-abc1234"}

python -c "import tether_premium; print(tether_premium.__version__)"
# → v2026-05-09-abc1234  (inside container)
# → dev  (local dev without env var)

Test plan

  • Push to main triggers fly-deploy prod job
  • flyctl build completes with TETHER_VERSION baked in
  • GET /api/version returns expected tag string
  • Git tag v{date}-{sha7} appears in repo after deploy
  • import tether_premium; tether_premium.__version__ returns tag (not "dev") in running container

jlunder00 added 30 commits May 6, 2026 14:07
Remove savedDates/fetchSavedDates, deprecated comment blocks,
autoMode(), "This Week" coming-soon box, stale router-view tags in
PlanView/KanbanView/CalendarView/DashboardView, Change Password and
OAuth Connections coming-soon sections from Settings, and smoke.test.ts.
fix: remove stale SQLite-era Beacon block in message_handler
chore: retire orphaned prompts + fix stale constraint in prompt_sections
chore: backend quick-win dead-code cleanup
perf: eliminate N+1 queries in plan range and meetings
chore: remove confirmed dead code (Phase A)
Add plan_date? to Task interface, remove FollowupConfig re-export,
replace all (task as any).plan_date / anchor_id casts in TaskCard.vue,
type standaloneTask as Task|null, fix tautological ternary in
TaskDetailPanel template, narrow v-else to v-else-if="task" for
proper null safety.
Create src/lib/dateUtils.ts with localDateString/localToday/offsetDate.
Remove duplicate implementations from plan.ts, DashboardView, PlanView,
CalendarView, PlanWeekView, MiniCalendar. Export VOICE from useTheme
and remove the duplicate mapping in main.ts. Extract genId() helper in
useSlideOver. Rename internal fetch()→load() in useLinks, useDependencies,
useSubtasks, useTaskContexts to stop shadowing the global fetch API.
Add scheduleTask, moveToBacklog, createPlanTask to plan store.
Add patchEvent to events store. Extend backlog createTask signature.
Migrate TaskDetailPanel (scheduleTask, moveToBacklog, deleteTask,
linkMilestoneFromSearch), AnchorBlock (onRemove, onAddNewTask),
DashboardView (onAddTaskToNow), KanbanView (onAddTask), CalendarView
(event-edit recurrence path) to use store actions instead of api().
Update events.ts, events store, AnchorBlock, and App.vue comments to
reflect that the backend contract has shipped. Remove references to
fixture data and unimplemented stream tags (motif-db-api, is_paid).
fix: type fixes — plan_date on Task, remove any casts (Phase B)
jlunder00 added 25 commits May 6, 2026 23:44
refactor: extract dateUtils, VOICE export, fetch→load rename (Phase C)
refactor: raw SQL extraction, MoveTaskBody, Optional modernization, _validate_motif dedup
refactor: migrate components off direct api() calls (Phase D)
chore: remove stale comments (Phase E)
Without !reset, Docker Compose v2 concatenates sequences from the
base file. ports: [] inherited 5432:5432 from base, colliding with
production postgres on the same Pi host. volumes: [] merged pgdata
and pgdata-dev onto the same container path. Both caused the dev
postgres container to fail to start, making the hostname
unresolvable to the API container.
fix: reset postgres ports+volumes in dev compose overlay
The per-service CI deploys use --no-deps, which bypasses
depends_on. Postgres was never started by any workflow.
Adding it to the force-deploy-all dev step ensures it gets
started (and kept up via restart: unless-stopped) on full
redeploys.
fix: start postgres in dev force-deploy workflow
alembic.ini was not copied into the Docker image, making
`docker compose run --rm api alembic upgrade head` silently
fail (alembic can't find its config). This also meant fresh
dev postgres containers couldn't be initialized.

Adds COPY alembic.ini to Dockerfile and a pi-deploy-db-dev.yml
workflow that runs migrations against dev postgres on push to
dev or manual dispatch.
fix: add alembic.ini to image and dev migration workflow
Alembic's env.py uses SQLAlchemy's synchronous engine_from_config which
requires a sync driver. The dev image only had asyncpg. Adding
psycopg2-binary>=2.9 gives alembic a sync driver so migrations run
without ModuleNotFoundError.
Mirrors the defensive upper-bound pattern already used for cryptography
and apscheduler — guards against a future psycopg2-binary 3.x wheel
that could stall on the Pi's CDN/MTU path.
Add psycopg2-binary for alembic dev migrations
configure.py reads TETHER_COMPOSE_DIR to decide where to write the
compose .env. Without it set, configure-db writes POSTGRES_PASSWORD
and TETHER_APP_PASSWORD to ~/tether/.env (production) instead of
~/tether-dev/.env. The dev API then falls back to the tether_app_dev
default, causing auth failures when the postgres role was created with
a different password.

Two fixes:
1. Set TETHER_COMPOSE_DIR=/home/toast/tether-dev on the build job so
   configure-db writes to the correct file.
2. Add an explicit ALTER ROLE step targeting the dev postgres via the
   correct compose project flags. This handles the case where
   tether_app already exists with a stale password. make configure-db
   also attempts this but omits -p tether-dev so it targets the wrong
   container.
Fix dev CI: write DB passwords to dev .env, sync tether_app role
In compose v5, !reset tags reset a field to its zero value (empty list
for ports) and ignore the value that follows. !override replaces with
the tagged value, which is the correct tag for substituting the prod
port binding with a different dev port. Postgres keeps !reset [] since
it intentionally wants no host ports.
Fix dev overlay ports: !override instead of !reset
# Conflicts:
#	bot/message_handler.py
… endpoint

- Dockerfile: inject TETHER_VERSION=dev ARG+ENV so all services can
  read the deployed tag at runtime
- fly-deploy.yml: auto-bump patch from latest vX.Y.Z git tag on each
  prod deploy; push new tag after success. Dev builds use same base
  version with -dev.{sha7} suffix, no tag pushed. fetch-depth: 0
  required so git tag -l sees all existing tags.
- api/main.py: add unauthenticated GET /api/version endpoint
@jlunder00
jlunder00 force-pushed the feature/release-versioning branch from 43ff017 to 7c543c3 Compare May 10, 2026 05:44
- pyproject.toml: reset version to 0.0.0 (start of proper semver)
- Dockerfile: TETHER_VERSION ARG+ENV baked into image at build time
- fly-deploy.yml: read TETHER_VERSION from pyproject.toml at deploy time;
  dev builds append -dev.{sha7} suffix
- api/main.py: GET /api/version returns tether + premium versions
- scripts/release.sh: CLI release script (--patch/--minor/--major/--alpha)
- .github/workflows/release.yml: on tag push, create GitHub Release
@jlunder00 jlunder00 changed the title feat(infra): add release versioning (TETHER_VERSION build arg + /api/version) feat(infra): add release versioning system May 10, 2026
@jlunder00
jlunder00 merged commit ee895d2 into main May 10, 2026
7 checks passed
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