Skip to content

Commit 38216c5

Browse files
committed
feat: Add automatic version detection and update workflow
- Auto-detect npm version before building - Skip build if version already released - Support force rebuild option - Daily version check schedule - Add check-update.sh script for local version checking - Auto-create GitHub Release with formatted notes
1 parent 2756e69 commit 38216c5

2 files changed

Lines changed: 398 additions & 43 deletions

File tree

Lines changed: 127 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,66 @@
11
name: Download Claude Code Offline Packages
22

33
on:
4-
# 手动触发
4+
# Manual trigger
55
workflow_dispatch:
6-
# 每周一自动运行检查更新
6+
inputs:
7+
force_rebuild:
8+
description: 'Force rebuild even if version exists'
9+
required: false
10+
default: 'false'
11+
# Daily check for new versions at 00:00 UTC
12+
schedule:
13+
- cron: '0 0 * * *'
14+
# Weekly full rebuild every Monday at 00:00 UTC
715
schedule:
816
- cron: '0 0 * * 1'
9-
# 发布时触发
10-
release:
11-
types: [created]
1217

1318
env:
1419
NODE_VERSION: '20'
20+
NPM_REGISTRY: 'https://registry.npmmirror.com'
1521

1622
jobs:
23+
check-version:
24+
runs-on: ubuntu-latest
25+
outputs:
26+
latest_version: ${{ steps.check.outputs.latest_version }}
27+
should_build: ${{ steps.check.outputs.should_build }}
28+
release_exists: ${{ steps.check.outputs.release_exists }}
29+
steps:
30+
- name: Check latest version from npm
31+
id: check
32+
run: |
33+
# Get latest version from npm
34+
LATEST_VERSION=$(curl -s https://registry.npmjs.org/@anthropic-ai/claude-code | jq -r '.["dist-tags"].latest')
35+
echo "Latest npm version: $LATEST_VERSION"
36+
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
37+
38+
# Check if release already exists
39+
RELEASE_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" \
40+
"https://api.github.com/repos/${{ github.repository }}/releases/tags/v${LATEST_VERSION}")
41+
42+
if [ "$RELEASE_EXISTS" = "200" ]; then
43+
echo "Release v${LATEST_VERSION} already exists"
44+
echo "release_exists=true" >> $GITHUB_OUTPUT
45+
46+
# Check if force rebuild
47+
if [ "${{ github.event.inputs.force_rebuild }}" = "true" ]; then
48+
echo "Force rebuild requested"
49+
echo "should_build=true" >> $GITHUB_OUTPUT
50+
else
51+
echo "Skipping build - version already exists"
52+
echo "should_build=false" >> $GITHUB_OUTPUT
53+
fi
54+
else
55+
echo "Release v${LATEST_VERSION} does not exist"
56+
echo "release_exists=false" >> $GITHUB_OUTPUT
57+
echo "should_build=true" >> $GITHUB_OUTPUT
58+
fi
59+
1760
build-offline-packages:
61+
needs: check-version
1862
runs-on: ubuntu-latest
63+
if: needs.check-version.outputs.should_build == 'true'
1964
permissions:
2065
contents: write
2166

@@ -27,67 +72,72 @@ jobs:
2772
uses: actions/setup-node@v4
2873
with:
2974
node-version: ${{ env.NODE_VERSION }}
30-
registry-url: 'https://registry.npmmirror.com' # 使用国内镜像加速
75+
registry-url: ${{ env.NPM_REGISTRY }}
3176

3277
- name: Configure npm mirrors
3378
run: |
34-
# 配置 npm 使用国内镜像
35-
npm config set registry https://registry.npmmirror.com
79+
# Configure npm to use domestic mirror
80+
npm config set registry ${{ env.NPM_REGISTRY }}
3681
37-
# 配置其他常用镜像
82+
# Configure other common mirrors
3883
npm config set disturl https://npmmirror.com/mirrors/node
3984
npm config set electron_mirror https://npmmirror.com/mirrors/electron/
4085
npm config set sass_binary_site https://npmmirror.com/mirrors/node-sass/
4186
npm config set phantomjs_cdnurl https://npmmirror.com/mirrors/phantomjs/
4287
43-
echo "npm registry configured"
88+
echo "npm registry configured: $(npm config get registry)"
4489
4590
- name: Install Claude Code globally
4691
run: |
4792
npm install -g @anthropic-ai/claude-code
93+
94+
# Verify installation
95+
CLAUDE_VERSION=$(claude --version 2>/dev/null || echo "${{ needs.check-version.outputs.latest_version }}")
96+
echo "Installed Claude Code version: $CLAUDE_VERSION"
97+
echo "CLAUDE_VERSION=$CLAUDE_VERSION" >> $GITHUB_ENV
4898
4999
- name: Prepare offline packages
50100
run: |
51-
# 创建输出目录
101+
# Create output directory
52102
mkdir -p claude-offline-packages
53103
54-
# 获取 Claude Code 版本
55-
CLAUDE_VERSION=$(claude --version 2>/dev/null || echo "latest")
104+
# Get Claude Code version
105+
CLAUDE_VERSION="${{ needs.check-version.outputs.latest_version }}"
56106
echo "CLAUDE_VERSION=$CLAUDE_VERSION" >> $GITHUB_ENV
57-
echo "Claude Code version: $CLAUDE_VERSION"
107+
echo "Building Claude Code version: $CLAUDE_VERSION"
58108
59-
# 找到全局安装路径
109+
# Find global installation path
60110
GLOBAL_PREFIX=$(npm prefix -g)
61111
echo "NPM global prefix: $GLOBAL_PREFIX"
62112
63-
# 复制 node_modules 到离线包目录
113+
# Copy node_modules to offline package directory
64114
if [ -d "$GLOBAL_PREFIX/lib/node_modules/@anthropic-ai" ]; then
65115
cp -r "$GLOBAL_PREFIX/lib/node_modules/@anthropic-ai/claude-code" claude-offline-packages/
66-
# 安装其他依赖
116+
# Install other dependencies
67117
cd claude-offline-packages
68118
npm install ./claude-code --production
69119
else
70-
# 备用方案:直接 npm install
120+
# Fallback: direct npm install
71121
cd claude-offline-packages
72122
npm install @anthropic-ai/claude-code --production
73123
fi
74124
75-
# 创建 .bin 目录和链接
125+
# Create .bin directory and links
76126
mkdir -p node_modules/.bin
77127
if [ -f "claude-code/cli.js" ]; then
78128
ln -sf ../claude-code/cli.js node_modules/.bin/claude
79129
elif [ -f "node_modules/@anthropic-ai/claude-code/cli.js" ]; then
80130
ln -sf ../@anthropic-ai/claude-code/cli.js node_modules/.bin/claude
81131
fi
82132
83-
# 添加执行权限
133+
# Add execute permissions
84134
chmod +x node_modules/.bin/claude 2>/dev/null || true
85135
chmod +x claude-code/cli.js 2>/dev/null || true
86136
chmod +x node_modules/@anthropic-ai/claude-code/cli.js 2>/dev/null || true
87137
88138
- name: Download VSCode extension
89139
run: |
90-
# 尝试下载最新版本的 VSCode 扩展
140+
# Try to download latest VSCode extension
91141
EXTENSION_URL=$(curl -s https://api.github.com/repos/anthropics/claude-code/releases/latest | \
92142
grep "browser_download_url.*vsix" | head -1 | cut -d '"' -f 4)
93143
@@ -101,7 +151,7 @@ jobs:
101151

102152
- name: Copy setup script
103153
run: |
104-
# 复制 setup-claude-code.sh 到离线包目录
154+
# Copy setup-claude-code.sh to offline package directory
105155
cp setup-claude-code.sh claude-offline-packages/
106156
chmod +x claude-offline-packages/setup-claude-code.sh
107157
echo "Setup script copied to offline packages"
@@ -111,58 +161,92 @@ jobs:
111161
cat > claude-offline-packages/package-info.json << EOF
112162
{
113163
"name": "claude-offline-packages",
114-
"version": "${{ env.CLAUDE_VERSION }}",
164+
"version": "${{ needs.check-version.outputs.latest_version }}",
115165
"created_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
116166
"node_version": "${{ env.NODE_VERSION }}",
117-
"source": "https://www.npmjs.com/package/@anthropic-ai/claude-code"
167+
"source": "https://www.npmjs.com/package/@anthropic-ai/claude-code",
168+
"github_repo": "${{ github.repository }}"
118169
}
119170
EOF
120171
121172
- name: Pack offline packages
122173
run: |
123174
tar -czf claude-offline-packages.tar.gz claude-offline-packages/
124175
125-
# 计算校验和
176+
# Calculate checksum
126177
sha256sum claude-offline-packages.tar.gz > claude-offline-packages.tar.gz.sha256
127178
128-
# 显示包大小
179+
# Show package size
180+
echo "Package size:"
129181
ls -lh claude-offline-packages.tar.gz
130182
131-
- name: Upload to GitHub Release
183+
- name: Create GitHub Release
184+
id: create_release
132185
uses: softprops/action-gh-release@v1
133-
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
134186
with:
135-
tag_name: ${{ github.event.release.tag_name || format('v{0}', env.CLAUDE_VERSION) }}
136-
files: |
137-
claude-offline-packages.tar.gz
138-
claude-offline-packages.tar.gz.sha256
187+
tag_name: v${{ needs.check-version.outputs.latest_version }}
188+
name: Claude Code v${{ needs.check-version.outputs.latest_version }}
139189
body: |
140-
Claude Code 离线安装包
190+
## Claude Code Offline Package v${{ needs.check-version.outputs.latest_version }}
141191
142-
- 版本: ${{ env.CLAUDE_VERSION }}
143-
- Node.js 版本: ${{ env.NODE_VERSION }}
144-
- 创建时间: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
192+
**Version:** ${{ needs.check-version.outputs.latest_version }}
193+
**Node.js:** ${{ env.NODE_VERSION }}
194+
**Build Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
145195
146-
## 使用方法
196+
### Downloads
147197
148-
1. 下载 `claude-offline-packages.tar.gz`
149-
2. 解压到任意目录:`tar -xzf claude-offline-packages.tar.gz`
150-
3. 进入目录:`cd claude-offline-packages`
151-
4. 运行脚本:`bash setup-claude-code.sh`
198+
| File | Description |
199+
|------|-------------|
200+
| `claude-offline-packages.tar.gz` | Offline installation package |
201+
| `claude-offline-packages.tar.gz.sha256` | SHA256 checksum |
152202
153-
## 校验
203+
### Quick Start
204+
205+
```bash
206+
# 1. Download and extract
207+
tar -xzf claude-offline-packages.tar.gz
208+
209+
# 2. Run installer
210+
cd claude-offline-packages
211+
bash setup-claude-code.sh
212+
```
213+
214+
### Verification
154215
155216
```bash
156217
sha256sum -c claude-offline-packages.tar.gz.sha256
157218
```
219+
220+
### Features
221+
222+
- ✅ Automatic mirror source detection
223+
- ✅ Region restriction bypass
224+
- ✅ Multi-language support (EN/ZH)
225+
- ✅ Universal Node.js installation
226+
- ✅ Uninstall support
227+
draft: false
228+
prerelease: false
229+
files: |
230+
claude-offline-packages.tar.gz
231+
claude-offline-packages.tar.gz.sha256
158232
env:
159233
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
160234

161235
- name: Upload artifact
162236
uses: actions/upload-artifact@v4
163237
with:
164-
name: claude-offline-packages
238+
name: claude-offline-packages-v${{ needs.check-version.outputs.latest_version }}
165239
path: |
166240
claude-offline-packages.tar.gz
167241
claude-offline-packages.tar.gz.sha256
168242
retention-days: 30
243+
244+
notify-no-build:
245+
needs: check-version
246+
runs-on: ubuntu-latest
247+
if: needs.check-version.outputs.should_build == 'false'
248+
steps:
249+
- name: Skip notification
250+
run: |
251+
echo "Skipping build - version ${{ needs.check-version.outputs.latest_version }} already exists"
252+
echo "To force rebuild, trigger workflow with 'force_rebuild' set to 'true'"

0 commit comments

Comments
 (0)