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
59 changes: 59 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,62 @@ updates:
cooldown:
default-days: 5
open-pull-requests-limit: 5

# Root Bun workspace. Uses the `bun` ecosystem (Dependabot >= v1.2.5)
# rather than `npm`, so bun.lock and Bun-specific manifest features
# (including `catalog:`) are parsed by the correct updater. Groups
# keep transitive churn bundled so the PR queue stays reviewable.
- package-ecosystem: "bun"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "Asia/Shanghai"
cooldown:
default-days: 7
open-pull-requests-limit: 5
groups:
electron:
patterns:
- "electron"
- "electron-*"
- "@electron-forge/*"
- "@electron/*"
typescript-tooling:
patterns:
- "typescript"
- "@types/*"
- "@tsconfig/*"
- "ts-*"
- "tslib"
turbo-build:
patterns:
- "turbo"
- "@turbo/*"
- "vite"
- "@vitejs/*"
- "vitest"
- "@vitest/*"
testing:
patterns:
- "playwright"
- "@playwright/*"
- "@testing-library/*"
opencode:
patterns:
- "@opencode-ai/*"
production-minor-patch:
patterns:
- "*"
dependency-type: "production"
update-types:
- "minor"
- "patch"
development-minor-patch:
patterns:
- "*"
dependency-type: "development"
update-types:
- "minor"
- "patch"
25 changes: 15 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
outputs:
docs_only: ${{ steps.filter.outputs.docs_only }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
Expand Down Expand Up @@ -92,26 +92,26 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
persist-credentials: false

- uses: actions/setup-node@v6.3.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # actions/setup-node@v6.3.0
with:
node-version: "24"

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # oven-sh/setup-bun@v2
with:
bun-version: "1.3.11"

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: node_modules/.cache/turbo
key: turbo-${{ runner.os }}-${{ hashFiles('turbo.json', '**/package.json', 'bun.lock') }}-${{ github.sha }}
Expand All @@ -133,26 +133,26 @@ jobs:
contents: read
checks: write
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
persist-credentials: false

- uses: actions/setup-node@v6.3.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # actions/setup-node@v6.3.0
with:
node-version: "24"

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # oven-sh/setup-bun@v2
with:
bun-version: "1.3.11"

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: node_modules/.cache/turbo
key: turbo-${{ runner.os }}-${{ hashFiles('turbo.json', '**/package.json', 'bun.lock') }}-${{ github.sha }}
Expand Down Expand Up @@ -182,14 +182,19 @@ jobs:

- name: Upload unit artifacts
if: always()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # actions/upload-artifact@v7
with:
name: unit-${{ github.run_attempt }}
include-hidden-files: true
if-no-files-found: ignore
retention-days: 7
path: packages/*/.artifacts/unit/junit.xml

# Aggregator for the `dev` branch ruleset. The required check on GitHub
# is `ci / check`; every new job added above MUST be listed in `needs:`
# below, otherwise its failure will not block merge. If this list grows
# past ~5 entries, consider switching to `re-actors/alls-green` for
# dynamic aggregation (tracked in issue #54).
check:
if: always()
needs:
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# This workflow is a required merge check on `dev`. The exact ruleset
# entry to register is `codeql / analyze-js-ts`. PawWork runs user-
# authored skills and accesses the OS keychain; solo-dev code review is
# not a substitute for a JS/TS security scanner. Keep it in its own file
# (not folded into ci.yml) so security failures are legible in isolation.
# Decision recorded in issue #54 (D1).
name: codeql

on:
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: dependency-review

on:
pull_request:
branches: [dev]

concurrency:
group: dependency-review-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write

jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
persist-credentials: false

# Non-blocking during the initial rollout: `warn-only` makes policy
# findings (CVEs, license violations) surface as a comment without
# failing the job, while still failing loudly on action-level
# misconfiguration (auth, parser, network). GitHub supports bun.lock
# directly, but the `catalog:` field and workspace resolution are the
# real unknowns on this repo. Once a PR run shows the dep graph is
# parsed correctly, drop warn-only, set fail-on-severity: high, and
# add this job to the dev ruleset. Tracked in #54.
#
# Skipped on fork PRs: GITHUB_TOKEN is read-only, so the
# comment-summary-in-pr write would fail or silently no-op under
# warn-only. Mirrors the fork guard on the junit publisher in ci.yml.
- if: >
github.event.pull_request.head.repo.full_name == github.repository
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # actions/dependency-review-action@v4.9.0
with:
comment-summary-in-pr: always
warn-only: true
13 changes: 8 additions & 5 deletions .github/workflows/desktop-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
outputs:
docs_only: ${{ steps.filter.outputs.docs_only }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
Expand Down Expand Up @@ -92,26 +92,26 @@ jobs:
runs-on: macos-14
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
persist-credentials: false

- uses: actions/setup-node@v6.3.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # actions/setup-node@v6.3.0
with:
node-version: "24"

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # oven-sh/setup-bun@v2
with:
bun-version: "1.3.11"

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: |
~/Library/Caches/electron
Expand Down Expand Up @@ -185,6 +185,9 @@ jobs:
grep -q "Signature=adhoc" /tmp/pawwork-codesign.txt
working-directory: packages/desktop-electron

# Aggregator for the `dev` branch ruleset. The required check on GitHub
# is `desktop-smoke / check`; every new job added above MUST be listed
# in `needs:` below, otherwise its failure will not block merge.
check:
if: always()
needs:
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/e2e-artifacts.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# This workflow is intentionally non-blocking: it uploads Playwright
# artifacts on PRs for manual inspection but never fails the PR. Do NOT
# add `e2e-artifacts / e2e-artifacts` to the `dev` ruleset as a required
# check -- `continue-on-error: true` on the job means the check reports
# success even when tests fail, which would make the gate lie about
# every PR forever. Decision recorded in issue #54.
name: e2e-artifacts

on:
Expand Down Expand Up @@ -30,26 +36,26 @@ jobs:
timeout-minutes: 30
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6
with:
persist-credentials: false

- uses: actions/setup-node@v6.3.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # actions/setup-node@v6.3.0
with:
node-version: "24"

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # oven-sh/setup-bun@v2
with:
bun-version: "1.3.11"

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-

- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # actions/cache@v5
with:
path: ${{ github.workspace }}/.playwright-browsers
key: playwright-${{ runner.os }}-${{ hashFiles('packages/app/package.json', 'bun.lock') }}
Expand Down Expand Up @@ -81,7 +87,7 @@ jobs:

- name: Upload e2e artifacts
if: always()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # actions/upload-artifact@v7
with:
name: e2e-artifacts-linux-${{ github.run_attempt }}
if-no-files-found: ignore
Expand Down
3 changes: 0 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"dev:storybook": "bun --cwd packages/storybook storybook",
"typecheck": "bun turbo typecheck",
"postinstall": "bun run --cwd packages/opencode fix-node-pty",
"prepare": "husky",
"random": "echo 'Random script'",
"hello": "echo 'Hello World!'",
"test": "echo 'do not run tests from root' && exit 1"
Expand Down Expand Up @@ -81,7 +80,6 @@
"@types/mime-types": "3.0.1",
"@typescript/native-preview": "catalog:",
"glob": "13.0.5",
"husky": "9.1.7",
"prettier": "3.6.2",
"semver": "^7.6.0",
"sst": "3.18.10",
Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/test/config/e2e-artifacts-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ describe("e2e artifacts workflow", () => {
expect(parsed.permissions).toEqual({ contents: "read" })
expect(job?.["runs-on"]).toBe("ubuntu-latest")
expect(job?.["continue-on-error"]).toBe(true)
expect(checkoutStep?.uses).toBe("actions/checkout@v6")
expect(checkoutStep?.uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd")
expect(checkoutStep?.with).toEqual({ "persist-credentials": false })
expect(bunStep?.uses).toBe("oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6")
expect(installBrowsersStep?.run).toBe("bunx playwright install --with-deps chromium")
expect(runStep?.run).toContain("bun --cwd packages/app test:e2e:local:smoke")
expect(warnStep?.if).toBe("failure()")
expect(warnStep?.run).toContain("::warning::")
expect(uploadStep?.uses).toBe("actions/upload-artifact@v7")
expect(uploadStep?.uses).toBe("actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a")
expect(uploadStep?.with?.name).toBe("e2e-artifacts-linux-${{ github.run_attempt }}")
expect(uploadStep?.with?.["if-no-files-found"]).toBe("ignore")
expect(uploadStep?.with?.["retention-days"]).toBe(7)
Expand Down
8 changes: 4 additions & 4 deletions packages/opencode/test/github/ci-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ describe("ci workflow", () => {

expect(parsed.name).toBe("ci")
expect(parsed.permissions).toEqual({ contents: "read" })
expect(changesCheckoutStep?.uses).toBe("actions/checkout@v6")
expect(typecheckCheckoutStep?.uses).toBe("actions/checkout@v6")
expect(unitCheckoutStep?.uses).toBe("actions/checkout@v6")
expect(changesCheckoutStep?.uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd")
expect(typecheckCheckoutStep?.uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd")
expect(unitCheckoutStep?.uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd")

expect(changesCheckoutStep?.with).toEqual({
"fetch-depth": 0,
Expand All @@ -38,7 +38,7 @@ describe("ci workflow", () => {
expect(unitCheckoutStep?.with).toEqual({ "persist-credentials": false })
expect(unitBunStep?.uses).toBe("oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6")
expect(junitStep?.uses).toBe("mikepenz/action-junit-report@bccf2e31636835cf0874589931c4116687171386")
expect(uploadArtifactsStep?.uses).toBe("actions/upload-artifact@v7")
expect(uploadArtifactsStep?.uses).toBe("actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a")

expect(workflow).not.toContain("pull_request_target")
expect(workflow).not.toContain("persist-credentials: true")
Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/test/github/desktop-smoke-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ describe("desktop smoke workflow", () => {
expect(parsed.on?.workflow_dispatch).toEqual(null)
expect(parsed.permissions).toEqual({ contents: "read" })
expect(Object.keys(jobs).sort()).toEqual(["changes", "check", "smoke-macos-arm64"])
expect(changesCheckoutStep?.uses).toBe("actions/checkout@v6")
expect(smokeCheckoutStep?.uses).toBe("actions/checkout@v6")
expect(changesCheckoutStep?.uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd")
expect(smokeCheckoutStep?.uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd")

expect(changes?.outputs).toEqual({ docs_only: "${{ steps.filter.outputs.docs_only }}" })
expect(changesCheckoutStep?.with).toEqual({
Expand Down
Loading