Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
86 changes: 86 additions & 0 deletions .github/actions/vscode/publish-release-vsix/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Publish Release VSIXs (OIDC)
description: >-
Downloads every VSIX asset from a GitHub release and publishes it to the VS Code
Marketplace via vsce --oidc trusted publishing, with per-VSIX retry. Composite action
(not a reusable workflow) -- the Marketplace's OIDC trust check keys off
job_workflow_ref, which for a nested reusable *workflow* always points at this repo
rather than the caller's, so OIDC publishing only works when this logic runs as a step
inside the caller's own job. The calling job must declare `permissions: id-token:
write` and have a Trusted Publishing policy registered for its repo + workflow
filename on the Marketplace. Use vscode-publish-release-vsix.yml instead when
publishing with a VSCE_PERSONAL_ACCESS_TOKEN PAT, where job_workflow_ref doesn't matter.

inputs:
release-tag:
description: GitHub release tag containing the VSIX assets
required: true
dry-run:
description: Download and inspect VSIXs without publishing
required: false
default: 'false'
vsix-name-pattern:
description: Glob of downloaded VSIX file names to publish
required: false
default: '*.vsix'
exclude-web-vsix:
description: Exclude *-web-* VSIXs from publishing
required: false
default: 'false'

runs:
using: composite
steps:
- name: Download release VSIXs
id: release
uses: salesforcecli/github-workflows/.github/actions/vscode/download-release-vsix@main

Check warning on line 35 in .github/actions/vscode/publish-release-vsix/action.yml

View check run for this annotation

APPLICATION-SECURITY-AGENT / SAST

Vulnerability found with Rule : base.yaml.github-actions.security.third-party-action-not-pinned-to-commit-sha .

Description : **Supply Chain Risk via Unpinned Third-Party GitHub Action** A third-party GitHub Action is referenced by a mutable tag or branch (e.g. `@v1`, `@main`) instead of a full-length commit SHA. Tags and branches can be silently re-pointed by the upstream maintainer or an attacker who compromises that repository, causing your workflow to execute unexpected code with access to your repository secrets. **Risk:** A compromised or hijacked upstream action can exfiltrate secrets (`GITHUB_TOKEN`, deploy keys, cloud credentials), inject malicious build artifacts, or pivot into protected environments. Recent supply-chain incidents (e.g. `tj-actions/changed-files`) demonstrate this is an active attack vector. **Common in GitHub Actions:** Semantic-version tags (`@v3`) and branch refs (`@main`, `@master`) are mutable in Git and are not equivalent to immutable releases. Only a full 40-character commit SHA pins the action to a specific, verifiable snapshot. Take Action : If you think this vulnerability is a false positive or not exploitable, please put the triageId: .github/actions/vscode/publish-release-vsix/action.yml:e68980df1b3056d1ed4a4ae98eaff88958bf9cb8c26945c8ac86d6936409d21e under respective sections: false_positive or not_exploitable in the triage.yaml file at this location sfdc_metadata/sast_scan_triage/triage.yaml. If the vulnerability is true positive please proceed with remediation to ensure secure code. Suggested Remediation : Pin every third-party action to a full-length (40-character) commit SHA and keep the human-readable version in a trailing comment for reviewers. Renovate/Dependabot can then update the SHA safely. Example: # Vulnerable - mutable tag can be re-pointed by upstream - uses: some-org/some-action@v3 # Vulnerable - branch ref is mutable - uses: some-org/some-action@main # Secure - full commit SHA (immutable), version pinned in comment - uses: some-org/some-action@abcdef0123456789abcdef0123456789abcdef01 # v3.1.0 # Secure - docker action pinned by image digest - uses: docker://alpine@sha256:402d21757a03a114d273bbe372fa4b9eca567e8b6c332fa7ebf982b902207242 For a sample triage.yaml file format please visit the Raw output section. For more details, please refer to checks tab and go to the APPLICATION-SECURITY-AGENT/SAST check.
Raw output
false_positive:
  - id: .github/actions/vscode/publish-release-vsix/action.yml:e68980df1b3056d1ed4a4ae98eaff88958bf9cb8c26945c8ac86d6936409d21e
    justification: <Enter your justification for false positive here>
not_exploitable: []
with:
release-tag: ${{ inputs.release-tag }}

- name: Publish VSIXs
shell: bash
env:
DRY_RUN: ${{ inputs.dry-run }}
PRE_RELEASE: ${{ steps.release.outputs.pre-release }}
VSIX_PATTERN: ${{ inputs.vsix-name-pattern }}
EXCLUDE_WEB: ${{ inputs.exclude-web-vsix }}
run: |
# Marketplace gallery requests can sit until typed-rest-client's 180s
# socket timeout. vsce has no timeout flag; retry per VSIX.
# --skip-duplicate makes a retry a no-op if the first attempt committed.
publish_with_retry() {
local attempt
for attempt in 1 2 3; do
echo "Publish attempt ${attempt}/3"
if "$@"; then
return 0
fi
if [ "$attempt" -lt 3 ]; then
echo "Publish failed; retrying in 15s..."
sleep 15
fi
done
return 1
}

while IFS= read -r -d '' vsix; do
args=(--packagePath "$vsix" --oidc --skip-duplicate)
if [ "$PRE_RELEASE" = true ]; then
args+=(--pre-release)
fi

if [ "$DRY_RUN" = true ]; then
echo "Would publish $vsix to the VS Code Marketplace with --skip-duplicate: @vscode/vsce publish ${args[*]}"
continue
fi

if ! publish_with_retry npx @vscode/vsce publish "${args[@]}"; then
echo "::error::Failed to publish $vsix after 3 attempts"
exit 1
fi
done < <(
if [ "$EXCLUDE_WEB" = "true" ]; then
find extensions -type f -name "$VSIX_PATTERN" ! -iname '*-web-*' -print0
else
find extensions -type f -name "$VSIX_PATTERN" -print0
fi
)
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ jobs:

### vscode-publish-release-vsix

Downloads every VSIX asset from a GitHub release in the calling repository and publishes it to the VS Code Marketplace. VSIX files are found recursively, the release's pre-release state is preserved, and already-published versions are skipped.
Downloads every VSIX asset from a GitHub release in the calling repository and publishes it to the VS Code Marketplace using a `VSCE_PERSONAL_ACCESS_TOKEN` PAT. VSIX files are found recursively, the release's pre-release state is preserved, and already-published versions are skipped.

```yaml
jobs:
Expand All @@ -779,6 +779,24 @@ jobs:
secrets: inherit
```

**Publishing via Marketplace OIDC trusted publishing instead of a PAT?** Use the `vscode/publish-release-vsix` composite action directly in your own job instead of this reusable workflow. The Marketplace's OIDC trust check keys off `job_workflow_ref`, which for a nested reusable *workflow* always points at this repo rather than the caller's -- so OIDC publishing only works when the publish step runs inside the caller's own job:

```yaml
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # vsce exchanges this job's OIDC token for a Marketplace publishing token
steps:
- uses: salesforcecli/github-workflows/.github/actions/vscode/publish-release-vsix@main
with:
release-tag: v67.10.0
dry-run: true # Download and inspect without publishing
```

This requires a Trusted Publishing policy registered for the calling repo + this exact workflow filename on the Marketplace publisher management page.

### openvsx-publish-release-vsix

Downloads every VSIX asset from a GitHub release in the calling repository and publishes it to Open VSX. VSIX files are found recursively, the release's pre-release state is preserved, and already-published versions are skipped.
Expand Down