From fc135348c3c07e86c2290387761d9de0397483a7 Mon Sep 17 00:00:00 2001 From: Spencer Ferris <3319370+spencewenski@users.noreply.github.com> Date: Fri, 29 Mar 2024 01:12:32 -0700 Subject: [PATCH 1/2] Add a minimal example --- .github/workflows/ci.yml | 20 ++ examples/minimal/.gitignore | 211 ++++++++++++++++++ examples/minimal/Cargo.toml | 34 +++ examples/minimal/README.md | 13 ++ examples/minimal/config/default.toml | 17 ++ examples/minimal/config/development.toml | 8 + examples/minimal/config/test.toml | 8 + examples/minimal/entity/Cargo.toml | 12 + examples/minimal/entity/src/lib.rs | 1 + examples/minimal/migration/Cargo.toml | 22 ++ examples/minimal/migration/README.md | 41 ++++ examples/minimal/migration/src/lib.rs | 12 + .../src/m20220101_000001_create_table.rs | 15 ++ examples/minimal/migration/src/main.rs | 6 + examples/minimal/src/app.rs | 21 ++ examples/minimal/src/app_state.rs | 30 +++ examples/minimal/src/lib.rs | 2 + examples/minimal/src/main.rs | 10 + 18 files changed, 483 insertions(+) create mode 100644 examples/minimal/.gitignore create mode 100644 examples/minimal/Cargo.toml create mode 100644 examples/minimal/README.md create mode 100644 examples/minimal/config/default.toml create mode 100644 examples/minimal/config/development.toml create mode 100644 examples/minimal/config/test.toml create mode 100644 examples/minimal/entity/Cargo.toml create mode 100644 examples/minimal/entity/src/lib.rs create mode 100644 examples/minimal/migration/Cargo.toml create mode 100644 examples/minimal/migration/README.md create mode 100644 examples/minimal/migration/src/lib.rs create mode 100644 examples/minimal/migration/src/m20220101_000001_create_table.rs create mode 100644 examples/minimal/migration/src/main.rs create mode 100644 examples/minimal/src/app.rs create mode 100644 examples/minimal/src/app_state.rs create mode 100644 examples/minimal/src/lib.rs create mode 100644 examples/minimal/src/main.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff2400a0..026b48ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,3 +75,23 @@ jobs: - uses: actions/checkout@v4 - name: Formatting run: cargo fmt -- --check + + examples: + name: Examples + runs-on: ubuntu-latest + strategy: + matrix: + # Todo: Is there a way to generate this list automatically? + example: + - minimal + steps: + - uses: actions/checkout@v4 + - run: pushd examples/${{matrix.example}} + - name: Test + run: cargo test --no-fail-fast + - name: Check + run: cargo check + - name: Clippy + run: cargo clippy --no-deps -- -D warnings + - name: Formatting + run: cargo fmt -- --check diff --git a/examples/minimal/.gitignore b/examples/minimal/.gitignore new file mode 100644 index 00000000..bd145226 --- /dev/null +++ b/examples/minimal/.gitignore @@ -0,0 +1,211 @@ +# tmp files +*~* + +env*/ +/target +gen/ + +# Ignore Cargo.lock because this is a lib crate +Cargo.lock + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/examples/minimal/Cargo.toml b/examples/minimal/Cargo.toml new file mode 100644 index 00000000..0d0a99fc --- /dev/null +++ b/examples/minimal/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "minimal" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[workspace] +members = [".", "entity", "migration"] + +[dependencies] +roadster = { version = "0.1", path = "../.." } +tokio = { version = "1.35.1", features = ["full", "macros"] } +anyhow = "1.0.81" +tracing = { version = "0.1.40", features = ["async-await"] } +async-trait = "0.1.77" +aide = { version = "0.13.3", features = ["axum"] } +axum = "0.7.5" + +# DB +entity = { path = "entity" } +migration = { path = "migration" } + +[dev-dependencies] +cargo-husky = { version = "1.5.0", features = ["default", "run-cargo-check", "run-cargo-clippy", "run-cargo-fmt", "run-cargo-test"] } + +[[bin]] +name = "minimal" +path = "./src/main.rs" + +[lib] +name = "minimal" +path = "./src/lib.rs" + diff --git a/examples/minimal/README.md b/examples/minimal/README.md new file mode 100644 index 00000000..35305e2d --- /dev/null +++ b/examples/minimal/README.md @@ -0,0 +1,13 @@ +# Minimal Example + +# Running locally + +```shell +# Set the environment, example: +export ROADSTER.ENVIRONMENT=development +# Start the database and redis (for sidekiq). Note: change the credentials when deploying to prod +docker run -d -p 5432:5432 -e POSTGRES_USER=roadster -e POSTGRES_DB=minimal_dev -e POSTGRES_PASSWORD=roadster postgres:15.3-alpine +docker run -d -p 6379:6379 redis:7.2-alpine +# Start the app +cargo run +``` diff --git a/examples/minimal/config/default.toml b/examples/minimal/config/default.toml new file mode 100644 index 00000000..6a1cfe5a --- /dev/null +++ b/examples/minimal/config/default.toml @@ -0,0 +1,17 @@ +[app] +name = "Minimal Example" + +[server] +host = "127.0.0.1" +port = 3000 + +[tracing] +level = "debug" + +[database] +auto-migrate = true +connect-timeout = 5000 +acquire-timeout = 5000 +idle-timeout = 60 +min-connections = 0 +max-connections = 10 diff --git a/examples/minimal/config/development.toml b/examples/minimal/config/development.toml new file mode 100644 index 00000000..e94cc901 --- /dev/null +++ b/examples/minimal/config/development.toml @@ -0,0 +1,8 @@ +[auth.jwt] +secret = "secret-dev" + +[database] +uri = "postgres://roadster:roadster@localhost:5432/minimal_dev" + +[worker.sidekiq.redis] +uri = "redis://localhost:6379" diff --git a/examples/minimal/config/test.toml b/examples/minimal/config/test.toml new file mode 100644 index 00000000..0c14e3ba --- /dev/null +++ b/examples/minimal/config/test.toml @@ -0,0 +1,8 @@ +[auth.jwt] +secret = "secret-test" + +[database] +uri = "postgres://roadster:roadster@localhost:5433/minimal_test" + +[worker.sidekiq.redis] +uri = "redis://localhost:6380" \ No newline at end of file diff --git a/examples/minimal/entity/Cargo.toml b/examples/minimal/entity/Cargo.toml new file mode 100644 index 00000000..d2abf4fa --- /dev/null +++ b/examples/minimal/entity/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "entity" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +name = "entity" +path = "src/lib.rs" + +[dependencies] +sea-orm = "1.0.0-rc.2" \ No newline at end of file diff --git a/examples/minimal/entity/src/lib.rs b/examples/minimal/entity/src/lib.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/examples/minimal/entity/src/lib.rs @@ -0,0 +1 @@ + diff --git a/examples/minimal/migration/Cargo.toml b/examples/minimal/migration/Cargo.toml new file mode 100644 index 00000000..b7f3f2d3 --- /dev/null +++ b/examples/minimal/migration/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "migration" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[dependencies] +async-std = { version = "1", features = ["attributes", "tokio1"] } + +[dependencies.sea-orm-migration] +version = "1.0.0-rc.2" +features = [ + # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. + # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. + # e.g. + "runtime-tokio-rustls", # `ASYNC_RUNTIME` feature + "sqlx-postgres", # `DATABASE_DRIVER` feature +] diff --git a/examples/minimal/migration/README.md b/examples/minimal/migration/README.md new file mode 100644 index 00000000..3b438d89 --- /dev/null +++ b/examples/minimal/migration/README.md @@ -0,0 +1,41 @@ +# Running Migrator CLI + +- Generate a new migration file + ```sh + cargo run -- generate MIGRATION_NAME + ``` +- Apply all pending migrations + ```sh + cargo run + ``` + ```sh + cargo run -- up + ``` +- Apply first 10 pending migrations + ```sh + cargo run -- up -n 10 + ``` +- Rollback last applied migrations + ```sh + cargo run -- down + ``` +- Rollback last 10 applied migrations + ```sh + cargo run -- down -n 10 + ``` +- Drop all tables from the database, then reapply all migrations + ```sh + cargo run -- fresh + ``` +- Rollback all applied migrations, then reapply all migrations + ```sh + cargo run -- refresh + ``` +- Rollback all applied migrations + ```sh + cargo run -- reset + ``` +- Check the status of all migrations + ```sh + cargo run -- status + ``` diff --git a/examples/minimal/migration/src/lib.rs b/examples/minimal/migration/src/lib.rs new file mode 100644 index 00000000..2c605afb --- /dev/null +++ b/examples/minimal/migration/src/lib.rs @@ -0,0 +1,12 @@ +pub use sea_orm_migration::prelude::*; + +mod m20220101_000001_create_table; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![Box::new(m20220101_000001_create_table::Migration)] + } +} diff --git a/examples/minimal/migration/src/m20220101_000001_create_table.rs b/examples/minimal/migration/src/m20220101_000001_create_table.rs new file mode 100644 index 00000000..02dab03a --- /dev/null +++ b/examples/minimal/migration/src/m20220101_000001_create_table.rs @@ -0,0 +1,15 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} diff --git a/examples/minimal/migration/src/main.rs b/examples/minimal/migration/src/main.rs new file mode 100644 index 00000000..c6b6e48d --- /dev/null +++ b/examples/minimal/migration/src/main.rs @@ -0,0 +1,6 @@ +use sea_orm_migration::prelude::*; + +#[async_std::main] +async fn main() { + cli::run_cli(migration::Migrator).await; +} diff --git a/examples/minimal/src/app.rs b/examples/minimal/src/app.rs new file mode 100644 index 00000000..174ee956 --- /dev/null +++ b/examples/minimal/src/app.rs @@ -0,0 +1,21 @@ +// The RoadsterApp trait uses `AppContext`, so allow an exception in order to implement the trait. +#![allow(clippy::disallowed_types)] + +use aide::axum::ApiRouter; +use roadster::app::App as RoadsterApp; +use roadster::config::app_config::AppConfig; +use roadster::controller::default_routes; + +use crate::app_state::AppState; + +const BASE: &str = "/api"; + +#[derive(Default)] +pub struct App; +impl RoadsterApp for App { + type State = AppState; + + fn router(config: &AppConfig) -> ApiRouter { + default_routes(BASE, config) + } +} diff --git a/examples/minimal/src/app_state.rs b/examples/minimal/src/app_state.rs new file mode 100644 index 00000000..dbccbf2d --- /dev/null +++ b/examples/minimal/src/app_state.rs @@ -0,0 +1,30 @@ +// We need to use the disallowed `roadster::app_context::AppContext` type in this module in order +// to implement the required traits used to convert it to/from `AppState`. +#![allow(clippy::disallowed_types)] + +use std::sync::Arc; + +use roadster::app_context::AppContext; + +#[derive(Debug, Clone)] +pub struct AppState { + context: Arc, +} + +impl AppState { + pub fn new(ctx: Arc) -> Self { + Self { context: ctx } + } +} + +impl From> for AppState { + fn from(value: Arc) -> Self { + AppState::new(value) + } +} + +impl From for Arc { + fn from(value: AppState) -> Self { + value.context + } +} diff --git a/examples/minimal/src/lib.rs b/examples/minimal/src/lib.rs new file mode 100644 index 00000000..d59371d9 --- /dev/null +++ b/examples/minimal/src/lib.rs @@ -0,0 +1,2 @@ +pub mod app; +pub mod app_state; diff --git a/examples/minimal/src/main.rs b/examples/minimal/src/main.rs new file mode 100644 index 00000000..25451bcf --- /dev/null +++ b/examples/minimal/src/main.rs @@ -0,0 +1,10 @@ +use migration::Migrator; +use minimal::app::App; +use roadster::app; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + app::start::().await?; + + Ok(()) +} From f66b740dc896f18a35b54ef7573ad8e19d25c1db Mon Sep 17 00:00:00 2001 From: Spencer Ferris <3319370+spencewenski@users.noreply.github.com> Date: Fri, 29 Mar 2024 01:24:07 -0700 Subject: [PATCH 2/2] Set working dir for examples job --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 026b48ff..a93c2622 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,9 +84,11 @@ jobs: # Todo: Is there a way to generate this list automatically? example: - minimal + defaults: + run: + working-directory: ./examples/${{matrix.example}} steps: - uses: actions/checkout@v4 - - run: pushd examples/${{matrix.example}} - name: Test run: cargo test --no-fail-fast - name: Check