Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,22 @@ jobs:
echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u "${{ github.actor }}" --password-stdin
helm package helm/altinity-sql-browser --version "${VERSION}" --app-version "${VERSION}"
helm push "altinity-sql-browser-${VERSION}.tgz" oci://ghcr.io/altinity/altinity-sql-browser/helm

# Mirror the just-built sql.html onto docs.altinity.com/altinity-sql-browser/
# (GitHub Pages is configured to serve this repo's /docs on main). dist/ is
# gitignored, so it survives the branch switch below. Run last so nothing
# else in this job depends on which ref ends up checked out.
- name: Publish sql.html to GitHub Pages docs/
run: |
git fetch --depth=1 origin main
git checkout -B main origin/main
cp dist/sql.html docs/sql.html
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add docs/sql.html
if git diff --cached --quiet; then
echo "docs/sql.html unchanged, skipping commit"
else
git commit -m "docs: publish sql.html ${GITHUB_REF_NAME} to GitHub Pages"
git push origin main
fi
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ auto-generated per-PR notes; this file is the curated, human-readable history.
## [Unreleased]

### Added
- **Every tagged release now mirrors `sql.html` to
`docs.altinity.com/altinity-sql-browser/sql.html`** (`docs/sql.html`,
published by a new `release.yml` step, alongside a demo `docs/config.json`
offering the Antalya/github.demo clusters) — a try-it-now link independent
of any ClickHouse-served deployment. Fixed `loadConfigDoc` (`src/net/oauth-config.ts`)
to resolve `config.json` from the containing directory when `basePath` is a
static filename (e.g. `sql.html`) rather than a route (e.g. `/sql`), which
this static hosting case needs and the ClickHouse route did not exercise.
- **File ▾ → Import example dashboard…** (#506): a modal dialog lists the three
flagship example dashboards (ClickHouse Operations, Shop Charts, OnTime
Charts) by their catalogue name; Import is disabled until one is selected,
Expand Down
5 changes: 5 additions & 0 deletions docs/ASSET-DISTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ real design question on a multi-node cluster, because **ClickHouse does not
replicate the `user_files/` directory**: it is a node-local folder.

This doc explains the trade-offs and what `deploy/install.sh` ships today.
(A `docs/sql.html` mirror is also published to GitHub Pages on every tagged
release, for an unauthenticated try-it-now demo — see `release.yml` — but
that's a separate distribution channel from the cluster-serving problem
below, not a replacement for it: a real deployment still needs the bytes on
every ClickHouse node.)

## What has to reach every node

Expand Down
26 changes: 26 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"basic_login": true,
"idps": [
{
"id": "google-antalya",
"label": "Google (Antalya)",
"issuer": "https://accounts.google.com",
"client_id": "925653064731-tpj128lp5qm5vkqn4llgbl96udvt3lsf.apps.googleusercontent.com",
"client_secret": "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"
},
{
"id": "google-github",
"label": "Google (github.demo)",
"issuer": "https://accounts.google.com",
"client_id": "925653064731-vsep3e0vjq74q16svj5jshgvdlm6uptm.apps.googleusercontent.com",
"client_secret": "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",
"ch_auth": "basic"
}
],
"hosts": [
{ "label": "Antalya (demo:demo)", "url": "https://antalya.demo.altinity.cloud", "auth": "basic", "user": "demo", "password": "demo" },
{ "label": "Antalya (Google SSO)", "url": "https://antalya.demo.altinity.cloud", "auth": "oauth", "idp": "google-antalya" },
{ "label": "github.demo (demo:demo)", "url": "https://github.demo.altinity.cloud", "auth": "basic", "user": "demo", "password": "demo" },
{ "label": "github.demo (Google SSO)", "url": "https://github.demo.altinity.cloud", "auth": "oauth", "idp": "google-github" }
]
}
422 changes: 422 additions & 0 deletions docs/sql.html

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/net/oauth-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,14 @@ function normalizeHost(h: RawHostEntry | null | undefined): HostDescriptor {
* describes a credentials-only deployment, so `idps` comes back empty rather
* than throwing. `basicLogin` (top-level `basic_login`, default true) lets an
* SSO-only deployment hide the username/password path.
* @param basePath e.g. location.pathname ('/sql')
* @param basePath e.g. location.pathname ('/sql', or '/sql/sql.html' for a
* static-file deployment — the last segment is dropped when it looks like a
* file (has a dot), so config.json is fetched from its containing directory
* either way)
*/
export async function loadConfigDoc(fetchFn: typeof fetch, basePath = ''): Promise<ConfigDoc> {
const cfgUrl = basePath.replace(/\/$/, '') + '/config.json';
const dir = basePath.replace(/\/[^/]*\.[^/]*$/, '').replace(/\/$/, '');
const cfgUrl = dir + '/config.json';
const cfgResp = await fetchFn(cfgUrl, { cache: 'no-store' });
if (!cfgResp.ok) throw new Error('GET ' + cfgUrl + ': ' + cfgResp.status);
const cfg = await cfgResp.json() as RawConfigDoc;
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/oauth-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ describe('loadConfigDoc', () => {
}]);
expect(f.mock.calls[0][0]).toBe('/sql/config.json');
});
it('fetches config.json from the containing directory when basePath is a static file (e.g. sql.html)', async () => {
const f = fetcher([[/config\.json$/, resp(true, { idps: [] })]]);
await loadConfigDoc(asFetch(f), '/altinity-sql-browser/sql.html');
expect(f.mock.calls[0][0]).toBe('/altinity-sql-browser/config.json');
});
it('parses a list and honours explicit id/label', async () => {
const idps = await docOf({ idps: [
{ id: 'g', label: 'Google', issuer: 'https://accounts.google.com', client_id: 'c1' },
Expand Down