Skip to content

Commit 39fb7ba

Browse files
committed
website: publish the RISC-V wheels dashboard at /dashboard (#2589)
The dashboard is the first reference for picking packages to port, but it lived only on a separate site. Serve it alongside the package index, regenerated on each publish from main. Generator vendored from riseproject-dev/python-wheels-dashboard@edcf127, which stays upstream and keeps its own site.
1 parent 4ea5f6b commit 39fb7ba

16 files changed

Lines changed: 1069 additions & 22 deletions

File tree

‎.github/workflows/website.yml‎

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ on:
88
branches: [main]
99
paths:
1010
- "docs/**"
11+
- "ci_scripts/dashboard/**"
1112
pull_request:
1213
types: [opened, synchronize, reopened, closed]
1314
paths:
1415
- "docs/**"
16+
- "ci_scripts/dashboard/**"
1517
workflow_dispatch:
1618

17-
concurrency:
18-
group: website
19-
cancel-in-progress: false
20-
queue: max
21-
2219
jobs:
2320
setup:
2421
if: github.event_name != 'pull_request' || github.actor != 'dependabot[bot]'
@@ -27,20 +24,21 @@ jobs:
2724
- run: true
2825

2926
preview:
27+
if: github.event_name == 'pull_request'
3028
needs: [setup]
3129
runs-on: ubuntu-latest
3230
permissions:
3331
contents: write
3432
pull-requests: write
3533
steps:
36-
- uses: actions/checkout@v7
34+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
3735

38-
- uses: actions/setup-python@v7
36+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
3937
if: github.event.action != 'closed'
4038
with:
4139
python-version: '3'
4240

43-
- name: Install package doc generator dependencies
41+
- name: Install site generator dependencies
4442
if: github.event.action != 'closed'
4543
run: pip install -r ci_scripts/requirements.txt
4644

@@ -54,7 +52,7 @@ jobs:
5452
run: |
5553
echo "value=/pr-preview/pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT"
5654
57-
- uses: ruby/setup-ruby@v1
55+
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
5856
if: github.event.action != 'closed'
5957
with:
6058
ruby-version: '3.3'
@@ -86,7 +84,7 @@ jobs:
8684
# occasionally not live for a few seconds is a smaller problem than a
8785
# misleading red X on an otherwise-working PR.
8886
- name: Deploy or remove PR preview
89-
uses: rossjrw/pr-preview-action@v1
87+
uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 # v1.8.1
9088
with:
9189
source-dir: ./_site
9290

@@ -97,26 +95,43 @@ jobs:
9795
permissions:
9896
contents: write
9997
steps:
100-
- uses: actions/checkout@v7
98+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
10199

102-
- uses: actions/setup-python@v7
100+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
103101
with:
104102
python-version: '3'
105103

106-
- name: Install package doc generator dependencies
104+
- name: Install site generator dependencies
107105
run: pip install -r ci_scripts/requirements.txt
108106

109107
- name: Generate package pages from YAML
110108
run: python ci_scripts/generate_packages_doc.py
111109

110+
- name: Restore the dashboard's pypi.org response cache
111+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
112+
with:
113+
path: ${{ runner.temp }}/dashboard/requests-cache.sqlite
114+
key: requests-cache-${{ github.ref }}
115+
restore-keys: requests-cache-main
116+
117+
# build.py stages nothing unless the result is complete, and keep_files
118+
# leaves the previous dashboard serving, so an upstream data outage must
119+
# not block a docs deploy.
120+
- name: Generate the dashboard
121+
continue-on-error: true
122+
run: |
123+
python ci_scripts/dashboard/build.py \
124+
--build-dir "${{ runner.temp }}/dashboard" \
125+
--output-dir docs/dashboard
126+
112127
- name: Build with Jekyll
113-
uses: actions/jekyll-build-pages@v1
128+
uses: actions/jekyll-build-pages@44a6e6beabd48582f863aeeb6cb2151cc1716697 # v1.0.13
114129
with:
115130
source: ./docs
116131
destination: ./_site
117132

118133
- name: Deploy to GitHub Pages
119-
uses: peaceiris/actions-gh-pages@v4
134+
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
120135
with:
121136
github_token: ${{ secrets.GITHUB_TOKEN }}
122137
publish_dir: ./_site

‎ci_scripts/dashboard/.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__/

‎ci_scripts/dashboard/LICENSE‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright (c) 2013, Charlie Denton
2+
2026, Stan Ulbrych
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without modification,
6+
are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice,
9+
this list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
19+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

‎ci_scripts/dashboard/README.md‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Vendored RISC-V Wheels dashboard generator
2+
3+
This directory is a **vendored copy** of the dashboard generator from
4+
<https://github.com/riseproject-dev/python-wheels-dashboard>, used to publish the
5+
dashboard at <https://pypi.riseproject.dev/dashboard/> as part of this repo's
6+
website build (`.github/workflows/website.yml`, `deploy` job).
7+
8+
The dashboard repo remains the **upstream source of truth**. It keeps its own
9+
GitHub Pages site and its own 6-hourly refresh; this copy is regenerated on each
10+
publish from `main`. The two sites can legitimately disagree by a few hours.
11+
12+
Vendored from commit **`edcf127`** ("Persist pypi.org request cache across CI
13+
runs, pin actions to SHAs").
14+
15+
## Licensing
16+
17+
The upstream project is BSD-2-Clause, whose clause 1 requires retaining the
18+
copyright notice, so `LICENSE` is shipped verbatim and the vendored files carry
19+
BSD-2-Clause SPDX headers. Only `build.py` is RISE-authored and MIT, matching the
20+
rest of this repo.
21+
22+
## Files
23+
24+
| File | Origin |
25+
|---|---|
26+
| `LICENSE` | verbatim from upstream |
27+
| `generate.py`, `utils.py`, `svg_wheel.py` | upstream, SPDX header prepended |
28+
| `wheel.css`, `favicon.ico` | verbatim from upstream |
29+
| `index.html` | upstream, with the text edits listed below |
30+
| `build.py` | **new**, RISE-authored — not upstream |
31+
32+
The generator's own dependencies (`requests`, `requests-cache`) live in
33+
`ci_scripts/requirements.txt` alongside the rest of this repo's CI Python deps;
34+
upstream's `pre-commit` pin is dropped, as there are no local hooks here.
35+
36+
`build.py` holds all python-wheels-specific logic so that the upstream files stay
37+
a clean copy. It fetches and sanity-checks the package list, runs `generate.py` in
38+
a scratch directory, validates the result, and only then stages five files into
39+
the Jekyll source tree.
40+
41+
## Resyncing from upstream
42+
43+
```bash
44+
cd ci_scripts/dashboard
45+
UP=/path/to/python-wheels-dashboard
46+
cp "$UP"/{LICENSE,generate.py,utils.py,svg_wheel.py,index.html,wheel.css,favicon.ico} .
47+
```
48+
49+
Then re-apply the local deltas:
50+
51+
1. Prepend the BSD-2-Clause SPDX header to `generate.py`, `utils.py` and
52+
`svg_wheel.py` (copy it from a sibling file).
53+
2. Re-apply the `index.html` edits:
54+
- drop the stale "top 360" figure from the "What is this list?" paragraph and
55+
the "Thanks" paragraph — the generator applies no slice, so the real count
56+
moves every run;
57+
- change the footer cadence from "Updated daily." to the real cadence;
58+
- keep the absolute link back to <https://pypi.riseproject.dev/> near the `<h1>`.
59+
3. If upstream changed its `requests`/`requests-cache` pins, update them in
60+
`ci_scripts/requirements.txt`.
61+
4. Update the vendored commit SHA above.
62+
63+
Leave `build.py` alone — it is not upstream.
64+
65+
**Never add YAML front matter to `index.html`.** It contains AngularJS bindings
66+
(`{{ package.name }}`) that are also valid Liquid. The file is correct only
67+
because Jekyll treats it as a static file and copies it byte-for-byte; front
68+
matter would make Liquid eat the bindings and the package list would render empty
69+
with no build error. `build.py` asserts this.
70+
71+
## Running it locally
72+
73+
```bash
74+
pip install -r ../requirements.txt
75+
python build.py --build-dir /tmp/dash --output-dir ../../docs/dashboard
76+
```
77+
78+
A cold run makes one pypi.org request per package (~15000 at 8 concurrency) and
79+
writes a multi-GB `requests-cache.sqlite` into the build dir, which is why the
80+
build dir is kept outside `docs/`.

0 commit comments

Comments
 (0)