博客
LunariaJS CI/CD 集成:自动化你的本地化流程
学习将 LunariaJS 集成到 GitHub Actions、GitLab CI 等 CI/CD 平台,实现翻译状态自动检查、仪表板自动构建发布,让本地化流程完全自动化。
LibDoc Team 2026年3月6日 LunariaJS 专栏 72 分钟阅读
#LunariaJS
#CI/CD
#GitHub Actions
#自动化
#持续集成
LunariaJS CI/CD 集成:自动化你的本地化流程
在前面的文章中,我们学习了 LunariaJS 的核心功能、Git 工作流和 Astro Starlight 集成。今天,让我们将本地化工作流提升到一个新的高度 —— 通过 CI/CD 实现完全自动化。
💡 官方文档:LunariaJS 中文文档 - CI/CD
CI/CD 集成的价值
为什么需要自动化?
在没有 CI/CD 集成的情况下,本地化管理存在以下问题:
| 问题 | 影响 |
|---|---|
| 手动检查翻译状态 | 费时费力,容易遗漏 |
| 仪表板更新不及时 | 团队看不到最新状态 |
| 翻译问题发现滞后 | 发布后才发现翻译缺失 |
| 缺乏自动化通知 | 贡献者不知道需要翻译 |
持续本地化概念
持续本地化(Continuous Localization) 是将翻译工作融入 CI/CD 流水线的实践:
代码提交 → 自动检测翻译变更 → 更新仪表板 → 通知相关人员 → 发布
核心价值:
- 即时反馈:每次提交都知道翻译状态
- 自动化:减少手动操作,提高效率
- 可视化:团队随时了解翻译进度
- 质量保障:发布前确保翻译完整
GitHub Actions 集成
基础 Workflow 配置
创建 .github/workflows/lunaria.yml:
name: Lunaria Dashboard
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'i18n/**'
- 'lunaria.config.json'
pull_request:
branches: [main]
workflow_dispatch: # 手动触发
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整 Git 历史
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Lunaria Dashboard
run: npx lunaria build
- name: Upload dashboard artifact
uses: actions/upload-artifact@v4
with:
name: lunaria-dashboard
path: lunaria-dashboard/
retention-days: 7
自动发布到 GitHub Pages
将仪表板自动部署到 GitHub Pages:
name: Deploy Lunaria Dashboard
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build main site
run: npm run build
- name: Build Lunaria Dashboard
run: npx lunaria build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: './dist'
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
PR 翻译状态检查
在 Pull Request 中自动检查翻译状态:
name: Translation Check
on:
pull_request:
branches: [main]
jobs:
check-translations:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Lunaria Dashboard
run: npx lunaria build --silent
- name: Check for missing translations
id: check
run: |
# 解析仪表板数据,检查是否有新增的缺失翻译
MISSING=$(node scripts/check-new-missing.js)
echo "missing=$MISSING" >> $GITHUB_OUTPUT
- name: Comment on PR
if: steps.check.outputs.missing != ''
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🌙 Translation Status Update\n\n${{ steps.check.outputs.missing }}`
})
完整的 GitHub Actions 配置
# .github/workflows/i18n.yml
name: i18n Automation
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# 每周一早上 9 点生成报告
- cron: '0 9 * * 1'
workflow_dispatch:
env:
NODE_VERSION: '20'
jobs:
# Job 1: 检查翻译状态
check:
name: Check Translation Status
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Lunaria Dashboard
run: npx lunaria build
- name: Generate status report
id: report
run: |
# 生成状态报告
REPORT=$(node scripts/generate-report.js)
echo "report<<EOF" >> $GITHUB_OUTPUT
echo "$REPORT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Upload dashboard
uses: actions/upload-artifact@v4
with:
name: lunaria-dashboard
path: lunaria-dashboard/
outputs:
report: ${{ steps.report.outputs.report }}
# Job 2: 发布仪表板(仅 main 分支)
deploy:
name: Deploy Dashboard
runs-on: ubuntu-latest
needs: check
if: github.ref == 'refs/heads/main'
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Download dashboard
uses: actions/download-artifact@v4
with:
name: lunaria-dashboard
path: ./dashboard
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload to Pages
uses: actions/upload-pages-artifact@v3
with:
path: ./dashboard
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
# Job 3: 发送通知(定时任务)
notify:
name: Send Weekly Report
runs-on: ubuntu-latest
needs: check
if: github.event_name == 'schedule'
steps:
- name: Send Slack notification
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "🌙 Weekly Translation Report",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "${{ needs.check.outputs.report }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
GitLab CI 集成
基础配置
创建 .gitlab-ci.yml:
# .gitlab-ci.yml
stages:
- check
- build
- deploy
variables:
NODE_VERSION: '20'
# 缓存配置
.node-cache:
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
# 检查翻译状态
lunaria-check:
stage: check
extends: .node-cache
image: node:${NODE_VERSION}
script:
- npm ci
- npx lunaria build
artifacts:
paths:
- lunaria-dashboard/
expire_in: 1 week
only:
- merge_requests
- main
# 构建并部署
lunaria-deploy:
stage: deploy
image: node:${NODE_VERSION}
needs:
- lunaria-check
script:
- echo "Deploying Lunaria dashboard..."
# 添加你的部署脚本
only:
- main
与 GitLab Pages 集成
# .gitlab-ci.yml
image: node:20
stages:
- deploy
pages:
stage: deploy
script:
- npm ci
- npm run build
- npx lunaria build
- mv lunaria-dashboard public
artifacts:
paths:
- public
only:
- main
GitLab CI 与 GitHub Actions 对比
| 功能 | GitHub Actions | GitLab CI |
|---|---|---|
| 获取完整历史 | fetch-depth: 0 | GIT_DEPTH: 0 |
| 产物上传 | upload-artifact | artifacts.paths |
| 部署到 Pages | deploy-pages | pages job |
| Secrets | secrets.VARIABLE | variables.VARIABLE |
| 条件执行 | if: | only:/except: |
自动化任务设计
翻译完整性检查
创建自定义检查脚本 scripts/check-new-missing.js:
// scripts/check-new-missing.js
const fs = require('fs');
const path = require('path');
function checkMissingTranslations() {
// 读取 LunariaJS 生成的状态数据
const statusPath = path.join('lunaria-dashboard', 'data', 'status.json');
if (!fs.existsSync(statusPath)) {
console.log('No status file found');
return '';
}
const status = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
// 找出缺失的翻译
const missing = [];
for (const [lang, data] of Object.entries(status.languages)) {
if (data.missing > 0) {
missing.push({
language: lang,
count: data.missing,
files: data.missingFiles || []
});
}
}
if (missing.length === 0) {
return '✅ All translations are up to date!';
}
// 生成报告
let report = '### ⚠️ Missing Translations Found\n\n';
for (const item of missing) {
report += `- **${item.language}**: ${item.count} missing files\n`;
}
report += '\nPlease check the [Lunaria Dashboard](/i18n-status/) for details.';
return report;
}
console.log(checkMissingTranslations());
过时翻译告警
检查过时的翻译并发出警告:
// scripts/check-outdated.js
const { execSync } = require('child_process');
function getOutdatedTranslations() {
// 获取最近 7 天内更新的源文件
const recentChanges = execSync(
'git log --since="7 days ago" --name-only --pretty=format: -- docs/en/',
{ encoding: 'utf8' }
);
const changedFiles = recentChanges
.split('\n')
.filter(f => f.trim())
.map(f => f.replace('docs/en/', '').replace('.md', ''));
if (changedFiles.length === 0) {
return { hasOutdated: false, files: [] };
}
return {
hasOutdated: true,
files: changedFiles,
message: `⚠️ The following files were updated in the last 7 days and may need translation updates:\n${changedFiles.map(f => `- ${f}`).join('\n')}`
};
}
const result = getOutdatedTranslations();
if (result.hasOutdated) {
console.log(result.message);
process.exit(1); // 非 0 退出码会使 CI 失败
} else {
console.log('✅ No recent source changes requiring translation updates.');
}
仪表板自动发布
在构建后自动发布仪表板:
- name: Publish Dashboard
run: |
# 复制仪表板到发布目录
cp -r lunaria-dashboard ./dist/i18n-status
# 更新部署状态
echo "Dashboard published to /i18n-status/"
通知与报告
Slack 通知
- name: Notify Slack
if: always()
uses: slackapi/slack-github-action@v1
with:
channel-id: 'C0123456789'
payload: |
{
"text": "Lunaria Dashboard Update",
"attachments": [
{
"color": "${{ job.status == 'success' && 'good' || 'danger' }}",
"fields": [
{
"title": "Status",
"value": "${{ job.status }}",
"short": true
},
{
"title": "Branch",
"value": "${{ github.ref_name }}",
"short": true
},
{
"title": "Dashboard URL",
"value": "<https://your-org.github.io/your-repo/i18n-status/|View Dashboard>",
"short": false
}
]
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
PR 评论机器人
在 PR 中自动评论翻译状态:
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const status = require('./lunaria-dashboard/data/status.json');
let body = '## 🌙 Translation Status\n\n';
body += '| Language | Done | Outdated | Missing | Progress |\n';
body += '|----------|------|----------|---------|----------|\n';
for (const [lang, data] of Object.entries(status.languages)) {
const progress = Math.round((data.done / data.total) * 100);
const emoji = progress >= 90 ? '✅' : progress >= 70 ? '⚠️' : '❌';
body += `| ${lang} | ${data.done} | ${data.outdated} | ${data.missing} | ${emoji} ${progress}% |\n`;
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
邮件报告
定期发送邮件报告:
- name: Send Email Report
if: github.event_name == 'schedule'
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: Weekly Translation Report - ${{ github.repository }}
to: team@example.com
from: CI Bot
body: |
Hi Team,
Here's the weekly translation status report:
${{ needs.check.outputs.report }}
View the full dashboard: https://your-org.github.io/your-repo/i18n-status/
Best regards,
CI Bot
CI/CD 最佳实践
1. 条件触发
只在相关文件变更时触发:
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'i18n/**'
- 'lunaria.config.json'
- '.github/workflows/lunaria.yml'
2. 缓存优化
使用缓存加速构建:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 启用 npm 缓存
- name: Cache Lunaria output
uses: actions/cache@v4
with:
path: .lunaria-cache
key: lunaria-${{ hashFiles('docs/**', 'i18n/**') }}
3. 失败策略
设置合理的失败策略:
jobs:
check:
continue-on-error: true # 翻译检查失败不阻止部署
deploy:
needs: check
if: always() && needs.check.result == 'success'
4. 并行执行
并行执行多个检查任务:
jobs:
check-missing:
# ...
check-outdated:
# ...
report:
needs: [check-missing, check-outdated]
# ...
5. 安全最佳实践
# 使用最小权限
permissions:
contents: read
pull-requests: write
# 不要暴露 secrets
env:
DASHBOARD_URL: ${{ secrets.DASHBOARD_URL }} # ❌ 不要在日志中暴露
总结
通过 CI/CD 集成,LunariaJS 可以实现完全自动化的本地化工作流:
| 功能 | 实现 |
|---|---|
| 自动检测翻译变更 | GitHub Actions / GitLab CI |
| 自动构建仪表板 | 每次提交触发 |
| 自动发布 | GitHub Pages / GitLab Pages |
| 自动通知 | Slack / Email / PR 评论 |
| 定期报告 | Scheduled jobs |
关键要点:
- 使用
fetch-depth: 0获取完整 Git 历史 - 配置条件触发减少不必要的构建
- 利用缓存加速 CI 运行
- 设置合理的通知机制
下一步
恭喜你完成了 LunariaJS 入门系列!从下一篇文章开始,我们将进入深度篇,深入探讨:
- 第 8 篇:@lunariajs/core 源码解析(8,000-15,000 字)
- 第 9 篇:高级配置与自定义策略(8,000-15,000 字)
- 第 10 篇:完整企业级实战(8,000-15,000 字)
敬请期待!
💡 推荐阅读: