Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8cffce7
:sparkles: feat: harden ingestion pipeline and source dispatch
LinMoQC Apr 4, 2026
7d7cdca
:package: chore: snapshot current workspace state
LinMoQC Apr 5, 2026
c9f306f
chore: snapshot current workspace before desktop refactor
LinMoQC Apr 16, 2026
e62f2bb
:sparkles: feat(desktop): bootstrap tauri runtime supervisor
LinMoQC Apr 17, 2026
5ada5db
:sparkles: feat(api): add desktop runtime services and release automa…
LinMoQC Apr 22, 2026
fe7c3e0
:sparkles: feat(apps): refresh desktop web and shared packages
LinMoQC Apr 22, 2026
3531835
:memo: docs(exec-plans): archive desktop implementation plans
LinMoQC Apr 22, 2026
7346b1d
:white_check_mark: test(web): fix chat bubble streaming cursor regres…
LinMoQC Apr 22, 2026
9b56717
:ambulance: fix(ci): restore PR47 web and api checks
LinMoQC Apr 22, 2026
dde68fd
:ambulance: fix(ci): remove premature api coverage gate
LinMoQC Apr 22, 2026
f75b8d9
:rocket: chore(release): prepare desktop v1.0.1 publish
LinMoQC Apr 22, 2026
bd22030
:ambulance: fix(release): skip cli publish when npm token missing
LinMoQC Apr 22, 2026
424d6ed
:ambulance: fix(release): create tagged releases from tag refs
LinMoQC Apr 22, 2026
e031253
:ambulance: fix(release): manage draft releases via GitHub API
LinMoQC Apr 22, 2026
45a2d15
:ambulance: fix(release): pin tauri action to a published tag
LinMoQC Apr 23, 2026
bada4ee
:ambulance: fix(release): use tauri action assetNamePattern input
LinMoQC Apr 23, 2026
9fec33b
:wrench: chore(release): stabilize desktop release asset upload
LinMoQC Apr 23, 2026
68214fa
✨ feat(chat): smooth transition animations for new chat flow
LinMoQC Apr 23, 2026
7095a71
✨ feat(observability): harden traces and GenUI note workflows
LinMoQC Apr 25, 2026
8bf3770
:ambulance: fix(ci): align observability fixtures and react types
LinMoQC Apr 25, 2026
50d8c14
:ambulance: fix(api): stabilize cancelled output persistence test
LinMoQC Apr 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
67 changes: 67 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,63 @@ jobs:
- name: Frontend tests
run: pnpm test

- name: Frontend coverage
run: pnpm test:coverage

monitoring-tests:
name: Monitoring — Typecheck & Test
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/monitoring

steps:
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v6
with:
node-version: 20
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

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

- name: TypeScript typecheck
run: pnpm typecheck

- name: Monitoring tests
run: pnpm test

desktop-tests:
name: Desktop — Typecheck & Test
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/desktop

steps:
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v6
with:
node-version: 20
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

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

- name: TypeScript typecheck
run: pnpm typecheck

- name: Desktop tests
run: pnpm test

# ── API tests ───────────────────────────────────────────────────────────────
api-tests:
name: API — Tests
Expand Down Expand Up @@ -101,6 +158,16 @@ jobs:
OPENAI_API_KEY: sk-test
run: pytest tests/ -v --tb=short --ignore=tests/e2e

- name: Coverage report
env:
DATABASE_URL: postgresql+asyncpg://lyranote:lyranote@localhost:5432/lyranote_test
REDIS_URL: redis://localhost:6379/0
JWT_SECRET: test-secret-key
STORAGE_BACKEND: local
STORAGE_LOCAL_PATH: /tmp/lyranote-test-storage
OPENAI_API_KEY: sk-test
run: pytest tests/ --cov=app --cov-report=term-missing --ignore=tests/e2e

- name: E2E API tests
env:
DATABASE_URL: postgresql+asyncpg://lyranote:lyranote@localhost:5432/lyranote_test
Expand Down
207 changes: 186 additions & 21 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,184 @@ permissions:
contents: write

jobs:
release:
name: Create GitHub Release
prepare-release:
name: Prepare draft release
runs-on: ubuntu-latest
outputs:
release_id: ${{ steps.release.outputs.release_id }}
version: ${{ steps.meta.outputs.version }}
prerelease: ${{ steps.meta.outputs.prerelease }}

steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Extract changelog for this version
id: changelog
- name: Extract release metadata
id: meta
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
# Extract the section for this version from CHANGELOG.md
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "Release tag must be a SemVer tag like v1.2.3 or v1.2.3-beta.1" >&2
exit 1
fi

NOTES=$(awk "/^## \[$VERSION\]/{found=1; next} found && /^## \[/{exit} found{print}" CHANGELOG.md)
if [ -z "$NOTES" ]; then
NOTES="See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details."
fi
echo "notes<<EOF" >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
printf '%s\n' "$NOTES" > release-notes.md

echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if [[ "$GITHUB_REF_NAME" == *-* ]]; then
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi

- name: Create or refresh draft release
id: release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
shell: bash
run: |
PRERELEASE="${{ steps.meta.outputs.prerelease }}"

if RELEASE_ID=$(gh api "repos/${{ github.repository }}/releases/tags/$GITHUB_REF_NAME" --jq '.id' 2>/dev/null); then
jq -n \
--arg name "LyraNote $GITHUB_REF_NAME" \
--rawfile body release-notes.md \
--argjson prerelease "$PRERELEASE" \
'{
name: $name,
body: $body,
draft: true,
prerelease: $prerelease
}' > release-payload.json

gh api \
--method PATCH \
"repos/${{ github.repository }}/releases/$RELEASE_ID" \
--input release-payload.json >/dev/null
else
jq -n \
--arg tag_name "$GITHUB_REF_NAME" \
--arg name "LyraNote $GITHUB_REF_NAME" \
--rawfile body release-notes.md \
--argjson prerelease "$PRERELEASE" \
'{
tag_name: $tag_name,
name: $name,
body: $body,
draft: true,
prerelease: $prerelease
}' > release-payload.json

RELEASE_ID=$(gh api \
--method POST \
"repos/${{ github.repository }}/releases" \
--input release-payload.json \
--jq '.id')
fi
echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT"

desktop-macos:
name: Desktop macOS (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
needs: prepare-release
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
- arch: aarch64
runner: macos-15
target: aarch64-apple-darwin
- arch: x86_64
runner: macos-15-intel
target: x86_64-apple-darwin

steps:
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v6
with:
node-version: 20
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: apps/api/requirements*.txt

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
- uses: dtolnay/rust-toolchain@stable
with:
tag_name: ${{ github.ref_name }}
name: "LyraNote ${{ github.ref_name }}"
body: ${{ steps.changelog.outputs.notes }}
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
generate_release_notes: true
targets: ${{ matrix.target }}

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

- name: Install API sidecar dependencies
run: python -m pip install -r apps/api/requirements.txt -r apps/api/requirements-dev.txt

- name: Sync desktop version from tag
env:
RELEASE_VERSION: ${{ needs.prepare-release.outputs.version }}
run: |
node <<'NODE'
const fs = require("fs")
const version = process.env.RELEASE_VERSION

function writeJson(path, patch) {
const data = JSON.parse(fs.readFileSync(path, "utf8"))
patch(data)
fs.writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`)
}

writeJson("apps/desktop/package.json", (data) => {
data.version = version
})
writeJson("apps/desktop/src-tauri/tauri.conf.json", (data) => {
data.version = version
})

const cargoPath = "apps/desktop/src-tauri/Cargo.toml"
const cargo = fs.readFileSync(cargoPath, "utf8")
fs.writeFileSync(
cargoPath,
cargo.replace(/^version = ".*"$/m, `version = "${version}"`),
)
NODE

- name: Build bundled API sidecar
run: python apps/api/scripts/build_desktop_sidecar.py --target-triple "${{ matrix.target }}"

- name: Build and upload Tauri desktop artifacts
uses: tauri-apps/tauri-action@action-v0.6.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with:
projectPath: apps/desktop
tagName: ${{ github.ref_name }}
releaseDraft: true
prerelease: ${{ needs.prepare-release.outputs.prerelease }}
args: --target ${{ matrix.target }}
assetNamePattern: LyraNote-[version]-macos-[arch]-[bundle][ext]

publish-cli:
name: Publish @lyranote/cli to npm
runs-on: ubuntu-latest
needs: release
needs: prepare-release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

steps:
- uses: actions/checkout@v6
Expand All @@ -60,11 +202,34 @@ jobs:
run: pnpm install --frozen-lockfile

- name: Sync version from git tag
run: |
VERSION="${GITHUB_REF_NAME#v}"
pnpm --filter @lyranote/cli exec npm version "$VERSION" --no-git-tag-version
run: pnpm --filter @lyranote/cli exec npm version "${{ needs.prepare-release.outputs.version }}" --no-git-tag-version

- name: Skip npm publish when token missing
if: ${{ env.NPM_TOKEN == '' }}
run: echo "NPM_TOKEN is not configured; skipping @lyranote/cli publish."

- name: Publish to npm
if: ${{ env.NPM_TOKEN != '' }}
run: pnpm --filter @lyranote/cli publish --access public --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}

publish-release:
name: Publish GitHub Release
runs-on: ubuntu-latest
needs:
- prepare-release
- desktop-macos

steps:
- name: Publish draft release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
shell: bash
run: |
if [[ "${{ needs.prepare-release.outputs.prerelease }}" == "true" ]]; then
gh release edit "$GITHUB_REF_NAME" --draft=false --prerelease
else
gh release edit "$GITHUB_REF_NAME" --draft=false --prerelease=false --latest
fi
17 changes: 16 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
{
"git.ignoreLimitWarning": true
"git.ignoreLimitWarning": true,
"terminal.integrated.env.osx": {
"ANTHROPIC_AUTH_TOKEN": "",
"ANTHROPIC_BASE_URL": "",
"ANTHROPIC_API_KEY": ""
},
"terminal.integrated.env.linux": {
"ANTHROPIC_AUTH_TOKEN": "",
"ANTHROPIC_BASE_URL": "",
"ANTHROPIC_API_KEY": ""
},
"terminal.integrated.env.windows": {
"ANTHROPIC_AUTH_TOKEN": "",
"ANTHROPIC_BASE_URL": "",
"ANTHROPIC_API_KEY": ""
}
}
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [1.0.1] - 2026-04-23

### Added
- LyraNote Desktop 的 macOS 打包与 GitHub Release 自动发布流程
- 桌面端应用内自动更新能力,包括 updater artifacts、签名与 `latest.json` 分发
- 桌面端运行时与本地 sidecar 的发布级集成,支持 Apple Silicon / Intel 双架构构建

### Fixed
- 修复打包后桌面 sidecar 启动不稳定导致的 runtime 卡住问题
- 修复桌面端聊天流式光标回归与 PR #47 的 CI 阻塞问题

### Changed
- Release workflow 调整为 draft-first 流程,并将 CLI npm 发布改为可选步骤
- 桌面端应用图标与 Web 端保持一致

---

## [0.3.0] - 2026-03-26

### Added
Expand Down Expand Up @@ -55,6 +72,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Docker Compose dev and production configurations
- Bilingual UI (Chinese / English) with next-intl

[Unreleased]: https://github.com/LinMoQC/LyraNote/compare/v0.3.0...HEAD
[Unreleased]: https://github.com/LinMoQC/LyraNote/compare/v1.0.1...HEAD
[1.0.1]: https://github.com/LinMoQC/LyraNote/compare/v1.0.0...v1.0.1
[0.3.0]: https://github.com/LinMoQC/LyraNote/compare/v0.2.0...v0.3.0
[0.1.0]: https://github.com/LinMoQC/LyraNote/releases/tag/v0.1.0
Loading
Loading