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
2 changes: 2 additions & 0 deletions .config/mise/conf.d/aliases.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[shell_alias]
mr = "mise run"
5 changes: 5 additions & 0 deletions .config/mise/conf.d/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[task_config]
dir = "{{ config_root }}"

[env]
'_'.path = { path = "./node_modules/.bin" }
9 changes: 9 additions & 0 deletions .config/mise/conf.d/local.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[env]
## This is the template that is copied to mise.local.toml for local overrides
## This copy is committed to VCS to provide an example of local overrides
## Update it whenever new env vars are added to the project that may need local overrides
# Local environment overrides
# Uncomment and modify the variables below as needed

# VITE_PORT = 5173
# STORYBOOK_PORT = 6006
58 changes: 58 additions & 0 deletions .config/mise/conf.d/tasks-build.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[vars]
build_dir = ".var/dist"
webapp_out_dir = "{{ vars.build_dir }}/webapp"
storybook_out_dir = "{{ vars.build_dir }}/storybook"
gh_pages_out_dir = "{{ vars.build_dir }}/gh-pages"

# exposing defaults to terminal so that
# direct commands can be run consistently with tasks
[env]
# asserted in vite.config.ts
WEBAPP_OUT_DIR = "{{ vars.webapp_out_dir }}"
WEBAPP_BASE_URL = "/"
# asserted in .storybook/main.ts
STORYBOOK_BASE_URL = "/"
# expected in .github/workflows/deploy.yml
GH_PAGES_OUT_DIR = "{{ vars.gh_pages_out_dir }}"

[tasks."build:webapp:base"]
hide = true
usage = '''
arg "<dir>" env="WEBAPP_OUT_DIR" default="{{ vars.webapp_out_dir }}" help="Output directory for the webapp build"
arg "<base>" env="WEBAPP_BASE_URL" default="/" help="Base URL for the webapp"
'''
run = "WEBAPP_OUT_DIR=${usage_dir?} WEBAPP_BASE_URL=${usage_base?} vite build"

[tasks."build:webapp"]
description = "Build Application"
run = "mise run build:webapp:base"
sources = ["src/**/*.{ts,tsx}", "index.html", "vite.config.ts"]
outputs = ["{{ vars.webapp_out_dir }}/**/*"]

[tasks."build:storybook:base"]
hide = true
usage = '''
Comment thread
Guria marked this conversation as resolved.
arg "<dir>" env="STORYBOOK_OUT_DIR" default="{{ vars.storybook_out_dir }}" help="Output directory for the Storybook build"
arg "<base>" env="STORYBOOK_BASE_URL" default="/" help="Base URL for the Storybook"
'''
run = "STORYBOOK_BASE_URL=${usage_base?} storybook build -o ${usage_dir?}"

[tasks."build:storybook"]
description = "Build Storybook"
run = "mise run build:storybook:base"
sources = ["src/**/*.{ts,tsx,stories.tsx}", ".storybook/**/*"]
outputs = ["{{ vars.storybook_out_dir }}/**/*"]

[tasks."build"]
description = "Run all build tasks"
run = [{ task = "build:webapp" }, { task = "build:storybook" }]

[tasks."build:gh-pages"]
description = "Prepare deployment artifacts (combine builds for GitHub Pages)"
run = [
"mise run build:webapp:base {{ vars.gh_pages_out_dir }} /modern-stack/",
"mise run build:storybook:base {{ vars.gh_pages_out_dir }}/storybook /modern-stack/storybook",
]
sources = ["src/**/*.{ts,tsx}", "index.html", "vite.config.ts", ".storybook/**/*"]
outputs = ["{{ vars.gh_pages_out_dir }}/**/*"]

30 changes: 30 additions & 0 deletions .config/mise/conf.d/tasks-dev.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Development tasks

[vars]
vite_port = "5173"
storybook_port = "6006"

[tasks.dev]
description = "Start Vite dev server"
usage = '''
flag "-p --port <port>" default="{{ vars.vite_port }}" help="Port for the Vite dev server"
arg "[rest]" help="Additional arguments to pass to Vite"
'''
run = "vite --port ${usage_port?} ${usage_rest}"

[tasks.storybook]
description = "Start Storybook dev server"
alias = "sb"
usage = '''
flag "-p --port <port>" default="{{ vars.storybook_port }}" help="Port for the Storybook dev server"
'''
run = "storybook dev -p ${usage_port?}"

[tasks.preview]
description = "Preview production build"
depends = ["build:webapp"]
run = "vite preview"

[tasks.clean]
description = "Clean build artifacts and caches"
run = ["rm -rf .var", "rm -rf node_modules/.vite", "rm -rf coverage"]
30 changes: 30 additions & 0 deletions .config/mise/conf.d/tasks-prepare.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[vars]
panda_outdir = "src/shared/styled-system"
panda_config = "panda.config.ts"

[env]
PANDA_OUTDIR = "{{ vars.panda_outdir }}"

[tasks."prepare:panda"]
description = "Run Panda code generation"
run = "panda codegen"

sources = ["{{ vars.panda_config }}", "theme/**/*.ts", "components.json"]
outputs = ["{{ vars.panda_outdir }}/**/*"]

[tasks."prepare:git-hooks"]
description = "Install Git hooks"
run = "lefthook install"
sources = ["lefthook.yml"]

[tasks."prepare:local-overrides"]
description = "Setup local overrides file if not exists"
run = "if [ ! -f mise.local.toml ]; then sed '/^##/d' .config/mise/conf.d/local.toml > mise.local.toml; fi"

[tasks.prepare]
description = "Prepare project"
run = [
{ task = "prepare:panda" },
{ task = "prepare:git-hooks" },
{ task = "prepare:local-overrides" },
]
Comment thread
Guria marked this conversation as resolved.
39 changes: 39 additions & 0 deletions .config/mise/conf.d/tasks-quality.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Code quality tasks

[tasks.format]
description = "Format code with oxfmt"
alias = "fmt"
run = "oxfmt --write ."

[tasks."format:check"]
description = "Check code formatting"
alias = "fmt:check"
run = "oxfmt --check ."

[tasks.lint]
description = "Lint code with oxlint"
run = "oxlint ."

[tasks.typecheck]
description = "Type check with TypeScript"
alias = "tc"
run = "tsc -b"
sources = ["src/**/*.{ts,tsx}", "tsconfig*.json"]
Comment thread
coderabbitai[bot] marked this conversation as resolved.

[tasks.validate]
description = "Run all quality checks (format, lint, typecheck, test). Default validation task for LLMs"
run = [ #
{ task = "prepare" },
{ task = "format" },
{ tasks = ["lint", "typecheck", "test:run"] },
]

[tasks.ci]
description = "Run all CI checks. No auto-fixes"
run = [
{ task = "format:check" },
{ task = "lint" },
{ task = "typecheck" },
{ task = "test:coverage" },
{ task = "build" },
]
Comment thread
Guria marked this conversation as resolved.
30 changes: 30 additions & 0 deletions .config/mise/conf.d/tasks-test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Testing tasks

[vars]
test_timeout = "10000"
Comment thread
Guria marked this conversation as resolved.
coverage_threshold_lines = "80"
coverage_threshold_functions = "80"
coverage_threshold_branches = "75"
coverage_threshold_statements = "80"

[env]
TEST_TIMEOUT = "{{ vars.test_timeout }}"
COVERAGE_THRESHOLD_LINES = "{{ vars.coverage_threshold_lines }}"
COVERAGE_THRESHOLD_FUNCTIONS = "{{ vars.coverage_threshold_functions }}"
COVERAGE_THRESHOLD_BRANCHES = "{{ vars.coverage_threshold_branches }}"
COVERAGE_THRESHOLD_STATEMENTS = "{{ vars.coverage_threshold_statements }}"

[tasks.test]
description = "Run tests in watch mode"
alias = "t"
run = "vitest"

[tasks."test:run"]
description = "Run tests once"
alias = "tr"
run = "vitest run"

[tasks."test:coverage"]
description = "Run tests with coverage"
alias = "tcov"
run = "vitest run --coverage"
2 changes: 2 additions & 0 deletions mise.toml → .config/mise/conf.d/tools.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Tool versions
[tools]
bun = "1.3.6"
node = "lts"
jq = "latest"
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,24 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Setup mise
uses: jdx/mise-action@v2
uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
with:
install: true
cache: true

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

- name: Run prepare script
run: bun run prepare

- name: Build app
run: bun run build

- name: Verify app build
run: test -f dist/index.html || exit 1

- name: Build Storybook
run: bun run build-storybook

- name: Verify Storybook build
run: test -f storybook-static/index.html || exit 1

- name: Combine builds
run: |
mkdir -p dist/storybook
cp -r storybook-static/. dist/storybook/
- name: Build artifacts
run: mise run build:gh-pages

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: ./dist
path: ${{ env.GH_PAGES_OUT_DIR }}
Comment thread
Guria marked this conversation as resolved.
Comment thread
Guria marked this conversation as resolved.

deploy:
needs: build
Expand All @@ -69,4 +52,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
24 changes: 6 additions & 18 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Setup mise
uses: jdx/mise-action@v2
uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
with:
install: true
cache: true

- name: Cache Bun dependencies
uses: actions/cache@v4
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.bun/install/cache
Expand All @@ -39,25 +39,13 @@ jobs:
- name: Install Playwright browsers
run: bunx playwright install --with-deps chromium

- name: Run prepare script
run: bun run prepare

- name: Type check
run: bun run typecheck

- name: Format check
run: bun run format:check

- name: Lint
run: bun run lint

- name: Run Storybook tests
run: xvfb-run --auto-servernum -- bun run test:run --coverage
- name: Run CI checks
run: mise run ci
env:
CI: true

- name: Upload coverage reports
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: success()
with:
name: coverage-reports
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
.env.test.local
.env.production.local
.env.local
mise.local.toml

# caches
.eslintcache
.cache
.var
*.tsbuildinfo

# IntelliJ based IDEs
Expand All @@ -36,9 +38,10 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
## Panda
styled-system
styled-system-studio

# Storybook
*storybook.log
storybook-static
docs

# ralphex progress logs
progress*.txt
12 changes: 6 additions & 6 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { defineMain } from '@storybook/react-vite/node'
import assert from 'node:assert'

const base = process.env['STORYBOOK_BASE_URL']
assert(base, 'STORYBOOK_BASE_URL env var is not set')

export default defineMain({
core: { disableTelemetry: true },
Expand All @@ -9,12 +13,8 @@ export default defineMain({
},
stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-vitest', '@storybook/addon-a11y', '@storybook/addon-docs'],
viteFinal: (config, { configType }) => {
if (process.env['CI'] === 'true' && configType === 'PRODUCTION') {
config.base = '/modern-stack/storybook/'
} else {
config.base = '/'
}
viteFinal: (config) => {
config.base = base
return config
},
})
10 changes: 9 additions & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { context } from '@reatom/core'

import '../src/index.css'
import '../src/reatom.init.ts'
import { context } from '@reatom/core'
import { reatomContext } from '@reatom/react'
import addonA11y from '@storybook/addon-a11y'
import { definePreview } from '@storybook/react-vite'
import { useMemo, type PropsWithChildren } from 'react'

import { css } from '#styled-system/css'

function ReatomDecorator({ children }: PropsWithChildren) {
// Create fresh context once per story mount to prevent state pollution
const frame = useMemo(() => context.start(), [])
Expand All @@ -20,6 +23,11 @@ const preview = definePreview({
<Story />
</ReatomDecorator>
),
(Story) => (
<div className={css({ colorPalette: 'orange' })}>
<Story />
</div>
),
],
parameters: {
controls: {
Expand Down
Loading