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
156 changes: 156 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Compatibility matrix behind the slim PR gate (#31): the PR gate ships one job,
# ubuntu · Node 24 · DSH 0.2.0-rc.2. This workflow restores Windows · Node 24 ·
# DSH 0.2.0-rc.2, ubuntu · Node 22 · DSH 0.2.0-rc.2 and ubuntu · Node 24 ·
# DSH 0.2.1-alpha.1 on schedule and dispatch, and supersedes the matrix/compat
# parts of #29. A window in which main had no commits is skipped; a schedule only
# fires on the default branch. macOS runs locally on a Mac with `npm run ci:local`
# (ds-bot/scripts/local-ci.sh), never on a GitHub-hosted runner.

name: Compatibility

on:
schedule:
- cron: "0 16 * * *" # daily 00:00 Asia/Shanghai
- cron: "0 17 * * 6" # weekly Sunday 01:00 Asia/Shanghai
workflow_dispatch:

permissions:
contents: read

concurrency:
group: compat-${{ github.ref }}
cancel-in-progress: false

jobs:
changes:
name: Window check
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
run: ${{ steps.gate.outputs.run }}
steps:
- name: Check out main with full history
if: github.event_name == 'schedule'
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Decide whether the window has commits on main
id: gate
shell: bash
run: |
run=false
since=""
case "${{ github.event.schedule }}" in
"0 16 * * *") since="24 hours ago" ;;
"0 17 * * 6") since="7 days ago" ;;
esac
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
run=true
reason="manual dispatch always runs"
elif [ -n "$since" ] && [ -n "$(git log --since="$since" --pretty=oneline)" ]; then
run=true
reason="main had commits in the last ${since}"
else
reason="main had no commits in the window (since ${since})"
fi
echo "run=$run" >> "$GITHUB_OUTPUT"
{
echo "### Compatibility run decision"
echo ""
echo "- event: \`${{ github.event_name }}\`"
echo "- window: ${since:-n/a (dispatch)}"
echo "- run: \`${run}\`: ${reason}"
} >> "$GITHUB_STEP_SUMMARY"

daily:
name: compat · ${{ matrix.os }} · Node ${{ matrix.node }} · DSH ${{ matrix.dsh }}
needs: changes
if: needs.changes.outputs.run == 'true' && (github.event_name == 'workflow_dispatch' || github.event.schedule == '0 16 * * *')
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-latest, node: 22, dsh: 0.2.0-rc.2 }
- { os: ubuntu-latest, node: 24, dsh: 0.2.1-alpha.1 }
defaults:
run:
shell: bash
working-directory: ds-bot
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: ds-bot/package-lock.json
- name: npm ci
run: npm ci --no-fund --no-audit
timeout-minutes: 5
- name: Install DSH ${{ matrix.dsh }}
run: npm run harness -- --no-save "@deepseek-ai/dsh@$DSH"
timeout-minutes: 5
env:
DSH: ${{ matrix.dsh }}
- name: Lint
run: npm run lint
- name: Build (client bundle is up to date)
run: node scripts/build-client.mjs --check
- name: Tests
run: npm test
- name: Plugin tests (social)
working-directory: ds-bot/plugins/social
run: node --import ../../test/harness-resolve.mjs --test "test/*.test.js"
- name: Plugin tests (tree)
working-directory: ds-bot/plugins/tree
run: node --test "test/*.test.js"

weekly:
name: compat · ${{ matrix.os }} · Node ${{ matrix.node }} · DSH ${{ matrix.dsh }}
needs: changes
if: needs.changes.outputs.run == 'true' && (github.event_name == 'workflow_dispatch' || github.event.schedule == '0 17 * * 6')
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- { os: windows-latest, node: 24, dsh: 0.2.0-rc.2 }
defaults:
run:
shell: bash
working-directory: ds-bot
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: ds-bot/package-lock.json
- name: npm ci
run: npm ci --no-fund --no-audit
timeout-minutes: 5
- name: Install DSH ${{ matrix.dsh }}
run: npm run harness -- --no-save "@deepseek-ai/dsh@$DSH"
timeout-minutes: 5
env:
DSH: ${{ matrix.dsh }}
- name: Lint
run: npm run lint
- name: Build (client bundle is up to date)
run: node scripts/build-client.mjs --check
- name: Tests
run: npm test
- name: Plugin tests (social)
working-directory: ds-bot/plugins/social
run: node --import ../../test/harness-resolve.mjs --test "test/*.test.js"
- name: Plugin tests (tree)
working-directory: ds-bot/plugins/tree
run: node --test "test/*.test.js"
16 changes: 13 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ name: Test
on:
push:
branches: [main]
# Docs-only pushes do not need the shipgate.
# pull_request must NOT ignore docs: Test is a required check there, and a
# skipped required check would block docs-only pull requests.
paths-ignore: ['docs/**', '**/*.md']
pull_request:
workflow_dispatch:

Expand All @@ -11,17 +15,18 @@ permissions:

concurrency:
group: test-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
test:
name: ${{ matrix.os }} · Node ${{ matrix.node }} · DSH ${{ matrix.dsh }}
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
# Slim PR/push shipgate: one cheap job.
# Dropped from the required matrix (restore later as nightly/manual if needed):
# The dropped legs run in the Compatibility workflow (nightly.yml):
# - windows-latest · Node 24 · DSH 0.2.0-rc.2
# - ubuntu-latest · Node 22 · DSH 0.2.0-rc.2
# - ubuntu-latest · Node 24 · DSH 0.2.1-alpha.1
Expand All @@ -33,14 +38,19 @@ jobs:
working-directory: ds-bot
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: ds-bot/package-lock.json
- run: npm ci --no-fund --no-audit
- name: npm ci
run: npm ci --no-fund --no-audit
timeout-minutes: 5
- name: Install DSH ${{ matrix.dsh }}
run: npm run harness -- --no-save "@deepseek-ai/dsh@${{ matrix.dsh }}"
timeout-minutes: 5
- run: npm test
- name: Build (client bundle is up to date)
run: node scripts/build-client.mjs --check
Expand Down
3 changes: 2 additions & 1 deletion ds-bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"test": "node --import ./test/harness-resolve.mjs --test \"test/*.test.js\"",
"lint": "node scripts/lint.mjs",
"harness": "npm install --prefix dev/harness --legacy-peer-deps=false --no-package-lock --no-fund --no-audit",
"check": "sh dev/check.sh"
"check": "sh dev/check.sh",
"ci:local": "bash scripts/local-ci.sh"
},
"peerDependencies": {
"@deepseek-ai/cordis": "*",
Expand Down
59 changes: 59 additions & 0 deletions ds-bot/scripts/local-ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Local compatibility CI for a Mac: the PR gate plus the plugin suites, with no
# GitHub-hosted runner. Run it from anywhere: ds-bot/scripts/local-ci.sh
set -euo pipefail

cd "$(dirname "${BASH_SOURCE[0]}")/.."

step="(start)"

on_exit() {
local status=$?
if [ "$status" -eq 0 ]; then
echo "PASS: $(git rev-parse --short HEAD)"
else
echo "FAIL: $step (exit $status)"
fi
}
trap on_exit EXIT

echo "FlyBot local CI"
echo "tip: $(git rev-parse --short HEAD) ($(git rev-parse HEAD))"
echo "branch: $(git branch --show-current)"

step="node -v (require major >= 22)"
echo "=== $step ==="
node -v
node_version="$(node -v)"
node_version="${node_version#v}"
if [ "${node_version%%.*}" -lt 22 ]; then
exit 1
fi

step="npm ci"
echo "=== $step ==="
npm ci --no-fund --no-audit

step="Install DSH 0.2.0-rc.2"
echo "=== $step ==="
npm run harness -- --no-save @deepseek-ai/dsh@0.2.0-rc.2

step="lint"
echo "=== $step ==="
npm run lint

step="Build (client bundle is up to date)"
echo "=== $step ==="
node scripts/build-client.mjs --check

step="tests"
echo "=== $step ==="
npm test

step="plugin tests (social)"
echo "=== $step ==="
(cd plugins/social && node --import ../../test/harness-resolve.mjs --test "test/*.test.js")

step="plugin tests (tree)"
echo "=== $step ==="
(cd plugins/tree && node --test "test/*.test.js")
Loading