From cbe355cd391e149e15a9810d5dd984c030a70796 Mon Sep 17 00:00:00 2001 From: sunerpy Date: Wed, 23 Jul 2025 16:22:57 +0800 Subject: [PATCH 1/8] =?UTF-8?q?ci:=20=E9=87=8D=E6=9E=84=20GitHub=20Actions?= =?UTF-8?q?=20=E5=B7=A5=E4=BD=9C=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 pnpm-cache.yml 工作流,用于设置 pnpm 缓存 - 更新 CI、nightly、pr-check 等工作流,使用新的 pnpm 缓存设置 - 优化工作流中的步骤,减少重复代码 - 更新 release-please 配置,移除不必要的设置 - 新增 .release-please-config.json 文件,详细配置 release-please --- .github/workflows/ci.yml | 164 +++++++++++++-------------- .github/workflows/env.yml | 4 +- .github/workflows/github-release.yml | 6 +- .github/workflows/nightly.yml | 14 +-- .github/workflows/pnpm-cache.yml | 19 ++++ .github/workflows/pr-check.yml | 23 ++-- .github/workflows/release-please.yml | 3 - .husky/pre-commit | 5 +- .release-please-config.json | 51 +++++++-- .vscode/settings.json | 3 +- 10 files changed, 170 insertions(+), 122 deletions(-) create mode 100644 .github/workflows/pnpm-cache.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3a6249..d9f961c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,77 +2,78 @@ name: CI on: pull_request: - branches: [ main, master ] + branches: [main, master] push: - branches: [ main, master ] + branches: [main, master] jobs: get-env: uses: ./.github/workflows/env.yml + get-pnpm-cache: + uses: ./.github/workflows/pnpm-cache.yml test: name: Test runs-on: ${{ matrix.os }} - needs: get-env + needs: [get-env, get-pnpm-cache] strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ needs.get-env.outputs.node_version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check types - run: pnpm run check-types - - - name: Lint - run: pnpm run lint - - - name: Compile - run: pnpm run compile - - - name: Run tests - run: pnpm run test - - - name: Package extension - run: pnpm run package:vsix - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: vscode-syncing-${{ matrix.os }}-${{ needs.get-env.outputs.node_version }} - path: | - *.vsix - dist/ - retention-days: 7 + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js ${{ needs.get-env.outputs.node_version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ needs.get-env.outputs.node_version }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ needs.get-env.outputs.pnpm_version }} + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ needs.get-pnpm-cache.outputs.store_path }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check types + run: pnpm run check-types + + - name: Lint + run: pnpm run lint + + - name: Compile + run: pnpm run compile + + - name: Run tests + run: pnpm run test + + - name: Package extension + run: pnpm run package:vsix + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: vscode-syncing-${{ matrix.os }}-${{ needs.get-env.outputs.node_version }} + path: | + *.vsix + dist/ + retention-days: 7 security: name: Security Check @@ -81,29 +82,28 @@ jobs: if: github.event_name == 'pull_request' steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run security audit - run: pnpm audit --audit-level moderate - - - name: Check for secrets - uses: trufflesecurity/trufflehog@main - with: - path: . - base: ${{ github.event.pull_request.base.sha }} - head: ${{ github.event.pull_request.head.sha }} \ No newline at end of file + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ needs.get-env.outputs.node_version }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ needs.get-env.outputs.pnpm_version }} + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run security audit + run: pnpm audit --audit-level moderate + + - name: Check for secrets + uses: trufflesecurity/trufflehog@main + with: + path: . + base: ${{ github.event.pull_request.base.sha }} + head: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/env.yml b/.github/workflows/env.yml index e40838a..0974ee1 100644 --- a/.github/workflows/env.yml +++ b/.github/workflows/env.yml @@ -12,8 +12,8 @@ jobs: set-env: runs-on: ubuntu-latest outputs: - node_version: "22.13.0" - pnpm_version: "9.15.0" + node_version: '22.13.0' + pnpm_version: '9.15.0' steps: - name: Output env run: echo "Providing shared env values..." diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index ae79846..da9cdd0 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -3,11 +3,11 @@ name: GitHub Release on: push: tags: - - "v*" + - 'v*' workflow_dispatch: inputs: tag_name: - description: "Tag name to use for the release" + description: 'Tag name to use for the release' required: false jobs: @@ -56,7 +56,7 @@ jobs: - name: Upload Release uses: ncipollo/release-action@v1 with: - artifacts: "*.vsix" + artifacts: '*.vsix' token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ steps.version.outputs.version }} name: Release ${{ steps.version.outputs.version }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 80eca4f..15910fe 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -10,10 +10,13 @@ jobs: get-env: uses: ./.github/workflows/env.yml + get-pnpm-cache: + uses: ./.github/workflows/pnpm-cache.yml + nightly: name: Nightly Build runs-on: ubuntu-latest - needs: get-env + needs: [get-env, get-pnpm-cache] steps: - name: Checkout uses: actions/checkout@v4 @@ -28,15 +31,10 @@ jobs: with: version: ${{ needs.get-env.outputs.pnpm_version }} - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - name: Setup pnpm cache uses: actions/cache@v4 with: - path: ${{ env.STORE_PATH }} + path: ${{ needs.get-pnpm-cache.outputs.store_path }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- @@ -103,4 +101,4 @@ jobs: with: name: dependency-report-${{ github.sha }} path: dependency-report.md - retention-days: 30 \ No newline at end of file + retention-days: 30 diff --git a/.github/workflows/pnpm-cache.yml b/.github/workflows/pnpm-cache.yml new file mode 100644 index 0000000..142a836 --- /dev/null +++ b/.github/workflows/pnpm-cache.yml @@ -0,0 +1,19 @@ +name: PNPM Cache Setup + +on: + workflow_call: + outputs: + store_path: + value: ${{ jobs.setup-pnpm-cache.outputs.store_path }} + +jobs: + setup-pnpm-cache: + runs-on: ubuntu-latest + outputs: + store_path: ${{ steps.get-store-path.outputs.STORE_PATH }} + steps: + - name: Get pnpm store directory + id: get-store-path + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index aba94cc..5bd2685 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -8,10 +8,13 @@ jobs: get-env: uses: ./.github/workflows/env.yml + get-pnpm-cache: + uses: ./.github/workflows/pnpm-cache.yml + code-quality: name: Code Quality runs-on: ubuntu-latest - needs: get-env + needs: [get-env, get-pnpm-cache] steps: - name: Checkout uses: actions/checkout@v4 @@ -26,15 +29,10 @@ jobs: with: version: ${{ needs.get-env.outputs.pnpm_version }} - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - name: Setup pnpm cache uses: actions/cache@v4 with: - path: ${{ env.STORE_PATH }} + path: ${{ needs.get-pnpm-cache.outputs.store_path }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- @@ -115,7 +113,7 @@ jobs: build-test: name: Build Test runs-on: ${{ matrix.os }} - needs: get-env + needs: [get-env, get-pnpm-cache] strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -134,15 +132,10 @@ jobs: with: version: ${{ needs.get-env.outputs.pnpm_version }} - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - name: Setup pnpm cache uses: actions/cache@v4 with: - path: ${{ env.STORE_PATH }} + path: ${{ needs.get-pnpm-cache.outputs.store_path }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- @@ -190,4 +183,4 @@ jobs: path: | *.vsix dist/ - retention-days: 7 \ No newline at end of file + retention-days: 7 diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 132af08..240ca0b 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -22,9 +22,6 @@ jobs: uses: googleapis/release-please-action@v4 with: release-type: node - package-name: vscode-syncing - bump-minor-pre-major: true - changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Chores","hidden":false},{"type":"docs","section":"Documentation","hidden":false},{"type":"refactor","section":"Refactorings","hidden":false},{"type":"test","section":"Tests","hidden":false}]' token: ${{ secrets.GOOGLE_RELEASE_TOKEN }} config-file: .release-please-config.json diff --git a/.husky/pre-commit b/.husky/pre-commit index c37466e..dd92465 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,7 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" - +zsh_path=$(zsh -c 'source ~/.zshrc && echo $PATH') # 将 zsh 的 PATH 保存到一个变量 +export PATH="$zsh_path" +echo "zsh path ${PATH}" +PATH="/usr/local/bin:$PATH" npx lint-staged \ No newline at end of file diff --git a/.release-please-config.json b/.release-please-config.json index bc673cc..ffa124d 100644 --- a/.release-please-config.json +++ b/.release-please-config.json @@ -1,10 +1,47 @@ { - "release-type": "node", - "packages": { - ".": { - "package-name": "vscode-syncing", - "changelog-path": "CHANGELOG.md" - } + "release-type": "node", + "packages": { + ".": { + "package-name": "vscode-syncing", + "release-type": "node", + "include-component-in-tag": false, + "include-v-in-tag": true, + "bump-minor-pre-major": false, + "bump-patch-for-minor-pre-major": false, + "draft": false, + "changelog-types": [ + { + "type": "feat", + "section": "Features", + "hidden": false + }, + { + "type": "fix", + "section": "Bug Fixes", + "hidden": false + }, + { + "type": "chore", + "section": "Chores", + "hidden": false + }, + { + "type": "docs", + "section": "Documentation", + "hidden": false + }, + { + "type": "refactor", + "section": "Refactorings", + "hidden": false + }, + { + "type": "test", + "section": "Tests", + "hidden": false + } + ], + "changelog-path": "CHANGELOG.md" } } - \ No newline at end of file +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 5c5ac48..7ad7704 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,6 @@ "dist": true // set this to false to include "dist" folder in search results }, // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off" + "typescript.tsc.autoDetect": "off", + "github-actions.remote-name": "upstream" } \ No newline at end of file From c816fdc1f77185eb1100deef8e6204465b6b6af3 Mon Sep 17 00:00:00 2001 From: sunerpy Date: Wed, 23 Jul 2025 17:19:41 +0800 Subject: [PATCH 2/8] =?UTF-8?q?ci:=20=E9=87=8D=E6=9E=84=20GitHub=20Actions?= =?UTF-8?q?=20=E5=B7=A5=E4=BD=9C=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 build-test.yml、code-quality.yml 和 setup.yml 工作流文件 - 重构 ci.yml、nightly.yml 和 pr-check.yml,使用新的工作流文件 - 移除 env.yml 和 pnpm-cache.yml 工作流文件 - 更新工作流调用,使用新的输入参数和输出值 --- .github/workflows/build-test.yml | 75 +++++++++ .github/workflows/ci.yml | 90 ++--------- .github/workflows/code-quality.yml | 58 +++++++ .github/workflows/env.yml | 19 --- .github/workflows/nightly.yml | 147 +++++++---------- .github/workflows/pnpm-cache.yml | 19 --- .github/workflows/pr-check.yml | 187 +++------------------- .github/workflows/publish-marketplace.yml | 73 --------- .github/workflows/setup.yml | 57 +++++++ 9 files changed, 275 insertions(+), 450 deletions(-) create mode 100644 .github/workflows/build-test.yml create mode 100644 .github/workflows/code-quality.yml delete mode 100644 .github/workflows/env.yml delete mode 100644 .github/workflows/pnpm-cache.yml delete mode 100644 .github/workflows/publish-marketplace.yml create mode 100644 .github/workflows/setup.yml diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 0000000..c250f5b --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,75 @@ +name: Build and Test + +on: + workflow_call: + inputs: + node_version: + required: false + type: string + default: '22.13.0' + pnpm_version: + required: false + type: string + default: '9.15.0' + test_matrix: + required: false + type: string + default: '["ubuntu-latest"]' # 默认只在ubuntu上测试以节省资源 + outputs: + vsix_file: + value: ${{ jobs.build-test.outputs.vsix_file }} + +jobs: + build-test: + name: Build and Test + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: ${{ fromJSON(inputs.test_matrix) }} + outputs: + vsix_file: ${{ steps.verify-vsix.outputs.vsix_file }} + steps: + - name: Setup + uses: ./.github/workflows/setup.yml + with: + node_version: ${{ inputs.node_version }} + pnpm_version: ${{ inputs.pnpm_version }} + + - name: Compile + run: pnpm run compile + + - name: Run tests + run: pnpm run test + + - name: Package extension + run: pnpm run package:vsix + + - name: Verify VSIX on Linux/macOS + if: runner.os != 'Windows' + id: verify-vsix + shell: bash + run: | + set -e + VSIX_FILE=$(ls *.vsix 2>/dev/null || true) + if [ -z "$VSIX_FILE" ]; then + echo "❌ VSIX file not found" + exit 1 + fi + + echo "✅ VSIX file created: $VSIX_FILE" + ls -lh $VSIX_FILE + echo "vsix_file=$VSIX_FILE" >> $GITHUB_OUTPUT + + - name: Verify VSIX on Windows + if: runner.os == 'Windows' + id: verify-vsix-win + shell: pwsh + run: | + $vsix = Get-ChildItem -Filter *.vsix + if (-not $vsix) { + Write-Error "❌ VSIX file not found" + exit 1 + } + Write-Host "✅ VSIX file created: $($vsix.Name)" + Get-ChildItem *.vsix | Format-List + echo "vsix_file=$($vsix.Name)" >> $env:GITHUB_OUTPUT diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9f961c..b0f70ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,96 +7,24 @@ on: branches: [main, master] jobs: - get-env: - uses: ./.github/workflows/env.yml + code-quality: + name: Code Quality + uses: ./.github/workflows/code-quality.yml - get-pnpm-cache: - uses: ./.github/workflows/pnpm-cache.yml test: name: Test - runs-on: ${{ matrix.os }} - needs: [get-env, get-pnpm-cache] - - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ needs.get-env.outputs.node_version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ needs.get-pnpm-cache.outputs.store_path }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check types - run: pnpm run check-types - - - name: Lint - run: pnpm run lint - - - name: Compile - run: pnpm run compile - - - name: Run tests - run: pnpm run test - - - name: Package extension - run: pnpm run package:vsix - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: vscode-syncing-${{ matrix.os }}-${{ needs.get-env.outputs.node_version }} - path: | - *.vsix - dist/ - retention-days: 7 + uses: ./.github/workflows/build-test.yml + with: + test_matrix: '["ubuntu-latest", "windows-latest", "macos-latest"]' + secrets: inherit security: name: Security Check runs-on: ubuntu-latest - needs: get-env if: github.event_name == 'pull_request' - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Install dependencies - run: pnpm install --frozen-lockfile + - name: Setup + uses: ./.github/workflows/setup.yml - name: Run security audit run: pnpm audit --audit-level moderate diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 0000000..3d35b99 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,58 @@ +name: Code Quality + +on: + workflow_call: + inputs: + node_version: + required: false + type: string + default: '22.13.0' + pnpm_version: + required: false + type: string + default: '9.15.0' + +jobs: + code-quality: + name: Code Quality + runs-on: ubuntu-latest + steps: + - name: Setup + uses: ./.github/workflows/setup.yml + with: + node_version: ${{ inputs.node_version }} + pnpm_version: ${{ inputs.pnpm_version }} + + - name: Check types + run: pnpm run check-types + + - name: Lint + run: pnpm run lint + + - name: Check package.json + run: | + # 检查package.json格式 + node -e "JSON.parse(require('fs').readFileSync('package.json', 'utf8'))" + echo "✅ package.json is valid JSON" + + - name: Check for console.log statements + run: | + if grep -r "console\.log" src/; then + echo "❌ Found console.log statements in source code" + exit 1 + else + echo "✅ No console.log statements found" + fi + + - name: Check for TODO comments + run: | + if grep -r "TODO" src/; then + echo "⚠️ Found TODO comments in source code" + else + echo "✅ No TODO comments found" + fi + + - name: Check file sizes + run: | + echo "📊 Checking file sizes..." + find src/ -name "*.ts" -exec wc -l {} + | sort -nr | head -10 diff --git a/.github/workflows/env.yml b/.github/workflows/env.yml deleted file mode 100644 index 0974ee1..0000000 --- a/.github/workflows/env.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Shared Env Variables - -on: - workflow_call: - outputs: - node_version: - value: ${{ jobs.set-env.outputs.node_version }} - pnpm_version: - value: ${{ jobs.set-env.outputs.pnpm_version }} - -jobs: - set-env: - runs-on: ubuntu-latest - outputs: - node_version: '22.13.0' - pnpm_version: '9.15.0' - steps: - - name: Output env - run: echo "Providing shared env values..." diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 15910fe..c6fe6ff 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -7,98 +7,63 @@ on: workflow_dispatch: # 允许手动触发 jobs: - get-env: - uses: ./.github/workflows/env.yml - - get-pnpm-cache: - uses: ./.github/workflows/pnpm-cache.yml + build: + name: Nightly Build + uses: ./.github/workflows/build-test.yml + with: + test_matrix: '["ubuntu-latest"]' # 夜间构建只需要在ubuntu上测试 + secrets: inherit nightly: - name: Nightly Build + name: Nightly Tasks runs-on: ubuntu-latest - needs: [get-env, get-pnpm-cache] + needs: build steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ needs.get-pnpm-cache.outputs.store_path }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check types - run: pnpm run check-types - - - name: Lint - run: pnpm run lint - - - name: Compile - run: pnpm run compile - - - name: Run tests - run: pnpm run test - - - name: Package extension - run: pnpm run package:vsix - - - name: Generate build info - run: | - echo "Build Date: $(date)" > build-info.txt - echo "Commit: ${{ github.sha }}" >> build-info.txt - echo "Branch: ${{ github.ref_name }}" >> build-info.txt - echo "Node Version: $(node --version)" >> build-info.txt - echo "pnpm Version: $(pnpm --version)" >> build-info.txt - - - name: Upload nightly build - uses: actions/upload-artifact@v4 - with: - name: vscode-syncing-nightly-${{ needs.get-env.outputs.node_version }}-${{ github.sha }} - path: | - *.vsix - dist/ - build-info.txt - retention-days: 30 - - - name: Check for security vulnerabilities - run: | - echo "🔒 Running security audit..." - pnpm audit --audit-level moderate || echo "⚠️ Security vulnerabilities found" - - - name: Check for outdated dependencies - run: | - echo "📦 Checking for outdated dependencies..." - pnpm outdated || echo "✅ All dependencies are up to date" - - - name: Generate dependency report - run: | - echo "# Dependency Report" > dependency-report.md - echo "Generated on: $(date)" >> dependency-report.md - echo "" >> dependency-report.md - echo "## Outdated Dependencies" >> dependency-report.md - pnpm outdated >> dependency-report.md 2>&1 || echo "All dependencies are up to date" >> dependency-report.md - echo "" >> dependency-report.md - echo "## Security Audit" >> dependency-report.md - pnpm audit --audit-level moderate >> dependency-report.md 2>&1 || echo "No security issues found" >> dependency-report.md - - - name: Upload dependency report - uses: actions/upload-artifact@v4 - with: - name: dependency-report-${{ github.sha }} - path: dependency-report.md - retention-days: 30 + - name: Setup + uses: ./.github/workflows/setup.yml + + - name: Generate build info + run: | + echo "Build Date: $(date)" > build-info.txt + echo "Commit: ${{ github.sha }}" >> build-info.txt + echo "Branch: ${{ github.ref_name }}" >> build-info.txt + echo "Node Version: $(node --version)" >> build-info.txt + echo "pnpm Version: $(pnpm --version)" >> build-info.txt + + - name: Upload nightly build + uses: actions/upload-artifact@v4 + with: + name: vscode-syncing-nightly-${{ github.sha }} + path: | + *.vsix + dist/ + build-info.txt + retention-days: 30 + + - name: Check for security vulnerabilities + run: | + echo "🔒 Running security audit..." + pnpm audit --audit-level moderate || echo "⚠️ Security vulnerabilities found" + + - name: Check for outdated dependencies + run: | + echo "📦 Checking for outdated dependencies..." + pnpm outdated || echo "✅ All dependencies are up to date" + + - name: Generate dependency report + run: | + echo "# Dependency Report" > dependency-report.md + echo "Generated on: $(date)" >> dependency-report.md + echo "" >> dependency-report.md + echo "## Outdated Dependencies" >> dependency-report.md + pnpm outdated >> dependency-report.md 2>&1 || echo "All dependencies are up to date" >> dependency-report.md + echo "" >> dependency-report.md + echo "## Security Audit" >> dependency-report.md + pnpm audit --audit-level moderate >> dependency-report.md 2>&1 || echo "No security issues found" >> dependency-report.md + + - name: Upload dependency report + uses: actions/upload-artifact@v4 + with: + name: dependency-report-${{ github.sha }} + path: dependency-report.md + retention-days: 30 diff --git a/.github/workflows/pnpm-cache.yml b/.github/workflows/pnpm-cache.yml deleted file mode 100644 index 142a836..0000000 --- a/.github/workflows/pnpm-cache.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: PNPM Cache Setup - -on: - workflow_call: - outputs: - store_path: - value: ${{ jobs.setup-pnpm-cache.outputs.store_path }} - -jobs: - setup-pnpm-cache: - runs-on: ubuntu-latest - outputs: - store_path: ${{ steps.get-store-path.outputs.STORE_PATH }} - steps: - - name: Get pnpm store directory - id: get-store-path - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 5bd2685..cd24d10 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -2,185 +2,38 @@ name: PR Check on: pull_request: - branches: [ main, master ] + branches: [main, master] jobs: - get-env: - uses: ./.github/workflows/env.yml - - get-pnpm-cache: - uses: ./.github/workflows/pnpm-cache.yml - code-quality: name: Code Quality - runs-on: ubuntu-latest - needs: [get-env, get-pnpm-cache] - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ needs.get-pnpm-cache.outputs.store_path }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check types - run: pnpm run check-types - - - name: Lint - run: pnpm run lint - - - name: Check package.json - run: | - # 检查package.json格式 - node -e "JSON.parse(require('fs').readFileSync('package.json', 'utf8'))" - echo "✅ package.json is valid JSON" - - - name: Check for console.log statements - run: | - if grep -r "console\.log" src/; then - echo "❌ Found console.log statements in source code" - exit 1 - else - echo "✅ No console.log statements found" - fi - - - name: Check for TODO comments - run: | - if grep -r "TODO" src/; then - echo "⚠️ Found TODO comments in source code" - else - echo "✅ No TODO comments found" - fi - - - name: Check file sizes - run: | - echo "📊 Checking file sizes..." - find src/ -name "*.ts" -exec wc -l {} + | sort -nr | head -10 + uses: ./.github/workflows/code-quality.yml dependency-check: name: Dependency Check runs-on: ubuntu-latest - needs: get-env steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} + - name: Setup + uses: ./.github/workflows/setup.yml - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} + - name: Check for outdated dependencies + run: | + echo "📦 Checking for outdated dependencies..." + pnpm outdated || echo "✅ All dependencies are up to date" - - name: Install dependencies - run: pnpm install --frozen-lockfile + - name: Check for unused dependencies + run: | + echo "🔍 Checking for unused dependencies..." + npx depcheck || echo "⚠️ Some dependencies might be unused" - - name: Check for outdated dependencies - run: | - echo "📦 Checking for outdated dependencies..." - pnpm outdated || echo "✅ All dependencies are up to date" - - - name: Check for unused dependencies - run: | - echo "🔍 Checking for unused dependencies..." - npx depcheck || echo "⚠️ Some dependencies might be unused" - - - name: Security audit - run: | - echo "🔒 Running security audit..." - pnpm audit --audit-level moderate || echo "⚠️ Security vulnerabilities found" + - name: Security audit + run: | + echo "🔒 Running security audit..." + pnpm audit --audit-level moderate || echo "⚠️ Security vulnerabilities found" build-test: name: Build Test - runs-on: ${{ matrix.os }} - needs: [get-env, get-pnpm-cache] - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ needs.get-pnpm-cache.outputs.store_path }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Compile - run: pnpm run compile - - - name: Package extension - run: pnpm run package:vsix - - - name: Verify VSIX on Linux/macOS - if: runner.os != 'Windows' - shell: bash - run: | - set -e - VSIX_FILE=$(ls *.vsix 2>/dev/null || true) - if [ -z "$VSIX_FILE" ]; then - echo "❌ VSIX file not found" - exit 1 - fi - - echo "✅ VSIX file created: $VSIX_FILE" - ls -lh $VSIX_FILE - - - name: Verify VSIX on Windows - if: runner.os == 'Windows' - shell: pwsh - run: | - $vsix = Get-ChildItem -Filter *.vsix - if (-not $vsix) { - Write-Error "❌ VSIX file not found" - exit 1 - } - Write-Host "✅ VSIX file created: $($vsix.Name)" - Get-ChildItem *.vsix | Format-List - - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: vscode-syncing-${{ matrix.os }} - path: | - *.vsix - dist/ - retention-days: 7 + uses: ./.github/workflows/build-test.yml + with: + test_matrix: '["ubuntu-latest", "windows-latest", "macos-latest"]' + secrets: inherit diff --git a/.github/workflows/publish-marketplace.yml b/.github/workflows/publish-marketplace.yml deleted file mode 100644 index 7da33c1..0000000 --- a/.github/workflows/publish-marketplace.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Publish to Marketplace - -on: - push: - tags: - - "v*" - workflow_dispatch: - inputs: - tag_name: - description: "Tag name to publish" - required: false - -jobs: - get-env: - uses: ./.github/workflows/env.yml - - publish: - runs-on: ubuntu-latest - needs: get-env - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Get tag name - id: tag - run: | - TAG="${{ github.event.inputs.tag_name }}" - if [ -z "$TAG" ]; then - TAG=${GITHUB_REF#refs/tags/} - fi - echo "tag_name=$TAG" >> $GITHUB_OUTPUT - echo "Tag: $TAG" - - - name: Sync package.json version with tag - run: | - TAG=${{ steps.tag.outputs.tag_name }} - VERSION=$(node -p "require('./package.json').version") - TAG_VERSION=${TAG#v} - if [ "$TAG_VERSION" != "$VERSION" ]; then - echo "package.json version ($VERSION) 不等于 tag ($TAG_VERSION),自动覆盖..." - jq ".version = \"$TAG_VERSION\"" package.json > package.json.tmp && mv package.json.tmp package.json - cat package.json - else - echo "package.json version ($VERSION) 与 tag ($TAG_VERSION) 一致" - fi - - - name: Package VSIX - run: pnpm run package:vsix - - - name: Publish to VS Code Marketplace - env: - VSCODE_MARKETPLACE_TOKEN: ${{ secrets.VSCODE_MARKETPLACE_TOKEN }} - run: | - VSIX_FILE=$(ls *.vsix | head -n1) - if [ -n "$VSCODE_MARKETPLACE_TOKEN" ]; then - echo "Publishing $VSIX_FILE to VS Code Marketplace..." - npx @vscode/vsce publish --packagePath "$VSIX_FILE" -p "$VSCODE_MARKETPLACE_TOKEN" - else - echo "VSCODE_MARKETPLACE_TOKEN not set, skipping" - fi diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml new file mode 100644 index 0000000..ddbcacc --- /dev/null +++ b/.github/workflows/setup.yml @@ -0,0 +1,57 @@ +name: Setup + +on: + workflow_call: + inputs: + node_version: + required: false + type: string + default: '22.13.0' + pnpm_version: + required: false + type: string + default: '9.15.0' + outputs: + node_version: + value: ${{ inputs.node_version }} + pnpm_version: + value: ${{ inputs.pnpm_version }} + store_path: + value: ${{ jobs.setup.outputs.store_path }} + +jobs: + setup: + name: Setup + runs-on: ubuntu-latest + outputs: + store_path: ${{ steps.get-store-path.outputs.STORE_PATH }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node_version }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.pnpm_version }} + + - name: Get pnpm store directory + id: get-store-path + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.get-store-path.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile From e3f276b751904c2e026fa111902e0834cbf3cc8a Mon Sep 17 00:00:00 2001 From: sunerpy Date: Wed, 23 Jul 2025 17:52:18 +0800 Subject: [PATCH 3/8] =?UTF-8?q?ci:=20=E9=87=8D=E6=9E=84=20GitHub=20Actions?= =?UTF-8?q?=20=E5=B7=A5=E4=BD=9C=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除各工作流中的重复 setup 步骤 - 新增单独的 setup 工作流,统一处理环境配置 - 更新工作流之间的依赖关系,确保按顺序执行 - 为发布到 Marketplace 添加新的工作流 --- .github/workflows/build-test.yml | 11 ----- .github/workflows/ci.yml | 10 ++-- .github/workflows/code-quality.yml | 12 ----- .github/workflows/github-release.yml | 23 ++------- .github/workflows/nightly.yml | 10 ++-- .github/workflows/pr-check.yml | 10 ++-- .github/workflows/publish-marketplace.yml | 58 +++++++++++++++++++++++ 7 files changed, 82 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/publish-marketplace.yml diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index c250f5b..b828958 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -3,14 +3,6 @@ name: Build and Test on: workflow_call: inputs: - node_version: - required: false - type: string - default: '22.13.0' - pnpm_version: - required: false - type: string - default: '9.15.0' test_matrix: required: false type: string @@ -31,9 +23,6 @@ jobs: steps: - name: Setup uses: ./.github/workflows/setup.yml - with: - node_version: ${{ inputs.node_version }} - pnpm_version: ${{ inputs.pnpm_version }} - name: Compile run: pnpm run compile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0f70ce..aadbfe4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,12 +7,18 @@ on: branches: [main, master] jobs: + setup: + name: Setup + uses: ./.github/workflows/setup.yml + code-quality: name: Code Quality + needs: setup uses: ./.github/workflows/code-quality.yml test: name: Test + needs: setup uses: ./.github/workflows/build-test.yml with: test_matrix: '["ubuntu-latest", "windows-latest", "macos-latest"]' @@ -21,11 +27,9 @@ jobs: security: name: Security Check runs-on: ubuntu-latest + needs: setup if: github.event_name == 'pull_request' steps: - - name: Setup - uses: ./.github/workflows/setup.yml - - name: Run security audit run: pnpm audit --audit-level moderate diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 3d35b99..b559bf1 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -2,15 +2,6 @@ name: Code Quality on: workflow_call: - inputs: - node_version: - required: false - type: string - default: '22.13.0' - pnpm_version: - required: false - type: string - default: '9.15.0' jobs: code-quality: @@ -19,9 +10,6 @@ jobs: steps: - name: Setup uses: ./.github/workflows/setup.yml - with: - node_version: ${{ inputs.node_version }} - pnpm_version: ${{ inputs.pnpm_version }} - name: Check types run: pnpm run check-types diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index da9cdd0..daa0579 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -11,33 +11,18 @@ on: required: false jobs: - get-env: - uses: ./.github/workflows/env.yml + setup: + name: Setup + uses: ./.github/workflows/setup.yml release: name: GitHub Release runs-on: ubuntu-latest - needs: get-env + needs: setup outputs: version: ${{ steps.version.outputs.version }} steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ needs.get-env.outputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ needs.get-env.outputs.pnpm_version }} - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - name: Compile run: pnpm run compile diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c6fe6ff..f74c3b4 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -7,8 +7,13 @@ on: workflow_dispatch: # 允许手动触发 jobs: + setup: + name: Setup + uses: ./.github/workflows/setup.yml + build: name: Nightly Build + needs: setup uses: ./.github/workflows/build-test.yml with: test_matrix: '["ubuntu-latest"]' # 夜间构建只需要在ubuntu上测试 @@ -17,11 +22,8 @@ jobs: nightly: name: Nightly Tasks runs-on: ubuntu-latest - needs: build + needs: [build, setup] steps: - - name: Setup - uses: ./.github/workflows/setup.yml - - name: Generate build info run: | echo "Build Date: $(date)" > build-info.txt diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index cd24d10..941f8ca 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -5,17 +5,20 @@ on: branches: [main, master] jobs: + setup: + name: Setup + uses: ./.github/workflows/setup.yml + code-quality: name: Code Quality + needs: setup uses: ./.github/workflows/code-quality.yml dependency-check: name: Dependency Check runs-on: ubuntu-latest + needs: setup steps: - - name: Setup - uses: ./.github/workflows/setup.yml - - name: Check for outdated dependencies run: | echo "📦 Checking for outdated dependencies..." @@ -33,6 +36,7 @@ jobs: build-test: name: Build Test + needs: setup uses: ./.github/workflows/build-test.yml with: test_matrix: '["ubuntu-latest", "windows-latest", "macos-latest"]' diff --git a/.github/workflows/publish-marketplace.yml b/.github/workflows/publish-marketplace.yml new file mode 100644 index 0000000..53fd18a --- /dev/null +++ b/.github/workflows/publish-marketplace.yml @@ -0,0 +1,58 @@ +name: Publish to Marketplace + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag_name: + description: "Tag name to publish" + required: false + +jobs: + setup: + name: Setup + uses: ./.github/workflows/setup.yml + + publish: + runs-on: ubuntu-latest + needs: setup + steps: + - name: Get tag name + id: tag + run: | + TAG="${{ github.event.inputs.tag_name }}" + if [ -z "$TAG" ]; then + TAG=${GITHUB_REF#refs/tags/} + fi + echo "tag_name=$TAG" >> $GITHUB_OUTPUT + echo "Tag: $TAG" + + - name: Sync package.json version with tag + run: | + TAG=${{ steps.tag.outputs.tag_name }} + VERSION=$(node -p "require('./package.json').version") + TAG_VERSION=${TAG#v} + if [ "$TAG_VERSION" != "$VERSION" ]; then + echo "package.json version ($VERSION) 不等于 tag ($TAG_VERSION),自动覆盖..." + jq ".version = \"$TAG_VERSION\"" package.json > package.json.tmp && mv package.json.tmp package.json + cat package.json + else + echo "package.json version ($VERSION) 与 tag ($TAG_VERSION) 一致" + fi + + - name: Package VSIX + run: pnpm run package:vsix + + - name: Publish to VS Code Marketplace + env: + VSCODE_MARKETPLACE_TOKEN: ${{ secrets.VSCODE_MARKETPLACE_TOKEN }} + run: | + VSIX_FILE=$(ls *.vsix | head -n1) + if [ -n "$VSCODE_MARKETPLACE_TOKEN" ]; then + echo "Publishing $VSIX_FILE to VS Code Marketplace..." + npx @vscode/vsce publish --packagePath "$VSIX_FILE" -p "$VSCODE_MARKETPLACE_TOKEN" + else + echo "VSCODE_MARKETPLACE_TOKEN not set, skipping" + fi From 6ef29d910d8d2ee33962d9aeb6f03680bddd24e6 Mon Sep 17 00:00:00 2001 From: sunerpy Date: Wed, 23 Jul 2025 17:57:07 +0800 Subject: [PATCH 4/8] =?UTF-8?q?ci:=20=E9=87=8D=E6=9E=84=20GitHub=20Actions?= =?UTF-8?q?=20=E5=B7=A5=E4=BD=9C=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 build-test.yml 和 code-quality.yml 中添加 setup 作业 - 使用 workflow_call 方式调用 setup.yml - 优化工作流结构,提高可维护性 --- .github/workflows/build-test.yml | 8 +++++--- .github/workflows/code-quality.yml | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index b828958..bb54bbd 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -12,18 +12,20 @@ on: value: ${{ jobs.build-test.outputs.vsix_file }} jobs: + setup: + name: Setup + uses: ./.github/workflows/setup.yml + build-test: name: Build and Test runs-on: ${{ matrix.os }} + needs: setup strategy: matrix: os: ${{ fromJSON(inputs.test_matrix) }} outputs: vsix_file: ${{ steps.verify-vsix.outputs.vsix_file }} steps: - - name: Setup - uses: ./.github/workflows/setup.yml - - name: Compile run: pnpm run compile diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index b559bf1..97581cd 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -4,13 +4,15 @@ on: workflow_call: jobs: + setup: + name: Setup + uses: ./.github/workflows/setup.yml + code-quality: name: Code Quality runs-on: ubuntu-latest + needs: setup steps: - - name: Setup - uses: ./.github/workflows/setup.yml - - name: Check types run: pnpm run check-types From 382c28aa817db1123f3975924b1b0304757f1ddf Mon Sep 17 00:00:00 2001 From: sunerpy Date: Wed, 23 Jul 2025 23:38:48 +0800 Subject: [PATCH 5/8] =?UTF-8?q?ci:=20=E9=87=8D=E6=9E=84=20GitHub=20Actions?= =?UTF-8?q?=20=E5=B7=A5=E4=BD=9C=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Setup Node.js and pnpm 复合操作,用于统一配置 Node.js 和 pnpm - 更新所有工作流文件,使用新的 Setup Node.js and pnpm 复合操作 - 移除单独的 setup 任务,直接在每个工作流中配置环境 - 优化工作流结构,提高可维护性和可读性 --- .github/actions/setup-node-pnpm/action.yml | 48 ++++++++++++++++++ .github/workflows/build-test.yml | 11 +++-- .github/workflows/ci.yml | 13 +++-- .github/workflows/code-quality.yml | 11 +++-- .github/workflows/github-release.yml | 12 ++--- .github/workflows/nightly.yml | 13 ++--- .github/workflows/pr-check.yml | 13 +++-- .github/workflows/publish-marketplace.yml | 11 +++-- .github/workflows/setup.yml | 57 ---------------------- 9 files changed, 91 insertions(+), 98 deletions(-) create mode 100644 .github/actions/setup-node-pnpm/action.yml delete mode 100644 .github/workflows/setup.yml diff --git a/.github/actions/setup-node-pnpm/action.yml b/.github/actions/setup-node-pnpm/action.yml new file mode 100644 index 0000000..52470be --- /dev/null +++ b/.github/actions/setup-node-pnpm/action.yml @@ -0,0 +1,48 @@ +name: 'Setup Node.js and pnpm' +description: 'Setup Node.js, pnpm, and install dependencies' + +inputs: + node_version: + description: 'Node.js version' + required: false + default: '22.13.0' + pnpm_version: + description: 'pnpm version' + required: false + default: '9.15.0' + +outputs: + store_path: + description: 'pnpm store path' + value: ${{ steps.get-store-path.outputs.STORE_PATH }} + +runs: + using: 'composite' + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node_version }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.pnpm_version }} + + - name: Get pnpm store directory + id: get-store-path + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.get-store-path.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + shell: bash + run: pnpm install --frozen-lockfile diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index bb54bbd..963f009 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -12,20 +12,21 @@ on: value: ${{ jobs.build-test.outputs.vsix_file }} jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - build-test: name: Build and Test runs-on: ${{ matrix.os }} - needs: setup strategy: matrix: os: ${{ fromJSON(inputs.test_matrix) }} outputs: vsix_file: ${{ steps.verify-vsix.outputs.vsix_file }} steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Compile run: pnpm run compile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aadbfe4..7c9d49a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,18 +7,12 @@ on: branches: [main, master] jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - code-quality: name: Code Quality - needs: setup uses: ./.github/workflows/code-quality.yml test: name: Test - needs: setup uses: ./.github/workflows/build-test.yml with: test_matrix: '["ubuntu-latest", "windows-latest", "macos-latest"]' @@ -27,9 +21,14 @@ jobs: security: name: Security Check runs-on: ubuntu-latest - needs: setup if: github.event_name == 'pull_request' steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Run security audit run: pnpm audit --audit-level moderate diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 97581cd..b82dc79 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -4,15 +4,16 @@ on: workflow_call: jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - code-quality: name: Code Quality runs-on: ubuntu-latest - needs: setup steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Check types run: pnpm run check-types diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index daa0579..073211a 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -11,18 +11,18 @@ on: required: false jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - release: name: GitHub Release runs-on: ubuntu-latest - needs: setup outputs: version: ${{ steps.version.outputs.version }} - steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Compile run: pnpm run compile diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f74c3b4..53c5c4c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -7,13 +7,8 @@ on: workflow_dispatch: # 允许手动触发 jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - build: name: Nightly Build - needs: setup uses: ./.github/workflows/build-test.yml with: test_matrix: '["ubuntu-latest"]' # 夜间构建只需要在ubuntu上测试 @@ -22,8 +17,14 @@ jobs: nightly: name: Nightly Tasks runs-on: ubuntu-latest - needs: [build, setup] + needs: build steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Generate build info run: | echo "Build Date: $(date)" > build-info.txt diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 941f8ca..9fccacb 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -5,20 +5,20 @@ on: branches: [main, master] jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - code-quality: name: Code Quality - needs: setup uses: ./.github/workflows/code-quality.yml dependency-check: name: Dependency Check runs-on: ubuntu-latest - needs: setup steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Check for outdated dependencies run: | echo "📦 Checking for outdated dependencies..." @@ -36,7 +36,6 @@ jobs: build-test: name: Build Test - needs: setup uses: ./.github/workflows/build-test.yml with: test_matrix: '["ubuntu-latest", "windows-latest", "macos-latest"]' diff --git a/.github/workflows/publish-marketplace.yml b/.github/workflows/publish-marketplace.yml index 53fd18a..75d6d20 100644 --- a/.github/workflows/publish-marketplace.yml +++ b/.github/workflows/publish-marketplace.yml @@ -11,14 +11,15 @@ on: required: false jobs: - setup: - name: Setup - uses: ./.github/workflows/setup.yml - publish: runs-on: ubuntu-latest - needs: setup steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js and pnpm + uses: ./.github/actions/setup-node-pnpm + - name: Get tag name id: tag run: | diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml deleted file mode 100644 index ddbcacc..0000000 --- a/.github/workflows/setup.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Setup - -on: - workflow_call: - inputs: - node_version: - required: false - type: string - default: '22.13.0' - pnpm_version: - required: false - type: string - default: '9.15.0' - outputs: - node_version: - value: ${{ inputs.node_version }} - pnpm_version: - value: ${{ inputs.pnpm_version }} - store_path: - value: ${{ jobs.setup.outputs.store_path }} - -jobs: - setup: - name: Setup - runs-on: ubuntu-latest - outputs: - store_path: ${{ steps.get-store-path.outputs.STORE_PATH }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ inputs.node_version }} - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ inputs.pnpm_version }} - - - name: Get pnpm store directory - id: get-store-path - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ steps.get-store-path.outputs.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile From b6b1e2387764bb773985b288ec716038b16b6beb Mon Sep 17 00:00:00 2001 From: sunerpy Date: Thu, 24 Jul 2025 16:04:48 +0800 Subject: [PATCH 6/8] =?UTF-8?q?feat(sync):=20=E4=BC=98=E5=8C=96GitHub?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=80=BB=E8=BE=91=E5=B9=B6=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将认证头抽离为统一方法以减少重复代码 - 添加对Gist创建响应信息的详细日志输出 - 提取获取文件SHA逻辑为独立方法,提升可读性和复用性 - 增强GitHub API错误处理的健壮性 - 在.vscode配置中添加Node.js路径以支持特定开发环境 - 修复esbuild任务匹配器为tsc-watch以支持TS错误识别 - 添加packageManager字段以确保pnpm一致性 --- .gitignore | 1 + .vscode/settings.json | 3 + .vscode/tasks.json | 2 +- package.json | 3 +- src/githubService.ts | 196 ++++++++++++++++++++++-------------------- src/syncManager.ts | 4 +- 6 files changed, 115 insertions(+), 94 deletions(-) diff --git a/.gitignore b/.gitignore index 0dfb59a..a693147 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.vscode out dist node_modules diff --git a/.vscode/settings.json b/.vscode/settings.json index 7ad7704..869b9da 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,8 @@ }, // Turn off tsc task auto detection since we have the necessary tasks as npm scripts "typescript.tsc.autoDetect": "off", + "terminal.integrated.env.linux": { + "PATH": "/config/.asdf/installs/nodejs/22.13.0/bin:${env:PATH}" + }, "github-actions.remote-name": "upstream" } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3cf99c3..a0c9b0c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -21,7 +21,7 @@ "type": "npm", "script": "watch:esbuild", "group": "build", - "problemMatcher": "$esbuild-watch", + "problemMatcher": "$tsc-watch", "isBackground": true, "label": "npm: watch:esbuild", "presentation": { diff --git a/package.json b/package.json index b080a47..269d133 100644 --- a/package.json +++ b/package.json @@ -167,5 +167,6 @@ "npm-run-all": "^4.1.5", "prettier": "3.6.2", "typescript": "^5.8.3" - } + }, + "packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a" } diff --git a/src/githubService.ts b/src/githubService.ts index 60be943..867756f 100644 --- a/src/githubService.ts +++ b/src/githubService.ts @@ -1,6 +1,13 @@ import * as vscode from 'vscode'; import { API_BASE_URL } from './constants'; +// ===== 常量定义 ===== +const GITHUB_ACCEPT_HEADER = 'application/vnd.github.v3+json'; +const CONTENT_TYPE_JSON = 'application/json'; +const DEFAULT_GIST_DESCRIPTION = 'VSCode 配置同步'; +const DEFAULT_COMMIT_MESSAGE = '自动同步配置'; + +// ===== 接口定义 ===== interface GistResponse { id: string; html_url: string; @@ -20,6 +27,10 @@ interface GistBody { public?: boolean; } +interface FileDataResponse { + sha?: string; +} + export class GitHubService { private readonly baseUrl = API_BASE_URL; @@ -33,124 +44,78 @@ export class GitHubService { const method = gistId ? 'PATCH' : 'POST'; const body: GistBody = { - description: `VSCode 配置同步 - ${new Date().toLocaleString()}`, + description: `${DEFAULT_GIST_DESCRIPTION} - ${new Date().toLocaleString()}`, files: { [fileName]: { - content: content, + content, }, }, + public: false, }; - if (!gistId) { - body.public = false; - } + const headers = this.getAuthHeaders(token, CONTENT_TYPE_JSON); - const response = await fetch(url, { - method: method, - headers: { - Authorization: `token ${token}`, - Accept: 'application/vnd.github.v3+json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), - }); + try { + const response = await fetch(url, { + method, + headers, + body: JSON.stringify(body), + }); - if (!response.ok) { - const error = await response.text(); - throw new Error(`GitHub API 错误: ${response.status} - ${error}`); - } + // 获取响应头信息 + const responseHeaders: Record = {}; + response.headers.forEach((value, key) => { + responseHeaders[key] = value; + }); + + await this.handleGitHubError(response); - const result = (await response.json()) as GistResponse; + const result = (await response.json()) as GistResponse; - // 如果是新创建的Gist,保存ID - if (!gistId && result.id) { - const config = vscode.workspace.getConfiguration('vscode-syncing'); - await config.update('gistId', result.id, vscode.ConfigurationTarget.Global); - vscode.window.showInformationMessage(`新的Gist已创建,ID: ${result.id}`); + if (!gistId && result.id) { + await this.saveGistIdToConfig(result.id); + } + + return result; + } catch (error) { + throw error; } - return result; } + // 更新仓库文件 async updateRepository( token: string, repoName: string, branch: string, fileName: string, content: string, - commitMessage: string, + commitMessage: string = DEFAULT_COMMIT_MESSAGE, ): Promise { - try { - // 获取文件的当前SHA(如果存在) - const fileUrl = `${this.baseUrl}/repos/${repoName}/contents/${fileName}?ref=${branch}`; - let sha: string | undefined; - - try { - const fileResponse = await fetch(fileUrl, { - headers: { - Authorization: `token ${token}`, - Accept: 'application/vnd.github.v3+json', - }, - }); - - if (fileResponse.ok) { - const fileData = await fileResponse.json(); - if ( - typeof fileData === 'object' && - fileData !== null && - 'sha' in fileData && - typeof fileData.sha === 'string' - ) { - sha = fileData.sha; - } - } - } catch (error) { - // 文件不存在,这是正常的 - } - - // 更新或创建文件 - interface RepoUpdateBody { - message: string; - content: string; - branch: string; - sha?: string; - } - const updateUrl = `${this.baseUrl}/repos/${repoName}/contents/${fileName}`; - const body: RepoUpdateBody = { - message: commitMessage, - content: Buffer.from(content).toString('base64'), - branch: branch, - }; - - if (sha) { - body.sha = sha; - } + const fileUrl = `${this.baseUrl}/repos/${repoName}/contents/${fileName}?ref=${branch}`; + const sha = await this.getFileSha(token, fileUrl); + + const updateUrl = `${this.baseUrl}/repos/${repoName}/contents/${fileName}`; + const body = { + message: commitMessage, + content: Buffer.from(content).toString('base64'), + branch, + ...(sha && { sha }), + }; - const response = await fetch(updateUrl, { - method: 'PUT', - headers: { - Authorization: `token ${token}`, - Accept: 'application/vnd.github.v3+json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), - }); + const response = await fetch(updateUrl, { + method: 'PUT', + headers: this.getAuthHeaders(token, CONTENT_TYPE_JSON), + body: JSON.stringify(body), + }); - if (!response.ok) { - const error = await response.text(); - throw new Error(`GitHub API 错误: ${response.status} - ${error}`); - } - } catch (error) { - throw new Error(`更新仓库失败: ${error}`); - } + await this.handleGitHubError(response); } + // 测试连接 async testConnection(token: string): Promise { try { const response = await fetch(`${this.baseUrl}/user`, { - headers: { - Authorization: `token ${token}`, - Accept: 'application/vnd.github.v3+json', - }, + headers: this.getAuthHeaders(token), }); return response.ok; @@ -158,4 +123,53 @@ export class GitHubService { return false; } } + + // ===== 私有辅助方法 ===== + + private getAuthHeaders(token: string, contentType?: string): Record { + const headers: Record = { + Authorization: `token ${token}`, + Accept: GITHUB_ACCEPT_HEADER, + }; + + if (contentType) { + headers['Content-Type'] = contentType; + } + + return headers; + } + + private async getFileSha(token: string, fileUrl: string): Promise { + try { + const response = await fetch(fileUrl, { + headers: this.getAuthHeaders(token), + }); + + if (!response.ok) { + return undefined; + } + + const fileData = (await response.json()) as FileDataResponse; + + return typeof fileData === 'object' && fileData !== null && 'sha' in fileData + ? (fileData.sha as string) + : undefined; + } catch (error) { + console.warn('获取文件 SHA 时出错:', error); + return undefined; + } + } + + private async handleGitHubError(response: Response): Promise { + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`GitHub API 错误: ${response.status} - ${errorText}`); + } + } + + private async saveGistIdToConfig(gistId: string): Promise { + const config = vscode.workspace.getConfiguration('vscode-syncing'); + await config.update('gistId', gistId, vscode.ConfigurationTarget.Global); + vscode.window.showInformationMessage(`新的 Gist 已创建,ID: ${gistId}`); + } } diff --git a/src/syncManager.ts b/src/syncManager.ts index 344ce3c..3ae78c6 100644 --- a/src/syncManager.ts +++ b/src/syncManager.ts @@ -709,7 +709,9 @@ export class SyncManager { fileName, JSON.stringify(data, null, 2), ); - this.outputChannel.appendLine(`Gist导出成功: ${gist.html_url}`); + this.outputChannel.appendLine( + `Gist导出成功: ${gist.html_url} resp: ${JSON.stringify(gist, null, 2)}`, + ); return gist.html_url; } From 51cf5b178d0d3e88914a3860c3dbbfa4b3a20a90 Mon Sep 17 00:00:00 2001 From: sunerpy Date: Thu, 24 Jul 2025 16:14:13 +0800 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20pnpm=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=B9=B6=E4=BC=98=E5=8C=96=20Gist=20?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/actions/setup-node-pnpm/action.yml | 2 +- src/syncManager.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/actions/setup-node-pnpm/action.yml b/.github/actions/setup-node-pnpm/action.yml index 52470be..59de4ee 100644 --- a/.github/actions/setup-node-pnpm/action.yml +++ b/.github/actions/setup-node-pnpm/action.yml @@ -9,7 +9,7 @@ inputs: pnpm_version: description: 'pnpm version' required: false - default: '9.15.0' + default: '9.4.0' outputs: store_path: diff --git a/src/syncManager.ts b/src/syncManager.ts index 3ae78c6..344ce3c 100644 --- a/src/syncManager.ts +++ b/src/syncManager.ts @@ -709,9 +709,7 @@ export class SyncManager { fileName, JSON.stringify(data, null, 2), ); - this.outputChannel.appendLine( - `Gist导出成功: ${gist.html_url} resp: ${JSON.stringify(gist, null, 2)}`, - ); + this.outputChannel.appendLine(`Gist导出成功: ${gist.html_url}`); return gist.html_url; } From c7ec8d6d8a86054dfa87e78fe832f1ee2ed27b42 Mon Sep 17 00:00:00 2001 From: sunerpy Date: Thu, 24 Jul 2025 16:16:00 +0800 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=20pnpm=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除了 setup-node-pnpm action 中的 pnpm 版本设置,以简化配置并使用默认版本。 --- .github/actions/setup-node-pnpm/action.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/actions/setup-node-pnpm/action.yml b/.github/actions/setup-node-pnpm/action.yml index 59de4ee..da518ae 100644 --- a/.github/actions/setup-node-pnpm/action.yml +++ b/.github/actions/setup-node-pnpm/action.yml @@ -26,8 +26,6 @@ runs: - name: Setup pnpm uses: pnpm/action-setup@v4 - with: - version: ${{ inputs.pnpm_version }} - name: Get pnpm store directory id: get-store-path