Skip to content

Commit 6733a6c

Browse files
authored
Add GitHub Pages extension repo to Release workflow. (#2)
Align MainDistributionPipeline on DuckDB v1.5.3, publish unsigned quackscale binaries to GitHub Pages on release, keep the linux QuackTail tarball on GitHub Releases, and document install paths in README.
1 parent 5408382 commit 6733a6c

4 files changed

Lines changed: 194 additions & 14 deletions

File tree

.github/workflows/MainDistributionPipeline.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
name: Build extension binaries
1717
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.5-variegata
1818
with:
19-
duckdb_version: v1.5.2
19+
duckdb_version: v1.5.3
2020
ci_tools_version: v1.5-variegata
2121
extension_name: quackscale
2222
extra_toolchains: 'go'
@@ -27,7 +27,7 @@ jobs:
2727
name: Code Quality Check
2828
uses: duckdb/extension-ci-tools/.github/workflows/_extension_code_quality.yml@v1.5-variegata
2929
with:
30-
duckdb_version: v1.5.2
30+
duckdb_version: v1.5.3
3131
ci_tools_version: v1.5-variegata
3232
extension_name: quackscale
3333
format_checks: 'format;tidy'

.github/workflows/Release.yml

Lines changed: 146 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,164 @@
1-
# Build a Linux DuckDB binary with quackscale embedded and attach it to the GitHub release.
2-
# E2e workflows download this artifact instead of compiling from source.
1+
# Publish unsigned quackscale loadable binaries to GitHub Pages (INSTALL FROM …)
2+
# and attach a linux QuackTail tarball (duckdb + extension) to GitHub Releases.
3+
#
4+
# One-time setup: repo Settings → Pages → Build and deployment → Source: GitHub Actions.
5+
#
6+
# Layout after deploy:
7+
# https://quackscience.github.io/duckdb-quackscale/v1.5.3/linux_amd64/quackscale.duckdb_extension.gz
8+
#
9+
# Users:
10+
# SET allow_unsigned_extensions = true;
11+
# INSTALL quackscale FROM 'https://quackscience.github.io/duckdb-quackscale';
12+
# LOAD quackscale;
13+
#
14+
# Note: deploy-pages replaces the whole site each run (one DuckDB version hosted).
315
name: Release
416

517
on:
618
release:
719
types: [published]
20+
workflow_dispatch:
21+
inputs:
22+
release_tag:
23+
description: 'Git tag for QuackTail linux tarball (manual runs; optional)'
24+
required: false
25+
type: string
26+
skip_pages:
27+
description: 'Skip GitHub Pages packaging and deploy'
28+
required: false
29+
default: false
30+
type: boolean
31+
skip_tarball:
32+
description: 'Skip QuackTail linux tarball upload'
33+
required: false
34+
default: false
35+
type: boolean
836

9-
permissions:
10-
contents: write
37+
concurrency:
38+
group: pages
39+
cancel-in-progress: false
1140

1241
env:
42+
EXT_NAME: quackscale
1343
DUCKDB_VERSION: v1.5.3
1444
RELEASE_ASSET: quacktail-linux-amd64
45+
PAGES_BASE_URL: https://quackscience.github.io/duckdb-quackscale
1546

1647
jobs:
17-
build-linux:
18-
name: Build QuackTail linux amd64
48+
build:
49+
name: Build extension binaries
50+
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.5-variegata
51+
with:
52+
duckdb_version: v1.5.3
53+
ci_tools_version: v1.5-variegata
54+
extension_name: quackscale
55+
extra_toolchains: go
56+
exclude_archs: 'windows_amd64;windows_arm64;windows_amd64_mingw;wasm_mvp;wasm_eh;wasm_threads;osx_amd64'
57+
58+
package-pages:
59+
name: Package extension repository
60+
runs-on: ubuntu-latest
61+
needs: build
62+
if: github.event_name == 'release' || inputs.skip_pages != true
63+
steps:
64+
- name: Download build artifacts
65+
uses: actions/download-artifact@v4
66+
with:
67+
path: artifacts
68+
pattern: ${{ env.EXT_NAME }}-${{ env.DUCKDB_VERSION }}-extension-*
69+
70+
- name: Assemble GitHub Pages tree
71+
shell: bash
72+
run: |
73+
set -euo pipefail
74+
shopt -s nullglob
75+
prefix="${EXT_NAME}-${DUCKDB_VERSION}-extension-"
76+
found=0
77+
mkdir -p _site
78+
for dir in artifacts/${prefix}*/; do
79+
arch="$(basename "$dir")"
80+
arch="${arch#${prefix}}"
81+
src="${dir}${EXT_NAME}.duckdb_extension"
82+
if [[ ! -f "$src" ]]; then
83+
echo "::warning::no ${EXT_NAME}.duckdb_extension in ${dir}, skipping ${arch}"
84+
continue
85+
fi
86+
out="_site/${DUCKDB_VERSION}/${arch}"
87+
mkdir -p "$out"
88+
cp "$src" work.bin
89+
truncate -s -256 work.bin
90+
dd if=/dev/zero bs=256 count=1 status=none >> work.bin
91+
gzip -n < work.bin > "${out}/${EXT_NAME}.duckdb_extension.gz"
92+
rm -f work.bin
93+
echo "packaged ${arch}"
94+
found=$((found + 1))
95+
done
96+
if [[ "$found" -eq 0 ]]; then
97+
echo "::error::no extension binaries found to package"
98+
exit 1
99+
fi
100+
echo "Packaged ${found} platform(s) for ${DUCKDB_VERSION}"
101+
102+
- name: Write landing page
103+
shell: bash
104+
env:
105+
PAGES_BASE_URL: ${{ env.PAGES_BASE_URL }}
106+
EXT_NAME: ${{ env.EXT_NAME }}
107+
DUCKDB_VERSION: ${{ env.DUCKDB_VERSION }}
108+
run: |
109+
set -euo pipefail
110+
{
111+
echo '<!DOCTYPE html>'
112+
echo '<html lang="en"><head><meta charset="utf-8"><title>quackscale extension repository</title></head><body>'
113+
echo '<h1>quackscale</h1>'
114+
echo "<p>Unsigned DuckDB extension repository. Requires DuckDB ${DUCKDB_VERSION}.</p>"
115+
echo '<pre>SET allow_unsigned_extensions = true;'
116+
echo "INSTALL ${EXT_NAME} FROM '${PAGES_BASE_URL}';"
117+
echo "LOAD ${EXT_NAME};</pre>"
118+
echo '<h2>Available binaries</h2><ul>'
119+
while IFS= read -r rel; do
120+
echo " <li><a href=\"${rel}\">${rel}</a></li>"
121+
done < <(cd _site && find . -name '*.duckdb_extension.gz' | sort | sed 's|^\./||')
122+
echo '</ul></body></html>'
123+
} > _site/index.html
124+
125+
- name: Upload Pages artifact
126+
uses: actions/upload-pages-artifact@v3
127+
with:
128+
path: _site
129+
130+
deploy-pages:
131+
name: Deploy to GitHub Pages
132+
runs-on: ubuntu-latest
133+
needs: package-pages
134+
if: github.event_name == 'release' || inputs.skip_pages != true
135+
permissions:
136+
pages: write
137+
id-token: write
138+
environment:
139+
name: github-pages
140+
url: ${{ steps.deployment.outputs.page_url }}
141+
steps:
142+
- name: Deploy to GitHub Pages
143+
id: deployment
144+
uses: actions/deploy-pages@v4
145+
146+
build-quacktail-bundle:
147+
name: Build QuackTail linux amd64 tarball
19148
runs-on: ubuntu-latest
20149
timeout-minutes: 90
150+
if: >-
151+
(github.event_name == 'release') ||
152+
(github.event_name == 'workflow_dispatch' && inputs.skip_tarball != true && inputs.release_tag != '')
153+
permissions:
154+
contents: write
155+
env:
156+
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.release_tag }}
21157

22158
steps:
23159
- uses: actions/checkout@v4
24160
with:
25-
ref: ${{ github.event.release.tag_name }}
161+
ref: ${{ github.event.release.tag_name || inputs.release_tag || github.ref }}
26162
submodules: recursive
27163

28164
- uses: actions/setup-go@v5
@@ -51,15 +187,15 @@ jobs:
51187
cp build/release/extension/quackscale/quackscale.duckdb_extension \
52188
"dist/${RELEASE_ASSET}/extension/quackscale/"
53189
{
54-
echo "tag=${{ github.event.release.tag_name }}"
190+
echo "tag=${RELEASE_TAG}"
55191
echo "duckdb=${{ env.DUCKDB_VERSION }}"
56192
echo "commit=${{ github.sha }}"
57193
} > "dist/${RELEASE_ASSET}/VERSION"
58-
tar -czf "dist/${RELEASE_ASSET}-${{ github.event.release.tag_name }}.tar.gz" -C dist "${RELEASE_ASSET}"
194+
tar -czf "dist/${RELEASE_ASSET}-${RELEASE_TAG}.tar.gz" -C dist "${RELEASE_ASSET}"
59195
ls -lh dist/
60196
61197
- name: Upload release assets
62198
uses: softprops/action-gh-release@v2
63199
with:
64-
tag_name: ${{ github.event.release.tag_name }}
200+
tag_name: ${{ env.RELEASE_TAG }}
65201
files: dist/*.tar.gz

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,34 @@ Do **not** copy the random `auth_token` from each `CALL quack_serve`. Use a flee
137137

138138
---
139139

140+
## Install
141+
142+
QuackScale ships in two forms: a **loadable extension** (stock DuckDB + `INSTALL`) and a **QuackTail release bundle** (prebuilt `duckdb` binary for Linux CI and compose).
143+
144+
### Loadable extension (GitHub Pages)
145+
146+
Published on each [release](https://github.com/quackscience/duckdb-quackscale/releases) to a DuckDB custom extension repository. Requires **DuckDB v1.5.3** and unsigned extension support:
147+
148+
```sql
149+
SET allow_unsigned_extensions = true;
150+
INSTALL quackscale FROM 'https://quackscience.github.io/duckdb-quackscale';
151+
LOAD quackscale;
152+
```
153+
154+
CLI equivalent: `duckdb -unsigned` then `LOAD quackscale;`
155+
156+
Install [Quack](https://duckdb.org/docs/current/quack/overview) from core separately (`INSTALL quack FROM core; LOAD quack;`) for `quack_serve`, `ATTACH`, and `quack_query`.
157+
158+
### QuackTail release bundle (GitHub Releases)
159+
160+
Linux amd64 tarball with `duckdb` and `extension/quackscale/quackscale.duckdb_extension` — used by [Headscale e2e CI](.github/workflows/headscale-e2e.yml) and `examples/` with `BUILD_FROM_SOURCE=0`. Download from [Releases](https://github.com/quackscience/duckdb-quackscale/releases) (`quacktail-linux-amd64-*.tar.gz`).
161+
162+
### Build from source
163+
164+
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for submodules, Go/libtailscale, and `make release`.
165+
166+
---
167+
140168
## Quick start
141169

142170
### Server

docs/DEVELOPMENT.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,28 @@ When bumping the DuckDB target:
7272
|----------|---------|---------|
7373
| [headscale-e2e.yml](../.github/workflows/headscale-e2e.yml) | **Manual only** | Release-binary two-node e2e (no source build) |
7474
| [headscale-integration.yml](../.github/workflows/headscale-integration.yml) | PR | Source build + Headscale smoke |
75-
| [Release.yml](../.github/workflows/Release.yml) | Release published | Build linux release tarball |
75+
| [Release.yml](../.github/workflows/Release.yml) | Release published / manual | Extension repo → GitHub Pages; linux QuackTail tarball → Releases |
7676
| [libtailscale-integration.yml](../.github/workflows/libtailscale-integration.yml) | PR | libtailscale `go test` |
7777
| [MainDistributionPipeline.yml](../.github/workflows/MainDistributionPipeline.yml) | PR | Extension distribution CI |
7878

7979
**E2e never runs on push/PR** and never compiles DuckDB in CI — use `workflow_dispatch` on `headscale-e2e` with a release tag. Full DuckLake compose demo is local dev only (`scripts/ci_compose_e2e.sh`).
8080

81+
### Release and GitHub Pages
82+
83+
On **Release published** (or manual **Release** workflow):
84+
85+
1. **build** — extension-ci-tools matrix (`quackscale` per platform, same exclusions as MainDistributionPipeline).
86+
2. **package-pages** + **deploy-pages** — unsigned `.duckdb_extension.gz` under `v1.5.3/{arch}/` at `https://quackscience.github.io/duckdb-quackscale`.
87+
3. **build-quacktail-bundle** — linux amd64 `quacktail-linux-amd64-{tag}.tar.gz` attached to the GitHub Release.
88+
89+
**One-time repo setup:** Settings → Pages → Build and deployment → **Source: GitHub Actions**.
90+
91+
**Manual Pages-only test:** Actions → Release → Run workflow → leave `release_tag` empty, uncheck skip_pages.
92+
93+
**Manual tarball test:** provide an existing git tag in `release_tag`, uncheck skip_tarball.
94+
95+
Each Pages deploy replaces the whole site (one DuckDB version hosted). To host multiple DuckDB versions, accumulate version directories in a follow-up change.
96+
8197
## Roadmap (selected)
8298

8399
| Item | Status |
@@ -88,7 +104,7 @@ When bumping the DuckDB target:
88104
| `ATTACH … TYPE quacktail_lake` (Tier 3 native catalog) | Planned |
89105
| `ducklake_discover()` enriched discovery | Planned |
90106
| `quackscale_serve()` one-call server bootstrap | Planned |
91-
| Community extension descriptor publish | Planned |
107+
| Community extension descriptor publish | Done (GitHub Pages on release) |
92108

93109
## Risks
94110

0 commit comments

Comments
 (0)