Front-end for the Differential Privacy Deployments Registry
Shared development practices and architectural goals will make the Differential Privacy Deployments Registry a sustainable community project.
Work is tracked with github issues.
- Bugs should include a reproducer and the expected behavior.
- Features should include a clear description of the desired feature, as well as a reminder of the motivation.
Development should happen in branches from main. To relate issues to branches we follow a naming convention on branches: [issue number]-[short description]. For example: 1234-add-dev-practices. To keep in-progress work from being lost, draft PRs can be filed. PR descriptions should list the issues which are fixed, so github will automatically close the linked issues on merge. Project maintainers are responsible for reviewing PRs and should either indicate what needs to change or approve and merge. We require branches to be up-to-date with the latest changes in main to avoid surprises.
Reviewers should confirm that a PR actually addresses the linked issue, that the implementation makes sense, that new tests are added for any new functionality. Tests aren't required for changes to static content, but if there is anything more complicated, we can't assume that maintainers will remember and test all the functionality of the site with each new PR.
When CI checks pass, PRs should be squash merged. The linked issue will be automatically closed, and the new version of the site automatically published.
Static site generation: The Differential Privacy Deployments Registry uses simple, widely adopted, actively maintained technologies to ensure its sustainability. It uses Jekyll to render static pages, and Github Pages to serve the content. Deployment should not rely on any steps apart from the static site generator, and the output files should be git-ignored.
Javascript: We are conservative about introducing new libraries. Any front-end libraries used should be pulled from a CDN, rather than checked in to the codebase. We avoid inline Javascript, and favor modern widely supported JS language features like modules.
Testing: Additional testing (playwright end-to-end tests, link checking, etc.) will use Python, just because of our greater familiarity with Python testing tools. We'll focus on making simple assertions with these tests, so if there is a desire in the future to make the whole project Ruby, it shouldn't be too hard.
Separation of concerns: This repo has front end details, and will describe DP in general terms. Particular deployments are described in deployments-registry-data which is referenced as a git module.
To build the site locally:
git clone --recurse-submodules https://github.com/opendp/deployments-registry-ui.git
cd deployments-registry-ui
git submodule init
git submodule update --remote
bundle install
bundle exec jekyll serveBy default, the site will be available at http://localhost:4000
You can specify the host and port number with the host and port flags:
bundle exec jekyll serve --host 0.0.0.0 --port 4000To run tests:
python3 -m venv .venv
source .venv/bin/activate
pip install -r tests/requirements.txt
playwright install
pytestBe sure that the Jekyll application is running (e.g., via bundle exec jekyll serve) when executing pytest.
We're using Playwright for end-to-end tests. You can use it to generate test code just by interacting with the app in a browser:
playwright codegen http://127.0.0.1:4000/You can also step through these tests and see what the browser sees:
PWDEBUG=1 pytestIf Playwright fails in CI, we can still see what went wrong:
- Scroll to the end of the CI log, to
actions/upload-artifact. - Download the zipped artifact locally.
- Inside the zipped artifact will be another zip:
trace.zip. - Don't unzip it! Instead, open it with trace.playwright.dev.
To update the deployments-registry-data submodule, start a new branch and run:
git submodule update --remoteCI in the data repo is responsible for validating the deployment records, but if there are changes to the schema, corresponding changes may be needed here. After making any necessary updates, commit your changes and make a PR.
The site is organized with documentation pages in the pages/ directory, but served at clean URLs:
- Documentation home:
/(served frompages/index.md) - Getting started pages:
/overview,/intro-to-dp(frompages/getting-started/) - Concept pages:
/concepts/trust-model,/concepts/standardization(frompages/concepts/)
This is achieved through Jekyll's permalink configuration, allowing clean URLs without moving files around.
To add new documentation pages:
Create your new .md file in the appropriate folder under the pages directory
Each page must include front matter with these fields:
---
title: Your Page Title
order: 1 # Controls order within the section (optional)
class: your-page-class # Optional CSS class
layout: docs # Use the docs layout for regular pages, main for special layouts
icon: '<svg>...</svg>' # Optional icon (used as part of page header)
---Add your page to _navigation/main.md. The navigation structure supports two types of sections:
Sections with sub-pages:
---
- section: your-section
title: Section Title
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">...</svg>'
path: /your-section/ # Note: URL path to the index file permalink
pages:
- path: /your-section/your-page/ # Note: URL path, not file path
title: Your Page Title
order: 1
---Direct link sections (no sub-pages):
---
- section: your-section
title: Section Title
path: /your-section/ # Direct link to a page
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">...</svg>'
---When adding a new section, you must also add it to the defaults in _config.yml to configure permalinks and layout:
---
defaults:
- scope:
path: "pages/your-section"
values:
layout: "docs"
permalink: /your-section/:basename/
---To create a new section:
- Create a new folder under
pages/ - Add pages to that folder
- Add a new section to
_navigation/main.md - Add permalink configuration to
_config.ymlunderdefaults
The sidebar navigation reads from _navigation/main.md, which contains a YAML front matter with the navigation structure. The sidebar supports:
- Icons: SVG icons for each section (16x16 recommended)
- Collapsible Sections: Sections with sub-pages that can be expanded/collapsed
- Direct Links: Sections that link directly to a single page
- Active State: Automatic highlighting of current page/section
- Order Control: Sort pages within sections using the
orderfield