--- name: Deploy Smoke on: push: branches: [main] paths: - Dockerfile - .dockerignore - .gitattributes - docker-compose.yml - scripts/docker-entrypoint-core.sh - .do/app.yaml - gitbooks/developing/cloud-deploy.md - .github/workflows/deploy-smoke.yml - Cargo.toml - Cargo.lock - rust-toolchain.toml - src/** pull_request: paths: - Dockerfile - .dockerignore - .gitattributes - docker-compose.yml - scripts/docker-entrypoint-core.sh - .do/app.yaml - gitbooks/developing/cloud-deploy.md - .github/workflows/deploy-smoke.yml - Cargo.toml - Cargo.lock - rust-toolchain.toml - src/** workflow_dispatch: permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.head_ref || github.ref }} cancel-in-progress: true jobs: docker-image: name: Build & smoke-test core image runs-on: ubuntu-22.04 timeout-minutes: 45 steps: - name: Checkout uses: actions/checkout@v5 with: fetch-depth: 1 submodules: false - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build openhuman-core image uses: docker/build-push-action@v6 with: context: . file: Dockerfile push: false load: true tags: openhuman-core:smoke cache-from: type=gha,scope=deploy-smoke cache-to: type=gha,scope=deploy-smoke,mode=max - name: Run container run: | docker run -d \ --name oh-smoke \ -p 7788:7788 \ -e OPENHUMAN_CORE_TOKEN=ci-smoke-token \ -e OPENHUMAN_APP_ENV=staging \ -e BACKEND_URL=https://staging-api.tinyhumans.ai \ openhuman-core:smoke - name: Wait for /health run: | set -e for i in $(seq 1 30); do if curl -fsS http://localhost:7788/health > /tmp/health.json; then echo "Healthy on attempt $i" cat /tmp/health.json exit 0 fi echo "attempt $i: not ready, sleeping..." sleep 2 done echo "Container never became healthy. Logs:" docker logs oh-smoke || true exit 1 - name: Verify /rpc rejects without bearer token run: | set -e status=$(curl -s -o /tmp/rpc.json -w "%{http_code}" \ -X POST http://localhost:7788/rpc \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"openhuman.about_app_list","params":{}}') if [ "$status" != "401" ]; then echo "Expected 401 from /rpc without token, got $status" cat /tmp/rpc.json docker logs oh-smoke || true exit 1 fi - name: Verify /rpc accepts the configured bearer token run: | set -e status=$(curl -s -o /tmp/rpc-ok.json -w "%{http_code}" \ -X POST http://localhost:7788/rpc \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ci-smoke-token' \ -d '{"jsonrpc":"2.0","id":1,"method":"openhuman.about_app_list","params":{}}') if [ "$status" != "200" ]; then echo "Expected 200 from authenticated /rpc, got $status" cat /tmp/rpc-ok.json docker logs oh-smoke || true exit 1 fi cat /tmp/rpc-ok.json - name: Container logs (always) if: always() run: docker logs oh-smoke || true - name: Tear down if: always() run: docker rm -f oh-smoke || true # Regression gate for issue #2065: named volume starts root-owned; the # entrypoint must chown it before dropping to the openhuman user, otherwise # the first disk write (init_rpc_token → write_token_file) raises EACCES # and the process exits with code 1. # # This job deliberately omits OPENHUMAN_CORE_TOKEN (so the core WILL attempt # to write core.token) and mounts a fresh anonymous volume at the workspace # path (so Docker creates it root:root). The existing job above always sets # the token and therefore short-circuits the write — it cannot catch this bug. docker-volume-permissions: name: Smoke-test core with fresh volume and no pre-set token runs-on: ubuntu-22.04 timeout-minutes: 45 needs: docker-image steps: - name: Checkout uses: actions/checkout@v5 with: fetch-depth: 1 submodules: false - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build openhuman-core image uses: docker/build-push-action@v6 with: context: . file: Dockerfile push: false load: true tags: openhuman-core:smoke cache-from: type=gha,scope=deploy-smoke cache-to: type=gha,scope=deploy-smoke,mode=max - name: Run container with fresh anonymous volume and no token run: | docker run -d \ --name oh-vol-smoke \ -p 7789:7788 \ -v oh-vol-smoke-workspace:/home/openhuman/.openhuman \ -e OPENHUMAN_APP_ENV=staging \ -e BACKEND_URL=https://staging-api.tinyhumans.ai \ openhuman-core:smoke - name: Wait for /health (volume-permissions path) run: | set -e for i in $(seq 1 30); do if curl -fsS http://localhost:7789/health > /tmp/vol-health.json; then echo "Healthy on attempt $i" cat /tmp/vol-health.json exit 0 fi echo "attempt $i: not ready, sleeping..." sleep 2 done echo "Container never became healthy. Logs:" docker logs oh-vol-smoke || true exit 1 - name: Assert no permission-denied errors in logs run: | set -e if docker logs oh-vol-smoke 2>&1 | grep -q "Permission denied (os error 13)"; then echo "FAIL: 'Permission denied (os error 13)' found in container logs" docker logs oh-vol-smoke || true exit 1 fi echo "PASS: no permission-denied errors in container logs" - name: Container logs (always) if: always() run: docker logs oh-vol-smoke || true - name: Tear down if: always() run: | docker rm -f oh-vol-smoke || true docker volume rm oh-vol-smoke-workspace || true