mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-18 23:42:43 +00:00
292 lines
10 KiB
YAML
292 lines
10 KiB
YAML
# .github/workflows/ci.yml
|
|
|
|
name: 'Qwen Code CI'
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- 'main'
|
|
- 'release/**'
|
|
pull_request:
|
|
branches:
|
|
- 'main'
|
|
- 'release/**'
|
|
merge_group:
|
|
workflow_dispatch:
|
|
inputs:
|
|
branch_ref:
|
|
description: 'Branch to run on'
|
|
required: true
|
|
default: 'main'
|
|
type: 'string'
|
|
|
|
concurrency:
|
|
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
|
|
cancel-in-progress: |-
|
|
${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }}
|
|
|
|
permissions:
|
|
checks: 'write'
|
|
contents: 'read'
|
|
statuses: 'write'
|
|
|
|
defaults:
|
|
run:
|
|
shell: 'bash'
|
|
|
|
env:
|
|
ACTIONLINT_VERSION: '1.7.7'
|
|
SHELLCHECK_VERSION: '0.11.0'
|
|
YAMLLINT_VERSION: '1.35.1'
|
|
|
|
jobs:
|
|
classify_pr:
|
|
name: 'Classify PR'
|
|
if: "${{ github.event_name == 'pull_request' }}"
|
|
runs-on: 'ubuntu-latest'
|
|
continue-on-error: true
|
|
outputs:
|
|
skip_ci: '${{ steps.release_sync.outputs.skip_ci }}'
|
|
steps:
|
|
- name: 'Detect release version-sync PR'
|
|
id: 'release_sync'
|
|
env:
|
|
# Repository variables can override these defaults if release naming
|
|
# or the CI bot account changes.
|
|
HEAD_REPO: "${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || '' }}"
|
|
HEAD_REF: "${{ github.event_name == 'pull_request' && github.head_ref || '' }}"
|
|
PR_TITLE: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || '' }}"
|
|
RELEASE_SYNC_HEAD_PREFIX: "${{ vars.RELEASE_SYNC_HEAD_PREFIX || 'release/' }}"
|
|
RELEASE_SYNC_TITLE_PREFIX: "${{ vars.RELEASE_SYNC_TITLE_PREFIX || 'chore(release):' }}"
|
|
RELEASE_SYNC_ACTOR: "${{ vars.RELEASE_SYNC_ACTOR || 'qwen-code-ci-bot' }}"
|
|
run: |-
|
|
skip_ci=false
|
|
repo_match=false
|
|
actor_match=false
|
|
head_match=false
|
|
title_match=false
|
|
[[ "${HEAD_REPO}" == "${GITHUB_REPOSITORY}" ]] && repo_match=true
|
|
[[ "${GITHUB_ACTOR}" == "${RELEASE_SYNC_ACTOR}" ]] && actor_match=true
|
|
[[ "${HEAD_REF}" == "${RELEASE_SYNC_HEAD_PREFIX}"* ]] && head_match=true
|
|
[[ "${PR_TITLE}" == "${RELEASE_SYNC_TITLE_PREFIX}"* ]] && title_match=true
|
|
|
|
if [[ "${GITHUB_EVENT_NAME}" == "pull_request" &&
|
|
"${repo_match}" == "true" &&
|
|
"${actor_match}" == "true" &&
|
|
"${head_match}" == "true" &&
|
|
"${title_match}" == "true" ]]; then
|
|
skip_ci=true
|
|
echo "Release sync PR detected: actor=${GITHUB_ACTOR}, head_ref=${HEAD_REF}, title=${PR_TITLE}"
|
|
else
|
|
echo "Not a release sync PR: event=${GITHUB_EVENT_NAME}, actor=${GITHUB_ACTOR}, expected_actor=${RELEASE_SYNC_ACTOR}, repo_match=${repo_match}, head_match=${head_match}, title_match=${title_match}"
|
|
fi
|
|
|
|
echo "skip_ci=${skip_ci}" >> "${GITHUB_OUTPUT}"
|
|
echo "skip_ci=${skip_ci}"
|
|
|
|
lint:
|
|
name: 'Lint'
|
|
needs: 'classify_pr'
|
|
if: "${{ !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' }}"
|
|
runs-on: 'ubuntu-latest'
|
|
steps:
|
|
- name: 'Checkout'
|
|
uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2
|
|
with:
|
|
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
|
|
fetch-depth: 0
|
|
|
|
- name: 'Set up Node.js 22.x'
|
|
uses: 'actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e' # v6.4.0
|
|
with:
|
|
node-version: '22.x'
|
|
cache: 'npm'
|
|
|
|
- name: 'Install dependencies and run prepare'
|
|
run: 'npm ci'
|
|
|
|
- name: 'Check lockfile'
|
|
run: 'npm run check:lockfile'
|
|
|
|
- name: 'Install linters'
|
|
run: 'node scripts/lint.js --setup'
|
|
|
|
- name: 'Run ESLint'
|
|
run: 'node scripts/lint.js --eslint'
|
|
|
|
- name: 'Run actionlint'
|
|
run: 'node scripts/lint.js --actionlint'
|
|
|
|
- name: 'Run shellcheck'
|
|
run: 'node scripts/lint.js --shellcheck'
|
|
|
|
- name: 'Run yamllint'
|
|
run: 'node scripts/lint.js --yamllint'
|
|
|
|
- name: 'Run Prettier'
|
|
run: 'node scripts/lint.js --prettier'
|
|
|
|
- name: 'Run sensitive keyword linter'
|
|
run: 'node scripts/lint.js --sensitive-keywords'
|
|
|
|
- name: 'Run i18n check'
|
|
run: 'npm run check-i18n'
|
|
|
|
- name: 'Generate settings schema'
|
|
run: 'npm run generate:settings-schema'
|
|
|
|
- name: 'Check settings schema is up-to-date'
|
|
run: |
|
|
if [[ -n $(git status --porcelain packages/vscode-ide-companion/schemas/settings.schema.json) ]]; then
|
|
echo "❌ Error: settings.schema.json is out of date!"
|
|
echo " Please run: npm run generate:settings-schema"
|
|
echo " Then commit the updated schema file."
|
|
git diff packages/vscode-ide-companion/schemas/settings.schema.json
|
|
exit 1
|
|
fi
|
|
echo "✅ Settings schema is up-to-date"
|
|
|
|
#
|
|
# Test: Node
|
|
#
|
|
test:
|
|
name: 'Test (${{ matrix.os }}, Node ${{ matrix.node-version }})'
|
|
needs: 'classify_pr'
|
|
if: "${{ !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' }}"
|
|
runs-on: '${{ matrix.os }}'
|
|
permissions:
|
|
contents: 'read'
|
|
checks: 'write'
|
|
pull-requests: 'write'
|
|
strategy:
|
|
fail-fast: false # So we can see all test failures
|
|
matrix:
|
|
include:
|
|
- os: 'macos-latest'
|
|
node-version: '22.x'
|
|
upload-coverage: 'false'
|
|
- os: 'ubuntu-latest'
|
|
node-version: '22.x'
|
|
upload-coverage: 'true'
|
|
- os: 'windows-latest'
|
|
node-version: '22.x'
|
|
upload-coverage: 'false'
|
|
steps:
|
|
- name: 'Checkout'
|
|
uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2
|
|
|
|
- name: 'Set up Node.js ${{ matrix.node-version }}'
|
|
uses: 'actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e' # v6.4.0
|
|
with:
|
|
node-version: '${{ matrix.node-version }}'
|
|
cache: 'npm'
|
|
cache-dependency-path: 'package-lock.json'
|
|
registry-url: 'https://registry.npmjs.org/'
|
|
|
|
- name: 'Configure npm for rate limiting'
|
|
run: |-
|
|
npm config set fetch-retry-mintimeout 20000
|
|
npm config set fetch-retry-maxtimeout 120000
|
|
npm config set fetch-retries 5
|
|
npm config set fetch-timeout 300000
|
|
|
|
- name: 'Install dependencies'
|
|
run: |-
|
|
npm ci --prefer-offline --no-audit --progress=false
|
|
|
|
- name: 'Run tests and generate reports'
|
|
env:
|
|
NO_COLOR: true
|
|
run: 'npm run test:ci'
|
|
|
|
- name: 'Publish Test Report (for non-forks)'
|
|
if: |-
|
|
${{ always() && (github.event.pull_request.head.repo.full_name == github.repository) }}
|
|
uses: 'dorny/test-reporter@dc3a92680fcc15842eef52e8c4606ea7ce6bd3f3' # ratchet:dorny/test-reporter@v2
|
|
with:
|
|
name: 'Test Results (${{ matrix.os }}, Node ${{ matrix.node-version }})'
|
|
path: 'packages/*/junit.xml'
|
|
reporter: 'java-junit'
|
|
fail-on-error: 'false'
|
|
|
|
- name: 'Upload Test Results Artifact (for forks)'
|
|
if: |-
|
|
${{ always() && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
|
uses: 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' # v7.0.1
|
|
with:
|
|
name: 'test-results-fork-${{ matrix.node-version }}-${{ matrix.os }}'
|
|
path: 'packages/*/junit.xml'
|
|
|
|
- name: 'Upload coverage reports'
|
|
if: |-
|
|
${{ always() && matrix.upload-coverage == 'true' }}
|
|
uses: 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' # v7.0.1
|
|
with:
|
|
name: 'coverage-reports-${{ matrix.node-version }}-${{ matrix.os }}'
|
|
path: 'packages/*/coverage'
|
|
|
|
post_coverage_comment:
|
|
name: 'Post Coverage Comment'
|
|
runs-on: 'ubuntu-latest'
|
|
needs:
|
|
- 'classify_pr'
|
|
- 'test'
|
|
if: |-
|
|
${{
|
|
always() &&
|
|
needs.classify_pr.outputs.skip_ci != 'true' &&
|
|
github.event_name == 'pull_request' &&
|
|
github.event.pull_request.head.repo.full_name == github.repository
|
|
}}
|
|
continue-on-error: true
|
|
permissions:
|
|
contents: 'read' # For checkout
|
|
pull-requests: 'write' # For commenting
|
|
strategy:
|
|
matrix:
|
|
# Reduce noise by only posting the comment once
|
|
os:
|
|
- 'ubuntu-latest'
|
|
node-version:
|
|
- '22.x'
|
|
steps:
|
|
- name: 'Checkout'
|
|
uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2
|
|
|
|
- name: 'Download coverage reports artifact'
|
|
uses: 'actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c' # v8.0.1
|
|
with:
|
|
name: 'coverage-reports-${{ matrix.node-version }}-${{ matrix.os }}'
|
|
path: 'coverage_artifact' # Download to a specific directory
|
|
|
|
- name: 'Post Coverage Comment using Composite Action'
|
|
uses: './.github/actions/post-coverage-comment' # Path to the composite action directory
|
|
with:
|
|
cli_json_file: 'coverage_artifact/cli/coverage/coverage-summary.json'
|
|
core_json_file: 'coverage_artifact/core/coverage/coverage-summary.json'
|
|
cli_full_text_summary_file: 'coverage_artifact/cli/coverage/full-text-summary.txt'
|
|
core_full_text_summary_file: 'coverage_artifact/core/coverage/full-text-summary.txt'
|
|
node_version: '${{ matrix.node-version }}'
|
|
os: '${{ matrix.os }}'
|
|
github_token: '${{ secrets.GITHUB_TOKEN }}'
|
|
|
|
codeql:
|
|
name: 'CodeQL'
|
|
needs: 'classify_pr'
|
|
if: "${{ !cancelled() && needs.classify_pr.outputs.skip_ci != 'true' }}"
|
|
runs-on: 'ubuntu-latest'
|
|
permissions:
|
|
actions: 'read'
|
|
contents: 'read'
|
|
security-events: 'write'
|
|
steps:
|
|
- name: 'Checkout'
|
|
uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6.0.2
|
|
|
|
- name: 'Initialize CodeQL'
|
|
uses: 'github/codeql-action/init@df559355d593797519d70b90fc8edd5db049e7a2' # ratchet:github/codeql-action/init@v3
|
|
with:
|
|
languages: 'javascript'
|
|
|
|
- name: 'Perform CodeQL Analysis'
|
|
uses: 'github/codeql-action/analyze@df559355d593797519d70b90fc8edd5db049e7a2' # ratchet:github/codeql-action/analyze@v3
|