Setup CI (#14)

* add ci config

* fmt

* jsonwebtoken opt

* add clippy

* clippy fixes

* install postgres

* apt update

* -y

* path

* fix path

* fix

* no root

* sudo

* which

* path

* fmt

* env

* ls

* full path

* chown

* echo path

* more chown

* fix

* useradd

* x

* -r

* p

* env

* p

* a

* env

* t

* ls

* cat

* ls

* cp

* rustup

* copy

* c

* x

* cleanup
This commit is contained in:
Nutomic 2024-01-26 14:21:59 +01:00 committed by GitHub
parent d7d385c051
commit 117323a5e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 89 additions and 11 deletions

61
.woodpecker.yml Normal file
View File

@ -0,0 +1,61 @@
variables:
- &rust_image "rust:1.75"
steps:
cargo_fmt:
image: *rust_image
environment:
# store cargo data in repo folder so that it gets cached between steps
CARGO_HOME: .cargo_home
commands:
- rustup component add rustfmt
- cargo fmt -- --check
frontend_wasm_build:
image: *rust_image
environment:
CARGO_HOME: .cargo_home
commands:
- "rustup target add wasm32-unknown-unknown"
- "cargo check --target wasm32-unknown-unknown --features csr,hydrate --no-default-features"
check_diesel_schema:
image: willsquire/diesel-cli
environment:
CARGO_HOME: .cargo_home
DATABASE_URL: postgres://ibis:password@database:5432/ibis
commands:
- diesel migration run
- diesel print-schema --config-file=diesel.toml > tmp.schema
- diff tmp.schema src/backend/database/schema.rs
cargo_clippy:
image: *rust_image
environment:
CARGO_HOME: .cargo_home
commands:
- rustup component add clippy
- cargo clippy --tests --all-targets --all-features
cargo_test:
image: *rust_image
environment:
LEMMY_DATABASE_URL: postgres://ibis:password@database:5432/ibis
CARGO_HOME: .cargo_home
commands:
- apt-get update
- apt-get install postgresql sudo -y --no-install-recommends --no-install-suggests
# dbinit (used by tests to create temp db) refuses to run as root so we need to setup another user
- adduser testuser
- cp /usr/local/rustup /home/testuser/.rustup -r
- chown testuser:testuser . -R
- chown testuser:testuser /home/testuser -R
- export PATH="/usr/lib/postgresql/15/bin:/usr/local/cargo/bin:$PATH"
- sudo -u testuser env "PATH=$PATH" cargo test --no-fail-fast
services:
database:
image: postgres:15.2-alpine
environment:
POSTGRES_USER: ibis
POSTGRES_PASSWORD: password

View File

@ -15,7 +15,8 @@ ssr = [
"diesel_migrations", "diesel_migrations",
"tokio", "tokio",
"leptos_axum", "leptos_axum",
"activitypub_federation" "activitypub_federation",
"jsonwebtoken"
] ]
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"] csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"] hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
@ -48,7 +49,7 @@ enum_delegate = "0.2.0"
env_logger = { version = "0.10.1", default-features = false } env_logger = { version = "0.10.1", default-features = false }
futures = "0.3.29" futures = "0.3.29"
hex = "0.4.3" hex = "0.4.3"
jsonwebtoken = "9.2.0" jsonwebtoken = {version = "9.2.0", optional = true }
rand = "0.8.5" rand = "0.8.5"
serde_json = "1.0.108" serde_json = "1.0.108"
sha2 = "0.10.8" sha2 = "0.10.8"

View File

@ -42,6 +42,7 @@ pub fn generate_article_version(edits: &Vec<DbEdit>, version: &EditVersion) -> M
mod test { mod test {
use super::*; use super::*;
use activitypub_federation::fetch::object_id::ObjectId; use activitypub_federation::fetch::object_id::ObjectId;
use chrono::Utc;
use diffy::create_patch; use diffy::create_patch;
fn create_edits() -> MyResult<Vec<DbEdit>> { fn create_edits() -> MyResult<Vec<DbEdit>> {
@ -53,8 +54,10 @@ mod test {
hash: EditVersion::new(&diff)?, hash: EditVersion::new(&diff)?,
ap_id: ObjectId::parse("http://example.com")?, ap_id: ObjectId::parse("http://example.com")?,
diff, diff,
summary: String::new(),
article_id: 0, article_id: 0,
previous_version_id: Default::default(), previous_version_id: Default::default(),
created: Utc::now(),
}) })
}; };
Ok([ Ok([

View File

@ -50,7 +50,7 @@ pub fn EditArticle() -> impl IntoView {
); );
view! { view! {
<ArticleNav article=article.clone()/> <ArticleNav article=article/>
<Show <Show
when=move || edit_response.get().is_some() when=move || edit_response.get().is_some()
fallback=move || { fallback=move || {

View File

@ -10,7 +10,7 @@ pub fn ArticleHistory() -> impl IntoView {
let article = article_resource(title.unwrap()); let article = article_resource(title.unwrap());
view! { view! {
<ArticleNav article=article.clone()/> <ArticleNav article=article/>
<Suspense fallback=|| view! { "Loading..." }> { <Suspense fallback=|| view! { "Loading..." }> {
move || article.get().map(|article| { move || article.get().map(|article| {
let title = article.article.title; let title = article.article.title;

View File

@ -15,7 +15,7 @@ pub fn ReadArticle() -> impl IntoView {
let article = article_resource(title); let article = article_resource(title);
view! { view! {
<ArticleNav article=article.clone()/> <ArticleNav article=article/>
<Suspense fallback=|| view! { "Loading..." }> { <Suspense fallback=|| view! { "Loading..." }> {
let parser = markdown_parser(); let parser = markdown_parser();
move || article.get().map(|article| move || article.get().map(|article|

View File

@ -10,7 +10,7 @@ pub fn EditDiff() -> impl IntoView {
let article = article_resource(title); let article = article_resource(title);
view! { view! {
<ArticleNav article=article.clone()/> <ArticleNav article=article/>
<Suspense fallback=|| view! { "Loading..." }> { <Suspense fallback=|| view! { "Loading..." }> {
move || article.get().map(|article| { move || article.get().map(|article| {
let hash = params let hash = params

View File

@ -95,8 +95,8 @@ impl IbisInstance {
spawn(move || { spawn(move || {
Command::new("./tests/scripts/start_dev_db.sh") Command::new("./tests/scripts/start_dev_db.sh")
.arg(&db_path) .arg(&db_path)
.stdout(Stdio::null()) .stdout(Stdio::inherit())
.stderr(Stdio::null()) .stderr(Stdio::inherit())
.output() .output()
.unwrap(); .unwrap();
}) })

View File

@ -41,13 +41,15 @@ async fn test_create_read_and_edit_local_article() -> MyResult<()> {
// edit article // edit article
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "Lorem Ipsum 2".to_string(), new_text: "Lorem Ipsum 2\n".to_string(),
summary: "summary".to_string(),
previous_version_id: get_res.latest_version, previous_version_id: get_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
let edit_res = data.alpha.edit_article(&edit_form).await?; let edit_res = data.alpha.edit_article(&edit_form).await?;
assert_eq!(edit_form.new_text, edit_res.article.text); assert_eq!(edit_form.new_text, edit_res.article.text);
assert_eq!(2, edit_res.edits.len()); assert_eq!(2, edit_res.edits.len());
assert_eq!(edit_form.summary, edit_res.edits[1].summary);
let search_form = SearchArticleData { let search_form = SearchArticleData {
query: title.clone(), query: title.clone(),
@ -134,6 +136,7 @@ async fn test_synchronize_articles() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "Lorem Ipsum 2\n".to_string(), new_text: "Lorem Ipsum 2\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version, previous_version_id: create_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -197,7 +200,8 @@ async fn test_edit_local_article() -> MyResult<()> {
// edit the article // edit the article
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "Lorem Ipsum 2".to_string(), new_text: "Lorem Ipsum 2\n".to_string(),
summary: "summary".to_string(),
previous_version_id: get_res.latest_version, previous_version_id: get_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -262,7 +266,8 @@ async fn test_edit_remote_article() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: get_res.article.id, article_id: get_res.article.id,
new_text: "Lorem Ipsum 2".to_string(), new_text: "Lorem Ipsum 2\n".to_string(),
summary: "summary".to_string(),
previous_version_id: get_res.latest_version, previous_version_id: get_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -306,6 +311,7 @@ async fn test_local_edit_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "Lorem Ipsum\n".to_string(), new_text: "Lorem Ipsum\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version.clone(), previous_version_id: create_res.latest_version.clone(),
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -317,6 +323,7 @@ async fn test_local_edit_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "Ipsum Lorem\n".to_string(), new_text: "Ipsum Lorem\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version, previous_version_id: create_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -334,6 +341,7 @@ async fn test_local_edit_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "Lorem Ipsum and Ipsum Lorem\n".to_string(), new_text: "Lorem Ipsum and Ipsum Lorem\n".to_string(),
summary: "summary".to_string(),
previous_version_id: edit_res.previous_version_id, previous_version_id: edit_res.previous_version_id,
resolve_conflict_id: Some(edit_res.id), resolve_conflict_id: Some(edit_res.id),
}; };
@ -380,6 +388,7 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: get_res.article.id, article_id: get_res.article.id,
new_text: "Lorem Ipsum\n".to_string(), new_text: "Lorem Ipsum\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version.clone(), previous_version_id: create_res.latest_version.clone(),
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -397,6 +406,7 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: resolve_res.article.id, article_id: resolve_res.article.id,
new_text: "aaaa\n".to_string(), new_text: "aaaa\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version, previous_version_id: create_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -412,6 +422,7 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: resolve_res.article.id, article_id: resolve_res.article.id,
new_text: "aaaa\n".to_string(), new_text: "aaaa\n".to_string(),
summary: "summary".to_string(),
previous_version_id: conflicts[0].previous_version_id.clone(), previous_version_id: conflicts[0].previous_version_id.clone(),
resolve_conflict_id: Some(conflicts[0].id.clone()), resolve_conflict_id: Some(conflicts[0].id.clone()),
}; };
@ -442,6 +453,7 @@ async fn test_overlapping_edits_no_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "my\nexample\ntext\n".to_string(), new_text: "my\nexample\ntext\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version.clone(), previous_version_id: create_res.latest_version.clone(),
resolve_conflict_id: None, resolve_conflict_id: None,
}; };
@ -453,6 +465,7 @@ async fn test_overlapping_edits_no_conflict() -> MyResult<()> {
let edit_form = EditArticleData { let edit_form = EditArticleData {
article_id: create_res.article.id, article_id: create_res.article.id,
new_text: "some\nexample\narticle\n".to_string(), new_text: "some\nexample\narticle\n".to_string(),
summary: "summary".to_string(),
previous_version_id: create_res.latest_version, previous_version_id: create_res.latest_version,
resolve_conflict_id: None, resolve_conflict_id: None,
}; };