( pluginId: string, source: PluginSource, manifest?: PluginManifest, installPath?: string, providedVersion?: string, gitCommitSha?: string, )
| 34 | * @returns Version string (semver, short SHA, or 'unknown') |
| 35 | */ |
| 36 | export async function calculatePluginVersion( |
| 37 | pluginId: string, |
| 38 | source: PluginSource, |
| 39 | manifest?: PluginManifest, |
| 40 | installPath?: string, |
| 41 | providedVersion?: string, |
| 42 | gitCommitSha?: string, |
| 43 | ): Promise<string> { |
| 44 | // 1. Use explicit version from plugin.json if available |
| 45 | if (manifest?.version) { |
| 46 | logForDebugging( |
| 47 | `Using manifest version for ${pluginId}: ${manifest.version}`, |
| 48 | ) |
| 49 | return manifest.version |
| 50 | } |
| 51 | |
| 52 | // 2. Use provided version (typically from marketplace entry) |
| 53 | if (providedVersion) { |
| 54 | logForDebugging( |
| 55 | `Using provided version for ${pluginId}: ${providedVersion}`, |
| 56 | ) |
| 57 | return providedVersion |
| 58 | } |
| 59 | |
| 60 | // 3. Use pre-resolved git SHA if caller captured it before discarding the clone |
| 61 | if (gitCommitSha) { |
| 62 | const shortSha = gitCommitSha.substring(0, 12) |
| 63 | if (typeof source === 'object' && source.source === 'git-subdir') { |
| 64 | // Encode the subdir path in the version so cache keys differ when |
| 65 | // marketplace.json's `path` changes but the monorepo SHA doesn't. |
| 66 | // Without this, two plugins at different subdirs of the same commit |
| 67 | // collide at cache/<m>/<p>/<sha>/ and serve each other's trees. |
| 68 | // |
| 69 | // Normalization MUST match the squashfs cron byte-for-byte: |
| 70 | // 1. backslash → forward slash |
| 71 | // 2. strip one leading `./` |
| 72 | // 3. strip all trailing `/` |
| 73 | // 4. UTF-8 sha256, first 8 hex chars |
| 74 | // See api/…/plugins_official_squashfs/job.py _validate_subdir(). |
| 75 | const normPath = source.path |
| 76 | .replace(/\\/g, '/') |
| 77 | .replace(/^\.\//, '') |
| 78 | .replace(/\/+$/, '') |
| 79 | const pathHash = createHash('sha256') |
| 80 | .update(normPath) |
| 81 | .digest('hex') |
| 82 | .substring(0, 8) |
| 83 | const v = `${shortSha}-${pathHash}` |
| 84 | logForDebugging( |
| 85 | `Using git-subdir SHA+path version for ${pluginId}: ${v} (path=${normPath})`, |
| 86 | ) |
| 87 | return v |
| 88 | } |
| 89 | logForDebugging(`Using pre-resolved git SHA for ${pluginId}: ${shortSha}`) |
| 90 | return shortSha |
| 91 | } |
| 92 | |
| 93 | // 4. Try to get git SHA from install path |
no test coverage detected