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
5 changes: 5 additions & 0 deletions .bumpy/vscode-oidc-publishing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
env-spec-language: patch
---

Maintenance release — no functional changes (switches Marketplace publishing to OIDC)
32 changes: 29 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
outputs:
mode: ${{ steps.plan.outputs.mode }}
includes-varlock: ${{ contains(fromJSON(steps.plan.outputs.json).packageNames, 'varlock') }}
includes-vscode: ${{ contains(fromJSON(steps.plan.outputs.json).packageNames, 'env-spec-language') }}
macos-cache-key: ${{ steps.keys.outputs.macos-cache-key }}
rust-source-hash: ${{ steps.keys.outputs.rust-source-hash }}
macos-cache-hit: ${{ steps.macos-cache.outputs.cache-hit }}
Expand Down Expand Up @@ -310,6 +311,32 @@ jobs:
env:
BUILD_TYPE: release

# Resolve VS Code extension publishing secrets from 1Password via varlock
# (schema lives in packages/vscode-plugin/.env.schema). Only OP_CI_TOKEN is
# injected here; AZURE_CLIENT_ID / AZURE_TENANT_ID (for OIDC) and OVSX_PAT
# (for Open VSX) come from the VarlockCI vault and are exported to the job
# environment for the steps below. (build:libs above provides the local
# varlock the action uses.)
- name: Load extension publishing secrets from 1Password
if: needs.plan.outputs.mode == 'publish' && needs.plan.outputs.includes-vscode == 'true'
uses: dmno-dev/varlock-action@v1.0.1
with:
working-directory: packages/vscode-plugin
env:
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}

# Authenticate to Azure via GitHub OIDC (workload identity federation) so the
# VS Code Marketplace publish (`vsce publish --azure-credential`) can mint a
# short-lived token instead of a long-lived VSCE_PAT. The federated credential
# on the Azure side is scoped to this repo's main branch; see docs below.
- name: Azure login (OIDC) for Marketplace publishing
if: needs.plan.outputs.mode == 'publish' && needs.plan.outputs.includes-vscode == 'true'
uses: azure/login@v2
with:
client-id: ${{ env.AZURE_CLIENT_ID }}
tenant-id: ${{ env.AZURE_TENANT_ID }}
allow-no-subscriptions: true

- name: Create Release PR / Publish
run: bunx @varlock/bumpy ci release
env:
Expand All @@ -318,8 +345,7 @@ jobs:
# (see https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/triggering-a-workflow#triggering-a-workflow-from-a-workflow)
BUMPY_GH_TOKEN: ${{ secrets.BUMPY_GH_TOKEN }}
GH_TOKEN: ${{ github.token }}
# these are needed for vscode extension publishing
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
# VS Code Marketplace auth comes from the Azure OIDC login step above;
# Open VSX (OVSX_PAT) is loaded into the job env by the varlock step above.

# TODO: send notifications?
28 changes: 23 additions & 5 deletions .github/workflows/vscode-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # required for Azure OIDC login
steps:
- uses: actions/checkout@v6
- name: Setup Bun
Expand All @@ -21,19 +22,36 @@ jobs:
- name: Install node deps
run: bun install

# Build varlock so the action can resolve secrets from 1Password
- name: Build libraries
run: bun run build:libs

# Resolve publishing secrets from 1Password via varlock: AZURE_CLIENT_ID /
# AZURE_TENANT_ID (for Marketplace OIDC) and OVSX_PAT (for Open VSX).
- name: Load extension publishing secrets from 1Password
uses: dmno-dev/varlock-action@v1.0.1
with:
working-directory: packages/vscode-plugin
env:
OP_CI_TOKEN: ${{ secrets.OP_CI_TOKEN }}

# OIDC login so `vsce publish --azure-credential` can mint a short-lived token
- name: Azure login (OIDC) for Marketplace publishing
uses: azure/login@v2
with:
client-id: ${{ env.AZURE_CLIENT_ID }}
tenant-id: ${{ env.AZURE_TENANT_ID }}
allow-no-subscriptions: true

- name: Build and package extension
working-directory: packages/vscode-plugin
run: bun run package

- name: Publish to VS Code Marketplace
working-directory: packages/vscode-plugin
run: bun run publish:vsce
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}

# OVSX_PAT was exported to the job env by the varlock step above
- name: Publish to Open VSX
working-directory: packages/vscode-plugin
run: bun run publish:ovsx
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}

2 changes: 2 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions packages/vscode-plugin/.env.schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# @defaultSensitive=false @defaultRequired=infer
# @plugin(@varlock/1password-plugin)
# In CI, OP_CI_TOKEN is injected and takes precedence; locally (no token) the
# 1Password desktop app is used. (token wins over allowAppAuth when both apply.)
# @initOp(token=$OP_CI_TOKEN, allowAppAuth=not($VARLOCK_IS_CI))
# ---

# True when running in CI (auto-detected). Declared explicitly so it resolves as
# a graph item (available early enough to gate the @initOp app-auth fallback).
# @type=boolean
VARLOCK_IS_CI=

# 1Password service account token. Injected in CI (GitHub Actions secret).
# Locally, leave it unset — 1Password desktop app auth is used instead
# (@initOp falls back to app auth when not in CI).
# @type=opServiceAccountToken @sensitive
OP_CI_TOKEN=

# Azure identity used for OIDC publishing to the VS Code Marketplace
# (vsce publish --azure-credential), instead of an expiring VSCE_PAT.
# Referenced by item id (the "vscode-marketplace-publishing" item in the
# VarlockCI vault) — stable across renames, per varlock guidance.
AZURE_CLIENT_ID=op("op://VarlockCI/jqci36cap7pkq3kaen5toyu4n4/azure-identity-client-id")
AZURE_TENANT_ID=op("op://VarlockCI/jqci36cap7pkq3kaen5toyu4n4/azure-identity-tenant-id")

# Open VSX access token, for publishing to the Open VSX registry (ovsx publish).
# Open VSX is a separate registry from the VS Code Marketplace and isn't covered
# by Azure OIDC, so it still uses a token — now sourced from 1Password.
# @sensitive
OVSX_PAT=op("op://VarlockCI/jqci36cap7pkq3kaen5toyu4n4/OVSX registry/ovsx-pat")
4 changes: 3 additions & 1 deletion packages/vscode-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,19 @@
"test:grammar": "vscode-tmgrammar-test -g ./language/env-spec.tmLanguage.json ./test/grammar.test.txt",
"test:ci": "vitest --run && bun run test:grammar",
"package": "bun run build && vsce package -o env-spec-language.vsix --no-dependencies",
"publish:vsce": "vsce publish -i env-spec-language.vsix",
"publish:vsce": "vsce publish -i env-spec-language.vsix --azure-credential",
"publish:ovsx": "ovsx publish -i env-spec-language.vsix",
"publish": "bun run package && bun run publish:vsce && bun run publish:ovsx",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "catalog:",
"@types/vscode": "^1.99.0",
"@varlock/1password-plugin": "workspace:*",
"@vscode/vsce": "^3.6.2",
"ovsx": "^0.10.6",
"tsup": "catalog:",
"varlock": "workspace:*",
"vitest": "catalog:",
"vscode-tmgrammar-test": "^0.1.3"
},
Expand Down