Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
41 changes: 41 additions & 0 deletions .github/workflows/check-website.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Check Webpage daily for Console Errors

on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:

jobs:
check-webpage:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22

- name: Install dependencies
run: npm install puppeteer

- name: Open webpage and check for errors
uses: actions/github-script@v7
with:
script: |
const puppeteer = require('puppeteer');

const browser = await puppeteer.launch();
const page = await browser.newPage();

page
.on('console', message => core.setFailed(`Webpage has console errors: ${message}`))
.on('pageerror', ({ message }) => core.setFailed(`Webpage has console errors: ${message}`));

await page.goto('https://jsonforms.io');

await new Promise(r => setTimeout(r, 5000));

await browser.close();
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ on:
push:
paths-ignore:
- '**.md'
- 'website/**'
pull_request:
paths-ignore:
- '**.md'
- 'website/**'

jobs:
ci:
Expand Down
149 changes: 149 additions & 0 deletions .github/workflows/release-website.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: 'Release Website'

# Pin the documentation website to a stable JSON Forms release and (re)deploy
# it. This is intentionally separate from publish.yaml: a website failure must
# never taint or block an already-published npm release, and the site also
# needs to be redeployable on its own (docs, news, community changes) without
# cutting a library release.
#
# Run manually after a stable release, passing the released version. It bumps
# the website's @jsonforms/* dependencies to that exact version, verifies the
# site still builds, pushes the bump to master, and triggers the Netlify build
# hook so production is published against the latest stable release.
#
# The optional regenerate_docs flag rebuilds the typedoc API docs from the
# current state of master (no tag checkout) and commits the refreshed
# website/static/api along with the bump. Use it while master still matches
# the released code, i.e. right after a stable release.
on:
workflow_dispatch:
inputs:
version:
type: 'string'
description: 'stable JSON Forms version to pin the website to (e.g. 3.9.0)'
required: true
skip_bump:
type: 'boolean'
description: 'mark to skip the dependency bump and only rebuild/redeploy the current website state'
required: false
default: false
skip_deploy:
type: 'boolean'
description: 'mark to only bump and push, skipping the Netlify deploy trigger'
required: false
default: false
regenerate_docs:
type: 'boolean'
description: 'mark to regenerate the API docs from the current repository state and commit them'
required: false
default: false

jobs:
release-website:
permissions:
contents: 'write'
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v4'
with:
ref: 'master'
token: '${{ secrets.JSONFORMS_PUBLISH_PAT }}'

- name: 'Configure Git Credentials'
run: |
git config user.name "jsonforms-publish[bot]"
git config user.email "jsonforms-publish@eclipsesource.com"

- name: 'Setup node'
uses: 'actions/setup-node@v4'
with:
node-version-file: 'website/.nvmrc'
registry-url: 'https://registry.npmjs.org'

- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
if: github.event.inputs.regenerate_docs == 'true'
name: 'Install pnpm'
with:
run_install: false

# Regenerate the API docs from the current repository state. The
# packages are built first because typedoc resolves cross-package types
# from the built lib/ output (same order as ci.yaml).
- name: 'Regenerate API docs'
if: github.event.inputs.regenerate_docs == 'true'
run: |
pnpm i --frozen-lockfile
pnpm run build
pnpm run doc
./website/copy-docs.sh

# Ensure the released version is actually on npmjs before pinning to it.
- name: 'Wait for npm propagation'
if: github.event.inputs.skip_bump == 'false'
run: |
for i in $(seq 1 30); do
if [ "$(npm view @jsonforms/core@${VERSION} version 2> /dev/null)" = "${VERSION}" ]; then
exit 0
fi
echo "@jsonforms/core@${VERSION} not yet available on npmjs, retrying..."
sleep 20
done
echo "@jsonforms/core@${VERSION} did not appear on npmjs in time"
exit 1
env:
VERSION: ${{ github.event.inputs.version }}

- name: 'Bump @jsonforms/* to the released version'
if: github.event.inputs.skip_bump == 'false'
working-directory: 'website'
run: |
npm install --save-exact \
@jsonforms/core@${VERSION} \
@jsonforms/react@${VERSION} \
@jsonforms/material-renderers@${VERSION} \
@jsonforms/examples@${VERSION}
env:
VERSION: ${{ github.event.inputs.version }}

# Install (in case the bump was skipped) and verify the site builds before
# pushing or deploying, so we never publish a broken bump.
- name: 'Install'
if: github.event.inputs.skip_bump == 'true'
working-directory: 'website'
run: npm ci

- name: 'Verify build'
working-directory: 'website'
run: npm run build:current

- name: 'Commit and push'
if: github.event.inputs.skip_bump == 'false' || github.event.inputs.regenerate_docs == 'true'
run: |
if [ "${SKIP_BUMP}" = "false" ]; then
git add website/package.json website/package-lock.json
fi
if [ "${REGENERATE_DOCS}" = "true" ]; then
git add website/static/api
fi
if git diff --cached --quiet; then
echo "Website already up to date, nothing to commit."
elif [ "${SKIP_BUMP}" = "false" ] && [ "${REGENERATE_DOCS}" = "true" ]; then
git commit -m "docs: pin website to JSON Forms ${VERSION} and regenerate API docs"
git push origin HEAD:master
elif [ "${SKIP_BUMP}" = "false" ]; then
git commit -m "docs: pin website to JSON Forms ${VERSION}"
git push origin HEAD:master
else
git commit -m "docs: regenerate website API docs"
git push origin HEAD:master
fi
env:
VERSION: ${{ github.event.inputs.version }}
SKIP_BUMP: ${{ github.event.inputs.skip_bump }}
REGENERATE_DOCS: ${{ github.event.inputs.regenerate_docs }}

# Trigger the production build on Netlify. Automatic Netlify deploys are
# disabled, so this hook is what publishes the site.
- name: 'Trigger website deploy'
if: github.event.inputs.skip_deploy == 'false'
run: curl -fsS -X POST -d '{}' "${{ secrets.NETLIFY_WEBSITE_BUILD_HOOK }}"
33 changes: 33 additions & 0 deletions .github/workflows/website.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Website

# Build the documentation website to catch breakage early. This job only
# verifies that the site compiles; it never deploys. Production is published
# separately against the latest stable release (see publish.yaml + Netlify).
on:
push:
paths:
- 'website/**'
pull_request:
paths:
- 'website/**'

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
defaults:
run:
working-directory: website
steps:
- uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: website/.nvmrc

- name: Install
run: npm ci

- name: Build
run: npm run build:current
55 changes: 55 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Netlify configuration for the JSON Forms documentation website, which lives
# in website/.
#
# The site is published only against the latest stable release, not on every
# push ("no rolling website"):
# - Automatic production deploys are disabled in the Netlify UI.
# - A Netlify build hook, fired from .github/workflows/release-website.yaml
# after a stable release, triggers the production build. The site renders
# against the @jsonforms/* versions pinned by that workflow.
# - The `ignore` command below skips deploy-preview builds for changes that
# don't touch website/ (paths are relative to the base directory).
[build]
base = "website"
command = "npm run build:current"
publish = "build"
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF -- ."

[[redirects]]
from = "/public/api/core/*"
to = "/api/core/"

[[redirects]]
from = "/public/api/react/*"
to = "/api/react/"

[[redirects]]
from = "/public/api/material/*"
to = "/api/material/"

[[redirects]]
from = "/public/api/vanilla/*"
to = "/api/vanilla/"

[[redirects]]
from = "/public/api/angular/*"
to = "/api/angular/"

[[redirects]]
from = "/public/api/vue/*"
to = "/api/vue/"

[[headers]]
for = "/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Referrer-Policy = "strict-origin-when-cross-origin"
Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-eval' 'sha256-O8zYuOjyuzUZDv3fub7DKfAs5TEd1dG+fz+hCSCFmQA=' 'sha256-nlA5Eh6znySQnjHmn8Yf6Vfz2I3XgXggeuOKoXBiBC0=' 'sha256-pBkmluod9Ko4GzDfbWgKM/wxzujFXUdGVOePkwOQT+c=' 'sha256-bI2b8zL8P3uzmgy+aB+Lh2ZEf8GRlptjS0Gs3QKMRSM=' static.cloudflareinsights.com cloudflareinsights.com/cdn-cgi/rum; connect-src 'self' cloudflareinsights.com/cdn-cgi/rum; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; frame-ancestors 'self';"
X-Frame-Options = "SAMEORIGIN"
X-Content-Type-Options = "nosniff"
Permissions-Policy = "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"

[[headers]]
for = "/api/*"
[headers.values]
Content-Security-Policy = "script-src 'self' 'unsafe-inline'; script-src-elem 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' data:;"
7 changes: 7 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
.docusaurus
build
.env
google7cffb0370fcac18c.html
.yalc
yalc.lock
1 change: 1 addition & 0 deletions website/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.14.0
31 changes: 31 additions & 0 deletions website/.prompts/project-info.prompttemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# JSON Forms Documentation Website

Docusaurus-based documentation website for [JSON Forms](https://github.com/eclipsesource/jsonforms), a declarative framework for building JSON Schema based forms.

## Key Architectural Decisions

- **Content in `/content/`**: All MDX content lives here, NOT in `/docs/` (Docusaurus default)
- **Sidebars in `/src/sidebars/`**: Navigation configs are separate files, not in docusaurus.config.js
- **Custom Blog Plugin** (`plugins/custom-blog-plugin.js`): Injects latest post into homepage
- **Version fetching**: `build.sh` queries GitHub API, writes to `/static/current-version.js`

## Important Patterns

### Interactive Examples
Use the `Demo` component (`src/components/common/Demo.js`) which renders JSON Forms with Material-UI and provides tabbed Schema/UI Schema/Form views.

### Adding Documentation
1. Create MDX file in `/content/docs/` or `/content/examples/`
2. Add entry to the appropriate sidebar in `/src/sidebars/`

### Custom Renderers
Example custom renderers exist in `src/components/common/` (rating, country, region controls).

### Component Development
- React components go in `/src/components/`
- Use the existing Demo component pattern for interactive examples
- Follow CSS Modules pattern for component-specific styles

## Important Guidelines

**Always build and test changes**: Run the build to check for compilation errors, then start the dev server and visually verify changes work correctly. Check for console errors in the browser. Do not consider a task complete until the build passes and changes have been visually verified.
12 changes: 12 additions & 0 deletions website/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"esbenp.prettier-vscode",
"ms-vscode.vscode-typescript-tslint-plugin"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
6 changes: 6 additions & 0 deletions website/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"editor.formatOnSave": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.jsxSingleQuote": true,
"prettier.singleQuote": true
}
Loading
Loading