diff --git a/.github/renovate.json b/.github/renovate.json index 148ff41e71..6094e39d65 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -11,6 +11,17 @@ "rolldown/**", "vite/**" ], + "customManagers": [ + { + "description": "Keep the exact setup-vp migration target current.", + "customType": "regex", + "managerFilePatterns": ["/^packages\\/cli\\/src\\/utils\\/constants\\.ts$/"], + "matchStrings": ["export const SETUP_VP_VERSION = '(?[^']+)';"], + "depNameTemplate": "voidzero-dev/setup-vp", + "datasourceTemplate": "github-releases", + "versioningTemplate": "semver-coerced" + } + ], "packageRules": [ { "description": "Ignore upstream toolchain npm packages (vendored via sync-remote or bumped by the proactive catalog workflow); everything else stays enabled so security alerts get fixed.", diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/package.json new file mode 100644 index 0000000000..cd0302a72e --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/package.json @@ -0,0 +1,11 @@ +{ + "name": "migration-setup-vp-version", + "devDependencies": { + "vite": "npm:@voidzero-dev/vite-plus-core@0.0.0-commit.0c515e3fbf5c140db35280d700df0bd600838617", + "vite-plus": "0.0.0-commit.0c515e3fbf5c140db35280d700df0bd600838617" + }, + "overrides": { + "vite": "npm:@voidzero-dev/vite-plus-core@0.0.0-commit.0c515e3fbf5c140db35280d700df0bd600838617" + }, + "packageManager": "npm@11.11.1" +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/snapshots.toml new file mode 100644 index 0000000000..ef11bbcd38 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/snapshots.toml @@ -0,0 +1,12 @@ +[[case]] +name = "migration_setup_vp_version" +vp = "global" +env = { VP_OVERRIDE_PACKAGES = "{\"vite\":\"npm:@voidzero-dev/vite-plus-core@0.0.0-commit.0c515e3fbf5c140db35280d700df0bd600838617\",\"vitest\":\"4.1.11\"}", VP_VERSION = "0.0.0-commit.0c515e3fbf5c140db35280d700df0bd600838617" } +steps = [ + { argv = ["vpt", "mkdir", "-p", ".github/workflows"], snapshot = false }, + { argv = ["vpt", "cp", "workflow.txt", ".github/workflows/ci.yml"], snapshot = false }, + { argv = ["vp", "migrate", "--no-interactive"], comment = "an existing Vite+ project upgrades the frozen setup-vp tag", continue-on-failure = true }, + { argv = ["vpt", "print-file", ".github/workflows/ci.yml"], comment = "the workflow uses the exact setup-vp release", continue-on-failure = true }, + { argv = ["vp", "migrate", "--no-interactive"], comment = "the setup-vp migration is idempotent", continue-on-failure = true }, + { argv = ["vpt", "print-file", ".github/workflows/ci.yml"], comment = "the exact setup-vp release remains unchanged", continue-on-failure = true }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/snapshots/migration_setup_vp_version.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/snapshots/migration_setup_vp_version.md new file mode 100644 index 0000000000..f1286894e7 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/snapshots/migration_setup_vp_version.md @@ -0,0 +1,71 @@ +# migration_setup_vp_version + +## `vpt mkdir -p .github/workflows` + + +## `vpt cp workflow.txt .github/workflows/ci.yml` + + +## `vp migrate --no-interactive` + +an existing Vite+ project upgrades the frozen setup-vp tag + +``` +VITE+ - The Unified Toolchain for the Web + +◇ Updated . to Vite+ +• Node npm +• Dependencies: + vite → +• setup-vp updated to in 1 GitHub Actions file +``` + +## `vpt print-file .github/workflows/ci.yml` + +the workflow uses the exact setup-vp release + +``` +name: CI + +on: [push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: voidzero-dev/setup-vp@ + with: + cache: true + - run: vp test +``` + +## `vp migrate --no-interactive` + +the setup-vp migration is idempotent + +``` +VITE+ - The Unified Toolchain for the Web + +This project is already using Vite+! Happy coding! +``` + +## `vpt print-file .github/workflows/ci.yml` + +the exact setup-vp release remains unchanged + +``` +name: CI + +on: [push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: voidzero-dev/setup-vp@ + with: + cache: true + - run: vp test +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/workflow.txt b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/workflow.txt new file mode 100644 index 0000000000..c437dc5966 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_setup_vp_version/workflow.txt @@ -0,0 +1,13 @@ +name: CI + +on: [push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: voidzero-dev/setup-vp@v1 + with: + cache: true + - run: vp test diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/new_create_vite/snapshots/new_create_vite.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/new_create_vite/snapshots/new_create_vite.md index 363845c5ea..d520ed6d39 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/new_create_vite/snapshots/new_create_vite.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/new_create_vite/snapshots/new_create_vite.md @@ -111,7 +111,7 @@ jobs: with: persist-credentials: false - name: Set up Vite+ - uses: voidzero-dev/setup-vp@v1 + uses: voidzero-dev/setup-vp@ with: cache: true run-install: true diff --git a/docs/guide/ci.md b/docs/guide/ci.md index c64fe477ff..00c103a5b1 100644 --- a/docs/guide/ci.md +++ b/docs/guide/ci.md @@ -10,6 +10,11 @@ You can use `voidzero-dev/setup-vp` to use Vite+ in CI environments. Set `` in each example to an exact version from the [`setup-vp` releases page](https://github.com/voidzero-dev/setup-vp/releases). You can use a commit SHA instead. Do not use the `v1` tag. The `v1` tag no longer receives updates. +Run `vp migrate` to replace exact `voidzero-dev/setup-vp@v1` references in +GitHub Actions workflows and composite actions under `.github` with the latest +exact release known to your Vite+ version. Existing exact versions and commit +SHAs remain unchanged. + ### Automatic Version Updates Dependabot and Renovate can update exact versions in GitHub Actions workflows. diff --git a/docs/guide/migrate-rules.md b/docs/guide/migrate-rules.md index 063d291119..a7eb4e2689 100644 --- a/docs/guide/migrate-rules.md +++ b/docs/guide/migrate-rules.md @@ -252,6 +252,14 @@ as `run` or `--`: Unrelated `bunx` commands and other package-executor forms remain unchanged. +## Continuous Integration Rules + +Migration replaces exact `voidzero-dev/setup-vp@v1` references in GitHub +Actions workflows and composite actions under `.github` with the latest exact +`setup-vp` release known to that Vite+ version. The frozen `v1` tag does not +receive new releases. Existing exact versions and commit SHAs are left +unchanged. + ## Node.js Version Rules Migration converts legacy Node.js version-manager files to `.node-version`, @@ -263,8 +271,9 @@ migrations run it unconditionally. existing `.node-version` is kept. - When `.nvmrc` is removed, any `actions/setup-node` `node-version-file: .nvmrc` reference in `.github/workflows/*.{yml,yaml}` and composite actions - (`.github/actions/**/action.{yml,yaml}`) is repointed to `.node-version` so - CI does not fail with "node version file ... does not exist". + under `.github` (`.github/**/action.{yml,yaml}`) is repointed to + `.node-version` so CI does not fail with "node version file ... does not + exist". ## Package-Manager Rules diff --git a/packages/cli/src/migration/__tests__/migrator.spec.ts b/packages/cli/src/migration/__tests__/migrator.spec.ts index d75bbb879f..c07158b82b 100644 --- a/packages/cli/src/migration/__tests__/migrator.spec.ts +++ b/packages/cli/src/migration/__tests__/migrator.spec.ts @@ -8,7 +8,11 @@ import { parseAllDocuments, parse as parseYaml } from 'yaml'; import { rewriteScripts } from '../../../binding/index.js'; import { PackageManager } from '../../types/index.js'; -import { VITE_PLUS_OVERRIDE_PACKAGES, VITEST_VERSION } from '../../utils/constants.js'; +import { + SETUP_VP_VERSION, + VITE_PLUS_OVERRIDE_PACKAGES, + VITEST_VERSION, +} from '../../utils/constants.js'; import { createMigrationReport } from '../report.js'; // Mock VITE_PLUS_VERSION to a stable value for snapshot tests. @@ -40,6 +44,7 @@ const { parseNvmrcVersion, detectNodeVersionManagerFile, migrateNodeVersionManagerFile, + migrateSetupVpVersion, detectFramework, hasFrameworkShim, addFrameworkShim, @@ -1446,6 +1451,125 @@ describe('setPackageManager', () => { }); }); +describe('migrateSetupVpVersion', () => { + let tmpDir: string; + + beforeEach(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vp-test-setup-vp-')); + }); + + afterEach(() => { + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + it('updates exact v1 references in workflows and composite actions', () => { + const workflowsDir = path.join(tmpDir, '.github', 'workflows'); + const actionDir = path.join(tmpDir, '.github', 'actions', 'setup'); + fs.mkdirSync(path.join(workflowsDir, 'nested'), { recursive: true }); + fs.mkdirSync(actionDir, { recursive: true }); + + const workflowPath = path.join(workflowsDir, 'ci.yml'); + fs.writeFileSync( + workflowPath, + [ + 'steps:', + ' - uses: voidzero-dev/setup-vp@v1', + " - uses: 'voidzero-dev/setup-vp@v1' # keep this comment", + ' - uses: "voidzero-dev/setup-vp@v1"', + ' - uses: voidzero-dev/setup-vp@v1.16.1', + ' - uses: voidzero-dev/setup-vp@v10', + ' - uses: voidzero-dev/setup-vp@313600b', + ' # - uses: voidzero-dev/setup-vp@v1', + '', + ].join('\r\n'), + ); + const actionPath = path.join(actionDir, 'action.yaml'); + fs.writeFileSync( + actionPath, + 'runs:\n using: composite\n steps:\n - uses : voidzero-dev/setup-vp@v1\n', + ); + const nestedWorkflowPath = path.join(workflowsDir, 'nested', 'ignored.yml'); + fs.writeFileSync(nestedWorkflowPath, '- uses: voidzero-dev/setup-vp@v1\n'); + const report = createMigrationReport(); + + const updatedFiles = migrateSetupVpVersion(tmpDir, report).map((filePath) => + filePath.split(path.sep).join('/'), + ); + + expect(updatedFiles).toHaveLength(2); + expect(updatedFiles).toEqual( + expect.arrayContaining(['.github/workflows/ci.yml', '.github/actions/setup/action.yaml']), + ); + expect(fs.readFileSync(workflowPath, 'utf8')).toBe( + [ + 'steps:', + ` - uses: voidzero-dev/setup-vp@${SETUP_VP_VERSION}`, + ` - uses: 'voidzero-dev/setup-vp@${SETUP_VP_VERSION}' # keep this comment`, + ` - uses: "voidzero-dev/setup-vp@${SETUP_VP_VERSION}"`, + ' - uses: voidzero-dev/setup-vp@v1.16.1', + ' - uses: voidzero-dev/setup-vp@v10', + ' - uses: voidzero-dev/setup-vp@313600b', + ' # - uses: voidzero-dev/setup-vp@v1', + '', + ].join('\r\n'), + ); + expect(fs.readFileSync(actionPath, 'utf8')).toContain( + `uses : voidzero-dev/setup-vp@${SETUP_VP_VERSION}`, + ); + expect(fs.readFileSync(nestedWorkflowPath, 'utf8')).toContain('setup-vp@v1'); + expect(report.setupVpVersionUpdatedFileCount).toBe(2); + + expect(migrateSetupVpVersion(tmpDir, report)).toEqual([]); + expect(report.setupVpVersionUpdatedFileCount).toBe(2); + }); + + it('updates composite actions elsewhere under .github and stays within that directory', () => { + const actionPath = path.join(tmpDir, '.github', 'ci', 'actions', 'setup', 'action.yml'); + const nonCompositePath = path.join( + tmpDir, + '.github', + 'ci', + 'actions', + 'javascript', + 'action.yml', + ); + const outsideScopePath = path.join(tmpDir, 'ci', 'actions', 'outside-scope', 'action.yml'); + const compositeAction = + 'runs:\n using: composite\n steps:\n - uses: voidzero-dev/setup-vp@v1\n'; + const nonCompositeAction = [ + 'inputs:', + ' example:', + ' description: Example workflow text', + ' default: |', + ' - uses: voidzero-dev/setup-vp@v1', + 'runs:', + ' using: node20', + ' main: index.js', + '', + ].join('\n'); + + fs.mkdirSync(path.dirname(actionPath), { recursive: true }); + fs.mkdirSync(path.dirname(nonCompositePath), { recursive: true }); + fs.mkdirSync(path.dirname(outsideScopePath), { recursive: true }); + fs.writeFileSync(actionPath, compositeAction); + fs.writeFileSync(nonCompositePath, nonCompositeAction); + fs.writeFileSync(outsideScopePath, compositeAction); + const report = createMigrationReport(); + + const updatedFiles = migrateSetupVpVersion(tmpDir, report).map((filePath) => + filePath.split(path.sep).join('/'), + ); + + expect(updatedFiles).toEqual(['.github/ci/actions/setup/action.yml']); + expect(fs.readFileSync(actionPath, 'utf8')).toContain( + `uses: voidzero-dev/setup-vp@${SETUP_VP_VERSION}`, + ); + expect(fs.readFileSync(nonCompositePath, 'utf8')).toBe(nonCompositeAction); + expect(fs.readFileSync(outsideScopePath, 'utf8')).toBe(compositeAction); + expect(report.setupVpVersionUpdatedFileCount).toBe(1); + }); +}); + describe('detectNodeVersionManagerFile', () => { let tmpDir: string; diff --git a/packages/cli/src/migration/bin.ts b/packages/cli/src/migration/bin.ts index 09aa45c993..dbf64a30c4 100644 --- a/packages/cli/src/migration/bin.ts +++ b/packages/cli/src/migration/bin.ts @@ -12,7 +12,7 @@ import { type WorkspacePackage, } from '../types/index.ts'; import { writeAgentInstructions } from '../utils/agent.ts'; -import { isForceOverrideMode, VITE_PLUS_VERSION } from '../utils/constants.ts'; +import { isForceOverrideMode, SETUP_VP_VERSION, VITE_PLUS_VERSION } from '../utils/constants.ts'; import { writeEditorConfigs } from '../utils/editor.ts'; import { renderCliDoc } from '../utils/help.ts'; import { hasVitePlusDependency, readNearestPackageJson } from '../utils/package.ts'; @@ -61,6 +61,7 @@ import { migrateEslintToOxlint, migrateNodeVersionManagerFile, migratePrettierToOxfmt, + migrateSetupVpVersion, migrateTsupToTsdown, configureYarnNodeModulesMode, rewriteMonorepo, @@ -717,6 +718,13 @@ function showMigrationSummary(options: { if (report.nodeVersionFileMigrated) { log(`${styleText('gray', '•')} Node version manager file migrated to .node-version`); } + const setupVpFileCount = report.setupVpVersionUpdatedFileCount; + if (setupVpFileCount > 0) { + const fileLabel = setupVpFileCount === 1 ? 'file' : 'files'; + log( + `${styleText('gray', '•')} setup-vp updated to ${SETUP_VP_VERSION} in ${setupVpFileCount} GitHub Actions ${fileLabel}`, + ); + } if (report.wrappedPluginConfigCount > 0) { log( `${styleText('gray', '•')} Inline Vite plugins wrapped with lazyPlugins for check/lint/fmt`, @@ -869,6 +877,9 @@ async function executeMigrationPlan( migrateNodeVersionManagerFile(workspaceInfo.rootDir, plan.nodeVersionDetection, report); } + updateMigrationProgress('Updating setup-vp workflows'); + migrateSetupVpVersion(workspaceInfo.rootDir, report); + // 4. Run vp install to ensure the project is ready updateMigrationProgress('Installing dependencies'); const initialInstallSummary = await runViteInstall( @@ -1146,6 +1157,11 @@ async function main() { } }; + updateMigrationProgress('Updating setup-vp workflows'); + if (migrateSetupVpVersion(workspaceInfoOptional.rootDir, report).length > 0) { + didMigrate = true; + } + const pendingCoreMigration = detectPendingCoreMigration(workspaceInfoOptional); const vitePlusBootstrapPending = detectVitePlusBootstrapPending( workspaceInfoOptional.rootDir, diff --git a/packages/cli/src/migration/migrator/README.md b/packages/cli/src/migration/migrator/README.md index 0c3aad0389..c7bd615944 100644 --- a/packages/cli/src/migration/migrator/README.md +++ b/packages/cli/src/migration/migrator/README.md @@ -35,7 +35,7 @@ Pick the file by what a function _does_, not by where it happens to be called. | `tsconfig.ts` | `tsconfig.json` cleanup and `types` rewriting. | | `framework-shim.ts` | Framework (Vue/Astro) shim detection and injection. | | `git-hooks.ts` | Vite+ hook defaults, project-owned hook preservation, and conservative detection of existing hook tools. | -| `setup.ts` | `packageManager` pin and Node version-manager file (`.nvmrc`/`.node-version`/Volta) migration. | +| `setup.ts` | `packageManager` pin, `setup-vp` GitHub Actions version, and Node version-manager file (`.nvmrc`/`.node-version`/Volta) migration. | | `core-finalization.ts` | Finalizing an existing-Vite+ core migration (rules YAML, core package scripts). | | `shared.ts` | Cross-cutting constants, types, and tiny utilities used by **two or more** modules. The only module that other modules import from directly (see rules). | diff --git a/packages/cli/src/migration/migrator/setup.ts b/packages/cli/src/migration/migrator/setup.ts index 42c8ccaca6..1dfdc41b39 100644 --- a/packages/cli/src/migration/migrator/setup.ts +++ b/packages/cli/src/migration/migrator/setup.ts @@ -4,12 +4,14 @@ import path from 'node:path'; import * as prompts from '@voidzero-dev/vite-plus-prompts'; import { globSync } from 'glob'; import semver from 'semver'; +import { parse as parseYaml } from 'yaml'; import { type DownloadPackageManagerResult } from '../../../binding/index.js'; +import { SETUP_VP_VERSION } from '../../utils/constants.ts'; import { editJsonFile } from '../../utils/json.ts'; import { detectConfigs } from '../detector.ts'; import { type MigrationReport } from '../report.ts'; -import { warnMigration } from './shared.ts'; +import { isPlainRecord, warnMigration } from './shared.ts'; export function setPackageManager( projectDir: string, @@ -129,20 +131,79 @@ export function parseNvmrcVersion(alias: string): string | null { */ const NODE_VERSION_FILE_NVMRC_RE = /(node-version-file:[ \t]*)(['"]?)(\.\/)?\.nvmrc\2(?=\s|$)/gm; +function isCompositeActionFile(filePath: string): boolean { + try { + const action = parseYaml(fs.readFileSync(filePath, 'utf8')) as unknown; + return isPlainRecord(action) && isPlainRecord(action.runs) && action.runs.using === 'composite'; + } catch { + return false; + } +} + /** - * Collect GitHub Actions YAML files that may carry a `node-version-file:` - * reference: top-level workflows (`.github/workflows/*.{yml,yaml}`, which GitHub - * runs only when flat in that directory) and composite action definitions - * (`.github/actions/**\/action.{yml,yaml}`, which may nest at any depth). Returns - * absolute paths; a missing `.github` tree just yields an empty list. `nocase` - * keeps the match case-insensitive on case-sensitive filesystems. + * Collect top-level workflows and composite action definitions under `.github`. + * Action metadata must declare `runs.using: composite`. Paths are absolute, and + * filename matching is case-insensitive. */ function collectGithubActionFiles(projectPath: string): string[] { - return globSync(['workflows/*.{yml,yaml}', 'actions/**/action.{yml,yaml}'], { + const globOptions = { cwd: path.join(projectPath, '.github'), absolute: true, nocase: true, - }); + nodir: true, + } as const; + const workflows = globSync('workflows/*.{yml,yaml}', globOptions); + const compositeActions = globSync('**/action.{yml,yaml}', { + ...globOptions, + dot: true, + }).filter(isCompositeActionFile); + + return [...new Set([...workflows, ...compositeActions])]; +} + +/** + * Match an exact `voidzero-dev/setup-vp@v1` action reference while preserving + * indentation, list syntax, quote style, and trailing comments. The end guard + * prevents prefix matches such as `@v1.2.3` or `@v10`. + */ +const SETUP_VP_V1_RE = + /^([ \t]*(?:-[ \t]*)?uses[ \t]*:[ \t]*)(['"]?)voidzero-dev\/setup-vp@v1\2(?=[ \t]*(?:#.*)?\r?$)/gm; + +/** + * Replace the frozen `voidzero-dev/setup-vp@v1` tag with the latest exact + * release known to this Vite+ version. GitHub workflow files and composite + * action definitions are both covered. Existing exact versions, commit SHAs, + * and commented-out steps are left unchanged. + * + * Returns the project-relative paths of the updated files. + */ +export function migrateSetupVpVersion(projectPath: string, report?: MigrationReport): string[] { + const updatedFiles: string[] = []; + + for (const filePath of collectGithubActionFiles(projectPath)) { + const relativePath = path.relative(projectPath, filePath); + try { + const original = fs.readFileSync(filePath, 'utf8'); + const rewritten = original.replace( + SETUP_VP_V1_RE, + `$1$2voidzero-dev/setup-vp@${SETUP_VP_VERSION}$2`, + ); + if (rewritten !== original) { + fs.writeFileSync(filePath, rewritten); + updatedFiles.push(relativePath); + } + } catch (error) { + warnMigration( + `Could not update the setup-vp version in ${relativePath}: ${error instanceof Error ? error.message : String(error)}`, + report, + ); + } + } + + if (report) { + report.setupVpVersionUpdatedFileCount += updatedFiles.length; + } + return updatedFiles; } /** diff --git a/packages/cli/src/migration/report.ts b/packages/cli/src/migration/report.ts index 4de0bc25a2..2225ef596c 100644 --- a/packages/cli/src/migration/report.ts +++ b/packages/cli/src/migration/report.ts @@ -25,6 +25,7 @@ export interface MigrationReport { prettierMigrated: boolean; tsupMigrated: boolean; nodeVersionFileMigrated: boolean; + setupVpVersionUpdatedFileCount: number; gitHooksConfigured: boolean; frameworkShimAdded: boolean; packageManagerBootstrapConfigured: boolean; @@ -49,6 +50,7 @@ export function createMigrationReport(): MigrationReport { tsupMigrated: false, prettierMigrated: false, nodeVersionFileMigrated: false, + setupVpVersionUpdatedFileCount: 0, gitHooksConfigured: false, frameworkShimAdded: false, packageManagerBootstrapConfigured: false, diff --git a/packages/cli/src/utils/__tests__/agent.spec.ts b/packages/cli/src/utils/__tests__/agent.spec.ts index f43419b993..9fa7da2bfe 100644 --- a/packages/cli/src/utils/__tests__/agent.spec.ts +++ b/packages/cli/src/utils/__tests__/agent.spec.ts @@ -17,6 +17,7 @@ import { writeAgentInstructions, writeCopilotSetupWorkflow, } from '../agent.js'; +import { SETUP_VP_VERSION } from '../constants.js'; import { pkgRoot } from '../path.js'; type MockNode = @@ -536,7 +537,7 @@ describe('writeCopilotSetupWorkflow', () => { expect(content).toContain('runs-on: ubuntu-latest'); expect(content).toContain('persist-credentials: false'); expect(content).toContain('uses: actions/checkout@v6'); - expect(content).toContain('uses: voidzero-dev/setup-vp@v1'); + expect(content).toContain(`uses: voidzero-dev/setup-vp@${SETUP_VP_VERSION}`); expect(content).toContain('run-install: true'); expect(content).toContain('- .github/workflows/copilot-setup-steps.yml'); diff --git a/packages/cli/src/utils/agent.ts b/packages/cli/src/utils/agent.ts index 885c119d83..2b78b197b2 100644 --- a/packages/cli/src/utils/agent.ts +++ b/packages/cli/src/utils/agent.ts @@ -5,6 +5,7 @@ import { styleText } from 'node:util'; import * as prompts from '@voidzero-dev/vite-plus-prompts'; +import { SETUP_VP_VERSION } from './constants.ts'; import { pkgRoot } from './path.ts'; // --- Backward-compatible exports --- @@ -105,7 +106,7 @@ jobs: with: persist-credentials: false - name: Set up Vite+ - uses: voidzero-dev/setup-vp@v1 + uses: voidzero-dev/setup-vp@${SETUP_VP_VERSION} with: cache: true run-install: true diff --git a/packages/cli/src/utils/constants.ts b/packages/cli/src/utils/constants.ts index 8e8131d3d0..efa75e4d62 100644 --- a/packages/cli/src/utils/constants.ts +++ b/packages/cli/src/utils/constants.ts @@ -17,6 +17,10 @@ export const VITE_CONFIG_FILES = [ export const VITEST_VERSION = '4.1.11'; +// Exact action release used by generated workflows and the @v1 migration. +// The Renovate custom manager keeps this value current. +export const SETUP_VP_VERSION = 'v1.18.0'; + // Stable 0.22.x predates non-TTY support. The dependency upgrade script replaces // this RC with the matching stable version when the bundled tsdown version advances. export const TSDOWN_MIGRATE_VERSION = '0.23.0-rc.0';