DEVX-182: feat(molecule): release lease emission (ships DEVX-181) #356

Merged
kireto merged 1 commits from DEVX-182-ship-lease-release into master 2026-09-30 16:15:43 +00:00
3 changed files with 60 additions and 4 deletions
+49
View File
@@ -0,0 +1,49 @@
# DEVX-182: feat(molecule): release lease emission (ships DEVX-181)
- Task: DEVX-182
- Status: draft
## Problem
DEVX-181 landed on master but was never released: the squash subject
came out `DEVX-181: ci: retrigger validation` because the branch's last
commit was an empty `ci:` retrigger. git-cliff found no bump-worthy
commit, so `v0.55.5` is still latest and the S08 lease producer is
unshipped. A `feat:` merge is needed to cut the release — and while
shipping, the emission log line is upgraded from a bare count to the
actual lease owner and UTC expiry, which is what an operator needs when
debugging a cleanup race.
## Approach
REQ-1: `start_docker.main()` computes `lease_env()` once and logs
`owner=` + ISO-8601 `until=` alongside the export confirmation. The
single call also removes a latent second-boundary inconsistency where
`emit_github_env` and the count message each re-derived `now`.
REQ-2: Merge squash commit carries `feat(molecule):` so git-cliff cuts
the next minor release containing DEVX-181's emitter and this change.
## Test Plan
- Update `test_emits_lease_on_success` + `test_prints_and_exports` for
the new log format; keep 100 % coverage.
- `make pre-push` — full devx suite green.
- Post-merge: verify a `v*` tag > v0.55.5 exists and
`pip index versions devx` (Gitea PyPI) lists it.
## Deploy Plan
- Auto-merge; post-merge release job tags + publishes.
- Infra (OBL-INFRA-658) and GRM (GRM-174) consume the new pin.
## Rollback Plan
- Revert merge; the unreleased module remains dormant regardless.
## Acceptance Criteria
- [x] REQ-1: emission log includes owner and ISO-8601 expiry; lease env
computed once — covered by updated unit tests.
- [x] REQ-2: merge commit uses `feat(molecule):` so the release job
cuts a version bump.
+8 -3
View File
@@ -31,11 +31,12 @@ import subprocess # nosec B404
import sys
import tempfile
import time
from datetime import UTC, datetime
import click
from devx.i18n import _
from devx.molecule.lease import emit_github_env, lease_env
from devx.molecule.lease import LEASE_UNTIL_ENV, OWNER_ENV, emit_github_env, lease_env
DEFAULT_TIMEOUT = 30
DOCKER_SOCK = "/var/run/docker.sock"
@@ -388,8 +389,12 @@ def main(timeout: int) -> None:
# Implements: REQ-2 (DEVX-181) — emit the S08 producer lease env so
# molecule-created objects carry org.oblachno.lease-until/owner
# labels that runner-cleanup.sh honors.
if emit_github_env(lease_env()):
click.echo(f"Exported {len(lease_env())} lease vars to GITHUB_ENV")
# Implements: REQ-1 (DEVX-182) — one lease_env() call; log the
# owner and UTC expiry an operator needs for cleanup debugging.
env = lease_env()
if emit_github_env(env):
until = datetime.fromtimestamp(int(env[LEASE_UNTIL_ENV]), tz=UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
click.echo(f"Exported lease vars to GITHUB_ENV (owner={env[OWNER_ENV]}, until={until})")
sys.exit(0)
sys.exit(1)
+3 -1
View File
@@ -118,4 +118,6 @@ class TestStartDockerIntegration:
):
result = runner.invoke(start_docker_main, ["--timeout", "1"])
assert result.exit_code == 0
assert "Exported 2 lease vars" in result.output
assert "Exported lease vars to GITHUB_ENV" in result.output
assert "owner=run-7-job" in result.output
assert "until=" in result.output