Skip to content

fix: update Announcement spec to v3.74.0 and unindent README details … #49

fix: update Announcement spec to v3.74.0 and unindent README details …

fix: update Announcement spec to v3.74.0 and unindent README details … #49

name: Publish Stable Extension
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
# Least privilege: publish-stable escalates to contents: write via its own
# job-level permissions block.
permissions:
contents: read
jobs:
check-pr-approval:
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- name: Check PR approval status
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
SHA: ${{ github.sha }}
run: |
pr_number=$(gh api "repos/${REPO}/commits/${SHA}/pulls" \
--header "Accept: application/vnd.github+json" \
--jq '.[0].number // empty')
if [ -z "$pr_number" ]; then
echo "No PR found for commit ${SHA}. Deployment requires an approved PR."
exit 1
fi
review_decision=$(gh api graphql \
-f owner="${REPO%%/*}" \
-f name="${REPO#*/}" \
-F number="$pr_number" \
-f query='
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
reviewDecision
}
}
}' \
--jq '.data.repository.pullRequest.reviewDecision // "NONE"')
echo "PR #${pr_number} review_decision: ${review_decision}"
if [ "$review_decision" != "APPROVED" ]; then
echo "PR #${pr_number} is not approved (state: ${review_decision}). Deployment blocked."
exit 1
fi
echo "PR #${pr_number} is approved. Proceeding."
publish-stable:
needs: [check-pr-approval]
runs-on: ubuntu-latest
environment: marketplace-production
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
with:
install-args: "--frozen-lockfile"
- name: Validate package identity
run: |
package_name=$(node -p "require('./src/package.json').name")
publisher=$(node -p "require('./src/package.json').publisher")
test "$package_name" = "zoo-code"
test "$publisher" = "ZooCodeOrganization"
- name: Validate publish ref
run: |
if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ] && [ "$GITHUB_REF_NAME" != "main" ]; then
echo "Manual stable publishes must run from main, not ${GITHUB_REF_NAME}."
exit 1
fi
- name: Validate release tag
if: github.event_name == 'push'
run: |
package_version=$(node -p "require('./src/package.json').version")
tag_version="${GITHUB_REF_NAME#v}"
if [ "$package_version" != "$tag_version" ]; then
echo "Tag v${tag_version} does not match src/package.json version ${package_version}."
exit 1
fi
- name: Build workspace packages
run: |
pnpm --filter @roo-code/build build
pnpm --filter @roo-code/vscode-webview build
- name: Package extension
env:
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
run: |
package_version=$(node -p "require('./src/package.json').version")
pnpm --filter ./src vsix
vsix_path="bin/zoo-code-${package_version}.vsix"
test -f "$vsix_path"
unzip -l "$vsix_path" > /tmp/zoo-code-vsix-contents.txt
grep -q "extension/package.json" /tmp/zoo-code-vsix-contents.txt
grep -q "extension/package.nls.json" /tmp/zoo-code-vsix-contents.txt
grep -q "extension/dist/extension.js" /tmp/zoo-code-vsix-contents.txt
grep -q "extension/webview-ui/audio/celebration.wav" /tmp/zoo-code-vsix-contents.txt
grep -q "extension/webview-ui/build/assets/index.js" /tmp/zoo-code-vsix-contents.txt
grep -q "extension/assets/codicons/codicon.ttf" /tmp/zoo-code-vsix-contents.txt
grep -q "extension/assets/vscode-material-icons/icons/3d.svg" /tmp/zoo-code-vsix-contents.txt
- name: Validate packaged manifest identity
run: |
package_version=$(node -p "require('./src/package.json').version")
vsix_path="bin/zoo-code-${package_version}.vsix"
artifact_name=$(unzip -p "$vsix_path" extension/package.json | jq -r '.name')
artifact_publisher=$(unzip -p "$vsix_path" extension/package.json | jq -r '.publisher')
test "$artifact_name" = "zoo-code"
test "$artifact_publisher" = "ZooCodeOrganization"
- name: Publish to VS Code Marketplace
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: |
package_version=$(node -p "require('./src/package.json').version")
npx @vscode/vsce publish --packagePath "bin/zoo-code-${package_version}.vsix"
echo "Published ZooCodeOrganization.zoo-code ${package_version} to VS Code Marketplace"
- name: Publish to Open VSX Registry
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}
run: |
package_version=$(node -p "require('./src/package.json').version")
pnpm exec ovsx publish "bin/zoo-code-${package_version}.vsix" --skip-duplicate
echo "Published ZooCodeOrganization.zoo-code ${package_version} to Open VSX Registry"
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
package_version=$(node -p "require('./src/package.json').version")
if [ "${GITHUB_REF_TYPE:-}" = "tag" ]; then
tag_name="$GITHUB_REF_NAME"
else
tag_name="v${package_version}"
fi
vsix_path="bin/zoo-code-${package_version}.vsix"
changelog_content=$(awk -v version="$package_version" '
$0 ~ "^## \\[" version "\\]" { found = 1 }
found && $0 == "---" { exit }
found && $0 ~ "^## " && $0 !~ "^## \\[" version "\\]" { exit }
found { print }
' CHANGELOG.md)
if [ -z "$changelog_content" ]; then
changelog_content="Release ${tag_name}"
fi
printf "%s\n" "$changelog_content" > /tmp/zoo-code-release-notes.md
if gh release view "$tag_name" >/dev/null 2>&1; then
gh release upload "$tag_name" "$vsix_path" --clobber
else
gh release create "$tag_name" \
--title "Zoo Code ${tag_name}" \
--notes-file /tmp/zoo-code-release-notes.md \
--target "$GITHUB_SHA" \
"$vsix_path"
fi