diff --git a/.github/actions/vscode/download-release-vsix/action.yml b/.github/actions/vscode/download-release-vsix/action.yml new file mode 100644 index 0000000..08e401b --- /dev/null +++ b/.github/actions/vscode/download-release-vsix/action.yml @@ -0,0 +1,46 @@ +name: Download Release VSIXs +description: Download VSIX assets from a GitHub release and determine its release type + +inputs: + release-tag: + description: GitHub release tag containing the VSIX assets + required: true + +outputs: + pre-release: + description: Whether the GitHub release is a pre-release + value: ${{ steps.release-type.outputs.pre-release }} + +runs: + using: composite + steps: + - name: Download VSIXs + id: download + shell: bash + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ inputs.release-tag }} + run: | + mkdir extensions + gh release download "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --pattern '*.vsix' --dir extensions + + if ! find extensions -type f -name '*.vsix' -print -quit | grep -q .; then + echo "No VSIX files found in release $RELEASE_TAG" + exit 1 + fi + + echo 'Downloaded VSIX files:' + find extensions -type f -name '*.vsix' + + - name: Detect release type + id: release-type + shell: bash + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ inputs.release-tag }} + run: | + if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json isPrerelease --jq .isPrerelease | grep -qx true; then + echo 'pre-release=true' >> "$GITHUB_OUTPUT" + else + echo 'pre-release=false' >> "$GITHUB_OUTPUT" + fi diff --git a/.github/workflows/openvsx-publish-release-vsix.yml b/.github/workflows/openvsx-publish-release-vsix.yml new file mode 100644 index 0000000..b5dd09f --- /dev/null +++ b/.github/workflows/openvsx-publish-release-vsix.yml @@ -0,0 +1,53 @@ +name: Publish Release VSIXs to Open VSX + +on: + workflow_call: + inputs: + release-tag: + description: GitHub release tag containing the VSIX assets + required: true + type: string + dry-run: + description: Download and inspect VSIXs without publishing + required: false + default: false + type: boolean + secrets: + IDEE_OVSX_PAT: + description: Open VSX publishing token + required: true + +permissions: + contents: read + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Download release VSIXs + id: release + uses: salesforcecli/github-workflows/.github/actions/vscode/download-release-vsix@03cb2583f2edf45cd7d2688f2a452ee29511229e + with: + release-tag: ${{ inputs.release-tag }} + + - name: Publish VSIXs + env: + DRY_RUN: ${{ inputs.dry-run }} + IDEE_OVSX_PAT: ${{ secrets.IDEE_OVSX_PAT }} + PRE_RELEASE: ${{ steps.release.outputs.pre-release }} + run: | + while IFS= read -r -d '' vsix; do + args=("$vsix" -p "$IDEE_OVSX_PAT" --skip-duplicate) + pre_release_suffix='' + if [ "$PRE_RELEASE" = true ]; then + args+=(--pre-release) + pre_release_suffix=' --pre-release' + fi + + if [ "$DRY_RUN" = true ]; then + echo "Would publish $vsix to Open VSX with --skip-duplicate${pre_release_suffix}" + continue + fi + + npx ovsx publish "${args[@]}" + done < <(find extensions -type f -name '*.vsix' -print0) diff --git a/.github/workflows/vscode-publish-release-vsix.yml b/.github/workflows/vscode-publish-release-vsix.yml new file mode 100644 index 0000000..9fb051f --- /dev/null +++ b/.github/workflows/vscode-publish-release-vsix.yml @@ -0,0 +1,51 @@ +name: Publish Release VSIXs to VS Code Marketplace + +on: + workflow_call: + inputs: + release-tag: + description: GitHub release tag containing the VSIX assets + required: true + type: string + dry-run: + description: Download and inspect VSIXs without publishing + required: false + default: false + type: boolean + secrets: + VSCE_PERSONAL_ACCESS_TOKEN: + description: VS Code Marketplace publishing token + required: true + +permissions: + contents: read + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Download release VSIXs + id: release + uses: salesforcecli/github-workflows/.github/actions/vscode/download-release-vsix@03cb2583f2edf45cd7d2688f2a452ee29511229e + with: + release-tag: ${{ inputs.release-tag }} + + - name: Publish VSIXs + env: + DRY_RUN: ${{ inputs.dry-run }} + PRE_RELEASE: ${{ steps.release.outputs.pre-release }} + VSCE_PERSONAL_ACCESS_TOKEN: ${{ secrets.VSCE_PERSONAL_ACCESS_TOKEN }} + run: | + while IFS= read -r -d '' vsix; do + args=(--packagePath "$vsix" --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: @vscode/vsce publish ${args[*]}" + continue + fi + + VSCE_PAT="$VSCE_PERSONAL_ACCESS_TOKEN" npx @vscode/vsce publish "${args[@]}" + done < <(find extensions -type f -name '*.vsix' -print0) diff --git a/README.md b/README.md index b3db4c9..49a824b 100644 --- a/README.md +++ b/README.md @@ -642,6 +642,34 @@ jobs: - `version-bump` (optional) - Version bump type: `auto`, `patch`, `minor`, `major` (default: `auto`) - `slack-notification-title` (optional) - Slack notification title (default: `🎉 Extensions Released Successfully!`) +### 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. + +```yaml +jobs: + publish: + uses: salesforcecli/github-workflows/.github/workflows/vscode-publish-release-vsix.yml@main + with: + release-tag: v67.10.0 + dry-run: true # Download and inspect without publishing + secrets: inherit +``` + +### 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. + +```yaml +jobs: + publish: + uses: salesforcecli/github-workflows/.github/workflows/openvsx-publish-release-vsix.yml@main + with: + release-tag: v67.10.0 + dry-run: true # Download and inspect without publishing + secrets: inherit +``` + ### vscode-promote-prerelease Promotes a vetted nightly build to pre-release on VS Code Marketplace and Open VSX. This workflow finds the oldest unpromoted nightly that meets the minimum age requirement, verifies CI checks passed, and publishes it as a pre-release.