feature/sdk-npm
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 | use { |
| 2 | crate::error_codes::{ErrorCode::UnsupportedRunner, ErrorResponse}, |
| 3 | serde::{Deserialize, Serialize}, |
| 4 | serde_repr::{Deserialize_repr, Serialize_repr}, |
| 5 | std::{ |
| 6 | fmt::{self, Display, Formatter}, |
| 7 | path::Path, |
| 8 | }, |
| 9 | }; |
| 10 | |
| 11 | #[derive(Debug, Deserialize_repr, Serialize_repr, Clone, Copy, PartialEq, Default)] |
| 12 | #[repr(u8)] |
| 13 | #[tsync::tsync] |
| 14 | pub enum Runner { |
| 15 | #[default] |
| 16 | NodeJs = 0, |
| 17 | /// A pure static site: no app process on the server, nginx serves files |
| 18 | /// directly. Always deployed via rsync — git push has no build step to run. |
| 19 | Static = 1, |
| 20 | Ruby = 2, |
| 21 | Swift = 3, |
| 22 | Rust = 4, |
| 23 | Monorepo = 255, |
| 24 | } |
| 25 | |
| 26 | impl Display for Runner { |
| 27 | fn fmt(&self, f: &mut Formatter) -> fmt::Result { |
| 28 | match self { |
| 29 | Runner::NodeJs => write!(f, "NodeJs"), |
| 30 | Runner::Static => write!(f, "Static"), |
| 31 | Runner::Ruby => write!(f, "Ruby"), |
| 32 | Runner::Swift => write!(f, "Swift"), |
| 33 | Runner::Rust => write!(f, "Rust"), |
| 34 | Runner::Monorepo => write!(f, "Monorepo"), |
| 35 | } |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | #[derive(Debug, Serialize, Deserialize)] |
| 40 | #[tsync::tsync] |
| 41 | pub enum NodeJsFramework { |
| 42 | NextJs, |
| 43 | Astro, |
| 44 | } |
| 45 | |
| 46 | #[derive(Debug, Serialize, Deserialize)] |
| 47 | #[tsync::tsync] |
| 48 | pub enum RubyFramework { |
| 49 | Rails, |
| 50 | } |
| 51 | |
| 52 | #[derive(Debug, Serialize, Deserialize)] |
| 53 | #[tsync::tsync] |
| 54 | pub enum SwiftFramework { |
| 55 | Vapor, |
| 56 | } |
| 57 | |
| 58 | impl Runner { |
| 59 | pub fn from(repo_path: &Path) -> Result<Runner, ErrorResponse> { |
| 60 | // Any package.json-driven app belongs on the NodeJs runner. |
| 61 | // Framework-specific checks are not reliable because modern Next.js apps |
| 62 | // do not need a next.config.* file at all. |
| 63 | if repo_path.join("package.json").exists() { |
| 64 | return Ok(Runner::NodeJs); |
| 65 | } |
| 66 | |
| 67 | if repo_path.join("Gemfile").exists() { |
| 68 | return Ok(Runner::Ruby); |
| 69 | } |
| 70 | if repo_path.join("Package.swift").exists() { |
| 71 | return Ok(Runner::Swift); |
| 72 | } |
| 73 | if repo_path.join("Cargo.toml").exists() { |
| 74 | return Ok(Runner::Rust); |
| 75 | } |
| 76 | // See if we have a monorepo setup. |
| 77 | non_framework_runner() |
| 78 | } |
| 79 | |
| 80 | pub fn git_host(&self) -> String { |
| 81 | format!("git@{}.smbcloud.xyz", self.api()) |
| 82 | } |
| 83 | |
| 84 | /// Returns the explicit hostname used for rsync SSH connections. |
| 85 | /// e.g. `api.smbcloud.xyz` or `api-1.smbcloud.xyz` |
| 86 | pub fn rsync_host(&self) -> String { |
| 87 | format!("{}.smbcloud.xyz", self.api()) |
| 88 | } |
| 89 | |
| 90 | fn api(&self) -> &str { |
| 91 | match self { |
| 92 | Runner::Monorepo => "monorepo", |
| 93 | // Static sites and NodeJs projects share the same lightweight tier |
| 94 | Runner::NodeJs | Runner::Static => "api", |
| 95 | Runner::Ruby | Runner::Swift | Runner::Rust => "api-1", |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | fn non_framework_runner() -> Result<Runner, ErrorResponse> { |
| 101 | Err(ErrorResponse::Error { |
| 102 | error_code: UnsupportedRunner, |
| 103 | message: UnsupportedRunner.message(None).to_string(), |
| 104 | }) |
| 105 | } |