qwen-code/.github/workflows/release-vscode-companion.yml
mingholy.lmh f1c88e9bc9 style: apply formatting and linting fixes across codebase
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-06 21:58:22 +08:00

359 lines
13 KiB
YAML

name: 'Release VSCode IDE Companion'
on:
workflow_dispatch:
inputs:
version:
description: 'The version to release (e.g., v0.1.11). Required for manual patch releases.'
required: false
type: 'string'
ref:
description: 'The branch or ref (full git sha) to release from.'
required: true
type: 'string'
default: 'main'
dry_run:
description: 'Run a dry-run of the release process; no branches, vsix packages or GitHub releases will be created.'
required: true
type: 'boolean'
default: true
create_preview_release:
description: 'Create a preview release. If version includes -preview.<id>, it is used as-is; otherwise a timestamp is appended.'
required: false
type: 'boolean'
default: false
force_skip_tests:
description: 'Select to skip the "Run Tests" step in testing. Prod releases should run tests'
required: false
type: 'boolean'
default: false
concurrency:
group: '${{ github.workflow }}'
cancel-in-progress: false
jobs:
# First job: Determine version and run tests once
prepare:
runs-on: 'ubuntu-latest'
if: |-
${{ github.repository == 'QwenLM/qwen-code' }}
permissions:
contents: 'read'
outputs:
release_version: '${{ steps.version.outputs.RELEASE_VERSION }}'
release_tag: '${{ steps.version.outputs.RELEASE_TAG }}'
vscode_tag: '${{ steps.version.outputs.VSCODE_TAG }}'
is_preview: '${{ steps.vars.outputs.is_preview }}'
is_dry_run: '${{ steps.vars.outputs.is_dry_run }}'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
with:
ref: '${{ github.event.inputs.ref || github.sha }}'
fetch-depth: 0
- name: 'Set booleans for simplified logic'
env:
CREATE_PREVIEW_RELEASE: '${{ github.event.inputs.create_preview_release }}'
DRY_RUN_INPUT: '${{ github.event.inputs.dry_run }}'
id: 'vars'
run: |-
is_preview="false"
if [[ "${CREATE_PREVIEW_RELEASE}" == "true" ]]; then
is_preview="true"
fi
echo "is_preview=${is_preview}" >> "${GITHUB_OUTPUT}"
is_dry_run="false"
if [[ "${DRY_RUN_INPUT}" == "true" ]]; then
is_dry_run="true"
fi
echo "is_dry_run=${is_dry_run}" >> "${GITHUB_OUTPUT}"
- name: 'Setup Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
cache-dependency-path: 'package-lock.json'
- name: 'Install Dependencies'
env:
NPM_CONFIG_PREFER_OFFLINE: 'true'
run: |-
npm ci
- name: 'Get the version'
id: 'version'
working-directory: 'packages/vscode-ide-companion'
run: |
# Get the base version from package.json regardless of scenario
BASE_VERSION=$(node -p "require('./package.json').version")
if [[ "${IS_PREVIEW}" == "true" ]]; then
# Generate preview version. If a manual version is provided and already
# contains -preview.<id>, use it as-is (no timestamp). Otherwise, append
# a timestamp for uniqueness.
if [[ -n "${MANUAL_VERSION}" ]]; then
MANUAL_CLEAN="${MANUAL_VERSION#v}" # Remove 'v' prefix if present
if [[ "${MANUAL_CLEAN}" == *"-preview."* ]]; then
PREVIEW_VERSION="${MANUAL_CLEAN}"
else
PREVIEW_BASE="${MANUAL_CLEAN%%-*}" # Strip any prerelease/build
TIMESTAMP=$(date +%Y%m%d%H%M%S)
PREVIEW_VERSION="${PREVIEW_BASE}-preview.${TIMESTAMP}"
fi
else
TIMESTAMP=$(date +%Y%m%d%H%M%S)
PREVIEW_VERSION="${BASE_VERSION}-preview.${TIMESTAMP}"
fi
RELEASE_TAG="${PREVIEW_VERSION}"
echo "RELEASE_TAG=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"
echo "RELEASE_VERSION=${PREVIEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "VSCODE_TAG=preview" >> "$GITHUB_OUTPUT"
else
# Use specified version or get from package.json
if [[ -n "${MANUAL_VERSION}" ]]; then
RELEASE_VERSION="${MANUAL_VERSION#v}" # Remove 'v' prefix if present
RELEASE_TAG="${MANUAL_VERSION#v}" # Remove 'v' prefix if present
else
RELEASE_VERSION="${BASE_VERSION}"
RELEASE_TAG="${BASE_VERSION}"
fi
echo "RELEASE_TAG=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT"
echo "VSCODE_TAG=latest" >> "$GITHUB_OUTPUT"
fi
env:
IS_PREVIEW: '${{ steps.vars.outputs.is_preview }}'
MANUAL_VERSION: '${{ inputs.version }}'
- name: 'Build webui dependency'
if: |-
${{ github.event.inputs.force_skip_tests != 'true' }}
run: |
npm run build --workspace=@qwen-code/webui
- name: 'Run Tests'
if: |-
${{ github.event.inputs.force_skip_tests != 'true' }}
working-directory: 'packages/vscode-ide-companion'
run: |
npm run test:ci
env:
OPENAI_API_KEY: '${{ secrets.OPENAI_API_KEY }}'
OPENAI_BASE_URL: '${{ secrets.OPENAI_BASE_URL }}'
OPENAI_MODEL: '${{ secrets.OPENAI_MODEL }}'
# Second job: Build platform-specific VSIXes in parallel
build:
needs: 'prepare'
strategy:
fail-fast: false
matrix:
include:
# Platform-specific builds (with node-pty native binaries)
- os: 'ubuntu-latest'
target: 'linux-x64'
universal: false
# macOS 15 (x64): use macos-15-intel
# Endpoint Badge: macos-latest-large, macos-15-large, or macos-15-intel
- os: 'macos-15-intel'
target: 'darwin-x64'
universal: false
# macOS 15 Arm64: use macos-latest
# Endpoint Badge: macos-latest, macos-15, or macos-15-xlarge
- os: 'macos-latest'
target: 'darwin-arm64'
universal: false
- os: 'windows-latest'
target: 'win32-x64'
universal: false
# Universal fallback (without node-pty, uses child_process)
- os: 'ubuntu-latest'
target: ''
universal: true
runs-on: '${{ matrix.os }}'
permissions:
contents: 'read'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
with:
ref: '${{ github.event.inputs.ref || github.sha }}'
fetch-depth: 0
- name: 'Setup Node.js'
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
cache-dependency-path: 'package-lock.json'
- name: 'Install Dependencies'
env:
NPM_CONFIG_PREFER_OFFLINE: 'true'
run: |-
npm ci
- name: 'Install VSCE'
run: |-
npm install -g @vscode/vsce
- name: 'Update package version'
env:
RELEASE_VERSION: '${{ needs.prepare.outputs.release_version }}'
shell: 'bash'
run: |-
npm run release:version -- "${RELEASE_VERSION}"
- name: 'Prepare VSCode Extension'
env:
UNIVERSAL_BUILD: '${{ matrix.universal }}'
VSCODE_TARGET: '${{ matrix.target }}'
run: |
# Build and stage the extension + bundled CLI
npm --workspace=qwen-code-vscode-ide-companion run prepackage
- name: 'Package VSIX (platform-specific)'
if: "${{ matrix.target != '' }}"
working-directory: 'packages/vscode-ide-companion'
run: |-
if [[ "${{ needs.prepare.outputs.is_preview }}" == "true" ]]; then
vsce package --no-dependencies --pre-release --target ${{ matrix.target }} \
--out ../../qwen-code-vscode-companion-${{ needs.prepare.outputs.release_version }}-${{ matrix.target }}.vsix
else
vsce package --no-dependencies --target ${{ matrix.target }} \
--out ../../qwen-code-vscode-companion-${{ needs.prepare.outputs.release_version }}-${{ matrix.target }}.vsix
fi
shell: 'bash'
- name: 'Package VSIX (universal)'
if: "${{ matrix.target == '' }}"
working-directory: 'packages/vscode-ide-companion'
run: |-
if [[ "${{ needs.prepare.outputs.is_preview }}" == "true" ]]; then
vsce package --no-dependencies --pre-release \
--out ../../qwen-code-vscode-companion-${{ needs.prepare.outputs.release_version }}-universal.vsix
else
vsce package --no-dependencies \
--out ../../qwen-code-vscode-companion-${{ needs.prepare.outputs.release_version }}-universal.vsix
fi
shell: 'bash'
- name: 'Upload VSIX Artifact'
uses: 'actions/upload-artifact@v4'
with:
name: "vsix-${{ matrix.target || 'universal' }}"
path: 'qwen-code-vscode-companion-${{ needs.prepare.outputs.release_version }}-*.vsix'
if-no-files-found: 'error'
# Third job: Publish all VSIXes to marketplaces
publish:
needs:
- 'prepare'
- 'build'
runs-on: 'ubuntu-latest'
environment:
name: 'production-release'
url: '${{ github.server_url }}/${{ github.repository }}/releases/tag/vscode-companion-${{ needs.prepare.outputs.release_tag }}'
permissions:
contents: 'read'
issues: 'write'
steps:
- name: 'Checkout'
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
with:
ref: '${{ github.event.inputs.ref || github.sha }}'
- name: 'Download all VSIX artifacts'
uses: 'actions/download-artifact@v4'
with:
pattern: 'vsix-*'
path: 'vsix-artifacts'
merge-multiple: true
- name: 'List downloaded artifacts'
run: |-
echo "Downloaded VSIX files:"
ls -la vsix-artifacts/
- name: 'Install VSCE and OVSX'
run: |-
npm install -g @vscode/vsce
npm install -g ovsx
- name: 'Publish to Microsoft Marketplace'
if: "${{ needs.prepare.outputs.is_dry_run == 'false' && needs.prepare.outputs.is_preview != 'true' }}"
env:
VSCE_PAT: '${{ secrets.VSCE_PAT }}'
run: |-
echo "Publishing to Microsoft Marketplace..."
for vsix in vsix-artifacts/*.vsix; do
echo "Publishing: ${vsix}"
vsce publish --packagePath "${vsix}" --pat "${VSCE_PAT}" --skip-duplicate
done
- name: 'Publish to OpenVSX'
if: "${{ needs.prepare.outputs.is_dry_run == 'false' }}"
env:
OVSX_TOKEN: '${{ secrets.OVSX_TOKEN }}'
run: |-
echo "Publishing to OpenVSX..."
for vsix in vsix-artifacts/*.vsix; do
echo "Publishing: ${vsix}"
if [[ "${{ needs.prepare.outputs.is_preview }}" == "true" ]]; then
ovsx publish "${vsix}" --pat "${OVSX_TOKEN}" --pre-release
else
ovsx publish "${vsix}" --pat "${OVSX_TOKEN}"
fi
done
- name: 'Upload all VSIXes as release artifacts (dry run)'
if: "${{ needs.prepare.outputs.is_dry_run == 'true' }}"
uses: 'actions/upload-artifact@v4'
with:
name: 'all-vsix-packages-${{ needs.prepare.outputs.release_version }}'
path: 'vsix-artifacts/*.vsix'
if-no-files-found: 'error'
report-failure:
name: 'Create Issue on Failure'
needs:
- 'prepare'
- 'build'
- 'publish'
if: |-
${{
always() &&
(
needs.build.result == 'failure' ||
needs.build.result == 'cancelled' ||
needs.publish.result == 'failure' ||
needs.publish.result == 'cancelled'
)
}}
runs-on: 'ubuntu-latest'
permissions:
contents: 'read'
issues: 'write'
steps:
- name: 'Create failure issue'
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
RELEASE_VERSION: '${{ needs.prepare.outputs.release_version }}'
DETAILS_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
GH_REPO: '${{ github.repository }}'
run: |-
gh issue create \
--repo "${GH_REPO}" \
--title "VSCode IDE Companion Release Failed for ${RELEASE_VERSION} on $(date +'%Y-%m-%d')" \
--body "The VSCode IDE Companion release workflow failed. See the full run for details: ${DETAILS_URL}"