···1515 .push(Router::with_path("recreate").post(recreate_project))
1616 .push(Router::with_path("pull").post(pull_project))
1717 .push(Router::with_path("build").post(build_project))
1818+ .push(Router::with_path("update").post(update_project))
1819 .push(
1920 Router::with_path("service/{service}")
2021 .push(Router::with_path("restart").post(restart_service))
···141142pub async fn build_project(project: PathParam<String>, depot: &mut Depot) -> LuminaryResponse<()> {
142143 let engine = obtain!(depot, LuminaryEngine);
143144145145+ engine.build(&project, None).await?;
146146+ return Ok(().into());
147147+}
148148+149149+/// Pulls and builds the images for all the services in the given project.
150150+#[endpoint]
151151+pub async fn update_project(project: PathParam<String>, depot: &mut Depot) -> LuminaryResponse<()> {
152152+ let engine = obtain!(depot, LuminaryEngine);
153153+154154+ engine.pull(&project, None).await?;
144155 engine.build(&project, None).await?;
145156 return Ok(().into());
146157}
+1-1
packages/node/src/api/mod.rs
···5252 crate::core::LuminaryProjectList::to_schema(&mut openapi.components);
5353 crate::logging::LogMessage::to_schema(&mut openapi.components);
54545555- let location = concat!(env!("CARGO_MANIFEST_DIR"), "/../panel/static/openapi.json");
5555+ let location = concat!(env!("CARGO_MANIFEST_DIR"), "/openapi.json");
5656 std::fs::write(location, openapi.to_pretty_json()?)?;
5757 info!("OpenAPI documentation written to {}", location);
5858 }
+11-7
packages/node/src/core/action.rs
···9797 Ok(())
9898 }
9999100100+ /// Recreates the given project and optionally, a specific service within that project.
100101 #[wrap_err("Failed to recreate project/service")]
101102 pub async fn recreate(&self, project: &str, service: Option<&str>) -> Result<()> {
102103 self.stop(project, service).await?;
···104105 Ok(())
105106 }
106107107107- /// Stops the given project and optionally, a specific service within that project.
108108+ /// Pulls the latest images for the given project and optionally, a specific service within that project.
108109 #[wrap_err("Failed to pull project/service images")]
109110 pub async fn pull(&self, project: &str, service: Option<&str>) -> Result<()> {
110110- self.run(LuminaryAction::Pulling, project, service, vec!["pull"])
111111- .await?;
112112- self.recreate(project, service).await?;
111111+ self.run(
112112+ LuminaryAction::Pulling,
113113+ project,
114114+ service,
115115+ vec!["up", "--pull", "always", "-d"],
116116+ )
117117+ .await?;
113118 Ok(())
114119 }
115120116116- /// Stops the given project and optionally, a specific service within that project.
121121+ /// Builds the images for the given project and optionally, a specific service within that project.
117122 #[wrap_err("Failed to build project/service images")]
118123 pub async fn build(&self, project: &str, service: Option<&str>) -> Result<()> {
119124 self.run(
120125 LuminaryAction::Building,
121126 project,
122127 service,
123123- vec!["build", "--no-cache"],
128128+ vec!["up", "--build", "-d"],
124129 )
125130 .await?;
126131127127- self.recreate(project, service).await?;
128132 Ok(())
129133 }
130134}
-1
packages/panel/.gitignore
···99/build
10101111# Generated
1212-/static/openapi.json
1312/src/lib/api/openapi.ts
14131514# OS
+1-1
packages/panel/plugin.ts
···33import { existsSync } from "node:fs";
44import type { Plugin } from "vite";
5566-const OPENAPI_PATH = new URL("static/openapi.json", import.meta.url);
66+const OPENAPI_PATH = new URL("../node/openapi.json", import.meta.url);
7788async function generateTypes() {
99 if (!existsSync(OPENAPI_PATH)) return;