diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e702d65db..bbcc2e9f4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,6 +14,10 @@ jobs:
test_and_deploy:
name: Test and deploy
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [20.x]
+
steps:
- name: Checkout the source code
uses: actions/checkout@v2
@@ -30,6 +34,17 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
key: linux
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Build frontend for testing
+ run: |
+ npm ci
+ npm run build
+ working-directory: ./site/frontend
- name: Run unit tests
run: cargo test --all
@@ -66,6 +81,10 @@ jobs:
test_on_windows:
name: Test on Windows
runs-on: windows-latest
+ strategy:
+ matrix:
+ node-version: [20.x]
+
steps:
- name: Checkout the source code
uses: actions/checkout@v2
@@ -87,6 +106,17 @@ jobs:
env:
RUSTFLAGS: -Dwarnings
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Build frontend for testing
+ run: |
+ npm ci
+ npm run build
+ working-directory: ./site/frontend
+
- name: Run unit tests
run: cargo test --all
diff --git a/site/frontend/.posthtmlrc b/site/frontend/.posthtmlrc
new file mode 100644
index 000000000..28fd562f6
--- /dev/null
+++ b/site/frontend/.posthtmlrc
@@ -0,0 +1,5 @@
+{
+ "plugins": {
+ "posthtml-include": {}
+ }
+}
\ No newline at end of file
diff --git a/site/frontend/package-lock.json b/site/frontend/package-lock.json
index 62f3be4a0..3fc517a58 100644
--- a/site/frontend/package-lock.json
+++ b/site/frontend/package-lock.json
@@ -22,6 +22,7 @@
"@parcel/compressor-brotli": "^2.8.3",
"@parcel/transformer-vue": "^2.8.3",
"@types/msgpack-lite": "^0.1.8",
+ "posthtml-include": "^2.0.1",
"prettier": "2.8.8",
"typescript": "^5.0.2",
"vue-tsc": "^1.8.3"
@@ -2753,6 +2754,12 @@
"resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz",
"integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw=="
},
+ "node_modules/fclone": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz",
+ "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==",
+ "dev": true
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -3574,6 +3581,57 @@
"node": ">=12.0.0"
}
},
+ "node_modules/posthtml-expressions": {
+ "version": "1.11.4",
+ "resolved": "https://registry.npmjs.org/posthtml-expressions/-/posthtml-expressions-1.11.4.tgz",
+ "integrity": "sha512-tJI6KhKLcePRO0/i4d01MNXfcaBa2jIu4MuVLixvGwCRzxdY2D7LLm17ijNyQNQu3xOhCffBLtUMju0K64smmQ==",
+ "dev": true,
+ "dependencies": {
+ "fclone": "^1.0.11",
+ "posthtml": "^0.16.5",
+ "posthtml-match-helper": "^1.0.1",
+ "posthtml-parser": "^0.10.0",
+ "posthtml-render": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/posthtml-include": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/posthtml-include/-/posthtml-include-2.0.1.tgz",
+ "integrity": "sha512-1YXy4QWeJldosTKLPz6ecbI4e26jHmo3R97NNTKMQqITvZOY025+yvX/RUgvcD1VghLeACs0Y2P3GjtJo5s27Q==",
+ "dev": true,
+ "dependencies": {
+ "posthtml": "^0.16.6",
+ "posthtml-expressions": "^1.7.1",
+ "posthtml-parser": "^0.11.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/posthtml-include/node_modules/posthtml-parser": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz",
+ "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==",
+ "dev": true,
+ "dependencies": {
+ "htmlparser2": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/posthtml-match-helper": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-1.0.4.tgz",
+ "integrity": "sha512-Tj9orTIBxHdnraCxoEGjoizsFsTGvukzwcuhOjYQGmDG6gTlaRbMrGgi1J+FwKTN8hsCQENHYY0Deqs9a89BVg==",
+ "dev": true,
+ "peerDependencies": {
+ "posthtml": ">=0.5.0"
+ }
+ },
"node_modules/posthtml-parser": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.10.2.tgz",
diff --git a/site/frontend/package.json b/site/frontend/package.json
index a6e54552e..eec041202 100644
--- a/site/frontend/package.json
+++ b/site/frontend/package.json
@@ -15,10 +15,16 @@
"@parcel/compressor-brotli": "^2.8.3",
"@parcel/transformer-vue": "^2.8.3",
"@types/msgpack-lite": "^0.1.8",
+ "posthtml-include": "^2.0.1",
"prettier": "2.8.8",
"typescript": "^5.0.2",
"vue-tsc": "^1.8.3"
},
+ "@parcel/bundler-default": {
+ "minBundles": 999,
+ "minBundleSize": 9999999,
+ "maxParallelRequests": 20
+ },
"dependencies": {
"date-fns": "^2.30.0",
"highcharts": "^11.4.1",
@@ -30,32 +36,28 @@
},
"targets": {
"dashboard": {
- "source": "src/pages/dashboard.ts",
- "distDir": "dist/scripts"
+ "source": "src/templates/dashboard.html",
+ "distDir": "dist/"
},
"status": {
- "source": "src/pages/status.ts",
- "distDir": "dist/scripts"
+ "source": "src/templates/status.html",
+ "distDir": "dist/"
},
"bootstrap": {
- "source": "src/pages/bootstrap.ts",
- "distDir": "dist/scripts"
+ "source": "src/templates/bootstrap.html",
+ "distDir": "dist/"
},
"graphs": {
- "source": "src/pages/graphs.ts",
- "distDir": "dist/scripts"
+ "source": "src/templates/graphs.html",
+ "distDir": "dist/"
},
"compare": {
- "source": "src/pages/compare.ts",
- "distDir": "dist/scripts"
+ "source": "src/templates/compare.html",
+ "distDir": "dist/"
},
"detailed-query": {
- "source": "src/pages/detailed-query.ts",
- "distDir": "dist/scripts"
- },
- "uplot": {
- "source": "node_modules/uplot/dist/uPlot.min.css",
- "distDir": "dist/styles"
+ "source": "src/templates/detailed-query.html",
+ "distDir": "dist/"
}
},
"browserslist": "> 0.5%, last 3 years, not dead",
diff --git a/site/frontend/src/templates/bootstrap.html b/site/frontend/src/templates/bootstrap.html
new file mode 100644
index 000000000..d3187ce1d
--- /dev/null
+++ b/site/frontend/src/templates/bootstrap.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/frontend/src/templates/compare.html b/site/frontend/src/templates/compare.html
new file mode 100644
index 000000000..4277760c4
--- /dev/null
+++ b/site/frontend/src/templates/compare.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/frontend/src/templates/dashboard.html b/site/frontend/src/templates/dashboard.html
new file mode 100644
index 000000000..3f731b95b
--- /dev/null
+++ b/site/frontend/src/templates/dashboard.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+ What data is in the dashboard?
+
+ The dashboard shows performance results for all stable Rust releases going
+ back to
+ 1.28.0
, along with the latest beta
release. The
+ displayed duration is an arithmetic mean amongst all
+ stable
+ benchmarks. The dashboard also shows the average duration of runtime
+ benchmarks, which measure the performance of Rust programs compiled by a
+ given version of the Rust compiler.
+
+
+
+
+
+
+
+
diff --git a/site/frontend/src/templates/detailed-query.html b/site/frontend/src/templates/detailed-query.html
new file mode 100644
index 000000000..a69c33804
--- /dev/null
+++ b/site/frontend/src/templates/detailed-query.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+ <
+
+
+
+
+
Artifact Size
+
+
+
+ Artifact
+ Size
+ Size delta
+
+
+
+
+
+ 'Time (%)' is the percentage of the cpu-clock time spent on this query
+ (we do not use wall-time as we want to account for parallelism).
+
+
Executions do not include cached executions.
+
+
+
+
+
+
+
diff --git a/site/frontend/src/templates/graphs.html b/site/frontend/src/templates/graphs.html
new file mode 100644
index 000000000..da4c8c1ae
--- /dev/null
+++ b/site/frontend/src/templates/graphs.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/frontend/src/templates/help.html b/site/frontend/src/templates/help.html
new file mode 100644
index 000000000..d031f74b4
--- /dev/null
+++ b/site/frontend/src/templates/help.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+ @rust-timer
commands
+
+
+ @rust-timer
supports several commands, the most common (and
+ simple) being @rust-timer queue
. This command is usually
+ invoked as @bors try @rust-timer queue
, which starts a bors
+ "try" run (not a merge). @rust-timer
will wait for the try
+ run to finish, and if it succeeds will then queue a perf run.
+
+
+ @rust-timer queue
has a few extra options that can be
+ useful:
+
+
+
+ include=<INCLUDE>
is a comma-separated list of
+ benchmark prefixes. A benchmark is included in the run only if its
+ name matches one of the given prefixes.
+
+
+ exclude=<EXCLUDE>
is a comma-separated list of
+ benchmark prefixes, and the inverse of include=
. A
+ benchmark is excluded from the run if its name matches one of the
+ given prefixes.
+
+
+ runs=<RUNS>
configures how many times the benchmark
+ is run. <RUNS>
is an integer. All benchmarks run at
+ least once by default, but some run more than one time. You can use
+ the runs
option to override the default run count and
+ make every benchmark run for <RUNS>
times.
+
+
+
+ @rust-timer build $commit
will queue a perf run for the
+ given commit $commit
. It is usually invoked with the commit
+ from a successful "try" run. (The queue
command can be seen
+ as a shortcut that automatically selects the "try" run's commit for the
+ build
command) This command also supports the same
+ include
, exclude
, and
+ runs
options as @rust-timer queue
.
+
+
+
+
+
diff --git a/site/frontend/src/templates/layout/footer.html b/site/frontend/src/templates/layout/footer.html
new file mode 100644
index 000000000..6403e12f9
--- /dev/null
+++ b/site/frontend/src/templates/layout/footer.html
@@ -0,0 +1,3 @@
+
diff --git a/site/frontend/src/templates/layout/head.html b/site/frontend/src/templates/layout/head.html
new file mode 100644
index 000000000..806df1db3
--- /dev/null
+++ b/site/frontend/src/templates/layout/head.html
@@ -0,0 +1,6 @@
+
+rustc performance data
+
+
+
+
diff --git a/site/frontend/src/templates/layout/navbar.html b/site/frontend/src/templates/layout/navbar.html
new file mode 100644
index 000000000..2cc6c0861
--- /dev/null
+++ b/site/frontend/src/templates/layout/navbar.html
@@ -0,0 +1,6 @@
+
diff --git a/site/frontend/src/templates/status.html b/site/frontend/src/templates/status.html
new file mode 100644
index 000000000..196ac2fa3
--- /dev/null
+++ b/site/frontend/src/templates/status.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/frontend/templates/layout.html b/site/frontend/templates/layout.html
deleted file mode 100644
index 44ce25427..000000000
--- a/site/frontend/templates/layout.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
- rustc performance data
-
-
-
-
- {% block head %}{% endblock %}
-
-
-
- {% block content %}{% endblock %}
-
- {% block script %}{% endblock %}
-
-
diff --git a/site/frontend/templates/pages/bootstrap.html b/site/frontend/templates/pages/bootstrap.html
deleted file mode 100644
index 2610f0c70..000000000
--- a/site/frontend/templates/pages/bootstrap.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-
-{% endblock %}
-{% block content %}
-
-{% endblock %}
-{% block script %}
-
-{% endblock %}
diff --git a/site/frontend/templates/pages/compare.html b/site/frontend/templates/pages/compare.html
deleted file mode 100644
index 4f95eac36..000000000
--- a/site/frontend/templates/pages/compare.html
+++ /dev/null
@@ -1,83 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-
-
-
-
-{% endblock %}
-{% block content %}
-{% raw %}
-
-{% endraw %}
-{% endblock %}
-{% block script %}
-
-{% endblock %}
diff --git a/site/frontend/templates/pages/dashboard.html b/site/frontend/templates/pages/dashboard.html
deleted file mode 100644
index 8010544be..000000000
--- a/site/frontend/templates/pages/dashboard.html
+++ /dev/null
@@ -1,38 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-{% endblock %}
-{% block content %}
-
- What data is in the dashboard?
-
- The dashboard shows performance results for all stable Rust releases going back to
- 1.28.0
, along with the latest beta
release. The displayed
- duration is an arithmetic mean amongst all
- stable
- benchmarks. The dashboard also shows the average duration of runtime benchmarks, which measure the performance of
- Rust programs
- compiled by a given version of the Rust compiler.
-
-
-
-
-{% endblock %}
-{% block script %}
-
-{% endblock %}
\ No newline at end of file
diff --git a/site/frontend/templates/pages/detailed-query.html b/site/frontend/templates/pages/detailed-query.html
deleted file mode 100644
index dbec34f59..000000000
--- a/site/frontend/templates/pages/detailed-query.html
+++ /dev/null
@@ -1,107 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-{% endblock %}
-{% block content %}
-
-
-
-
-
Artifact Size
-
-
-
- Artifact
- Size
- Size delta
-
-
-
-
-
-
'Time (%)' is the percentage of the cpu-clock time spent on this query (we do not use
- wall-time as we want to account for parallelism).
-
Executions do not include cached executions.
-
-
-
-{% endblock content %}
-{% block script %}
-
-{% endblock script %}
diff --git a/site/frontend/templates/pages/graphs.html b/site/frontend/templates/pages/graphs.html
deleted file mode 100644
index c1b20f59b..000000000
--- a/site/frontend/templates/pages/graphs.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-
-{% endblock %}
-{% block content %}
-
-{% endblock %}
-{% block script %}
-
-{% endblock %}
diff --git a/site/frontend/templates/pages/help.html b/site/frontend/templates/pages/help.html
deleted file mode 100644
index 06b184c9c..000000000
--- a/site/frontend/templates/pages/help.html
+++ /dev/null
@@ -1,48 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-{% endblock %}
-
-{% block content %}
-
-
@rust-timer
commands
-
@rust-timer
supports several commands, the most common (and simple) being
- @rust-timer queue
. This command is usually invoked as @bors try @rust-timer queue
,
- which starts a bors "try" run (not a merge). @rust-timer
will wait for the try run to finish,
- and if it succeeds will then queue a perf run.
-
-
@rust-timer queue
has a few extra options that can be useful:
-
- include=<INCLUDE>
is a comma-separated list of benchmark prefixes. A benchmark is included in
- the run only if its name matches one of the given prefixes.
-
- exclude=<EXCLUDE>
is a comma-separated list of benchmark prefixes, and the inverse of include=
.
- A benchmark is excluded from the run if its name matches one of the given prefixes.
- runs=<RUNS>
configures how many times the benchmark is run. <RUNS>
- is an integer. All benchmarks run at least once by default, but some run more than one time. You can use
- the runs
option to override the default run count and make every benchmark run for
- <RUNS>
times.
-
-
-
@rust-timer build $commit
will queue a perf run for the given commit $commit
.
- It is usually invoked with the commit from a successful "try" run. (The
- queue
command can be seen as a shortcut that automatically selects the
- "try" run's commit for the build
command)
- This command also supports the same include
, exclude
, and runs
options
- as @rust-timer queue
.
-
-
-{% endblock %}
diff --git a/site/frontend/templates/pages/status.html b/site/frontend/templates/pages/status.html
deleted file mode 100644
index fc1900e45..000000000
--- a/site/frontend/templates/pages/status.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "layout.html" %}
-{% block head %}
-
-{% endblock %}
-{% block content %}
-
-{% endblock %}
-{% block script %}
-
-{% endblock %}
diff --git a/site/src/resources.rs b/site/src/resources.rs
index 71a3ffbcf..78fe3c809 100644
--- a/site/src/resources.rs
+++ b/site/src/resources.rs
@@ -23,7 +23,7 @@ struct StaticCompiledAssets;
/// HTML template files that will be rendered by `tera`.
#[derive(RustEmbed)]
-#[folder = "frontend/templates/"]
+#[folder = "frontend/dist"]
#[include = "*.html"]
struct TemplateAssets;
diff --git a/site/src/server.rs b/site/src/server.rs
index 6bb155bbd..1ce753271 100644
--- a/site/src/server.rs
+++ b/site/src/server.rs
@@ -624,15 +624,12 @@ async fn handle_fs_path(
}
async fn resolve_template(path: &str) -> Vec {
- TEMPLATES
- .get_template(&format!("pages/{}", path))
- .await
- .unwrap()
+ TEMPLATES.get_template(path).await.unwrap()
}
let relative_path = path.trim_start_matches('/');
let source = match path {
- "" | "/" | "/index.html" => resolve_template("graphs.html").await,
+ "" | "/" | "/index.html" | "/graphs.html" => resolve_template("graphs.html").await,
"/bootstrap.html"
| "/compare.html"
| "/dashboard.html"
@@ -818,3 +815,51 @@ impl ResponseHeaders for http::response::Builder {
self
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ #[tokio::test]
+ async fn handle_fs_path_html() {
+ // Test case 1: Path is ""
+ let req = Request::default();
+ let path = "";
+ let use_compression = false;
+ let response = handle_fs_path(&req, path, use_compression).await.unwrap();
+ // "", "/", "/index.html", "/graphs.html" map to "graphs.html"
+ let expected_body = TEMPLATES.get_template("graphs.html").await.unwrap();
+ let expected_response = http::Response::builder()
+ .header_typed(ETag::from_str(&format!(r#""{}""#, *VERSION_UUID)).unwrap())
+ .header(CACHE_CONTROL, "max-age=60, stale-while-revalidate=86400")
+ .header_typed(ContentType::html())
+ .body(hyper::Body::from(expected_body))
+ .unwrap();
+ assert_eq!(response.headers(), expected_response.headers());
+ assert_eq!(
+ hyper::body::to_bytes(response.into_body()).await.unwrap(),
+ hyper::body::to_bytes(expected_response.into_body())
+ .await
+ .unwrap()
+ );
+
+ // Test case 2: Path is "/compare.html"
+ let req = Request::default();
+ let path = "/compare.html";
+ let use_compression = false;
+ let response = handle_fs_path(&req, path, use_compression).await.unwrap();
+ let expected_body = TEMPLATES.get_template("compare.html").await.unwrap();
+ let expected_response = http::Response::builder()
+ .header_typed(ETag::from_str(&format!(r#""{}""#, *VERSION_UUID)).unwrap())
+ .header(CACHE_CONTROL, "max-age=60, stale-while-revalidate=86400")
+ .header_typed(ContentType::html())
+ .body(hyper::Body::from(expected_body))
+ .unwrap();
+ assert_eq!(response.headers(), expected_response.headers());
+ assert_eq!(
+ hyper::body::to_bytes(response.into_body()).await.unwrap(),
+ hyper::body::to_bytes(expected_response.into_body())
+ .await
+ .unwrap()
+ );
+ }
+}