snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
This commit is contained in:
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: univer
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
68
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
68
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: 🐛 Bug report
|
||||
description: Create a report to help us improve.
|
||||
type: Bug
|
||||
labels: bug 🐛
|
||||
title: '[Bug] '
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Thank you for helping us improve Univer!**
|
||||
|
||||
> [!CAUTION]
|
||||
> Before submitting a bug report, please ensure that you have read the [Univer GitHub Issues Community Guide](https://github.com/dream-num/univer/wiki/Univer-GitHub-Issues-Community-Guide).
|
||||
|
||||
- type: checkboxes
|
||||
id: initial-checklist
|
||||
attributes:
|
||||
label: Before you submit this issue, have you checked the following
|
||||
options:
|
||||
- label: Is this really a problem?
|
||||
required: true
|
||||
- label: I have searched the Github Issues for similar issues, but did not find anything.
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: affected-versions
|
||||
attributes:
|
||||
label: Affected packages and versions
|
||||
description: Please test using the latest version of the relevant packages to make sure your issue has not already been fixed.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Reproduction link
|
||||
description: |
|
||||
> [!CAUTION]
|
||||
> Please note that it is essential to provide a reproduction and describe the reproduction steps in detail. **If you cannot provide a reproduction link, your issue may be closed directly.**
|
||||
|
||||
We provide a [Vite online template](https://stackblitz.com/edit/univer-sheets-vite) and a [UMD online template](https://stackblitz.com/edit/univer-sheets-umd). If your issue can be reproduced in one of these templates, please provide the reproduction link here.
|
||||
We also provide some other [template repositories](https://github.com/awesome-univer), you can choose one of them to reproduce your issue.
|
||||
If your issue cannot be reproduced in the template, please provide as detailed reproduction steps as possible.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: What should happen?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: actual-behavior
|
||||
attributes:
|
||||
label: Actual behavior
|
||||
description: What happens instead?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: System information
|
||||
description: Output of `npx envinfo --system --binaries --browsers`
|
||||
84
.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
vendored
Normal file
84
.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
name: 🐛 Bug 报告
|
||||
description: 尽管我们提供了中文 Bug 报告的入口,但还是建议您使用英语描述问题,这可以让更多的人来帮助您。
|
||||
type: Bug
|
||||
labels: bug 🐛
|
||||
title: '[Bug] '
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**感谢您帮助我们改进 Univer!**
|
||||
|
||||
> [!CAUTION]
|
||||
> 在提交 Bug 报告之前,请确保您已阅读 [Univer GitHub Issues 社区手册](https://github.com/dream-num/univer/wiki/Univer-GitHub-Issues-%E7%A4%BE%E5%8C%BA%E6%89%8B%E5%86%8C)。
|
||||
|
||||
- type: checkboxes
|
||||
id: initial-checklist
|
||||
attributes:
|
||||
label: 在您提交此问题之前,您是否检查了以下内容?
|
||||
options:
|
||||
- label: 这真的是个问题吗?
|
||||
required: true
|
||||
- label: 我已经在 Github Issues 中搜索过了,但没有找到类似的问题。
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: affected-versions
|
||||
attributes:
|
||||
label: 受影响的包和版本
|
||||
description: 请使用最新版本的相关包进行测试,以确保您的问题尚未解决。
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: 复现链接
|
||||
description: |
|
||||
> [!CAUTION]
|
||||
> **请注意,请务必认真提供复现并详细描述复现步骤,**如果您无法提供复现链接,你的问题会被直接关闭。**
|
||||
|
||||
我们提供了 [Vite 在线模板](https://stackblitz.com/edit/univer-sheets-vite) 和 [UMD 在线模板](https://stackblitz.com/edit/univer-sheets-umd),如果您的问题可以在这个模板中复现,那么请在这里提供复现链接。
|
||||
我们也提供了一些其他你可能会用到的 [模板仓库](https://github.com/awesome-univer),你可以选择其中一个来复现你的问题。
|
||||
如果您的问题无法在模板中复现,请提供尽可能详细的复现步骤。
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: 预期行为
|
||||
description: 本应发生什么?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: actual-behavior
|
||||
attributes:
|
||||
label: 实际行为
|
||||
description: 实际发生了什么?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: javascript-runtime
|
||||
attributes:
|
||||
label: 运行环境
|
||||
description: |
|
||||
您使用的浏览器是?
|
||||
multiple: true
|
||||
options:
|
||||
- Chrome
|
||||
- Safari
|
||||
- Firefox
|
||||
- Electron
|
||||
- 其他 (请在复现步骤中说明)
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: 系统信息
|
||||
description: 在这里粘贴 `npx envinfo --system --binaries --browsers` 命令的输出结果
|
||||
9
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
9
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: 💬 Github Discussions
|
||||
url: https://github.com/dream-num/univer/discussions
|
||||
about: Use github issues for bug reports and feature requests. For questions please use discussions. | Github issues 仅用于错误报告和功能请求。如有疑问请使用 Github Discussions。
|
||||
|
||||
- name: 👾 Discord Community
|
||||
url: https://discord.gg/z3NKNT6D2f
|
||||
about: Ask for help in the Discord community. | 在 Discord 社区寻求帮助。
|
||||
24
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
24
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: 🚀 Feature request
|
||||
description: Suggest an idea
|
||||
type: Feature
|
||||
labels: enhancement 🚀
|
||||
title: '[Feature] '
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: initial-checklist
|
||||
attributes:
|
||||
label: Initial checklist
|
||||
options:
|
||||
- label: Is this really a problem?
|
||||
required: true
|
||||
- label: I have searched the Github Issues for similar issues, but did not find anything.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Problem
|
||||
description: Please describe the problem you are trying to solve here.
|
||||
validations:
|
||||
required: true
|
||||
27
.github/ISSUE_TEMPLATE/feature_request.zh-CN.yml
vendored
Normal file
27
.github/ISSUE_TEMPLATE/feature_request.zh-CN.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: 🚀 新功能请求
|
||||
description: 尽管我们提供了中文 Feature request 的入口,但还是建议您使用英语描述需求,这可以让更多的人来帮助您。
|
||||
type: Feature
|
||||
labels: enhancement 🚀
|
||||
title: '[Feature] '
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: initial-checklist
|
||||
attributes:
|
||||
label: 初始清单
|
||||
options:
|
||||
- label: 这真的是个问题吗?
|
||||
required: true
|
||||
- label: 我已经在 Github Issues 中搜索过了,但没有找到类似的问题。
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: 问题
|
||||
description: |
|
||||
请详细描述您的需求,如果您的描述无法被理解,**那么您的问题可能会被直接关闭**。
|
||||
- 您应当清楚地提供需求的背景、目的、以及您希望的解决方案。
|
||||
- 如果您有任何的设计稿、流程图、或者其他相关的附件,请在这里提供。
|
||||
validations:
|
||||
required: true
|
||||
41
.github/actions/setup-node/action.yml
vendored
Normal file
41
.github/actions/setup-node/action.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Node Setup
|
||||
description: Node.js setup for CI, including cache configuration
|
||||
|
||||
inputs:
|
||||
save-cache:
|
||||
description: Save a new pnpm store cache entry from this job
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup pnpm and Node.js
|
||||
uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@24.3.0
|
||||
install: false
|
||||
|
||||
- name: Get pnpm store path
|
||||
id: pnpm-store
|
||||
shell: bash
|
||||
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Restore pnpm store
|
||||
id: pnpm-cache
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.path }}
|
||||
key: pnpm-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package.json', 'pnpm-lock.yaml', 'pnpm-workspace.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-${{ runner.os }}-${{ runner.arch }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
shell: bash
|
||||
|
||||
- name: Save pnpm store
|
||||
if: inputs.save-cache == 'true' && github.ref_name == github.event.repository.default_branch && steps.pnpm-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.path }}
|
||||
key: pnpm-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package.json', 'pnpm-lock.yaml', 'pnpm-workspace.yaml') }}
|
||||
13
.github/dependabot.yml
vendored
Normal file
13
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm # See documentation for possible values
|
||||
directory: / # Location of package manifests
|
||||
schedule:
|
||||
interval: weekly
|
||||
versioning-strategy: auto
|
||||
open-pull-requests-limit: 5
|
||||
26
.github/pull_request_template.md
vendored
Normal file
26
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
Thank you for submitting a Pull Request.
|
||||
Please read our Pull Request guidelines:
|
||||
https://github.com/dream-num/univer/blob/dev/CONTRIBUTING.md#submitting-pull-requests
|
||||
-->
|
||||
|
||||
<!-- Associate issues with the pull request if there is one. Separate them width commas. -->
|
||||
<!-- Feel free to delete this if there is no related issue. -->
|
||||
close #xxx
|
||||
|
||||
<!-- A description of the proposed changes. -->
|
||||
|
||||
<!-- How to test them. -->
|
||||
|
||||
<!-- Uncomment the below lines if there are breaking changes introduced in this PR. -->
|
||||
<!-- BREAKING CHANGE:
|
||||
Before:
|
||||
|
||||
After: -->
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
- [ ] Related tickets or issues have been linked in the PR description (or missing issue).
|
||||
- [ ] [Naming convention](https://github.com/dream-num/univer/blob/dev/docs/NAMING_CONVENTION.md) is followed (**do please** check it especially when you created new plugins, commands and resources).
|
||||
- [ ] Unit tests have been added for the changes (if applicable).
|
||||
- [ ] Breaking changes have been documented (or no breaking changes introduced in this PR).
|
||||
61
.github/workflows/build-packages.yml
vendored
Normal file
61
.github/workflows/build-packages.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: 📦 Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
TURBO_TELEMETRY_DISABLED: '1'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository == 'dream-num/univer' && (github.event_name != 'pull_request' || !github.event.pull_request.draft)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
save-cache: 'true'
|
||||
|
||||
- name: 📦 Build
|
||||
run: pnpm build:ci
|
||||
|
||||
- name: Check for uncommitted changes
|
||||
run: |
|
||||
if [[ -n $(git status --porcelain) ]]; then
|
||||
echo "Error: Uncommitted changes detected after build."
|
||||
echo "Changed files:"
|
||||
git status --porcelain
|
||||
echo "Diff of changes:"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
128
.github/workflows/ci-quality-checks.yml
vendored
Normal file
128
.github/workflows/ci-quality-checks.yml
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
name: 🧪 CI Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
TURBO_TELEMETRY_DISABLED: '1'
|
||||
|
||||
jobs:
|
||||
test-shard:
|
||||
name: test shard (${{ matrix.shard-index }}/${{ matrix.shard-total }})
|
||||
if: github.repository == 'dream-num/univer' && (github.event_name != 'pull_request' || !github.event.pull_request.draft)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
matrix:
|
||||
shard-index: [1, 2, 3, 4]
|
||||
shard-total: [4]
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: 🩺 Run test
|
||||
run: node --experimental-strip-types ./scripts/coverage-shard.mts --shard-index=${{ matrix.shard-index }} --shard-total=${{ matrix.shard-total }} --concurrency=2
|
||||
|
||||
- name: 🧬 Report coverage
|
||||
uses: codecov/codecov-action@v7
|
||||
with:
|
||||
name: unit-${{ matrix.shard-index }}
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
test:
|
||||
name: test
|
||||
if: always() && github.repository == 'dream-num/univer' && (github.event_name != 'pull_request' || !github.event.pull_request.draft)
|
||||
runs-on: minimum-runner
|
||||
timeout-minutes: 5
|
||||
needs: test-shard
|
||||
|
||||
steps:
|
||||
- name: Check test shard results
|
||||
run: |
|
||||
if [ "${{ needs.test-shard.result }}" != "success" ]; then
|
||||
echo "One or more test shards failed: ${{ needs.test-shard.result }}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All test shards passed"
|
||||
|
||||
eslint:
|
||||
if: github.repository == 'dream-num/univer' && (github.event_name != 'pull_request' || !github.event.pull_request.draft)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Restore ESLint cache
|
||||
id: eslint-cache
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: .eslintcache
|
||||
key: eslint-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'package.json', 'eslint.config.ts') }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
eslint-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'package.json', 'eslint.config.ts') }}-
|
||||
|
||||
- name: 🌡️ Run ESLint
|
||||
run: pnpm lint --quiet --cache --cache-location .eslintcache
|
||||
|
||||
- name: Save ESLint cache
|
||||
if: github.ref_name == github.event.repository.default_branch && steps.eslint-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
path: .eslintcache
|
||||
key: eslint-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'package.json', 'eslint.config.ts') }}-${{ github.sha }}
|
||||
|
||||
typecheck:
|
||||
if: github.repository == 'dream-num/univer' && (github.event_name != 'pull_request' || !github.event.pull_request.draft)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: 🧼 Type checking
|
||||
run: pnpm typecheck
|
||||
65
.github/workflows/collect-pr-metadata.yml
vendored
Normal file
65
.github/workflows/collect-pr-metadata.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: 🎬 Setup
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- closed
|
||||
- ready_for_review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
TURBO_TELEMETRY_DISABLED: '1'
|
||||
|
||||
jobs:
|
||||
set-pr-info:
|
||||
name: set PR info
|
||||
if: github.repository == 'dream-num/univer' && !github.event.pull_request.draft
|
||||
runs-on: minimum-runner
|
||||
steps:
|
||||
- name: Save PR info
|
||||
env:
|
||||
PR_ID: ${{ github.event.pull_request.number || '' }}
|
||||
PR_REF: ${{ github.head_ref || github.ref_name }}
|
||||
PR_REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
||||
PR_STATE: ${{ github.event.pull_request.state || '' }}
|
||||
run: |
|
||||
printf '%s\n' "$PR_ID" > ./pr-id.txt
|
||||
printf '%s\n' "$PR_REF" > ./pr-ref.txt
|
||||
printf '%s\n' "$PR_REPO" > ./pr-repo.txt
|
||||
printf '%s\n' "$PR_STATE" > ./pr-state.txt
|
||||
|
||||
- name: Upload PR number
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pr-id
|
||||
path: ./pr-id.txt
|
||||
|
||||
- name: Upload PR ref
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pr-ref
|
||||
path: ./pr-ref.txt
|
||||
|
||||
- name: Upload PR repo
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pr-repo
|
||||
path: ./pr-repo.txt
|
||||
|
||||
- name: Upload PR state
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pr-state
|
||||
path: ./pr-state.txt
|
||||
24
.github/workflows/dispatch-sync-univer-pro.yml
vendored
Normal file
24
.github/workflows/dispatch-sync-univer-pro.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: 🔫 Sync to Pro
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
dispatch-sync:
|
||||
if: github.repository == 'dream-num/univer'
|
||||
runs-on: minimum-runner
|
||||
|
||||
steps:
|
||||
- name: Dispatch sync event to univer-pro
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
repository: dream-num/univer-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
event-type: sync-univer
|
||||
client-payload: >
|
||||
{
|
||||
"ref": "${{ github.ref_name }}",
|
||||
"sha": "${{ github.sha }}"
|
||||
}
|
||||
62
.github/workflows/release-npm.yml
vendored
Normal file
62
.github/workflows/release-npm.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: 🍰 Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
- 'v*.*.*-alpha.*'
|
||||
- 'v*.*.*-beta.*'
|
||||
- 'v*.*.*-rc.*'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
TURBO_TELEMETRY_DISABLED: '1'
|
||||
|
||||
jobs:
|
||||
release-npm:
|
||||
if: github.repository == 'dream-num/univer'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ github.ref_name }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install pnpm and Node.js
|
||||
uses: pnpm/setup@v2
|
||||
with:
|
||||
runtime: node@24.3.0
|
||||
install: false
|
||||
|
||||
- name: Configure npm registry
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
registry-url: https://registry.npmjs.org
|
||||
package-manager-cache: false
|
||||
|
||||
- name: 🚚 Install dependencies and build
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm build
|
||||
|
||||
- name: 🐙 Publish
|
||||
env:
|
||||
REF_NAME: ${{ github.ref_name }}
|
||||
run: |
|
||||
if [[ "$REF_NAME" =~ -(alpha|beta|rc)\. ]]; then
|
||||
pnpm publish --access public --tag "${BASH_REMATCH[1]}" -r --no-git-checks --provenance
|
||||
else
|
||||
pnpm publish --access public -r --no-git-checks --provenance
|
||||
fi
|
||||
191
.github/workflows/security-semgrep.yml
vendored
Normal file
191
.github/workflows/security-semgrep.yml
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
name: 🔐 Semgrep
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
semgrep:
|
||||
if: github.repository == 'dream-num/univer'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install Semgrep
|
||||
id: install-semgrep
|
||||
continue-on-error: true
|
||||
run: python -m pip install --upgrade pip semgrep
|
||||
|
||||
- name: Run Semgrep
|
||||
id: semgrep
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
env:
|
||||
INSTALL_OUTCOME: ${{ steps.install-semgrep.outcome }}
|
||||
run: |
|
||||
mkdir -p reports
|
||||
|
||||
if [ "$INSTALL_OUTCOME" = "success" ]; then
|
||||
set +e
|
||||
semgrep scan \
|
||||
--config auto \
|
||||
--sarif \
|
||||
--output reports/semgrep.sarif
|
||||
exit_code=$?
|
||||
set -e
|
||||
else
|
||||
exit_code=2
|
||||
fi
|
||||
|
||||
if [ ! -s reports/semgrep.sarif ]; then
|
||||
printf '%s\n' \
|
||||
'{' \
|
||||
' "version": "2.1.0",' \
|
||||
' "$schema": "https://json.schemastore.org/sarif-2.1.0.json",' \
|
||||
' "runs": [' \
|
||||
' {' \
|
||||
' "tool": {' \
|
||||
' "driver": {' \
|
||||
' "name": "Semgrep",' \
|
||||
' "informationUri": "https://semgrep.dev"' \
|
||||
' }' \
|
||||
' },' \
|
||||
' "invocations": [' \
|
||||
' {' \
|
||||
' "executionSuccessful": false,' \
|
||||
' "toolExecutionNotifications": [' \
|
||||
' {' \
|
||||
' "level": "error",' \
|
||||
' "message": {' \
|
||||
' "text": "Semgrep did not produce a SARIF report. Check the workflow logs for the setup or scan failure."' \
|
||||
' }' \
|
||||
' }' \
|
||||
' ]' \
|
||||
' }' \
|
||||
' ],' \
|
||||
' "results": []' \
|
||||
' }' \
|
||||
' ]' \
|
||||
'}' > reports/semgrep.sarif
|
||||
fi
|
||||
|
||||
echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload Semgrep SARIF to GitHub
|
||||
id: upload-sarif
|
||||
if: ${{ always() }}
|
||||
continue-on-error: true
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: reports/semgrep.sarif
|
||||
category: semgrep
|
||||
|
||||
- name: Upload Semgrep report artifact
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: semgrep-sarif-${{ github.run_id }}
|
||||
path: reports/semgrep.sarif
|
||||
if-no-files-found: error
|
||||
retention-days: 14
|
||||
|
||||
- name: Summarize Semgrep report
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
env:
|
||||
SEMGREP_EXIT_CODE: ${{ steps.semgrep.outputs.exit_code }}
|
||||
INSTALL_OUTCOME: ${{ steps.install-semgrep.outcome }}
|
||||
SARIF_UPLOAD_OUTCOME: ${{ steps.upload-sarif.outcome }}
|
||||
run: |
|
||||
python - <<'PY'
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
report_path = Path("reports/semgrep.sarif")
|
||||
with report_path.open() as file:
|
||||
sarif = json.load(file)
|
||||
|
||||
results = []
|
||||
for run in sarif.get("runs", []):
|
||||
results.extend(run.get("results", []))
|
||||
|
||||
counts = {"error": 0, "warning": 0, "note": 0, "other": 0}
|
||||
for result in results:
|
||||
level = result.get("level", "warning")
|
||||
counts[level if level in counts else "other"] += 1
|
||||
|
||||
sarif_upload_outcome = os.environ.get("SARIF_UPLOAD_OUTCOME") or "skipped"
|
||||
|
||||
with open(os.environ["GITHUB_STEP_SUMMARY"], "a", encoding="utf-8") as summary:
|
||||
summary.write("## Semgrep report\n")
|
||||
summary.write(f"- Total findings: {len(results)}\n")
|
||||
summary.write(f"- Error: {counts['error']}\n")
|
||||
summary.write(f"- Warning: {counts['warning']}\n")
|
||||
summary.write(f"- Note: {counts['note']}\n")
|
||||
summary.write(f"- Other: {counts['other']}\n")
|
||||
summary.write(f"- Exit code: {os.environ['SEMGREP_EXIT_CODE']}\n")
|
||||
summary.write(f"- Semgrep install: {os.environ['INSTALL_OUTCOME']}\n")
|
||||
summary.write("- Artifact: `semgrep-sarif-${{ github.run_id }}`\n")
|
||||
summary.write(f"- Code scanning upload: {sarif_upload_outcome}\n")
|
||||
PY
|
||||
|
||||
- name: Fail on Semgrep error findings or execution errors
|
||||
if: ${{ always() }}
|
||||
shell: bash
|
||||
env:
|
||||
SEMGREP_EXIT_CODE: ${{ steps.semgrep.outputs.exit_code }}
|
||||
run: |
|
||||
if [ -z "$SEMGREP_EXIT_CODE" ]; then
|
||||
echo "Semgrep exit code is missing."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ "$SEMGREP_EXIT_CODE" -ne 0 ]; then
|
||||
echo "Semgrep execution failed."
|
||||
echo "See the uploaded SARIF artifact for details."
|
||||
exit "$SEMGREP_EXIT_CODE"
|
||||
fi
|
||||
|
||||
python - <<'PY'
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
report_path = Path("reports/semgrep.sarif")
|
||||
with report_path.open() as file:
|
||||
sarif = json.load(file)
|
||||
|
||||
error_results = [
|
||||
result
|
||||
for run in sarif.get("runs", [])
|
||||
for result in run.get("results", [])
|
||||
if result.get("level") == "error"
|
||||
]
|
||||
|
||||
if error_results:
|
||||
print(f"Semgrep reported {len(error_results)} error-level finding(s).")
|
||||
print("See the uploaded SARIF artifact for details.")
|
||||
sys.exit(1)
|
||||
PY
|
||||
21
.github/workflows/sync-gitee-mirror.yml
vendored
Normal file
21
.github/workflows/sync-gitee-mirror.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: 🔮 Sync Mirror
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
if: github.repository == 'dream-num/univer'
|
||||
runs-on: minimum-runner
|
||||
steps:
|
||||
- name: Sync Gitee
|
||||
uses: jikkai/sync-gitee@main
|
||||
with:
|
||||
repository: dream-num/univer
|
||||
username: ${{ secrets.GITEE_USERNAME }}
|
||||
password: ${{ secrets.GITEE_PASSWORD }}
|
||||
tags: true
|
||||
branches: main dev
|
||||
25
.github/workflows/validate-pr-title.yml
vendored
Normal file
25
.github/workflows/validate-pr-title.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: 📌 Check PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
|
||||
permissions:
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: validate PR title
|
||||
if: github.repository == 'dream-num/univer' && !github.event.pull_request.draft
|
||||
runs-on: minimum-runner
|
||||
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
Reference in New Issue
Block a user