diff --git a/.codex/skills/vscode-release/SKILL.md b/.codex/skills/vscode-release/SKILL.md deleted file mode 100644 index f24665df..00000000 --- a/.codex/skills/vscode-release/SKILL.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: vscode-release -description: Execute the VS Code extension release workflow when the user asks to publish/release the difit VS Code extension. Run local VSIX build and smoke verification first, ask for explicit OK in Japanese, then publish with vsce. -metadata: - internal: true ---- - -# VS Code Extension Release Workflow - -Follow this workflow for the current repository. - -## Prepare local build verification - -1. Verify release target files in `packages/vscode` and confirm current branch state. -2. Run `pnpm install --frozen-lockfile`. -3. Run `pnpm -C packages/vscode run package`. -4. Read `packages/vscode/package.json` and confirm the current extension version. -5. Confirm the VSIX exists at `packages/vscode/difit-vscode-.vsix`. -6. Ask the user to smoke test the local VSIX install in VS Code: - - Install from VSIX. - - Confirm the `difit` command opens review correctly. - - Confirm the toolbar button/icon appears and works. -7. Ask for explicit OK in Japanese before publishing. - -## Release after explicit OK - -Treat the locally verified build result at OK time as the source of truth. Do not skip rebuilding after version changes. - -1. Bump extension version in `packages/vscode/package.json`: - - `pnpm -C packages/vscode version patch --no-git-tag-version` -2. Re-run `pnpm -C packages/vscode run package` and confirm the new VSIX filename. -3. Commit `packages/vscode/package.json` with an English message: `chore(vscode): release vX.Y.Z`. -4. Create tag `vscode-vX.Y.Z`. -5. Push `main` and tags: `git push origin main --tags`. -6. If push is rejected by non-fast-forward: - - Run `git pull --rebase origin main`. - - Retry `git push origin main --tags`. -7. Publish to Visual Studio Marketplace: - - `pnpm -C packages/vscode exec vsce publish` - - Use the already bumped version from `packages/vscode/package.json`. - -## Output to user - -- Respond in Japanese. -- Report local build verification result, released version, created tag, and publish result. -- Mention if any recovery step was required (for example, rebase due to non-fast-forward). diff --git a/.codex/skills/vscode-release/agents/openai.yaml b/.codex/skills/vscode-release/agents/openai.yaml deleted file mode 100644 index f4293055..00000000 --- a/.codex/skills/vscode-release/agents/openai.yaml +++ /dev/null @@ -1,4 +0,0 @@ -interface: - display_name: 'VSCode Release' - short_description: 'Run VS Code extension release with local VSIX verification.' - default_prompt: 'Use $vscode-release to verify local VSIX build, ask for explicit OK, and publish the VS Code extension.' diff --git a/.github/workflows/publish-vscode.yml b/.github/workflows/publish-vscode.yml new file mode 100644 index 00000000..d80e28da --- /dev/null +++ b/.github/workflows/publish-vscode.yml @@ -0,0 +1,79 @@ +name: Publish VS Code Extension + +on: + release: + types: + - published + workflow_dispatch: + +permissions: + contents: read + +jobs: + publish: + name: Publish to VS Code Marketplace + runs-on: ubuntu-latest + # Must match the federated credential subject configured on the Entra ID + # identity (repo:yoshiko-pg/difit:environment:release). + environment: release + permissions: + # Attach the .vsix to the GitHub release. + contents: write + # Issue the OIDC token for Entra ID workload identity federation. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: '24' + + - name: Setup pnpm + uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + with: + version: 11.6.0 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + # The extension bundles difit, so its Marketplace version tracks the + # difit version being released. The repository keeps a placeholder + # version; it is only rewritten here at publish time. + - name: Sync extension version with difit + run: | + VERSION=$(node -p "require('./package.json').version") + (cd packages/vscode && npm pkg set version="$VERSION") + echo "Publishing yoshiko-pg.difit $VERSION" + + - name: Package VS Code extension + run: pnpm run package:vscode + + # Secure automated publishing: no PAT. The workflow exchanges its OIDC + # token for an Entra ID session, and vsce publishes with that credential. + # https://code.visualstudio.com/api/working-with-extensions/publishing-extension + - name: Azure login (workload identity federation) + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Publish to VS Code Marketplace + working-directory: packages/vscode + run: pnpm exec vsce publish --no-dependencies --azure-credential --packagePath difit-*.vsix + + - name: Publish to Open VSX + if: ${{ secrets.OVSX_PAT != '' }} + working-directory: packages/vscode + env: + OVSX_PAT: ${{ secrets.OVSX_PAT }} + run: pnpm dlx ovsx publish difit-*.vsix -p "$OVSX_PAT" + + - name: Attach VSIX to GitHub release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + run: gh release upload "${{ github.event.release.tag_name }}" packages/vscode/difit-*.vsix --clobber diff --git a/packages/vscode/README.md b/packages/vscode/README.md index e958b437..b8b5acfe 100644 --- a/packages/vscode/README.md +++ b/packages/vscode/README.md @@ -30,3 +30,9 @@ pnpm run build # builds the difit client assets into dist/client pnpm -C packages/vscode run build # bundles the extension into packages/vscode/dist pnpm -C packages/vscode run package # produces the .vsix ``` + +## Release + +Publishing is automated: when a difit GitHub release is published, the `Publish VS Code Extension` workflow rebuilds the extension, sets its version to the released difit version, publishes it to the VS Code Marketplace (and Open VSX when `OVSX_PAT` is configured), and attaches the `.vsix` to the GitHub release. The `version` field in this package.json is a placeholder; it is rewritten in CI at publish time. + +Marketplace authentication uses [secure automated publishing](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#secure-automated-publishing-to-visual-studio-marketplace) (Microsoft Entra ID workload identity federation + `vsce publish --azure-credential`) instead of a PAT: the workflow's `release` environment exchanges a GitHub OIDC token for an Entra ID credential of an identity that is a member of the `yoshiko-pg` publisher. Required repository secrets: `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`. diff --git a/packages/vscode/package.json b/packages/vscode/package.json index 853301ea..2e67f777 100644 --- a/packages/vscode/package.json +++ b/packages/vscode/package.json @@ -1,5 +1,5 @@ { - "name": "difit-vscode", + "name": "difit", "displayName": "difit", "version": "0.1.0", "description": "GitHub-like diff review inside VS Code. difit is bundled — no extra install needed.",