main
claude/smbcloud-github-app-k9641p
development
feature/apps
feature/build-release
feature/ci-docs
feature/ci-ruby-gems
feature/cicd
feature/completion
feature/dist-nuget
feature/fix-ci-sdk-pypi-rubygem
feature/fix-clippy-on-stable-channel
feature/fix-deployment-script
feature/github-email
feature/gresiq-v1
feature/project-new-structure
feature/rsync-deploy
feature/ruby-runner
feature/sdk-npm
feature/sdk-workflows
feature/smbcloud-cli-release-npm
feature/smbcloud-deploy
feature/wasm
main
release/v0.7.4
| 1 | # CI / non-interactive deploys |
| 2 | |
| 3 | `smb` is interactive by default — it prompts for confirmations, project setup, |
| 4 | credentials, and so on. In CI that's a problem: there's no TTY to answer a |
| 5 | prompt, so the command would hang or fail with a cryptic terminal error. |
| 6 | |
| 7 | Pass the global **`--ci`** flag (or set **`SMB_CI=1`**, or run under any provider |
| 8 | that sets the conventional **`CI`** env var) to put `smb` in **non-interactive |
| 9 | mode**: |
| 10 | |
| 11 | - Confirmations resolve to their default instead of asking |
| 12 | (e.g. `smb --ci logout` proceeds without a y/n prompt). |
| 13 | - Any command that genuinely needs interactive input — `login`, `init`, |
| 14 | `signup`, `account forgot-password`, `project new/update/delete`, and picking a |
| 15 | monorepo target — **fails fast with a clear, actionable message** instead of |
| 16 | blocking. |
| 17 | |
| 18 | ```sh |
| 19 | smb --ci deploy # flag |
| 20 | SMB_CI=1 smb deploy # env var |
| 21 | CI=true smb deploy # most CI providers set this automatically |
| 22 | ``` |
| 23 | |
| 24 | ## Authenticate ahead of time |
| 25 | |
| 26 | Logging in is interactive, so it can't run under `--ci`. Provision the token |
| 27 | once and make it available to the CI job at `~/.smb/token` (production) or |
| 28 | `~/.smb-dev/token` (dev). Typically you store the token contents in a CI secret |
| 29 | and write the file at the start of the job: |
| 30 | |
| 31 | ```yaml |
| 32 | - run: | |
| 33 | mkdir -p ~/.smb |
| 34 | printf '%s' "${{ secrets.SMB_TOKEN }}" > ~/.smb/token |
| 35 | chmod 600 ~/.smb/token |
| 36 | ``` |
| 37 | |
| 38 | Deploys also rsync over SSH using `~/.ssh/id_<user-id>@smbcloud`; install that |
| 39 | key the same way if your project deploys to a server tier. |
| 40 | |
| 41 | ## Deploying from GitHub Actions |
| 42 | |
| 43 | The [`smbcloudXYZ/smbcloud-deploy-action`](https://github.com/smbcloudXYZ/smbcloud-deploy-action) |
| 44 | composite action wraps the steps above: it installs the CLI, writes the token to |
| 45 | the right state dir, optionally installs the SSH key, then runs `smb --ci deploy`. |
| 46 | |
| 47 | ```yaml |
| 48 | - uses: smbcloudXYZ/smbcloud-deploy-action@v1 |
| 49 | with: |
| 50 | token: ${{ secrets.SMB_TOKEN }} |
| 51 | ``` |
| 52 | |
| 53 | For a monorepo, name the sub-project and pass the SSH inputs that rsync deploys |
| 54 | need: |
| 55 | |
| 56 | ```yaml |
| 57 | - uses: smbcloudXYZ/smbcloud-deploy-action@v1 |
| 58 | with: |
| 59 | token: ${{ secrets.SMB_TOKEN }} |
| 60 | project: docs |
| 61 | ssh-private-key: ${{ secrets.SMB_SSH_PRIVATE_KEY }} |
| 62 | ssh-key-name: ${{ secrets.SMB_SSH_KEY_NAME }} |
| 63 | ssh-known-hosts: ${{ secrets.SMB_SSH_KNOWN_HOSTS }} |
| 64 | ``` |
| 65 | |
| 66 | The action installs the latest published CLI release, so `--ci` must exist in |
| 67 | that release. Pin the `version` input if you need a specific CLI version. See the |
| 68 | action's README for the full input reference. |
| 69 | |
| 70 | ## Example: the AircraftsHub monorepo |
| 71 | |
| 72 | [AircraftsHub](https://aircraftshub.5mb.app) is a Tauri app whose Next.js web app |
| 73 | lives in the same repo (`web/`) as a pnpm workspace. Only the web app deploys to |
| 74 | smbCloud; the desktop/mobile app ships to the app stores. Its `.smb/config.toml`: |
| 75 | |
| 76 | ```toml |
| 77 | name = "aircraftshubweb" |
| 78 | |
| 79 | [project] |
| 80 | id = 61 |
| 81 | kind = "nextjs-ssr" |
| 82 | source = "web" # local Next.js app directory (workspace member) |
| 83 | path = "apps/web/aircraftshubweb" # remote runtime directory on the server |
| 84 | package_manager = "pnpm" |
| 85 | pm2_app = "aircraftshub-web" |
| 86 | port = 3022 |
| 87 | ``` |
| 88 | |
| 89 | Because the config pins the project, the source, and the runtime, deploying needs |
| 90 | no interaction at all: |
| 91 | |
| 92 | ```sh |
| 93 | smb --ci deploy |
| 94 | # ✔ Build complete. |
| 95 | # App is running ✔ |
| 96 | # ✔ Deployment complete. |
| 97 | ``` |
| 98 | |
| 99 | For a monorepo config with several `[[projects]]` entries, name the target — |
| 100 | `--ci` mode won't prompt you to choose: |
| 101 | |
| 102 | ```sh |
| 103 | smb --ci deploy --project aircraftshubweb |
| 104 | ``` |
| 105 | |
| 106 | ## Behavior reference |
| 107 | |
| 108 | | Command | `--ci` behavior | |
| 109 | |---|---| |
| 110 | | `deploy` (config pins project) | Runs fully non-interactively | |
| 111 | | `deploy` (monorepo, no `--project`) | Fails: pass `--project <name>` | |
| 112 | | `deploy` (not authenticated) | Fails: provision the token first | |
| 113 | | `logout` | Proceeds (confirmation defaults to yes) | |
| 114 | | `login`, `init`, `signup`, `account forgot-password` | Fails fast — interactive only | |
| 115 | | `project new`, `project update`, `project delete` | Fails fast — interactive only | |
| 116 | | `me`, `migrate`, `project list/show`, `mail` | Unaffected (no prompts) | |