Compare commits

...

130 Commits

Author SHA1 Message Date
Cats Juice
423c5bd711 fix(core): adjust ai chat tool calling style (#12985)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Enhanced the visual appearance of tool cards with improved
backgrounds, shine animation, refined layouts, and smoother
collapse/expand transitions.
* Updated icon sizes, hover effects, and icon presentation for a more
polished user experience.

* **Bug Fixes**
* Improved result rendering logic to prevent errors when result arrays
are empty.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 06:29:33 +00:00
EYHN
3d12bb2adf feat(core): add missing affine version header to server config (#12986)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a custom version header to server configuration requests for
improved request context.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 04:56:57 +00:00
fengmk2
a2810f3f61 feat(server): send comment notifications (#12925)
close CLOUD-228















#### PR Dependency Tree


* **PR #12924**
  * **PR #12925** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-07-01 14:25:31 +00:00
fengmk2
7ed72ed1d0 feat(server): support comment notification type (#12924)
#### PR Dependency Tree


* **PR #12924** 👈
  * **PR #12925**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced comment and comment mention notifications, including email
notifications when users are mentioned or receive comments on documents.
* Added new email templates for comment and comment mention
notifications.
* Users can now control whether they receive comment-related emails via
a new user setting.

* **Bug Fixes**
  * None.

* **Documentation**
* Updated GraphQL schema documentation to reflect new notification types
and user settings.

* **Refactor**
* Streamlined and enhanced test coverage for notification and user
settings, including comment notifications.

* **Chores**
* Improved test setup and snapshot coverage for user settings and
notifications.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 13:48:06 +00:00
fengmk2
2aa5c13082 feat(server): comment service and resolver (#12761)
close CLOUD-227
close CLOUD-230

































#### PR Dependency Tree


* **PR #12761** 👈
  * **PR #12924**
    * **PR #12925**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced a comprehensive commenting system, enabling users to
create, update, resolve, and delete comments and replies on documents.
* Added support for uploading attachments to comments, with clear error
messaging if size limits are exceeded.
* Implemented role-based permissions for comment actions, including a
new "Commenter" role.
* Enabled paginated listing and change tracking of comments and replies
via GraphQL queries.
* Provided full localization and error handling for comment-related
actions.

* **Bug Fixes**
* Improved uniqueness handling when fetching user data for comments and
replies.

* **Documentation**
* Extended GraphQL schema and frontend localization to document and
support new comment features.

* **Tests**
* Added extensive backend test suites covering all comment and reply
functionalities, permissions, and attachment uploads.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 13:12:28 +00:00
Lakr
6a04fbe335 fix: 🚑 build on Xcode 16.2 (#12981)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Improved compatibility for chat cell handling, allowing broader
support for different view model types in chat-related features.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 12:47:21 +00:00
DarkSky
0326da0806 feat(server): add typed list session gql (#12979)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced new API endpoints and GraphQL queries to retrieve Copilot
chat sessions by workspace, document, and pinned status, with detailed
session and message information.
* Added support for filtering and querying Copilot chat histories with
new options such as pinned status and message ordering.

* **Bug Fixes**
* Improved filtering logic for listing and retrieving chat sessions,
ensuring accurate results for workspace, document, and pinned session
queries.

* **Tests**
* Expanded and refactored test coverage for session listing, filtering,
and new query options to ensure reliability and correctness of Copilot
session retrieval.
* Updated snapshot data to reflect new session types and filtering
capabilities.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 11:31:37 +00:00
Wu Yue
6e9487a9e1 feat(core): remove chat-panel component's dependency on doc (#12975)
Close [AI-259](https://linear.app/affine-design/issue/AI-259)
Close [AI-243](https://linear.app/affine-design/issue/AI-243)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced a unified AI chat content component to manage and display
chat interactions.
* Added new chat block message components for improved chat message
rendering.

* **Refactor**
* Simplified and unified session management across all AI chat
components, now passing full session objects instead of session IDs.
* Updated component and property names for clarity and consistency
(e.g., chat message and block message components).
* Consolidated chat history and actions retrieval for a more streamlined
chat experience.
* Removed redundant session ID getters and replaced them with direct
session object usage.
* Streamlined chat panel and composer components by removing internal
message and context state management.

* **Bug Fixes**
* Improved handling of chat session state and loading, reducing
redundant state properties.
* Enhanced event handling to prevent errors when chat parameters are
missing.

* **Tests**
* Removed outdated chat clearing test cases to align with new chat state
management.

* **Chores**
* Updated import paths and reorganized module exports for better
maintainability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 11:20:20 +00:00
Hwang
d49a069351 fix(web): adjust sign-in panel height (#12976)
before:


![image](https://github.com/user-attachments/assets/dde283fb-65af-413f-8610-a297da8968d6)


after:

![Electron 2025-07-01 15 02
53](https://github.com/user-attachments/assets/cf1b58d2-612c-4fc3-9e7e-56685b6668c3)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Updated the sign-in dialog to have a flexible height, allowing it to
adjust between 550 and 650 pixels for improved display across different
content sizes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 09:26:53 +00:00
EYHN
f600a1534a chore(ios): revert upgrade ci xcode version (#12978)
Reverts toeverything/AFFiNE#12977

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
  * Updated the iOS build environment to use Xcode version 16.2.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 09:12:56 +00:00
EYHN
eb0ee52706 chore(ios): upgrade ci xcode version (#12977)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
  * Updated the iOS build process to use Xcode version 16.4.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 08:00:52 +00:00
fengmk2
e8bc8f2d63 feat(server): add comment-attachment storage (#12911)
close CLOUD-230












#### PR Dependency Tree


* **PR #12911** 👈
  * **PR #12761**
    * **PR #12924**
      * **PR #12925**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for uploading and retrieving comment attachments in
workspace documents via a new API endpoint.
* Introduced a service for managing comment attachments, including
storage, retrieval, deletion, and URL generation.
* Implemented localized error messages and improved error handling for
missing comment attachments.

* **Bug Fixes**
  * Improved error feedback when comment attachments are not found.

* **Tests**
* Added comprehensive tests for comment attachment storage, retrieval,
deletion, API endpoint behavior, and permission checks.

* **Documentation**
* Updated GraphQL schema and localization files to include new error
types for comment attachments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 07:04:52 +00:00
DarkSky
6e034185cf feat: title of session (#12971)
fix AI-253
2025-07-01 05:24:42 +00:00
Lakr
2be3f84196 fix: 🚑 compiler issue on newer syntax (#12974)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Updated method and function signatures to accept any type conforming
to the chat cell view model protocol, improving flexibility and
extensibility of chat cell configuration and height estimation.
  * Simplified internal logic for determining text color in chat cells.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 13:06:06 +08:00
EYHN
f46d288b1b fix(core): fix client crash (#12966)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved reliability when displaying OAuth provider icons by handling
cases where the provider may not be recognized, preventing potential
errors during authentication.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 03:38:13 +00:00
Lakr
9529adf33e chore: remove intelligent button from release (#12970)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* The "Intelligents" button is now only shown in debug builds; it will
not appear in production versions.
* **Bug Fixes**
* Removed all references to the "Intelligents" plugin and related UI,
ensuring a cleaner production app experience.
* **Chores**
* Cleaned up project settings and removed redundant or empty
configuration entries.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 10:48:58 +00:00
Peng Xiao
03aeb44dc9 fix(editor): peekable conditions for edgeless note block (#12969)
fix AF-2704

#### PR Dependency Tree


* **PR #12969** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved peek behavior to allow peeking inside note blocks, even when
the hit target differs from the current model, as long as the current
model is contained within the note block. This enhances usability when
interacting with nested note blocks.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 07:13:02 +00:00
德布劳外 · 贾贵
c9aad0d55e refactor(core): open embedding settings when click check-status button (#12772)
> CLOSE BS-3582

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a "Check status" button in the AI chat interface that opens the
embedding settings panel for improved user access.

- **Refactor**
- Simplified the embedding status tooltip to display static information
and a direct link to settings, removing dynamic progress updates.
- Integrated workspace dialog service across AI chat components for
consistent dialog management.

- **Tests**
- Updated end-to-end tests to verify that clicking the "Check status"
button opens the embedding settings panel.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 07:00:17 +00:00
Lakr
29ae6afe71 chore: created first ai stream (#12968)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced a redesigned chat interface with new cell types for user,
assistant, system, loading, and error messages.
  * Added streaming chat responses and improved session management.
* Enhanced input box behavior, allowing sending messages with the return
key and inserting new lines via the edit menu.
* Added new GraphQL queries for fetching recent and latest chat
sessions.

* **Refactor**
* Replaced previous chat message and session management with a new, more
structured view model system.
* Updated chat view to use a custom table view component for better
message rendering and empty state handling.
* Simplified and improved error and loading state handling in the chat
UI.

* **Bug Fixes**
  * Improved error reporting and retry options for failed chat messages.
  * Fixed inconsistent property types for message and error identifiers.

* **Style**
* Updated UI components for chat cells with modern layouts and
consistent styling.

* **Chores**
  * Added a new package dependency for event streaming support.
* Renamed various internal properties and classes for clarity and
consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 06:51:00 +00:00
Cats Juice
32787bc88b fix(core): fix ai input style in chat block and simply img rendering (#12943)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Improved visual styling and cursor behavior for chat input send, stop,
and preference trigger buttons.
* Enhanced appearance and interactivity cues for the chat input
preference trigger.

* **Refactor**
* Simplified image preview grid by using CSS hover states for close
button visibility and switching to background images for previews.
* Streamlined image deletion process for a more intuitive user
experience.

* **Tests**
* Updated image upload test to wait for image container elements,
improving test reliability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 06:22:04 +00:00
EYHN
bbafce2c40 fix(ios): fix testflight (#12964)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Updated internal workflow configuration for iOS TestFlight uploads. No
impact on app features or user experience.
* Improved version handling to preserve full version strings for iOS
marketing versions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 06:06:21 +00:00
Peng Xiao
f7f69c3bc4 chore(core): do remove timeout for audio transcription job (#12965)
#### PR Dependency Tree


* **PR #12965** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved request timeout handling to ensure timeouts are only set when
appropriate and provide clearer error messages.
* Updated audio transcription submission to wait indefinitely for
completion, preventing requests from being aborted due to timeouts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 06:00:53 +00:00
fengmk2
5599c39e97 feat(server): add read doc tool (#12811)
close AI-186















#### PR Dependency Tree


* **PR #12811** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a new tool enabling users to read document content and metadata
within a workspace, with enforced access control.
- **Improvements**
- Updated tool interfaces and outputs to support the document reading
functionality seamlessly.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 03:37:34 +00:00
EYHN
6b2639cbbb fix(ios): fix xcode marketing version (#12963)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved version handling to ensure only the main version number is
used, ignoring any suffixes after a hyphen when updating the iOS
marketing version.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 03:35:45 +00:00
Richard Lora
82b3c0d264 feat(core): add allowGuestDemoWorkspace flag to force login (#12779)
https://github.com/user-attachments/assets/41a659c9-6def-4492-be8e-5910eb148d6f

This PR enforces login‑first access (#8716) by disabling or enabling the
guest demo workspace via Admin Server Client Page and redirecting
unauthenticated users straight to `/sign‑in`.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a configuration option to control whether guest users can create
demo workspaces.
* Updated server and client interfaces, GraphQL schema, and queries to
support the new guest demo workspace flag.

* **Bug Fixes**
* Improved sign-out behavior to redirect users appropriately based on
guest demo workspace permissions.
* Enhanced navigation flow to handle guest demo workspace access and
user authentication state.

* **Tests**
* Added tests to verify sign-out logic when guest demo workspaces are
enabled or disabled.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: liuyi <forehalo@gmail.com>
Co-authored-by: fengmk2 <fengmk2@gmail.com>
2025-06-29 14:17:18 +00:00
Wu Yue
a4680d236d fix(core): ai make it real ci timeout (#12954)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Replaced the boolean flag for selecting AI workflow endpoints with a
clear and flexible enum, enhancing clarity and maintainability for
AI-powered features.

* **Tests**
  * Simplified example text in AI action tests to improve consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2025-06-28 12:56:12 +00:00
github-actions[bot]
f88e1dffb6 chore(i18n): sync translations (#12604)
New Crowdin translations by [Crowdin GH
Action](https://github.com/crowdin/github-action)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: fengmk2 <fengmk2@gmail.com>
2025-06-28 09:00:17 +00:00
fengmk2
e773930256 feat(server): add comment-attachment model (#12909)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced support for comment attachments, allowing users to add,
view, and manage attachments linked to comments within documents.
* **Tests**
* Added comprehensive tests to ensure correct behavior for adding,
updating, deleting, listing, and retrieving comment attachments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


#### PR Dependency Tree


* **PR #12909** 👈
  * **PR #12911**
    * **PR #12761**
      * **PR #12924**
        * **PR #12925**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-28 08:45:24 +00:00
DarkSky
1c1dade2d5 feat(server): add morph doc edit tool (#12789)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced support for the Morph provider in the copilot module,
enabling integration with the Morph LLM API.
- Added a new document editing tool that allows users to propose and
apply edits to existing documents via AI assistance.
- **Configuration**
- Added configuration options for the Morph provider in both backend and
admin interfaces.
- **Enhancements**
- Expanded tool support to include document editing capabilities within
the copilot feature set.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-28 08:27:08 +00:00
fengmk2
e2a799c70a feat(server): comment model (#12760)
close CLOUD-226

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced support for comments and replies within workspaces and
documents, enabling users to create, update, delete, and resolve
comments, as well as manage threaded replies.
- **Bug Fixes**
- Added user-friendly error messages and handling for situations where
comments or replies are not found.
- **Tests**
- Added comprehensive tests to ensure correct behavior of comment and
reply operations.
- **Localization**
  - Added English translations for new comment and reply error messages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->














#### PR Dependency Tree


* **PR #12760** 👈
  * **PR #12909**
    * **PR #12911**
      * **PR #12761**
        * **PR #12924**
          * **PR #12925**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-28 08:01:53 +00:00
DarkSky
9b881eb59a feat(server): faster reranking based on confidence (#12957)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved document reranking with a more streamlined and accurate
scoring system.
* Enhanced support for binary ("yes"/"no") document relevance judgments.

* **Improvements**
* Simplified user prompts and output formats for reranking tasks, making
results easier to interpret.
  * Increased reliability and consistency in document ranking results.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-28 03:41:53 +00:00
DarkSky
e6f91cced6 feat(server): remove context prefetch & integrate context search (#12956)
fix AI-173
2025-06-27 23:45:49 +08:00
Cats Juice
ad306edcf1 fix(core): persist right sidebar open state correctly for desktop (#12953)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Improved the method for updating the right sidebar's open state to
enhance maintainability. No visible changes to end-user functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 09:57:30 +00:00
fengmk2
dc55518c5b feat(server): support multiple hosts in one deployment (#12950)
close CLOUD-233



#### PR Dependency Tree


* **PR #12950** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for configuring multiple server hosts across backend and
frontend settings.
* Enhanced deployment and Helm chart configuration to allow specifying
multiple ingress hosts.
* Updated admin and configuration interfaces to display and manage
multiple server hosts.

* **Improvements**
* Improved URL generation, OAuth, and worker service logic to
dynamically handle requests from multiple hosts.
  * Enhanced captcha verification to support multiple allowed hostnames.
* Updated frontend logic for platform-specific server base URLs and
allowed origins, including Apple app domains.
  * Expanded test coverage for multi-host scenarios.

* **Bug Fixes**
* Corrected backend logic to consistently use dynamic base URLs and
origins based on request host context.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 09:41:37 +00:00
Cats Juice
5c45c66ce8 fix(core): correct workspace selector position in sidebar fallback (#12945)
- prevent drag-handle being clipped in header

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Reduced horizontal padding and header height in the app sidebar
fallback view for a more compact layout.
* Updated header padding in the workbench view and introduced
conditional left padding based on sidebar switch visibility.

* **Refactor**
* Simplified and centralized the logic for displaying the sidebar
switch, improving code clarity and maintainability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 07:47:55 +00:00
Lakr
9a1ce2ba3c chore: define view model (#12949)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced a chat interface with message list, empty state view, and
support for user, assistant, and system messages.
* Added a chat manager for session and message handling, including
session creation, message sending, and error management.
* Implemented various chat cell types (attachments, context references,
workflow status, loading, and error cells) with corresponding data
models and view models.
* Enabled asynchronous message sending from the input box with error
alerts and automatic session creation.
* Added workflow and context-related models for advanced chat features.

* **Enhancements**
* Improved UI responsiveness with table view updates and dynamic empty
state handling.
  * Provided a method to clear all attachments in the input box.

* **Bug Fixes / Style**
* Refined code formatting, access control, and minor stylistic
improvements across multiple files for consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 06:36:37 +00:00
Peng Xiao
f80b69273f feat(editor): allow embedding any iframes (#12895)
fix BS-3606




#### PR Dependency Tree


* **PR #12892**
  * **PR #12895** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced support for embedding generic iframes with customizable
dimensions and permissions, while ensuring only secure, non-AFFiNE URLs
are allowed.
* Enhanced embedding options by prioritizing custom embed blocks over
iframe blocks for a richer embedding experience across toolbars and link
actions.
* Added URL validation to support secure and flexible embedding
configurations.

* **Bug Fixes**
* Improved iframe embedding reliability by removing restrictive HTTP
headers and certain Content Security Policy directives that could block
iframe usage in the Electron app.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 04:49:54 +00:00
Peng Xiao
ec66b6d660 fix(electron): adjust some command line flags (#12597)
some flags are copied from vscode.
In some cases that Electron is running in HDR mode, the color toning
will be over exposed. Force using srgb to workaround this issue.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Improved app performance and compatibility by enabling and disabling
specific Electron features.
- Enhanced color profile handling by forcing the color profile to
"srgb".
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 04:16:27 +00:00
Wu Yue
a7185e419c feat(core): add ai tool call error type and ui (#12941)
<img width="775" alt="截屏2025-06-26 16 17 05"
src="https://github.com/user-attachments/assets/ed6bcae3-94af-4eb1-81e8-710f36ef5e46"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Introduced a tool to crawl web pages and extract key information.
* Added a visual component to display tool call failures in the AI
interface.
* Enhanced error reporting for document and web search tools with
structured error messages.

* **Improvements**
* Updated error handling across AI tools and components for more
consistent and informative feedback.
* Default values added for tool card components to improve reliability
and display.

* **Bug Fixes**
* Improved handling of error and empty states in web crawl and web
search result displays.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 09:38:19 +00:00
Wu Yue
2171d1bfe2 feat(core): add ai playground feature flag and remove model switch feature flag (#12934)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added support for the "AI Playground" experimental feature, including
new settings and localization entries.

* **Refactor**
* Renamed configuration and service references from "Model Switch" to
"Playground" across the AI chat and playground interfaces.
* Updated feature flag from "enable_ai_model_switch" to
"enable_ai_playground" for consistency.

* **Bug Fixes**
* The "Model" submenu in AI chat preferences is now always visible,
simplifying menu options.

* **Chores**
  * Removed outdated Claude model options from the chat prompt.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 09:04:57 +00:00
DarkSky
5e193b58c0 fix(server): allow fork empty session in playground (#12940)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved session forking by allowing sessions to be forked even when
no messages are provided, preventing unnecessary errors.
* Reduced unnecessary database operations by only updating messages when
there are messages to update.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 09:04:25 +00:00
EYHN
eef2e05d83 feat(ios): update code sign identity script (#12942) 2025-06-26 08:59:01 +00:00
EYHN
f3a2a75743 feat(ios): update code sign identity script (#12938)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Improved the iOS release workflow to include automated version setup
and code signing identity updates during the release process.
* Introduced a script to automatically update iOS project code signing
settings for enhanced reliability.
* Enhanced versioning script to update the iOS marketing version in the
project file.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 08:05:14 +00:00
L-Sun
a6edb6192f fix(editor): improve performence of link card render (#12937)
Close
[BS-3097](https://linear.app/affine-design/issue/BS-3607/linkdoccard-重复渲染导致卡顿)

![CleanShot 2025-06-26 at 14 58
54](https://github.com/user-attachments/assets/2787f88b-3596-4a34-a9a8-91966b83418d)


#### PR Dependency Tree


* **PR #12937** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Improved the handling of updates for embedded linked documents,
reducing unnecessary reloads when the document list changes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 07:13:15 +00:00
EYHN
320d2f5bdf feat(editor): use affine container url in preview (#12919)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Bug Fixes**
- Improved code block preview rendering to only display the preview when
appropriate, preventing unwanted previews.

- **Refactor**
- Simplified the HTML preview system by always using a secure
iframe-based approach and removing the WebContainer integration.
- Updated iframe permissions and content delivery for enhanced security
and compatibility.

- **Chores**
- Removed the "Enable Web Container" feature flag and all related
internal logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 02:50:38 +00:00
Cats Juice
ea7678f17e feat(component): new component to edit icon and name (#12921)
https://github.com/user-attachments/assets/994f7f58-bcbe-4f26-9142-282ffa5025f9



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced an icon and name editor component, allowing users to select
emoji icons and edit names within a menu popover.
- Added an emoji picker for icon selection, supporting theme adaptation.
- **Style**
- Applied new styles for the icon and name editor, including emoji
picker appearance.
- **Documentation**
- Added Storybook stories to showcase and demonstrate the new icon and
name editor component.
- **Chores**
- Added emoji-related dependencies to support emoji selection features.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 02:39:16 +00:00
DarkSky
06f27e8d6a feat(server): allow multiple session attach to doc (#12933)
fix AI-236
2025-06-26 02:15:31 +00:00
DarkSky
e32c9a814a feat(server): improve session modify (#12928)
fix AI-248
2025-06-25 12:02:21 +00:00
Lakr
697e0bf9ba feat: completed input box ui + ux (#12927)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a document picker UI for embedding and selecting AFFiNE
documents, with improved search and recent document functionality.
- Added support for searching and fetching recently updated documents
within a workspace.
- Enhanced error handling for login and metadata validation during
document operations.
  - Added ability to attach documents directly from the input box.

- **Improvements**
- Refined UI animations and layout behaviors for attachment and document
picker components.
- Updated attachment and header views for clearer pluralization and
display logic.
- Improved selection indicators and search experience in the document
picker.
- Enhanced delegate handling for user actions across input and
attachment components.

- **Bug Fixes**
- Fixed progress indicators and error alerts for failed document
operations.

- **Chores**
- Updated project configuration for improved build and signing
processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-25 09:54:06 +00:00
DarkSky
07ec427021 fix(server): copilot permission check (#12923)
fix AI-176
2025-06-25 17:01:58 +08:00
Peng Xiao
e00a37cd00 fix(electron): embeded youtube videos not playable (#12892)
#### PR Dependency Tree


* **PR #12892** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved handling of CORS headers to ensure they are only removed for
responses from non-whitelisted domains, enhancing compatibility with
certain sites.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


#### PR Dependency Tree


* **PR #12892** 👈
  * **PR #12895**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-25 06:51:40 +00:00
Lakr
c37df9fb94 chore: made attachment header & management sheet (#12922)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced file, image, and document attachment support in the input
box, including new UI components for managing and previewing
attachments.
- Added a searchable document picker view and a file attachment header
with interactive management options.
- Enabled an attachment management controller for viewing and deleting
attachments.
- Improved image attachment bar with horizontal scrolling and removal
functionality.
- Enhanced error handling for file attachments, providing user-facing
alerts.

- **Improvements**
  - Updated attachment menus for clearer file type indications.
- Streamlined attachment handling logic and UI updates for a smoother
user experience.

- **Bug Fixes**
- Addressed error notification by replacing console logging with user
alerts when file attachment issues occur.

- **Refactor**
- Replaced and reorganized the input box view model and attachment bar
for better modularity and maintainability.

- **Chores**
- Updated asset catalogs to include new attachment icons for various
file types.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-25 05:30:00 +00:00
EYHN
aa4874a55c feat(core): use cloud indexer for search (#12899)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added enhanced error handling and user-friendly error messages in
quick search and document search menus.
  - Introduced loading state indicators for search operations.
  - Quick Search now provides explicit error feedback in the UI.

- **Improvements**
- Search and aggregation operations can now prefer remote or local
indexers based on user or system preference.
- Streamlined indexer logic for more consistent and reliable search
experiences.
- Refined error handling in messaging and synchronization layers for
improved stability.
- Enhanced error object handling in messaging for clearer error
propagation.
- Updated cloud workspace storage to always use IndexedDB locally and
CloudIndexer remotely.
- Shifted indexer operations to use synchronized indexer layer for
better consistency.
  - Simplified indexer client by consolidating storage and sync layers.
- Improved error propagation in messaging handlers by wrapping error
objects.
- Updated document search to prioritize remote indexer results by
default.

- **Bug Fixes**
- Improved robustness of search features by handling errors gracefully
and preventing potential runtime issues.

- **Style**
  - Added new styles for displaying error messages in search interfaces.

- **Chores**
- Removed the obsolete "Enable Cloud Indexer" feature flag; cloud
indexer behavior is now always enabled where applicable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-25 02:55:27 +00:00
Cats Juice
6813d84deb fix(core): adjust workspace selector style in import page (#12916)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Style**
- Updated padding for workspace selector elements to provide a more
uniform appearance.
- Adjusted container height and workspace selector width for improved
layout consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-25 01:03:55 +00:00
fengmk2
f0671cf2dd fix(server): should check doc public attribute when snapshot not exists (#12913)
close CLOUD-232



#### PR Dependency Tree


* **PR #12913** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- The visibility status of documents now accurately reflects their
public status instead of always showing as private.
- **Tests**
- Added an end-to-end test to verify correct handling of the public
attribute for documents without snapshots.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 11:40:21 +00:00
doufa
3186fb8306 feat(electron): upgrade flatpak runtimeversion (#12025)
Close: #9577 

@electron-forge/maker-flatpak use @malept/electron-installer-flatpak for
make installer, in @malept/electron-installer-flatpak use zypak as
module to allow run Chromium based applications that require a sandbox
in a Flatpak environment.

electron-installer-flatpak add zypak module with v2021.01 as default
which may not compatible with runtimeVersion 24.08.

Add modules config in forge.config with zypak v2024.01.17 for
runtimeVersion 24.08 to override the default zypak version.

The flatpak info shows:

![flatpak-24
08](https://github.com/user-attachments/assets/8b4e2309-e420-47fd-bab1-e59e9ff7b342)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Updated the Flatpak configuration for Linux, including a newer runtime
version and additional module support.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Peng Xiao <pengxiao@outlook.com>
2025-06-24 08:53:23 +00:00
liuyi
fd962b57db ci: tag candidate images with app version 2025-06-24 16:02:29 +08:00
liuyi
cece56802b ci: failed to detect new canary version 2025-06-24 15:24:12 +08:00
liuyi
9e1fa23c5e chore: bump base version 2025-06-24 14:43:39 +08:00
liuyi
8f0812ae12 ci: change canary release tag format 2025-06-24 14:38:54 +08:00
liuyi
d2a9b048ad ci: use docker buildx to release channel tag 2025-06-24 14:03:10 +08:00
Lakr
10139205b4 chore: update graphql support for fetching initial user status (#12905)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new context management system for intelligent features,
enabling the collection and preparation of metadata from both web view
and GraphQL sources.
- Added a service for managing GraphQL API interactions, including user,
workspace, subscription, and quota queries.
- Enabled searching documents within a workspace using a new GraphQL
query and input structure.

- **Enhancements**
- Expanded chat session and chat history search capabilities with
additional filter and pagination options.

- **Refactor**
- Replaced the previous context management class with a more
comprehensive and modular implementation.
- Improved handling of cookies for network requests to ensure session
continuity.

- **Style**
- Minor code style and formatting improvements for clarity and
consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 05:03:35 +00:00
Wu Yue
63de20c3d5 feat(core): support objects render in ai chat block (#12906)
Close [AI-195](https://linear.app/affine-design/issue/AI-195)


<img width="1219" alt="截屏2025-06-24 10 55 18"
src="https://github.com/user-attachments/assets/8c54ad41-2bbf-443a-a41a-9cea9aede7b4"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new component to render various AI stream objects within
chat messages, supporting richer content types like reasoning blocks and
tool calls.

- **Improvements**
- Enhanced chat message rendering by consolidating message properties
into a single object and simplifying component interfaces.
- Improved scrolling behavior with smooth, throttled scrolling and
better synchronization with chat status.
- Updated chat history and streaming updates to use immutable data
handling for more reliable message updates.
- Refined rendering keys and content merging for more accurate display
of streamed AI responses.
- Improved handling and display of tool results and web search/crawl
outputs.

- **Bug Fixes**
- Ensured consistent presence of attachments and streaming objects in
chat message data.
- Enhanced parsing and merging of streamed AI responses for better
message accuracy.

- **Refactor**
- Streamlined imports, component registrations, and internal message
handling for maintainability.
- Updated type definitions to support new optional message properties
and improve compatibility.

- **Style**
- Adjusted layout by moving history clear controls for a more intuitive
chat interface.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 05:03:11 +00:00
Cats Juice
616e755dde fix(core): center align user avatar in doc property (#12908)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added an option to center-align user labels in components displaying
user information, improving visual alignment of avatars and usernames.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 05:01:56 +00:00
Peng Xiao
4e6f40b30e chore(electron): update icons (#12907) 2025-06-24 05:01:18 +00:00
Cats Juice
8754d1b164 feat(core): limit visible doc inline stack tags (#12647)
![CleanShot 2025-05-29 at
18.06.32@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/LakojjjzZNf6ogjOVwKE/09538910-0577-48cc-9532-53591d76f759.png)



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Tag lists now display a maximum of three tags, with an additional "+N
Tags" indicator if more tags are present.
- The "+N Tags" indicator label is localized based on your language
settings.

- **Style**
  - Improved spacing for the "+N Tags" indicator in tag lists.

- **Bug Fixes**
- Icons in certain property views are now only shown when available,
preventing empty icon placeholders.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 03:08:32 +00:00
Cats Juice
d743082d83 fix(mobile): change mobile docs display config and prevent opening doc when close menu (#12903)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Improvements**
- Updated document explorer to hide quick favorite and document icons,
and display more detailed system properties for each document.
- Enhanced link behavior in the workbench to prevent unintended clicks
from triggering navigation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 02:17:57 +00:00
L-Sun
1686b92adb fix(editor): middle click open new tab (#12902)
Close
[BS-3251](https://linear.app/affine-design/issue/BS-3251/正文的inline链接,chrome中,中键开新窗口的行为丢失了)

#### PR Dependency Tree


* **PR #12902** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Middle-clicking on links and references now opens them in a new
browser tab.
- Linux platform detection has been added for improved
environment-specific behavior.

- **Bug Fixes**
- Middle-click paste prevention is now limited to Linux environments
when the relevant setting is disabled and excludes clicks on links and
references.

- **Tests**
- Added end-to-end tests to verify that middle-clicking links opens them
in a new tab for external links, internal links, and reference
documents.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 12:33:51 +00:00
Richard Lora
a8c18cd631 feat(editor): streamline cell editing and navigation with improved keyboard support (#12770)
https://github.com/user-attachments/assets/6bce5fa3-fb25-4906-bef1-50d4da4a13f6

This PR addresses #12769 and improves table editing UX by making Enter
commit changes and move focus down, and Tab/Shift+Tab move focus
horizontally—matching spreadsheet-like behavior.

Typing now immediately enters edit mode for selected cells without
double-clicking.
These updates apply to both the standard and virtual table views.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- You can now start editing a table cell by simply typing any character
while the cell is selected.
- **Improvements**
- Pressing Enter while editing a cell will exit editing and move focus
down.
- Pressing Tab or Shift-Tab while editing a cell will exit editing and
move focus right or left, respectively.
- **Tests**
- Added unit tests for table cell hotkey behaviors to ensure reliable
editing and navigation.
- **Chores**
- Introduced Vitest configuration for streamlined testing and coverage
reporting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: L-Sun <zover.v@gmail.com>
2025-06-23 20:24:22 +08:00
Richard Lora
74106ba7c6 fix(core): persist sidebar open state and width to prevent flash on load (#12743)
https://github.com/user-attachments/assets/6b61c9f2-80bd-4f2c-943d-1fd610a69ecf

This PR change updates the sidebar initialization so it reads the open
and width values from persistent storage. This prevents the UI from
flashing open by default on startup.

Both left and right sidebars restore correctly from the last known state
from storage.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Sidebar and workbench panels now retain their open/closed status and
width based on your previously saved preferences, providing a more
personalized and consistent experience across sessions.
- **Tests**
- Added comprehensive tests to ensure sidebar state persistence and
behavior are reliable and consistent.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Norkz <richardlora557@gmail.com>
2025-06-23 10:46:10 +00:00
Cats Juice
4507c88792 fix(core): remove list view doc preview skeleton (#12621)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Updated the document preview in the list view to remove the loading
placeholder, resulting in a simplified and cleaner display when loading
previews.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 10:36:46 +00:00
Cats Juice
dd1b8ff920 fix(core): show toolbar when quick select doc explorer (#12601)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Selection mode is now automatically activated when a document is
selected or deselected in the quick actions view.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 10:35:02 +00:00
Cats Juice
ea92e2291d fix(core): adjust new doc list filter style (#12629)
close AF-2678, AF-2677, AF-2674, AF-2655

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
  - Added customizable spacing for dividers.
  - Introduced a flexible filter value menu for easier filter editing.
- Added options to control visibility of creation actions in empty
document views.

- **Improvements**
- Enhanced menu components for filter values with a more declarative and
simplified interface.
  - Improved vertical alignment in some UI containers.
  - Updated divider spacing for more consistent UI appearance.

- **Bug Fixes**
  - Menu popups for filters now appear in correct positions.

- **Removals**
- Removed support for the "zotero" integration type from integration
settings and filters.

- **Style**
  - Updated CSS for better menu positioning and alignment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 10:34:00 +00:00
Cats Juice
24b205ae83 feat(mobile): add delete operation for detail page menu (#12900)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added a "Move to Trash" option in the page header menu, allowing users
to move documents to trash with confirmation and permission checks.

- **Refactor**
- Centralized and reorganized tab-related type definitions for improved
maintainability.
  - Updated tab components to use shared constants and types.

- **Style**
- Updated menu item styling for the new trash action to indicate a
destructive operation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 10:33:24 +00:00
liuyi
934e377054 ci: update docker image name 2025-06-23 15:57:02 +08:00
liuyi
8d77c480e0 ci: bring ios & android canary tests back 2025-06-23 15:34:49 +08:00
fengmk2
862a50c982 fix(server): use job queue instead event on doc indexing changes (#12893)
close CLOUD-231



#### PR Dependency Tree


* **PR #12893** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Updated background processing for document indexing and deletion to
use a job queue system instead of event-based triggers.
- **Bug Fixes**
- Improved reliability of embedding updates and deletions by ensuring
tasks are properly queued and processed.
- **Tests**
- Adjusted tests to verify that document operations correctly trigger
job queue actions.
  
No changes to user-facing features or interface.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 06:56:04 +00:00
liuyi
705d2e9bbe ci: fix release workflow 2025-06-23 14:49:15 +08:00
Yii
e6d8008d4f ci: group cloud, desktop, mobile in one release workflow (#12802)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced new workflows for preparing releases, cloud deployment, and
coordinated multi-platform releases with manual approval for stable
Docker images.
- Added a reusable action to output app version, Git hash, and build
type for consistent release metadata.

- **Refactor**
- Simplified and unified input handling across workflows, requiring
explicit version and build metadata inputs.
- Updated release workflows (desktop, mobile, cloud) to use direct
inputs instead of deriving values internally.

- **Chores**
- Removed several legacy and redundant workflows, including automatic
deployment, release, label checking, auto-assign, and Helm chart
publishing.
- Deleted jobs and workflows related to self-hosted image builds, mobile
app test builds, and previous deployment processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 14:30:23 +08:00
Richard Lora
e976fcfc04 docs: clarify and fix desktop build instructions (#12881)
This PR changes documentation files related to building the desktop
client app to allow other contributors to develop and test without
becoming stuck due to outdated docs.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Documentation**
- Improved build instructions for native dependencies and E2E testing,
including updated commands and clearer server startup steps.
- Enhanced desktop client app documentation with clarified build steps,
corrected artifact paths, and added Linux installation guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 12:30:41 +08:00
Yifeng Wang
76568bae9f feat(editor): support connector dom renderer (#12505)
### TL;DR

Added DOM-based renderer for connector elements in the AFFiNE editor.

### What changed?

- Created a new DOM-based renderer for connector elements that uses SVG
for rendering
- Implemented `ConnectorDomRendererExtension` to register the DOM
renderer for connector elements
- Added support for rendering connector paths, endpoints (arrows,
triangles, circles, diamonds), stroke styles, and labels
- Registered the new DOM renderer extension in the connector view setup
- Added comprehensive tests to verify DOM rendering functionality

### How to test?

1. Enable the DOM renderer flag in the editor
2. Create connector elements between shapes or with fixed positions
3. Verify that connectors render correctly with different styles:
   - Try different stroke styles (solid, dashed)
   - Test various endpoint styles (Arrow, Triangle, Circle, Diamond)
   - Add text labels to connectors
4. Check that connectors update properly when connected elements move
5. Verify that connectors are removed when deleted

### Why make this change?

The DOM-based renderer provides an alternative to the Canvas-based
renderer, offering better accessibility and potentially improved
performance for certain use cases. This implementation allows connectors
to be rendered as SVG elements within the DOM, which can be more easily
inspected, styled with CSS, and interacted with by assistive
technologies.
2025-06-23 03:59:45 +00:00
Wu Yue
12fce1f21a feat(core): ai tools css style adjustment (#12891)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added collapsible behavior to tool result cards, allowing users to
expand or collapse detailed results.
- Footer icons are now displayed on collapsed cards, showing up to three
relevant icons for quick reference.
- Improved icon rendering ensures consistent display, including
fallbacks when favicons are missing.
- Tool result cards and chat messages now dynamically adjust to panel
width, enhancing responsive display.
- Web crawl and web search tools display favicons in result footers for
better visual context.

- **Style**
- Enhanced UI interaction with updated margins, cursor styles, and
overlapping icon visuals for a cleaner look.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 03:44:24 +00:00
fengmk2
011f92f7da feat(server): add search docs by keyword gql api (#12866)
close AI-220









#### PR Dependency Tree


* **PR #12866** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a new document search capability, allowing users to search
for documents by keyword within a workspace.
- Search results include document details such as title, highlights,
creation and update timestamps, and creator/updater information.
  - Added support for limiting the number of search results returned.
- **Tests**
- Added comprehensive end-to-end and snapshot tests to ensure accuracy
and access control for the new search functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 11:29:37 +00:00
Lakr
10e981aa6d chore: update codegen cli and apollo version on iOS (#12879)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added support for creating new documents from markdown and retrieving
the current locale in the iOS app.
- Introduced a shell script to automate Apollo iOS code generation
tasks.

- **Improvements**
- Upgraded the Apollo iOS library to version 1.22.0 for improved
performance and compatibility.
- Enhanced metadata handling in the app to include document ID,
workspace ID, server URL, and locale.
- Improved JavaScript execution integration for document and workspace
operations.

- **Bug Fixes**
- Fixed button appearance in the input bar by setting a static corner
radius for the send button.

- **Chores**
- Removed unused dependencies and updated .gitignore entries for cleaner
project management.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 11:03:16 +00:00
fengmk2
e978147a16 feat(server): add doc keyword search tool (#12837)
close AI-185

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a keyword-based document search tool, allowing users to
search for relevant documents within their workspace using keywords.
- Search results include document titles, summaries, and direct links,
enhancing document discovery and navigation.
- **Bug Fixes**
  - None.
- **Tests**
- Added new tests to verify document search by IDs and by keywords,
ensuring accurate and reliable search functionality.
- **Documentation**
  - None.
- **Chores**
- Updated configuration file organization for improved clarity; no
changes to functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->








#### PR Dependency Tree


* **PR #12867**
  * **PR #12863**
    * **PR #12837** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-20 10:50:34 +00:00
Cats Juice
3a124b67bd feat(core): enable quick select for trash page (#12878)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enabled quick select functionality in the Trash page, allowing users
to more efficiently select multiple items.
- Improved selection mode activation when using quick select actions in
document explorer views.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 10:49:09 +00:00
Peng Xiao
da980876cb fix(core): iframe rendering issue for youtube videos (#12880)
#### PR Dependency Tree


* **PR #12880** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved iframe preview behavior for code blocks, enabling enhanced
compatibility and resource access within previews.
- **Chores**
- Updated internal server configuration to no longer set custom
cross-origin headers during development.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 10:19:28 +00:00
fengmk2
62d74de810 feat(server): search docs by keywork from indexer (#12863)
#### PR Dependency Tree


* **PR #12867**
  * **PR #12863** 👈
    * **PR #12837**
    * **PR #12866**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-20 09:48:30 +00:00
fengmk2
bebe4349a9 fix(server): convert date and timestamp value to Date instance (#12867)
#### PR Dependency Tree


* **PR #12867** 👈
  * **PR #12863**
    * **PR #12837**
    * **PR #12866**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Date fields in search results are now returned as JavaScript Date
objects instead of strings or numeric timestamps.
- **Bug Fixes**
- Improved consistency and correctness of date field types across
different search providers.
- **Tests**
- Added tests to verify that date fields are correctly returned as Date
objects.
- Updated existing test snapshots to reflect the new Date object format
for date fields.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 09:21:29 +00:00
DarkSky
13b64c6780 fix(server): session update check (#12877)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved validation to prevent updates to sessions with action prompts
and restrict certain updates on forked sessions.
- **Tests**
- Expanded and clarified test coverage for session updates, pinning
behavior, and session type conversions, with more explicit error
handling and validation scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 08:53:48 +00:00
DarkSky
c7113b0195 feat(server): add pinned & action filter for session query (#12876)
fix AI-222
2025-06-20 08:31:04 +00:00
renovate[bot]
fb250c6374 chore: bump up SnapKit/SnapKit version to from: "5.7.1" (#12873)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [SnapKit/SnapKit](https://redirect.github.com/SnapKit/SnapKit) | minor
| `from: "5.0.1"` -> `from: "5.7.1"` |

---

### Release Notes

<details>
<summary>SnapKit/SnapKit (SnapKit/SnapKit)</summary>

###
[`v5.7.1`](https://redirect.github.com/SnapKit/SnapKit/releases/tag/5.7.1)

[Compare
Source](https://redirect.github.com/SnapKit/SnapKit/compare/5.7.0...5.7.1)

- Podspec bump with privacy manifest support via Cocoapods

###
[`v5.7.0`](https://redirect.github.com/SnapKit/SnapKit/releases/tag/5.7.0)

[Compare
Source](https://redirect.github.com/SnapKit/SnapKit/compare/5.6.0...5.7.0)

Minor release:

- Update minimum deployment targets (iOS 12.0, macOS 10.13)
- Add `PrivacyInfo.xcprivacy` for Swift PM targets, Cocoapods
unsupported due to
[#&#8203;10325](https://redirect.github.com/CocoaPods/CocoaPods/issues/10325)

Happy New Year!

###
[`v5.6.0`](https://redirect.github.com/SnapKit/SnapKit/releases/tag/5.6.0)

[Compare
Source](https://redirect.github.com/SnapKit/SnapKit/compare/5.0.1...5.6.0)

- Upgrade to syntax compatibility of Swift 5.6
- Upgrade dependency manager integrations
- Small tweaks and fixes

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/toeverything/AFFiNE).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42MC4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjAuMSIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-20 07:02:07 +00:00
fengmk2
c62627427c fix(server): save snapshot and delete updates in the same transaction (#12856)
close CLOUD-229



#### PR Dependency Tree


* **PR #12856** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Improved the internal handling of document updates and snapshots to
enhance reliability and maintainability. No changes to user-facing
features or functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 05:23:34 +00:00
Lakr
eb5a2ffe05 chore: basic setup of v2 AI (#12864)
Co-authored-by: Hwang <hwangdev97@gmail.com>
2025-06-20 05:09:33 +00:00
fengmk2
5a87d3d9f6 fix(server): don't use global AFFiNELogger (#12871)
![image](https://github.com/user-attachments/assets/0e5d313f-e72b-436b-9f13-9f0a1cff8685)

#### PR Dependency Tree


* **PR #12871** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Updated internal logging mechanism to use a standard logger, resulting
in a simplified and more consistent logging approach. No changes to
user-facing features or functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


#### PR Dependency Tree


* **PR #12871** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-20 05:02:42 +00:00
liuyi
07328d1348 ci: add merge queue 2025-06-20 11:47:36 +08:00
fengmk2
ad5722f637 feat(server): get recently updated docs (#12861)
close AI-218



#### PR Dependency Tree


* **PR #12861** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a "Recently Updated Documents" feature, allowing users to view a
paginated list of the most recently updated documents within a
workspace.
- Document metadata now includes a "title" field for easier
identification.
- **Tests**
- Introduced new end-to-end tests to verify the recently updated
documents query and its pagination behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 11:35:39 +08:00
fengmk2
5623d808bf fix(server): set empty embedding on empty doc (#12857)
#### PR Dependency Tree


* **PR #12857** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Bug Fixes**
- Improved error handling in document embedding jobs to log and skip
errors instead of interrupting the process.
- Enhanced logging with clearer messages about embedding outcomes and
skipped operations.
- Added warnings when documents or summaries are missing during
embedding.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 10:30:53 +08:00
DarkSky
dfaf69475b fix(server): session unique index conflict (#12865) 2025-06-20 08:36:22 +08:00
Cats Juice
7376926553 chore(core): adjust tab height and windows control, remove input background (#12862)
close AF-2697, AF-2696

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Style**
- Made the AI chat input field background transparent for improved
visual consistency.
- Reduced the size of window app control buttons and removed extra
padding from the close button.
- Decreased the height of tabs and the width of the window app controls
placeholder for a more compact layout.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 20:12:40 +08:00
Wu Yue
3886babcf4 feat(core): add ai web-search and web-crawl tools ui components (#12854) 2025-06-19 19:15:46 +08:00
L-Sun
2edc8e43e2 fix(android): graphql service type error (#12858)
#### PR Dependency Tree


* **PR #12858** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Improved consistency in how session data is handled when starting a
Copilot session.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 16:22:47 +08:00
DarkSky
bd04930560 feat(server): allow chat session dangling & pin session support (#12849)
fix AI-181
fix AI-179
fix AI-178
fix PD-2682
fix PD-2683
2025-06-19 13:17:01 +08:00
fengmk2
d80bfac1d2 feat(server): parse ydoc to ai editable markdown format (#12846)
close AI-213









#### PR Dependency Tree


* **PR #12846** 👈
  * **PR #12811**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced support for AI-editable blocks in document parsing,
allowing blocks to include metadata for AI-based editing.
  - Added rendering for todo list items with markdown checkbox syntax.
- Unsupported block types are now marked with placeholders in the parsed
output.

- **Tests**
- Added new test cases and snapshots to verify parsing behavior with
AI-editable content enabled.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 11:27:04 +08:00
Cats Juice
380f40ebed style(core): adjust app sidebar style (#12852)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Style**
- Adjusted layout and spacing in sidebar and quick search components for
a more compact appearance.
- Reduced header and tab heights in the desktop app, increasing main
view space.
- Updated add-page button size, padding, and font for improved
usability.
  - Refined menu positioning in workspace selector for dense layouts.
  - Improved macOS window button positioning for better alignment.
  - Updated and restructured iOS app dependencies.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: fengmk2 <fengmk2@gmail.com>
2025-06-19 10:15:42 +08:00
fengmk2
73402c8447 feat(server): parse ydoc to markdown (#12812)
close AI-190

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced an endpoint to retrieve a document's markdown content and
title.
- Added backend support for parsing document snapshots directly into
markdown format.

- **Tests**
- Added comprehensive tests and snapshot files for markdown retrieval,
including success and error scenarios.
- Improved test coverage for content type validation and markdown
parsing utilities.

- **Documentation**
- Enhanced internal documentation through detailed test cases and
snapshot references for new markdown features.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->








#### PR Dependency Tree


* **PR #12812** 👈
  * **PR #12846**
    * **PR #12811**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-19 09:14:00 +08:00
Wu Yue
6169cdab3a feat(core): add stream object api (#12841)
Close [AI-193](https://linear.app/affine-design/issue/AI-193)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added support for streaming structured AI chat responses as objects,
enabling richer and more interactive chat experiences.
- Chat messages now include a new field displaying structured stream
objects, such as reasoning steps, text deltas, tool calls, and tool
results.
- GraphQL APIs and queries updated to expose these structured streaming
objects in chat histories.
  - Introduced a new streaming chat endpoint for object-based responses.

- **Bug Fixes**
- Improved error handling for streaming responses to ensure more robust
and informative error reporting.

- **Refactor**
- Centralized and streamlined session preparation and streaming logic
for AI chat providers.
  - Unified streaming setup across multiple AI model providers.

- **Tests**
- Extended test coverage for streaming object responses to ensure
reliability and correctness.

- **Documentation**
- Updated type definitions and schemas to reflect new streaming object
capabilities in both backend and frontend code.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2025-06-19 09:13:18 +08:00
Peng Xiao
ce951ec316 feat(editor): by default render code iframe for html preview (#12848)
#### PR Dependency Tree


* **PR #12848** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a feature flag to enable or disable web container
functionality for code block previews.
- **Improvements**
- Code block HTML previews now support an alternative rendering method
based on the new feature flag, enhancing flexibility.
- **Chores**
- Updated feature flag settings by removing an obsolete flag and adding
the new web container flag.
- **Tests**
- Simplified code block preview tests for faster and more direct
validation of HTML preview content.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 09:12:33 +08:00
Peng Xiao
e046260deb feat(core): allow importing affine file within import dialog (#12850) 2025-06-18 20:33:41 +08:00
DarkSky
31e65d96d4 fix(server): ci nextest (#12851)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Updated testing workflow to use a specific version of the testing tool
for improved consistency across jobs.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-18 20:20:00 +08:00
Peng Xiao
899ffd1ad3 feat(native): windows audio monitoring & recording (#12615)
fix AF-2692

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added comprehensive Windows support for audio and application capture,
including real-time microphone usage detection, combined microphone and
system audio recording, and application state monitoring.
  - The "meetings" setting is now enabled on Windows as well as macOS.
- Conditional UI styling and attributes introduced for Windows
environments in the Electron renderer.

- **Bug Fixes**
- Enhanced file path handling and validation for Windows in Electron
file requests.

- **Refactor**
- Unified application info handling across platforms by consolidating
types into a single `ApplicationInfo` structure.
- Updated native module APIs by removing deprecated types, refining
method signatures, and improving error messages.
- Streamlined audio tapping APIs to use process IDs and consistent
callback types.

- **Documentation**
- Added detailed documentation for the Windows-specific audio recording
and microphone listener modules.

- **Chores**
  - Updated development dependencies in multiple packages.
- Reorganized and added platform-specific dependencies and configuration
for Windows support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->





#### PR Dependency Tree


* **PR #12615** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2025-06-18 13:57:01 +08:00
DarkSky
c844786a7f chore(server): bump gemini to ga version (#12845)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Updated Gemini model identifiers from preview versions to their latest
stable versions across prompts and provider configurations. This ensures
continued compatibility and access to the latest Gemini 2.5 Flash and
Pro models. No changes to user-facing features or prompt content.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-18 12:42:19 +08:00
renovate[bot]
138c35a0f9 chore: bump up manticoresearch/manticore Docker tag to v10 (#12816)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| manticoresearch/manticore | service | major | `9.3.2` -> `10.1.0` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/toeverything/AFFiNE).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC41MC4wIiwidXBkYXRlZEluVmVyIjoiNDAuNTAuMCIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: fengmk2 <fengmk2@gmail.com>
2025-06-18 09:57:55 +08:00
renovate[bot]
29826e1c1e chore: bump up happy-dom version to v18 (#12799)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [happy-dom](https://redirect.github.com/capricorn86/happy-dom) |
[`^17.0.0` ->
`^18.0.0`](https://renovatebot.com/diffs/npm/happy-dom/17.4.7/18.0.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/happy-dom/18.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/happy-dom/18.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/happy-dom/17.4.7/18.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/happy-dom/17.4.7/18.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>capricorn86/happy-dom (happy-dom)</summary>

###
[`v18.0.1`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v18.0.1)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v18.0.0...v18.0.1)

##### 👷‍♂️ Patch fixes

- Addresses an issue where an error occurred if the Element ID was set
to the same name as a Window property with a null value - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1841](https://redirect.github.com/capricorn86/happy-dom/issues/1841)

###
[`v18.0.0`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v18.0.0)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.6.3...v18.0.0)

##### 💣 Breaking Changes

- Makes the types for Happy DOM strict - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)
- This makes it possible to use the option `skipLibCheck` set to "false"
in the typescript configuration for projects with a strict configuration
- This change has resulted in that some types has changed and is
therefore considered as a breaking change
- `BrowserContext.close()` now throws an error when trying to close the
default context of a browser - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)

##### 🎨 Features

- Adds support for `Browser.closed`, `BrowserContext.closed`,
`BrowserPage.closed` and `BrowserFrame.closed` - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)
- Adds support for `VirtualConsolePrinter.close()` and
`VirtualConsolePrinter.closed` - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)
- Adds support for `CookieContainer.clearCookies()` - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)

###
[`v17.6.3`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.6.3)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.6.2...v17.6.3)

##### 👷‍♂️ Patch fixes

- Removes global typescript definition that was used for custom elements
- By **[@&#8203;capricorn86](https://redirect.github.com/capricorn86)**
in task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)

###
[`v17.6.2`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.6.2)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.6.1...v17.6.2)

##### 👷‍♂️ Patch fixes

- Updates Typescript to the latest version - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1154](https://redirect.github.com/capricorn86/happy-dom/issues/1154)

###
[`v17.6.1`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.6.1)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.6.0...v17.6.1)

##### 🎨 Features

- Adds support for disabling validation of certificates, to allow for
self-signed certificates to be used - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1763](https://redirect.github.com/capricorn86/happy-dom/issues/1763)
- Read more about the new setting `fetch.disableStrictSSL` under
[IBrowserSettings](https://redirect.github.com/capricorn86/happy-dom/wiki/IBrowserSettings)
in the Wiki

###
[`v17.6.0`](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.9...v17.6.0)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.9...v17.6.0)

###
[`v17.5.9`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.9)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.8...v17.5.9)

##### 👷‍♂️ Patch fixes

- Adds missing null check in `HTMLLinkElement` for a browser frame
property that becomes null during teardown of a `Window` - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1800](https://redirect.github.com/capricorn86/happy-dom/issues/1800)

###
[`v17.5.8`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.8)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.7...v17.5.8)

##### 👷‍♂️ Patch fixes

- Incorrect cache matching caused `Element.classList` to return the
wrong items - By
**[@&#8203;capricorn86](https://redirect.github.com/capricorn86)** in
task
[#&#8203;1812](https://redirect.github.com/capricorn86/happy-dom/issues/1812)

###
[`v17.5.7`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.7)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.6...v17.5.7)

##### 👷‍♂️ Patch fixes

- Handle wider range of valid characters in unquoted attribute value
parsing - By **[@&#8203;AudunWA](https://redirect.github.com/AudunWA)**
in task
[#&#8203;1817](https://redirect.github.com/capricorn86/happy-dom/issues/1817)

###
[`v17.5.6`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.6)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.5...v17.5.6)

##### 👷‍♂️ Patch fixes

- Removes the min and max boundary check when setting the value of an
input field of type "date" - By
**[@&#8203;zgrybus](https://redirect.github.com/zgrybus)** in task
[#&#8203;1815](https://redirect.github.com/capricorn86/happy-dom/issues/1815)

###
[`v17.5.5`](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.4...v17.5.5)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.4...v17.5.5)

###
[`v17.5.4`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.4)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.3...v17.5.4)

##### 👷‍♂️ Patch fixes

- Fixes issue where the body of a `ReadableStream` was locked after
being cloned - By
**[@&#8203;MarcMcIntosh](https://redirect.github.com/MarcMcIntosh)** in
task
[#&#8203;1493](https://redirect.github.com/capricorn86/happy-dom/issues/1493)

###
[`v17.5.3`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.3)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.2...v17.5.3)

##### 👷‍♂️ Patch fixes

- Adds `previousSibling` and `nextSibling` to `MutationObserver` records
when a child is removed - By
**[@&#8203;uxuip](https://redirect.github.com/uxuip)** in task
[#&#8203;1803](https://redirect.github.com/capricorn86/happy-dom/issues/1803)

###
[`v17.5.2`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.2)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.1...v17.5.2)

##### 👷‍♂️ Patch fixes

- Adds support for the unicode characters `«` and `»` in query selectors
used by the React 19.1 "useId" hook - By
**[@&#8203;terrymun](https://redirect.github.com/terrymun)** in task
[#&#8203;1785](https://redirect.github.com/capricorn86/happy-dom/issues/1785)

###
[`v17.5.1`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.1)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.5.0...v17.5.1)

##### 👷‍♂️ Patch fixes

- Existing URL query string should be overwritten on form submit when
method is "GET" - By
**[@&#8203;rslabbert](https://redirect.github.com/rslabbert)** in task
[#&#8203;1786](https://redirect.github.com/capricorn86/happy-dom/issues/1786)

###
[`v17.5.0`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.5.0)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.4.9...v17.5.0)

##### 🎨 Features

- Adds support for `XMLHttpRequest.overrideMimeType()` - By
**[@&#8203;maxmil](https://redirect.github.com/maxmil)** in task
[#&#8203;1782](https://redirect.github.com/capricorn86/happy-dom/issues/1782)

###
[`v17.4.9`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.4.9)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.4.8...v17.4.9)

##### 👷‍♂️ Patch fixes

- A disabled input element should not be parsed in `FormData` - By
**[@&#8203;juandiegombr](https://redirect.github.com/juandiegombr)** in
task
[#&#8203;1790](https://redirect.github.com/capricorn86/happy-dom/issues/1790)

###
[`v17.4.8`](https://redirect.github.com/capricorn86/happy-dom/releases/tag/v17.4.8)

[Compare
Source](https://redirect.github.com/capricorn86/happy-dom/compare/v17.4.7...v17.4.8)

##### 👷‍♂️ Patch fixes

- Fixes issue where CSS variables where not being parsed in color
functions - By
**[@&#8203;hampustagerud](https://redirect.github.com/hampustagerud)**
in task
[#&#8203;1822](https://redirect.github.com/capricorn86/happy-dom/issues/1822)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/toeverything/AFFiNE).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC41MC4wIiwidXBkYXRlZEluVmVyIjoiNDAuNTAuMCIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: fengmk2 <fengmk2@gmail.com>
2025-06-17 22:52:01 +08:00
Peng Xiao
f4c20056a0 feat(core): moving in affine-reader doc parsers (#12840)
fix AI-191

#### PR Dependency Tree


* **PR #12840** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced the ability to convert rich text documents into Markdown,
supporting a wide range of content types such as headings, lists,
tables, images, code blocks, attachments, and embedded documents.
- Added support for parsing collaborative document structures and
rendering them as structured Markdown or parsed representations.
- Enhanced handling of database and table blocks, including conversion
to Markdown tables with headers and cell content.

- **Documentation**
  - Added a README noting the use of a forked Markdown converter.

- **Tests**
  - Added new test coverage for document parsing features.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


#### PR Dependency Tree


* **PR #12840** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-17 16:32:11 +08:00
Cats Juice
dfe4c22a75 feat(core): linked doc visiblity setting and new sidebar layout (#12836)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a setting to control the visibility of linked document
structures in the sidebar, enabled by default.
- Introduced a "dense" mode for workspace selectors and cards, providing
a more compact display.

- **Improvements**
- Refined sidebar and navigation panel layouts with updated padding,
spacing, and avatar/button sizing for a cleaner and more consistent
appearance.
- Enhanced sidebar appearance settings UI, including new localization
for the linked doc visibility option.
- Updated color theming and spacing in sidebar menu items and quick
search input for better usability.
- Enabled collapsible behavior control for navigation panel tree nodes,
improving user interaction flexibility.

- **Style**
- Adjusted various component styles for improved compactness and
alignment across the sidebar and navigation panels.
- Reduced sizes and padding of buttons and icons for a tidier interface.
- Updated CSS variables and dynamic sizing for workspace cards to
support dense mode.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-17 16:09:34 +08:00
L-Sun
ba718b955a fix(editor): unexpectedly update edgeless note in readonly mode (#12839)
#### PR Dependency Tree


* **PR #12839** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2025-06-17 15:42:47 +08:00
DarkSky
09c3aa0a92 chore(server): improve semantic search (#12838)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Updated document-related tools in chat prompts, including new options
for document keyword and semantic search.

- **Refactor**
- Renamed and reorganized document search tools for improved clarity in
tool selection and results display.

- **Bug Fixes**
- Ensured tool identifiers and results are consistent across chat and
search features.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-17 15:01:02 +08:00
Yii
a4d929b19c ci: remove graphite pre check (#12834)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Updated the CI workflow by removing the "optimize_ci" job and all
related dependencies and conditions. All remaining jobs now run
unconditionally.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-17 13:37:10 +08:00
EYHN
c1691157f9 feat(core): enable socket cors (#12823)
fix android & ios selfhost syncing

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved WebSocket connection compatibility by enabling cross-origin
requests with credentials and restricting allowed HTTP methods to GET
and POST.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: fengmk2 <fengmk2@gmail.com>
2025-06-17 09:40:08 +08:00
Cats Juice
2366c1aba6 feat(core): adjust the layout, style, and structure of the AI chat input (#12828)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added support for image uploads in the chat panel, including upload
limits and user feedback when limits are exceeded.
- Introduced a unified chat input preference menu for selecting AI
models, toggling extended thinking, and enabling web search.
- Menu buttons and menus now support test identifiers for improved
testing.

- **Improvements**
- Updated chat input UI with enhanced styling, consolidated controls,
and simplified feature toggling.
  - Improved layout and spacing for chat chips and image preview grids.
  - Chat abort icon now adapts to the current color theme.

- **Refactor**
- Replaced the separate AI model selection component with the new chat
input preference menu.
- Streamlined imports and custom element registrations for chat input
preferences.

- **Tests**
- Enhanced test utilities to support the new chat input preference menu
interactions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-17 09:26:29 +08:00
DarkSky
cdaaa52845 feat(server): embedding search tool (#12810) 2025-06-17 09:22:56 +08:00
Mirone
0785438cfe docs(editor): add typedoc for schema module (#12830)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Added comprehensive documentation for the `Schema` class, detailing
its methods, properties, and usage.
- Improved formatting and linking in the documentation for the `Store`
class, enhancing clarity and navigation.
- Updated the README to include a direct link to the new `Schema` class
documentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 22:24:40 +08:00
Mirone
8f5851e8bf chore: disable code block html preview (#12829)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Updated the default setting for the code block HTML preview feature
flag; it is now disabled by default. This change affects only
experimental builds.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: L-Sun <zover.v@gmail.com>
2025-06-16 21:28:42 +08:00
Aadi
1fb68e3933 fix(editor): filterableList - prevent undefined item selection in keyboard nav (#12818)
Fixes error in FilterableList when pressing Enter on empty search
results.


![image](https://github.com/user-attachments/assets/3929c7ab-b20e-40d9-bc3d-808762ada8f3)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Resolved an issue where pressing Enter could cause errors if no item
was focused in filterable lists. Now, selection only occurs when a valid
item is focused.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 18:05:49 +08:00
DarkSky
e118db4387 chore(ios): update gql schema (#12825)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced advanced search and aggregation capabilities, including
support for new search query types, options, and pagination.
- Added new GraphQL mutations and queries for managing workspace
embedding files and ignored documents.
- Extended user and workspace management with new fields and
configuration options.
- Added support for sending test emails and validating app
configuration.

- **Improvements**
- Enhanced license management with updated fragments and additional
fields.
- Improved invitation and member management workflows, including removal
of deprecated arguments and streamlined APIs.
- Expanded support for audio transcription actions and retry
functionality.
- Added new enum values for OAuth providers, server features, and
workspace member status.

- **Removals**
- Deprecated and removed legacy queries and mutations related to user
roles and invitations.

- **Bug Fixes**
- Corrected field types and documentation comments for improved
consistency and clarity.

- **Other**
- Numerous schema and type updates to support new features and enhance
data modeling.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 16:35:15 +08:00
fengmk2
c0c813edfd feat(server): search blob names from indexer (#12822)
#### PR Dependency Tree


* **PR #12822** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added the ability to search for blob names by their IDs within a
workspace.
- **Tests**
- Introduced new test cases and snapshot tests to validate searching
blob names and reading filenames from document snapshots.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 16:34:23 +08:00
renovate[bot]
4f75111055 chore: bump up sinon version to v21 (#12827)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [sinon](https://sinonjs.org/)
([source](https://redirect.github.com/sinonjs/sinon)) | [`^20.0.0` ->
`^21.0.0`](https://renovatebot.com/diffs/npm/sinon/20.0.0/21.0.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/sinon/21.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/sinon/21.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/sinon/20.0.0/21.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sinon/20.0.0/21.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>sinonjs/sinon (sinon)</summary>

###
[`v21.0.0`](https://redirect.github.com/sinonjs/sinon/blob/HEAD/CHANGES.md#2100)

[Compare
Source](https://redirect.github.com/sinonjs/sinon/compare/v20.0.0...52b0d97a0ff32888a26941325b9dc0a059fdf739)

-
[`fd10f13f`](fd10f13f3f)
chore!: remove assert.failException property
([#&#8203;2659](https://redirect.github.com/sinonjs/sinon/issues/2659))
(Morgan Roderick)
> This was used for allowing customisation of the thrown error between
> sandboxes and for customisation for integrations (most likely from the
    > days of BusterJS).
    >
> To my knowledge and what I've been able to find on GitHub, this has
    > never had any *production* use by end users.
    >
    > BREAKING CHANGE: this removes assert.failException from the API

*Released by Morgan Roderick on 2025-06-13.*

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/toeverything/AFFiNE).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC41MC4wIiwidXBkYXRlZEluVmVyIjoiNDAuNTAuMCIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 16:23:37 +08:00
renovate[bot]
3335f9bb00 chore: bump up @nestjs-cls/transactional-adapter-prisma version to v1.2.24 (#12826)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[@nestjs-cls/transactional-adapter-prisma](https://papooch.github.io/nestjs-cls/)
([source](https://redirect.github.com/Papooch/nestjs-cls)) | [`1.2.23`
->
`1.2.24`](https://renovatebot.com/diffs/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.23/1.2.24)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.23/1.2.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.23/1.2.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>Papooch/nestjs-cls
(@&#8203;nestjs-cls/transactional-adapter-prisma)</summary>

###
[`v1.2.24`](https://redirect.github.com/Papooch/nestjs-cls/compare/@nestjs-cls/transactional-adapter-prisma@1.2.23...@nestjs-cls/transactional-adapter-prisma@1.2.24)

[Compare
Source](https://redirect.github.com/Papooch/nestjs-cls/compare/@nestjs-cls/transactional-adapter-prisma@1.2.23...@nestjs-cls/transactional-adapter-prisma@1.2.24)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/toeverything/AFFiNE).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC41MC4wIiwidXBkYXRlZEluVmVyIjoiNDAuNTAuMCIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 15:54:27 +08:00
renovate[bot]
566ff7470e chore: bump up oxlint version to v1.1.0 (#12509)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [oxlint](https://oxc.rs)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint))
| [`0.16.11` ->
`0.18.1`](https://renovatebot.com/diffs/npm/oxlint/0.16.11/0.18.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/oxlint/0.18.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/oxlint/0.18.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/oxlint/0.16.11/0.18.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxlint/0.16.11/0.18.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxlint)</summary>

###
[`v0.18.1`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.18.1):
oxlint v0.18.1

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.18.0...oxlint_v0.18.1)

#### \[0.18.1] - 2025-06-09

##### 🐛 Bug Fixes

-
[`6d68568`](https://redirect.github.com/oxc-project/oxc/commit/6d68568)
linter: False negative in typescript/array-type
([#&#8203;11574](https://redirect.github.com/oxc-project/oxc/issues/11574))
(camc314)
-
[`6a856a0`](https://redirect.github.com/oxc-project/oxc/commit/6a856a0)
linter/no-magic-numbers: Fix typo in error message
([#&#8203;11560](https://redirect.github.com/oxc-project/oxc/issues/11560))
(overlookmotel)
-
[`3952e01`](https://redirect.github.com/oxc-project/oxc/commit/3952e01)
linter: False negative in jsx-a11y/aria-role
([#&#8203;11547](https://redirect.github.com/oxc-project/oxc/issues/11547))
(camc314)
-
[`b0e3e08`](https://redirect.github.com/oxc-project/oxc/commit/b0e3e08)
linter: Misplaced quote in jsx-curly-brace-presence test case
([#&#8203;11546](https://redirect.github.com/oxc-project/oxc/issues/11546))
(camc314)
-
[`a833ed1`](https://redirect.github.com/oxc-project/oxc/commit/a833ed1)
linter: Misplaced quote in anchor-is-valid test case
([#&#8203;11545](https://redirect.github.com/oxc-project/oxc/issues/11545))
(camc314)
-
[`4e53b80`](https://redirect.github.com/oxc-project/oxc/commit/4e53b80)
linter: Misplaced backtick in exhaustive-deps test case
([#&#8203;11544](https://redirect.github.com/oxc-project/oxc/issues/11544))
(camc314)
-
[`e8a04b6`](https://redirect.github.com/oxc-project/oxc/commit/e8a04b6)
linter: Misplaced backtick in no-object-constructor test case
([#&#8203;11543](https://redirect.github.com/oxc-project/oxc/issues/11543))
(camc314)
-
[`65311d0`](https://redirect.github.com/oxc-project/oxc/commit/65311d0)
linter: Remove duplicate rule/scope from diagnostic
([#&#8203;11531](https://redirect.github.com/oxc-project/oxc/issues/11531))
(camc314)

##### 🚜 Refactor

-
[`7ab84c2`](https://redirect.github.com/oxc-project/oxc/commit/7ab84c2)
editor: Use pattern for textDocument filter
([#&#8203;11559](https://redirect.github.com/oxc-project/oxc/issues/11559))
(Sysix)
-
[`9b475ad`](https://redirect.github.com/oxc-project/oxc/commit/9b475ad)
linter: Use one instance of rope per file
([#&#8203;11552](https://redirect.github.com/oxc-project/oxc/issues/11552))
(Sysix)

##### 📚 Documentation

-
[`e13ed51`](https://redirect.github.com/oxc-project/oxc/commit/e13ed51)
editor/vscode: Fix typo in README
([#&#8203;11572](https://redirect.github.com/oxc-project/oxc/issues/11572))
(David)
-
[`fa924ab`](https://redirect.github.com/oxc-project/oxc/commit/fa924ab)
linter: Cleanup docs for multiple linter rules
([#&#8203;11551](https://redirect.github.com/oxc-project/oxc/issues/11551))
(Ulrich Stark)

#####  Performance

-
[`7bf25cb`](https://redirect.github.com/oxc-project/oxc/commit/7bf25cb)
language_server: Transform `MessageWithPosition` to `Diagnostic` with
less allocations
([#&#8203;11561](https://redirect.github.com/oxc-project/oxc/issues/11561))
(Sysix)

###
[`v0.18.0`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.18.0):
oxlint v0.18.0

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.17.0...oxlint_v0.18.0)

#### \[0.18.0] - 2025-06-06

-
[`bd9dd88`](https://redirect.github.com/oxc-project/oxc/commit/bd9dd88)
linter: \[**BREAKING**] Add more info to json reporter
([#&#8203;11524](https://redirect.github.com/oxc-project/oxc/issues/11524))
(camc314)

##### Features

-
[`825d40c`](https://redirect.github.com/oxc-project/oxc/commit/825d40c)
linter: Fix casing in unicorn/no-useless-promise-resolve-reject
([#&#8203;11528](https://redirect.github.com/oxc-project/oxc/issues/11528))
(camc314)
-
[`2faee3d`](https://redirect.github.com/oxc-project/oxc/commit/2faee3d)
linter: Fix grammer in react/exhaustive-deps
([#&#8203;11527](https://redirect.github.com/oxc-project/oxc/issues/11527))
(camc314)

##### Bug Fixes

-
[`1a71d7c`](https://redirect.github.com/oxc-project/oxc/commit/1a71d7c)
linter: Misplaced backtick in unicorn/no-array-for-each diagnostic
([#&#8203;11529](https://redirect.github.com/oxc-project/oxc/issues/11529))
(camc314)
-
[`7430b14`](https://redirect.github.com/oxc-project/oxc/commit/7430b14)
linter: Grammer in jest/valid-expect diagnostic
([#&#8203;11522](https://redirect.github.com/oxc-project/oxc/issues/11522))
(camc314)
-
[`b92ac41`](https://redirect.github.com/oxc-project/oxc/commit/b92ac41)
linter: Grammer in eslint/no-redeclare diagnostic
([#&#8203;11521](https://redirect.github.com/oxc-project/oxc/issues/11521))
(camc314)
-
[`17883e3`](https://redirect.github.com/oxc-project/oxc/commit/17883e3)
linter: Improve eslint/no-unsafe-negation diagnostic
([#&#8203;11520](https://redirect.github.com/oxc-project/oxc/issues/11520))
(camc314)
-
[`8c89937`](https://redirect.github.com/oxc-project/oxc/commit/8c89937)
linter: Improve eslint/no-shadow-restricted-names diagnostic
([#&#8203;11519](https://redirect.github.com/oxc-project/oxc/issues/11519))
(camc314)
-
[`3f0d889`](https://redirect.github.com/oxc-project/oxc/commit/3f0d889)
linter: Add missing article to oxc/bad-array-method-on-arguments
diagnostic
([#&#8203;11518](https://redirect.github.com/oxc-project/oxc/issues/11518))
(camc314)
-
[`cf0c24c`](https://redirect.github.com/oxc-project/oxc/commit/cf0c24c)
linter: Improve message in react/prefer-es6-class diagnostic
([#&#8203;11516](https://redirect.github.com/oxc-project/oxc/issues/11516))
(camc314)
-
[`91855df`](https://redirect.github.com/oxc-project/oxc/commit/91855df)
linter: Fix message in react/rules-of-hooks diagnostic
([#&#8203;11515](https://redirect.github.com/oxc-project/oxc/issues/11515))
(camc314)
-
[`b272194`](https://redirect.github.com/oxc-project/oxc/commit/b272194)
linter: Misplaced backtick in jest/no-conditional-expect diagnostic
([#&#8203;11514](https://redirect.github.com/oxc-project/oxc/issues/11514))
(camc314)
-
[`3403303`](https://redirect.github.com/oxc-project/oxc/commit/3403303)
linter: Misplaced backtick in unicorn/prefer-dom-node-dataset diagnostic
([#&#8203;11513](https://redirect.github.com/oxc-project/oxc/issues/11513))
(camc314)
-
[`d5ca872`](https://redirect.github.com/oxc-project/oxc/commit/d5ca872)
linter: Misplaced backtick in eslint/radix diagnostic
([#&#8203;11512](https://redirect.github.com/oxc-project/oxc/issues/11512))
(camc314)
-
[`2dcf8be`](https://redirect.github.com/oxc-project/oxc/commit/2dcf8be)
linter: Improve diagnostic message when function name is referenced
([#&#8203;11509](https://redirect.github.com/oxc-project/oxc/issues/11509))
(camc314)
-
[`0de0c9c`](https://redirect.github.com/oxc-project/oxc/commit/0de0c9c)
linter: Improve diagnostic message for no-unsafe-declaration-merging
([#&#8203;11508](https://redirect.github.com/oxc-project/oxc/issues/11508))
(camc314)
-
[`0946dac`](https://redirect.github.com/oxc-project/oxc/commit/0946dac)
linter: Correctly inherit categories when plugins are enabled
([#&#8203;11353](https://redirect.github.com/oxc-project/oxc/issues/11353))
(Cameron)
-
[`510c1c6`](https://redirect.github.com/oxc-project/oxc/commit/510c1c6)
linter: Add missing `allowArrowFunctions` option for eslint/func-style
([#&#8203;11455](https://redirect.github.com/oxc-project/oxc/issues/11455))
(yefan)
-
[`c77787c`](https://redirect.github.com/oxc-project/oxc/commit/c77787c)
linter: Improve `eslint/no-loss-of-precision`
([#&#8203;11437](https://redirect.github.com/oxc-project/oxc/issues/11437))
(magic-akari)
-
[`11d4523`](https://redirect.github.com/oxc-project/oxc/commit/11d4523)
linter: False positive in react/exhaustive-deps
([#&#8203;11438](https://redirect.github.com/oxc-project/oxc/issues/11438))
(camc314)
-
[`616b613`](https://redirect.github.com/oxc-project/oxc/commit/616b613)
linter/switch-case-braces: Align the logic with `unicorn`
([#&#8203;11405](https://redirect.github.com/oxc-project/oxc/issues/11405))
(shulaoda)

##### Refactor

-
[`db0b099`](https://redirect.github.com/oxc-project/oxc/commit/db0b099)
language_server: Convert only once uri to path when creating
`ServerLinter`
([#&#8203;11503](https://redirect.github.com/oxc-project/oxc/issues/11503))
(Sysix)
-
[`ccceb52`](https://redirect.github.com/oxc-project/oxc/commit/ccceb52)
language_server: Simplify `workspace/didChangeConfiguration` call
([#&#8203;11462](https://redirect.github.com/oxc-project/oxc/issues/11462))
(Sysix)
-
[`0fdc51e`](https://redirect.github.com/oxc-project/oxc/commit/0fdc51e)
linter: Simplify `OxlintRules::override_rules`
([#&#8203;11510](https://redirect.github.com/oxc-project/oxc/issues/11510))
(camc314)

##### Testing

-
[`2ba2893`](https://redirect.github.com/oxc-project/oxc/commit/2ba2893)
editor: Fix test for auto `fixAll` on save
([#&#8203;11448](https://redirect.github.com/oxc-project/oxc/issues/11448))
(Sysix)

###
[`v0.17.0`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.17.0):
oxlint v0.17.0

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.16.12...oxlint_v0.17.0)

#### \[0.17.0] - 2025-05-30

-
[`ead5309`](https://redirect.github.com/oxc-project/oxc/commit/ead5309)
linter: \[**BREAKING**] Remove react from default plugin set
([#&#8203;11382](https://redirect.github.com/oxc-project/oxc/issues/11382))
(camc314)

##### Features

-
[`2d25bd8`](https://redirect.github.com/oxc-project/oxc/commit/2d25bd8)
linter: Remove `unicorn/no-for-loop` over `typescript/prefer-for-of`
([#&#8203;11354](https://redirect.github.com/oxc-project/oxc/issues/11354))
(camc314)
-
[`bbb7eb1`](https://redirect.github.com/oxc-project/oxc/commit/bbb7eb1)
linter: Add auto-fix to react/forward-ref-uses-ref
([#&#8203;11342](https://redirect.github.com/oxc-project/oxc/issues/11342))
(yefan)
-
[`590c27b`](https://redirect.github.com/oxc-project/oxc/commit/590c27b)
linter: Add auto-fix to unicorn/no-await-expression-member
([#&#8203;11306](https://redirect.github.com/oxc-project/oxc/issues/11306))
(yefan)
-
[`7824f01`](https://redirect.github.com/oxc-project/oxc/commit/7824f01)
linter: Implement suggestion for `jsx/no-useless-fragment`
([#&#8203;10800](https://redirect.github.com/oxc-project/oxc/issues/10800))
(Cam McHenry)
-
[`2083d33`](https://redirect.github.com/oxc-project/oxc/commit/2083d33)
linter/language_server: Add second editor suggestion for
`react/forward-ref-uses-ref`
([#&#8203;11375](https://redirect.github.com/oxc-project/oxc/issues/11375))
(Sysix)

##### Bug Fixes

-
[`f6424dd`](https://redirect.github.com/oxc-project/oxc/commit/f6424dd)
linter: Reflect react plugin is disabled by default in cli
([#&#8203;11397](https://redirect.github.com/oxc-project/oxc/issues/11397))
(camc314)
-
[`25ecbfe`](https://redirect.github.com/oxc-project/oxc/commit/25ecbfe)
linter: Remove use of `FrameworkFlags::React` to decide whether rules
should run
([#&#8203;11383](https://redirect.github.com/oxc-project/oxc/issues/11383))
(camc314)
-
[`0d240e4`](https://redirect.github.com/oxc-project/oxc/commit/0d240e4)
linter: False positive in react/exhaustive-deps with default formal
parameter
([#&#8203;11395](https://redirect.github.com/oxc-project/oxc/issues/11395))
(camc314)
-
[`c91697e`](https://redirect.github.com/oxc-project/oxc/commit/c91697e)
linter: Fix panic in multi byte char in `TryFrom` aria
([#&#8203;11350](https://redirect.github.com/oxc-project/oxc/issues/11350))
(camc314)
-
[`9798ef1`](https://redirect.github.com/oxc-project/oxc/commit/9798ef1)
linter: Stack overflow in no-async-endpoint-handlers
([#&#8203;11317](https://redirect.github.com/oxc-project/oxc/issues/11317))
(camc314)
-
[`348ad97`](https://redirect.github.com/oxc-project/oxc/commit/348ad97)
linter: Skip no-unused-vars on astro files
([#&#8203;11303](https://redirect.github.com/oxc-project/oxc/issues/11303))
(camc314)
-
[`183d7f0`](https://redirect.github.com/oxc-project/oxc/commit/183d7f0)
linter: Make `jest/no-large-snapshots` error easier to comprehend
([#&#8203;11294](https://redirect.github.com/oxc-project/oxc/issues/11294))
(Ulrich Stark)
-
[`4e606a5`](https://redirect.github.com/oxc-project/oxc/commit/4e606a5)
linter: Improve `jest/no-large-snapshots`
([#&#8203;11291](https://redirect.github.com/oxc-project/oxc/issues/11291))
(Ulrich Stark)
-
[`14f790f`](https://redirect.github.com/oxc-project/oxc/commit/14f790f)
linter: Improve `jest/no-restricted-matchers`
([#&#8203;11292](https://redirect.github.com/oxc-project/oxc/issues/11292))
(Ulrich Stark)
-
[`a2c82be`](https://redirect.github.com/oxc-project/oxc/commit/a2c82be)
linter/block-scoped-var: Better diagnostic messages
([#&#8203;11290](https://redirect.github.com/oxc-project/oxc/issues/11290))
(DonIsaac)
-
[`19772e5`](https://redirect.github.com/oxc-project/oxc/commit/19772e5)
linter/no-unused-vars: Panic when variable is redeclared as function in
same scope
([#&#8203;11280](https://redirect.github.com/oxc-project/oxc/issues/11280))
(Dunqing)
-
[`7af5bb1`](https://redirect.github.com/oxc-project/oxc/commit/7af5bb1)
oxc_language_server: Include save option for text document sync
capability
([#&#8203;11297](https://redirect.github.com/oxc-project/oxc/issues/11297))
(Nicholas Rayburn)

##### Performance

-
[`0ed6c1a`](https://redirect.github.com/oxc-project/oxc/commit/0ed6c1a)
language_server: Use `Arc<RwLock>` instead of `Mutex` for workspace
workers
([#&#8203;11328](https://redirect.github.com/oxc-project/oxc/issues/11328))
(Sysix)
-
[`a0ee946`](https://redirect.github.com/oxc-project/oxc/commit/a0ee946)
linter: Reduce code size in `globals`
([#&#8203;11333](https://redirect.github.com/oxc-project/oxc/issues/11333))
(shulaoda)
-
[`c90c5e9`](https://redirect.github.com/oxc-project/oxc/commit/c90c5e9)
linter/no-unused-vars: Simplify checking self call usage
([#&#8203;11281](https://redirect.github.com/oxc-project/oxc/issues/11281))
(Dunqing)

##### Documentation

-
[`eae51ca`](https://redirect.github.com/oxc-project/oxc/commit/eae51ca)
linter: Clarify jsdoc/check-tag-names configuration
([#&#8203;11394](https://redirect.github.com/oxc-project/oxc/issues/11394))
(Rägnar O'ock)
-
[`cd354d4`](https://redirect.github.com/oxc-project/oxc/commit/cd354d4)
oxlint: Remove incorrect doc comment
([#&#8203;11326](https://redirect.github.com/oxc-project/oxc/issues/11326))
(camc314)

##### Refactor

-
[`42738f0`](https://redirect.github.com/oxc-project/oxc/commit/42738f0)
linter: Shorten code of match arms
([#&#8203;11389](https://redirect.github.com/oxc-project/oxc/issues/11389))
(Ulrich Stark)
-
[`8a34447`](https://redirect.github.com/oxc-project/oxc/commit/8a34447)
linter: Improve `unicorn/text-encoding-identifier-case`
([#&#8203;11386](https://redirect.github.com/oxc-project/oxc/issues/11386))
(shulaoda)
-
[`eaa605e`](https://redirect.github.com/oxc-project/oxc/commit/eaa605e)
linter: Avoid some `Arc::clone` in linter runtime
([#&#8203;11388](https://redirect.github.com/oxc-project/oxc/issues/11388))
(Boshen)
-
[`1cd8b9c`](https://redirect.github.com/oxc-project/oxc/commit/1cd8b9c)
linter: Fixes in `react/forward-ref-uses-ref` are suggestions
([#&#8203;11376](https://redirect.github.com/oxc-project/oxc/issues/11376))
(Sysix)
-
[`50ef691`](https://redirect.github.com/oxc-project/oxc/commit/50ef691)
linter: Add `diagnostics_with_multiple_fixes` to `LintContext`
([#&#8203;11357](https://redirect.github.com/oxc-project/oxc/issues/11357))
(Sysix)
-
[`606bb34`](https://redirect.github.com/oxc-project/oxc/commit/606bb34)
linter: Accept `PossibleFixes` instead of `Fix` for `Messages`
([#&#8203;11295](https://redirect.github.com/oxc-project/oxc/issues/11295))
(Sysix)
-
[`042a3f3`](https://redirect.github.com/oxc-project/oxc/commit/042a3f3)
linter: Use `PossibleFixes` instead of `Option<Fix>`
([#&#8203;11284](https://redirect.github.com/oxc-project/oxc/issues/11284))
(Sysix)
-
[`ffcfb46`](https://redirect.github.com/oxc-project/oxc/commit/ffcfb46)
linter: Improve `unicorn/throw-new-error`
([#&#8203;11364](https://redirect.github.com/oxc-project/oxc/issues/11364))
(shulaoda)
-
[`8fb55c3`](https://redirect.github.com/oxc-project/oxc/commit/8fb55c3)
linter: Cleanup docs and simplify code of `eslint/no-fallthrough`
([#&#8203;11331](https://redirect.github.com/oxc-project/oxc/issues/11331))
(Ulrich Stark)
-
[`e2f0f0a`](https://redirect.github.com/oxc-project/oxc/commit/e2f0f0a)
linter: Improve docs and simplify code of `eslint/no-duplicate-imports`
([#&#8203;11320](https://redirect.github.com/oxc-project/oxc/issues/11320))
(Ulrich Stark)
-
[`b53b053`](https://redirect.github.com/oxc-project/oxc/commit/b53b053)
linter: Simplify accessing span of NameSpan
([#&#8203;11305](https://redirect.github.com/oxc-project/oxc/issues/11305))
(Ulrich Stark)
-
[`4bc2650`](https://redirect.github.com/oxc-project/oxc/commit/4bc2650)
linter: Improve `eslint/no-void`
([#&#8203;11285](https://redirect.github.com/oxc-project/oxc/issues/11285))
(shulaoda)

##### Styling

-
[`49b664c`](https://redirect.github.com/oxc-project/oxc/commit/49b664c)
linter: Remove needless newline in `declare_oxc_lint`
([#&#8203;11400](https://redirect.github.com/oxc-project/oxc/issues/11400))
(camc314)

##### Testing

-
[`c4f64aa`](https://redirect.github.com/oxc-project/oxc/commit/c4f64aa)
linter: Explicitly disable correctness for clarity
([#&#8203;11327](https://redirect.github.com/oxc-project/oxc/issues/11327))
(camc314)
-
[`a404b2c`](https://redirect.github.com/oxc-project/oxc/commit/a404b2c)
linter: `eslint/no-duplicate-imports` shouldn't report the same span
([#&#8203;11324](https://redirect.github.com/oxc-project/oxc/issues/11324))
(Ulrich Stark)

###
[`v0.16.12`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#01612---2025-05-25)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.16.11...oxlint_v0.16.12)

##### Features

-
[`6a7018e`](https://redirect.github.com/oxc-project/oxc/commit/6a7018e)
linter: Generate stricter json schema for lint plugins
([#&#8203;11219](https://redirect.github.com/oxc-project/oxc/issues/11219))
(camc314)

##### Bug Fixes

-
[`e8470d9`](https://redirect.github.com/oxc-project/oxc/commit/e8470d9)
linter: Delay merging of oxlintrc configs
([#&#8203;10835](https://redirect.github.com/oxc-project/oxc/issues/10835))
(camc314)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/toeverything/AFFiNE).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC4xNi4wIiwidXBkYXRlZEluVmVyIjoiNDAuNTAuMCIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Refactor**
- Simplified array element retrieval across multiple components and
utilities by replacing `.filter(...)[0]` with `.find(...)` or
`.findLast(...)`, improving code readability and efficiency.
- Improved JSX structure in the audio player component by nesting
elements directly rather than using a `children` prop.
- Enhanced code organization in the modal container by repositioning
functions and updating dependency arrays for better maintainability.
- Added a comment to disable a specific lint rule in a React hook for
clarity.

- **Chores**
- Updated the `oxlint` development dependency to allow for newer
compatible versions.

- **Tests**
- Refactored test setup logic for more direct and clear retrieval of
test data.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: LongYinan <lynweklm@gmail.com>
2025-06-16 15:20:48 +08:00
1009 changed files with 35793 additions and 14138 deletions

View File

@@ -1,7 +1,7 @@
name: affine
services:
affine:
image: ghcr.io/toeverything/affine-graphql:${AFFINE_REVISION:-stable}
image: ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}
container_name: affine_server
ports:
- '${PORT:-3010}:3010'
@@ -25,7 +25,7 @@ services:
restart: unless-stopped
affine_migration:
image: ghcr.io/toeverything/affine-graphql:${AFFINE_REVISION:-stable}
image: ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}
container_name: affine_migration_job
volumes:
# custom configurations

View File

@@ -540,6 +540,11 @@
"description": "Where the server get deployed(FQDN).\n@default \"localhost\"\n@environment `AFFINE_SERVER_HOST`",
"default": "localhost"
},
"hosts": {
"type": "array",
"description": "Multiple hosts the server will accept requests from.\n@default []",
"default": []
},
"port": {
"type": "number",
"description": "Which port the server will listen on.\n@default 3010\n@environment `AFFINE_SERVER_PORT`",
@@ -560,6 +565,11 @@
"type": "boolean",
"description": "Only allow users with early access features to access the app\n@default false",
"default": false
},
"allowGuestDemoWorkspace": {
"type": "boolean",
"description": "Whether allow guest users to create demo workspaces.\n@default true",
"default": true
}
}
},
@@ -587,6 +597,11 @@
"type": "string",
"description": "Allowed version range of the app that allowed to access the server. Requires 'client/versionControl.enabled' to be true to take effect.\n@default \">=0.20.0\"",
"default": ">=0.20.0"
},
"allowGuestDemoWorkspace": {
"type": "boolean",
"description": "Allow guests to access demo workspace.\n@default true",
"default": true
}
}
},
@@ -727,6 +742,11 @@
},
"default": {}
},
"providers.morph": {
"type": "object",
"description": "The config for the morph provider.\n@default {}",
"default": {}
},
"unsplash": {
"type": "object",
"description": "The config for the unsplash key.\n@default {\"key\":\"\"}",
@@ -864,22 +884,6 @@
}
}
},
"customerIo": {
"type": "object",
"description": "Configuration for customerIo module",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable customer.io integration\n@default false",
"default": false
},
"token": {
"type": "string",
"description": "Customer.io token\n@default \"\"",
"default": ""
}
}
},
"indexer": {
"type": "object",
"description": "Configuration for indexer module",
@@ -921,6 +925,22 @@
}
}
},
"customerIo": {
"type": "object",
"description": "Configuration for customerIo module",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable customer.io integration\n@default false",
"default": false
},
"token": {
"type": "string",
"description": "Customer.io token\n@default \"\"",
"default": ""
}
}
},
"oauth": {
"type": "object",
"description": "Configuration for oauth module",

View File

@@ -1,9 +1,6 @@
name: 'Deploy to Cluster'
description: 'Deploy AFFiNE Cloud to cluster'
inputs:
build-type:
description: 'Align with App build type, canary|beta|stable|internal'
default: 'canary'
gcp-project-number:
description: 'GCP project number'
required: true
@@ -36,5 +33,3 @@ runs:
- name: Deploy
shell: bash
run: node ./.github/actions/deploy/deploy.mjs
env:
BUILD_TYPE: '${{ inputs.build-type }}'

View File

@@ -126,7 +126,10 @@ const createHelmCommand = ({ isDryRun }) => {
? 'internal'
: 'dev';
const host = DEPLOY_HOST || CANARY_DEPLOY_HOST;
const hosts = (DEPLOY_HOST || CANARY_DEPLOY_HOST)
.split(',')
.map(host => host.trim())
.filter(host => host);
const deployCommand = [
`helm upgrade --install affine .github/helm/affine`,
`--namespace ${namespace}`,
@@ -135,7 +138,9 @@ const createHelmCommand = ({ isDryRun }) => {
`--set-string global.app.buildType="${buildType}"`,
`--set global.ingress.enabled=true`,
`--set-json global.ingress.annotations="{ \\"kubernetes.io/ingress.class\\": \\"gce\\", \\"kubernetes.io/ingress.allow-http\\": \\"true\\", \\"kubernetes.io/ingress.global-static-ip-name\\": \\"${STATIC_IP_NAME}\\" }"`,
`--set-string global.ingress.host="${host}"`,
...hosts.map(
(host, index) => `--set global.ingress.hosts[${index}]=${host}`
),
`--set-string global.version="${APP_VERSION}"`,
...redisAndPostgres,
...indexerOptions,
@@ -143,14 +148,14 @@ const createHelmCommand = ({ isDryRun }) => {
`--set-string web.image.tag="${imageTag}"`,
`--set graphql.replicaCount=${replica.graphql}`,
`--set-string graphql.image.tag="${imageTag}"`,
`--set graphql.app.host=${host}`,
`--set graphql.app.host=${hosts[0]}`,
`--set sync.replicaCount=${replica.sync}`,
`--set-string sync.image.tag="${imageTag}"`,
`--set-string renderer.image.tag="${imageTag}"`,
`--set renderer.app.host=${host}`,
`--set renderer.app.host=${hosts[0]}`,
`--set renderer.replicaCount=${replica.renderer}`,
`--set-string doc.image.tag="${imageTag}"`,
`--set doc.app.host=${host}`,
`--set doc.app.host=${hosts[0]}`,
`--set doc.replicaCount=${replica.doc}`,
...serviceAnnotations,
...resources,

View File

@@ -0,0 +1,41 @@
name: Prepare Release
description: 'Prepare Release'
outputs:
APP_VERSION:
description: 'App Version'
value: ${{ steps.get-version.outputs.APP_VERSION }}
GIT_SHORT_HASH:
description: 'Git Short Hash'
value: ${{ steps.get-version.outputs.GIT_SHORT_HASH }}
BUILD_TYPE:
description: 'Build Type'
value: ${{ steps.get-version.outputs.BUILD_TYPE }}
runs:
using: 'composite'
steps:
- name: Get Version
id: get-version
shell: bash
run: |
GIT_SHORT_HASH=$(git rev-parse --short HEAD)
if [ "${{ github.ref_type }}" == "tag" ]; then
APP_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//')
else
APP_VERSION=$(date '+%Y.%-m.%-d-canary.%-H%-M')
fi
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
BUILD_TYPE=stable
elif [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$ ]]; then
BUILD_TYPE=beta
elif [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-canary\.[0-9a-f]+$ ]]; then
BUILD_TYPE=canary
else
echo "Error: unsupported version string: $APP_VERSION" >&2
exit 1
fi
echo $APP_VERSION
echo $GIT_SHORT_HASH
echo $BUILD_TYPE
echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_OUTPUT"
echo "GIT_SHORT_HASH=$GIT_SHORT_HASH" >> "$GITHUB_OUTPUT"
echo "BUILD_TYPE=$BUILD_TYPE" >> "$GITHUB_OUTPUT"

View File

@@ -1,24 +1,12 @@
name: Setup Version
description: 'Setup Version'
outputs:
APP_VERSION:
inputs:
app-version:
description: 'App Version'
value: ${{ steps.version.outputs.APP_VERSION }}
required: true
runs:
using: 'composite'
steps:
- name: 'Write Version'
id: version
shell: bash
run: |
if [ "${{ github.ref_type }}" == "tag" ]; then
APP_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//')
else
PACKAGE_VERSION=$(node -p "require('./package.json').version")
TIME_VERSION=$(date +%Y%m%d%H%M)
GIT_SHORT_HASH=$(git rev-parse --short HEAD)
APP_VERSION=$PACKAGE_VERSION-nightly-$GIT_SHORT_HASH
fi
echo $APP_VERSION
echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_OUTPUT"
./scripts/set-version.sh $APP_VERSION
run: ./scripts/set-version.sh ${{ inputs.app-version }}

View File

@@ -3,4 +3,4 @@ name: affine
description: AFFiNE cloud chart
type: application
version: 0.0.0
appVersion: "0.21.0"
appVersion: "0.22.4"

View File

@@ -3,7 +3,7 @@ name: doc
description: AFFiNE doc server
type: application
version: 0.0.0
appVersion: "0.20.0"
appVersion: "0.22.4"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -1,6 +1,6 @@
replicaCount: 1
image:
repository: ghcr.io/toeverything/affine-graphql
repository: ghcr.io/toeverything/affine
pullPolicy: IfNotPresent
tag: ''

View File

@@ -3,7 +3,7 @@ name: graphql
description: AFFiNE GraphQL server
type: application
version: 0.0.0
appVersion: "0.21.0"
appVersion: "0.22.4"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -1,6 +1,6 @@
replicaCount: 1
image:
repository: ghcr.io/toeverything/affine-graphql
repository: ghcr.io/toeverything/affine
pullPolicy: IfNotPresent
tag: ''

View File

@@ -3,7 +3,7 @@ name: renderer
description: AFFiNE renderer server
type: application
version: 0.0.0
appVersion: "0.16.0"
appVersion: "0.22.4"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -1,6 +1,6 @@
replicaCount: 1
image:
repository: ghcr.io/toeverything/affine-graphql
repository: ghcr.io/toeverything/affine
pullPolicy: IfNotPresent
tag: ''

View File

@@ -3,7 +3,7 @@ name: sync
description: AFFiNE Sync Server
type: application
version: 0.0.0
appVersion: "0.21.0"
appVersion: "0.22.4"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -1,6 +1,6 @@
replicaCount: 1
image:
repository: ghcr.io/toeverything/affine-graphql
repository: ghcr.io/toeverything/affine
pullPolicy: IfNotPresent
tag: ''

View File

@@ -36,7 +36,8 @@ spec:
{{- end }}
{{- end }}
rules:
- host: "{{ .Values.global.ingress.host }}"
{{- range .Values.global.ingress.hosts }}
- host: {{ . | quote }}
http:
paths:
- path: /socket.io
@@ -45,33 +46,34 @@ spec:
service:
name: affine-sync
port:
number: {{ .Values.sync.service.port }}
number: {{ $.Values.sync.service.port }}
- path: /graphql
pathType: Prefix
backend:
service:
name: affine-graphql
port:
number: {{ .Values.graphql.service.port }}
number: {{ $.Values.graphql.service.port }}
- path: /api
pathType: Prefix
backend:
service:
name: affine-graphql
port:
number: {{ .Values.graphql.service.port }}
number: {{ $.Values.graphql.service.port }}
- path: /workspace
pathType: Prefix
backend:
service:
name: affine-renderer
port:
number: {{ .Values.renderer.service.port }}
number: {{ $.Values.renderer.service.port }}
- path: /
pathType: Prefix
backend:
service:
name: affine-web
port:
number: {{ .Values.web.service.port }}
number: {{ $.Values.web.service.port }}
{{- end }}
{{- end }}

View File

@@ -4,7 +4,13 @@ global:
ingress:
enabled: false
className: ''
host: affine.pro
# hosts for ingress rules
# e.g.
# hosts:
# - affine.pro
# - www.affine.pro
hosts:
- affine.pro
tls: []
secret:
secretName: 'server-private-key'

View File

@@ -3,7 +3,13 @@ name: Build Images
on:
workflow_call:
inputs:
flavor:
build-type:
type: string
required: true
app-version:
type: string
required: true
git-short-hash:
type: string
required: true
@@ -16,12 +22,13 @@ jobs:
build-web:
name: Build @affine/web
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.flavor }}
environment: ${{ inputs.build-type }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Build Core
@@ -30,11 +37,11 @@ jobs:
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
BUILD_TYPE: ${{ github.event.inputs.flavor }}
BUILD_TYPE: ${{ inputs.build-type }}
CAPTCHA_SITE_KEY: ${{ secrets.CAPTCHA_SITE_KEY }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: 'affine-web'
SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }}
SENTRY_RELEASE: ${{ inputs.app-version }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }}
@@ -49,12 +56,13 @@ jobs:
build-admin:
name: Build @affine/admin
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.flavor }}
environment: ${{ inputs.build-type }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Build Admin
@@ -63,7 +71,7 @@ jobs:
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
BUILD_TYPE: ${{ github.event.inputs.flavor }}
BUILD_TYPE: ${{ inputs.build-type }}
CAPTCHA_SITE_KEY: ${{ secrets.CAPTCHA_SITE_KEY }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: 'affine-admin'
@@ -81,12 +89,13 @@ jobs:
build-mobile:
name: Build @affine/mobile
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.flavor }}
environment: ${{ inputs.build-type }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Build Mobile
@@ -95,7 +104,7 @@ jobs:
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
BUILD_TYPE: ${{ github.event.inputs.flavor }}
BUILD_TYPE: ${{ inputs.build-type }}
CAPTCHA_SITE_KEY: ${{ secrets.CAPTCHA_SITE_KEY }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: 'affine-mobile'
@@ -113,7 +122,7 @@ jobs:
build-server-native:
name: Build Server native - ${{ matrix.targets.name }}
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.flavor }}
environment: ${{ inputs.build-type }}
strategy:
fail-fast: false
matrix:
@@ -128,8 +137,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
@@ -161,8 +171,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
@@ -202,16 +213,6 @@ jobs:
with:
name: server-dist
path: ./packages/backend/server/dist
- name: Setup env
run: |
echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
if [ -z "${{ inputs.flavor }}" ]
then
echo "RELEASE_FLAVOR=canary" >> "$GITHUB_ENV"
else
echo "RELEASE_FLAVOR=${{ inputs.flavor }}" >> "$GITHUB_ENV"
fi
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
@@ -263,8 +264,9 @@ jobs:
run: mv ./node_modules ./packages/backend/server
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Build front Dockerfile
uses: docker/build-push-action@v6
@@ -275,7 +277,7 @@ jobs:
platforms: linux/amd64,linux/arm64
provenance: true
file: .github/deployment/front/Dockerfile
tags: ghcr.io/toeverything/affine-front:${{env.RELEASE_FLAVOR}}-${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-front:${{env.RELEASE_FLAVOR}}
tags: ghcr.io/toeverything/affine-front:${{inputs.build-type}}-${{ inputs.git-short-hash }}
- name: Build graphql Dockerfile
uses: docker/build-push-action@v6
@@ -286,4 +288,4 @@ jobs:
platforms: linux/amd64,linux/arm64,linux/arm/v7
provenance: true
file: .github/deployment/node/Dockerfile
tags: ghcr.io/toeverything/affine-graphql:${{env.RELEASE_FLAVOR}}-${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-graphql:${{env.RELEASE_FLAVOR}}
tags: ghcr.io/toeverything/affine:${{inputs.build-type}}-${{ inputs.git-short-hash }}

View File

@@ -1,25 +0,0 @@
name: Build Selfhost Image
on:
workflow_dispatch:
inputs:
flavor:
description: 'Select distribution to build'
type: choice
default: canary
options:
- canary
- beta
- stable
permissions:
contents: 'write'
id-token: 'write'
packages: 'write'
jobs:
build-image:
name: Build Image
uses: ./.github/workflows/build-images.yml
with:
flavor: ${{ github.event.inputs.flavor }}

View File

@@ -11,6 +11,7 @@ on:
paths-ignore:
- README.md
pull_request:
merge_group:
env:
DEBUG: napi:*
@@ -27,26 +28,11 @@ concurrency:
cancel-in-progress: true
jobs:
optimize_ci:
name: Optimize CI
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check_skip.outputs.skip }}
steps:
- uses: actions/checkout@v4
- name: Graphite CI Optimizer
uses: withgraphite/graphite-ci-action@main
id: check_skip
with:
graphite_token: ${{ secrets.GRAPHITE_CI_OPTIMIZER_TOKEN }}
analyze:
name: Analyze
runs-on: ubuntu-latest
env:
NODE_OPTIONS: --max-old-space-size=14384
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
permissions:
actions: read
contents: read
@@ -80,9 +66,6 @@ jobs:
lint:
name: Lint
runs-on: ubuntu-24.04-arm
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Run oxlint
@@ -108,8 +91,6 @@ jobs:
typecheck:
name: Typecheck
runs-on: ubuntu-24.04-arm
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
NODE_OPTIONS: --max-old-space-size=14384
steps:
@@ -137,8 +118,6 @@ jobs:
lint-rust:
name: Lint Rust
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-rust
@@ -159,9 +138,7 @@ jobs:
name: Check Git Status
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-server-native
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
@@ -197,8 +174,6 @@ jobs:
check-yarn-binary:
name: Check yarn binary
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Run check
@@ -209,8 +184,6 @@ jobs:
e2e-blocksuite-test:
name: E2E BlockSuite Test
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
matrix:
@@ -242,8 +215,6 @@ jobs:
e2e-blocksuite-cross-browser-test:
name: E2E BlockSuite Cross Browser Test
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
matrix:
@@ -278,8 +249,6 @@ jobs:
e2e-test:
name: E2E Test
runs-on: ubuntu-24.04-arm
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
DISTRIBUTION: web
IN_CI_TEST: true
@@ -312,8 +281,6 @@ jobs:
e2e-mobile-test:
name: E2E Mobile Test
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
DISTRIBUTION: mobile
IN_CI_TEST: true
@@ -345,9 +312,7 @@ jobs:
name: Unit Test
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-native
if: needs.optimize_ci.outputs.skip == 'false'
env:
DISTRIBUTION: web
strategy:
@@ -384,8 +349,6 @@ jobs:
build-native:
name: Build AFFiNE native (${{ matrix.spec.target }})
runs-on: ${{ matrix.spec.os }}
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
CARGO_PROFILE_RELEASE_DEBUG: '1'
strategy:
@@ -428,8 +391,6 @@ jobs:
build-windows-native:
name: Build AFFiNE native (${{ matrix.spec.target }})
runs-on: ${{ matrix.spec.os }}
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
CARGO_PROFILE_RELEASE_DEBUG: '1'
strategy:
@@ -477,8 +438,6 @@ jobs:
build-server-native:
name: Build Server native
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
CARGO_PROFILE_RELEASE_DEBUG: '1'
steps:
@@ -504,8 +463,6 @@ jobs:
build-electron-renderer:
name: Build @affine/electron renderer
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
@@ -531,9 +488,7 @@ jobs:
name: Native Unit Test
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-native
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
@@ -553,9 +508,7 @@ jobs:
name: Server Test
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-server-native
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
matrix:
@@ -587,7 +540,7 @@ jobs:
- 1025:1025
- 8025:8025
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:
@@ -628,9 +581,7 @@ jobs:
name: Server Test with Elasticsearch
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-server-native
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
env:
@@ -713,9 +664,7 @@ jobs:
name: Server E2E Test
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-server-native
if: needs.optimize_ci.outputs.skip == 'false'
env:
NODE_ENV: test
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
@@ -737,7 +686,7 @@ jobs:
ports:
- 6379:6379
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:
@@ -773,9 +722,6 @@ jobs:
miri:
name: miri code check
runs-on: ubuntu-latest
needs:
- optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
RUST_BACKTRACE: full
CARGO_TERM_COLOR: always
@@ -789,7 +735,9 @@ jobs:
toolchain: nightly
components: miri
- name: Install latest nextest release
uses: taiki-e/install-action@nextest
uses: taiki-e/install-action@v2
with:
tool: nextest@0.9.98
- name: Miri Code Check
continue-on-error: true
@@ -799,9 +747,6 @@ jobs:
loom:
name: loom thread test
runs-on: ubuntu-latest
needs:
- optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
RUSTFLAGS: --cfg loom
RUST_BACKTRACE: full
@@ -814,7 +759,9 @@ jobs:
with:
toolchain: stable
- name: Install latest nextest release
uses: taiki-e/install-action@nextest
uses: taiki-e/install-action@v2
with:
tool: nextest@0.9.98
- name: Loom Thread Test
run: |
@@ -823,9 +770,6 @@ jobs:
fuzzing:
name: fuzzing
runs-on: ubuntu-latest
needs:
- optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
CARGO_TERM_COLOR: always
steps:
@@ -872,9 +816,6 @@ jobs:
- { target: 'aarch64-apple-darwin', os: 'macos-latest' }
- { target: 'x86_64-pc-windows-msvc', os: 'windows-latest' }
- { target: 'aarch64-pc-windows-msvc', os: 'windows-11-arm' }
needs:
- optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
@@ -908,8 +849,6 @@ jobs:
rust-test:
name: Run native tests
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
env:
CARGO_TERM_COLOR: always
steps:
@@ -921,7 +860,9 @@ jobs:
no-build: 'true'
- name: Install latest nextest release
uses: taiki-e/install-action@nextest
uses: taiki-e/install-action@v2
with:
tool: nextest@0.9.98
- name: Run tests
run: cargo nextest run --workspace --exclude affine_server_native --features use-as-lib --release --no-fail-fast
@@ -930,9 +871,7 @@ jobs:
name: Server Copilot Api Test
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-server-native
if: needs.optimize_ci.outputs.skip == 'false'
env:
NODE_ENV: test
DISTRIBUTION: web
@@ -960,7 +899,7 @@ jobs:
- 1025:1025
- 8025:8025
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:
@@ -1054,7 +993,7 @@ jobs:
ports:
- 6379:6379
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:
@@ -1114,10 +1053,8 @@ jobs:
name: ${{ matrix.tests.name }}
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-server-native
- build-native
if: needs.optimize_ci.outputs.skip == 'false'
env:
DISTRIBUTION: web
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
@@ -1176,7 +1113,7 @@ jobs:
- 1025:1025
- 8025:8025
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:
@@ -1221,10 +1158,8 @@ jobs:
name: Desktop Test (${{ matrix.spec.os }}, ${{ matrix.spec.platform }}, ${{ matrix.spec.arch }}, ${{ matrix.spec.target }}, ${{ matrix.spec.test }})
runs-on: ${{ matrix.spec.os }}
needs:
- optimize_ci
- build-electron-renderer
- build-native
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
matrix:
@@ -1319,10 +1254,8 @@ jobs:
name: Desktop bundle check (${{ matrix.spec.os }}, ${{ matrix.spec.platform }}, ${{ matrix.spec.arch }}, ${{ matrix.spec.target }}, ${{ matrix.spec.test }})
runs-on: ${{ matrix.spec.os }}
needs:
- optimize_ci
- build-electron-renderer
- build-native
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
matrix:
@@ -1426,17 +1359,6 @@ jobs:
run: |
yarn affine @affine/electron node ./scripts/macos-arm64-output-check.ts
test-build-mobile-app:
uses: ./.github/workflows/release-mobile.yml
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
with:
build-type: canary
build-target: development
secrets: inherit
permissions:
id-token: 'write'
test-done:
needs:
- analyze
@@ -1467,7 +1389,6 @@ jobs:
- desktop-test
- desktop-bundle-check
- cloud-e2e-test
- test-build-mobile-app
if: always()
runs-on: ubuntu-latest
name: 3, 2, 1 Launch

View File

@@ -60,7 +60,7 @@ jobs:
- 1025:1025
- 8025:8025
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:
@@ -130,7 +130,7 @@ jobs:
ports:
- 6379:6379
indexer:
image: manticoresearch/manticore:9.3.2
image: manticoresearch/manticore:10.1.0
ports:
- 9308:9308
steps:

View File

@@ -1,32 +0,0 @@
name: Deploy Automatically
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+-canary.[0-9]+'
schedule:
- cron: '0 9 * * *'
permissions:
contents: write
pull-requests: write
actions: write
jobs:
dispatch-deploy:
runs-on: ubuntu-latest
name: Setup Deploy
steps:
- name: dispatch deploy by tag
if: ${{ github.event_name == 'push' }}
uses: benc-uk/workflow-dispatch@v1
with:
workflow: deploy.yml
inputs: '{ "flavor": "canary" }'
- name: dispatch deploy by schedule
if: ${{ github.event_name == 'schedule' }}
uses: benc-uk/workflow-dispatch@v1
with:
workflow: deploy.yml
inputs: '{ "flavor": "canary" }'
ref: canary

View File

@@ -1,189 +0,0 @@
name: Deploy
on:
workflow_dispatch:
inputs:
flavor:
description: 'Select what enverionment to deploy to'
type: choice
default: canary
options:
- canary
- beta
- stable
- internal
permissions:
contents: 'write'
id-token: 'write'
packages: 'write'
jobs:
output-prev-version:
name: Output previous version
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.flavor }}
outputs:
prev: ${{ steps.print.outputs.version }}
namespace: ${{ steps.print.outputs.namespace }}
steps:
- uses: actions/checkout@v4
- name: Auth to Cluster
uses: './.github/actions/cluster-auth'
with:
gcp-project-number: ${{ secrets.GCP_PROJECT_NUMBER }}
gcp-project-id: ${{ secrets.GCP_PROJECT_ID }}
service-account: ${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }}
cluster-name: ${{ secrets.GCP_CLUSTER_NAME }}
cluster-location: ${{ secrets.GCP_CLUSTER_LOCATION }}
- name: Output previous version
id: print
run: |
namespace=""
if [ "${{ github.event.inputs.flavor }}" = "canary" ]; then
namespace="dev"
elif [ "${{ github.event.inputs.flavor }}" = "beta" ]; then
namespace="beta"
elif [ "${{ github.event.inputs.flavor }}" = "stable" ]; then
namespace="production"
else
echo "Invalid flavor: ${{ github.event.inputs.flavor }}"
exit 1
fi
echo "Namespace set to: $namespace"
# Get the previous version from the deployment
prev_version=$(kubectl get deployment -n $namespace affine-graphql -o=jsonpath='{.spec.template.spec.containers[0].image}' | awk -F '-' '{print $3}')
echo "Previous version: $prev_version"
echo "version=$prev_version" >> $GITHUB_OUTPUT
echo "namesapce=$namespace" >> $GITHUB_OUTPUT
build-images:
name: Build Images
uses: ./.github/workflows/build-images.yml
secrets: inherit
with:
flavor: ${{ github.event.inputs.flavor }}
deploy:
name: Deploy to cluster
if: ${{ github.event_name == 'workflow_dispatch' }}
environment: ${{ github.event.inputs.flavor }}
needs:
- build-images
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
- name: Deploy to ${{ github.event.inputs.flavor }}
uses: ./.github/actions/deploy
with:
build-type: ${{ github.event.inputs.flavor }}
gcp-project-number: ${{ secrets.GCP_PROJECT_NUMBER }}
gcp-project-id: ${{ secrets.GCP_PROJECT_ID }}
service-account: ${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }}
cluster-name: ${{ secrets.GCP_CLUSTER_NAME }}
cluster-location: ${{ secrets.GCP_CLUSTER_LOCATION }}
env:
APP_VERSION: ${{ steps.version.outputs.APP_VERSION }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
CANARY_DEPLOY_HOST: ${{ secrets.CANARY_DEPLOY_HOST }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DATABASE_USERNAME: ${{ secrets.DATABASE_USERNAME }}
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
DATABASE_NAME: ${{ secrets.DATABASE_NAME }}
GCLOUD_CONNECTION_NAME: ${{ secrets.GCLOUD_CONNECTION_NAME }}
REDIS_SERVER_HOST: ${{ secrets.REDIS_SERVER_HOST }}
REDIS_SERVER_PASSWORD: ${{ secrets.REDIS_SERVER_PASSWORD }}
CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }}
APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }}
STATIC_IP_NAME: ${{ secrets.STATIC_IP_NAME }}
AFFINE_INDEXER_SEARCH_PROVIDER: ${{ secrets.AFFINE_INDEXER_SEARCH_PROVIDER }}
AFFINE_INDEXER_SEARCH_ENDPOINT: ${{ secrets.AFFINE_INDEXER_SEARCH_ENDPOINT }}
AFFINE_INDEXER_SEARCH_API_KEY: ${{ secrets.AFFINE_INDEXER_SEARCH_API_KEY }}
deploy-done:
needs:
- output-prev-version
- build-images
- deploy
if: always()
runs-on: ubuntu-latest
name: Post deploy message
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
repository: toeverything/blocksuite
path: blocksuite
fetch-depth: 0
fetch-tags: true
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
extra-flags: 'workspaces focus @affine/changelog'
electron-install: false
- name: Output deployed info
if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
id: set_info
run: |
if [ "${{ github.event.inputs.flavor }}" = "canary" ]; then
echo "deployed_url=https://affine.fail" >> $GITHUB_OUTPUT
elif [ "${{ github.event.inputs.flavor }}" = "beta" ]; then
echo "deployed_url=https://insider.affine.pro" >> $GITHUB_OUTPUT
elif [ "${{ github.event.inputs.flavor }}" = "stable" ]; then
echo "deployed_url=https://app.affine.pro" >> $GITHUB_OUTPUT
else
exit 1
fi
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Post Success event to a Slack channel
if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
run: node ./tools/changelog/index.js
env:
CHANNEL_ID: ${{ secrets.RELEASE_SLACK_CHNNEL_ID }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
DEPLOYED_URL: ${{ steps.set_info.outputs.deployed_url }}
PREV_VERSION: ${{ needs.output-prev-version.outputs.prev }}
NAMESPACE: ${{ needs.output-prev-version.outputs.namespace }}
DEPLOYMENT: 'SERVER'
FLAVOR: ${{ github.event.inputs.flavor }}
BLOCKSUITE_REPO_PATH: ${{ github.workspace }}/blocksuite
- name: Post Failed event to a Slack channel
id: failed-slack
uses: slackapi/slack-github-action@v2.1.0
if: ${{ always() && contains(needs.*.result, 'failure') }}
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.RELEASE_SLACK_CHNNEL_ID }}
text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy failed `${{ github.event.inputs.flavor }}`>"
blocks:
- type: section
text:
type: mrkdwn
text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy failed `${{ github.event.inputs.flavor }}`>"
- name: Post Cancel event to a Slack channel
id: cancel-slack
uses: slackapi/slack-github-action@v2.1.0
if: ${{ always() && contains(needs.*.result, 'cancelled') && !contains(needs.*.result, 'failure') }}
with:
token: ${{ secrets.SLACK_BOT_TOKEN }}
method: chat.postMessage
payload: |
channel: ${{ secrets.RELEASE_SLACK_CHNNEL_ID }}
text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy cancelled `${{ github.event.inputs.flavor }}`>"
blocks:
- type: section
text:
type: mrkdwn
text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Backend deploy cancelled `${{ github.event.inputs.flavor }}`>"

View File

@@ -1,66 +0,0 @@
name: Release Charts
on:
push:
branches: [canary]
paths:
- '.github/helm/**/Chart.yml'
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Checkout Helm chart repo
uses: actions/checkout@v4
with:
repository: toeverything/helm-charts
path: .helm-chart-repo
ref: gh-pages
token: ${{ secrets.HELM_RELEASER_TOKEN }}
- name: Install Helm
uses: azure/setup-helm@v4
- name: Install chart releaser
run: |
set -e
arch="$(dpkg --print-architecture)"
curl -s https://api.github.com/repos/helm/chart-releaser/releases/latest \
| yq --indent 0 --no-colors --input-format json --unwrapScalar \
".assets[] | select(.name | test("\""^chart-releaser_.+_linux_${arch}\.tar\.gz$"\"")) | .browser_download_url" \
| xargs curl -SsL \
| tar zxf - -C /usr/local/bin
- name: Package charts
working-directory: .helm-chart-repo
run: |
mkdir -p .cr-index
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm dependencies build ../.github/helm/affine
helm dependencies build ../.github/helm/affine-cloud
cr package ../.github/helm/affine
cr package ../.github/helm/affine-cloud
- name: Publish charts
working-directory: .helm-chart-repo
run: |
set -ex
git config --local user.name "$GITHUB_ACTOR"
git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
owner=$(cut -d '/' -f 1 <<< '${{ github.repository }}')
repo=helm-charts
git_hash=$(git rev-parse HEAD)
cr upload --commit "$git_hash" \
--git-repo "$repo" --owner "$owner" \
--token '${{ secrets.HELM_RELEASER_TOKEN }}' \
--skip-existing
cr index --git-repo "$repo" --owner "$owner" \
--token '${{ secrets.HELM_RELEASER_TOKEN }}' \
--index-path .cr-index --push

View File

@@ -1,19 +0,0 @@
name: Label Checker
on:
pull_request:
types:
- opened
- labeled
- unlabeled
branches:
- canary
jobs:
check_labels:
name: PR should not have a blocked label
runs-on: ubuntu-latest
steps:
- uses: docker://agilepathway/pull-request-label-checker:latest
with:
none_of: blocked
repo_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,12 +0,0 @@
name: Pull request auto assign
# on: pull_request
on:
pull_request:
types: [opened, ready_for_review]
jobs:
add-reviews:
runs-on: ubuntu-latest
steps:
- uses: kentaro-m/auto-assign-action@v2.0.0

View File

@@ -1,38 +0,0 @@
name: Release Desktop/Mobile Automatically
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+-canary.[0-9]+'
schedule:
- cron: '0 9 * * *'
permissions:
contents: write
pull-requests: write
actions: write
jobs:
dispatch-release-desktop:
runs-on: ubuntu-latest
name: Setup Release Desktop
steps:
- name: dispatch desktop release by tag
if: ${{ github.event_name == 'push' }}
uses: benc-uk/workflow-dispatch@v1
with:
workflow: release-desktop.yml
inputs: '{ "build-type": "canary", "is-draft": false, "is-pre-release": true }'
- name: dispatch desktop release by schedule
if: ${{ github.event_name == 'schedule' }}
uses: benc-uk/workflow-dispatch@v1
with:
workflow: release-desktop.yml
inputs: '{ "build-type": "canary", "is-draft": false, "is-pre-release": true }'
ref: canary
- name: dispatch desktop release by tag
uses: benc-uk/workflow-dispatch@v1
with:
workflow: release-mobile.yml
inputs: '{ "build-type": "canary", "build-target": "distribution" }'

66
.github/workflows/release-cloud.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: Release Cloud
on:
workflow_call:
inputs:
build-type:
required: true
type: string
app-version:
required: true
type: string
git-short-hash:
required: true
type: string
permissions:
contents: 'write'
id-token: 'write'
packages: 'write'
jobs:
build-images:
name: Build Images
uses: ./.github/workflows/build-images.yml
secrets: inherit
with:
build-type: ${{ inputs.build-type }}
app-version: ${{ inputs.app-version }}
git-short-hash: ${{ inputs.git-short-hash }}
deploy:
name: Deploy to cluster
environment: ${{ inputs.build-type }}
needs:
- build-images
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to ${{ inputs.build-type }}
uses: ./.github/actions/deploy
with:
gcp-project-number: ${{ secrets.GCP_PROJECT_NUMBER }}
gcp-project-id: ${{ secrets.GCP_PROJECT_ID }}
service-account: ${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }}
cluster-name: ${{ secrets.GCP_CLUSTER_NAME }}
cluster-location: ${{ secrets.GCP_CLUSTER_LOCATION }}
env:
BUILD_TYPE: ${{ inputs.build-type }}
APP_VERSION: ${{ inputs.app-version }}
GIT_SHORT_HASH: ${{ inputs.git-short-hash }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
CANARY_DEPLOY_HOST: ${{ secrets.CANARY_DEPLOY_HOST }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DATABASE_USERNAME: ${{ secrets.DATABASE_USERNAME }}
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
DATABASE_NAME: ${{ secrets.DATABASE_NAME }}
GCLOUD_CONNECTION_NAME: ${{ secrets.GCLOUD_CONNECTION_NAME }}
REDIS_SERVER_HOST: ${{ secrets.REDIS_SERVER_HOST }}
REDIS_SERVER_PASSWORD: ${{ secrets.REDIS_SERVER_PASSWORD }}
CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }}
APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }}
STATIC_IP_NAME: ${{ secrets.STATIC_IP_NAME }}
AFFINE_INDEXER_SEARCH_PROVIDER: ${{ secrets.AFFINE_INDEXER_SEARCH_PROVIDER }}
AFFINE_INDEXER_SEARCH_ENDPOINT: ${{ secrets.AFFINE_INDEXER_SEARCH_ENDPOINT }}
AFFINE_INDEXER_SEARCH_API_KEY: ${{ secrets.AFFINE_INDEXER_SEARCH_API_KEY }}

View File

@@ -1,27 +1,17 @@
name: Release Desktop App
name: Release Desktop
on:
workflow_dispatch:
workflow_call:
inputs:
build-type:
description: 'Build Type'
type: choice
required: true
default: canary
options:
- canary
- beta
- stable
is-draft:
description: 'Draft Release?'
type: boolean
type: string
app-version:
required: true
default: true
is-pre-release:
description: 'Pre Release? (labeled as "PreRelease")'
type: boolean
type: string
git-short-hash:
required: true
default: true
type: string
permissions:
actions: write
@@ -31,7 +21,8 @@ permissions:
attestations: write
env:
BUILD_TYPE: ${{ github.event.inputs.build-type }}
BUILD_TYPE: ${{ inputs.build-type }}
RELEASE_VERSION: ${{ inputs.app-version }}
DEBUG: 'affine:*,napi:*'
APP_NAME: affine
MACOSX_DEPLOYMENT_TARGET: '10.13'
@@ -39,14 +30,13 @@ env:
jobs:
before-make:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.build-type }}
outputs:
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
environment: ${{ inputs.build-type }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Setup @sentry/cli
@@ -58,14 +48,14 @@ jobs:
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }}
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
SENTRY_RELEASE: ${{ inputs.app-version }}
RELEASE_VERSION: ${{ inputs.app-version }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
- name: Upload web artifact
uses: actions/upload-artifact@v4
with:
name: web
name: desktop-web
path: packages/frontend/apps/electron/resources/web-static
make-distribution:
@@ -87,7 +77,7 @@ jobs:
target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.spec.runner }}
needs: before-make
environment: ${{ github.event.inputs.build-type }}
environment: ${{ inputs.build-type }}
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
@@ -97,13 +87,14 @@ jobs:
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ needs.before-make.outputs.RELEASE_VERSION }}
SENTRY_RELEASE: ${{ inputs.app-version }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
timeout-minutes: 10
uses: ./.github/actions/setup-node
@@ -119,7 +110,7 @@ jobs:
package: '@affine/native'
- uses: actions/download-artifact@v4
with:
name: web
name: desktop-web
path: packages/frontend/apps/electron/resources/web-static
- name: Build Desktop Layers
@@ -165,31 +156,31 @@ jobs:
if: ${{ matrix.spec.platform == 'darwin' }}
run: |
mkdir -p builds
mv packages/frontend/apps/electron/out/*/make/*.dmg ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg
mv packages/frontend/apps/electron/out/*/make/zip/darwin/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip
mv packages/frontend/apps/electron/out/*/make/*.dmg ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg
mv packages/frontend/apps/electron/out/*/make/zip/darwin/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip
- name: Save artifacts (linux)
if: ${{ matrix.spec.platform == 'linux' }}
run: |
mkdir -p builds
mv packages/frontend/apps/electron/out/*/make/zip/linux/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.zip
mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.appimage
mv packages/frontend/apps/electron/out/*/make/deb/${{ matrix.spec.arch }}/*.deb ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.deb
mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak
mv packages/frontend/apps/electron/out/*/make/zip/linux/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.zip
mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.appimage
mv packages/frontend/apps/electron/out/*/make/deb/${{ matrix.spec.arch }}/*.deb ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.deb
mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak
- uses: actions/attest-build-provenance@v2
if: ${{ matrix.spec.platform == 'darwin' }}
with:
subject-path: |
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg
- uses: actions/attest-build-provenance@v2
if: ${{ matrix.spec.platform == 'linux' }}
with:
subject-path: |
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.zip
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.appimage
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.deb
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.zip
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.appimage
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-x64.deb
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
@@ -197,7 +188,7 @@ jobs:
path: builds
package-distribution-windows:
environment: ${{ github.event.inputs.build-type }}
environment: ${{ inputs.build-type }}
strategy:
fail-fast: false
matrix:
@@ -221,13 +212,14 @@ jobs:
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ needs.before-make.outputs.RELEASE_VERSION }}
SENTRY_RELEASE: ${{ inputs.app-version }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
timeout-minutes: 10
uses: ./.github/actions/setup-node
@@ -242,7 +234,7 @@ jobs:
package: '@affine/native'
- uses: actions/download-artifact@v4
with:
name: web
name: desktop-web
path: packages/frontend/apps/electron/resources/web-static
- name: Build Desktop Layers
@@ -314,8 +306,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
timeout-minutes: 10
uses: ./.github/actions/setup-node
@@ -399,16 +392,16 @@ jobs:
- name: Save artifacts
run: |
mkdir -p builds
mv packages/frontend/apps/electron/out/*/make/zip/win32/${{ matrix.spec.arch }}/AFFiNE*-win32-${{ matrix.spec.arch }}-*.zip ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip
mv packages/frontend/apps/electron/out/*/make/squirrel.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe
mv packages/frontend/apps/electron/out/*/make/nsis.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe
mv packages/frontend/apps/electron/out/*/make/zip/win32/${{ matrix.spec.arch }}/AFFiNE*-win32-${{ matrix.spec.arch }}-*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip
mv packages/frontend/apps/electron/out/*/make/squirrel.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe
mv packages/frontend/apps/electron/out/*/make/nsis.windows/${{ matrix.spec.arch }}/*.exe ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe
- uses: actions/attest-build-provenance@v2
with:
subject-path: |
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe
./builds/affine-${{ needs.before-make.outputs.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.zip
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.exe
./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-windows-${{ matrix.spec.arch }}.nsis.exe
- name: Upload Artifact
uses: actions/upload-artifact@v4
@@ -424,7 +417,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: web
name: desktop-web
path: web-static
- name: Zip web-static
run: zip -r web-static.zip web-static
@@ -465,32 +458,14 @@ jobs:
run: |
node ./scripts/generate-release-yml.mjs
env:
RELEASE_VERSION: ${{ needs.before-make.outputs.RELEASE_VERSION }}
- name: Create Release Draft
if: ${{ github.ref_type == 'tag' }}
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: ${{ needs.before-make.outputs.RELEASE_VERSION }}
body: ''
draft: ${{ github.event.inputs.is-draft }}
prerelease: ${{ github.event.inputs.is-pre-release }}
files: |
./release/*
./release/.env.example
- name: Create Nightly Release Draft
if: ${{ github.ref_type == 'branch' }}
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
with:
# Temporarily, treat release from branch as nightly release, artifact saved to AFFiNE-Releases.
# Need to improve internal build and nightly release logic.
repository: 'toeverything/AFFiNE-Releases'
name: ${{ needs.before-make.outputs.RELEASE_VERSION }}
tag_name: ${{ needs.before-make.outputs.RELEASE_VERSION }}
body: ''
draft: false
prerelease: true
name: ${{ env.RELEASE_VERSION }}
draft: ${{ inputs.build-type == 'stable' }}
prerelease: ${{ inputs.build-type != 'stable' }}
tag_name: ${{ env.RELEASE_VERSION}}
files: |
./release/*
./release/.env.example

View File

@@ -1,68 +1,33 @@
name: Release Mobile App
name: Release Mobile
on:
workflow_call:
inputs:
build-target:
description: 'Build Target'
app-version:
type: string
required: true
git-short-hash:
type: string
required: true
build-type:
description: 'Build Type'
type: string
required: true
workflow_dispatch:
inputs:
build-target:
description: 'Build Target'
type: choice
required: true
default: distribution
options:
- development
- distribution
build-type:
description: 'Build Type'
type: choice
required: true
default: canary
options:
- canary
- beta
- stable
env:
BUILD_TYPE: ${{ inputs.build-type || github.event.inputs.build-type }}
BUILD_TARGET: ${{ inputs.build-target || github.event.inputs.build-target }}
BUILD_TYPE: ${{ inputs.build-type }}
DEBUG: napi:*
KEYCHAIN_NAME: ${{ github.workspace }}/signing_temp
jobs:
output-env:
runs-on: ubuntu-latest
outputs:
ENVIRONMENT: ${{ steps.env.outputs.ENVIRONMENT }}
steps:
- name: Output Environment
id: env
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "ENVIRONMENT=${{ github.event.inputs.build-type }}" >> $GITHUB_OUTPUT
else
echo "ENVIRONMENT=" >> $GITHUB_OUTPUT
fi
build-ios-web:
needs:
- output-env
runs-on: ubuntu-24.04-arm
environment: ${{ needs.output-env.outputs.ENVIRONMENT }}
outputs:
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
runs-on: ubuntu-latest
environment: ${{ inputs.build-type }}
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Setup @sentry/cli
@@ -76,8 +41,8 @@ jobs:
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }}
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
SENTRY_RELEASE: ${{ inputs.app-version }}
RELEASE_VERSION: ${{ inputs.app-version }}
- name: Upload ios artifact
uses: actions/upload-artifact@v4
with:
@@ -85,17 +50,13 @@ jobs:
path: packages/frontend/apps/ios/dist
build-android-web:
runs-on: ubuntu-24.04-arm
needs:
- output-env
environment: ${{ needs.output-env.outputs.ENVIRONMENT }}
outputs:
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Setup @sentry/cli
@@ -109,8 +70,7 @@ jobs:
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ steps.version.outputs.APP_VERSION }}
RELEASE_VERSION: ${{ steps.version.outputs.APP_VERSION }}
SENTRY_RELEASE: ${{ inputs.app-version }}
- name: Upload android artifact
uses: actions/upload-artifact@v4
with:
@@ -123,6 +83,13 @@ jobs:
- build-ios-web
steps:
- uses: actions/checkout@v4
- name: Setup Version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: 'Update Code Sign Identity'
shell: bash
run: ./packages/frontend/apps/ios/update_code_sign_identity.sh
- name: Download mobile artifact
uses: actions/download-artifact@v4
with:
@@ -165,6 +132,7 @@ jobs:
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
fastlane beta
env:
BUILD_TARGET: distribution
BUILD_PROVISION_PROFILE: ${{ secrets.BUILD_PROVISION_PROFILE }}
PP_PATH: ${{ runner.temp }}/build_pp.mobileprovision
APPLE_STORE_CONNECT_API_KEY_ID: ${{ secrets.APPLE_STORE_CONNECT_API_KEY_ID }}
@@ -180,8 +148,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup Version
id: version
uses: ./.github/actions/setup-version
with:
app-version: ${{ inputs.app-version }}
- name: Download mobile artifact
uses: actions/download-artifact@v4
with:
@@ -214,7 +183,6 @@ jobs:
- name: Auth gcloud
id: auth
uses: google-github-actions/auth@v2
if: ${{ env.BUILD_TARGET == 'distribution' }}
with:
workload_identity_provider: 'projects/${{ secrets.GCP_PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github-actions/providers/github-actions-helm-deploy'
service_account: '${{ secrets.GCP_HELM_DEPLOY_SERVICE_ACCOUNT }}'
@@ -228,7 +196,6 @@ jobs:
cache: 'gradle'
- name: Auto increment version code
id: bump
if: ${{ env.BUILD_TARGET == 'distribution' }}
run: yarn affine @affine/playstore-auto-bump bump
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ steps.auth.outputs.credentials_file_path }}
@@ -240,14 +207,13 @@ jobs:
AFFINE_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.AFFINE_ANDROID_KEYSTORE_PASSWORD }}
AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD: ${{ secrets.AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD }}
AFFINE_ANDROID_SIGN_KEYSTORE: ${{ secrets.AFFINE_ANDROID_SIGN_KEYSTORE }}
VERSION_NAME: ${{ steps.version.outputs.APP_VERSION }}
VERSION_NAME: ${{ inputs.app-version }}
- name: Upload to Google Play
uses: r0adkll/upload-google-play@v1
if: ${{ env.BUILD_TARGET == 'distribution' }}
with:
serviceAccountJson: ${{ steps.auth.outputs.credentials_file_path }}
packageName: app.affine.pro
releaseName: ${{ steps.version.outputs.APP_VERSION }}
releaseName: ${{ inputs.app-version }}
releaseFiles: packages/frontend/apps/android/App/app/build/outputs/bundle/${{ env.BUILD_TYPE }}Release/app-${{ env.BUILD_TYPE }}-release-signed.aab
track: internal
status: draft

119
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,119 @@
name: Release
on:
schedule:
- cron: '0 9 * * *'
workflow_dispatch:
inputs:
web:
description: 'Release Web?'
required: true
type: boolean
default: false
desktop:
description: 'Release Desktop?'
required: true
type: boolean
default: false
mobile:
description: 'Release Mobile?'
required: true
type: boolean
default: false
permissions:
contents: write
pull-requests: write
actions: write
id-token: write
packages: write
security-events: write
attestations: write
jobs:
prepare:
name: Prepare
runs-on: ubuntu-latest
outputs:
APP_VERSION: ${{ steps.prepare.outputs.APP_VERSION }}
GIT_SHORT_HASH: ${{ steps.prepare.outputs.GIT_SHORT_HASH }}
BUILD_TYPE: ${{ steps.prepare.outputs.BUILD_TYPE }}
steps:
- uses: actions/checkout@v4
- name: Prepare Release
id: prepare
uses: ./.github/actions/prepare-release
cloud:
name: Release Cloud
if: ${{ inputs.web || github.event_name != 'workflow_dispatch' }}
needs:
- prepare
uses: ./.github/workflows/release-cloud.yml
secrets: inherit
with:
build-type: ${{ needs.prepare.outputs.BUILD_TYPE }}
app-version: ${{ needs.prepare.outputs.APP_VERSION }}
git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }}
image:
name: Release Docker Image
runs-on: ubuntu-latest
needs:
- prepare
- cloud
steps:
- uses: trstringer/manual-approval@v1
if: ${{ needs.prepare.outputs.BUILD_TYPE == 'stable' }}
name: Wait for approval
with:
secret: ${{ secrets.GITHUB_TOKEN }}
approvers: forehalo,fengmk2
fail-on-denial: true
issue-title: Please confirm to release docker image
issue-body: |
Env: ${{ needs.prepare.outputs.BUILD_TYPE }}
Candidate: ghcr.io/toeverything/affine:${{ needs.prepare.outputs.BUILD_TYPE }}-${{ needs.prepare.outputs.GIT_SHORT_HASH }}
Tag: ghcr.io/toeverything/affine:${{ needs.prepare.outputs.BUILD_TYPE }}
> comment with "approve", "approved", "lgtm", "yes" to approve
> comment with "deny", "deny", "no" to deny
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
logout: false
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Tag Image
run: |
docker buildx imagetools create --tag ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}} ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}}-${{needs.prepare.outputs.GIT_SHORT_HASH}}
docker buildx imagetools create --tag ghcr.io/toeverything/affine:${{needs.prepare.outputs.APP_VERSION}} ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}}-${{needs.prepare.outputs.GIT_SHORT_HASH}}
desktop:
name: Release Desktop
if: ${{ inputs.desktop || github.event_name != 'workflow_dispatch' }}
needs:
- prepare
uses: ./.github/workflows/release-desktop.yml
secrets: inherit
with:
build-type: ${{ needs.prepare.outputs.BUILD_TYPE }}
app-version: ${{ needs.prepare.outputs.APP_VERSION }}
git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }}
mobile:
name: Release Mobile
if: ${{ inputs.mobile }}
needs:
- prepare
uses: ./.github/workflows/release-mobile.yml
secrets: inherit
with:
build-type: ${{ needs.prepare.outputs.BUILD_TYPE }}
app-version: ${{ needs.prepare.outputs.APP_VERSION }}
git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }}

332
Cargo.lock generated
View File

@@ -77,8 +77,10 @@ version = "0.0.0"
dependencies = [
"block2",
"core-foundation",
"coreaudio-rs",
"coreaudio-rs 0.12.1",
"cpal",
"criterion2",
"crossbeam-channel",
"dispatch2",
"libc",
"napi",
@@ -91,6 +93,8 @@ dependencies = [
"symphonia",
"thiserror 2.0.12",
"uuid",
"windows 0.61.1",
"windows-core 0.61.2",
]
[[package]]
@@ -213,6 +217,28 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "alsa"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43"
dependencies = [
"alsa-sys",
"bitflags 2.9.1",
"cfg-if",
"libc",
]
[[package]]
name = "alsa-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527"
dependencies = [
"libc",
"pkg-config",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
@@ -695,9 +721,17 @@ version = "1.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
dependencies = [
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cexpr"
version = "0.6.0"
@@ -853,6 +887,16 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes",
"memchr",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -979,6 +1023,17 @@ dependencies = [
"libm",
]
[[package]]
name = "coreaudio-rs"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace"
dependencies = [
"bitflags 1.3.2",
"core-foundation-sys",
"coreaudio-sys",
]
[[package]]
name = "coreaudio-rs"
version = "0.12.1"
@@ -999,6 +1054,29 @@ dependencies = [
"bindgen",
]
[[package]]
name = "cpal"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779"
dependencies = [
"alsa",
"core-foundation-sys",
"coreaudio-rs 0.11.3",
"dasp_sample",
"jni",
"js-sys",
"libc",
"mach2",
"ndk",
"ndk-context",
"oboe",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows 0.54.0",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
@@ -1085,6 +1163,15 @@ dependencies = [
"walkdir",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
@@ -1165,6 +1252,12 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "dasp_sample"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
[[package]]
name = "der"
version = "0.7.10"
@@ -1820,7 +1913,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
"windows-core 0.61.2",
"windows-core 0.57.0",
]
[[package]]
@@ -2082,6 +2175,38 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e"
[[package]]
name = "jni"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
dependencies = [
"cesu8",
"cfg-if",
"combine",
"jni-sys",
"log",
"thiserror 1.0.69",
"walkdir",
"windows-sys 0.45.0",
]
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [
"getrandom 0.3.3",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.77"
@@ -2159,7 +2284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.52.6",
"windows-targets 0.48.5",
]
[[package]]
@@ -2264,6 +2389,15 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "mach2"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
dependencies = [
"libc",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
@@ -2370,9 +2504,9 @@ dependencies = [
[[package]]
name = "napi"
version = "3.0.0-beta.3"
version = "3.0.0-beta.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a5c343e6e1fb57bf3ea3386638c4affb394ee932708128840a56aaac3d6a8ab"
checksum = "c502f122fc89e92c6222810b3144411c6f945da5aa3b713ddfad3bdcae7c9bb4"
dependencies = [
"anyhow",
"bitflags 2.9.1",
@@ -2380,21 +2514,23 @@ dependencies = [
"ctor",
"napi-build",
"napi-sys",
"nohash-hasher",
"rustc-hash 2.1.1",
"serde",
"tokio",
]
[[package]]
name = "napi-build"
version = "2.2.0"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03acbfa4f156a32188bfa09b86dc11a431b5725253fc1fc6f6df5bed273382c4"
checksum = "44e0e3177307063d3e7e55b7dd7b648cca9d7f46daa35422c0d98cc2bf48c2c1"
[[package]]
name = "napi-derive"
version = "3.0.0-beta.3"
version = "3.0.0-beta.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d23065ee795a4b1a8755fdf4a39c2a229679f01f923a8feea33f045d6d96cb"
checksum = "fcf1e732a67e934b069d6d527251d6288753a36840572abe132a7aed9e77f0bc"
dependencies = [
"convert_case 0.8.0",
"ctor",
@@ -2406,9 +2542,9 @@ dependencies = [
[[package]]
name = "napi-derive-backend"
version = "2.0.0-beta.3"
version = "2.0.0-beta.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "348aaac2c51b5d11cf90cf7670b470c7f4d1607d15c338efd4d3db361003e4f5"
checksum = "462b775ba74791c98989fadc46c4bb2ec53016427be4d420d31c4bbaab34b308"
dependencies = [
"convert_case 0.8.0",
"proc-macro2",
@@ -2419,13 +2555,42 @@ dependencies = [
[[package]]
name = "napi-sys"
version = "3.0.0-alpha.2"
version = "3.0.0-alpha.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b443b980b2258dbaa31b99115e74da6c0866e537278309d566b4672a2f8df516"
checksum = "c4401c63f866b42d673a8b213d5662c84a0701b0f6c3acff7e2b9fc439f1675d"
dependencies = [
"libloading",
]
[[package]]
name = "ndk"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7"
dependencies = [
"bitflags 2.9.1",
"jni-sys",
"log",
"ndk-sys",
"num_enum",
"thiserror 1.0.69",
]
[[package]]
name = "ndk-context"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
[[package]]
name = "ndk-sys"
version = "0.5.0+25.2.9519653"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691"
dependencies = [
"jni-sys",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
@@ -2444,6 +2609,12 @@ dependencies = [
"libc",
]
[[package]]
name = "nohash-hasher"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "nom"
version = "7.1.3"
@@ -2510,6 +2681,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "num-integer"
version = "0.1.46"
@@ -2628,6 +2810,29 @@ dependencies = [
"memchr",
]
[[package]]
name = "oboe"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb"
dependencies = [
"jni",
"ndk",
"ndk-context",
"num-derive",
"num-traits",
"oboe-sys",
]
[[package]]
name = "oboe-sys"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d"
dependencies = [
"cc",
]
[[package]]
name = "once_cell"
version = "1.21.3"
@@ -5003,6 +5208,19 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
@@ -5116,7 +5334,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.48.0",
]
[[package]]
@@ -5125,6 +5343,16 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
dependencies = [
"windows-core 0.54.0",
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.57.0"
@@ -5157,6 +5385,16 @@ dependencies = [
"windows-core 0.61.2",
]
[[package]]
name = "windows-core"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
dependencies = [
"windows-result 0.1.2",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.57.0"
@@ -5280,6 +5518,15 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@@ -5307,6 +5554,21 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
@@ -5347,6 +5609,12 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
@@ -5359,6 +5627,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@@ -5371,6 +5645,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@@ -5389,6 +5669,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@@ -5401,6 +5687,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@@ -5413,6 +5705,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@@ -5425,6 +5723,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"

View File

@@ -28,12 +28,14 @@ base64-simd = "0.8"
bitvec = "1.0"
block2 = "0.6"
byteorder = "1.5"
cpal = "0.15"
chrono = "0.4"
clap = { version = "4.4", features = ["derive"] }
core-foundation = "0.10"
coreaudio-rs = "0.12"
criterion = { version = "0.5", features = ["html_reports"] }
criterion2 = { version = "3", default-features = false }
crossbeam-channel = "0.5"
dispatch2 = "0.3"
docx-parser = { git = "https://github.com/toeverything/docx-parser" }
dotenvy = "0.15"
@@ -97,6 +99,19 @@ uniffi = "0.29"
url = { version = "2.5" }
uuid = "1.8"
v_htmlescape = "0.15"
windows = { version = "0.61", features = [
"Win32_Devices_FunctionDiscovery",
"Win32_UI_Shell_PropertiesSystem",
"Win32_Media_Audio",
"Win32_System_Variant",
"Win32_System_Com_StructuredStorage",
"Win32_System_Threading",
"Win32_System_ProcessStatus",
"Win32_Foundation",
"Win32_System_Com",
"Win32_System_Diagnostics_ToolHelp",
] }
windows-core = { version = "0.61" }
y-octo = { path = "./packages/common/y-octo/core" }
y-sync = { version = "0.4" }
yrs = "0.23.0"

View File

@@ -292,7 +292,7 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0",
"version": "0.22.4",
"devDependencies": {
"@vanilla-extract/vite-plugin": "^5.0.0",
"msw": "^2.8.4",

View File

@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -1,4 +1,5 @@
import {
canEmbedAsEmbedBlock,
canEmbedAsIframe,
EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE,
EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE,
@@ -149,13 +150,10 @@ const builtinToolbarConfig = {
if (!model) return true;
const url = model.props.url;
// check if the url can be embedded as iframe block or other embed blocks
const options = ctx.std
.get(EmbedOptionProvider)
.getEmbedBlockOptions(url);
return (
!canEmbedAsIframe(ctx.std, url) && options?.viewType !== 'embed'
!canEmbedAsIframe(ctx.std, url) &&
!canEmbedAsEmbedBlock(ctx.std, url)
);
},
run(ctx) {
@@ -169,15 +167,8 @@ const builtinToolbarConfig = {
let blockId: string | undefined;
// first try to embed as iframe block
if (canEmbedAsIframe(ctx.std, url)) {
const embedIframeService = ctx.std.get(EmbedIframeService);
blockId = embedIframeService.addEmbedIframeBlock(
{ url, caption, title, description },
parent.id,
index
);
} else {
// first try to embed as a custom embed block
if (canEmbedAsEmbedBlock(ctx.std, url)) {
const options = ctx.std
.get(EmbedOptionProvider)
.getEmbedBlockOptions(url);
@@ -202,6 +193,13 @@ const builtinToolbarConfig = {
parent,
index
);
} else if (canEmbedAsIframe(ctx.std, url)) {
const embedIframeService = ctx.std.get(EmbedIframeService);
blockId = embedIframeService.addEmbedIframeBlock(
{ url, caption, title, description },
parent.id,
index
);
}
if (!blockId) return;
@@ -379,27 +377,8 @@ const builtinSurfaceToolbarConfig = {
let newId: string | undefined;
// first try to embed as iframe block
if (canEmbedAsIframe(ctx.std, url)) {
const embedIframeService = ctx.std.get(EmbedIframeService);
const config = embedIframeService.getConfig(url);
if (!config) {
return;
}
const bound = Bound.deserialize(xywh);
const options = config.options;
const { widthInSurface, heightInSurface } = options ?? {};
bound.w = widthInSurface ?? EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE;
bound.h =
heightInSurface ?? EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE;
newId = ctx.store.addBlock(
'affine:embed-iframe',
{ url, caption, title, description, xywh: bound.serialize() },
parent
);
} else {
// first try to embed as a custom embed block
if (canEmbedAsEmbedBlock(ctx.std, url)) {
const options = ctx.std
.get(EmbedOptionProvider)
.getEmbedBlockOptions(url);
@@ -429,8 +408,29 @@ const builtinSurfaceToolbarConfig = {
},
parent
);
} else if (canEmbedAsIframe(ctx.std, url)) {
const embedIframeService = ctx.std.get(EmbedIframeService);
const config = embedIframeService.getConfig(url);
if (!config) {
return;
}
const bound = Bound.deserialize(xywh);
const options = config.options;
const { widthInSurface, heightInSurface } = options ?? {};
bound.w = widthInSurface ?? EMBED_IFRAME_DEFAULT_WIDTH_IN_SURFACE;
bound.h =
heightInSurface ?? EMBED_IFRAME_DEFAULT_HEIGHT_IN_SURFACE;
newId = ctx.store.addBlock(
'affine:embed-iframe',
{ url, caption, title, description, xywh: bound.serialize() },
parent
);
}
if (!newId) return;
ctx.command.exec(reassociateConnectorsCommand, { oldId, newId });
ctx.store.deleteBlock(model);
@@ -449,13 +449,10 @@ const builtinSurfaceToolbarConfig = {
when(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);
if (!model) return false;
const { url } = model.props;
const options = ctx.std
.get(EmbedOptionProvider)
.getEmbedBlockOptions(url);
return canEmbedAsIframe(ctx.std, url) || options?.viewType === 'embed';
return (
canEmbedAsIframe(ctx.std, url) || canEmbedAsEmbedBlock(ctx.std, url)
);
},
content(ctx) {
const model = ctx.getCurrentModelByType(BookmarkBlockModel);

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -47,5 +47,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -450,7 +450,7 @@ export class CodeBlockComponent extends CaptionedBlockComponent<CodeBlockModel>
contenteditable="false"
class="affine-code-block-preview"
>
${previewContext?.renderer(this.model)}
${shouldRenderPreview && previewContext?.renderer(this.model)}
</div>
${this.renderChildren(this.model)} ${Object.values(this.widgets)}
</div>

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -48,5 +48,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -39,5 +39,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -495,14 +495,6 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
const linkedDoc = this.linkedDoc;
if (linkedDoc) {
this.disposables.add(
linkedDoc.workspace.slots.docListUpdated.subscribe(() => {
this._load().catch(e => {
console.error(e);
this.isError = true;
});
})
);
// Should throttle the blockUpdated event to avoid too many re-renders
// Because the blockUpdated event is triggered too frequently at some cases
this.disposables.add(

View File

@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -11,6 +11,8 @@ import {
EmbedCardLightVerticalIcon,
} from '@blocksuite/affine-components/icons';
import { ColorScheme } from '@blocksuite/affine-model';
import { EmbedOptionProvider } from '@blocksuite/affine-shared/services';
import type { BlockStdScope } from '@blocksuite/std';
import type { TemplateResult } from 'lit';
type EmbedCardIcons = {
@@ -40,3 +42,8 @@ export function getEmbedCardIcons(theme: ColorScheme): EmbedCardIcons {
};
}
}
export function canEmbedAsEmbedBlock(std: BlockStdScope, url: string) {
const options = std.get(EmbedOptionProvider).getEmbedBlockOptions(url);
return options?.viewType === 'embed';
}

View File

@@ -0,0 +1,75 @@
import { EmbedIframeConfigExtension } from '@blocksuite/affine-shared/services';
const GENERIC_DEFAULT_WIDTH_IN_SURFACE = 800;
const GENERIC_DEFAULT_HEIGHT_IN_SURFACE = 600;
const GENERIC_DEFAULT_WIDTH_PERCENT = 100;
const GENERIC_DEFAULT_HEIGHT_IN_NOTE = 400;
/**
* AFFiNE domains that should be excluded from generic embedding
* These are based on the centralized cloud constants and known AFFiNE domains
*/
const AFFINE_DOMAINS = [
'affine.pro', // Main AFFiNE domain
'app.affine.pro', // Stable cloud domain
'insider.affine.pro', // Beta/internal cloud domain
'affine.fail', // Canary cloud domain
'toeverything.app', // Safety measure for potential future use
'apple.getaffineapp.com', // Cloud domain for Apple app
];
/**
* Validates if a URL is suitable for generic iframe embedding
* Allows HTTPS URLs but excludes AFFiNE domains
* @param url The URL to validate
* @returns Boolean indicating if the URL can be generically embedded
*/
function isValidGenericEmbedUrl(url: string): boolean {
try {
const parsedUrl = new URL(url);
// Only allow HTTPS for security
if (parsedUrl.protocol !== 'https:') {
return false;
}
// Exclude AFFiNE domains
const hostname = parsedUrl.hostname.toLowerCase();
if (
AFFINE_DOMAINS.some(
domain => hostname === domain || hostname.endsWith(`.${domain}`)
)
) {
return false;
}
return true;
} catch {
// Invalid URL
return false;
}
}
const genericConfig = {
name: 'generic',
match: (url: string) => isValidGenericEmbedUrl(url),
buildOEmbedUrl: (url: string) => {
if (!isValidGenericEmbedUrl(url)) {
return undefined;
}
return url;
},
useOEmbedUrlDirectly: true,
options: {
widthInSurface: GENERIC_DEFAULT_WIDTH_IN_SURFACE,
heightInSurface: GENERIC_DEFAULT_HEIGHT_IN_SURFACE,
widthPercent: GENERIC_DEFAULT_WIDTH_PERCENT,
heightInNote: GENERIC_DEFAULT_HEIGHT_IN_NOTE,
allowFullscreen: true,
style: 'border: none; border-radius: 8px;',
allow: 'clipboard-read; clipboard-write; picture-in-picture;',
referrerpolicy: 'no-referrer-when-downgrade',
},
};
export const GenericEmbedConfig = EmbedIframeConfigExtension(genericConfig);

View File

@@ -1,4 +1,5 @@
import { ExcalidrawEmbedConfig } from './excalidraw';
import { GenericEmbedConfig } from './generic';
import { GoogleDocsEmbedConfig } from './google-docs';
import { GoogleDriveEmbedConfig } from './google-drive';
import { MiroEmbedConfig } from './miro';
@@ -10,4 +11,5 @@ export const EmbedIframeConfigExtensions = [
MiroEmbedConfig,
ExcalidrawEmbedConfig,
GoogleDocsEmbedConfig,
GenericEmbedConfig,
];

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -62,13 +62,11 @@ const builtinSurfaceToolbarConfig = {
if (!rootModel) return;
const { id: frameId, xywh } = model;
let lastNoteId = rootModel.children
.filter(
note =>
matchModels(note, [NoteBlockModel]) &&
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
)
.pop()?.id;
let lastNoteId = rootModel.children.findLast(
note =>
matchModels(note, [NoteBlockModel]) &&
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
)?.id;
if (!lastNoteId) {
const bounds = Bound.deserialize(xywh);

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -14,6 +14,7 @@ export class EdgelessNoteMask extends SignalWatcher(
protected override firstUpdated() {
const maskDOM = this.renderRoot!.querySelector('.affine-note-mask');
const observer = new ResizeObserver(entries => {
if (this.model.store.readonly) return;
for (const entry of entries) {
if (!this.model.props.edgeless.collapse) {
const bound = Bound.deserialize(this.model.xywh);

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -67,5 +67,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -81,5 +81,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -11,6 +11,7 @@ import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { keyed } from 'lit/directives/keyed.js';
import type { ClassInfo } from 'lit-html/directives/class-map.js';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { MenuFocusable } from './focusable.js';
import type { Menu } from './menu.js';
@@ -21,6 +22,7 @@ export type MenuButtonData = {
class: ClassInfo;
select: (ele: HTMLElement) => void | false;
onHover?: (hover: boolean) => void;
testId?: string;
};
export class MenuButton extends MenuFocusable {
@@ -97,7 +99,12 @@ export class MenuButton extends MenuFocusable {
focused: this.isFocused$.value,
...this.data.class,
});
return html` <div class="${classString}">${this.data.content()}</div>`;
return html` <div
class="${classString}"
data-testid=${ifDefined(this.data.testId)}
>
${this.data.content()}
</div>`;
}
@property({ attribute: false })
@@ -157,7 +164,12 @@ export class MobileMenuButton extends MenuFocusable {
focused: this.isFocused$.value,
...this.data.class,
});
return html` <div class="${classString}">${this.data.content()}</div>`;
return html` <div
class="${classString}"
data-testid=${ifDefined(this.data.testId)}
>
${this.data.content()}
</div>`;
}
@property({ attribute: false })
@@ -188,6 +200,7 @@ export const menuButtonItems = {
onHover?: (hover: boolean) => void;
class?: MenuClass;
hide?: () => boolean;
testId?: string;
}) =>
menu => {
if (config.hide?.() || !menu.search(config.name)) {
@@ -209,6 +222,7 @@ export const menuButtonItems = {
'selected-item': config.isSelected ?? false,
...config.class,
},
testId: config.testId,
};
return renderButton(data, menu);
},
@@ -220,6 +234,7 @@ export const menuButtonItems = {
label?: () => TemplateResult;
select: (checked: boolean) => boolean;
class?: ClassInfo;
testId?: string;
}) =>
menu => {
if (!menu.search(config.name)) {
@@ -240,6 +255,7 @@ export const menuButtonItems = {
return false;
},
class: config.class ?? {},
testId: config.testId,
};
return html`${keyed(config.name, renderButton(data, menu))}`;
},
@@ -247,10 +263,12 @@ export const menuButtonItems = {
(config: {
name: string;
on: boolean;
prefix?: TemplateResult;
postfix?: TemplateResult;
label?: () => TemplateResult;
onChange: (on: boolean) => void;
class?: ClassInfo;
testId?: string;
}) =>
menu => {
if (!menu.search(config.name)) {
@@ -262,6 +280,7 @@ export const menuButtonItems = {
const data: MenuButtonData = {
content: () => html`
${config.prefix}
<div class="affine-menu-action-text">
${config.label?.() ?? config.name}
</div>
@@ -276,6 +295,7 @@ export const menuButtonItems = {
return false;
},
class: config.class ?? {},
testId: config.testId,
};
return html`${keyed(config.name, renderButton(data, menu))}`;
},

View File

@@ -23,6 +23,7 @@ export type MenuOptions = {
placeholder?: string;
};
items: MenuConfig[];
testId?: string;
};
// Global menu open listener type
@@ -72,6 +73,9 @@ export class Menu {
? document.createElement('mobile-menu')
: document.createElement('affine-menu');
this.menuElement.menu = this;
if (this.options.testId) {
this.menuElement.dataset.testid = this.options.testId;
}
// Call global menu open listeners
menuOpenListeners.forEach(listener => {

View File

@@ -111,6 +111,7 @@ export class FilterableListComponent<Props = unknown> extends WithDisposable(
if (ev.isComposing) break;
ev.preventDefault();
const item = filteredItems[this._curFocusIndex];
if (!item) return;
this._select(item);
break;
}

View File

@@ -1,7 +1,14 @@
import { NoteBlockModel } from '@blocksuite/affine-model';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { isInsideEdgelessEditor } from '@blocksuite/affine-shared/utils';
import {
isInsideEdgelessEditor,
matchModels,
} from '@blocksuite/affine-shared/utils';
import type { Constructor } from '@blocksuite/global/utils';
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
import {
GfxBlockElementModel,
GfxControllerIdentifier,
} from '@blocksuite/std/gfx';
import type { BlockModel } from '@blocksuite/store';
import type { LitElement, TemplateResult } from 'lit';
@@ -72,6 +79,20 @@ export const Peekable =
);
if (hitTarget && hitTarget !== model) {
// Check if hitTarget is a GfxBlockElementModel (which extends BlockModel)
// and if it's a NoteBlockModel, then check if current model is inside it
if (
hitTarget instanceof GfxBlockElementModel &&
matchModels(hitTarget, [NoteBlockModel])
) {
let curModel: BlockModel | null = model;
while (curModel) {
if (curModel === hitTarget) {
return true; // Model is inside the NoteBlockModel, allow peek
}
curModel = curModel.parent;
}
}
return false;
}

View File

@@ -28,6 +28,7 @@
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"rxjs": "^7.8.1",
"vitest": "^3.2.3",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
@@ -45,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -0,0 +1,120 @@
import { describe, expect, it, vi } from 'vitest';
import { TableHotkeysController } from '../view-presets/table/pc/controller/hotkeys.js';
import { TableHotkeysController as VirtualHotkeysController } from '../view-presets/table/pc-virtual/controller/hotkeys.js';
import {
TableViewAreaSelection,
TableViewRowSelection,
} from '../view-presets/table/selection';
function createLogic() {
const view = {
rowsDelete: vi.fn(),
rows$: { value: [] },
groupTrait: { groupsDataList$: { value: [] } },
};
const ui = { disposables: { add: vi.fn() }, requestUpdate: vi.fn() };
const selectionController = {
selection: undefined as any,
getCellContainer: vi.fn(),
insertRowAfter: vi.fn(),
focusToCell: vi.fn(),
rowSelectionChange: vi.fn(),
areaToRows: vi.fn().mockReturnValue([]),
rowsToArea: vi.fn(),
navigateRowSelection: vi.fn(),
selectionAreaUp: vi.fn(),
selectionAreaDown: vi.fn(),
selectionAreaLeft: vi.fn(),
selectionAreaRight: vi.fn(),
isRowSelection: vi.fn().mockReturnValue(false),
};
const logic: any = {
view,
ui$: { value: ui },
selectionController,
bindHotkey: vi.fn((hotkeys: any) => {
logic.hotkeys = hotkeys;
return { dispose: vi.fn() };
}),
handleEvent: vi.fn((name: string, handler: any) => {
if (name === 'keyDown') logic.keyDown = handler;
return { dispose: vi.fn() };
}),
};
return { logic, view, ui, selectionController };
}
describe('TableHotkeysController', () => {
it('deletes rows on Backspace', () => {
const { logic, view, ui, selectionController } = createLogic();
const ctrl = new TableHotkeysController(logic as any);
ctrl.hostConnected();
selectionController.selection = TableViewRowSelection.create({
rows: [{ id: 'r1' }],
});
logic.hotkeys.Backspace();
expect(selectionController.selection).toBeUndefined();
expect(view.rowsDelete).toHaveBeenCalledWith(['r1']);
expect(ui.requestUpdate).toHaveBeenCalled();
});
it('starts editing on character key', () => {
const { logic, selectionController } = createLogic();
const ctrl = new TableHotkeysController(logic as any);
ctrl.hostConnected();
const cell = {
rowId: 'r1',
dataset: { rowId: 'r1', columnId: 'c1' },
column: { valueSetFromString: vi.fn() },
};
selectionController.getCellContainer.mockReturnValue(cell);
selectionController.selection = TableViewAreaSelection.create({
focus: { rowIndex: 0, columnIndex: 0 },
isEditing: false,
});
const evt = {
key: 'A',
metaKey: false,
ctrlKey: false,
altKey: false,
preventDefault: vi.fn(),
};
logic.keyDown({ get: () => ({ raw: evt }) });
expect(cell.column.valueSetFromString).toHaveBeenCalledWith('r1', 'A');
expect(selectionController.selection.isEditing).toBe(true);
expect(evt.preventDefault).toHaveBeenCalled();
});
});
describe('Virtual TableHotkeysController', () => {
it('writes character to cell', () => {
const { logic, selectionController } = createLogic();
const ctrl = new VirtualHotkeysController(logic as any);
ctrl.hostConnected();
const cell = {
rowId: 'r1',
dataset: { rowId: 'r1', columnId: 'c1' },
column$: { value: { valueSetFromString: vi.fn() } },
};
selectionController.getCellContainer.mockReturnValue(cell);
selectionController.selection = TableViewAreaSelection.create({
focus: { rowIndex: 1, columnIndex: 0 },
isEditing: false,
});
const evt = {
key: 'b',
metaKey: false,
ctrlKey: false,
altKey: false,
preventDefault: vi.fn(),
};
logic.keyDown({ get: () => ({ raw: evt }) });
expect(cell.column$.value.valueSetFromString).toHaveBeenCalledWith(
'r1',
'b'
);
expect(selectionController.selection.isEditing).toBe(true);
expect(evt.preventDefault).toHaveBeenCalled();
});
});

View File

@@ -35,7 +35,7 @@ export const selectPropertyModelConfig = selectPropertyType.modelConfig({
const name = oldValue
.split(',')
.map(v => v.trim())
.filter(v => v)[0];
.find(v => v);
if (!name) {
return { value: null, data: data };
}

View File

@@ -3,6 +3,8 @@ import { DisposableGroup } from '@blocksuite/global/disposable';
import type { ReactiveController } from 'lit';
import { TableViewAreaSelection, TableViewRowSelection } from '../../selection';
import { handleCharStartEdit } from '../../utils.js';
import type { DatabaseCellContainer } from '../row/cell.js';
import { popRowMenu } from '../row/menu';
import type { VirtualTableViewUILogic } from '../table-view-ui-logic';
@@ -138,7 +140,11 @@ export class TableHotkeysController implements ReactiveController {
});
}
} else if (selection.isEditing) {
return false;
this.selectionController.selection = {
...selection,
isEditing: false,
};
this.selectionController.focusToCell('down');
} else {
this.selectionController.selection = {
...selection,
@@ -172,27 +178,31 @@ export class TableHotkeysController implements ReactiveController {
},
Tab: ctx => {
const selection = this.selectionController.selection;
if (
!selection ||
TableViewRowSelection.is(selection) ||
selection.isEditing
) {
if (!selection || TableViewRowSelection.is(selection)) {
return false;
}
ctx.get('keyboardState').raw.preventDefault();
if (selection.isEditing) {
this.selectionController.selection = {
...selection,
isEditing: false,
};
}
this.selectionController.focusToCell('right');
return true;
},
'Shift-Tab': ctx => {
const selection = this.selectionController.selection;
if (
!selection ||
TableViewRowSelection.is(selection) ||
selection.isEditing
) {
if (!selection || TableViewRowSelection.is(selection)) {
return false;
}
ctx.get('keyboardState').raw.preventDefault();
if (selection.isEditing) {
this.selectionController.selection = {
...selection,
isEditing: false,
};
}
this.selectionController.focusToCell('left');
return true;
},
@@ -390,5 +400,19 @@ export class TableHotkeysController implements ReactiveController {
},
})
);
this.disposables.add(
this.logic.handleEvent('keyDown', ctx => {
const event = ctx.get('keyboardState').raw;
return handleCharStartEdit<DatabaseCellContainer>({
event,
selection: this.selectionController.selection,
getCellContainer: this.selectionController.getCellContainer.bind(
this.selectionController
),
updateSelection: sel => (this.selectionController.selection = sel),
getColumn: cell => cell.column$.value,
});
})
);
}
}

View File

@@ -2,6 +2,8 @@ import { popupTargetFromElement } from '@blocksuite/affine-components/context-me
import type { ReactiveController } from 'lit';
import { TableViewAreaSelection, TableViewRowSelection } from '../../selection';
import { handleCharStartEdit } from '../../utils.js';
import type { TableViewCellContainer } from '../cell.js';
import { popRowMenu } from '../menu.js';
import type { TableViewUILogic } from '../table-view-ui-logic';
@@ -136,7 +138,11 @@ export class TableHotkeysController implements ReactiveController {
});
}
} else if (selection.isEditing) {
return false;
this.selectionController.selection = {
...selection,
isEditing: false,
};
this.selectionController.focusToCell('down');
} else {
this.selectionController.selection = {
...selection,
@@ -170,27 +176,31 @@ export class TableHotkeysController implements ReactiveController {
},
Tab: ctx => {
const selection = this.selectionController.selection;
if (
!selection ||
TableViewRowSelection.is(selection) ||
selection.isEditing
) {
if (!selection || TableViewRowSelection.is(selection)) {
return false;
}
ctx.get('keyboardState').raw.preventDefault();
if (selection.isEditing) {
this.selectionController.selection = {
...selection,
isEditing: false,
};
}
this.selectionController.focusToCell('right');
return true;
},
'Shift-Tab': ctx => {
const selection = this.selectionController.selection;
if (
!selection ||
TableViewRowSelection.is(selection) ||
selection.isEditing
) {
if (!selection || TableViewRowSelection.is(selection)) {
return false;
}
ctx.get('keyboardState').raw.preventDefault();
if (selection.isEditing) {
this.selectionController.selection = {
...selection,
isEditing: false,
};
}
this.selectionController.focusToCell('left');
return true;
},
@@ -388,5 +398,19 @@ export class TableHotkeysController implements ReactiveController {
},
})
);
this.host?.disposables.add(
this.logic.handleEvent('keyDown', ctx => {
const event = ctx.get('keyboardState').raw;
return handleCharStartEdit<TableViewCellContainer>({
event,
selection: this.selectionController.selection,
getCellContainer: this.selectionController.getCellContainer.bind(
this.selectionController
),
updateSelection: sel => (this.selectionController.selection = sel),
getColumn: cell => cell.column,
});
})
);
}
}

View File

@@ -0,0 +1,58 @@
import type { TableViewSelectionWithType } from './selection';
import { TableViewRowSelection } from './selection';
export interface TableCell {
rowId: string;
}
export type ColumnAccessor<T extends TableCell> = (
cell: T
) => { valueSetFromString(rowId: string, value: string): void } | undefined;
export interface StartEditOptions<T extends TableCell> {
event: KeyboardEvent;
selection: TableViewSelectionWithType | undefined;
getCellContainer: (
groupKey: string | undefined,
rowIndex: number,
columnIndex: number
) => T | undefined;
updateSelection: (sel: TableViewSelectionWithType) => void;
getColumn: ColumnAccessor<T>;
}
export function handleCharStartEdit<T extends TableCell>(
options: StartEditOptions<T>
): boolean {
const { event, selection, getCellContainer, updateSelection, getColumn } =
options;
const target = event.target as HTMLElement | null;
if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA')) {
return false;
}
if (
selection &&
!TableViewRowSelection.is(selection) &&
!selection.isEditing &&
!event.metaKey &&
!event.ctrlKey &&
!event.altKey &&
event.key.length === 1
) {
const cell = getCellContainer(
selection.groupKey,
selection.focus.rowIndex,
selection.focus.columnIndex
);
if (cell) {
const column = getColumn(cell);
column?.valueSetFromString(cell.rowId, event.key);
updateSelection({ ...selection, isEditing: true });
event.preventDefault();
return true;
}
}
return false;
}

View File

@@ -0,0 +1,25 @@
import { defineConfig } from 'vitest/config';
export default defineConfig({
esbuild: {
target: 'es2018',
},
test: {
globalSetup: '../../scripts/vitest-global.js',
include: ['src/__tests__/**/*.unit.spec.ts'],
testTimeout: 1000,
coverage: {
provider: 'istanbul',
reporter: ['lcov'],
reportsDirectory: '../../.coverage/data-view',
},
onConsoleLog(log, type) {
if (log.includes('lit.dev/msg/dev-mode')) {
return false;
}
console.warn(`Unexpected ${type} log`, log);
throw new Error(log);
},
environment: 'happy-dom',
},
});

View File

@@ -26,5 +26,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -40,5 +40,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -0,0 +1,11 @@
import { DomElementRendererExtension } from '@blocksuite/affine-block-surface';
import { connectorDomRenderer } from './connector-dom/index.js';
/**
* Extension to register the DOM-based renderer for 'connector' elements.
*/
export const ConnectorDomRendererExtension = DomElementRendererExtension(
'connector',
connectorDomRenderer
);

View File

@@ -0,0 +1,367 @@
import type { DomRenderer } from '@blocksuite/affine-block-surface';
import {
type ConnectorElementModel,
ConnectorMode,
DefaultTheme,
type PointStyle,
} from '@blocksuite/affine-model';
import { PointLocation, SVGPathBuilder } from '@blocksuite/global/gfx';
import { isConnectorWithLabel } from '../../connector-manager.js';
import { DEFAULT_ARROW_SIZE } from '../utils.js';
interface PathBounds {
minX: number;
minY: number;
maxX: number;
maxY: number;
}
function calculatePathBounds(path: PointLocation[]): PathBounds {
if (path.length === 0) {
return { minX: 0, minY: 0, maxX: 0, maxY: 0 };
}
let minX = path[0][0];
let minY = path[0][1];
let maxX = path[0][0];
let maxY = path[0][1];
for (const point of path) {
minX = Math.min(minX, point[0]);
minY = Math.min(minY, point[1]);
maxX = Math.max(maxX, point[0]);
maxY = Math.max(maxY, point[1]);
}
return { minX, minY, maxX, maxY };
}
function createConnectorPath(
points: PointLocation[],
mode: ConnectorMode
): string {
if (points.length < 2) return '';
const pathBuilder = new SVGPathBuilder();
pathBuilder.moveTo(points[0][0], points[0][1]);
if (mode === ConnectorMode.Curve) {
// Use bezier curves
for (let i = 1; i < points.length; i++) {
const prev = points[i - 1];
const curr = points[i];
pathBuilder.curveTo(
prev.absOut[0],
prev.absOut[1],
curr.absIn[0],
curr.absIn[1],
curr[0],
curr[1]
);
}
} else {
// Use straight lines
for (let i = 1; i < points.length; i++) {
pathBuilder.lineTo(points[i][0], points[i][1]);
}
}
return pathBuilder.build();
}
function createArrowMarker(
id: string,
style: PointStyle,
color: string,
strokeWidth: number,
isStart: boolean = false
): SVGMarkerElement {
const marker = document.createElementNS(
'http://www.w3.org/2000/svg',
'marker'
);
const size = DEFAULT_ARROW_SIZE * (strokeWidth / 2);
marker.id = id;
marker.setAttribute('viewBox', '0 0 20 20');
marker.setAttribute('refX', isStart ? '20' : '0');
marker.setAttribute('refY', '10');
marker.setAttribute('markerWidth', String(size));
marker.setAttribute('markerHeight', String(size));
marker.setAttribute('orient', 'auto');
marker.setAttribute('markerUnits', 'strokeWidth');
switch (style) {
case 'Arrow': {
const path = document.createElementNS(
'http://www.w3.org/2000/svg',
'path'
);
path.setAttribute(
'd',
isStart ? 'M 20 5 L 10 10 L 20 15 Z' : 'M 0 5 L 10 10 L 0 15 Z'
);
path.setAttribute('fill', color);
path.setAttribute('stroke', color);
marker.append(path);
break;
}
case 'Triangle': {
const path = document.createElementNS(
'http://www.w3.org/2000/svg',
'path'
);
path.setAttribute(
'd',
isStart ? 'M 20 7 L 12 10 L 20 13 Z' : 'M 0 7 L 8 10 L 0 13 Z'
);
path.setAttribute('fill', color);
path.setAttribute('stroke', color);
marker.append(path);
break;
}
case 'Circle': {
const circle = document.createElementNS(
'http://www.w3.org/2000/svg',
'circle'
);
circle.setAttribute('cx', '10');
circle.setAttribute('cy', '10');
circle.setAttribute('r', '4');
circle.setAttribute('fill', color);
circle.setAttribute('stroke', color);
marker.append(circle);
break;
}
case 'Diamond': {
const path = document.createElementNS(
'http://www.w3.org/2000/svg',
'path'
);
path.setAttribute('d', 'M 10 6 L 14 10 L 10 14 L 6 10 Z');
path.setAttribute('fill', color);
path.setAttribute('stroke', color);
marker.append(path);
break;
}
}
return marker;
}
function renderConnectorLabel(
model: ConnectorElementModel,
container: HTMLElement,
renderer: DomRenderer,
zoom: number
) {
if (!isConnectorWithLabel(model) || !model.labelXYWH) {
return;
}
const [lx, ly, lw, lh] = model.labelXYWH;
const {
labelStyle: {
color,
fontSize,
fontWeight,
fontStyle,
fontFamily,
textAlign,
},
} = model;
// Create label element
const labelElement = document.createElement('div');
labelElement.style.position = 'absolute';
labelElement.style.left = `${lx * zoom}px`;
labelElement.style.top = `${ly * zoom}px`;
labelElement.style.width = `${lw * zoom}px`;
labelElement.style.height = `${lh * zoom}px`;
labelElement.style.pointerEvents = 'none';
labelElement.style.overflow = 'hidden';
labelElement.style.display = 'flex';
labelElement.style.alignItems = 'center';
labelElement.style.justifyContent =
textAlign === 'center'
? 'center'
: textAlign === 'right'
? 'flex-end'
: 'flex-start';
// Style the text
labelElement.style.color = renderer.getColorValue(
color,
DefaultTheme.black,
true
);
labelElement.style.fontSize = `${fontSize * zoom}px`;
labelElement.style.fontWeight = fontWeight;
labelElement.style.fontStyle = fontStyle;
labelElement.style.fontFamily = fontFamily;
labelElement.style.textAlign = textAlign;
labelElement.style.lineHeight = '1.2';
labelElement.style.whiteSpace = 'pre-wrap';
labelElement.style.wordWrap = 'break-word';
// Add text content
if (model.text) {
labelElement.textContent = model.text.toString();
}
container.append(labelElement);
}
/**
* Renders a ConnectorElementModel to a given HTMLElement using DOM/SVG.
* This function is intended to be registered via the DomElementRendererExtension.
*
* @param model - The connector element model containing rendering properties.
* @param element - The HTMLElement to apply the connector's styles to.
* @param renderer - The main DOMRenderer instance, providing access to viewport and color utilities.
*/
export const connectorDomRenderer = (
model: ConnectorElementModel,
element: HTMLElement,
renderer: DomRenderer
): void => {
const { zoom } = renderer.viewport;
const {
mode,
path: points,
strokeStyle,
frontEndpointStyle,
rearEndpointStyle,
strokeWidth,
stroke,
} = model;
// Clear previous content
element.innerHTML = '';
// Early return if no path points
if (!points || points.length < 2) {
return;
}
// Calculate bounds for the SVG viewBox
const pathBounds = calculatePathBounds(points);
const padding = Math.max(strokeWidth * 2, 20); // Add padding for arrows
const svgWidth = (pathBounds.maxX - pathBounds.minX + padding * 2) * zoom;
const svgHeight = (pathBounds.maxY - pathBounds.minY + padding * 2) * zoom;
const offsetX = pathBounds.minX - padding;
const offsetY = pathBounds.minY - padding;
// Create SVG element
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.style.position = 'absolute';
svg.style.left = `${offsetX * zoom}px`;
svg.style.top = `${offsetY * zoom}px`;
svg.style.width = `${svgWidth}px`;
svg.style.height = `${svgHeight}px`;
svg.style.overflow = 'visible';
svg.style.pointerEvents = 'none';
svg.setAttribute('viewBox', `0 0 ${svgWidth / zoom} ${svgHeight / zoom}`);
// Create defs for markers
const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
svg.append(defs);
const strokeColor = renderer.getColorValue(
stroke,
DefaultTheme.connectorColor,
true
);
// Create markers for endpoints
let startMarkerId = '';
let endMarkerId = '';
if (frontEndpointStyle !== 'None') {
startMarkerId = `start-marker-${model.id}`;
const startMarker = createArrowMarker(
startMarkerId,
frontEndpointStyle,
strokeColor,
strokeWidth,
true
);
defs.append(startMarker);
}
if (rearEndpointStyle !== 'None') {
endMarkerId = `end-marker-${model.id}`;
const endMarker = createArrowMarker(
endMarkerId,
rearEndpointStyle,
strokeColor,
strokeWidth,
false
);
defs.append(endMarker);
}
// Create path element
const pathElement = document.createElementNS(
'http://www.w3.org/2000/svg',
'path'
);
// Adjust points relative to the SVG coordinate system
const adjustedPoints = points.map(point => {
const adjustedPoint = new PointLocation([
point[0] - offsetX,
point[1] - offsetY,
]);
if (point.absIn) {
adjustedPoint.in = [
point.absIn[0] - offsetX - adjustedPoint[0],
point.absIn[1] - offsetY - adjustedPoint[1],
];
}
if (point.absOut) {
adjustedPoint.out = [
point.absOut[0] - offsetX - adjustedPoint[0],
point.absOut[1] - offsetY - adjustedPoint[1],
];
}
return adjustedPoint;
});
const pathData = createConnectorPath(adjustedPoints, mode);
pathElement.setAttribute('d', pathData);
pathElement.setAttribute('stroke', strokeColor);
pathElement.setAttribute('stroke-width', String(strokeWidth));
pathElement.setAttribute('fill', 'none');
pathElement.setAttribute('stroke-linecap', 'round');
pathElement.setAttribute('stroke-linejoin', 'round');
// Apply stroke style
if (strokeStyle === 'dash') {
pathElement.setAttribute('stroke-dasharray', '12,12');
}
// Apply markers
if (startMarkerId) {
pathElement.setAttribute('marker-start', `url(#${startMarkerId})`);
}
if (endMarkerId) {
pathElement.setAttribute('marker-end', `url(#${endMarkerId})`);
}
svg.append(pathElement);
element.append(svg);
// Set element size and position
element.style.width = `${model.w * zoom}px`;
element.style.height = `${model.h * zoom}px`;
element.style.overflow = 'visible';
element.style.pointerEvents = 'none';
// Set z-index for layering
element.style.zIndex = renderer.layerManager.getZIndex(model).toString();
// Render label if present
renderConnectorLabel(model, element, renderer, zoom);
};

View File

@@ -2,6 +2,7 @@ export * from './adapter';
export * from './connector-manager';
export * from './connector-tool';
export * from './element-renderer';
export { ConnectorDomRendererExtension } from './element-renderer/connector-dom';
export * from './element-transform';
export * from './text';
export * from './toolbar/config';

View File

@@ -7,6 +7,7 @@ import { ConnectionOverlay } from './connector-manager';
import { ConnectorTool } from './connector-tool';
import { effects } from './effects';
import { ConnectorElementRendererExtension } from './element-renderer';
import { ConnectorDomRendererExtension } from './element-renderer/connector-dom';
import { ConnectorFilter } from './element-transform';
import { connectorToolbarExtension } from './toolbar/config';
import { connectorQuickTool } from './toolbar/quick-tool';
@@ -24,6 +25,7 @@ export class ConnectorViewExtension extends ViewExtensionProvider {
super.setup(context);
context.register(ConnectorElementView);
context.register(ConnectorElementRendererExtension);
context.register(ConnectorDomRendererExtension);
if (this.isEdgeless(context.scope)) {
context.register(ConnectorTool);
context.register(ConnectorFilter);

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -40,13 +40,11 @@ export const groupToolbarConfig = {
if (!rootModel) return;
const { id: groupId, xywh } = model;
let lastNoteId = rootModel.children
.filter(
note =>
matchModels(note, [NoteBlockModel]) &&
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
)
.pop()?.id;
let lastNoteId = rootModel.children.findLast(
note =>
matchModels(note, [NoteBlockModel]) &&
note.props.displayMode !== NoteDisplayMode.EdgelessOnly
)?.id;
if (!lastNoteId) {
const bounds = Bound.deserialize(xywh);

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -51,5 +51,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -1,6 +1,7 @@
import type { DomRenderer } from '@blocksuite/affine-block-surface';
import type { ShapeElementModel } from '@blocksuite/affine-model';
import { DefaultTheme } from '@blocksuite/affine-model';
import { SVGShapeBuilder } from '@blocksuite/global/gfx';
import { manageClassNames, setStyles } from './utils';
@@ -122,25 +123,22 @@ export const shapeDomRenderer = (
element.style.backgroundColor = 'transparent'; // Host element is transparent
const strokeW = model.strokeWidth;
const halfStroke = strokeW / 2; // Calculate half stroke width for point adjustment
let svgPoints = '';
if (model.shapeType === 'diamond') {
// Adjusted points for diamond
svgPoints = [
`${unscaledWidth / 2},${halfStroke}`,
`${unscaledWidth - halfStroke},${unscaledHeight / 2}`,
`${unscaledWidth / 2},${unscaledHeight - halfStroke}`,
`${halfStroke},${unscaledHeight / 2}`,
].join(' ');
// Generate diamond points using shared utility
svgPoints = SVGShapeBuilder.diamond(
unscaledWidth,
unscaledHeight,
strokeW
);
} else {
// triangle
// Adjusted points for triangle
svgPoints = [
`${unscaledWidth / 2},${halfStroke}`,
`${unscaledWidth - halfStroke},${unscaledHeight - halfStroke}`,
`${halfStroke},${unscaledHeight - halfStroke}`,
].join(' ');
// triangle - generate triangle points using shared utility
svgPoints = SVGShapeBuilder.triangle(
unscaledWidth,
unscaledHeight,
strokeW
);
}
// Determine if stroke should be visible and its color

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -25,5 +25,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -47,5 +47,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -50,5 +50,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.21.0"
"version": "0.22.4"
}

Some files were not shown because too many files have changed in this diff Show More