From e1655edd83893946cace9a44efb979a7357736b6 Mon Sep 17 00:00:00 2001 From: Jade Ellis <jade@ellis.link> Date: Fri, 25 Apr 2025 02:47:48 +0100 Subject: [PATCH 1/6] feat: HTML default page --- .dockerignore | 2 +- .forgejo/workflows/release-image.yml | 3 + Cargo.lock | 64 ++++++++++++++++ Cargo.toml | 5 ++ docker/Dockerfile | 106 +++++++++++++++++++++++++-- nix/pkgs/main/default.nix | 2 + src/router/Cargo.toml | 1 + src/router/router.rs | 6 +- src/web/Cargo.toml | 32 ++++++++ src/web/css/index.css | 68 +++++++++++++++++ src/web/mod.rs | 61 +++++++++++++++ src/web/templates/_layout.html.j2 | 32 ++++++++ src/web/templates/error.html.j2 | 20 +++++ src/web/templates/index.html.j2 | 16 ++++ 14 files changed, 408 insertions(+), 10 deletions(-) create mode 100644 src/web/Cargo.toml create mode 100644 src/web/css/index.css create mode 100644 src/web/mod.rs create mode 100644 src/web/templates/_layout.html.j2 create mode 100644 src/web/templates/error.html.j2 create mode 100644 src/web/templates/index.html.j2 diff --git a/.dockerignore b/.dockerignore index 453634df..8ca2e3f8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,7 +11,7 @@ docker/ *.iml # Git folder -.git +# .git .gitea .gitlab .github diff --git a/.forgejo/workflows/release-image.yml b/.forgejo/workflows/release-image.yml index 141bfef9..3eb84223 100644 --- a/.forgejo/workflows/release-image.yml +++ b/.forgejo/workflows/release-image.yml @@ -144,6 +144,9 @@ jobs: file: "docker/Dockerfile" build-args: | CONDUWUIT_VERSION_EXTRA=${{ env.COMMIT_SHORT_SHA }} + COMMIT_SHA=${{ github.sha }}) + REMOTE_URL=${{github.event.repository.html_url }} + REMOTE_COMMIT_URL=${{github.event.head_commit.url }} platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} annotations: ${{ steps.meta.outputs.annotations }} diff --git a/Cargo.lock b/Cargo.lock index 2d8a2d0f..1b6c5d26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,48 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a" +[[package]] +name = "askama" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash 2.1.1", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + [[package]] name = "assign" version = "1.1.1" @@ -415,6 +457,15 @@ version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.69.5" @@ -904,6 +955,7 @@ dependencies = [ "conduwuit_api", "conduwuit_core", "conduwuit_service", + "conduwuit_web", "const-str", "futures", "http", @@ -961,6 +1013,18 @@ dependencies = [ "webpage", ] +[[package]] +name = "conduwuit_web" +version = "0.5.0-rc.5" +dependencies = [ + "askama", + "axum", + "futures", + "rand 0.8.5", + "thiserror 2.0.12", + "tracing", +] + [[package]] name = "console-api" version = "0.8.1" diff --git a/Cargo.toml b/Cargo.toml index 1ce5c1db..44db4c4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -626,6 +626,11 @@ package = "conduwuit_macros" path = "src/macros" default-features = false +[workspace.dependencies.conduwuit-web] +package = "conduwuit_web" +path = "src/web" +default-features = false + ############################################################################### # # Release profiles diff --git a/docker/Dockerfile b/docker/Dockerfile index 536af632..56f2d5fa 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -111,14 +111,112 @@ RUN mkdir /out FROM toolchain AS builder + +# Get source +COPY . . + # Conduwuit version info ARG COMMIT_SHA= +ARG SHORT_COMMIT_SHA= +ARG REMOTE_URL= ARG CONDUWUIT_VERSION_EXTRA= +ENV COMMIT_SHA=$COMMIT_SHA +ENV SHORT_COMMIT_SHA=$SHORT_COMMIT_SHA +ENV REMOTE_URL=$REMOTE_URL ENV CONDUWUIT_VERSION_EXTRA=$CONDUWUIT_VERSION_EXTRA -RUN <<EOF -if [ -z "${CONDUWUIT_VERSION_EXTRA}" ]; then - echo "CONDUWUIT_VERSION_EXTRA='$(set -e; git rev-parse --short ${COMMIT_SHA:-HEAD} || echo unknown revision)'" >> /etc/environment + +# Calculate version info from git if not provided via ARGs +# and write all relevant vars to /etc/environment +RUN <<'EOF' +set -e # Exit on error + +# Use temp variables to store calculated values +calculated_commit_sha="" +calculated_remote_url="" +calculated_version_extra="" + +# --- COMMIT_SHA --- +# Calculate COMMIT_SHA if ENV var (from ARG) is empty +if [ -z "${COMMIT_SHA}" ]; then + # Try to get short commit hash from git + calculated_commit_sha=$(git rev-parse HEAD 2>/dev/null || echo "") + if [ -n "${calculated_commit_sha}" ]; then + echo "COMMIT_SHA='${calculated_commit_sha}'" >> /etc/environment + fi +else + # Ensure ARG-provided value is in /etc/environment + echo "COMMIT_SHA='${COMMIT_SHA}'" >> /etc/environment fi + + +if [ -z "${SHORT_COMMIT_SHA}" ]; then + # Try to get short commit hash from git + calculated_short_commit_sha=$(git rev-parse --short HEAD 2>/dev/null || echo "") + if [ -n "${calculated_short_commit_sha}" ]; then + echo "SHORT_COMMIT_SHA='${calculated_short_commit_sha}'" >> /etc/environment + fi +else + # Ensure ARG-provided value is in /etc/environment + echo "SHORT_COMMIT_SHA='${SHORT_COMMIT_SHA}'" >> /etc/environment +fi + +# --- REMOTE_URL --- +# Calculate REMOTE_URL if ENV var (from ARG) is empty +if [ -z "${REMOTE_URL}" ]; then + # Try to get remote origin URL from git + remote_url_raw=$(git config --get remote.origin.url 2>/dev/null || echo "") + if [ -n "${remote_url_raw}" ]; then + # Transform git URL (SSH or HTTPS) to web URL + if [[ $remote_url_raw == "https://"* ]]; then + # Already HTTPS, just remove .git suffix + calculated_remote_url=$(echo "$remote_url_raw" | sed 's/\.git$//') + else + # Convert SSH URL to HTTPS URL + calculated_remote_url=$(echo "$remote_url_raw" | sed 's/\.git$//' | sed 's/:/\//' | sed 's/^git@/https:\/\//') + fi + + # Write calculated web URL if transformation was successful + if [ -n "${calculated_remote_url}" ]; then + echo "REMOTE_URL='${calculated_remote_url}'" >> /etc/environment + fi + fi +else + # Ensure ARG-provided value is in /etc/environment (assume it's a valid web URL) + echo "REMOTE_URL='${REMOTE_URL}'" >> /etc/environment + # Use provided value for REMOTE_COMMIT_URL calculation below + calculated_remote_url="${REMOTE_URL}" +fi + +# --- Determine effective values for subsequent calculations --- +# Use ENV var value if set (from ARG), otherwise use calculated value +effective_commit_sha="${COMMIT_SHA:-$calculated_commit_sha}" +effective_short_commit_sha="${SHORT_COMMIT_SHA:-$calculated_short_commit_sha}" +effective_remote_url="${REMOTE_URL:-$calculated_remote_url}" + +# --- REMOTE_COMMIT_URL --- +# Calculate and write REMOTE_COMMIT_URL if both components are available +if [ -z "${REMOTE_COMMIT_URL}" ] && [ -n "${effective_remote_url}" ] && [ -n "${effective_commit_sha}" ]; then + echo "REMOTE_COMMIT_URL='${effective_remote_url}/commit/${effective_commit_sha}'" >> /etc/environment +else + # Ensure ARG-provided value is in /etc/environment + echo "REMOTE_COMMIT_URL='${REMOTE_COMMIT_URL}'" >> /etc/environment +fi + +# --- CONDUWUIT_VERSION_EXTRA --- +# Calculate CONDUWUIT_VERSION_EXTRA if ENV var (from ARG) is empty +if [ -z "${CONDUWUIT_VERSION_EXTRA}" ]; then + # Use the effective short commit sha, fallback to "unknown revision" + calculated_version_extra="${effective_short_commit_sha:-unknown revision}" + # Handle case where commit sha calculation failed and ARG wasn't set + if [ -z "${calculated_version_extra}" ]; then + calculated_version_extra="unknown revision" + fi + echo "CONDUWUIT_VERSION_EXTRA='${calculated_version_extra}'" >> /etc/environment +else + # Ensure ARG-provided value is in /etc/environment + echo "CONDUWUIT_VERSION_EXTRA='${CONDUWUIT_VERSION_EXTRA}'" >> /etc/environment +fi + EOF ARG TARGETPLATFORM @@ -127,8 +225,6 @@ ARG TARGETPLATFORM RUN cat /etc/environment RUN xx-cargo --print-target-triple -# Get source -COPY . . # Build the binary RUN --mount=type=cache,target=/usr/local/cargo/registry \ diff --git a/nix/pkgs/main/default.nix b/nix/pkgs/main/default.nix index 9c8038a7..3a43af5a 100644 --- a/nix/pkgs/main/default.nix +++ b/nix/pkgs/main/default.nix @@ -130,6 +130,8 @@ buildDepsOnlyEnv = }); buildPackageEnv = { + COMMIT_SHA = inputs.self.rev or inputs.self.dirtyRev or ""; + SHORT_COMMIT_SHA = inputs.self.shortRev or inputs.self.dirtyShortRev or ""; CONDUWUIT_VERSION_EXTRA = inputs.self.shortRev or inputs.self.dirtyShortRev or ""; } // buildDepsOnlyEnv // { # Only needed in static stdenv because these are transitive dependencies of rocksdb diff --git a/src/router/Cargo.toml b/src/router/Cargo.toml index e4ddcb9b..9fcb8d6a 100644 --- a/src/router/Cargo.toml +++ b/src/router/Cargo.toml @@ -103,6 +103,7 @@ conduwuit-admin.workspace = true conduwuit-api.workspace = true conduwuit-core.workspace = true conduwuit-service.workspace = true +conduwuit-web.workspace = true const-str.workspace = true futures.workspace = true http.workspace = true diff --git a/src/router/router.rs b/src/router/router.rs index 0f95b924..2b9ce2ec 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use axum::{Router, response::IntoResponse, routing::get}; +use axum::{Router, response::IntoResponse}; use conduwuit::Error; use conduwuit_api::router::{state, state::Guard}; use conduwuit_service::Services; @@ -11,7 +11,7 @@ pub(crate) fn build(services: &Arc<Services>) -> (Router, Guard) { let router = Router::<state::State>::new(); let (state, guard) = state::create(services.clone()); let router = conduwuit_api::router::build(router, &services.server) - .route("/", get(it_works)) + .merge(conduwuit_web::build::<state::State>().with_state(())) .fallback(not_found) .with_state(state); @@ -21,5 +21,3 @@ pub(crate) fn build(services: &Arc<Services>) -> (Router, Guard) { async fn not_found(_uri: Uri) -> impl IntoResponse { Error::Request(ErrorKind::Unrecognized, "Not Found".into(), StatusCode::NOT_FOUND) } - -async fn it_works() -> &'static str { "hewwo from conduwuit woof!" } diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml new file mode 100644 index 00000000..07dde0f7 --- /dev/null +++ b/src/web/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "conduwuit_web" +categories.workspace = true +description.workspace = true +edition.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +version.workspace = true + +[lib] +path = "mod.rs" +crate-type = [ + "rlib", +# "dylib", +] + +[features] + + +[dependencies] +askama = "0.14.0" + +axum.workspace = true +futures.workspace = true +tracing.workspace = true +rand.workspace = true +thiserror.workspace = true + +[lints] +workspace = true diff --git a/src/web/css/index.css b/src/web/css/index.css new file mode 100644 index 00000000..86cb6d8d --- /dev/null +++ b/src/web/css/index.css @@ -0,0 +1,68 @@ +:root { + color-scheme: light; + --font-stack: sans-serif; + + --background-color: #fff; + --text-color: #000; + + --bg: oklch(0.76 0.0854 317.27); + --panel-bg: oklch(0.91 0.042 317.27); + + --name-lightness: 0.45; + + @media (prefers-color-scheme: dark) { + color-scheme: dark; + --text-color: #fff; + --bg: oklch(0.15 0.042 317.27); + --panel-bg: oklch(0.24 0.03 317.27); + + --name-lightness: 0.8; + } + + --c1: oklch(0.44 0.177 353.06); + --c2: oklch(0.59 0.158 150.88); + + --normal-font-size: 1rem; + --small-font-size: 0.8rem; +} + +body { + color: var(--text-color); + font-family: var(--font-stack); + margin: 0; + padding: 0; + display: grid; + place-items: center; + min-height: 100vh; +} + +html { + background-color: var(--bg); + background-image: linear-gradient( + 70deg, + oklch(from var(--bg) l + 0.2 c h), + oklch(from var(--bg) l - 0.2 c h) + ); + font-size: 16px; +} + +.panel { + width: min(clamp(24rem, 12rem + 40vw, 48rem), 100vw); + border-radius: 15px; + background-color: var(--panel-bg); + padding-inline: 1.5rem; + padding-block: 1rem; + box-shadow: 0 0.25em 0.375em hsla(0, 0%, 0%, 0.1); +} + +.project-name { + text-decoration: none; + background: linear-gradient( + 130deg, + oklch(from var(--c1) var(--name-lightness) c h), + oklch(from var(--c2) var(--name-lightness) c h) + ); + background-clip: text; + color: transparent; + filter: brightness(1.2); +} diff --git a/src/web/mod.rs b/src/web/mod.rs new file mode 100644 index 00000000..ddf13be4 --- /dev/null +++ b/src/web/mod.rs @@ -0,0 +1,61 @@ +use askama::Template; +use axum::{ + Router, + http::{StatusCode, header}, + response::{Html, IntoResponse, Response}, + routing::get, +}; + +pub fn build<S>() -> Router<()> { Router::new().route("/", get(index_handler)) } + +async fn index_handler() -> Result<impl IntoResponse, WebError> { + #[derive(Debug, Template)] + #[template(path = "index.html.j2")] + struct Tmpl<'a> { + nonce: &'a str, + } + let nonce = rand::random::<u64>().to_string(); + + let template = Tmpl { nonce: &nonce }; + Ok(( + [(header::CONTENT_SECURITY_POLICY, format!("default-src 'none' 'nonce-{nonce}';"))], + Html(template.render()?), + )) +} + +#[derive(Debug, thiserror::Error)] +enum WebError { + #[error("Failed to render template: {0}")] + Render(#[from] askama::Error), +} + +impl IntoResponse for WebError { + fn into_response(self) -> Response { + #[derive(Debug, Template)] + #[template(path = "error.html.j2")] + struct Tmpl<'a> { + nonce: &'a str, + err: WebError, + } + + let nonce = rand::random::<u64>().to_string(); + + let status = match &self { + | Self::Render(_) => StatusCode::INTERNAL_SERVER_ERROR, + }; + let tmpl = Tmpl { nonce: &nonce, err: self }; + if let Ok(body) = tmpl.render() { + ( + status, + [( + header::CONTENT_SECURITY_POLICY, + format!("default-src 'none' 'nonce-{nonce}';"), + )], + Html(body), + ) + .into_response() + } else { + (status, "Something went wrong").into_response() + } + } +} diff --git a/src/web/templates/_layout.html.j2 b/src/web/templates/_layout.html.j2 new file mode 100644 index 00000000..a38745e1 --- /dev/null +++ b/src/web/templates/_layout.html.j2 @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8" /> + <title>{% block title %}Continuwuity{% endblock %}</title> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + + <style type="text/css" nonce="{{ nonce }}"> + /*<![CDATA[*/ + {{ include_str !("css/index.css") | safe }} + /*]]>*/ + </style> +</head> + +<body> + <main>{%~ block content %}{% endblock ~%}</main> + {%~ block footer ~%} + <footer> + <p>Powered by <a href="https://continuwuity.org">Continuwuity</a> + {%~ if let Some(version_info) = option_env!("CONDUWUIT_VERSION_EXTRA").or(option_env!("SHORT_COMMIT_SHA")) ~%} + {%~ if let Some(url) = option_env!("REMOTE_COMMIT_URL").or(option_env!("REMOTE_URL")) ~%} + (<a href="{{ url }}">{{ version_info }}</a>) + {%~ else ~%} + ({{ version_info }}) + {%~ endif ~%} + {%~ endif ~%}</p> + </footer> + {%~ endblock ~%} +</body> + +</html> diff --git a/src/web/templates/error.html.j2 b/src/web/templates/error.html.j2 new file mode 100644 index 00000000..e320d0ed --- /dev/null +++ b/src/web/templates/error.html.j2 @@ -0,0 +1,20 @@ +{% extends "_layout.html.j2" %} + +{%- block title -%} +Server Error +{%- endblock -%} + +{%- block content -%} +<h1> + {%- match err -%} + {% else -%} 500: Internal Server Error + {%- endmatch -%} +</h1> + +{%- match err -%} + {% when WebError::Render(err) -%} + <pre>{{ err }}</pre> + {% else -%} <p>An error occurred</p> +{%- endmatch -%} + +{%- endblock -%} diff --git a/src/web/templates/index.html.j2 b/src/web/templates/index.html.j2 new file mode 100644 index 00000000..51393822 --- /dev/null +++ b/src/web/templates/index.html.j2 @@ -0,0 +1,16 @@ +{% extends "_layout.html.j2" %} +{%- block content -%} +<div class="orb"></div> +<div class="panel"> + <h1>Welcome to <a class="project-name" href="https://continuwuity.org">Continuwuity</a>!</h1> + <p>Continuwuity is successfully installed and working. </p> + <p>To get started, you can:</p> + <ul> + <li>Read the <a href="https://continuwuity.org/introduction">documentation</a></li> + <li>Join the <a href="https://continuwuity.org/community">community</a></li> + <li>Log in with a <a href="https://matrix.org/ecosystem/clients/">client</a></li> + <li>Ensure <a href="https://federationtester.matrix.org/">federation</a> works</li> + </ul> +</div> + +{%- endblock content -%} From a98da7d9422500de592824eee0f441bc94803065 Mon Sep 17 00:00:00 2001 From: Jade Ellis <jade@ellis.link> Date: Thu, 1 May 2025 00:38:35 +0100 Subject: [PATCH 2/6] refactor: Move git version info gather in into a build script --- .forgejo/workflows/release-image.yml | 8 +- Cargo.lock | 44 ++++++++++ Cargo.toml | 6 ++ docker/Dockerfile | 118 ++++----------------------- nix/pkgs/main/default.nix | 5 +- src/api/client/message.rs | 5 +- src/build_metadata/Cargo.toml | 34 ++++++++ src/build_metadata/build.rs | 92 +++++++++++++++++++++ src/build_metadata/mod.rs | 23 ++++++ src/core/Cargo.toml | 1 + src/core/info/version.rs | 11 +-- src/web/Cargo.toml | 2 + src/web/mod.rs | 1 + src/web/templates/_layout.html.j2 | 4 +- 14 files changed, 231 insertions(+), 123 deletions(-) create mode 100644 src/build_metadata/Cargo.toml create mode 100644 src/build_metadata/build.rs create mode 100644 src/build_metadata/mod.rs diff --git a/.forgejo/workflows/release-image.yml b/.forgejo/workflows/release-image.yml index 3eb84223..de009ad5 100644 --- a/.forgejo/workflows/release-image.yml +++ b/.forgejo/workflows/release-image.yml @@ -143,10 +143,10 @@ jobs: context: . file: "docker/Dockerfile" build-args: | - CONDUWUIT_VERSION_EXTRA=${{ env.COMMIT_SHORT_SHA }} - COMMIT_SHA=${{ github.sha }}) - REMOTE_URL=${{github.event.repository.html_url }} - REMOTE_COMMIT_URL=${{github.event.head_commit.url }} + GIT_COMMIT_HASH=${{ github.sha }}) + GIT_COMMIT_HASH_SHORT=${{ env.COMMIT_SHORT_SHA }}) + GIT_REMOTE_URL=${{github.event.repository.html_url }} + GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }} platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} annotations: ${{ steps.meta.outputs.annotations }} diff --git a/Cargo.lock b/Cargo.lock index 1b6c5d26..5f82384e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -584,6 +584,9 @@ name = "built" version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" +dependencies = [ + "cargo-lock", +] [[package]] name = "bumpalo" @@ -631,6 +634,19 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "cargo-lock" +version = "10.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06acb4f71407ba205a07cb453211e0e6a67b21904e47f6ba1f9589e38f2e454" +dependencies = [ + "petgraph", + "semver", + "serde", + "toml", + "url", +] + [[package]] name = "cargo_toml" version = "0.21.0" @@ -856,6 +872,13 @@ dependencies = [ "tracing", ] +[[package]] +name = "conduwuit_build_metadata" +version = "0.5.0-rc.5" +dependencies = [ + "built", +] + [[package]] name = "conduwuit_core" version = "0.5.0-rc.5" @@ -870,6 +893,7 @@ dependencies = [ "checked_ops", "chrono", "clap", + "conduwuit_build_metadata", "conduwuit_macros", "const-str", "core_affinity", @@ -1019,6 +1043,7 @@ version = "0.5.0-rc.5" dependencies = [ "askama", "axum", + "conduwuit_build_metadata", "futures", "rand 0.8.5", "thiserror 2.0.12", @@ -1515,6 +1540,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.1.1" @@ -3132,6 +3163,16 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap 2.8.0", +] + [[package]] name = "phf" version = "0.11.3" @@ -4127,6 +4168,9 @@ name = "semver" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +dependencies = [ + "serde", +] [[package]] name = "sentry" diff --git a/Cargo.toml b/Cargo.toml index 44db4c4b..43cd3f4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -631,6 +631,12 @@ package = "conduwuit_web" path = "src/web" default-features = false + +[workspace.dependencies.conduwuit-build-metadata] +package = "conduwuit_build_metadata" +path = "src/build_metadata" +default-features = false + ############################################################################### # # Release profiles diff --git a/docker/Dockerfile b/docker/Dockerfile index 56f2d5fa..3029282f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -115,116 +115,26 @@ FROM toolchain AS builder # Get source COPY . . -# Conduwuit version info -ARG COMMIT_SHA= -ARG SHORT_COMMIT_SHA= -ARG REMOTE_URL= -ARG CONDUWUIT_VERSION_EXTRA= -ENV COMMIT_SHA=$COMMIT_SHA -ENV SHORT_COMMIT_SHA=$SHORT_COMMIT_SHA -ENV REMOTE_URL=$REMOTE_URL -ENV CONDUWUIT_VERSION_EXTRA=$CONDUWUIT_VERSION_EXTRA - -# Calculate version info from git if not provided via ARGs -# and write all relevant vars to /etc/environment -RUN <<'EOF' -set -e # Exit on error - -# Use temp variables to store calculated values -calculated_commit_sha="" -calculated_remote_url="" -calculated_version_extra="" - -# --- COMMIT_SHA --- -# Calculate COMMIT_SHA if ENV var (from ARG) is empty -if [ -z "${COMMIT_SHA}" ]; then - # Try to get short commit hash from git - calculated_commit_sha=$(git rev-parse HEAD 2>/dev/null || echo "") - if [ -n "${calculated_commit_sha}" ]; then - echo "COMMIT_SHA='${calculated_commit_sha}'" >> /etc/environment - fi -else - # Ensure ARG-provided value is in /etc/environment - echo "COMMIT_SHA='${COMMIT_SHA}'" >> /etc/environment -fi - - -if [ -z "${SHORT_COMMIT_SHA}" ]; then - # Try to get short commit hash from git - calculated_short_commit_sha=$(git rev-parse --short HEAD 2>/dev/null || echo "") - if [ -n "${calculated_short_commit_sha}" ]; then - echo "SHORT_COMMIT_SHA='${calculated_short_commit_sha}'" >> /etc/environment - fi -else - # Ensure ARG-provided value is in /etc/environment - echo "SHORT_COMMIT_SHA='${SHORT_COMMIT_SHA}'" >> /etc/environment -fi - -# --- REMOTE_URL --- -# Calculate REMOTE_URL if ENV var (from ARG) is empty -if [ -z "${REMOTE_URL}" ]; then - # Try to get remote origin URL from git - remote_url_raw=$(git config --get remote.origin.url 2>/dev/null || echo "") - if [ -n "${remote_url_raw}" ]; then - # Transform git URL (SSH or HTTPS) to web URL - if [[ $remote_url_raw == "https://"* ]]; then - # Already HTTPS, just remove .git suffix - calculated_remote_url=$(echo "$remote_url_raw" | sed 's/\.git$//') - else - # Convert SSH URL to HTTPS URL - calculated_remote_url=$(echo "$remote_url_raw" | sed 's/\.git$//' | sed 's/:/\//' | sed 's/^git@/https:\/\//') - fi - - # Write calculated web URL if transformation was successful - if [ -n "${calculated_remote_url}" ]; then - echo "REMOTE_URL='${calculated_remote_url}'" >> /etc/environment - fi - fi -else - # Ensure ARG-provided value is in /etc/environment (assume it's a valid web URL) - echo "REMOTE_URL='${REMOTE_URL}'" >> /etc/environment - # Use provided value for REMOTE_COMMIT_URL calculation below - calculated_remote_url="${REMOTE_URL}" -fi - -# --- Determine effective values for subsequent calculations --- -# Use ENV var value if set (from ARG), otherwise use calculated value -effective_commit_sha="${COMMIT_SHA:-$calculated_commit_sha}" -effective_short_commit_sha="${SHORT_COMMIT_SHA:-$calculated_short_commit_sha}" -effective_remote_url="${REMOTE_URL:-$calculated_remote_url}" - -# --- REMOTE_COMMIT_URL --- -# Calculate and write REMOTE_COMMIT_URL if both components are available -if [ -z "${REMOTE_COMMIT_URL}" ] && [ -n "${effective_remote_url}" ] && [ -n "${effective_commit_sha}" ]; then - echo "REMOTE_COMMIT_URL='${effective_remote_url}/commit/${effective_commit_sha}'" >> /etc/environment -else - # Ensure ARG-provided value is in /etc/environment - echo "REMOTE_COMMIT_URL='${REMOTE_COMMIT_URL}'" >> /etc/environment -fi - -# --- CONDUWUIT_VERSION_EXTRA --- -# Calculate CONDUWUIT_VERSION_EXTRA if ENV var (from ARG) is empty -if [ -z "${CONDUWUIT_VERSION_EXTRA}" ]; then - # Use the effective short commit sha, fallback to "unknown revision" - calculated_version_extra="${effective_short_commit_sha:-unknown revision}" - # Handle case where commit sha calculation failed and ARG wasn't set - if [ -z "${calculated_version_extra}" ]; then - calculated_version_extra="unknown revision" - fi - echo "CONDUWUIT_VERSION_EXTRA='${calculated_version_extra}'" >> /etc/environment -else - # Ensure ARG-provided value is in /etc/environment - echo "CONDUWUIT_VERSION_EXTRA='${CONDUWUIT_VERSION_EXTRA}'" >> /etc/environment -fi - -EOF - ARG TARGETPLATFORM # Verify environment configuration RUN cat /etc/environment RUN xx-cargo --print-target-triple +# Conduwuit version info +ARG GIT_COMMIT_HASH= +ARG GIT_COMMIT_HASH_SHORT= +ARG GIT_REMOTE_URL= +ARG GIT_REMOTE_COMMIT_URL= +ARG CONDUWUIT_VERSION_EXTRA= +ARG CONTINUWUITY_VERSION_EXTRA= +ENV GIT_COMMIT_HASH=$GIT_COMMIT_HASH +ENV GIT_COMMIT_HASH_SHORT=$GIT_COMMIT_HASH_SHORT +ENV GIT_REMOTE_URL=$GIT_REMOTE_URL +ENV GIT_REMOTE_COMMIT_URL=$GIT_REMOTE_COMMIT_URL +ENV CONDUWUIT_VERSION_EXTRA=$CONDUWUIT_VERSION_EXTRA +ENV CONTINUWUITY_VERSION_EXTRA=$CONTINUWUITY_VERSION_EXTRA + # Build the binary RUN --mount=type=cache,target=/usr/local/cargo/registry \ diff --git a/nix/pkgs/main/default.nix b/nix/pkgs/main/default.nix index 3a43af5a..f2fffec0 100644 --- a/nix/pkgs/main/default.nix +++ b/nix/pkgs/main/default.nix @@ -130,9 +130,8 @@ buildDepsOnlyEnv = }); buildPackageEnv = { - COMMIT_SHA = inputs.self.rev or inputs.self.dirtyRev or ""; - SHORT_COMMIT_SHA = inputs.self.shortRev or inputs.self.dirtyShortRev or ""; - CONDUWUIT_VERSION_EXTRA = inputs.self.shortRev or inputs.self.dirtyShortRev or ""; + GIT_COMMIT_HASH = inputs.self.rev or inputs.self.dirtyRev or ""; + GIT_COMMIT_HASH_SHORT = inputs.self.shortRev or inputs.self.dirtyShortRev or ""; } // buildDepsOnlyEnv // { # Only needed in static stdenv because these are transitive dependencies of rocksdb CARGO_BUILD_RUSTFLAGS = buildDepsOnlyEnv.CARGO_BUILD_RUSTFLAGS diff --git a/src/api/client/message.rs b/src/api/client/message.rs index 16b1796a..e442850b 100644 --- a/src/api/client/message.rs +++ b/src/api/client/message.rs @@ -143,7 +143,10 @@ pub(crate) async fn get_message_events_route( if let Some(registration) = body.appservice_info.as_ref() { <&DeviceId>::from(registration.registration.id.as_str()) } else { - panic!("No device_id provided and no appservice registration found, this should be unreachable"); + panic!( + "No device_id provided and no appservice registration found, this \ + should be unreachable" + ); }, }, room_id, diff --git a/src/build_metadata/Cargo.toml b/src/build_metadata/Cargo.toml new file mode 100644 index 00000000..3a98c6bf --- /dev/null +++ b/src/build_metadata/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "conduwuit_build_metadata" +categories.workspace = true +description.workspace = true +edition.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +version.workspace = true + + +build = "build.rs" +# [[bin]] +# path = "main.rs" +# name = "conduwuit_build_metadata" + +[lib] +path = "mod.rs" +crate-type = [ + "rlib", +# "dylib", +] + +[features] + + +[dependencies] + +[build-dependencies] +built = {version = "0.7", features = ["cargo-lock", "dependency-tree"]} + +[lints] +workspace = true diff --git a/src/build_metadata/build.rs b/src/build_metadata/build.rs new file mode 100644 index 00000000..2fec16a7 --- /dev/null +++ b/src/build_metadata/build.rs @@ -0,0 +1,92 @@ +use std::process::Command; + +fn run_git_command(args: &[&str]) -> Option<String> { + Command::new("git") + .args(args) + .output() + .ok() + .filter(|output| output.status.success()) + .and_then(|output| String::from_utf8(output.stdout).ok()) + .map(|s| s.trim().to_owned()) + .filter(|s| !s.is_empty()) +} +fn get_env(env_var: &str) -> Option<String> { + match std::env::var(env_var) { + | Ok(val) if !val.is_empty() => Some(val), + | _ => None, + } +} +fn main() { + // built gets the default crate from the workspace. Not sure if this is intended + // behavior, but it's what we want. + built::write_built_file().expect("Failed to acquire build-time information"); + + // --- Git Information --- + let mut commit_hash = None; + let mut commit_hash_short = None; + let mut remote_url_web = None; + + // Get full commit hash + if let Some(hash) = + get_env("GIT_COMMIT_HASH").or_else(|| run_git_command(&["rev-parse", "HEAD"])) + { + println!("cargo:rustc-env=GIT_COMMIT_HASH={hash}"); + commit_hash = Some(hash); + } + + // Get short commit hash + if let Some(short_hash) = get_env("GIT_COMMIT_HASH_SHORT") + .or_else(|| run_git_command(&["rev-parse", "--short", "HEAD"])) + { + println!("cargo:rustc-env=GIT_COMMIT_HASH_SHORT={short_hash}"); + commit_hash_short = Some(short_hash); + } + + // Get remote URL and convert to web URL + if let Some(remote_url_raw) = get_env("GIT_REMOTE_URL") + .or_else(|| run_git_command(&["config", "--get", "remote.origin.url"])) + { + println!("cargo:rustc-env=GIT_REMOTE_URL={remote_url_raw}"); + let web_url = if remote_url_raw.starts_with("https://") { + remote_url_raw.trim_end_matches(".git").to_owned() + } else if remote_url_raw.starts_with("git@") { + remote_url_raw + .trim_end_matches(".git") + .replacen(':', "/", 1) + .replacen("git@", "https://", 1) + } else if remote_url_raw.starts_with("ssh://") { + remote_url_raw + .trim_end_matches(".git") + .replacen("git@", "", 1) + .replacen("ssh:", "https:", 1) + } else { + // Assume it's already a web URL or unknown format + remote_url_raw + }; + println!("cargo:rustc-env=GIT_REMOTE_WEB_URL={web_url}"); + remote_url_web = Some(web_url); + } + + // Construct remote commit URL + if let Some(remote_commit_url) = get_env("GIT_REMOTE_COMMIT_URL") { + println!("cargo:rustc-env=GIT_REMOTE_COMMIT_URL={remote_commit_url}"); + } else if let (Some(base_url), Some(hash)) = + (&remote_url_web, commit_hash.as_ref().or(commit_hash_short.as_ref())) + { + let commit_page = format!("{base_url}/commit/{hash}"); + println!("cargo:rustc-env=GIT_REMOTE_COMMIT_URL={commit_page}"); + } + + // --- Rerun Triggers --- + // Rerun if the git HEAD changes + println!("cargo:rerun-if-changed=.git/HEAD"); + // Rerun if the ref pointed to by HEAD changes (e.g., new commit on branch) + if let Some(ref_path) = run_git_command(&["symbolic-ref", "--quiet", "HEAD"]) { + println!("cargo:rerun-if-changed=.git/{ref_path}"); + } + + println!("cargo:rerun-if-env-changed=GIT_COMMIT_HASH"); + println!("cargo:rerun-if-env-changed=GIT_COMMIT_HASH_SHORT"); + println!("cargo:rerun-if-env-changed=GIT_REMOTE_URL"); + println!("cargo:rerun-if-env-changed=GIT_REMOTE_COMMIT_URL"); +} diff --git a/src/build_metadata/mod.rs b/src/build_metadata/mod.rs new file mode 100644 index 00000000..cf3364c1 --- /dev/null +++ b/src/build_metadata/mod.rs @@ -0,0 +1,23 @@ +pub mod built { + include!(concat!(env!("OUT_DIR"), "/built.rs")); +} + +pub static GIT_COMMIT_HASH: Option<&str> = option_env!("GIT_COMMIT_HASH"); + +pub static GIT_COMMIT_HASH_SHORT: Option<&str> = option_env!("GIT_COMMIT_HASH_SHORT"); + +// this would be a lot better if Option::or was const. +pub static VERSION_EXTRA: Option<&str> = + if let v @ Some(_) = option_env!("CONTINUWUITY_VERSION_EXTRA") { + v + } else if let v @ Some(_) = option_env!("CONDUWUIT_VERSION_EXTRA") { + v + } else if let v @ Some(_) = option_env!("CONDUIT_VERSION_EXTRA") { + v + } else { + GIT_COMMIT_HASH_SHORT + }; +pub static GIT_REMOTE_WEB_URL: Option<&str> = option_env!("GIT_REMOTE_WEB_URL"); +pub static GIT_REMOTE_COMMIT_URL: Option<&str> = option_env!("GIT_REMOTE_COMMIT_URL"); + +// TODO: Mark dirty builds within the version string diff --git a/src/core/Cargo.toml b/src/core/Cargo.toml index f42b049b..0c33c590 100644 --- a/src/core/Cargo.toml +++ b/src/core/Cargo.toml @@ -67,6 +67,7 @@ checked_ops.workspace = true chrono.workspace = true clap.workspace = true conduwuit-macros.workspace = true +conduwuit-build-metadata.workspace = true const-str.workspace = true core_affinity.workspace = true ctor.workspace = true diff --git a/src/core/info/version.rs b/src/core/info/version.rs index 6abb6e13..523c40a2 100644 --- a/src/core/info/version.rs +++ b/src/core/info/version.rs @@ -26,13 +26,6 @@ pub fn user_agent() -> &'static str { USER_AGENT.get_or_init(init_user_agent) } fn init_user_agent() -> String { format!("{}/{}", name(), version()) } fn init_version() -> String { - option_env!("CONDUWUIT_VERSION_EXTRA") - .or(option_env!("CONDUIT_VERSION_EXTRA")) - .map_or(SEMANTIC.to_owned(), |extra| { - if extra.is_empty() { - SEMANTIC.to_owned() - } else { - format!("{SEMANTIC} ({extra})") - } - }) + conduwuit_build_metadata::VERSION_EXTRA + .map_or(SEMANTIC.to_owned(), |extra| format!("{SEMANTIC} ({extra})")) } diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 07dde0f7..8e03a338 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -20,6 +20,8 @@ crate-type = [ [dependencies] +conduwuit-build-metadata.workspace = true + askama = "0.14.0" axum.workspace = true diff --git a/src/web/mod.rs b/src/web/mod.rs index ddf13be4..520a9a34 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -5,6 +5,7 @@ use axum::{ response::{Html, IntoResponse, Response}, routing::get, }; +use conduwuit_build_metadata::{GIT_REMOTE_COMMIT_URL, GIT_REMOTE_WEB_URL, VERSION_EXTRA}; pub fn build<S>() -> Router<()> { Router::new().route("/", get(index_handler)) } diff --git a/src/web/templates/_layout.html.j2 b/src/web/templates/_layout.html.j2 index a38745e1..fd0a5b29 100644 --- a/src/web/templates/_layout.html.j2 +++ b/src/web/templates/_layout.html.j2 @@ -18,8 +18,8 @@ {%~ block footer ~%} <footer> <p>Powered by <a href="https://continuwuity.org">Continuwuity</a> - {%~ if let Some(version_info) = option_env!("CONDUWUIT_VERSION_EXTRA").or(option_env!("SHORT_COMMIT_SHA")) ~%} - {%~ if let Some(url) = option_env!("REMOTE_COMMIT_URL").or(option_env!("REMOTE_URL")) ~%} + {%~ if let Some(version_info) = VERSION_EXTRA ~%} + {%~ if let Some(url) = GIT_REMOTE_COMMIT_URL.or(GIT_REMOTE_WEB_URL) ~%} (<a href="{{ url }}">{{ version_info }}</a>) {%~ else ~%} ({{ version_info }}) From cbcf4300dffb55ad9b1ed5529ae6bf81ad446408 Mon Sep 17 00:00:00 2001 From: Jade Ellis <jade@ellis.link> Date: Thu, 1 May 2025 00:47:03 +0100 Subject: [PATCH 3/6] ci: Cache timelord-cli to avoid unnecesary compilation --- .forgejo/workflows/release-image.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.forgejo/workflows/release-image.yml b/.forgejo/workflows/release-image.yml index de009ad5..69d7d2fd 100644 --- a/.forgejo/workflows/release-image.yml +++ b/.forgejo/workflows/release-image.yml @@ -80,17 +80,29 @@ jobs: run: echo '${{ toJSON(fromJSON(needs.define-variables.outputs.build_matrix)) }}' - name: Echo matrix run: echo '${{ toJSON(matrix) }}' - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - run: | if ! command -v rustup &> /dev/null ; then curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH fi - - uses: https://github.com/cargo-bins/cargo-binstall@main + + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Cache timelord-cli installation + id: cache-timelord-bin + uses: actions/cache@v3 + with: + path: ~/.cargo/bin/timelord + key: timelord-cli-v3.0.1 + - name: Install timelord-cli + uses: https://github.com/cargo-bins/cargo-binstall@main + if: steps.cache-timelord-bin.outputs.cache-hit != 'true' - run: cargo binstall timelord-cli@3.0.1 + if: steps.cache-timelord-bin.outputs.cache-hit != 'true' + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Set up QEMU From fb9d4c30f4e89227244fcb275cdbed6261607610 Mon Sep 17 00:00:00 2001 From: Jade Ellis <jade@ellis.link> Date: Thu, 1 May 2025 18:46:30 +0100 Subject: [PATCH 4/6] feat: Prefill server name in federation test --- Cargo.lock | 1 + src/api/router.rs | 4 ++-- src/router/layers.rs | 3 +-- src/router/router.rs | 5 ++--- src/service/mod.rs | 1 + src/{api/router => service}/state.rs | 2 +- src/web/Cargo.toml | 1 + src/web/mod.rs | 17 ++++++++++++++--- src/web/templates/index.html.j2 | 2 +- 9 files changed, 24 insertions(+), 12 deletions(-) rename src/{api/router => service}/state.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 5f82384e..18375234 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1044,6 +1044,7 @@ dependencies = [ "askama", "axum", "conduwuit_build_metadata", + "conduwuit_service", "futures", "rand 0.8.5", "thiserror 2.0.12", diff --git a/src/api/router.rs b/src/api/router.rs index 3fbef275..5416e9e9 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -3,7 +3,6 @@ mod auth; mod handler; mod request; mod response; -pub mod state; use std::str::FromStr; @@ -13,10 +12,11 @@ use axum::{ routing::{any, get, post}, }; use conduwuit::{Server, err}; +pub(super) use conduwuit_service::state::State; use http::{Uri, uri}; use self::handler::RouterExt; -pub(super) use self::{args::Args as Ruma, response::RumaResponse, state::State}; +pub(super) use self::{args::Args as Ruma, response::RumaResponse}; use crate::{client, server}; pub fn build(router: Router<State>, server: &Server) -> Router<State> { diff --git a/src/router/layers.rs b/src/router/layers.rs index 6920555d..70f3a660 100644 --- a/src/router/layers.rs +++ b/src/router/layers.rs @@ -6,8 +6,7 @@ use axum::{ }; use axum_client_ip::SecureClientIpSource; use conduwuit::{Result, Server, debug, error}; -use conduwuit_api::router::state::Guard; -use conduwuit_service::Services; +use conduwuit_service::{Services, state::Guard}; use http::{ HeaderValue, Method, StatusCode, header::{self, HeaderName}, diff --git a/src/router/router.rs b/src/router/router.rs index 2b9ce2ec..fdaf9126 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -2,8 +2,7 @@ use std::sync::Arc; use axum::{Router, response::IntoResponse}; use conduwuit::Error; -use conduwuit_api::router::{state, state::Guard}; -use conduwuit_service::Services; +use conduwuit_service::{Services, state, state::Guard}; use http::{StatusCode, Uri}; use ruma::api::client::error::ErrorKind; @@ -11,7 +10,7 @@ pub(crate) fn build(services: &Arc<Services>) -> (Router, Guard) { let router = Router::<state::State>::new(); let (state, guard) = state::create(services.clone()); let router = conduwuit_api::router::build(router, &services.server) - .merge(conduwuit_web::build::<state::State>().with_state(())) + .merge(conduwuit_web::build()) .fallback(not_found) .with_state(state); diff --git a/src/service/mod.rs b/src/service/mod.rs index eb15e5ec..3d7a3aa9 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -5,6 +5,7 @@ mod manager; mod migrations; mod service; pub mod services; +pub mod state; pub mod account_data; pub mod admin; diff --git a/src/api/router/state.rs b/src/service/state.rs similarity index 98% rename from src/api/router/state.rs rename to src/service/state.rs index 57eb94ca..c0884a5c 100644 --- a/src/api/router/state.rs +++ b/src/service/state.rs @@ -1,6 +1,6 @@ use std::{ops::Deref, sync::Arc}; -use conduwuit_service::Services; +use crate::Services; #[derive(Clone, Copy)] pub struct State { diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 8e03a338..5c2dbebb 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -21,6 +21,7 @@ crate-type = [ [dependencies] conduwuit-build-metadata.workspace = true +conduwuit-service.workspace = true askama = "0.14.0" diff --git a/src/web/mod.rs b/src/web/mod.rs index 520a9a34..25ec868c 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -1,23 +1,34 @@ use askama::Template; use axum::{ Router, + extract::State, http::{StatusCode, header}, response::{Html, IntoResponse, Response}, routing::get, }; use conduwuit_build_metadata::{GIT_REMOTE_COMMIT_URL, GIT_REMOTE_WEB_URL, VERSION_EXTRA}; +use conduwuit_service::state; -pub fn build<S>() -> Router<()> { Router::new().route("/", get(index_handler)) } +pub fn build() -> Router<state::State> { + let router = Router::<state::State>::new(); + router.route("/", get(index_handler)) +} -async fn index_handler() -> Result<impl IntoResponse, WebError> { +async fn index_handler( + State(services): State<state::State>, +) -> Result<impl IntoResponse, WebError> { #[derive(Debug, Template)] #[template(path = "index.html.j2")] struct Tmpl<'a> { nonce: &'a str, + server_name: &'a str, } let nonce = rand::random::<u64>().to_string(); - let template = Tmpl { nonce: &nonce }; + let template = Tmpl { + nonce: &nonce, + server_name: services.config.server_name.as_str(), + }; Ok(( [(header::CONTENT_SECURITY_POLICY, format!("default-src 'none' 'nonce-{nonce}';"))], Html(template.render()?), diff --git a/src/web/templates/index.html.j2 b/src/web/templates/index.html.j2 index 51393822..648f5ddd 100644 --- a/src/web/templates/index.html.j2 +++ b/src/web/templates/index.html.j2 @@ -9,7 +9,7 @@ <li>Read the <a href="https://continuwuity.org/introduction">documentation</a></li> <li>Join the <a href="https://continuwuity.org/community">community</a></li> <li>Log in with a <a href="https://matrix.org/ecosystem/clients/">client</a></li> - <li>Ensure <a href="https://federationtester.matrix.org/">federation</a> works</li> + <li>Ensure <a href="https://federationtester.matrix.org/#{{ server_name }}">federation</a> works</li> </ul> </div> From e3ae024ed37ce869e66a45f1d567b54600a90cf7 Mon Sep 17 00:00:00 2001 From: Jade Ellis <jade@ellis.link> Date: Thu, 1 May 2025 21:21:28 +0100 Subject: [PATCH 5/6] chore: Link to Matrix rooms directly --- src/web/templates/index.html.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/templates/index.html.j2 b/src/web/templates/index.html.j2 index 648f5ddd..7f11cb1c 100644 --- a/src/web/templates/index.html.j2 +++ b/src/web/templates/index.html.j2 @@ -7,7 +7,7 @@ <p>To get started, you can:</p> <ul> <li>Read the <a href="https://continuwuity.org/introduction">documentation</a></li> - <li>Join the <a href="https://continuwuity.org/community">community</a></li> + <li>Join the <a href="https://matrix.to/#/#continuwuity:continuwuity.org">Continuwuity Matrix room</a> or <a href="https://matrix.to/#/#space:continuwuity.org">space</a></li> <li>Log in with a <a href="https://matrix.org/ecosystem/clients/">client</a></li> <li>Ensure <a href="https://federationtester.matrix.org/#{{ server_name }}">federation</a> works</li> </ul> From d78fc53577b38d0cd9f93341804d1ca930d0d719 Mon Sep 17 00:00:00 2001 From: Jade Ellis <jade@ellis.link> Date: Thu, 1 May 2025 21:27:12 +0100 Subject: [PATCH 6/6] ci: Fix bad comparison --- .forgejo/workflows/release-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/release-image.yml b/.forgejo/workflows/release-image.yml index 69d7d2fd..704a3bbf 100644 --- a/.forgejo/workflows/release-image.yml +++ b/.forgejo/workflows/release-image.yml @@ -214,7 +214,7 @@ jobs: type=semver,pattern=v{{version}} type=semver,pattern=v{{major}}.{{minor}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.0.') }} type=semver,pattern=v{{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }} - type=ref,event=branch,prefix=${{ format('refs/heads/{0}', github.event.repository.default_branch) 1= github.ref && 'branch-' || '' }} + type=ref,event=branch,prefix=${{ format('refs/heads/{0}', github.event.repository.default_branch) != github.ref && 'branch-' || '' }} type=ref,event=pr type=sha,format=long images: ${{needs.define-variables.outputs.images}}