diff --git a/.circleci/config.yml b/.circleci/config.yml
index 4fec5ecb2c..ab9f9f9e0c 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -631,10 +631,8 @@ workflows:
parameters:
path:
- resources/aws-rds
- - resources/metadata
- resources/persist
- resources/qdrant
- - resources/secrets
- resources/shared-db
- resources/turso
- resources/opendal
diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs
index eca66eb3dc..7409f0e382 100644
--- a/cargo-shuttle/src/lib.rs
+++ b/cargo-shuttle/src/lib.rs
@@ -448,7 +448,8 @@ impl Shuttle {
} else {
get_templates_schema()
.await
- .map_err(|_| {
+ .map_err(|e| {
+ error!(err = %e, "Failed to get templates");
println!(
"{}",
"Failed to look up template list. Falling back to internal list."
diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs
index 9935ad3adb..7072046057 100644
--- a/codegen/src/lib.rs
+++ b/codegen/src/lib.rs
@@ -26,7 +26,7 @@ mod shuttle_main;
/// | `ShuttlePoem` | [shuttle-poem](https://crates.io/crates/shuttle-poem) | [poem](https://docs.rs/poem/2.0) | 2.0 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/poem/hello-world) |
/// | `ShuttleRocket` | [shuttle-rocket](https://crates.io/crates/shuttle-rocket) | [rocket](https://docs.rs/rocket/0.5) | 0.5 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/rocket/hello-world) |
/// | `ShuttleSalvo` | [shuttle-salvo](https://crates.io/crates/shuttle-salvo) | [salvo](https://docs.rs/salvo/0.63) | 0.63 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/salvo/hello-world) |
-/// | `ShuttleSerenity` | [shuttle-serenity](https://crates.io/crates/shuttle-serenity | [serenity](https://docs.rs/serenity/0.12) and [poise](https://docs.rs/poise/0.6) | 0.12 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/serenity/hello-world) |
+/// | `ShuttleSerenity` | [shuttle-serenity](https://crates.io/crates/shuttle-serenity) | [serenity](https://docs.rs/serenity/0.12) and [poise](https://docs.rs/poise/0.6) | 0.12 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/serenity/hello-world) |
/// | `ShuttleThruster` | [shuttle-thruster](https://crates.io/crates/shuttle-thruster) | [thruster](https://docs.rs/thruster/1.3) | 1.3 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/thruster/hello-world) |
/// | `ShuttleTower` | [shuttle-tower](https://crates.io/crates/shuttle-tower) | [tower](https://docs.rs/tower/0.4) | 0.4 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/tower/hello-world) |
/// | `ShuttleTide` | [shuttle-tide](https://crates.io/crates/shuttle-tide) | [tide](https://docs.rs/tide/0.16) | 0.16 | [GitHub](https://github.com/shuttle-hq/shuttle-examples/tree/main/tide/hello-world) |
diff --git a/common/src/resource.rs b/common/src/resource.rs
index b2d7b9c9bb..53931733e7 100644
--- a/common/src/resource.rs
+++ b/common/src/resource.rs
@@ -56,10 +56,10 @@ pub struct Response {
/// The type of this resource.
pub r#type: Type,
- /// The config used when creating this resource. Use the [Self::r#type] to know how to parse this data.
+ /// The config used when creating this resource. Use the `r#type` to know how to parse this data.
pub config: Value,
- /// The data associated with this resource. Use the [Self::r#type] to know how to parse this data.
+ /// The data associated with this resource. Use the `r#type` to know how to parse this data.
pub data: Value,
}
diff --git a/common/src/secrets.rs b/common/src/secrets.rs
index 7ce4684b97..e90c4c7512 100644
--- a/common/src/secrets.rs
+++ b/common/src/secrets.rs
@@ -4,7 +4,7 @@ use zeroize::Zeroize;
/// Wrapper type for secret values such as passwords or authentication keys.
///
-/// Once wrapped, the inner value cannot leak accidentally, as both the [`Display`] and [`Debug`]
+/// Once wrapped, the inner value cannot leak accidentally, as both the [`std::fmt::Display`] and [`Debug`]
/// implementations cover up the actual value and only show the type.
///
/// If you need access to the inner value, there is an [expose](`Secret::expose`) method.
diff --git a/examples b/examples
index 7af5b42f94..7cf399638b 160000
--- a/examples
+++ b/examples
@@ -1 +1 @@
-Subproject commit 7af5b42f944a386140df8fdfe045a12fc88657e5
+Subproject commit 7cf399638b96e7c78a06b68b0b2a5a980f7b3d32
diff --git a/resources/metadata/Cargo.toml b/resources/metadata/Cargo.toml
index fbaaf4e7a4..4650539a05 100644
--- a/resources/metadata/Cargo.toml
+++ b/resources/metadata/Cargo.toml
@@ -8,4 +8,4 @@ keywords = ["shuttle-service", "metadata"]
[dependencies]
async-trait = "0.1.56"
-shuttle-service = { path = "../../service", version = "0.41.0" }
+shuttle-service = { path = "../../service", version = "<=0.44.0" }
diff --git a/resources/metadata/README.md b/resources/metadata/README.md
index 171af2863d..566d836650 100644
--- a/resources/metadata/README.md
+++ b/resources/metadata/README.md
@@ -1,22 +1,3 @@
# Shuttle Metadata
-This plugin allows applications to obtain certain information about their runtime environment.
-
-## Usage
-
-Add `shuttle-metadata` to the dependencies for your service.
-
-You can get this resource using the `shuttle_metadata::ShuttleMetadata` attribute to get a `Metadata`. This struct will contain information such as the Shuttle service name.
-
-```rust
-#[shuttle_runtime::main]
-async fn app(
- #[shuttle_metadata::ShuttleMetadata] metadata: shuttle_metadata::Metadata,
-) -> __ { ... }
-```
-
-#### Example projects that use `shuttle-metadata`
-
-| Framework | Link |
-| --------- | -------------------------------------------------------------------------------------- |
-| Axum | [axum example](https://github.com/shuttle-hq/shuttle-examples/tree/main/axum/metadata) |
+This plugin has been moved to [shuttle-runtime](https://crates.io/crates/shuttle-runtime).
diff --git a/resources/metadata/src/lib.rs b/resources/metadata/src/lib.rs
index e612e08e27..38ab9d1ede 100644
--- a/resources/metadata/src/lib.rs
+++ b/resources/metadata/src/lib.rs
@@ -3,6 +3,10 @@ pub use shuttle_service::{DeploymentMetadata as Metadata, Environment, SecretSto
use shuttle_service::{Error, ResourceFactory, ResourceInputBuilder};
#[derive(Default)]
+#[deprecated(
+ since = "0.42.0",
+ note = "This plugin has been moved to shuttle_runtime::Metadata, see https://docs.shuttle.rs/resources/shuttle-metadata"
+)]
pub struct ShuttleMetadata;
#[async_trait]
diff --git a/resources/secrets/Cargo.toml b/resources/secrets/Cargo.toml
index 22223b9b4e..86b39f0040 100644
--- a/resources/secrets/Cargo.toml
+++ b/resources/secrets/Cargo.toml
@@ -9,4 +9,4 @@ keywords = ["shuttle-service", "secrets"]
[dependencies]
async-trait = "0.1.56"
serde_json = "1"
-shuttle-service = { path = "../../service", version = "0.41.0" }
+shuttle-service = { path = "../../service", version = "<=0.44.0" }
diff --git a/resources/secrets/README.md b/resources/secrets/README.md
index 9164d92df6..09b60280fe 100644
--- a/resources/secrets/README.md
+++ b/resources/secrets/README.md
@@ -1,32 +1,3 @@
# Shuttle Secrets
-This plugin manages secrets on [Shuttle](https://www.shuttle.rs).
-
-## Usage
-
-Add `shuttle-secrets` to the dependencies for your service, and add a `Secrets.toml` to the root of your project
-with the secrets you'd like to store. Make sure to add `Secrets*.toml` to a `.gitignore` to omit your secrets from version control.
-
-Next, pass `#[shuttle_secrets::Secrets] secret_store: SecretStore` as an argument to your `shuttle_service::main` function.
-`SecretStore::get` can now be called to retrieve your API keys and other secrets at runtime.
-
-## Example
-
-```rust,ignore
-#[shuttle_runtime::main]
-async fn rocket(
- #[shuttle_secrets::Secrets] secret_store: SecretStore,
-) -> ShuttleRocket {
- // get secret defined in `Secrets.toml` file.
- let secret = if let Some(secret) = secret_store.get("MY_API_KEY") {
- secret
- } else {
- return Err(anyhow!("secret was not found").into());
- };
-
- let state = MyState { secret };
- let rocket = rocket::build().mount("/", routes![secret]).manage(state);
-
- Ok(rocket.into())
-}
-```
+This plugin has been moved to [shuttle-runtime](https://crates.io/crates/shuttle-runtime).
diff --git a/resources/secrets/src/lib.rs b/resources/secrets/src/lib.rs
index 44d3b20ddc..fb7725a643 100644
--- a/resources/secrets/src/lib.rs
+++ b/resources/secrets/src/lib.rs
@@ -1,3 +1,4 @@
+
#![doc = include_str!("../README.md")]
use async_trait::async_trait;
pub use shuttle_service::SecretStore;
@@ -8,6 +9,10 @@ use shuttle_service::{
/// Secrets plugin that provides service secrets
#[derive(Default)]
+#[deprecated(
+ since = "0.42.0",
+ note = "This plugin has been moved to shuttle_runtime::Secrets, see https://docs.shuttle.rs/resources/shuttle-secrets"
+)]
pub struct Secrets;
#[async_trait]
diff --git a/runtime/README.md b/runtime/README.md
index 07cc9d24b2..f06b4d3007 100644
--- a/runtime/README.md
+++ b/runtime/README.md
@@ -1,15 +1,93 @@
-# shuttle-runtime
+# Shuttle - Deploy Rust apps with a single Cargo subcommand
-[Shuttle](https://www.shuttle.rs/) is a Rust-native cloud development platform that lets you deploy your Rust apps for free.
-
-Shuttle is built for productivity, reliability and performance:
+
+

+
-- Zero-Configuration support for Rust using annotations
-- Automatic resource provisioning (databases, caches, subdomains, etc.) via [Infrastructure-From-Code](https://www.shuttle.rs/blog/2022/05/09/ifc)
-- First-class support for popular Rust frameworks ([Actix Web](https://docs.shuttle.rs/examples/actix), [Rocket](https://docs.shuttle.rs/examples/rocket), [Axum](https://docs.shuttle.rs/examples/axum), and [more](https://docs.shuttle.rs/examples/other))
-- Support for deploying Discord bots using [Serenity](https://docs.shuttle.rs/examples/serenity)
-- Scalable hosting (with optional self-hosting in the future)
+[Shuttle](https://www.shuttle.rs/) is a Rust-native cloud development platform that lets you deploy your Rust apps for free.
đź“– Check out our documentation to get started quickly: [docs.shuttle.rs](https://docs.shuttle.rs)
🙋‍♂️ If you have any questions, join our [Discord](https://discord.gg/shuttle) server.
+
+## Usage
+
+Start by installing the [`cargo shuttle`](https://docs.rs/crate/cargo-shuttle/latest) subcommand by running the following in a terminal:
+
+```bash
+cargo install cargo-shuttle
+```
+
+Now that Shuttle is installed, you can initialize a project with Axum boilerplate:
+
+```bash
+cargo shuttle init --template axum my-axum-app
+```
+
+By looking at the `Cargo.toml` file of the generated `my-axum-app` project you will see it has been made to
+be a binary crate with a few dependencies including `shuttle-runtime` and `shuttle-axum`.
+
+```toml
+axum = "0.7.3"
+shuttle-axum = "0.41.0"
+shuttle-runtime = "0.41.0"
+tokio = "1.28.2"
+```
+
+A boilerplate code for your axum project can also be found in `src/main.rs`:
+
+```rust,no_run
+use axum::{routing::get, Router};
+
+async fn hello_world() -> &'static str {
+ "Hello, world!"
+}
+
+#[shuttle_runtime::main]
+async fn main() -> shuttle_axum::ShuttleAxum {
+ let router = Router::new().route("/", get(hello_world));
+
+ Ok(router.into())
+}
+```
+
+Check out [our docs](https://docs.shuttle.rs/introduction/welcome) to see all the frameworks we support, or
+our [examples](https://github.com/shuttle-hq/shuttle-examples) if you prefer that format.
+
+## Running locally
+
+To test your app locally before deploying, use:
+
+```bash
+cargo shuttle run
+```
+
+You should see your app build and start on the default port 8000. You can test this using;
+
+```bash
+curl http://localhost:8000/
+# Hello, world!
+```
+
+## Deploying
+
+Before you can deploy, you have to create a project. This will start a deployer container for your
+project under the hood, ensuring isolation from other users' projects. PS. you don't have to do this
+now if you did in in the `cargo shuttle init` flow.
+
+```bash
+cargo shuttle project start
+```
+
+Then, deploy the service with:
+
+```bash
+cargo shuttle deploy
+```
+
+Your service will immediately be available at `https://{project_name}.shuttleapp.rs/`. For example:
+
+```bash
+curl https://my-axum-app.shuttleapp.rs/
+# Hello, world!
+```
diff --git a/runtime/src/alpha.rs b/runtime/src/alpha.rs
index 51c5938781..0675b55f50 100644
--- a/runtime/src/alpha.rs
+++ b/runtime/src/alpha.rs
@@ -25,9 +25,8 @@ use tokio::sync::{
use tokio_stream::wrappers::ReceiverStream;
use tonic::{transport::Server, Request, Response, Status};
-use crate::__internals::print_version;
-
use crate::args::args;
+use crate::print_version;
// uses custom macro instead of clap to reduce dependency weight
args! {
@@ -49,17 +48,14 @@ pub async fn start(loader: impl Loader + Send + 'static, runner: impl Runner + S
Ok(args) => args,
Err(e) => {
eprintln!("Runtime received malformed or incorrect args, {e}");
- let help_str = "[HINT]: Run shuttle with `cargo shuttle run`";
+ let help_str = "[HINT]: Run your Shuttle app with `cargo shuttle run`";
let wrapper_str = "-".repeat(help_str.len());
eprintln!("{wrapper_str}\n{help_str}\n{wrapper_str}");
return;
}
};
- println!(
- "shuttle-runtime executable started (version {})",
- crate::VERSION
- );
+ println!("{} {} executable started", crate::NAME, crate::VERSION);
// this is handled after arg parsing to not interfere with --version above
#[cfg(feature = "setup-tracing")]
@@ -81,21 +77,10 @@ pub async fn start(loader: impl Loader + Send + 'static, runner: impl Runner + S
.init();
println!(
- "{}\n\
- {}\n\
- To disable the subscriber and use your own,\n\
- turn off the default features for {}:\n\
- \n\
- {}\n\
- {}",
- "=".repeat(63).yellow(),
- "Shuttle's default tracing subscriber is initialized!"
- .yellow()
- .bold(),
- "shuttle-runtime".italic(),
- r#"shuttle-runtime = { version = "...", default-features = false }"#.italic(),
- "=".repeat(63).yellow(),
+ "{}",
+ "Shuttle's default tracing subscriber is initialized!".yellow(),
);
+ println!("To disable it and use your own, check the docs: https://docs.shuttle.rs/configuration/logs");
}
// where to serve the gRPC control layer
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 4ef3567a1e..8aa8b58a89 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -1,212 +1,14 @@
+#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/shuttle-hq/shuttle/main/assets/logo-square-transparent.png",
html_favicon_url = "https://raw.githubusercontent.com/shuttle-hq/shuttle/main/assets/favicon.ico"
)]
-//! # Shuttle - Deploy Rust apps with a single Cargo subcommand
-//!
-//!

-//!
-//!
-//! Hello, and welcome to the shuttle API documentation!
-//!
-//! Shuttle is an open-source app platform that uses traits and annotations to configure your backend deployments.
-//!
-//! ## Usage
-//! Start by installing the [`cargo shuttle`](https://docs.rs/crate/cargo-shuttle/latest) subcommand by running the following in a terminal:
-//!
-//! ```bash
-//! $ cargo install cargo-shuttle
-//! ```
-//!
-//! Now that shuttle is installed, you can initialize a project with Axum boilerplate:
-//! ```bash
-//! $ cargo shuttle init --template axum my-axum-app
-//! ```
-//!
-//! By looking at the `Cargo.toml` file of the generated `my-axum-app` project you will see it has been made to
-//! be a binary crate with a few dependencies including `shuttle-runtime` and `shuttle-axum`.
-//!
-//! ```toml
-//! axum = "0.7.3"
-//! shuttle-axum = "0.41.0"
-//! shuttle-runtime = "0.41.0"
-//! tokio = "1.28.2"
-//! ```
-//!
-//! A boilerplate code for your axum project can also be found in `src/main.rs`:
-//!
-//! ```rust,no_run
-//! use axum::{routing::get, Router};
-//!
-//! async fn hello_world() -> &'static str {
-//! "Hello, world!"
-//! }
-//!
-//! #[shuttle_runtime::main]
-//! async fn main() -> shuttle_axum::ShuttleAxum {
-//! let router = Router::new().route("/", get(hello_world));
-//!
-//! Ok(router.into())
-//! }
-//! ```
-//!
-//! Check out [our docs](https://docs.shuttle.rs/introduction/welcome) to see all the frameworks we support, or
-//! our [examples](https://github.com/shuttle-hq/shuttle-examples) if you prefer that format.
-//!
-//! ## Running locally
-//! To test your app locally before deploying, use:
-//!
-//! ```bash
-//! $Â cargo shuttle run
-//! ```
-//!
-//! You should see your app build and start on the default port 8000. You can test this using;
-//!
-//! ```bash
-//! $Â curl http://localhost:8000/
-//! Hello, world!
-//! ```
-//!
-//! ## Deploying
-//!
-//! You can deploy your service with the [`cargo shuttle`](https://docs.rs/crate/cargo-shuttle/latest) subcommand too.
-//! But, you will need to authenticate with the shuttle service first using:
-//!
-//! ```bash
-//! $Â cargo shuttle login
-//! ```
-//!
-//! This will open a browser window and prompt you to connect using your GitHub account.
-//!
-//! Before you can deploy, you have to create a project. This will start a deployer container for your
-//! project under the hood, ensuring isolation from other users' projects. PS. you don't have to do this
-//! now if you did in in the `cargo shuttle init` flow.
-//!
-//! ```bash
-//! $Â cargo shuttle project start
-//! ```
-//!
-//! Then, deploy the service with:
-//!
-//! ```bash
-//! $Â cargo shuttle deploy
-//! ```
-//!
-//! Your service will immediately be available at `{crate_name}.shuttleapp.rs`. For example:
-//!
-//! ```bash
-//! $ curl https://my-axum-app.shuttleapp.rs/
-//! Hello, world!
-//! ```
-//!
-//! ## Using `sqlx`
-//!
-//! Here is a quick example to deploy a rocket service that uses a postgres database and [sqlx](http://docs.rs/sqlx):
-//!
-//! Initialize a project with Rocket boilerplate:
-//! ```bash
-//! $ cargo shuttle init --template rocket my-rocket-app
-//! ```
-//!
-//! Add `shuttle-shared-db` as a dependency with the `postgres` feature, and add `sqlx` as a dependency with the
-//! `runtime-tokio-native-tls` and `postgres` features inside `Cargo.toml`:
-//!
-//! ```toml
-//! shuttle-shared-db = { version = "0.41.0", features = ["postgres"] }
-//! sqlx = "0.7.1"
-//! ```
-//!
-//! Now update the `#[shuttle_runtime::main]` function to take in a `PgPool`:
-//!
-//! ```rust,no_run
-//! #[macro_use]
-//! extern crate rocket;
-//!
-//! use rocket::State;
-//! use sqlx::PgPool;
-//! use shuttle_rocket::ShuttleRocket;
-//!
-//! struct MyState(PgPool);
-//!
-//! #[get("/")]
-//! fn hello(state: &State) -> &'static str {
-//! // Do things with `state.0`...
-//! "Hello, Postgres!"
-//! }
-//!
-//! #[shuttle_runtime::main]
-//! async fn rocket(#[shuttle_shared_db::Postgres] pool: PgPool) -> ShuttleRocket {
-//! let state = MyState(pool);
-//! let rocket = rocket::build().manage(state).mount("/", routes![hello]);
-//!
-//! Ok(rocket.into())
-//! }
-//! ```
-//!
-//! For a local run, shuttle will automatically provision a Postgres instance inside a [Docker](https://www.docker.com/) container on your machine and connect it to the `PgPool`.
-//!
-//! For deploys, shuttle will provision a database for your application and connect it to the `PgPool` on your behalf.
-//!
-//! To learn more about shuttle managed resources, see our [resource docs](https://docs.shuttle.rs/resources/shuttle-shared-db).
-//!
-//! ## Configuration
-//!
-//! The `cargo shuttle` command can be customized by creating a `Shuttle.toml` in the same location as your `Cargo.toml`.
-//!
-//! ##### Change the name of your service
-//!
-//! To have your service deployed with a different name, add a `name` entry in the `Shuttle.toml`:
-//!
-//! ```toml
-//! name = "hello-world"
-//! ```
-//!
-//! If the `name` key is not specified, the service's name will be the same as the crate's name.
-//!
-//! Alternatively, you can override the project name on the command-line, by passing the --name argument to any subcommand like so:
-//!
-//! ```bash
-//! $ cargo shuttle deploy --name=$PROJECT_NAME
-//! ```
-//!
-//! ##### Using Podman instead of Docker
-//! If you are using [Podman](https://podman.io/) instead of Docker, then `cargo shuttle run` will give
-//! `got unexpected error while inspecting docker container: error trying to connect: No such file or directory` error.
-//!
-//! To fix this error you will need to expose a rootless socket for Podman first. This can be done using:
-//!
-//! ```bash
-//! podman system service --time=0 unix:///tmp/podman.sock
-//! ```
-//!
-//! Now set the `DOCKER_HOST` environment variable to point to this socket using:
-//!
-//! ```bash
-//! export DOCKER_HOST=unix:///tmp/podman.sock
-//! ```
-//!
-//! Now all `cargo shuttle run` commands will work against Podman.
-//!
-//! ## Getting API keys
-//!
-//! After you've installed the [cargo-shuttle](https://docs.rs/crate/cargo-shuttle/latest) command, run:
-//!
-//! ```bash
-//! $ cargo shuttle login
-//! ```
-//!
-//! this will open a browser window and prompt you to connect using your GitHub account.
-//!
-//! ## Join Discord
-//!
-//! If you have any questions, [join our Discord server](https://discord.gg/shuttle). There's always someone on there that can help!
-//!
-//! You can also [open an issue or a discussion on GitHub](https://github.com/shuttle-hq/shuttle).
// Public API
pub use shuttle_codegen::main;
pub use shuttle_service::{
- CustomError, DbInput, Error, IntoResource, ResourceFactory, ResourceInputBuilder, Service,
+ CustomError, DbInput, DeploymentMetadata, Error, IntoResource, ResourceFactory,
+ ResourceInputBuilder, SecretStore, Service,
};
// Useful re-exports
@@ -218,6 +20,9 @@ mod args;
const NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");
+fn print_version() {
+ println!("{} {}", crate::NAME, crate::VERSION);
+}
// Not part of public API
#[doc(hidden)]
@@ -233,9 +38,83 @@ pub mod __internals {
pub use strfmt::strfmt;
#[cfg(feature = "setup-tracing")]
pub use tracing_subscriber;
+}
+
+pub use plugins::*;
+/// Built-in plugins
+mod plugins {
+ use crate::async_trait;
+ use shuttle_service::{
+ resource::{ProvisionResourceRequest, ShuttleResourceOutput, Type},
+ DeploymentMetadata, Error, ResourceFactory, ResourceInputBuilder, SecretStore,
+ };
+
+ /// ## Shuttle Metadata
+ ///
+ /// Plugin for getting various metadata at runtime.
+ ///
+ /// ### Usage
+ ///
+ /// ```rust,ignore
+ /// #[shuttle_runtime::main]
+ /// async fn main(
+ /// #[shuttle_runtime::Metadata] metadata: DeploymentMetadata,
+ /// ) -> __ { ... }
+ #[derive(Default)]
+ pub struct Metadata;
+
+ #[async_trait]
+ impl ResourceInputBuilder for Metadata {
+ type Input = DeploymentMetadata;
+ type Output = DeploymentMetadata;
+
+ async fn build(self, factory: &ResourceFactory) -> Result {
+ Ok(factory.get_metadata())
+ }
+ }
+
+ /// ## Shuttle Secrets
+ ///
+ /// Plugin for getting secrets in your [Shuttle](https://www.shuttle.rs) service.
+ ///
+ /// ### Usage
+ ///
+ /// Add a `Secrets.toml` file to the root of your crate with the secrets you'd like to store.
+ /// Make sure to add `Secrets*.toml` to `.gitignore` to omit your secrets from version control.
+ ///
+ /// Next, add `#[shuttle_runtime::Secrets] secrets: SecretStore` as a parameter to your `shuttle_service::main` function.
+ /// `SecretStore::get` can now be called to retrieve your API keys and other secrets at runtime.
+ ///
+ /// ### Example
+ ///
+ /// ```rust,ignore
+ /// #[shuttle_runtime::main]
+ /// async fn main(
+ /// #[shuttle_runtime::Secrets] secrets: SecretStore
+ /// ) -> ShuttleAxum {
+ /// // get secret defined in `Secrets.toml` file.
+ /// let secret = secrets.get("MY_API_KEY").unwrap();
+ ///
+ /// let router = Router::new()
+ /// .route("/", || async move { format!("My secret is: {}", secret) });
+ ///
+ /// Ok(router.into())
+ /// }
+ /// ```
+ #[derive(Default)]
+ pub struct Secrets;
+
+ #[async_trait]
+ impl ResourceInputBuilder for Secrets {
+ type Input = ProvisionResourceRequest;
+ type Output = ShuttleResourceOutput;
- // Print the version of the runtime.
- pub fn print_version() {
- println!("{} {}", crate::NAME, crate::VERSION);
+ async fn build(self, _factory: &ResourceFactory) -> Result {
+ Ok(ProvisionResourceRequest::new(
+ Type::Secrets,
+ serde_json::Value::Null,
+ serde_json::Value::Null,
+ ))
+ }
}
}
diff --git a/scripts/patches.toml b/scripts/patches.toml
index 0c9bc82073..b94c85fbaf 100644
--- a/scripts/patches.toml
+++ b/scripts/patches.toml
@@ -6,12 +6,10 @@ shuttle-runtime = { path = "BASE/runtime" }
shuttle-service = { path = "BASE/service" }
shuttle-aws-rds = { path = "BASE/resources/aws-rds" }
-shuttle-metadata = { path = "BASE/resources/metadata" }
shuttle-opendal = { path = "BASE/resources/opendal" }
shuttle-persist = { path = "BASE/resources/persist" }
shuttle-qdrant = { path = "BASE/resources/qdrant" }
shuttle-shared-db = { path = "BASE/resources/shared-db" }
-shuttle-secrets = { path = "BASE/resources/secrets" }
shuttle-turso = { path = "BASE/resources/turso" }
shuttle-axum = { path = "BASE/services/shuttle-axum" }
diff --git a/service/src/lib.rs b/service/src/lib.rs
index b7388e450f..c9c5b673cb 100644
--- a/service/src/lib.rs
+++ b/service/src/lib.rs
@@ -114,7 +114,7 @@ impl IntoResource for ShuttleResource
/// The core trait of the Shuttle platform. Every service deployed to Shuttle needs to implement this trait.
///
-/// An `Into` implementor is what is returned in the [`shuttle_runtime::main`] macro
+/// An `Into` implementor is what is returned in the `shuttle_runtime::main` macro
/// in order to run it on the Shuttle servers.
#[async_trait]
pub trait Service: Send {
diff --git a/services/shuttle-actix-web/README.md b/services/shuttle-actix-web/README.md
index 9176405e44..687e0365d4 100644
--- a/services/shuttle-actix-web/README.md
+++ b/services/shuttle-actix-web/README.md
@@ -1,4 +1,4 @@
-## Shuttle service integration for the Actix Web framework.
+## Shuttle service integration for the Actix Web framework
### Example
@@ -19,5 +19,4 @@ async fn actix_web() -> ShuttleActixWeb &'static str {
"Hello, world!"
@@ -18,5 +16,4 @@ async fn rocket() -> shuttle_rocket::ShuttleRocket {
Ok(rocket.into())
}
-# }
```
diff --git a/services/shuttle-salvo/README.md b/services/shuttle-salvo/README.md
index d3c81e35cb..53bae0baa6 100644
--- a/services/shuttle-salvo/README.md
+++ b/services/shuttle-salvo/README.md
@@ -1,4 +1,4 @@
-## Shuttle service integration for the Salvo web framework.
+## Shuttle service integration for the Salvo web framework
### Example
@@ -16,5 +16,4 @@ async fn salvo() -> shuttle_salvo::ShuttleSalvo {
Ok(router.into())
}
-
```
diff --git a/services/shuttle-serenity/Cargo.toml b/services/shuttle-serenity/Cargo.toml
index bcff870496..3f2e03dce4 100644
--- a/services/shuttle-serenity/Cargo.toml
+++ b/services/shuttle-serenity/Cargo.toml
@@ -13,12 +13,6 @@ serenity = { version = "0.12", default-features = false, features = ["client", "
serenity-0-11 = { package = "serenity", version = "0.11.7", default-features = false, features = ["client", "gateway", "model"], optional = true }
shuttle-runtime = { path = "../../runtime", version = "0.41.0", default-features = false }
-[dev-dependencies]
-anyhow = "1.0.69"
-shuttle-secrets = { path = "../../resources/secrets" }
-tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] }
-tracing = "0.1.37"
-
[features]
default = ["rustls_backend"]
diff --git a/services/shuttle-serenity/README.md b/services/shuttle-serenity/README.md
index 8cb362c25e..ca7cab99db 100644
--- a/services/shuttle-serenity/README.md
+++ b/services/shuttle-serenity/README.md
@@ -12,12 +12,12 @@ shuttle-serenity = { version = "0.41.0", default-features = false, features = ["
### Example
```rust,ignore
-use anyhow::anyhow;
+use anyhow::Context as _;
use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
use serenity::prelude::*;
-use shuttle_secrets::SecretStore;
+use shuttle_runtime::SecretStore;
use tracing::{error, info};
struct Bot;
@@ -39,14 +39,10 @@ impl EventHandler for Bot {
#[shuttle_runtime::main]
async fn serenity(
- #[shuttle_secrets::Secrets] secret_store: SecretStore,
+ #[shuttle_runtime::Secrets] secrets: SecretStore,
) -> shuttle_serenity::ShuttleSerenity {
// Get the discord token set in `Secrets.toml`
- let token = if let Some(token) = secret_store.get("DISCORD_TOKEN") {
- token
- } else {
- return Err(anyhow!("'DISCORD_TOKEN' was not found").into());
- };
+ let token = secrets.get("DISCORD_TOKEN").context("'DISCORD_TOKEN' was not found")?;
// Set gateway intents, which decides what events the bot will be notified about
let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT;
diff --git a/services/shuttle-thruster/README.md b/services/shuttle-thruster/README.md
index 699f928a0c..344d7027f9 100644
--- a/services/shuttle-thruster/README.md
+++ b/services/shuttle-thruster/README.md
@@ -1,4 +1,4 @@
-## Shuttle service integration for the Thruster web framework.
+## Shuttle service integration for the Thruster web framework
### Example
diff --git a/services/shuttle-tide/README.md b/services/shuttle-tide/README.md
index 5b443fc3f1..e4c54235c8 100644
--- a/services/shuttle-tide/README.md
+++ b/services/shuttle-tide/README.md
@@ -1,4 +1,4 @@
-## Shuttle service integration for the Tide web framework.
+## Shuttle service integration for the Tide web framework
### Example
diff --git a/services/shuttle-tower/README.md b/services/shuttle-tower/README.md
index 555f6efc01..c62a600e6c 100644
--- a/services/shuttle-tower/README.md
+++ b/services/shuttle-tower/README.md
@@ -1,4 +1,4 @@
-## Shuttle service integration for the Tower framework.
+## Shuttle service integration for the Tower framework
### Example
diff --git a/services/shuttle-warp/README.md b/services/shuttle-warp/README.md
index d1184ebe83..ed060a2419 100644
--- a/services/shuttle-warp/README.md
+++ b/services/shuttle-warp/README.md
@@ -1,4 +1,4 @@
-## Shuttle service integration for the Warp web framework.
+## Shuttle service integration for the Warp web framework
### Example