Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
65726c9
fix: support package manager retries in VS Code promotion
peternhale Aug 12, 2026
de7d56d
test: use workflow branch action references
peternhale Aug 12, 2026
c30e756
fix: retain stable retry action references
peternhale Aug 12, 2026
a4b927a
fix: use IDE token for VS Code releases
peternhale Aug 12, 2026
43e42d4
fix: avoid npm cache for automerge
peternhale Aug 13, 2026
7706d94
feat: support pnpm in shared release workflows
peternhale Aug 13, 2026
5a67fde
fix: trim VS Code release branch inputs
peternhale Aug 13, 2026
2d477fd
feat: publish manual VSIX builds to CBWeb
peternhale Aug 13, 2026
deab148
Revert "feat: publish manual VSIX builds to CBWeb"
peternhale Aug 13, 2026
ded807a
feat: publish manual VSIX builds to CBWeb
peternhale Aug 13, 2026
32e3bdb
fix: fall back to workflow token for manual publishing
peternhale Aug 13, 2026
0019d8c
fix: use configured manual publish quality checks
peternhale Aug 13, 2026
029341b
fix: resolve shared VSIX publish actions
peternhale Aug 14, 2026
2a3dc1c
fix: preserve comma-containing CI check names
peternhale Aug 14, 2026
3bb536d
fix: validate manual publish CI inputs
peternhale Aug 17, 2026
a36fe54
ci: report release credential identity
peternhale Aug 17, 2026
bff52fd
fix: quote release credential diagnostic
peternhale Aug 17, 2026
6b5e83c
revert: remove release credential diagnostic
peternhale Aug 17, 2026
b33b8ee
fix: gate marketplace tracking tags
peternhale Aug 17, 2026
f67c897
Merge remote-tracking branch 'origin/main' into ph/W-23832274-pnpm-st…
peternhale Aug 18, 2026
c83fa15
fix: use main for shared workflow refs
peternhale Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .github/actions/check-ci-status/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ inputs:
required: true
required-checks:
description: >
Comma-separated list of check names that must have succeeded.
JSON array of check names that must have succeeded.
If empty, all non-skipped check-runs must have conclusion "success".
required: false
default: ''
Expand Down Expand Up @@ -49,10 +49,13 @@ runs:
FAILED=0

if [ -n "$REQUIRED_CHECKS" ]; then
if ! jq -e 'type == "array"' <<< "$REQUIRED_CHECKS" >/dev/null; then
echo "ERROR: required-checks must be a JSON array"
exit 1
fi

# Only validate the specified checks
IFS=',' read -ra CHECKS <<< "$REQUIRED_CHECKS"
for CHECK in "${CHECKS[@]}"; do
CHECK=$(echo "$CHECK" | xargs) # trim whitespace
while IFS= read -r CHECK; do

# Grab the latest run for this name (check-runs are newest-first per name).
MATCH=$(echo "$CHECK_RUNS" | jq -c --arg name "$CHECK" \
Expand All @@ -76,7 +79,7 @@ runs:
else
echo "PASS: required check '$CHECK' succeeded"
fi
done
done < <(jq -r '.[]' <<< "$REQUIRED_CHECKS")
else
# Validate all non-skipped check-runs
while IFS= read -r RUN; do
Expand Down
21 changes: 20 additions & 1 deletion .github/actions/ctcOpen/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/npmInstallWithRetries/action.yml
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
60 changes: 60 additions & 0 deletions .github/actions/updateNodeLockfile/action.yml
Original file line number Diff line number Diff line change
@@ -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 }}
13 changes: 8 additions & 5 deletions .github/actions/vscode/check-ci-status/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ inputs:
required: true
required-checks:
description: >
Comma-separated list of check names that must have succeeded.
JSON array of check names that must have succeeded.
If empty, all non-skipped check-runs must have conclusion "success".
required: false
default: ''
Expand Down Expand Up @@ -49,10 +49,13 @@ runs:
FAILED=0

if [ -n "$REQUIRED_CHECKS" ]; then
if ! jq -e 'type == "array"' <<< "$REQUIRED_CHECKS" >/dev/null; then
echo "ERROR: required-checks must be a JSON array"
exit 1
fi

# Only validate the specified checks
IFS=',' read -ra CHECKS <<< "$REQUIRED_CHECKS"
for CHECK in "${CHECKS[@]}"; do
CHECK=$(echo "$CHECK" | xargs) # trim whitespace
while IFS= read -r CHECK; do
CONCLUSION=$(echo "$CHECK_RUNS" | jq -r --arg name "$CHECK" \
'select(.name == $name) | .conclusion' | head -1)
if [ "$CONCLUSION" != "success" ]; then
Expand All @@ -61,7 +64,7 @@ runs:
else
echo "PASS: required check '$CHECK' succeeded"
fi
done
done < <(jq -r '.[]' <<< "$REQUIRED_CHECKS")
else
# Validate all non-skipped check-runs
while IFS= read -r RUN; do
Expand Down
72 changes: 72 additions & 0 deletions .github/actions/vscode/repackage-vsix-stable/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: "Repackage VSIX for Stable"
description: >
Repackage a pre-release VSIX as a stable build by repacking its extension
contents with vsce.

inputs:
source-vsix-path:
description: "Path to the source pre-release VSIX"
required: true
prerelease-version:
description: "Current pre-release version, used for logging"
required: true
stable-version:
description: "Stable version to stamp into the repackaged VSIX"
required: true
output-dir:
description: "Directory for the repackaged VSIX"
required: false
default: "./vsix-artifacts"

outputs:
vsix-path:
description: "Path to the repackaged stable VSIX"
value: ${{ steps.repack.outputs.vsix-path }}

runs:
using: composite
steps:
- name: Repackage VSIX with stable version
id: repack
shell: bash
env:
SOURCE_VSIX: ${{ inputs.source-vsix-path }}
PRERELEASE_VERSION: ${{ inputs.prerelease-version }}
STABLE_VERSION: ${{ inputs.stable-version }}
OUTPUT_DIR: ${{ inputs.output-dir }}
run: |
set -euo pipefail
echo "Repackaging VSIX via vsce: $PRERELEASE_VERSION -> $STABLE_VERSION"

if [ ! -f "$SOURCE_VSIX" ]; then
echo "::error::Source VSIX not found: $SOURCE_VSIX"
exit 1
fi

WORK_DIR="./vsix-repack"
rm -rf "$WORK_DIR"
mkdir -p "$WORK_DIR" "$OUTPUT_DIR"
unzip -q "$SOURCE_VSIX" -d "$WORK_DIR"

PKG_JSON="$WORK_DIR/extension/package.json"
if [ ! -f "$PKG_JSON" ]; then
echo "::error::extension/package.json not found in VSIX"
exit 1
fi

node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('$PKG_JSON', 'utf8'));
pkg.version = '$STABLE_VERSION';
delete pkg.preRelease;
fs.writeFileSync('$PKG_JSON', JSON.stringify(pkg, null, 2) + '\\n');
"

OUT_ABS="$(cd "$OUTPUT_DIR" && pwd)/apex-language-server-extension-${STABLE_VERSION}.vsix"
(
cd "$WORK_DIR/extension"
npx --yes @vscode/vsce@3 package --no-dependencies --out "$OUT_ABS"
)

echo "Created stable VSIX: $OUT_ABS"
echo "vsix-path=$OUT_ABS" >> "$GITHUB_OUTPUT"
24 changes: 23 additions & 1 deletion .github/workflows/automerge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -29,10 +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: npm
cache: ${{ inputs.package-manager }}
cache-dependency-path: ${{ inputs.cache-dependency-path }}

- run: npm install -g @salesforce/plugin-release-management --omit=dev

Expand Down
25 changes: 23 additions & 2 deletions .github/workflows/ctcClose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,39 @@ 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:
runs-on: static-ip-ubuntu-24-runners
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: |
Expand Down
25 changes: 23 additions & 2 deletions .github/workflows/ctcOpen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
Loading