From 65726c90fd5568d1269bf4ebfb4926b9ea4dd1e1 Mon Sep 17 00:00:00 2001 From: peternhale Date: Wed, 12 Aug 2026 14:21:48 -0600 Subject: [PATCH 01/12] fix: support package manager retries in VS Code promotion --- .../actions/npmInstallWithRetries/action.yml | 2 +- .github/actions/updateNodeLockfile/action.yml | 60 ++++++++++ .github/workflows/vscode-manual-publish.yml | 111 +++++++++++++++--- .../workflows/vscode-promote-prerelease.yml | 3 - .github/workflows/vscode-promote-stable.yml | 110 +++++++++++++---- 5 files changed, 247 insertions(+), 39 deletions(-) create mode 100644 .github/actions/updateNodeLockfile/action.yml diff --git a/.github/actions/npmInstallWithRetries/action.yml b/.github/actions/npmInstallWithRetries/action.yml index 30c64cf..78e9829 100644 --- a/.github/actions/npmInstallWithRetries/action.yml +++ b/.github/actions/npmInstallWithRetries/action.yml @@ -1,5 +1,5 @@ name: npm-install-with-retries -description: 'wraps npm install with retries/timeout to handle network failures' +description: 'Wraps npm ci with retries and timeouts. New workflows should use setupNodeAndInstall for package-manager-agnostic installation.' inputs: ignore-scripts: default: 'false' diff --git a/.github/actions/updateNodeLockfile/action.yml b/.github/actions/updateNodeLockfile/action.yml new file mode 100644 index 0000000..3e4ceca --- /dev/null +++ b/.github/actions/updateNodeLockfile/action.yml @@ -0,0 +1,60 @@ +name: Update Node lockfile +description: Refreshes an npm, pnpm, or Yarn lockfile with retries and without lifecycle scripts. +inputs: + package-manager: + description: 'Package manager to use: npm, pnpm, or yarn.' + required: true + package-manager-version: + description: 'pnpm version to install when package-manager is pnpm.' + required: false + default: '10' + lockfile-path: + description: 'Path to the lockfile to refresh.' + required: true +runs: + using: composite + steps: + - name: Validate package manager and lockfile + shell: bash + env: + PACKAGE_MANAGER: ${{ inputs.package-manager }} + LOCKFILE_PATH: ${{ inputs.lockfile-path }} + run: | + case "$PACKAGE_MANAGER" in + npm|pnpm|yarn) ;; + *) echo "Unsupported package manager: $PACKAGE_MANAGER"; exit 1 ;; + esac + [ -f "$LOCKFILE_PATH" ] || { echo "Lockfile not found: $LOCKFILE_PATH"; exit 1; } + + - name: Setup pnpm + if: inputs.package-manager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.package-manager-version }} + + - name: Resolve lockfile update command + id: command + shell: bash + env: + PACKAGE_MANAGER: ${{ inputs.package-manager }} + LOCKFILE_PATH: ${{ inputs.lockfile-path }} + run: | + LOCKFILE_DIR=$(dirname "$LOCKFILE_PATH") + case "$PACKAGE_MANAGER" in + npm) COMMAND="cd '$LOCKFILE_DIR' && npm install --package-lock-only --ignore-scripts" ;; + pnpm) COMMAND="cd '$LOCKFILE_DIR' && pnpm install --lockfile-only --ignore-scripts" ;; + yarn) + YARN_MAJOR=$(yarn --version | cut -d. -f1) + if [ "$YARN_MAJOR" -ge 2 ]; then + COMMAND="cd '$LOCKFILE_DIR' && YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install --mode=skip-build" + else + COMMAND="cd '$LOCKFILE_DIR' && yarn install --ignore-scripts" + fi + ;; + esac + echo "value=$COMMAND" >> "$GITHUB_OUTPUT" + + - name: Refresh lockfile with retries + uses: salesforcecli/github-workflows/.github/actions/retry@main + with: + command: ${{ steps.command.outputs.value }} diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index 78ed14e..ace8c31 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -22,7 +22,7 @@ name: Manual Publish VS Code Extension # # Requirements - calling repository must have: # - Secrets: IDEE_GH_TOKEN, VSCE_PERSONAL_ACCESS_TOKEN, IDEE_OVSX_PAT -# - Action: ./.github/actions/npm-install-with-retries (custom npm install with retry logic) +# - The package manager and lockfile inputs must match the caller repository. # - Action: ./.github/actions/check-ci-status (validates CI checks passed before publish) # - Action: ./.github/actions/repackage-vsix-stable (repackages pre-release VSIX as stable) # - Action: ./.github/actions/publish-vsix (publishes to VS Code Marketplace and/or Open VSX) @@ -106,6 +106,31 @@ on: required: false default: "22.x" type: string + package-manager: + description: "Package manager to use: npm, pnpm, or yarn" + required: false + default: "npm" + type: string + package-manager-version: + description: "pnpm version to use when package-manager is pnpm" + required: false + default: "10" + type: string + cache-dependency-path: + description: "Path to the package manager lockfile" + required: false + default: "package-lock.json" + type: string + lockfile-path: + description: "Single lockfile path to update and commit with the stable version" + required: false + default: "package-lock.json" + type: string + install-command: + description: "Command used to install dependencies" + required: false + default: "npm ci" + type: string workflow_dispatch: inputs: extension-name: @@ -187,6 +212,32 @@ on: required: false default: "22.x" type: string + package-manager: + description: "Package manager to use: npm, pnpm, or yarn" + required: false + default: "npm" + type: choice + options: [npm, pnpm, yarn] + package-manager-version: + description: "pnpm version to use when package-manager is pnpm" + required: false + default: "10" + type: string + cache-dependency-path: + description: "Path to the package manager lockfile" + required: false + default: "package-lock.json" + type: string + lockfile-path: + description: "Single lockfile path to update and commit with the stable version" + required: false + default: "package-lock.json" + type: string + install-command: + description: "Command used to install dependencies" + required: false + default: "npm ci" + type: string concurrency: group: manual-publish @@ -253,13 +304,14 @@ jobs: fetch-depth: 0 token: ${{ secrets.IDEE_GH_TOKEN }} - - name: Setup Node.js - uses: actions/setup-node@v6 + - name: Setup Node.js and install dependencies + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main with: node-version: ${{ inputs.node-version || '22.x' }} - - - name: Install dependencies - uses: ./.github/actions/npm-install-with-retries + package-manager: ${{ inputs.package-manager }} + package-manager-version: ${{ inputs.package-manager-version }} + cache-dependency-path: ${{ inputs.cache-dependency-path }} + install-command: ${{ inputs.install-command }} - name: Resolve source and compute versions id: resolve @@ -612,6 +664,12 @@ jobs: with: node-version: ${{ inputs.node-version || '22.x' }} + - name: Setup pnpm + if: inputs.package-manager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.package-manager-version }} + - name: Download source VSIX uses: actions/download-artifact@v8 with: @@ -677,9 +735,6 @@ jobs: with: node-version: ${{ inputs.node-version || '22.x' }} - - name: Install dependencies - uses: ./.github/actions/npm-install-with-retries - - name: Download VSIX uses: actions/download-artifact@v8 with: @@ -845,7 +900,8 @@ jobs: with: node-version: ${{ inputs.node-version || '22.x' }} - - name: Commit stable version bump to main + - name: Update stable version + id: update-version env: STABLE_VERSION: ${{ needs.prepare.outputs.stable-version }} DRY_RUN: ${{ inputs.dry-run || 'false' }} @@ -876,11 +932,13 @@ jobs: ') if [ "$IS_GT" != "yes" ]; then echo "Skipping commit-back: main ($CURRENT_VERSION) is already >= stable ($STABLE_VERSION)" + echo "should-commit=false" >> "$GITHUB_OUTPUT" exit 0 fi if [ "$DRY_RUN" = "true" ]; then echo "DRY RUN: Would set $PKG_DIR to $STABLE_VERSION and commit to main" + echo "should-commit=false" >> "$GITHUB_OUTPUT" exit 0 fi @@ -890,12 +948,35 @@ jobs: ( cd "$PKG_DIR" && npm version "$STABLE_VERSION" --no-git-tag-version ) - npm install --package-lock-only --ignore-scripts + git add "$PKG_DIR/package.json" + if git diff --cached --quiet -- "$PKG_DIR/package.json"; then + echo "Package version was not updated: $PKG_DIR/package.json" + exit 1 + fi + echo "should-commit=true" >> "$GITHUB_OUTPUT" - git add "$PKG_DIR/package.json" package-lock.json - if git diff --staged --quiet; then - echo "No version change to commit - skipping (idempotent rerun)" - exit 0 + - name: Refresh lockfile with retries + if: steps.update-version.outputs.should-commit == 'true' + uses: salesforcecli/github-workflows/.github/actions/updateNodeLockfile@main + with: + package-manager: ${{ inputs.package-manager }} + package-manager-version: ${{ inputs.package-manager-version }} + lockfile-path: ${{ inputs.lockfile-path }} + + - name: Commit stable version bump + if: steps.update-version.outputs.should-commit == 'true' + env: + STABLE_VERSION: ${{ needs.prepare.outputs.stable-version }} + EXTENSION_NAME: ${{ inputs.extension-name }} + EXTENSIONS_ROOT: ${{ inputs.extensions-root }} + LOCKFILE_PATH: ${{ inputs.lockfile-path }} + run: | + set -euo pipefail + git add "$LOCKFILE_PATH" + if [ -n "$(git diff --name-only)" ]; then + echo "Lockfile refresh produced unstaged changes:" + git diff --name-only + exit 1 fi git commit -m "chore: set stable version $STABLE_VERSION [skip ci]" diff --git a/.github/workflows/vscode-promote-prerelease.yml b/.github/workflows/vscode-promote-prerelease.yml index c101c5f..9f79a24 100644 --- a/.github/workflows/vscode-promote-prerelease.yml +++ b/.github/workflows/vscode-promote-prerelease.yml @@ -210,9 +210,6 @@ jobs: with: node-version: ${{ inputs.node-version || '22.x' }} - - name: Install dependencies - uses: salesforcecli/github-workflows/.github/actions/npmInstallWithRetries@main - - name: Download VSIX from nightly GitHub release env: GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} diff --git a/.github/workflows/vscode-promote-stable.yml b/.github/workflows/vscode-promote-stable.yml index 50c2997..fa65d73 100644 --- a/.github/workflows/vscode-promote-stable.yml +++ b/.github/workflows/vscode-promote-stable.yml @@ -22,7 +22,7 @@ name: Promote Pre-release to Stable # - Secrets: IDEE_GH_TOKEN, VSCE_PERSONAL_ACCESS_TOKEN, IDEE_OVSX_PAT # - Action: ./.github/actions/repackage-vsix-stable (repackages pre-release VSIX as stable) # - Action: ./.github/actions/publish-vsix (publishes to VS Code Marketplace and/or Open VSX) -# - Action: ./.github/actions/npm-install-with-retries (custom npm install with retry logic) +# - The package manager and lockfile inputs must match the caller repository. # # Note: This workflow uses local actions from the calling repository. For a fully self-contained # workflow that doesn't require local actions, use vscode-promote-prerelease.yml instead. @@ -63,6 +63,31 @@ on: required: false default: '22.x' type: string + package-manager: + description: 'Package manager to use: npm, pnpm, or yarn' + required: false + default: 'npm' + type: string + package-manager-version: + description: 'pnpm version to use when package-manager is pnpm' + required: false + default: '10' + type: string + cache-dependency-path: + description: 'Path to the package manager lockfile' + required: false + default: 'package-lock.json' + type: string + lockfile-path: + description: 'Single lockfile path to update and commit with the stable version' + required: false + default: 'package-lock.json' + type: string + install-command: + description: 'Command used to install dependencies' + required: false + default: 'npm ci' + type: string workflow_dispatch: inputs: extension-name: @@ -100,6 +125,32 @@ on: required: false default: '22.x' type: string + package-manager: + description: 'Package manager to use: npm, pnpm, or yarn' + required: false + default: 'npm' + type: choice + options: [npm, pnpm, yarn] + package-manager-version: + description: 'pnpm version to use when package-manager is pnpm' + required: false + default: '10' + type: string + cache-dependency-path: + description: 'Path to the package manager lockfile' + required: false + default: 'package-lock.json' + type: string + lockfile-path: + description: 'Single lockfile path to update and commit with the stable version' + required: false + default: 'package-lock.json' + type: string + install-command: + description: 'Command used to install dependencies' + required: false + default: 'npm ci' + type: string concurrency: group: promote-stable @@ -125,13 +176,14 @@ jobs: fetch-depth: 0 token: ${{ secrets.IDEE_GH_TOKEN }} - - name: Setup Node.js - uses: actions/setup-node@v6 + - name: Setup Node.js and install dependencies + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main with: node-version: ${{ inputs.node-version || '22.x' }} - - - name: Install dependencies - uses: ./.github/actions/npm-install-with-retries + package-manager: ${{ inputs.package-manager }} + package-manager-version: ${{ inputs.package-manager-version }} + cache-dependency-path: ${{ inputs.cache-dependency-path }} + install-command: ${{ inputs.install-command }} - name: Find latest pre-release candidate and compute stable version id: find @@ -292,9 +344,6 @@ jobs: with: node-version: ${{ inputs.node-version || '22.x' }} - - name: Install dependencies - uses: ./.github/actions/npm-install-with-retries - - name: Download stable VSIX artifact uses: actions/download-artifact@v8 with: @@ -459,7 +508,8 @@ jobs: with: node-version: ${{ inputs.node-version || '22.x' }} - - name: Commit stable version bump to main + - name: Update stable version + id: update-version env: STABLE_VERSION: ${{ needs.find-prerelease-candidate.outputs.stable-version }} DRY_RUN: ${{ inputs.dry-run || 'false' }} @@ -481,11 +531,13 @@ jobs: fi if [ "$IS_GT" != "yes" ]; then echo "Skipping commit-back: main ($CURRENT_VERSION) is already >= stable ($STABLE_VERSION)" + echo "should-commit=false" >> "$GITHUB_OUTPUT" exit 0 fi if [ "$DRY_RUN" = "true" ]; then echo "DRY RUN: Would set $PKG_DIR to $STABLE_VERSION and commit to main" + echo "should-commit=false" >> "$GITHUB_OUTPUT" exit 0 fi @@ -495,17 +547,35 @@ jobs: ( cd "$PKG_DIR" && npm version "$STABLE_VERSION" --no-git-tag-version ) - # Keep the root lockfile's workspace entry in sync with package.json. - # --package-lock-only rewrites package-lock.json from the manifests - # without installing node_modules, so the lockfile never drifts behind - # the committed version. This commit carries [skip ci], so nothing - # downstream re-derives the lockfile — it must be correct here. - npm install --package-lock-only --ignore-scripts + git add "$PKG_DIR/package.json" + if git diff --cached --quiet -- "$PKG_DIR/package.json"; then + echo "Package version was not updated: $PKG_DIR/package.json" + exit 1 + fi + echo "should-commit=true" >> "$GITHUB_OUTPUT" - git add "$PKG_DIR/package.json" package-lock.json - if git diff --staged --quiet; then - echo "No version change to commit - skipping (idempotent rerun)" - exit 0 + - name: Refresh lockfile with retries + if: steps.update-version.outputs.should-commit == 'true' + uses: salesforcecli/github-workflows/.github/actions/updateNodeLockfile@main + with: + package-manager: ${{ inputs.package-manager }} + package-manager-version: ${{ inputs.package-manager-version }} + lockfile-path: ${{ inputs.lockfile-path }} + + - name: Commit stable version bump + if: steps.update-version.outputs.should-commit == 'true' + env: + STABLE_VERSION: ${{ needs.find-prerelease-candidate.outputs.stable-version }} + EXTENSION_NAME: ${{ inputs.extension-name }} + EXTENSIONS_ROOT: ${{ inputs.extensions-root }} + LOCKFILE_PATH: ${{ inputs.lockfile-path }} + run: | + set -euo pipefail + git add "$LOCKFILE_PATH" + if [ -n "$(git diff --name-only)" ]; then + echo "Lockfile refresh produced unstaged changes:" + git diff --name-only + exit 1 fi git commit -m "chore: set stable version $STABLE_VERSION [skip ci]" From de7d56d709e54e20a8916da59a49483c21995bdc Mon Sep 17 00:00:00 2001 From: peternhale Date: Wed, 12 Aug 2026 14:36:14 -0600 Subject: [PATCH 02/12] test: use workflow branch action references --- .github/actions/npmInstallWithRetries/action.yml | 2 +- .github/actions/setupNodeAndInstall/action.yml | 6 +++--- .github/actions/updateNodeLockfile/action.yml | 2 +- .github/actions/yarnInstallWithRetries/action.yml | 2 +- .github/workflows/vscode-manual-publish.yml | 4 ++-- .github/workflows/vscode-promote-stable.yml | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/actions/npmInstallWithRetries/action.yml b/.github/actions/npmInstallWithRetries/action.yml index 78e9829..3864485 100644 --- a/.github/actions/npmInstallWithRetries/action.yml +++ b/.github/actions/npmInstallWithRetries/action.yml @@ -11,6 +11,6 @@ runs: run: npm config set fetch-timeout 600000 shell: bash - name: npm ci - uses: salesforcecli/github-workflows/.github/actions/retry@main + uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion with: command: npm ci --no-audit --no-fund ${{ inputs.ignore-scripts == 'true' && '--ignore-scripts' || '' }} diff --git a/.github/actions/setupNodeAndInstall/action.yml b/.github/actions/setupNodeAndInstall/action.yml index 184e11a..b716640 100644 --- a/.github/actions/setupNodeAndInstall/action.yml +++ b/.github/actions/setupNodeAndInstall/action.yml @@ -63,14 +63,14 @@ runs: - name: Install npm dependencies if: inputs.package-manager == 'npm' && steps.install-command.outputs.value == 'npm ci' - uses: salesforcecli/github-workflows/.github/actions/npmInstallWithRetries@main + uses: salesforcecli/github-workflows/.github/actions/npmInstallWithRetries@ph/W-23832274-pnpm-stable-promotion - name: Install Yarn dependencies if: inputs.package-manager == 'yarn' && steps.install-command.outputs.value == 'yarn install --network-timeout 600000' - uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main + uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@ph/W-23832274-pnpm-stable-promotion - name: Install custom or pnpm dependencies if: (inputs.package-manager != 'npm' || steps.install-command.outputs.value != 'npm ci') && (inputs.package-manager != 'yarn' || steps.install-command.outputs.value != 'yarn install --network-timeout 600000') - uses: salesforcecli/github-workflows/.github/actions/retry@main + uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion with: command: ${{ steps.install-command.outputs.value }} diff --git a/.github/actions/updateNodeLockfile/action.yml b/.github/actions/updateNodeLockfile/action.yml index 3e4ceca..f196e08 100644 --- a/.github/actions/updateNodeLockfile/action.yml +++ b/.github/actions/updateNodeLockfile/action.yml @@ -55,6 +55,6 @@ runs: echo "value=$COMMAND" >> "$GITHUB_OUTPUT" - name: Refresh lockfile with retries - uses: salesforcecli/github-workflows/.github/actions/retry@main + uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion with: command: ${{ steps.command.outputs.value }} diff --git a/.github/actions/yarnInstallWithRetries/action.yml b/.github/actions/yarnInstallWithRetries/action.yml index 439f758..8781514 100644 --- a/.github/actions/yarnInstallWithRetries/action.yml +++ b/.github/actions/yarnInstallWithRetries/action.yml @@ -8,6 +8,6 @@ runs: using: composite steps: - name: yarn install - uses: salesforcecli/github-workflows/.github/actions/retry@main + uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion with: command: yarn install --network-timeout 600000 ${{ inputs.ignore-scripts == 'true' && '--ignore-scripts' || '' }} diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index ace8c31..b077031 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -305,7 +305,7 @@ jobs: token: ${{ secrets.IDEE_GH_TOKEN }} - name: Setup Node.js and install dependencies - uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version || '22.x' }} package-manager: ${{ inputs.package-manager }} @@ -957,7 +957,7 @@ jobs: - name: Refresh lockfile with retries if: steps.update-version.outputs.should-commit == 'true' - uses: salesforcecli/github-workflows/.github/actions/updateNodeLockfile@main + uses: salesforcecli/github-workflows/.github/actions/updateNodeLockfile@ph/W-23832274-pnpm-stable-promotion with: package-manager: ${{ inputs.package-manager }} package-manager-version: ${{ inputs.package-manager-version }} diff --git a/.github/workflows/vscode-promote-stable.yml b/.github/workflows/vscode-promote-stable.yml index fa65d73..c641aae 100644 --- a/.github/workflows/vscode-promote-stable.yml +++ b/.github/workflows/vscode-promote-stable.yml @@ -177,7 +177,7 @@ jobs: token: ${{ secrets.IDEE_GH_TOKEN }} - name: Setup Node.js and install dependencies - uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version || '22.x' }} package-manager: ${{ inputs.package-manager }} @@ -556,7 +556,7 @@ jobs: - name: Refresh lockfile with retries if: steps.update-version.outputs.should-commit == 'true' - uses: salesforcecli/github-workflows/.github/actions/updateNodeLockfile@main + uses: salesforcecli/github-workflows/.github/actions/updateNodeLockfile@ph/W-23832274-pnpm-stable-promotion with: package-manager: ${{ inputs.package-manager }} package-manager-version: ${{ inputs.package-manager-version }} From c30e756bb58d21a1ba8352c8799f3ca37de72bcc Mon Sep 17 00:00:00 2001 From: peternhale Date: Wed, 12 Aug 2026 15:03:12 -0600 Subject: [PATCH 03/12] fix: retain stable retry action references --- .github/actions/npmInstallWithRetries/action.yml | 2 +- .github/actions/setupNodeAndInstall/action.yml | 2 +- .github/actions/updateNodeLockfile/action.yml | 2 +- .github/actions/yarnInstallWithRetries/action.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/npmInstallWithRetries/action.yml b/.github/actions/npmInstallWithRetries/action.yml index 3864485..78e9829 100644 --- a/.github/actions/npmInstallWithRetries/action.yml +++ b/.github/actions/npmInstallWithRetries/action.yml @@ -11,6 +11,6 @@ runs: run: npm config set fetch-timeout 600000 shell: bash - name: npm ci - uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion + uses: salesforcecli/github-workflows/.github/actions/retry@main with: command: npm ci --no-audit --no-fund ${{ inputs.ignore-scripts == 'true' && '--ignore-scripts' || '' }} diff --git a/.github/actions/setupNodeAndInstall/action.yml b/.github/actions/setupNodeAndInstall/action.yml index b716640..660ecee 100644 --- a/.github/actions/setupNodeAndInstall/action.yml +++ b/.github/actions/setupNodeAndInstall/action.yml @@ -71,6 +71,6 @@ runs: - name: Install custom or pnpm dependencies if: (inputs.package-manager != 'npm' || steps.install-command.outputs.value != 'npm ci') && (inputs.package-manager != 'yarn' || steps.install-command.outputs.value != 'yarn install --network-timeout 600000') - uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion + uses: salesforcecli/github-workflows/.github/actions/retry@main with: command: ${{ steps.install-command.outputs.value }} diff --git a/.github/actions/updateNodeLockfile/action.yml b/.github/actions/updateNodeLockfile/action.yml index f196e08..3e4ceca 100644 --- a/.github/actions/updateNodeLockfile/action.yml +++ b/.github/actions/updateNodeLockfile/action.yml @@ -55,6 +55,6 @@ runs: echo "value=$COMMAND" >> "$GITHUB_OUTPUT" - name: Refresh lockfile with retries - uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion + uses: salesforcecli/github-workflows/.github/actions/retry@main with: command: ${{ steps.command.outputs.value }} diff --git a/.github/actions/yarnInstallWithRetries/action.yml b/.github/actions/yarnInstallWithRetries/action.yml index 8781514..439f758 100644 --- a/.github/actions/yarnInstallWithRetries/action.yml +++ b/.github/actions/yarnInstallWithRetries/action.yml @@ -8,6 +8,6 @@ runs: using: composite steps: - name: yarn install - uses: salesforcecli/github-workflows/.github/actions/retry@ph/W-23832274-pnpm-stable-promotion + uses: salesforcecli/github-workflows/.github/actions/retry@main with: command: yarn install --network-timeout 600000 ${{ inputs.ignore-scripts == 'true' && '--ignore-scripts' || '' }} From a4b927aa25f7d3d19cf8728e9af70f5ee1df31f9 Mon Sep 17 00:00:00 2001 From: peternhale Date: Wed, 12 Aug 2026 15:32:39 -0600 Subject: [PATCH 04/12] fix: use IDE token for VS Code releases --- .github/workflows/vscode-publish-extensions.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/vscode-publish-extensions.yml b/.github/workflows/vscode-publish-extensions.yml index f5e24fa..d6f7d3d 100644 --- a/.github/workflows/vscode-publish-extensions.yml +++ b/.github/workflows/vscode-publish-extensions.yml @@ -545,7 +545,7 @@ jobs: - name: Validate GitHub authentication if: inputs.dry-run != 'true' && github.event.inputs.dry-run != 'true' env: - GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} run: | # Validate that required tokens are present if [ -z "$GH_TOKEN" ]; then @@ -565,8 +565,8 @@ jobs: # Manually push the missing tags: git push origin --tags - name: Commit version bumps with tags env: - # Ensure GitHub CLI has proper authentication - GITHUB_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + # Use the IDE token when configured; otherwise retain GitHub's workflow token. + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} DRY_RUN: ${{ inputs.dry-run || github.event.inputs.dry-run || 'false' }} GIT_USER_NAME: ${{ inputs.git-user-name }} GIT_USER_EMAIL: ${{ inputs.git-user-email }} @@ -599,8 +599,8 @@ jobs: export GIT_COMMITTER_NAME="$GIT_USER_NAME" export GIT_COMMITTER_EMAIL="$GIT_USER_EMAIL" - # Configure git to use the PAT for authentication - git remote set-url origin https://x-access-token:${{ secrets.IDEE_GH_TOKEN }}@github.com/${{ github.repository }}.git + # Configure git to use the effective workflow token for authentication. + git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" # Add all changes # Note: git add . respects .gitignore, so ignored files won't be added @@ -964,7 +964,7 @@ jobs: - name: Create GitHub releases env: - GITHUB_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} GITHUB_REPOSITORY: ${{ github.repository }} SELECTED_EXTENSIONS: ${{ needs.determine-changes.outputs.selected-extensions }} IS_NIGHTLY: ${{ inputs.nightly && 'true' || 'false' }} @@ -1205,6 +1205,7 @@ jobs: if: inputs.dry-run != 'true' && github.event.inputs.dry-run != 'true' && needs.publish.result == 'success' uses: slackapi/slack-github-action@v3.0.3 with: + webhook-type: incoming-webhook payload: | { "text": "${{ inputs.slack-notification-title }}", @@ -1338,6 +1339,7 @@ jobs: if: inputs.dry-run != 'true' && github.event.inputs.dry-run != 'true' && (needs.publish.result == 'failure' || needs.bump-versions.result == 'failure' || needs.package.result == 'failure') uses: slackapi/slack-github-action@v3.0.3 with: + webhook-type: incoming-webhook payload: | { "text": "❌ VS Code Extension Release Failed!", From 43e42d4590f034f94f86eda4e43f895e8d9e3164 Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 05:37:04 -0600 Subject: [PATCH 05/12] fix: avoid npm cache for automerge --- .github/workflows/automerge.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 593f9b5..168b647 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -32,7 +32,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: lts/* - cache: npm - run: npm install -g @salesforce/plugin-release-management --omit=dev From 7706d9463c8b10f411e209c8f80104ded896cdb7 Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 06:12:32 -0600 Subject: [PATCH 06/12] feat: support pnpm in shared release workflows --- .github/actions/ctcOpen/action.yml | 21 ++++++++- .github/workflows/automerge.yml | 23 ++++++++++ .github/workflows/ctcClose.yml | 25 +++++++++- .github/workflows/ctcOpen.yml | 25 +++++++++- .github/workflows/npmPublish.yml | 46 +++++++++++++++---- .../workflows/vscode-publish-extensions.yml | 10 ++-- 6 files changed, 132 insertions(+), 18 deletions(-) diff --git a/.github/actions/ctcOpen/action.yml b/.github/actions/ctcOpen/action.yml index 942c97d..2c918bf 100644 --- a/.github/actions/ctcOpen/action.yml +++ b/.github/actions/ctcOpen/action.yml @@ -21,6 +21,18 @@ inputs: description: version of node to use. It's better to specify latest, lts/* or lts/-1 than to hardcode numbers required: false default: lts/* + package-manager: + description: Package manager used by the calling repository (npm, pnpm, or yarn) + required: false + default: npm + package-manager-version: + description: pnpm version to use when package-manager is pnpm + required: false + default: '10' + cache-dependency-path: + description: Path to the calling repository's package manager lockfile + required: false + default: package-lock.json outputs: changeCaseId: @@ -32,10 +44,17 @@ runs: steps: - uses: actions/checkout@v4 + - name: Setup pnpm + if: inputs.package-manager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.package-manager-version }} + - uses: actions/setup-node@v4 with: node-version: ${{ inputs.nodeVersion }} - cache: npm + cache: ${{ inputs.package-manager }} + cache-dependency-path: ${{ inputs.cache-dependency-path }} - run: npm install -g @salesforce/change-case-management --omit=dev shell: bash diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 168b647..7620273 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -20,6 +20,21 @@ on: description: Optionally skip ci builds on merges into main type: boolean default: false + package-manager: + required: false + description: Package manager used by the calling repository (npm, pnpm, or yarn) + type: string + default: npm + package-manager-version: + required: false + description: pnpm version to use when package-manager is pnpm + type: string + default: '10' + cache-dependency-path: + required: false + description: Path to the calling repository's package manager lockfile + type: string + default: package-lock.json jobs: dependabot-automerge: @@ -29,9 +44,17 @@ jobs: with: token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + - name: Setup pnpm + if: inputs.package-manager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.package-manager-version }} + - uses: actions/setup-node@v4 with: node-version: lts/* + cache: ${{ inputs.package-manager }} + cache-dependency-path: ${{ inputs.cache-dependency-path }} - run: npm install -g @salesforce/plugin-release-management --omit=dev diff --git a/.github/workflows/ctcClose.yml b/.github/workflows/ctcClose.yml index 6d76f9d..cfa9581 100644 --- a/.github/workflows/ctcClose.yml +++ b/.github/workflows/ctcClose.yml @@ -15,6 +15,21 @@ on: type: string default: lts/* required: false + package-manager: + description: Package manager used by the calling repository (npm, pnpm, or yarn) + type: string + default: npm + required: false + package-manager-version: + description: pnpm version to use when package-manager is pnpm + type: string + default: '10' + required: false + cache-dependency-path: + description: Path to the calling repository's package manager lockfile + type: string + default: package-lock.json + required: false jobs: ctcClose: @@ -22,11 +37,17 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup pnpm + if: inputs.package-manager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.package-manager-version }} + - uses: actions/setup-node@v4 with: node-version: ${{ inputs.nodeVersion }} - # No `cache: npm`: it requires an npm lockfile and so hard-fails on - # pnpm/yarn consumer repos; the CTC CLI below is a one-off global install. + cache: ${{ inputs.package-manager }} + cache-dependency-path: ${{ inputs.cache-dependency-path }} - run: npm install -g @salesforce/change-case-management --omit=dev - id: ctc run: | diff --git a/.github/workflows/ctcOpen.yml b/.github/workflows/ctcOpen.yml index 4934fe2..9babb60 100644 --- a/.github/workflows/ctcOpen.yml +++ b/.github/workflows/ctcOpen.yml @@ -9,6 +9,21 @@ on: type: string default: lts/* required: false + package-manager: + description: Package manager used by the calling repository (npm, pnpm, or yarn) + type: string + default: npm + required: false + package-manager-version: + description: pnpm version to use when package-manager is pnpm + type: string + default: '10' + required: false + cache-dependency-path: + description: Path to the calling repository's package manager lockfile + type: string + default: package-lock.json + required: false outputs: changeCaseId: description: Id for the change case created @@ -22,11 +37,17 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup pnpm + if: inputs.package-manager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.package-manager-version }} + - uses: actions/setup-node@v4 with: node-version: ${{ inputs.nodeVersion }} - # No `cache: npm`: it requires an npm lockfile and so hard-fails on - # pnpm/yarn consumer repos; the CTC CLI below is a one-off global install. + cache: ${{ inputs.package-manager }} + cache-dependency-path: ${{ inputs.cache-dependency-path }} - run: npm install -g @salesforce/change-case-management --omit=dev diff --git a/.github/workflows/npmPublish.yml b/.github/workflows/npmPublish.yml index 8e39a96..5ae954d 100644 --- a/.github/workflows/npmPublish.yml +++ b/.github/workflows/npmPublish.yml @@ -52,10 +52,20 @@ on: required: true type: string packageManager: - description: the package manager to use. Defaults to yarn, but can be set to npm + description: the package manager to use. Defaults to yarn; supports npm, pnpm, or yarn required: false default: yarn type: string + packageManagerVersion: + description: pnpm version to use when packageManager is pnpm + required: false + default: '10' + type: string + cacheDependencyPath: + description: path to the package manager lockfile; defaults to yarn.lock, so npm and pnpm callers must override it + required: false + default: yarn.lock + type: string vulnerabilityCheck: description: if true, checks for known vulnerable package versions required: false @@ -81,8 +91,8 @@ jobs: ref: ${{ inputs.githubTag }} - name: Validate package manager run: | - if [[ "$INPUTS_PACKAGE_MANAGER" != "yarn" && "$INPUTS_PACKAGE_MANAGER" != "npm" ]]; then - echo "Error: packageManager must be 'yarn' or 'npm', got '$INPUTS_PACKAGE_MANAGER'" + if [[ "$INPUTS_PACKAGE_MANAGER" != "yarn" && "$INPUTS_PACKAGE_MANAGER" != "npm" && "$INPUTS_PACKAGE_MANAGER" != "pnpm" ]]; then + echo "Error: packageManager must be 'npm', 'pnpm', or 'yarn', got '$INPUTS_PACKAGE_MANAGER'" exit 1 fi - uses: actions/setup-node@v4 @@ -118,10 +128,13 @@ jobs: needs: [check-publish] # CTC will only open when publishing to 'latest' if: inputs.ctc && needs.check-publish.outputs.published == 'false' && inputs.tag == 'latest' - uses: salesforcecli/github-workflows/.github/workflows/ctcOpen.yml@main + uses: salesforcecli/github-workflows/.github/workflows/ctcOpen.yml@ph/W-23832274-pnpm-stable-promotion with: githubTag: ${{ inputs.githubTag }} nodeVersion: ${{ inputs.nodeVersion }} + package-manager: ${{ inputs.packageManager }} + package-manager-version: ${{ inputs.packageManagerVersion }} + cache-dependency-path: ${{ inputs.cacheDependencyPath }} secrets: inherit npm-publish: @@ -136,16 +149,27 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.githubTag }} + - name: Setup pnpm + if: inputs.packageManager == 'pnpm' + uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.packageManagerVersion }} - uses: actions/setup-node@v4 with: node-version: ${{ inputs.nodeVersion }} cache: ${{ inputs.packageManager }} + cache-dependency-path: ${{ inputs.cacheDependencyPath }} - name: Install dependencies with yarn if: inputs.packageManager == 'yarn' - uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main + uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@ph/W-23832274-pnpm-stable-promotion - name: Install dependencies with npm if: inputs.packageManager == 'npm' - uses: salesforcecli/github-workflows/.github/actions/npmInstallWithRetries@main + uses: salesforcecli/github-workflows/.github/actions/npmInstallWithRetries@ph/W-23832274-pnpm-stable-promotion + - name: Install dependencies with pnpm + if: inputs.packageManager == 'pnpm' + uses: salesforcecli/github-workflows/.github/actions/retry@main + with: + command: pnpm install --frozen-lockfile - name: Vulnerability check if: inputs.vulnerabilityCheck # Check for known vulnerable packages from the following supply chain attacks: @@ -200,18 +224,24 @@ jobs: ctcCloseSuccess: needs: [ctc-open, npm-publish] if: needs.ctc-open.result == 'success' && needs.npm-publish.result == 'success' && needs.ctc-open.outputs.changeCaseId - uses: salesforcecli/github-workflows/.github/workflows/ctcClose.yml@main + uses: salesforcecli/github-workflows/.github/workflows/ctcClose.yml@ph/W-23832274-pnpm-stable-promotion secrets: inherit with: changeCaseId: ${{needs.ctc-open.outputs.changeCaseId}} nodeVersion: ${{ inputs.nodeVersion }} + package-manager: ${{ inputs.packageManager }} + package-manager-version: ${{ inputs.packageManagerVersion }} + cache-dependency-path: ${{ inputs.cacheDependencyPath }} ctcCloseFail: needs: [ctc-open, npm-publish] if: always() && inputs.ctc && needs.ctc-open.outputs.changeCaseId && (needs.ctc-open.result != 'success' || needs.npm-publish.result != 'success') - uses: salesforcecli/github-workflows/.github/workflows/ctcClose.yml@main + uses: salesforcecli/github-workflows/.github/workflows/ctcClose.yml@ph/W-23832274-pnpm-stable-promotion secrets: inherit with: changeCaseId: ${{ needs.ctc-open.outputs.changeCaseId }} nodeVersion: ${{ inputs.nodeVersion }} status: Not Implemented + package-manager: ${{ inputs.packageManager }} + package-manager-version: ${{ inputs.packageManagerVersion }} + cache-dependency-path: ${{ inputs.cacheDependencyPath }} diff --git a/.github/workflows/vscode-publish-extensions.yml b/.github/workflows/vscode-publish-extensions.yml index d6f7d3d..6002ad3 100644 --- a/.github/workflows/vscode-publish-extensions.yml +++ b/.github/workflows/vscode-publish-extensions.yml @@ -203,7 +203,7 @@ jobs: ref: ${{ inputs.branch || github.ref }} - name: Setup Node.js and install dependencies - uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version || '22.x' }} package-manager: ${{ inputs.package-manager }} @@ -326,7 +326,7 @@ jobs: fetch-depth: 0 - name: Setup Node.js and install dependencies - uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version || '22.x' }} package-manager: ${{ inputs.package-manager }} @@ -673,7 +673,7 @@ jobs: package: needs: [bump-versions, calculate-artifact-name] - uses: salesforcecli/github-workflows/.github/workflows/vscode-package.yml@main + uses: salesforcecli/github-workflows/.github/workflows/vscode-package.yml@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version }} branch: ${{ inputs.branch || github.ref_name }} @@ -701,7 +701,7 @@ jobs: uses: actions/checkout@v6 - name: Setup Node.js and install dependencies - uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version || '22.x' }} package-manager: ${{ inputs.package-manager }} @@ -948,7 +948,7 @@ jobs: token: ${{ secrets.IDEE_GH_TOKEN || github.token }} - name: Setup Node.js and install dependencies - uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@main + uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion with: node-version: ${{ inputs.node-version || '22.x' }} package-manager: ${{ inputs.package-manager }} From 5a67fdea02df4118355da8c4ac3c4d327d92520d Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 06:38:54 -0600 Subject: [PATCH 07/12] fix: trim VS Code release branch inputs --- .github/workflows/vscode-publish-extensions.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/vscode-publish-extensions.yml b/.github/workflows/vscode-publish-extensions.yml index 6002ad3..bf7a885 100644 --- a/.github/workflows/vscode-publish-extensions.yml +++ b/.github/workflows/vscode-publish-extensions.yml @@ -348,6 +348,9 @@ jobs: run: | set -e + # workflow_dispatch string inputs can retain pasted whitespace. + BRANCH=$(echo "$BRANCH" | xargs) + case "$PACKAGE_MANAGER" in pnpm) unexpected_lockfiles=(package-lock.json yarn.lock) ;; yarn) unexpected_lockfiles=(package-lock.json pnpm-lock.yaml) ;; @@ -572,6 +575,8 @@ jobs: GIT_USER_EMAIL: ${{ inputs.git-user-email }} BRANCH: ${{ inputs.branch || github.ref_name }} run: | + BRANCH=$(echo "$BRANCH" | xargs) + if [ "$DRY_RUN" = "true" ]; then echo "🔄 DRY RUN: Would commit and push version bumps..." echo "📋 DRY RUN: Changes that would be committed:" @@ -976,6 +981,8 @@ jobs: EXTENSIONS_ROOT: ${{ inputs.extensions-root || 'packages' }} EXCLUDE_WEB: ${{ inputs.exclude-web-vsix || 'false' }} run: | + BRANCH=$(echo "$BRANCH" | xargs) + echo "Mode: $([ "$DRY_RUN" = "true" ] && echo "DRY RUN" || echo "LIVE")" echo "Creating GitHub releases..." From 2d477fd21ffec1067eac7e8c13c7f2335ae862c4 Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 07:15:09 -0600 Subject: [PATCH 08/12] feat: publish manual VSIX builds to CBWeb --- .github/workflows/vscode-manual-publish.yml | 81 +++++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index b077031..43269a8 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -14,7 +14,7 @@ name: Manual Publish VS Code Extension # vsix-name-pattern: 'apex-language-server-extension-*.vsix' # version-tag: 'apex-language-server-extension-v0.5.3-nightly.20260301' # OR source-run-id # slot: 'pre-release' # or 'stable' -# registries: 'all' # or 'vsce' or 'ovsx' +# registries: 'all' # or 'vsce', 'ovsx', or 'internal' # exclude-web-vsix: 'true' # extensions-root: 'packages' # dry-run: 'false' @@ -22,6 +22,7 @@ name: Manual Publish VS Code Extension # # Requirements - calling repository must have: # - Secrets: IDEE_GH_TOKEN, VSCE_PERSONAL_ACCESS_TOKEN, IDEE_OVSX_PAT +# - For internal publishing: MARKETPLACE_DEPLOY_TOKEN and MARKETPLACE_URL variable # - The package manager and lockfile inputs must match the caller repository. # - Action: ./.github/actions/check-ci-status (validates CI checks passed before publish) # - Action: ./.github/actions/repackage-vsix-stable (repackages pre-release VSIX as stable) @@ -57,7 +58,7 @@ on: required: true type: string registries: - description: "Registries to publish to (all, vsce, ovsx)" + description: "Registries to publish to (all, vsce, ovsx, internal). A version-tag source limits all to public registries." required: false default: "all" type: string @@ -168,6 +169,7 @@ on: - all - vsce - ovsx + - internal target-stable-version: description: "Optional stable version override" required: false @@ -268,6 +270,12 @@ jobs: SOURCE_RUN_ID="${{ inputs.source-run-id }}" SKIP_QC="${{ inputs.skip-quality-checks }}" BYPASS="${{ inputs.confirm-bypass }}" + REGISTRIES="${{ inputs.registries }}" + + case "$REGISTRIES" in + all|vsce|ovsx|internal) ;; + *) echo "ERROR: registries must be all, vsce, ovsx, or internal."; exit 1 ;; + esac # Exactly one source must be provided if [ -z "$VERSION_TAG" ] && [ -z "$SOURCE_RUN_ID" ]; then @@ -279,6 +287,20 @@ jobs: exit 1 fi + if [ -n "$VERSION_TAG" ] && [ "$REGISTRIES" = "internal" ]; then + echo "ERROR: registries=internal requires source-run-id because nightly GitHub releases do not include web VSIX artifacts." + exit 1 + fi + + if { [ "$REGISTRIES" = "internal" ] || { [ "$REGISTRIES" = "all" ] && [ -n "$SOURCE_RUN_ID" ]; }; } && [ "${{ inputs.slot }}" != "pre-release" ]; then + echo "ERROR: CBWeb publishing currently supports only the pre-release slot." + exit 1 + fi + + if [ -n "$VERSION_TAG" ] && [ "$REGISTRIES" = "all" ]; then + echo "INFO: version-tag source contains no web VSIX; limiting registries=all to VS Code Marketplace and Open VSX." + fi + # Run path requires bypass (branch CI profiles differ from main) if [ -n "$SOURCE_RUN_ID" ]; then if [ "$SKIP_QC" != "true" ]; then @@ -721,7 +743,7 @@ jobs: # ── publish ──────────────────────────────────────────────────────────────── publish: needs: [prepare, repackage] - if: always() && needs.prepare.result == 'success' && needs.repackage.result == 'success' + if: always() && inputs.registries != 'internal' && needs.prepare.result == 'success' && needs.repackage.result == 'success' runs-on: ubuntu-latest strategy: matrix: @@ -764,6 +786,51 @@ jobs: VSCE_PERSONAL_ACCESS_TOKEN: ${{ secrets.VSCE_PERSONAL_ACCESS_TOKEN }} OVSX_PAT: ${{ secrets.IDEE_OVSX_PAT }} + publish-internal: + needs: [prepare, gate] + if: always() && (inputs.registries == 'internal' || (inputs.registries == 'all' && inputs.source-run-id != '')) && needs.prepare.result == 'success' && needs.gate.result == 'success' + runs-on: ubuntu-latest + steps: + - name: Download source VSIX artifacts + uses: actions/download-artifact@v8 + with: + name: source-vsix + path: ./vsix-artifacts + + - name: Locate web VSIX + id: web-vsix + env: + VSIX_NAME_PATTERN: ${{ inputs.vsix-name-pattern }} + run: | + VSIX_FILE=$(find ./vsix-artifacts -type f -name "$VSIX_NAME_PATTERN" -name '*-web-*' | head -1) + if [ -z "$VSIX_FILE" ]; then + echo "ERROR: registries=${{ inputs.registries }} requires a web VSIX artifact from source-run-id." + exit 1 + fi + echo "vsix-file=$VSIX_FILE" >> "$GITHUB_OUTPUT" + + - name: Publish web VSIX to CBWeb internal marketplace + env: + DRY_RUN: ${{ inputs.dry-run || 'false' }} + MARKETPLACE_URL: ${{ vars.MARKETPLACE_URL }} + MARKETPLACE_DEPLOY_TOKEN: ${{ secrets.MARKETPLACE_DEPLOY_TOKEN }} + VSIX_FILE: ${{ steps.web-vsix.outputs.vsix-file }} + run: | + if [ "$DRY_RUN" = "true" ]; then + echo "DRY RUN: Would publish $VSIX_FILE to CBWeb marketplace" + exit 0 + fi + + if [ -z "$MARKETPLACE_URL" ] || [ -z "$MARKETPLACE_DEPLOY_TOKEN" ]; then + echo "CBWeb marketplace credentials are required for live publishing" + exit 1 + fi + + curl --fail-with-body \ + -X POST "${MARKETPLACE_URL}/api/internal/publish" \ + -H "Authorization: Bearer ${MARKETPLACE_DEPLOY_TOKEN}" \ + -F "vsix=@${VSIX_FILE}" + # ── create-github-release ────────────────────────────────────────────────── create-github-release: needs: [prepare, repackage, publish] @@ -838,8 +905,8 @@ jobs: # ── tag-published ────────────────────────────────────────────────────────── tag-published: - needs: [prepare, publish, create-github-release] - if: always() && needs.publish.result == 'success' && (inputs.slot == 'pre-release' || needs.create-github-release.result == 'success') + needs: [prepare, publish, publish-internal, create-github-release] + if: always() && needs.prepare.result == 'success' && (needs.publish.result == 'success' || needs.publish.result == 'skipped') && (needs.publish-internal.result == 'success' || needs.publish-internal.result == 'skipped') && (inputs.slot == 'pre-release' || needs.create-github-release.result == 'success') runs-on: ubuntu-latest steps: - name: Checkout @@ -884,8 +951,8 @@ jobs: # ── commit-stable-version ──────────────────────────────────────────────── commit-stable-version: - needs: [prepare, publish, create-github-release, tag-published] - if: needs.publish.result == 'success' && inputs.slot == 'stable' + needs: [prepare, publish, publish-internal, create-github-release, tag-published] + if: needs.publish.result == 'success' && needs.publish-internal.result == 'skipped' && inputs.slot == 'stable' runs-on: ubuntu-latest steps: - name: Checkout main From deab1487e9536f19b8d24de973b820f6d1a3518e Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 07:30:16 -0600 Subject: [PATCH 09/12] Revert "feat: publish manual VSIX builds to CBWeb" This reverts commit 2d477fd21ffec1067eac7e8c13c7f2335ae862c4. --- .github/workflows/vscode-manual-publish.yml | 81 ++------------------- 1 file changed, 7 insertions(+), 74 deletions(-) diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index 43269a8..b077031 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -14,7 +14,7 @@ name: Manual Publish VS Code Extension # vsix-name-pattern: 'apex-language-server-extension-*.vsix' # version-tag: 'apex-language-server-extension-v0.5.3-nightly.20260301' # OR source-run-id # slot: 'pre-release' # or 'stable' -# registries: 'all' # or 'vsce', 'ovsx', or 'internal' +# registries: 'all' # or 'vsce' or 'ovsx' # exclude-web-vsix: 'true' # extensions-root: 'packages' # dry-run: 'false' @@ -22,7 +22,6 @@ name: Manual Publish VS Code Extension # # Requirements - calling repository must have: # - Secrets: IDEE_GH_TOKEN, VSCE_PERSONAL_ACCESS_TOKEN, IDEE_OVSX_PAT -# - For internal publishing: MARKETPLACE_DEPLOY_TOKEN and MARKETPLACE_URL variable # - The package manager and lockfile inputs must match the caller repository. # - Action: ./.github/actions/check-ci-status (validates CI checks passed before publish) # - Action: ./.github/actions/repackage-vsix-stable (repackages pre-release VSIX as stable) @@ -58,7 +57,7 @@ on: required: true type: string registries: - description: "Registries to publish to (all, vsce, ovsx, internal). A version-tag source limits all to public registries." + description: "Registries to publish to (all, vsce, ovsx)" required: false default: "all" type: string @@ -169,7 +168,6 @@ on: - all - vsce - ovsx - - internal target-stable-version: description: "Optional stable version override" required: false @@ -270,12 +268,6 @@ jobs: SOURCE_RUN_ID="${{ inputs.source-run-id }}" SKIP_QC="${{ inputs.skip-quality-checks }}" BYPASS="${{ inputs.confirm-bypass }}" - REGISTRIES="${{ inputs.registries }}" - - case "$REGISTRIES" in - all|vsce|ovsx|internal) ;; - *) echo "ERROR: registries must be all, vsce, ovsx, or internal."; exit 1 ;; - esac # Exactly one source must be provided if [ -z "$VERSION_TAG" ] && [ -z "$SOURCE_RUN_ID" ]; then @@ -287,20 +279,6 @@ jobs: exit 1 fi - if [ -n "$VERSION_TAG" ] && [ "$REGISTRIES" = "internal" ]; then - echo "ERROR: registries=internal requires source-run-id because nightly GitHub releases do not include web VSIX artifacts." - exit 1 - fi - - if { [ "$REGISTRIES" = "internal" ] || { [ "$REGISTRIES" = "all" ] && [ -n "$SOURCE_RUN_ID" ]; }; } && [ "${{ inputs.slot }}" != "pre-release" ]; then - echo "ERROR: CBWeb publishing currently supports only the pre-release slot." - exit 1 - fi - - if [ -n "$VERSION_TAG" ] && [ "$REGISTRIES" = "all" ]; then - echo "INFO: version-tag source contains no web VSIX; limiting registries=all to VS Code Marketplace and Open VSX." - fi - # Run path requires bypass (branch CI profiles differ from main) if [ -n "$SOURCE_RUN_ID" ]; then if [ "$SKIP_QC" != "true" ]; then @@ -743,7 +721,7 @@ jobs: # ── publish ──────────────────────────────────────────────────────────────── publish: needs: [prepare, repackage] - if: always() && inputs.registries != 'internal' && needs.prepare.result == 'success' && needs.repackage.result == 'success' + if: always() && needs.prepare.result == 'success' && needs.repackage.result == 'success' runs-on: ubuntu-latest strategy: matrix: @@ -786,51 +764,6 @@ jobs: VSCE_PERSONAL_ACCESS_TOKEN: ${{ secrets.VSCE_PERSONAL_ACCESS_TOKEN }} OVSX_PAT: ${{ secrets.IDEE_OVSX_PAT }} - publish-internal: - needs: [prepare, gate] - if: always() && (inputs.registries == 'internal' || (inputs.registries == 'all' && inputs.source-run-id != '')) && needs.prepare.result == 'success' && needs.gate.result == 'success' - runs-on: ubuntu-latest - steps: - - name: Download source VSIX artifacts - uses: actions/download-artifact@v8 - with: - name: source-vsix - path: ./vsix-artifacts - - - name: Locate web VSIX - id: web-vsix - env: - VSIX_NAME_PATTERN: ${{ inputs.vsix-name-pattern }} - run: | - VSIX_FILE=$(find ./vsix-artifacts -type f -name "$VSIX_NAME_PATTERN" -name '*-web-*' | head -1) - if [ -z "$VSIX_FILE" ]; then - echo "ERROR: registries=${{ inputs.registries }} requires a web VSIX artifact from source-run-id." - exit 1 - fi - echo "vsix-file=$VSIX_FILE" >> "$GITHUB_OUTPUT" - - - name: Publish web VSIX to CBWeb internal marketplace - env: - DRY_RUN: ${{ inputs.dry-run || 'false' }} - MARKETPLACE_URL: ${{ vars.MARKETPLACE_URL }} - MARKETPLACE_DEPLOY_TOKEN: ${{ secrets.MARKETPLACE_DEPLOY_TOKEN }} - VSIX_FILE: ${{ steps.web-vsix.outputs.vsix-file }} - run: | - if [ "$DRY_RUN" = "true" ]; then - echo "DRY RUN: Would publish $VSIX_FILE to CBWeb marketplace" - exit 0 - fi - - if [ -z "$MARKETPLACE_URL" ] || [ -z "$MARKETPLACE_DEPLOY_TOKEN" ]; then - echo "CBWeb marketplace credentials are required for live publishing" - exit 1 - fi - - curl --fail-with-body \ - -X POST "${MARKETPLACE_URL}/api/internal/publish" \ - -H "Authorization: Bearer ${MARKETPLACE_DEPLOY_TOKEN}" \ - -F "vsix=@${VSIX_FILE}" - # ── create-github-release ────────────────────────────────────────────────── create-github-release: needs: [prepare, repackage, publish] @@ -905,8 +838,8 @@ jobs: # ── tag-published ────────────────────────────────────────────────────────── tag-published: - needs: [prepare, publish, publish-internal, create-github-release] - if: always() && needs.prepare.result == 'success' && (needs.publish.result == 'success' || needs.publish.result == 'skipped') && (needs.publish-internal.result == 'success' || needs.publish-internal.result == 'skipped') && (inputs.slot == 'pre-release' || needs.create-github-release.result == 'success') + needs: [prepare, publish, create-github-release] + if: always() && needs.publish.result == 'success' && (inputs.slot == 'pre-release' || needs.create-github-release.result == 'success') runs-on: ubuntu-latest steps: - name: Checkout @@ -951,8 +884,8 @@ jobs: # ── commit-stable-version ──────────────────────────────────────────────── commit-stable-version: - needs: [prepare, publish, publish-internal, create-github-release, tag-published] - if: needs.publish.result == 'success' && needs.publish-internal.result == 'skipped' && inputs.slot == 'stable' + needs: [prepare, publish, create-github-release, tag-published] + if: needs.publish.result == 'success' && inputs.slot == 'stable' runs-on: ubuntu-latest steps: - name: Checkout main From ded807ab56b8b9c5bf25b2bf275ab78e29979874 Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 08:25:41 -0600 Subject: [PATCH 10/12] feat: publish manual VSIX builds to CBWeb --- .github/workflows/vscode-manual-publish.yml | 91 +++++++++++++++++++-- 1 file changed, 84 insertions(+), 7 deletions(-) diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index b077031..20c8f98 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -14,7 +14,8 @@ name: Manual Publish VS Code Extension # vsix-name-pattern: 'apex-language-server-extension-*.vsix' # version-tag: 'apex-language-server-extension-v0.5.3-nightly.20260301' # OR source-run-id # slot: 'pre-release' # or 'stable' -# registries: 'all' # or 'vsce' or 'ovsx' +# registries: 'all' # or 'vsce', 'ovsx', or 'none' +# publish-web-vsix: 'true' # publish the web artifact to CBWeb # exclude-web-vsix: 'true' # extensions-root: 'packages' # dry-run: 'false' @@ -22,6 +23,7 @@ name: Manual Publish VS Code Extension # # Requirements - calling repository must have: # - Secrets: IDEE_GH_TOKEN, VSCE_PERSONAL_ACCESS_TOKEN, IDEE_OVSX_PAT +# - For CBWeb: MARKETPLACE_DEPLOY_TOKEN and MARKETPLACE_URL variable # - The package manager and lockfile inputs must match the caller repository. # - Action: ./.github/actions/check-ci-status (validates CI checks passed before publish) # - Action: ./.github/actions/repackage-vsix-stable (repackages pre-release VSIX as stable) @@ -57,10 +59,15 @@ on: required: true type: string registries: - description: "Registries to publish to (all, vsce, ovsx)" + description: "Public registries to publish to (all, vsce, ovsx, none)" required: false default: "all" type: string + publish-web-vsix: + description: "Publish the web VSIX to the CBWeb internal marketplace" + required: false + default: "false" + type: string target-stable-version: description: "Optional stable version override (e.g., 0.6.1). Must be valid semver with EVEN minor. Only applies when slot is stable. Required when using source-run-id with slot stable." required: false @@ -168,6 +175,15 @@ on: - all - vsce - ovsx + - none + publish-web-vsix: + description: "Publish the web VSIX to the CBWeb internal marketplace" + required: false + default: "false" + type: choice + options: + - "false" + - "true" target-stable-version: description: "Optional stable version override" required: false @@ -268,6 +284,13 @@ jobs: SOURCE_RUN_ID="${{ inputs.source-run-id }}" SKIP_QC="${{ inputs.skip-quality-checks }}" BYPASS="${{ inputs.confirm-bypass }}" + REGISTRIES="${{ inputs.registries }}" + PUBLISH_WEB_VSIX="${{ inputs.publish-web-vsix }}" + + case "$REGISTRIES" in + all|vsce|ovsx|none) ;; + *) echo "ERROR: registries must be all, vsce, ovsx, or none."; exit 1 ;; + esac # Exactly one source must be provided if [ -z "$VERSION_TAG" ] && [ -z "$SOURCE_RUN_ID" ]; then @@ -279,6 +302,16 @@ jobs: exit 1 fi + if [ "$REGISTRIES" = "none" ] && [ "$PUBLISH_WEB_VSIX" != "true" ]; then + echo "ERROR: registries=none requires publish-web-vsix=true." + exit 1 + fi + + if [ "$PUBLISH_WEB_VSIX" = "true" ] && [ "${{ inputs.slot }}" != "pre-release" ]; then + echo "ERROR: publish-web-vsix currently supports only the pre-release slot." + exit 1 + fi + # Run path requires bypass (branch CI profiles differ from main) if [ -n "$SOURCE_RUN_ID" ]; then if [ "$SKIP_QC" != "true" ]; then @@ -721,7 +754,7 @@ jobs: # ── publish ──────────────────────────────────────────────────────────────── publish: needs: [prepare, repackage] - if: always() && needs.prepare.result == 'success' && needs.repackage.result == 'success' + if: always() && inputs.registries != 'none' && needs.prepare.result == 'success' && needs.repackage.result == 'success' runs-on: ubuntu-latest strategy: matrix: @@ -764,6 +797,50 @@ jobs: VSCE_PERSONAL_ACCESS_TOKEN: ${{ secrets.VSCE_PERSONAL_ACCESS_TOKEN }} OVSX_PAT: ${{ secrets.IDEE_OVSX_PAT }} + publish-to-cbweb-marketplace: + name: Publish to CBWeb Internal Marketplace + needs: [prepare, gate] + if: always() && inputs.publish-web-vsix == 'true' && needs.prepare.result == 'success' && needs.gate.result == 'success' + runs-on: ubuntu-latest + steps: + - name: Download source VSIX artifacts + uses: actions/download-artifact@v8 + with: + name: source-vsix + path: ./vsix-artifacts + + - name: Find web VSIX + id: web-vsix + run: | + mapfile -t VSIX_FILES < <(find ./vsix-artifacts -type f -name '*-web-*.vsix') + if [ "${#VSIX_FILES[@]}" -ne 1 ]; then + echo "Expected exactly one web VSIX artifact, found ${#VSIX_FILES[@]}" + exit 1 + fi + echo "vsix_file=${VSIX_FILES[0]}" >> "$GITHUB_OUTPUT" + + - name: Publish web VSIX to CBWeb internal marketplace + env: + DRY_RUN: ${{ inputs.dry-run || 'false' }} + MARKETPLACE_URL: ${{ vars.MARKETPLACE_URL }} + MARKETPLACE_DEPLOY_TOKEN: ${{ secrets.MARKETPLACE_DEPLOY_TOKEN }} + VSIX_FILE: ${{ steps.web-vsix.outputs.vsix_file }} + run: | + if [ "$DRY_RUN" = "true" ]; then + echo "DRY RUN: Would publish $VSIX_FILE to CBWeb marketplace" + exit 0 + fi + + if [ -z "$MARKETPLACE_URL" ] || [ -z "$MARKETPLACE_DEPLOY_TOKEN" ]; then + echo "CBWeb marketplace credentials are required for live publishing" + exit 1 + fi + + curl --fail-with-body \ + -X POST "${MARKETPLACE_URL}/api/internal/publish" \ + -H "Authorization: Bearer ${MARKETPLACE_DEPLOY_TOKEN}" \ + -F "vsix=@${VSIX_FILE}" + # ── create-github-release ────────────────────────────────────────────────── create-github-release: needs: [prepare, repackage, publish] @@ -838,8 +915,8 @@ jobs: # ── tag-published ────────────────────────────────────────────────────────── tag-published: - needs: [prepare, publish, create-github-release] - if: always() && needs.publish.result == 'success' && (inputs.slot == 'pre-release' || needs.create-github-release.result == 'success') + needs: [prepare, publish, publish-to-cbweb-marketplace, create-github-release] + if: always() && needs.prepare.result == 'success' && (needs.publish.result == 'success' || needs.publish.result == 'skipped') && (needs.publish-to-cbweb-marketplace.result == 'success' || needs.publish-to-cbweb-marketplace.result == 'skipped') && (inputs.slot == 'pre-release' || needs.create-github-release.result == 'success') runs-on: ubuntu-latest steps: - name: Checkout @@ -884,8 +961,8 @@ jobs: # ── commit-stable-version ──────────────────────────────────────────────── commit-stable-version: - needs: [prepare, publish, create-github-release, tag-published] - if: needs.publish.result == 'success' && inputs.slot == 'stable' + needs: [prepare, publish, publish-to-cbweb-marketplace, create-github-release, tag-published] + if: needs.publish.result == 'success' && needs.publish-to-cbweb-marketplace.result == 'skipped' && inputs.slot == 'stable' runs-on: ubuntu-latest steps: - name: Checkout main From 32e3bdb659edba67b1d462cc4453af1673ffbf5c Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 09:17:28 -0600 Subject: [PATCH 11/12] fix: fall back to workflow token for manual publishing --- .github/workflows/vscode-manual-publish.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index 20c8f98..93cb2df 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -335,7 +335,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 - token: ${{ secrets.IDEE_GH_TOKEN }} + token: ${{ secrets.IDEE_GH_TOKEN || github.token }} - name: Setup Node.js and install dependencies uses: salesforcecli/github-workflows/.github/actions/setupNodeAndInstall@ph/W-23832274-pnpm-stable-promotion @@ -349,7 +349,7 @@ jobs: - name: Resolve source and compute versions id: resolve env: - GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} VERSION_TAG: ${{ inputs.version-tag }} SOURCE_RUN_ID: ${{ inputs.source-run-id }} SLOT: ${{ inputs.slot }} @@ -530,7 +530,7 @@ jobs: id: ci-commit if: inputs.skip-quality-checks != 'true' env: - GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} REPO: ${{ github.repository }} START_SHA: ${{ steps.resolve.outputs.commit-sha }} run: | @@ -668,7 +668,7 @@ jobs: uses: ./.github/actions/check-ci-status with: commit-sha: ${{ needs.prepare.outputs.ci-commit-sha }} - token: ${{ secrets.IDEE_GH_TOKEN }} + token: ${{ secrets.IDEE_GH_TOKEN || github.token }} required-checks: ${{ inputs.required-ci-checks }} # ── gate ─────────────────────────────────────────────────────────────────── @@ -851,7 +851,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 - token: ${{ secrets.IDEE_GH_TOKEN }} + token: ${{ secrets.IDEE_GH_TOKEN || github.token }} - name: Download VSIX uses: actions/download-artifact@v8 @@ -861,7 +861,7 @@ jobs: - name: Create GitHub release for stable version env: - GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} STABLE_VERSION: ${{ needs.prepare.outputs.stable-version }} PRERELEASE_VERSION: ${{ needs.prepare.outputs.prerelease-version }} SOURCE_TYPE: ${{ needs.prepare.outputs.source-type }} @@ -923,7 +923,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 - token: ${{ secrets.IDEE_GH_TOKEN }} + token: ${{ secrets.IDEE_GH_TOKEN || github.token }} - name: Create tracking tag env: @@ -932,7 +932,7 @@ jobs: STABLE_VERSION: ${{ needs.prepare.outputs.stable-version }} COMMIT_SHA: ${{ needs.prepare.outputs.commit-sha }} DRY_RUN: ${{ inputs.dry-run || 'false' }} - GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} EXTENSION_NAME: ${{ inputs.extension-name }} run: | if [ "$SLOT" = "stable" ]; then @@ -970,7 +970,7 @@ jobs: with: ref: main fetch-depth: 0 - token: ${{ secrets.IDEE_GH_TOKEN }} + token: ${{ secrets.IDEE_GH_TOKEN || github.token }} - name: Setup Node.js uses: actions/setup-node@v6 @@ -982,7 +982,7 @@ jobs: env: STABLE_VERSION: ${{ needs.prepare.outputs.stable-version }} DRY_RUN: ${{ inputs.dry-run || 'false' }} - GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN }} + GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} EXTENSION_NAME: ${{ inputs.extension-name }} EXTENSIONS_ROOT: ${{ inputs.extensions-root }} run: | From 0019d8c8e1da000ed62025dfaa4bbc0b85ecac11 Mon Sep 17 00:00:00 2001 From: peternhale Date: Thu, 13 Aug 2026 10:03:36 -0600 Subject: [PATCH 12/12] fix: use configured manual publish quality checks --- .github/workflows/vscode-manual-publish.yml | 24 ++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/vscode-manual-publish.yml b/.github/workflows/vscode-manual-publish.yml index 93cb2df..6b68291 100644 --- a/.github/workflows/vscode-manual-publish.yml +++ b/.github/workflows/vscode-manual-publish.yml @@ -533,20 +533,34 @@ jobs: GH_TOKEN: ${{ secrets.IDEE_GH_TOKEN || github.token }} REPO: ${{ github.repository }} START_SHA: ${{ steps.resolve.outputs.commit-sha }} + REQUIRED_CHECKS: ${{ inputs.required-ci-checks }} run: | MAX_DEPTH=20 SHA="$START_SHA" CI_SHA="" + IFS=',' read -r -a CHECK_NAMES <<< "$REQUIRED_CHECKS" + for i in "${!CHECK_NAMES[@]}"; do + CHECK_NAMES[$i]=$(echo "${CHECK_NAMES[$i]}" | xargs) + done + for i in $(seq 1 "$MAX_DEPTH"); do - CONCLUSION=$(gh api "repos/$REPO/commits/$SHA/check-runs" --paginate \ - --jq '[.check_runs[] | select(.name == "CI Complete")] | .[0].conclusion // empty' 2>/dev/null || echo "") - if [ "$CONCLUSION" = "success" ]; then + CHECK_RUNS=$(gh api "repos/$REPO/commits/$SHA/check-runs" --paginate 2>/dev/null || echo "") + MISSING_OR_FAILED="" + for CHECK_NAME in "${CHECK_NAMES[@]}"; do + CONCLUSION=$(echo "$CHECK_RUNS" | jq -r --arg name "$CHECK_NAME" \ + '[.check_runs[] | select(.name == $name)] | .[0].conclusion // empty') + if [ "$CONCLUSION" != "success" ]; then + MISSING_OR_FAILED="${MISSING_OR_FAILED}${MISSING_OR_FAILED:+, }${CHECK_NAME} (${CONCLUSION:-none})" + fi + done + + if [ -z "$MISSING_OR_FAILED" ]; then CI_SHA="$SHA" echo "Found CI-tested ancestor at depth $((i - 1)): $CI_SHA" break fi - echo " $SHA: no successful 'CI Complete' (conclusion='${CONCLUSION:-none}') — walking to parent" + echo " $SHA: required checks not successful: $MISSING_OR_FAILED — walking to parent" PARENT=$(git rev-parse "${SHA}^" 2>/dev/null || echo "") if [ -z "$PARENT" ]; then echo "Reached root of history without a CI-tested commit." @@ -556,7 +570,7 @@ jobs: done if [ -z "$CI_SHA" ]; then - echo "ERROR: No ancestor with a successful 'CI Complete' check found within $MAX_DEPTH commits of $START_SHA." + echo "ERROR: No ancestor with successful required checks ('$REQUIRED_CHECKS') found within $MAX_DEPTH commits of $START_SHA." echo "Cannot verify CI status — failing to prevent untested promotion. Use skip-quality-checks=true to bypass." exit 1 fi