mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 06:30:10 +08:00
* ♻️ refactor: implement config-based update system with version compatibility control Replace GitHub API-based update discovery with JSON config file system. Support version gating (users below v1.7 must upgrade to v1.7.0 before v2.0). Auto-select GitHub/GitCode config source based on IP location. Simplify fallback logic. Changes: - Add update-config.json with version compatibility rules - Implement _fetchUpdateConfig() and _findCompatibleChannel() - Remove legacy _getReleaseVersionFromGithub() and GitHub API dependency - Refactor _setFeedUrl() with simplified fallback to default feed URLs - Add design documentation in docs/UPDATE_CONFIG_DESIGN.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(i18n): Auto update translations for PR #11147 * format code * 🔧 chore: update config for v1.7.5 → v2.0.0 → v2.1.6 upgrade path Update version configuration to support multi-step upgrade path: - v1.6.x users → v1.7.5 (last v1.x release) - v1.7.x users → v2.0.0 (v2.x intermediate version) - v2.0.0+ users → v2.1.6 (current latest) Changes: - Update 1.7.0 → 1.7.5 with fixed feedUrl - Set 2.0.0 as intermediate version with fixed feedUrl - Add 2.1.6 as current latest pointing to releases/latest This ensures users upgrade through required intermediate versions before jumping to major releases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * 🔧 chore: refactor update config with constants and adjust versions Refactor update configuration system and adjust to actual versions: - Add UpdateConfigUrl enum in constant.ts for centralized config URLs - Point to test server (birdcat.top) for development testing - Update AppUpdater.ts to use UpdateConfigUrl constants - Adjust update-config.json to actual v1.6.7 with rc/beta channels - Remove v2.1.6 entry (not yet released) - Set package version to 1.6.5 for testing upgrade path - Add update-config.example.json for reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * update version * ✅ test: add comprehensive unit tests for AppUpdater config system Add extensive test coverage for new config-based update system including: - Config fetching with IP-based source selection (GitHub/GitCode) - Channel compatibility matching with version constraints - Smart fallback from rc/beta to latest when appropriate - Multi-step upgrade path validation (1.6.3 → 1.6.7 → 2.0.0) - Error handling for network and HTTP failures Test Coverage: - _fetchUpdateConfig: 4 tests (GitHub/GitCode selection, error handling) - _findCompatibleChannel: 9 tests (channel matching, version comparison) - Upgrade Path: 3 tests (version gating scenarios) - Total: 30 tests, 100% passing Also optimize _findCompatibleChannel logic with better variable naming and log messages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * ✅ test: add complete multi-step upgrade path tests (1.6.3 → 1.7.5 → 2.0.0 → 2.1.6) Add comprehensive test suite for complete upgrade journey including: - Individual step validation (1.6.3→1.7.5, 1.7.5→2.0.0, 2.0.0→2.1.6) - Full multi-step upgrade simulation with version progression - Version gating enforcement (block skipping intermediate versions) - Verification that 1.6.3 cannot directly upgrade to 2.0.0 or 2.1.6 - Verification that 1.7.5 cannot skip 2.0.0 to reach 2.1.6 Test Coverage: - 6 new tests for complete upgrade path scenarios - Total: 36 tests, 100% passing This ensures the version compatibility system correctly enforces intermediate version upgrades for major releases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * 📝 docs: reorganize update config documentation with English translation Move update configuration design document to docs/technical/ directory and add English translation for international contributors. Changes: - Move docs/UPDATE_CONFIG_DESIGN.md → docs/technical/app-update-config-zh.md - Add docs/technical/app-update-config-en.md (English translation) - Organize technical documentation in dedicated directory Documentation covers: - Config-based update system design and rationale - JSON schema with version compatibility control - Multi-step upgrade path examples (1.6.3 → 1.7.5 → 2.0.0 → 2.1.6) - TypeScript type definitions and matching algorithms - GitHub/GitCode source selection for different regions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * format code * ✅ test: add tests for latest channel self-comparison prevention Add tests to verify the optimization that prevents comparing latest channel with itself when latest is requested, and ensures rc/beta channels are returned when they are newer than latest. New tests: - should not compare latest with itself when requesting latest channel - should return rc when rc version > latest version - should return beta when beta version > latest version These tests ensure the requestedChannel !== UpgradeChannel.LATEST check works correctly and users get the right channel based on version comparisons. Test Coverage: 39 tests, 100% passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * update github/gitcode * format code * update rc version * ♻️ refactor: merge update configs into single multi-mirror file - Merge app-upgrade-config-github.json and app-upgrade-config-gitcode.json into single app-upgrade-config.json - Add UpdateMirror enum for type-safe mirror selection - Optimize _fetchUpdateConfig to receive mirror parameter, eliminating duplicate IP country checks - Update ChannelConfig interface to use Record<UpdateMirror, string> for feedUrls - Rename documentation files from app-update-config-* to app-upgrade-config-* - Update docs with new multi-mirror configuration structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * ✅ test: update AppUpdater tests for multi-mirror configuration - Add UpdateMirror enum import - Update _fetchUpdateConfig tests to accept mirror parameter - Convert all feedUrl to feedUrls structure in test mocks - Update test expectations to match new ChannelConfig interface - All 39 tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * format code * delete files * 📝 docs: add UpdateMirror enum to type definitions - Add UpdateMirror enum definition in both EN and ZH docs - Update ChannelConfig to use Record<UpdateMirror, string> - Add comments showing equivalent structure for clarity 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * 🐛 fix: return actual channel from _findCompatibleChannel Fix channel mismatch issue where requesting rc/beta but getting latest: - Change _findCompatibleChannel return type to include actual channel - Return { config, channel } instead of just config - Update _setFeedUrl to use actualChannel instead of requestedChannel - Update all test expectations to match new return structure - Add channel assertions to key tests This ensures autoUpdater.channel matches the actual feed URL being used. Fixes issue where: - User requests 'rc' channel - latest >= rc, so latest config is returned - But channel was set to 'rc' with latest URL ❌ - Now channel is correctly set to 'latest' ✅ All 39 tests passing ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * update version * udpate version * update config * add no cache header * update files * 🤖 chore: automate app upgrade config updates * format code * update workflow * update get method * docs: document upgrade workflow automation --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: GitHub Action <action@github.com>
213 lines
7.6 KiB
YAML
213 lines
7.6 KiB
YAML
name: Update App Upgrade Config
|
|
|
|
on:
|
|
release:
|
|
types:
|
|
- released
|
|
- prereleased
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "Release tag (e.g., v1.2.3)"
|
|
required: true
|
|
type: string
|
|
is_prerelease:
|
|
description: "Mark the tag as a prerelease when running manually"
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
propose-update:
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'release' && github.event.release.draft == false)
|
|
|
|
steps:
|
|
- name: Check if should proceed
|
|
id: check
|
|
run: |
|
|
EVENT="${{ github.event_name }}"
|
|
|
|
if [ "$EVENT" = "workflow_dispatch" ]; then
|
|
TAG="${{ github.event.inputs.tag }}"
|
|
else
|
|
TAG="${{ github.event.release.tag_name }}"
|
|
fi
|
|
|
|
latest_tag=$(
|
|
curl -L \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ github.token }}" \
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
https://api.github.com/repos/${{ github.repository }}/releases/latest \
|
|
| jq -r '.tag_name'
|
|
)
|
|
|
|
if [ "$EVENT" = "workflow_dispatch" ]; then
|
|
MANUAL_IS_PRERELEASE="${{ github.event.inputs.is_prerelease }}"
|
|
if [ -z "$MANUAL_IS_PRERELEASE" ]; then
|
|
MANUAL_IS_PRERELEASE="false"
|
|
fi
|
|
if [ "$MANUAL_IS_PRERELEASE" = "true" ]; then
|
|
if ! echo "$TAG" | grep -E '(-beta([.-][0-9]+)?|-rc([.-][0-9]+)?)' >/dev/null; then
|
|
echo "Manual prerelease flag set but tag $TAG lacks beta/rc suffix. Skipping." >&2
|
|
echo "should_run=false" >> "$GITHUB_OUTPUT"
|
|
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
fi
|
|
echo "should_run=true" >> "$GITHUB_OUTPUT"
|
|
echo "is_prerelease=$MANUAL_IS_PRERELEASE" >> "$GITHUB_OUTPUT"
|
|
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
|
|
IS_PRERELEASE="${{ github.event.release.prerelease }}"
|
|
|
|
if [ "$IS_PRERELEASE" = "true" ]; then
|
|
if ! echo "$TAG" | grep -E '(-beta([.-][0-9]+)?|-rc([.-][0-9]+)?)' >/dev/null; then
|
|
echo "Release marked as prerelease but tag $TAG lacks beta/rc suffix. Skipping." >&2
|
|
echo "should_run=false" >> "$GITHUB_OUTPUT"
|
|
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
echo "should_run=true" >> "$GITHUB_OUTPUT"
|
|
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
|
|
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
|
|
echo "Release is prerelease, proceeding"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${latest_tag}" == "$TAG" ]]; then
|
|
echo "should_run=true" >> "$GITHUB_OUTPUT"
|
|
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
|
|
echo "Release is latest, proceeding"
|
|
else
|
|
echo "should_run=false" >> "$GITHUB_OUTPUT"
|
|
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
|
|
echo "Release is neither prerelease nor latest, skipping"
|
|
fi
|
|
|
|
- name: Prepare metadata
|
|
id: meta
|
|
if: steps.check.outputs.should_run == 'true'
|
|
run: |
|
|
EVENT="${{ github.event_name }}"
|
|
LATEST_TAG="${{ steps.check.outputs.latest_tag }}"
|
|
if [ "$EVENT" = "release" ]; then
|
|
TAG="${{ github.event.release.tag_name }}"
|
|
PRE="${{ github.event.release.prerelease }}"
|
|
|
|
if [ -n "$LATEST_TAG" ] && [ "$LATEST_TAG" = "$TAG" ]; then
|
|
LATEST="true"
|
|
else
|
|
LATEST="false"
|
|
fi
|
|
TRIGGER="release"
|
|
else
|
|
TAG="${{ github.event.inputs.tag }}"
|
|
PRE="${{ github.event.inputs.is_prerelease }}"
|
|
if [ -z "$PRE" ]; then
|
|
PRE="false"
|
|
fi
|
|
if [ -n "$LATEST_TAG" ] && [ "$LATEST_TAG" = "$TAG" ] && [ "$PRE" != "true" ]; then
|
|
LATEST="true"
|
|
else
|
|
LATEST="false"
|
|
fi
|
|
TRIGGER="manual"
|
|
fi
|
|
|
|
SAFE_TAG=$(echo "$TAG" | sed 's/[^A-Za-z0-9._-]/-/g')
|
|
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
echo "safe_tag=$SAFE_TAG" >> "$GITHUB_OUTPUT"
|
|
echo "prerelease=$PRE" >> "$GITHUB_OUTPUT"
|
|
echo "latest=$LATEST" >> "$GITHUB_OUTPUT"
|
|
echo "trigger=$TRIGGER" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Checkout default branch
|
|
if: steps.check.outputs.should_run == 'true'
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
path: main
|
|
fetch-depth: 0
|
|
|
|
- name: Checkout cs-releases branch
|
|
if: steps.check.outputs.should_run == 'true'
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: cs-releases
|
|
path: cs
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node.js
|
|
if: steps.check.outputs.should_run == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Enable Corepack
|
|
if: steps.check.outputs.should_run == 'true'
|
|
run: corepack enable && corepack prepare yarn@4.9.1 --activate
|
|
|
|
- name: Install dependencies
|
|
if: steps.check.outputs.should_run == 'true'
|
|
working-directory: main
|
|
run: yarn install --immutable
|
|
|
|
- name: Update upgrade config
|
|
if: steps.check.outputs.should_run == 'true'
|
|
working-directory: main
|
|
env:
|
|
RELEASE_TAG: ${{ steps.meta.outputs.tag }}
|
|
IS_PRERELEASE: ${{ steps.check.outputs.is_prerelease }}
|
|
run: |
|
|
yarn tsx scripts/update-app-upgrade-config.ts \
|
|
--tag "$RELEASE_TAG" \
|
|
--config ../cs/app-upgrade-config.json \
|
|
--is-prerelease "$IS_PRERELEASE"
|
|
|
|
- name: Detect changes
|
|
if: steps.check.outputs.should_run == 'true'
|
|
id: diff
|
|
working-directory: cs
|
|
run: |
|
|
if git diff --quiet -- app-upgrade-config.json; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Create pull request
|
|
if: steps.check.outputs.should_run == 'true' && steps.diff.outputs.changed == 'true'
|
|
uses: peter-evans/create-pull-request@v7
|
|
with:
|
|
path: cs
|
|
base: cs-releases
|
|
branch: chore/update-app-upgrade-config/${{ steps.meta.outputs.safe_tag }}
|
|
commit-message: "🤖 chore: sync app-upgrade-config for ${{ steps.meta.outputs.tag }}"
|
|
title: "chore: update app-upgrade-config for ${{ steps.meta.outputs.tag }}"
|
|
body: |
|
|
Automated update triggered by `${{ steps.meta.outputs.trigger }}`.
|
|
|
|
- Source tag: `${{ steps.meta.outputs.tag }}`
|
|
- Pre-release: `${{ steps.meta.outputs.prerelease }}`
|
|
- Latest: `${{ steps.meta.outputs.latest }}`
|
|
- Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
labels: |
|
|
automation
|
|
app-upgrade
|
|
|
|
- name: No changes detected
|
|
if: steps.check.outputs.should_run == 'true' && steps.diff.outputs.changed != 'true'
|
|
run: echo "No updates required for cs-releases/app-upgrade-config.json"
|