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
45 changes: 45 additions & 0 deletions .github/actions/dashboard-build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Build dashboard
description: >-
Sets up Node and pnpm, installs dashboard dependencies, generates the
TanStack Router tree, and runs the Vite production build. Output is
written to `py_src/taskito/static/dashboard/` for packaging into the
Python wheel.

runs:
using: composite
steps:
- name: Set up pnpm
uses: pnpm/action-setup@v6
with:
version: "10.30.3"

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "22"
cache: pnpm
cache-dependency-path: dashboard/pnpm-lock.yaml

- name: Install dashboard dependencies
shell: bash
working-directory: dashboard
run: pnpm install --frozen-lockfile

- name: Generate TanStack Router tree
shell: bash
working-directory: dashboard
run: pnpm exec tsr generate

- name: Vite production build
shell: bash
working-directory: dashboard
run: pnpm exec vite build

- name: Verify build output
shell: bash
run: |
set -euo pipefail
if [ ! -f py_src/taskito/static/dashboard/index.html ]; then
echo "::error::Dashboard build did not produce py_src/taskito/static/dashboard/index.html"
exit 1
fi
38 changes: 9 additions & 29 deletions .github/workflows/dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,29 @@ on:
paths:
- "dashboard/**"
- ".github/workflows/dashboard.yml"
- ".github/actions/dashboard-build/**"
pull_request:
branches: [master]
paths:
- "dashboard/**"
- ".github/workflows/dashboard.yml"
- ".github/actions/dashboard-build/**"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
working-directory: dashboard

jobs:
ci:
name: lint · typecheck · test · build
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
working-directory: dashboard
steps:
- uses: actions/checkout@v6

- name: Set up pnpm
uses: pnpm/action-setup@v6
with:
version: "10.30.3"

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: dashboard/pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Generate route tree
# TanStack Router's file-based tree is a build artifact; tsc needs
# it to resolve route imports.
run: pnpm exec tsr generate
- uses: ./.github/actions/dashboard-build

- name: Biome (lint + format)
run: pnpm exec biome ci src/
Expand All @@ -57,22 +39,20 @@ jobs:
- name: Unit tests (vitest)
run: pnpm exec vitest run

- name: Build
run: pnpm exec vite build

- name: Bundle size summary
if: always()
working-directory: ${{ github.workspace }}
run: |
set -e
{
echo "### Dashboard bundle"
echo
echo "| File | Size | Gzipped |"
echo "|------|-----:|--------:|"
find ../py_src/taskito/static/dashboard -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) | sort | while read -r f; do
find py_src/taskito/static/dashboard -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) | sort | while read -r f; do
raw=$(stat -c%s "$f")
gz=$(gzip -c "$f" | wc -c)
printf "| \`%s\` | %s | %s |\n" "${f#../py_src/taskito/static/dashboard/}" "$(numfmt --to=iec --suffix=B "$raw")" "$(numfmt --to=iec --suffix=B "$gz")"
printf "| \`%s\` | %s | %s |\n" "${f#py_src/taskito/static/dashboard/}" "$(numfmt --to=iec --suffix=B "$raw")" "$(numfmt --to=iec --suffix=B "$gz")"
done
} >> "$GITHUB_STEP_SUMMARY"

Expand Down
79 changes: 78 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,24 @@ permissions:
contents: read

jobs:
build-dashboard:
name: Build dashboard assets
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/dashboard-build

- name: Upload dashboard artifact
uses: actions/upload-artifact@v7
with:
name: dashboard-dist
path: py_src/taskito/static/dashboard
if-no-files-found: error
retention-days: 1

build-wheels-linux:
needs: build-dashboard
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -20,6 +37,16 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Download dashboard assets
uses: actions/download-artifact@v8
with:
name: dashboard-dist
path: py_src/taskito/static/dashboard

- name: Verify dashboard assets present
shell: bash
run: test -f py_src/taskito/static/dashboard/index.html

- name: Build wheels
uses: PyO3/maturin-action@v1
with:
Expand All @@ -34,8 +61,10 @@ jobs:
with:
name: wheels-linux-${{ matrix.target }}
path: dist/*.whl
if-no-files-found: error

build-wheels-musllinux:
needs: build-dashboard
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -47,6 +76,16 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Download dashboard assets
uses: actions/download-artifact@v8
with:
name: dashboard-dist
path: py_src/taskito/static/dashboard

- name: Verify dashboard assets present
shell: bash
run: test -f py_src/taskito/static/dashboard/index.html

- name: Build wheels
uses: PyO3/maturin-action@v1
with:
Expand All @@ -61,8 +100,10 @@ jobs:
with:
name: wheels-musllinux-${{ matrix.target }}
path: dist/*.whl
if-no-files-found: error

build-wheels-macos:
needs: build-dashboard
runs-on: macos-latest
strategy:
matrix:
Expand All @@ -72,6 +113,16 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Download dashboard assets
uses: actions/download-artifact@v8
with:
name: dashboard-dist
path: py_src/taskito/static/dashboard

- name: Verify dashboard assets present
shell: bash
run: test -f py_src/taskito/static/dashboard/index.html

- name: Set up Python 3.10
uses: actions/setup-python@v6
with:
Expand Down Expand Up @@ -103,8 +154,10 @@ jobs:
with:
name: wheels-macos-${{ matrix.target }}
path: dist/*.whl
if-no-files-found: error

build-wheels-windows:
needs: build-dashboard
runs-on: windows-latest
strategy:
matrix:
Expand All @@ -113,6 +166,16 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Download dashboard assets
uses: actions/download-artifact@v8
with:
name: dashboard-dist
path: py_src/taskito/static/dashboard

- name: Verify dashboard assets present
shell: bash
run: test -f py_src/taskito/static/dashboard/index.html

- name: Set up Python 3.10
uses: actions/setup-python@v6
with:
Expand Down Expand Up @@ -144,12 +207,24 @@ jobs:
with:
name: wheels-windows-${{ matrix.target }}
path: dist/*.whl
if-no-files-found: error

build-sdist:
needs: build-dashboard
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Download dashboard assets
uses: actions/download-artifact@v8
with:
name: dashboard-dist
path: py_src/taskito/static/dashboard

- name: Verify dashboard assets present
shell: bash
run: test -f py_src/taskito/static/dashboard/index.html

- name: Build sdist
uses: PyO3/maturin-action@v1
with:
Expand All @@ -161,6 +236,7 @@ jobs:
with:
name: sdist
path: dist/*.tar.gz
if-no-files-found: error

publish:
needs: [build-wheels-linux, build-wheels-musllinux, build-wheels-macos, build-wheels-windows, build-sdist]
Expand All @@ -169,9 +245,10 @@ jobs:
permissions:
id-token: write
steps:
- name: Download all artifacts
- name: Download wheel and sdist artifacts
uses: actions/download-artifact@v8
with:
pattern: "{wheels-*,sdist}"
path: dist
merge-multiple: true

Expand Down
2 changes: 1 addition & 1 deletion crates/taskito-async/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "taskito-async"
version = "0.12.0"
version = "0.12.1"
edition = "2021"

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/taskito-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "taskito-core"
version = "0.12.0"
version = "0.12.1"
edition = "2021"

[features]
Expand Down
2 changes: 1 addition & 1 deletion crates/taskito-python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "taskito-python"
version = "0.12.0"
version = "0.12.1"
edition = "2021"

[features]
Expand Down
2 changes: 1 addition & 1 deletion crates/taskito-workflows/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "taskito-workflows"
version = "0.12.0"
version = "0.12.1"
edition = "2021"

[dependencies]
Expand Down
12 changes: 12 additions & 0 deletions docs/content/docs/more/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ description: "Release history for taskito — every notable change, fix, and fea

All notable changes to taskito are documented here.

## 0.12.1

### Fixed

- **PyPI wheels and sdist now bundle the compiled dashboard.** A regression in 0.12.0 shipped wheels with an empty `taskito/static/` directory because the release pipeline ran `maturin build` without first building the dashboard frontend. End users hit `Dashboard assets not bundled` when running `taskito dashboard`. The release pipeline now builds the dashboard once in a dedicated job, distributes it to every wheel/sdist job as a build artifact, and verifies `static/dashboard/index.html` is present before each `maturin build` invocation — preventing the regression class entirely.

### Internal

- **`.github/actions/dashboard-build/`** — composite action centralizing pnpm/Node toolchain versions and the dashboard build steps. Consumed by both `publish.yml` (release) and `dashboard.yml` (CI), so the assets shipped in a wheel are produced by the exact same build path that CI tests on every PR.

---

## 0.12.0

### Added
Expand Down
2 changes: 1 addition & 1 deletion py_src/taskito/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@

__version__ = _get_version("taskito")
except PackageNotFoundError:
__version__ = "0.12.0"
__version__ = "0.12.1"
8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "taskito"
version = "0.12.0"
version = "0.12.1"
description = "Rust-powered task queue for Python. No broker required."
requires-python = ">=3.10"
license = { file = "LICENSE" }
Expand Down Expand Up @@ -50,6 +50,12 @@ manifest-path = "crates/taskito-python/Cargo.toml"
python-source = "py_src"
module-name = "taskito._taskito"
features = ["extension-module", "postgres", "redis", "workflows"]
# Maturin's `python-source` only auto-packages Python sources (`.py`, `.pyi`,
# `py.typed`). The compiled dashboard SPA must be opted in explicitly so it
# ships in both the wheel and the sdist.
include = [
{ path = "py_src/taskito/static/dashboard/**/*", format = ["wheel", "sdist"] },
]

[project.scripts]
taskito = "taskito.cli:main"
Expand Down
Loading