first commit

This commit is contained in:
Matt Kane
2026-04-01 10:44:22 +01:00
commit 43fcb9a131
1789 changed files with 395041 additions and 0 deletions

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

35
.github/workflows/bonk.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: Bonk
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
bonk:
if: github.event.sender.type != 'Bot'
runs-on: ubuntu-latest
timeout-minutes: 40
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.issue.number || github.ref }}
cancel-in-progress: false
permissions:
id-token: write
issues: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Run Bonk
uses: ask-bonk/ask-bonk/github@c39e982defd0114385df54e72012a3fc4333c4d4 # main 2026-03-23
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_AI_GATEWAY_ACCOUNT_ID }}
CLOUDFLARE_GATEWAY_ID: ${{ secrets.CF_AI_GATEWAY_NAME }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_AI_GATEWAY_TOKEN }}
with:
model: "cloudflare-ai-gateway/anthropic/claude-opus-4-6"
mentions: "/bonk,@ask-bonk"

203
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,203 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
typecheck:
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm typecheck
- run: pnpm run --filter emdashcms-demo --filter @emdashcms/demo-cloudflare typecheck
- run: pnpm typecheck:templates
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm lint:json
test:
name: Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:17
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: emdash_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run --filter emdashcms... build
- run: pnpm test:unit
env:
EMDASH_TEST_PG: postgres://postgres:test@localhost:5432/emdash_test
validate-plugins:
name: Validate Plugins
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run --filter emdashcms... build
- name: Validate marketplace plugins
run: |
CLI="node packages/core/dist/cli/index.mjs"
for dir in packages/plugins/*/; do
[ -f "$dir/package.json" ] || continue
if [ ! -f "$dir/src/sandbox-entry.ts" ] && \
! grep -q '"./sandbox"' "$dir/package.json" 2>/dev/null; then
continue
fi
name=$(basename "$dir")
case "$name" in
marketplace-test|sandboxed-test|api-test) continue ;;
esac
echo "::group::Validating $name"
$CLI plugin bundle --validateOnly --dir "$dir"
echo "::endgroup::"
done
test-smoke:
name: Smoke Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:17
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: emdash_smoke
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm --filter emdashcms exec vitest run --config vitest.smoke.config.ts
timeout-minutes: 5
env:
DATABASE_URL: postgres://postgres:test@localhost:5432/emdash_smoke
test-browser:
name: Browser Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run --filter @emdashcms/admin... build
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: playwright-${{ hashFiles('pnpm-lock.yaml') }}
- run: pnpm exec playwright install --with-deps chromium
if: steps.playwright-cache.outputs.cache-hit != 'true'
- run: pnpm run --filter @emdashcms/admin test
test-e2e:
name: E2E tests (${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
shardTotal: [8]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run --filter emdashcms... build
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: playwright-${{ hashFiles('pnpm-lock.yaml') }}
- run: pnpm exec playwright install --with-deps chromium
if: steps.playwright-cache.outputs.cache-hit != 'true'
- run: pnpm exec playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: failure()
with:
name: playwright-report-${{ matrix.shardIndex }}
path: |
playwright-report/
test-results/
retention-days: 7

View File

@@ -0,0 +1,73 @@
name: Seed Marketplace Plugins
on:
workflow_dispatch:
push:
branches: [main]
paths:
- "packages/plugins/**"
- ".github/workflows/deploy-marketplace.yml"
permissions:
contents: read
concurrency:
group: seed-marketplace
cancel-in-progress: false
jobs:
seed:
name: Seed Plugins
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
# Build core (produces the CLI at dist/cli/index.mjs)
- run: pnpm run --filter emdashcms... build
# Bundle and publish each standard-format plugin.
# Only plugins with a sandbox entry can be marketplace-installed.
# Invokes the built CLI directly via node since pnpm exec can't
# resolve binaries from workspace packages (only from dependencies).
- name: Seed plugins
run: |
CLI="node packages/core/dist/cli/index.mjs"
failures=0
for dir in packages/plugins/*/; do
[ -f "$dir/package.json" ] || continue
# Only include plugins that have a sandbox entry
if [ ! -f "$dir/src/sandbox-entry.ts" ] && \
! grep -q '"./sandbox"' "$dir/package.json" 2>/dev/null; then
continue
fi
name=$(basename "$dir")
# Skip test-only plugins
case "$name" in
marketplace-test|sandboxed-test|api-test) continue ;;
esac
echo "::group::$name"
$CLI plugin publish --build --dir "$dir" --no-wait --registry "$MARKETPLACE_URL" || {
echo "::warning::Failed to publish $name"
failures=$((failures + 1))
}
echo "::endgroup::"
done
if [ "$failures" -gt 0 ]; then
echo "::error::$failures plugin(s) failed to publish"
exit 1
fi
env:
EMDASH_MARKETPLACE_TOKEN: ${{ secrets.MARKETPLACE_SEED_TOKEN }}
MARKETPLACE_URL: https://marketplace.emdashcms.com

26
.github/workflows/format.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Format
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
format:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm format:check