mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 11:41:04 +00:00
359 lines
13 KiB
YAML
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}"
|