Skip to content

Commit 376483c

Browse files
committed
GitHub Action
1 parent 3ec915a commit 376483c

File tree

5 files changed

+1051
-123
lines changed

5 files changed

+1051
-123
lines changed

.github/workflows/build.yml

Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
name: Build and Package
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ main ]
9+
10+
env:
11+
NODE_VERSION: '18'
12+
13+
jobs:
14+
build:
15+
name: Build on ${{ matrix.os }} (${{ matrix.arch }})
16+
runs-on: ${{ matrix.os }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
include:
21+
# Linux builds
22+
- os: ubuntu-latest
23+
arch: x64
24+
node_arch: x64
25+
cmake_arch: x86_64
26+
27+
# macOS builds
28+
- os: macos-latest
29+
arch: arm64
30+
node_arch: arm64
31+
cmake_arch: arm64
32+
33+
# Windows builds
34+
- os: windows-latest
35+
arch: x64
36+
node_arch: x64
37+
cmake_arch: x64
38+
39+
steps:
40+
# 1. 检出代码
41+
- name: Checkout code
42+
uses: actions/checkout@v4
43+
with:
44+
submodules: recursive
45+
fetch-depth: 0
46+
47+
# 2. 设置 Node.js 环境
48+
- name: Setup Node.js
49+
id: setup_node
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: ${{ env.NODE_VERSION }}
53+
architecture: ${{ matrix.node_arch }}
54+
55+
# 3. 安装系统依赖 - Linux
56+
- name: Install Linux dependencies
57+
if: runner.os == 'Linux'
58+
run: |
59+
sudo apt-get update
60+
sudo apt-get install -y \
61+
cmake \
62+
build-essential \
63+
gfortran \
64+
libfftw3-dev \
65+
libboost-all-dev \
66+
pkg-config
67+
68+
# 3a. Linux ARM64 交叉编译设置
69+
- name: Setup Linux ARM64 cross-compilation
70+
if: runner.os == 'Linux' && matrix.arch == 'arm64'
71+
run: |
72+
sudo apt-get install -y \
73+
gcc-aarch64-linux-gnu \
74+
g++-aarch64-linux-gnu \
75+
gfortran-aarch64-linux-gnu
76+
# 添加 ARM64 架构支持
77+
sudo dpkg --add-architecture arm64
78+
sudo apt-get update
79+
sudo apt-get install -y \
80+
libfftw3-dev:arm64 \
81+
libboost-all-dev:arm64
82+
# 设置交叉编译环境变量
83+
echo "CC=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
84+
echo "CXX=aarch64-linux-gnu-g++" >> $GITHUB_ENV
85+
echo "FC=aarch64-linux-gnu-gfortran" >> $GITHUB_ENV
86+
87+
# 3. 安装系统依赖 - macOS
88+
- name: Install macOS dependencies
89+
if: runner.os == 'macOS'
90+
run: |
91+
brew install cmake fftw boost gcc pkg-config
92+
93+
# 根据架构设置不同的路径
94+
if [ "${{ matrix.arch }}" = "arm64" ]; then
95+
# Apple Silicon (ARM64)
96+
BREW_PREFIX="/opt/homebrew"
97+
else
98+
# Intel (x64)
99+
BREW_PREFIX="/usr/local"
100+
fi
101+
102+
# 确保brew路径在PATH中
103+
echo "${BREW_PREFIX}/bin" >> $GITHUB_PATH
104+
105+
# 验证gfortran安装并设置环境变量
106+
echo "Checking gfortran installation..."
107+
ls -la ${BREW_PREFIX}/bin/gfortran* || echo "gfortran not found"
108+
109+
# 找到正确的gfortran路径
110+
GFORTRAN_PATH=$(find ${BREW_PREFIX}/bin -name "gfortran*" | head -1)
111+
if [ -n "$GFORTRAN_PATH" ] && [ -x "$GFORTRAN_PATH" ]; then
112+
echo "Found gfortran at: $GFORTRAN_PATH"
113+
echo "FC=$GFORTRAN_PATH" >> $GITHUB_ENV
114+
echo "CMAKE_Fortran_COMPILER=$GFORTRAN_PATH" >> $GITHUB_ENV
115+
116+
# 测试gfortran
117+
$GFORTRAN_PATH --version || echo "gfortran test failed"
118+
else
119+
echo "ERROR: gfortran not found or not executable"
120+
exit 1
121+
fi
122+
123+
# 设置库路径
124+
echo "LIBRARY_PATH=${BREW_PREFIX}/lib:$LIBRARY_PATH" >> $GITHUB_ENV
125+
echo "LD_LIBRARY_PATH=${BREW_PREFIX}/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
126+
127+
# 3. 安装系统依赖 - Windows
128+
- name: Setup MSYS2 for Windows build
129+
if: runner.os == 'Windows'
130+
uses: msys2/setup-msys2@v2
131+
with:
132+
msystem: MINGW64
133+
update: true
134+
path-type: inherit
135+
install: >-
136+
mingw-w64-x86_64-gcc
137+
mingw-w64-x86_64-gcc-fortran
138+
mingw-w64-x86_64-cmake
139+
mingw-w64-x86_64-ninja
140+
mingw-w64-x86_64-pkg-config
141+
mingw-w64-x86_64-fftw
142+
mingw-w64-x86_64-boost
143+
144+
- name: Setup Windows environment
145+
if: runner.os == 'Windows'
146+
shell: msys2 {0}
147+
run: |
148+
echo "/c/msys64/mingw64/bin" >> $GITHUB_PATH
149+
echo "Verifying pkg-config installation..."
150+
which pkg-config || (echo "pkg-config not found, reinstalling..." && pacman -S --noconfirm mingw-w64-x86_64-pkg-config)
151+
pkg-config --version || (echo "Unable to run pkg-config, reinstalling..." && pacman -S --noconfirm mingw-w64-x86_64-pkg-config)
152+
153+
echo "CC=gcc" >> $GITHUB_ENV
154+
echo "CXX=g++" >> $GITHUB_ENV
155+
echo "FC=gfortran" >> $GITHUB_ENV
156+
echo "CMAKE_Fortran_COMPILER=gfortran" >> $GITHUB_ENV
157+
echo "CMAKE_GENERATOR=MinGW Makefiles" >> $GITHUB_ENV
158+
159+
gcc --version
160+
g++ --version
161+
gfortran --version
162+
cmake --version
163+
164+
# 4. 安装 npm 依赖
165+
- name: Install npm dependencies
166+
run: npm ci --ignore-scripts
167+
168+
# 5. 构建 TypeScript
169+
- name: Build TypeScript
170+
run: npm run build:ts
171+
172+
# 6. 构建原生模块 - Linux/macOS
173+
- name: Build native module (Linux/macOS)
174+
if: runner.os != 'Windows'
175+
run: |
176+
if [ "${{ matrix.arch }}" = "arm64" ] && [ "${{ runner.os }}" = "Linux" ]; then
177+
# Linux ARM64 交叉编译
178+
npx cmake-js compile --arch=${{ matrix.cmake_arch }} \
179+
--CDCMAKE_SYSTEM_NAME=Linux \
180+
--CDCMAKE_SYSTEM_PROCESSOR=aarch64 \
181+
--CDCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
182+
--CDCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
183+
--CDCMAKE_Fortran_COMPILER=aarch64-linux-gnu-gfortran
184+
else
185+
# 本地编译
186+
npx cmake-js compile --arch=${{ matrix.cmake_arch }}
187+
fi
188+
189+
# 6. 构建原生模块 - Windows
190+
- name: Build native module (Windows)
191+
if: runner.os == 'Windows'
192+
shell: msys2 {0}
193+
run: |
194+
echo "--- Checking Node.js and npx in MSYS2 (with path-type: inherit) ---"
195+
echo "PATH: $PATH"
196+
197+
echo "which node:"
198+
which node || echo "node not found"
199+
echo "node --version:"
200+
node --version || echo "node not runnable"
201+
202+
echo "which npx:"
203+
which npx || echo "npx not found"
204+
echo "npx --version:"
205+
npx --version || echo "npx not runnable"
206+
207+
echo "Attempting to run npx cmake-js compile..."
208+
npx cmake-js compile --arch=${{ matrix.cmake_arch }} \
209+
-G "MinGW Makefiles" \
210+
--CDCMAKE_C_COMPILER=gcc \
211+
--CDCMAKE_CXX_COMPILER=g++ \
212+
--CDCMAKE_Fortran_COMPILER=gfortran \
213+
--CDCMAKE_SHARED_LINKER_FLAGS='' \
214+
--CDCMAKE_MODULE_LINKER_FLAGS='' \
215+
--CDCMAKE_EXE_LINKER_FLAGS='' \
216+
--CDCMAKE_JS_SRC='' \
217+
--verbose
218+
219+
# 7. 运行测试
220+
- name: Run tests
221+
run: |
222+
# 显示编译后的文件结构
223+
echo "📁 Checking compiled files structure:"
224+
ls -la dist/ || echo "dist directory not found"
225+
find dist -name "*.js" -type f || echo "No JS files found in dist"
226+
227+
# 检查测试文件是否存在
228+
if [ -f "dist/test/wsjtx.basic.test.js" ]; then
229+
echo "✅ Basic test file found: dist/test/wsjtx.basic.test.js"
230+
231+
# 检查原生模块是否存在
232+
if [ -f "build/Release/wsjtx_lib_nodejs.node" ]; then
233+
echo "✅ Native module found: build/Release/wsjtx_lib_nodejs.node"
234+
# 运行基础测试
235+
npm test
236+
else
237+
echo "❌ Native module not found! Cannot run tests."
238+
exit 1
239+
fi
240+
else
241+
echo "❌ Basic test file not found!"
242+
exit 1
243+
fi
244+
245+
# 8. 创建预构建二进制文件
246+
- name: Create prebuilt binaries
247+
run: |
248+
# 创建目标目录
249+
mkdir -p prebuilds/${{ matrix.os }}-${{ matrix.arch }}
250+
251+
# 复制构建的 .node 文件
252+
if [ "${{ runner.os }}" = "Windows" ]; then
253+
cp build/Release/*.node prebuilds/${{ matrix.os }}-${{ matrix.arch }}/
254+
else
255+
cp build/Release/*.node prebuilds/${{ matrix.os }}-${{ matrix.arch }}/
256+
fi
257+
258+
# 显示构建结果
259+
echo "构建完成的文件:"
260+
ls -la prebuilds/${{ matrix.os }}-${{ matrix.arch }}/
261+
shell: bash
262+
263+
# 9. 上传构建产物到 artifacts
264+
- name: Upload build artifacts
265+
uses: actions/upload-artifact@v4
266+
with:
267+
name: prebuilt-${{ matrix.os }}-${{ matrix.arch }}
268+
path: prebuilds/
269+
retention-days: 30
270+
if-no-files-found: error
271+
272+
# 10. 上传完整构建目录(用于调试)
273+
- name: Upload build directory for debugging
274+
if: failure()
275+
uses: actions/upload-artifact@v4
276+
with:
277+
name: build-debug-${{ matrix.os }}-${{ matrix.arch }}
278+
path: build/
279+
retention-days: 7
280+
281+
# 汇总所有构建产物
282+
collect-artifacts:
283+
name: Collect All Artifacts
284+
needs: build
285+
runs-on: ubuntu-latest
286+
if: always() && needs.build.result == 'success'
287+
288+
steps:
289+
- name: Download all build artifacts
290+
uses: actions/download-artifact@v4
291+
with:
292+
path: all-artifacts
293+
294+
- name: Organize artifacts
295+
run: |
296+
mkdir -p final-prebuilds
297+
298+
# 合并所有预构建文件
299+
for artifact_dir in all-artifacts/prebuilt-*; do
300+
if [ -d "$artifact_dir" ]; then
301+
echo "处理 $artifact_dir"
302+
cp -r "$artifact_dir"/* final-prebuilds/
303+
fi
304+
done
305+
306+
# 显示最终结果
307+
echo "所有平台的构建产物:"
308+
find final-prebuilds -name "*.node" -exec ls -la {} \;
309+
310+
# 创建构建摘要
311+
echo "# 构建摘要" > build-summary.md
312+
echo "构建时间: $(date)" >> build-summary.md
313+
echo "## 支持的平台:" >> build-summary.md
314+
find final-prebuilds -name "*.node" | while read file; do
315+
platform=$(echo "$file" | cut -d'/' -f2)
316+
echo "- $platform" >> build-summary.md
317+
done
318+
319+
- name: Upload combined artifacts
320+
uses: actions/upload-artifact@v4
321+
with:
322+
name: all-prebuilds
323+
path: |
324+
final-prebuilds/
325+
build-summary.md
326+
retention-days: 90

0 commit comments

Comments
 (0)