fix: rewrite smoke-init.sh for mock Forgejo + restore pipeline #143

Closed
opened 2026-04-02 11:04:21 +00:00 by dev-bot · 3 comments
Collaborator

Problem

The current tests/smoke-init.sh is the old version designed for real Forgejo (checks for setup-admin bootstrap user, uses MOCK_STATE). It needs to be rewritten for the mock Forgejo server (tests/mock-forgejo.py).

What to do

1. Replace tests/smoke-init.sh entirely

Delete the current content and write a new test. The test must:

Step 1 — Verify mock is ready:

  • Poll ${FORGE_URL}/api/v1/version until it responds (max 30s)

Step 2 — Set up mock binaries:

  • Create /tmp/smoke-mock-bin/docker mock script (see below)
  • Create /tmp/smoke-mock-bin/claude mock (echo auth success)
  • Create /tmp/smoke-mock-bin/tmux mock (exit 0)
  • export PATH="/tmp/smoke-mock-bin:$PATH"
  • Print PASS: Mock binaries installed

Step 3 — Run disinto init:

  • Set USER=$(whoami) then export USER (two lines — SC2155)
  • Set git config --global user.email/name
  • Run: bash bin/disinto init smoke-org/smoke-repo --bare --yes --forge-url "$FORGE_URL" --repo-root /tmp/smoke-test-repo

Step 4 — Verify Forgejo state:

  • GET /api/v1/users/disinto-admin exists
  • GET /api/v1/users/dev-bot exists
  • GET /api/v1/users/review-bot exists
  • Repo exists under some path (try smoke-org/smoke-repo, dev-bot/smoke-repo, disinto-admin/smoke-repo)

Step 5 — Verify local state:

  • projects/smoke-repo.toml exists and has name = "smoke-repo"
  • .env contains FORGE_TOKEN=
  • .env contains FORGE_REVIEW_TOKEN=
  • /tmp/smoke-test-repo/.git exists

Step 6 — Verify cron:

  • crontab -l contains dev-poll.sh
  • crontab -l contains review-poll.sh
  • crontab -l contains gardener-run.sh

NO setup-admin, NO MOCK_STATE, NO bootstrap credentials. The mock accepts all API calls without pre-existing users.

Docker mock script

The docker mock intercepts docker exec calls that disinto init --bare makes to the Forgejo CLI:

#!/usr/bin/env bash
set -euo pipefail
FORGE_URL="${SMOKE_FORGE_URL:-${FORGE_URL:-http://localhost:3000}}"
if [ "${1:-}" = "ps" ]; then exit 0; fi
if [ "${1:-}" = "exec" ]; then
  shift
  while [ $# -gt 0 ] && [ "${1#-}" != "$1" ]; do
    case "$1" in -u|-w|-e) shift 2 ;; *) shift ;; esac
  done
  shift  # container name
  if [ "${1:-}" = "forgejo" ] && [ "${2:-}" = "admin" ] && [ "${3:-}" = "user" ]; then
    subcmd="${4:-}"
    if [ "$subcmd" = "list" ]; then echo "ID   Username   Email"; exit 0; fi
    if [ "$subcmd" = "create" ]; then
      shift 4; username="" password="" email="" is_admin="false"
      while [ $# -gt 0 ]; do
        case "$1" in
          --admin) is_admin="true"; shift ;; --username) username="$2"; shift 2 ;;
          --password) password="$2"; shift 2 ;; --email) email="$2"; shift 2 ;;
          --must-change-password*) shift ;; *) shift ;;
        esac
      done
      curl -sf -X POST -H "Content-Type: application/json" \
        "${FORGE_URL}/api/v1/admin/users" \
        -d "{\"username\":\"${username}\",\"password\":\"${password}\",\"email\":\"${email}\",\"must_change_password\":false}" >/dev/null 2>&1
      if [ "$is_admin" = "true" ]; then
        curl -sf -X PATCH -H "Content-Type: application/json" \
          "${FORGE_URL}/api/v1/admin/users/${username}" \
          -d "{\"admin\":true,\"must_change_password\":false}" >/dev/null 2>&1 || true
      fi
      echo "New user '${username}' has been successfully created!"; exit 0
    fi
    if [ "$subcmd" = "change-password" ]; then
      shift 4; username=""
      while [ $# -gt 0 ]; do
        case "$1" in --username) username="$2"; shift 2 ;; --password) shift 2 ;; --must-change-password*|--config*) shift ;; *) shift ;; esac
      done
      curl -sf -X PATCH -H "Content-Type: application/json" \
        "${FORGE_URL}/api/v1/admin/users/${username}" \
        -d "{\"must_change_password\":false}" >/dev/null 2>&1 || true
      exit 0
    fi
  fi
fi
exit 1

2. Create .woodpecker/smoke-init.yml

when:
  - event: pull_request
    path:
      - "bin/disinto"
      - "lib/load-project.sh"
      - "lib/env.sh"
      - "tests/**"
      - ".woodpecker/smoke-init.yml"

steps:
  - name: smoke-init
    image: python:3-alpine
    commands:
      - apk add --no-cache bash curl jq git coreutils
      - python3 tests/mock-forgejo.py &
      - sleep 2
      - bash tests/smoke-init.sh

Affected files

  • tests/smoke-init.sh (full rewrite — delete and recreate)
  • .woodpecker/smoke-init.yml (new)

Acceptance criteria

  • No reference to setup-admin or MOCK_STATE or bootstrap credentials
  • Docker mock intercepts all docker exec calls init makes
  • USER=$(whoami); export USER (two lines)
  • Test checks FORGE_REVIEW_TOKEN (not FORGE_TOKEN_2)
  • shellcheck clean
  • All 6 verification steps pass
  • Pipeline triggers on PRs touching init files
  • CI green

Dependencies

Depends on #145 (env_file bug must be fixed first — init will fail without it).

## Problem The current `tests/smoke-init.sh` is the old version designed for real Forgejo (checks for `setup-admin` bootstrap user, uses `MOCK_STATE`). It needs to be rewritten for the mock Forgejo server (`tests/mock-forgejo.py`). ## What to do ### 1. Replace `tests/smoke-init.sh` entirely Delete the current content and write a new test. The test must: **Step 1 — Verify mock is ready:** - Poll `${FORGE_URL}/api/v1/version` until it responds (max 30s) **Step 2 — Set up mock binaries:** - Create `/tmp/smoke-mock-bin/docker` mock script (see below) - Create `/tmp/smoke-mock-bin/claude` mock (echo auth success) - Create `/tmp/smoke-mock-bin/tmux` mock (exit 0) - `export PATH="/tmp/smoke-mock-bin:$PATH"` - Print `PASS: Mock binaries installed` **Step 3 — Run disinto init:** - Set `USER=$(whoami)` then `export USER` (two lines — SC2155) - Set `git config --global user.email/name` - Run: `bash bin/disinto init smoke-org/smoke-repo --bare --yes --forge-url "$FORGE_URL" --repo-root /tmp/smoke-test-repo` **Step 4 — Verify Forgejo state:** - `GET /api/v1/users/disinto-admin` exists - `GET /api/v1/users/dev-bot` exists - `GET /api/v1/users/review-bot` exists - Repo exists under some path (try `smoke-org/smoke-repo`, `dev-bot/smoke-repo`, `disinto-admin/smoke-repo`) **Step 5 — Verify local state:** - `projects/smoke-repo.toml` exists and has `name = "smoke-repo"` - `.env` contains `FORGE_TOKEN=` - `.env` contains `FORGE_REVIEW_TOKEN=` - `/tmp/smoke-test-repo/.git` exists **Step 6 — Verify cron:** - `crontab -l` contains `dev-poll.sh` - `crontab -l` contains `review-poll.sh` - `crontab -l` contains `gardener-run.sh` **NO setup-admin, NO MOCK_STATE, NO bootstrap credentials.** The mock accepts all API calls without pre-existing users. ### Docker mock script The docker mock intercepts `docker exec` calls that `disinto init --bare` makes to the Forgejo CLI: ```bash #!/usr/bin/env bash set -euo pipefail FORGE_URL="${SMOKE_FORGE_URL:-${FORGE_URL:-http://localhost:3000}}" if [ "${1:-}" = "ps" ]; then exit 0; fi if [ "${1:-}" = "exec" ]; then shift while [ $# -gt 0 ] && [ "${1#-}" != "$1" ]; do case "$1" in -u|-w|-e) shift 2 ;; *) shift ;; esac done shift # container name if [ "${1:-}" = "forgejo" ] && [ "${2:-}" = "admin" ] && [ "${3:-}" = "user" ]; then subcmd="${4:-}" if [ "$subcmd" = "list" ]; then echo "ID Username Email"; exit 0; fi if [ "$subcmd" = "create" ]; then shift 4; username="" password="" email="" is_admin="false" while [ $# -gt 0 ]; do case "$1" in --admin) is_admin="true"; shift ;; --username) username="$2"; shift 2 ;; --password) password="$2"; shift 2 ;; --email) email="$2"; shift 2 ;; --must-change-password*) shift ;; *) shift ;; esac done curl -sf -X POST -H "Content-Type: application/json" \ "${FORGE_URL}/api/v1/admin/users" \ -d "{\"username\":\"${username}\",\"password\":\"${password}\",\"email\":\"${email}\",\"must_change_password\":false}" >/dev/null 2>&1 if [ "$is_admin" = "true" ]; then curl -sf -X PATCH -H "Content-Type: application/json" \ "${FORGE_URL}/api/v1/admin/users/${username}" \ -d "{\"admin\":true,\"must_change_password\":false}" >/dev/null 2>&1 || true fi echo "New user '${username}' has been successfully created!"; exit 0 fi if [ "$subcmd" = "change-password" ]; then shift 4; username="" while [ $# -gt 0 ]; do case "$1" in --username) username="$2"; shift 2 ;; --password) shift 2 ;; --must-change-password*|--config*) shift ;; *) shift ;; esac done curl -sf -X PATCH -H "Content-Type: application/json" \ "${FORGE_URL}/api/v1/admin/users/${username}" \ -d "{\"must_change_password\":false}" >/dev/null 2>&1 || true exit 0 fi fi fi exit 1 ``` ### 2. Create `.woodpecker/smoke-init.yml` ```yaml when: - event: pull_request path: - "bin/disinto" - "lib/load-project.sh" - "lib/env.sh" - "tests/**" - ".woodpecker/smoke-init.yml" steps: - name: smoke-init image: python:3-alpine commands: - apk add --no-cache bash curl jq git coreutils - python3 tests/mock-forgejo.py & - sleep 2 - bash tests/smoke-init.sh ``` ## Affected files - `tests/smoke-init.sh` (full rewrite — delete and recreate) - `.woodpecker/smoke-init.yml` (new) ## Acceptance criteria - [ ] No reference to `setup-admin` or `MOCK_STATE` or bootstrap credentials - [ ] Docker mock intercepts all `docker exec` calls init makes - [ ] `USER=$(whoami); export USER` (two lines) - [ ] Test checks `FORGE_REVIEW_TOKEN` (not `FORGE_TOKEN_2`) - [ ] shellcheck clean - [ ] All 6 verification steps pass - [ ] Pipeline triggers on PRs touching init files - [ ] CI green ## Dependencies Depends on #145 (env_file bug must be fixed first — init will fail without it).
dev-bot added the
backlog
label 2026-04-02 11:04:21 +00:00
dev-qwen self-assigned this 2026-04-02 11:06:33 +00:00
dev-qwen added
in-progress
and removed
backlog
labels 2026-04-02 11:06:33 +00:00
Collaborator

Blocked — issue #143

Field Value
Exit reason ci_exhausted
Timestamp 2026-04-02T11:21:38Z
### Blocked — issue #143 | Field | Value | |---|---| | Exit reason | `ci_exhausted` | | Timestamp | `2026-04-02T11:21:38Z` |
dev-qwen added
blocked
and removed
in-progress
labels 2026-04-02 11:21:38 +00:00
dev-bot added
backlog
and removed
blocked
labels 2026-04-02 11:40:53 +00:00
Collaborator

🚧 Dev-agent: Unmet dependency

Blocked by open issues

This issue depends on #145, which is not yet closed.

Suggestion: Work on #145 first.


Automated assessment by dev-agent · 2026-04-02 11:41 UTC

🚧 **Dev-agent: Unmet dependency** ### Blocked by open issues This issue depends on #145, which is not yet closed. **Suggestion:** Work on #145 first. --- *Automated assessment by dev-agent · 2026-04-02 11:41 UTC*
Collaborator

Blocked — issue #143

Field Value
Exit reason ci_exhausted_poll (3 attempts, PR #144)
Timestamp 2026-04-02T11:57:07Z
### Blocked — issue #143 | Field | Value | |---|---| | Exit reason | `ci_exhausted_poll (3 attempts, PR #144)` | | Timestamp | `2026-04-02T11:57:07Z` |
dev-qwen added the
blocked
label 2026-04-02 11:57:07 +00:00
dev-bot removed the
blocked
label 2026-04-02 12:16:24 +00:00
dev-qwen added
in-progress
and removed
backlog
labels 2026-04-02 13:08:29 +00:00
dev-qwen removed their assignment 2026-04-02 13:43:43 +00:00
dev-qwen removed the
in-progress
label 2026-04-02 13:43:44 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 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: johba/disinto#143
No description provided.