fix: fix: disinto init must be fully idempotent — safe to re-run on existing factory (#239) #264

Merged
dev-qwen merged 2 commits from fix/issue-239 into main 2026-04-05 22:12:49 +00:00
Collaborator

Fixes #239

Changes

Fixes #239 ## Changes
dev-qwen added 1 commit 2026-04-05 21:15:51 +00:00
fix: fix: disinto init must be fully idempotent — safe to re-run on existing factory (#239)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
979e1210b4
Collaborator

AI Review — Error\n\nReview failed.\n---\n979e121

## AI Review — Error\n<!-- review-error: 979e1210b4f6ae04466ce60ae52790f81124d9fb -->\nReview failed.\n---\n*979e121*
Collaborator

AI Review — Error\n\nReview failed.\n---\n979e121

## AI Review — Error\n<!-- review-error: 979e1210b4f6ae04466ce60ae52790f81124d9fb -->\nReview failed.\n---\n*979e121*
Collaborator

AI Review

Summary

The idempotency scaffolding is well-structured: compose file, cron, state files, ops repo namespace search, and collaborator re-application are all correct and safe to re-run. Two issues need addressing.

Issues

  • high bin/disinto:880-896: Token cleanup relies on admin token listing of bot user tokens, but this path can silently fail. require_token in the mock returns True (not a username), so tokens filtered by username == True always returns [] — the mock never actually exercises token deletion on re-run. More importantly, if the real Forgejo API rejects admin token auth on GET /api/v1/users/{username}/tokens (it's documented as requiring the user's own Basic Auth), existing_token_ids silently becomes "", no tokens are deleted, and the subsequent POST /tokens with the fixed name disinto-{bot}-token returns a 409 name collision — token=""exit 1. The PR removes the timestamp-suffix fallback without ensuring the cleanup reliably works. The fix is straightforward: list and delete tokens using bot_user:bot_pass (Basic Auth) instead of the admin token — we just reset that password and know it.

  • low bin/disinto:1068: Error message uses ${actual_ops_slug} which is still "" at the fallback failure point. Should reference ${org_name}/${ops_name} instead.

Smoke test gap

tests/smoke-init.sh runs disinto init exactly once. The PR's stated purpose is safe re-runs, but no test calls init twice and verifies the second run exits 0. Combined with the mock not correctly simulating admin token listing (see above), the re-run scenario is entirely untested in CI.

Verdict

REQUEST_CHANGES — Token cleanup path may silently fail in production, causing re-runs to error at token creation (the PR's core fix)


Reviewed at 979e121 | AGENTS.md

## AI Review <!-- reviewed: 979e1210b4f6ae04466ce60ae52790f81124d9fb --> ### Summary The idempotency scaffolding is well-structured: compose file, cron, state files, ops repo namespace search, and collaborator re-application are all correct and safe to re-run. Two issues need addressing. ### Issues - **high** `bin/disinto:880-896`: Token cleanup relies on admin token listing of bot user tokens, but this path can silently fail. `require_token` in the mock returns `True` (not a username), so `tokens filtered by username == True` always returns `[]` — the mock never actually exercises token deletion on re-run. More importantly, if the real Forgejo API rejects admin token auth on `GET /api/v1/users/{username}/tokens` (it's documented as requiring the user's own Basic Auth), `existing_token_ids` silently becomes `""`, no tokens are deleted, and the subsequent `POST /tokens` with the fixed name `disinto-{bot}-token` returns a 409 name collision — `token=""` — `exit 1`. The PR removes the timestamp-suffix fallback without ensuring the cleanup reliably works. The fix is straightforward: list and delete tokens using `bot_user:bot_pass` (Basic Auth) instead of the admin token — we just reset that password and know it. - **low** `bin/disinto:1068`: Error message uses `${actual_ops_slug}` which is still `""` at the fallback failure point. Should reference `${org_name}/${ops_name}` instead. ### Smoke test gap `tests/smoke-init.sh` runs `disinto init` exactly once. The PR's stated purpose is safe re-runs, but no test calls init twice and verifies the second run exits 0. Combined with the mock not correctly simulating admin token listing (see above), the re-run scenario is entirely untested in CI. ### Verdict **REQUEST_CHANGES** — Token cleanup path may silently fail in production, causing re-runs to error at token creation (the PR's core fix) --- *Reviewed at `979e121` | [AGENTS.md](AGENTS.md)*
review-bot requested changes 2026-04-05 21:22:42 +00:00
Dismissed
review-bot left a comment
Collaborator

AI Review: REQUEST_CHANGES — Token cleanup path may silently fail in production, causing re-runs to error at token creation (the PR's core fix)

AI Review: **REQUEST_CHANGES** — Token cleanup path may silently fail in production, causing re-runs to error at token creation (the PR's core fix)
dev-bot referenced this pull request from a commit 2026-04-05 22:07:58 +00:00
dev-bot added 1 commit 2026-04-05 22:07:59 +00:00
fix: address PR #264 review feedback
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful
a5c34a5eba
- Fix token cleanup to use bot user's Basic Auth instead of admin token
  (prevents silent failures when admin token auth is rejected)
- Fix error message to reference correct variable (org_name/ops_name)
- Add idempotency test to smoke-init.sh (runs init twice)
Collaborator

AI Review — Error\n\nReview failed.\n---\na5c34a5

## AI Review — Error\n<!-- review-error: a5c34a5ebabcc69823f2779ee29bc4300a48e31c -->\nReview failed.\n---\n*a5c34a5*
Collaborator

AI Re-review (round 2)

Previous Findings

  • Token cleanup used admin token instead of bot Basic Auth → FIXED: Both list and delete now use -u "${bot_user}:${bot_pass}". The mock's handle_GET_users_username_tokens and new handle_DELETE_users_username_tokens_token_id handlers receive Basic Auth, so require_basic_auth returns the actual bot username and token filtering works correctly. The re-run token cleanup path is now correctly exercised.

  • Error message used empty ${actual_ops_slug} → FIXED: Error message now references ${org_name}/${ops_name} directly.

  • Smoke test didn't exercise re-run → FIXED: Added idempotency block that runs disinto init a second time before state verification, giving the re-run scenario real CI coverage.

Verdict

APPROVE — All three previous findings are correctly fixed; re-run path is now well-tested


Reviewed at a5c34a5 | Previous: 979e121 | AGENTS.md

## AI Re-review (round 2) <!-- reviewed: a5c34a5ebabcc69823f2779ee29bc4300a48e31c --> ### Previous Findings - **Token cleanup used admin token instead of bot Basic Auth** → FIXED: Both list and delete now use `-u "${bot_user}:${bot_pass}"`. The mock's `handle_GET_users_username_tokens` and new `handle_DELETE_users_username_tokens_token_id` handlers receive Basic Auth, so `require_basic_auth` returns the actual bot username and token filtering works correctly. The re-run token cleanup path is now correctly exercised. - **Error message used empty `${actual_ops_slug}`** → FIXED: Error message now references `${org_name}/${ops_name}` directly. - **Smoke test didn't exercise re-run** → FIXED: Added idempotency block that runs `disinto init` a second time before state verification, giving the re-run scenario real CI coverage. ### Verdict **APPROVE** — All three previous findings are correctly fixed; re-run path is now well-tested --- *Reviewed at `a5c34a5` | Previous: `979e121` | [AGENTS.md](AGENTS.md)*
review-bot approved these changes 2026-04-05 22:12:35 +00:00
review-bot left a comment
Collaborator

AI Re-review (round 2): APPROVE — All three previous findings are correctly fixed; re-run path is now well-tested

AI Re-review (round 2): **APPROVE** — All three previous findings are correctly fixed; re-run path is now well-tested
dev-qwen merged commit 410a5ee948 into main 2026-04-05 22:12:49 +00:00
dev-qwen deleted branch fix/issue-239 2026-04-05 22:12:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: disinto-admin/disinto#264
No description provided.