bod-cli 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -11694,8 +11694,8 @@ function getDefaultInstance(config) {
11694
11694
  return { name, instance: config.instances[name] };
11695
11695
  }
11696
11696
  var instanceOverride2;
11697
- function getResolvedInstance(config) {
11698
- const override = instanceOverride2 ?? process.env.BOD_INSTANCE;
11697
+ function getResolvedInstance(config, yamlInstance) {
11698
+ const override = instanceOverride2 ?? process.env.BOD_INSTANCE ?? yamlInstance;
11699
11699
  if (override) {
11700
11700
  const inst = config.instances[override];
11701
11701
  if (!inst)
@@ -11858,6 +11858,23 @@ function readAppNameFromYaml() {
11858
11858
  return;
11859
11859
  }
11860
11860
  }
11861
+ function readInstanceFromYaml() {
11862
+ try {
11863
+ const yaml = readFileSync3("bodify.yaml", "utf-8");
11864
+ return yaml.match(/instance:\s*(.+)/)?.[1]?.trim();
11865
+ } catch {
11866
+ return;
11867
+ }
11868
+ }
11869
+ function readDeployModeFromYaml() {
11870
+ try {
11871
+ const yaml = readFileSync3("bodify.yaml", "utf-8");
11872
+ const mode = yaml.match(/deploy:\s*(.+)/)?.[1]?.trim();
11873
+ return mode === "upload" ? "upload" : mode === "git" ? "git" : undefined;
11874
+ } catch {
11875
+ return;
11876
+ }
11877
+ }
11861
11878
  function resolveAppName(arg) {
11862
11879
  if (arg)
11863
11880
  return arg;
@@ -11986,17 +12003,21 @@ var deploy_default = defineCommand2({
11986
12003
  meta: { name: "deploy", description: "Trigger a deployment" },
11987
12004
  args: {
11988
12005
  app: { type: "positional", description: "App name (or reads from bodify.yaml)", required: false },
11989
- branch: { type: "string", description: "Branch to deploy (default: current git branch)" }
12006
+ branch: { type: "string", description: "Branch to deploy (default: current git branch)" },
12007
+ upload: { type: "boolean", description: "Upload local source instead of git clone", default: false }
11990
12008
  },
11991
12009
  async run({ args }) {
11992
- const { url, apiKey } = getResolvedInstance(loadConfig());
12010
+ const { url, apiKey, name: instanceName } = getResolvedInstance(loadConfig(), readInstanceFromYaml());
12011
+ if (readInstanceFromYaml())
12012
+ console.log(source_default.dim(`Using instance "${instanceName}" from bodify.yaml`));
11993
12013
  const client = new BodClient(url, apiKey);
11994
12014
  const appName = resolveAppName(args.app);
11995
12015
  const appId = await resolveAppId(client, appName);
11996
12016
  const branch = await detectBranch(args.branch);
11997
12017
  const detail = await client.get(`/apps/${appId}`);
12018
+ const forceUpload = args.upload || readDeployModeFromYaml() === "upload";
11998
12019
  let hasRepo = !!detail.repo;
11999
- if (!hasRepo) {
12020
+ if (!hasRepo && !forceUpload) {
12000
12021
  const proc = Bun.spawnSync(["git", "remote", "get-url", "origin"]);
12001
12022
  const repo = proc.exitCode === 0 ? proc.stdout.toString().trim() : "";
12002
12023
  if (repo) {
@@ -12005,12 +12026,13 @@ var deploy_default = defineCommand2({
12005
12026
  hasRepo = true;
12006
12027
  }
12007
12028
  }
12008
- console.log(source_default.dim(`Deploying ${appName} (branch: ${branch})${hasRepo ? "" : " via upload"}...`));
12029
+ const useUpload = forceUpload || !hasRepo;
12030
+ console.log(source_default.dim(`Deploying ${appName} (branch: ${branch})${useUpload ? " via upload" : ""}...`));
12009
12031
  const since = Date.now();
12010
- if (hasRepo) {
12011
- await gitDeploy(client, appId, branch);
12012
- } else {
12032
+ if (useUpload) {
12013
12033
  await uploadDeploy(client, appId, branch);
12034
+ } else {
12035
+ await gitDeploy(client, appId, branch);
12014
12036
  }
12015
12037
  console.log(source_default.green(`✓ Deployment queued`));
12016
12038
  await pollDeploy(client, appId, since);
@@ -12025,7 +12047,7 @@ var rollback_default = defineCommand2({
12025
12047
  branch: { type: "string", description: "Branch to rollback (default: production branch)" }
12026
12048
  },
12027
12049
  async run({ args }) {
12028
- const { url, apiKey } = getResolvedInstance(loadConfig());
12050
+ const { url, apiKey } = getResolvedInstance(loadConfig(), readInstanceFromYaml());
12029
12051
  const client = new BodClient(url, apiKey);
12030
12052
  const appName = resolveAppName(args.app);
12031
12053
  const appId = await resolveAppId(client, appName);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bod-cli",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "bod": "./dist/cli.js"
@@ -2,7 +2,7 @@ import { defineCommand } from 'citty'
2
2
  import chalk from 'chalk'
3
3
  import { loadConfig, getResolvedInstance } from '../config'
4
4
  import { BodClient } from '../client'
5
- import { resolveAppId, resolveAppName } from '../utils/resolve'
5
+ import { resolveAppId, resolveAppName, readInstanceFromYaml, readDeployModeFromYaml } from '../utils/resolve'
6
6
 
7
7
  async function detectBranch(explicit?: string): Promise<string> {
8
8
  if (explicit) return explicit
@@ -66,9 +66,11 @@ export default defineCommand({
66
66
  args: {
67
67
  app: { type: 'positional', description: 'App name (or reads from bodify.yaml)', required: false },
68
68
  branch: { type: 'string', description: 'Branch to deploy (default: current git branch)' },
69
+ upload: { type: 'boolean', description: 'Upload local source instead of git clone', default: false },
69
70
  },
70
71
  async run({ args }) {
71
- const { url, apiKey } = getResolvedInstance(loadConfig())
72
+ const { url, apiKey, name: instanceName } = getResolvedInstance(loadConfig(), readInstanceFromYaml())
73
+ if (readInstanceFromYaml()) console.log(chalk.dim(`Using instance "${instanceName}" from bodify.yaml`))
72
74
  const client = new BodClient(url, apiKey)
73
75
 
74
76
  const appName = resolveAppName(args.app)
@@ -77,8 +79,10 @@ export default defineCommand({
77
79
  const branch = await detectBranch(args.branch)
78
80
  const detail = await client.get<any>(`/apps/${appId}`)
79
81
 
82
+ const forceUpload = args.upload || readDeployModeFromYaml() === 'upload'
83
+
80
84
  let hasRepo = !!detail.repo
81
- if (!hasRepo) {
85
+ if (!hasRepo && !forceUpload) {
82
86
  const proc = Bun.spawnSync(['git', 'remote', 'get-url', 'origin'])
83
87
  const repo = proc.exitCode === 0 ? proc.stdout.toString().trim() : ''
84
88
  if (repo) {
@@ -88,13 +92,14 @@ export default defineCommand({
88
92
  }
89
93
  }
90
94
 
91
- console.log(chalk.dim(`Deploying ${appName} (branch: ${branch})${hasRepo ? '' : ' via upload'}...`))
95
+ const useUpload = forceUpload || !hasRepo
96
+ console.log(chalk.dim(`Deploying ${appName} (branch: ${branch})${useUpload ? ' via upload' : ''}...`))
92
97
 
93
98
  const since = Date.now()
94
- if (hasRepo) {
95
- await gitDeploy(client, appId, branch)
96
- } else {
99
+ if (useUpload) {
97
100
  await uploadDeploy(client, appId, branch)
101
+ } else {
102
+ await gitDeploy(client, appId, branch)
98
103
  }
99
104
 
100
105
  console.log(chalk.green(`✓ Deployment queued`))
@@ -2,7 +2,7 @@ import { defineCommand } from 'citty'
2
2
  import chalk from 'chalk'
3
3
  import { loadConfig, getResolvedInstance } from '../config'
4
4
  import { BodClient } from '../client'
5
- import { resolveAppId, resolveAppName } from '../utils/resolve'
5
+ import { resolveAppId, resolveAppName, readInstanceFromYaml } from '../utils/resolve'
6
6
 
7
7
  export default defineCommand({
8
8
  meta: { name: 'rollback', description: 'Rollback to previous deployment' },
@@ -11,7 +11,7 @@ export default defineCommand({
11
11
  branch: { type: 'string', description: 'Branch to rollback (default: production branch)' },
12
12
  },
13
13
  async run({ args }) {
14
- const { url, apiKey } = getResolvedInstance(loadConfig())
14
+ const { url, apiKey } = getResolvedInstance(loadConfig(), readInstanceFromYaml())
15
15
  const client = new BodClient(url, apiKey)
16
16
 
17
17
  const appName = resolveAppName(args.app)
package/src/config.ts CHANGED
@@ -70,8 +70,8 @@ export function setInstanceOverride(name: string | undefined) {
70
70
  instanceOverride = name
71
71
  }
72
72
 
73
- export function getResolvedInstance(config: Config): { name: string; url: string; apiKey: string; instance: Instance } {
74
- const override = instanceOverride ?? process.env.BOD_INSTANCE
73
+ export function getResolvedInstance(config: Config, yamlInstance?: string): { name: string; url: string; apiKey: string; instance: Instance } {
74
+ const override = instanceOverride ?? process.env.BOD_INSTANCE ?? yamlInstance
75
75
  if (override) {
76
76
  const inst = config.instances[override]
77
77
  if (!inst) throw new Error(`Instance "${override}" not found in config. Available: ${Object.keys(config.instances).join(', ')}`)
@@ -19,6 +19,21 @@ export function readAppNameFromYaml(): string | undefined {
19
19
  } catch { return undefined }
20
20
  }
21
21
 
22
+ export function readInstanceFromYaml(): string | undefined {
23
+ try {
24
+ const yaml = readFileSync('bodify.yaml', 'utf-8')
25
+ return yaml.match(/instance:\s*(.+)/)?.[1]?.trim()
26
+ } catch { return undefined }
27
+ }
28
+
29
+ export function readDeployModeFromYaml(): 'upload' | 'git' | undefined {
30
+ try {
31
+ const yaml = readFileSync('bodify.yaml', 'utf-8')
32
+ const mode = yaml.match(/deploy:\s*(.+)/)?.[1]?.trim()
33
+ return mode === 'upload' ? 'upload' : mode === 'git' ? 'git' : undefined
34
+ } catch { return undefined }
35
+ }
36
+
22
37
  /** Resolve app name from explicit arg or bodify.yaml fallback. Logs clearly when falling back. */
23
38
  export function resolveAppName(arg: string | undefined): string {
24
39
  if (arg) return arg