Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(templates): embed templates #35

Merged
merged 8 commits into from
Jan 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 112 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: Run Tests & Publishing

on: [push, pull_request]

permissions:
contents: write

jobs:
lint:
name: Lint Codebase
Expand All @@ -14,7 +17,7 @@ jobs:
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
targets: wasm32-unknown-unknown
components: clippy

- name: Restore Rust Cache
Expand All @@ -36,11 +39,118 @@ jobs:
- name: Setup Rust
uses: dtolnay/rust-toolchain@nightly
with:
targets: wasm32-unknown-unknown
targets: wasm32-unknown-unknown
components: rustfmt

- name: Restore Rust Cache
uses: Swatinem/rust-cache@v2

- name: Check Formatting
run: cargo +nightly fmt -- --unstable-features

check-templates:
name: Check Templates
runs-on: ubuntu-latest
steps:
- name: Checkout Project
uses: actions/checkout@v3
with:
path: stackable

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
components: clippy

- name: Restore Rust Cache
uses: Swatinem/rust-cache@v2

- name: Install Cargo Generate
run: cargo install cargo-generate

- name: Generate Template
run: |
cargo generate --path stackable/templates/fullstack \
--name template-fullstack-generated \
--define stackable_is_main=false \
--define stackable_is_release=false

- name: Add Stackable Crates
run: |
cargo add -p template-fullstack-generated-api \
--path ../stackable/crates/stackable-bridge

cargo add -p template-fullstack-generated-client \
--path ../stackable/crates/stackable-frontend

cargo add -p template-fullstack-generated-server \
--path ../stackable/crates/stackable-backend \
--features cli

cargo add -p template-fullstack-generated-view \
--path ../stackable/crates/stackable-frontend

cargo add -p template-fullstack-generated-view \
--path ../stackable/crates/stackable-bridge

cargo add -p stackctl \
--path ../stackable/crates/stackable-cli
working-directory: template-fullstack-generated

- name: Run Lints
run: |
cargo clippy --bin stackctl
cargo clippy --bin template-fullstack-generated-client
cargo clippy --bin template-fullstack-generated-server
working-directory: template-fullstack-generated

publish-templates:
name: Publish Templates
runs-on: ubuntu-latest
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))
needs: check-templates
steps:
- name: Checkout Project
uses: actions/checkout@v3

- name: Read Stackable Version
if: startsWith(github.ref, 'refs/tags/')
run: |
STACKABLE_VER=$(echo '${{ github.ref_name }}' | sed 's/v0*//')
echo "Current version: $STACKABLE_VER"

echo "STACKABLE_VER=$(echo '${{ github.ref_name }}' | sed 's/v0*//')" >> $GITHUB_ENV

- name: Set Stackable Target to 'main'
if: github.ref == 'refs/heads/main'
run: |
echo 'variable::set("stackable_target", "main");' >> templates/fullstack/resolve-crates.rhai

- name: Set Stackable Target to 'release'
if: startsWith(github.ref, 'refs/tags/')
run: |
echo 'variable::set("stackable_target", "release");' >> templates/fullstack/resolve-crates.rhai

- name: Set Stackable Version
if: startsWith(github.ref, 'refs/tags/')
run: |
echo 'variable::set("stackable_release_ver", "${{ env.STACKABLE_VER }}");' >> templates/fullstack/resolve-crates.rhai

- name: Publish Main Templates
if: github.ref == 'refs/heads/main'
uses: s0/git-publish-subdir-action@v2.6.0
env:
REPO: self
BRANCH: templates-main
FOLDER: templates
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Publish Release Templates
if: startsWith(github.ref, 'refs/tags/')
uses: s0/git-publish-subdir-action@v2.6.0
env:
REPO: self
BRANCH: templates
FOLDER: templates
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@

# These are backup files generated by rustfmt
**/*.rs.bk

# Visual Studio Code
.vscode/
2 changes: 1 addition & 1 deletion crates/stackable-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! When the `resolvable` feature is enabled, it will require query and mutations to implement their
//! resolver type which is responsible for resolving the request.
//!
//! You can check out the [example](https://github.com/futursolo/stackable/blob/master/examples/fullstack/api/src/lib.rs) for how to implement resolvers.
//! You can check out the [example](https://github.com/futursolo/stackable/blob/main/examples/fullstack/api/src/lib.rs) for how to implement resolvers.

#![deny(clippy::all)]
#![deny(missing_debug_implementations)]
Expand Down
14 changes: 14 additions & 0 deletions templates/fullstack/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Cargo
# will have compiled files and executables
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# Stackable artifacts
.stackable/
build/
11 changes: 11 additions & 0 deletions templates/fullstack/Cargo.toml.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[workspace]
members = [
"crates/*",
]
resolver = "2"

[profile.release]
lto = true
codegen-units = 1
panic = "abort"
opt-level = "z"
18 changes: 18 additions & 0 deletions templates/fullstack/Makefile.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true

# stackctl
[tasks.stackctl]
workspace = false
command = "cargo"
args = ["run", "--bin", "stackctl", "--", "${@}"]

[tasks.start]
workspace = false
command = "cargo"
args = ["run", "--bin", "stackctl", "--", "serve", "--open"]

[tasks.build]
workspace = false
command = "cargo"
args = ["run", "--bin", "stackctl", "--", "build", "--release"]
8 changes: 8 additions & 0 deletions templates/fullstack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Getting Started with Stackable

This project is created with Stackable.

# Available Commands

To start the development server, use `cargo make start`.
To build a release distribuation, use `cargo make build`.
5 changes: 5 additions & 0 deletions templates/fullstack/cargo-generate.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[template]
cargo_generate_version = ">=0.9.0"

[hooks]
init = ["resolve-crates.rhai"]
8 changes: 8 additions & 0 deletions templates/fullstack/crates/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Files generated by Cargo
target/

# These are backup files generated by rustfmt
**/*.rs.bk

# Files created by Stackable
.stackable/
25 changes: 25 additions & 0 deletions templates/fullstack/crates/api/Cargo.toml.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "{{ project-name }}-api"
version = "0.1.0"
edition = "2021"
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
time = { version = "0.3", features = ["wasm-bindgen", "serde-human-readable"] }
serde = { version = "1", features = ["derive"] }
async-trait = "0.1.59"
thiserror = "1"
{% if stackable_target == "release" %}
# Stackable
stackable-bridge = "{{ stackable_release_ver }}"

{% elsif stackable_target == "main" %}
# Stackable
stackable-bridge = { git = "https://github.com/futursolo/stackable" }

{% endif %}

[features]
resolvable = ["stackable-bridge/resolvable"]
17 changes: 17 additions & 0 deletions templates/fullstack/crates/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![deny(clippy::all)]
#![deny(missing_debug_implementations)]

mod types;
pub use types::*;

#[cfg(feature = "resolvable")]
mod resolvers;

use stackable_bridge::Bridge;

pub fn create_bridge() -> Bridge {
Bridge::builder()
.add_query::<ServerTimeQuery>()
.add_mutation::<GreetingMutation>()
.build()
}
31 changes: 31 additions & 0 deletions templates/fullstack/crates/api/src/resolvers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use async_trait::async_trait;
use stackable_bridge::resolvers::{MutationResolver, QueryResolver};
use stackable_bridge::types::{MutationResult, QueryResult};
use stackable_bridge::BridgeMetadata;
use time::OffsetDateTime;

use crate::types::*;

#[async_trait(?Send)]
impl QueryResolver for ServerTimeQuery {
type Context = ();

async fn resolve(_metadata: &BridgeMetadata<()>, _input: &Self::Input) -> QueryResult<Self> {
Ok(Self {
value: OffsetDateTime::now_utc(),
}
.into())
}
}

#[async_trait(?Send)]
impl MutationResolver for GreetingMutation {
type Context = ();

async fn resolve(_metadata: &BridgeMetadata<()>, name: &Self::Input) -> MutationResult<Self> {
Ok(Self {
message: format!("Hello, {name}!"),
}
.into())
}
}
38 changes: 38 additions & 0 deletions templates/fullstack/crates/api/src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use serde::{Deserialize, Serialize};
use stackable_bridge::types::{BridgedMutation, BridgedQuery};
use thiserror::Error;
use time::OffsetDateTime;

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ServerTimeQuery {
pub value: OffsetDateTime,
}

#[derive(Debug, Error, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub enum Error {
#[error("failed to communicate with server.")]
Network,
}

impl BridgedQuery for ServerTimeQuery {
type Error = Error;
type Input = ();

fn into_query_error(_e: stackable_bridge::BridgeError) -> Self::Error {
Error::Network
}
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct GreetingMutation {
pub message: String,
}

impl BridgedMutation for GreetingMutation {
type Error = Error;
type Input = String;

fn into_mutation_error(_e: stackable_bridge::BridgeError) -> Self::Error {
Error::Network
}
}
29 changes: 29 additions & 0 deletions templates/fullstack/crates/client/Cargo.toml.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "{{project-name}}-client"
version = "0.1.0"
edition = "2021"
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
yew = "0.20.0"
gloo = "0.8"

{% if stackable_target == "release" %}
# Stackable
stackable-frontend = "{{stackable_release_ver}}"

{% elsif stackable_target == "main" %}
# Stackable
stackable-frontend = { git = "https://github.com/futursolo/stackable" }

{% endif %}
# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3.16", default-features = false, features = ["time", "std", "fmt", "ansi"] }

# Example Workspace
{{project-name}}-view = { path = "../view" }
{{project-name}}-api = { path = "../api" }

10 changes: 10 additions & 0 deletions templates/fullstack/crates/client/src/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use yew::prelude::*;

use crate::view::Main;

#[function_component]
pub fn App() -> Html {
html! {
<Main />
}
}
Loading