Set up automatic VS Code publishing (#3905)

When pushing to production branch we now also package and publish a new
version of the VS Code extension. We get the last version from VS Code
marketplace and update the package.json with that version. We don't
commit that to the repo though (see the discussion below).

I added `VSCE_PAT` secret (my own personal access token from the
dev.azure.com), which will expire in 1 year. This is used when running
the publish command.

Some more info here:
- [Publishing from
CI](https://code.visualstudio.com/api/working-with-extensions/continuous-integration#github-actions)
- Publishing uses `VSCE_PAT` env variable

![image](https://github.com/tldraw/tldraw/assets/2523721/df971c57-5197-4525-bc58-d50dd4bd8f3c)


### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [x] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [x] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Release Notes

- Automate publishing of the VS Code extension.
This commit is contained in:
Mitja Bezenšek 2024-06-17 16:14:42 +02:00 committed by GitHub
parent 1bcc16d15a
commit ccc673b5af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 88 additions and 0 deletions

View file

@ -0,0 +1,39 @@
name: Publish VS Code Extension
on:
push:
branches:
- production
env:
CI: 1
PRINT_GITHUB_ANNOTATIONS: 1
defaults:
run:
shell: bash
jobs:
deploy:
name: Publish VS Code Extension
timeout-minutes: 15
runs-on: ubuntu-latest-16-cores-open
steps:
- name: Check out code
uses: actions/checkout@v3
with:
submodules: true
- uses: ./.github/actions/setup
- name: Build types
run: yarn build-types
- name: Get extension info from the marketplace
working-directory: 'apps/vscode/extension'
run: yarn get-info
- name: Publish extension
run: yarn tsx ./scripts/publish-vscode-extension.ts
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}

View file

@ -123,6 +123,7 @@
"scripts": {
"dev": "tsx scripts/dev.ts",
"build": "cd ../editor && yarn build && cd ../extension && tsx scripts/build.ts",
"get-info": "vsce show tldraw-org.tldraw-vscode --json > extension.json",
"package": "yarn build && tsx scripts/package.ts",
"publish": "vsce publish",
"lint": "yarn run -T tsx ../../../scripts/lint.ts",

View file

@ -0,0 +1,48 @@
import { existsSync, readFileSync, writeFileSync } from 'fs'
import path from 'path'
import { exec } from './lib/exec'
import { makeEnv } from './lib/makeEnv'
// VSCE_PAT needs to be set. It is used by the vsce publish command.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const env = makeEnv(['VSCE_PAT'])
const EXTENSION_DIR = 'apps/vscode/extension'
async function updateExtensionVersion() {
const extensionInfoJsonPath = path.join(EXTENSION_DIR, 'extension.json')
if (!existsSync(extensionInfoJsonPath)) {
throw new Error('Published extension info not found.')
}
const extensionInfoJson = JSON.parse(readFileSync(extensionInfoJsonPath, 'utf8'))
const version = extensionInfoJson.versions[0].version
if (!version) {
throw new Error('Could not get the version of the published extension.')
}
const versionSplit = version.split('.')
versionSplit[2] = Number(versionSplit[2]) + 1
const nextVersion = versionSplit.join('.')
const packageJsonPath = path.join(EXTENSION_DIR, 'package.json')
if (!existsSync(packageJsonPath)) {
throw new Error("Could not find the extension's package.json file.")
}
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
packageJson.version = nextVersion
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, '\t') + '\n')
}
async function packageAndPublish() {
await exec('yarn', ['package'], { pwd: EXTENSION_DIR })
await exec('yarn', ['publish'], { pwd: EXTENSION_DIR })
}
async function main() {
await updateExtensionVersion()
await packageAndPublish()
}
main().catch(async (err) => {
console.error(err)
process.exit(1)
})