From 6143db41c5175475a222f08c76b13ea97002d12f Mon Sep 17 00:00:00 2001 From: Dario Valdespino Date: Thu, 10 Sep 2026 21:21:37 -0300 Subject: [PATCH 1/2] fix: ignore nested project manifests Signed-off-by: Dario Valdespino --- PUBLISHING.md | 104 +++++++++++++++++++++ README.md | 5 +- packages/core/src/elide.ts | 29 ++++++ packages/core/src/index.ts | 2 + packages/core/test/elide.test.ts | 32 ++++++- packages/vscode/CHANGELOG.md | 6 ++ packages/vscode/README.md | 3 +- packages/vscode/src/extension.ts | 21 +++-- packages/vscode/src/projects.ts | 50 ++++++++-- packages/vscode/test/integration/runner.ts | 21 +++++ 10 files changed, 256 insertions(+), 17 deletions(-) create mode 100644 PUBLISHING.md diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 0000000..bbbe3cd --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,104 @@ +# Publishing to the Visual Studio Marketplace + +Everything in this repository that can be automated is in place: the manifest carries the metadata the Marketplace +requires, `bun run --filter elide package` produces a clean `.vsix`, and `.github/workflows/release.yml` publishes on a +`vX.Y.Z` tag as soon as a `VSCE_PAT` secret exists. What is left are the steps that need a human with an account — +none of them can be done from this repository. + +## What the repo already provides + +| Requirement | Where | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `publisher`, `name`, `version`, `engines.vscode` | `packages/vscode/package.json` (`elide-dev.elide`, `0.1.0`, `^1.105.0`) | +| Icon (256×256 PNG, brand mark) | `packages/vscode/icon.png`, rasterized from Elide's official `elide-square-gradient` artwork; 128×128 is the Marketplace minimum, 256×256 is what it recommends for retina listings | +| Gallery banner | `galleryBanner` (`#0F0F0F`, dark) | +| Marketplace README, changelog, license | `packages/vscode/{README.md,CHANGELOG.md,LICENSE}`, all shipped in the `.vsix` | +| Repository / issues / homepage links | `repository`, `bugs`, `homepage` in the manifest | +| Trust and remote declarations | `capabilities.untrustedWorkspaces` (unsupported), `capabilities.virtualWorkspaces` (unsupported), `extensionKind: ["workspace"]` | +| Reproducible package build | `vscode:prepublish` builds `@elide/ide-core` and the bundle, so `vsce package` works from a clean checkout | +| Automated publication | `Release` workflow: tag check → unit tests → `tools/deploy.sh` → `vsce publish --packagePath` (skipped without `VSCE_PAT`) → GitHub release | + +The `.vsix` contents were verified locally: `extension/{package.json,README.md,CHANGELOG.md,LICENSE.txt,icon.png,dist/extension.js}`, 40 KB total, no source or test files. + +## Remaining manual steps + +### 1. Azure DevOps organization and publisher + +1. Sign in to with the Microsoft/Entra account that should own the extension (a shared Elide + account, not a personal one — the publisher cannot be transferred without support intervention). +2. Create (or reuse) an Azure DevOps organization for Elide. +3. Create the publisher at . The **publisher ID must be + exactly `elide-dev`** — that is what `packages/vscode/package.json` and `tools/deploy.sh` assume. If `elide-dev` is + already taken, the manifest `publisher`, the extension ID used by `plugins.elide.dev` (`elide-dev.elide`), and the + README install links all have to change together. +4. Fill in the publisher display name, logo, and links on the management page. This data is publisher-level and cannot + be set from the manifest. + +### 2. Personal access token + +1. In Azure DevOps: **User settings ▸ Personal access tokens ▸ New Token**. +2. Organization: **All accessible organizations** (required; a single-org token fails with a 401 at publish time). +3. Scopes: **Custom defined ▸ Marketplace ▸ Manage**. Nothing else. +4. Expiration: maximum is 1 year — put a calendar reminder on the rotation date, or the release workflow starts + skipping the publish step silently (it only emits a notice when the secret is missing; an expired token fails loudly + instead). +5. Store it as the repository secret **`VSCE_PAT`** (Settings ▸ Secrets and variables ▸ Actions). No other change is + needed: the workflow step activates on its own. + +### 3. Verify the publisher (optional, recommended) + +Domain verification adds the blue check next to the publisher name. It requires adding a TXT record to a domain you +control (`elide.dev`) from the publisher management page. Not required to publish. + +### 4. First publication + +The very first upload of an extension ID is the risky one — the Marketplace validates the manifest, icon, and README +before the extension appears, and rejected uploads can leave the ID in a half-created state. Two options: + +- **Manual first release (recommended).** From a clean checkout: + ```sh + bun install + bun run --filter elide package # → packages/vscode/elide-0.1.0.vsix + cd packages/vscode + bunx @vscode/vsce login elide-dev # paste the PAT + bunx @vscode/vsce publish --no-dependencies --packagePath elide-0.1.0.vsix + ``` + Then tag `v0.1.0` so the plugins.elide.dev upload and GitHub release happen through the workflow (the workflow's + Marketplace step will re-publish the same version and fail if `VSCE_PAT` is already set — publish manually *or* by + tag for the first release, not both). +- **Tag-driven.** Set `VSCE_PAT` first, then push `v0.1.0` and watch the `Release` run. + +Marketplace validation runs asynchronously after upload; the listing goes live within a few minutes, and a validation +failure arrives by email to the publisher account. + +### 5. Post-publication follow-ups + +- Add the Marketplace badges to the READMEs once the listing exists, e.g. + `https://img.shields.io/visual-studio-marketplace/v/elide-dev.elide` (version) and `.../i/elide-dev.elide` + (installs). `img.shields.io` is on vsce's trusted-badge list, so these are safe in the packaged README. +- Replace the "Until the extension is on the Marketplace…" section of the root `README.md` with the Marketplace + install instructions (`code --install-extension elide-dev.elide`), keeping the `plugins.elide.dev` link as the + fallback for air-gapped installs. +- Drop `"preview": true` from `packages/vscode/package.json` when the extension leaves 0.x, so the "Preview" badge + disappears from the listing. +- Consider publishing to **Open VSX** () as well, for VSCodium, Cursor, Windsurf, and Gitpod + users: create an Eclipse Foundation account, sign the publisher agreement, mint an access token, and add an + `npx ovsx publish` step next to the Marketplace step. This needs its own account and agreement, so it is a separate + manual decision. +- Enable **private vulnerability reporting** in the repository settings (Settings ▸ Code security) so the + `security/advisories/new` link in `SECURITY.md` resolves; it 404s for reporters until that switch is on. +- Confirm the org identifiers these files assert, none of which can be checked from this repository: + - `engineering@elide.dev` is the fallback contact in `SECURITY.md` and the enforcement contact in + `CODE_OF_CONDUCT.md`. It is the address on Elide's release GPG key, so it exists — but confirm it routes to + people who should receive vulnerability and conduct reports, or swap in a dedicated mailbox. + - `.github/CODEOWNERS` lists `@sgammon @darvld`, mirroring the main Elide repository's ownership. Switch to a + GitHub team if one is created; CODEOWNERS silently fails for handles without write access to the repo. + +## Things that intentionally were not changed + +- `packages/vscode/package.json` keeps `"private": true`. `vsce` ignores the field (it is checked by npm, not by the + Marketplace); it prevents an accidental `npm publish` of the extension package. +- The extension is not marked as a pre-release (`--pre-release`); `preview: true` is metadata only and does not affect + the release channel. +- No platform-specific (`--target`) packages: the extension is pure JavaScript and depends on a locally installed + Elide CLI. diff --git a/README.md b/README.md index 39ae134..6b59470 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,10 @@ Opening a folder that contains `elide.pkl` runs a **sync**: `intellij.jdkForSymbolResolution` is written to **user** settings. A running Kotlin LSP is then asked to reload. `workspace.json` is a generated artifact — add it to `.gitignore`. Every `elide.pkl` under a workspace folder (outside -`.dev/` and `node_modules/`) becomes a set of modules in that folder's single `workspace.json`. +`.dev/` and `node_modules/`) becomes a set of modules in that folder's single `workspace.json`. A manifest nested +inside another project's directory — a vendored checkout, a sample, a fixture — is a separate build the enclosing +project does not invoke: only the outermost manifest of each tree is imported, and changes to the nested ones do not +trigger a sync. ### Mixed-editor checkouts (`.idea`, Gradle, Maven) diff --git a/packages/core/src/elide.ts b/packages/core/src/elide.ts index d0fc496..0040647 100644 --- a/packages/core/src/elide.ts +++ b/packages/core/src/elide.ts @@ -5,6 +5,7 @@ import { homedir } from "node:os"; import path from "node:path"; import { ElideCommandFailedError, ElideNotFoundError, InvalidElideHomeError, ManifestParseError } from "./errors.js"; import { decodeManifest, type Manifest } from "./manifest.js"; +import { isPathUnder, normalizePath } from "./sourceRoots.js"; export interface ElideDistribution { /** Distribution root, e.g. `~/.local/share/elide`. */ @@ -292,6 +293,34 @@ export function isLockfileName(fileName: string): boolean { return fileName.startsWith(LOCKFILE_PREFIX) && fileName.endsWith(LOCKFILE_EXTENSION); } +/** Whether `p` is a strict descendant of directory `dir`; both are resolved and compared as normalized paths. */ +export function isNestedUnder(p: string, dir: string): boolean { + const child = normalizePath(path.resolve(p)); + const parent = normalizePath(path.resolve(dir)); + return child !== parent && isPathUnder(child, parent); +} + +/** + * Keep only the outermost manifest of each directory tree. + * + * Elide has no subproject concept: a manifest inside another project's directory (a vendored checkout, a sample, a + * test fixture) is a separate build the enclosing project never invokes. Importing both resolves the inner sources + * twice and produces overlapping content roots in the generated workspace model, so the nested ones are dropped. + * Input order is preserved. + */ +export function outermostManifests(manifestPaths: Iterable): string[] { + const all = [...manifestPaths].map((manifest) => ({ manifest, root: path.dirname(path.resolve(manifest)) })); + const roots: string[] = []; + const kept = new Set(); + // Shallower roots first: an ancestor is always shorter than its descendants, so it is decided before them. + for (const entry of [...all].sort((a, b) => a.root.length - b.root.length)) { + if (roots.some((r) => r === entry.root || isNestedUnder(entry.root, r))) continue; + roots.push(entry.root); + kept.add(entry.manifest); + } + return all.map((e) => e.manifest).filter((m) => kept.has(m)); +} + /** * Whether installed dependencies can be trusted without `elide install`: `.dev/dependencies` exists and the * newest `.dev/elide.lock*.bin` is at least as recent as the manifest. diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a46c1c4..2cc208b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -8,7 +8,9 @@ export { distributionAt, isLockfileCurrent, isLockfileName, + isNestedUnder, killProcessTree, + outermostManifests, parseClasspath, resolveElideDistribution, type ClasspathUsage, diff --git a/packages/core/test/elide.test.ts b/packages/core/test/elide.test.ts index 92bd7fd..f6e3d24 100644 --- a/packages/core/test/elide.test.ts +++ b/packages/core/test/elide.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test"; -import { ElideNotFoundError, InvalidElideHomeError, parseClasspath, resolveElideDistribution } from "../src/index.js"; +import { ElideNotFoundError, InvalidElideHomeError, outermostManifests, parseClasspath, resolveElideDistribution } from "../src/index.js"; describe("resolveElideDistribution", () => { const files = new Set(["/custom/elide/bin/elide", "/home/u/.local/share/elide/bin/elide", "/usr/local/bin/elide"]); @@ -27,3 +27,33 @@ describe("parseClasspath", () => { expect(parseClasspath("", "/proj", ":")).toEqual([]); }); }); + +describe("outermostManifests", () => { + test("drops manifests nested inside another project, keeping discovery order", () => { + expect( + outermostManifests([ + "/proj/tools/elide.pkl", + "/proj/elide.pkl", + "/proj/samples/ktjvm/elide.pkl", + "/proj/third_party/vendored/deep/elide.pkl", + ]), + ).toEqual(["/proj/elide.pkl"]); + }); + + test("keeps siblings and prefix-sharing roots", () => { + expect(outermostManifests(["/w/app/elide.pkl", "/w/app-tests/elide.pkl", "/w/lib/elide.pkl"])).toEqual([ + "/w/app/elide.pkl", + "/w/app-tests/elide.pkl", + "/w/lib/elide.pkl", + ]); + }); + + test("an outer manifest discovered last still shadows the inner ones", () => { + expect(outermostManifests(["/w/a/b/elide.pkl", "/w/a/elide.pkl"])).toEqual(["/w/a/elide.pkl"]); + }); + + test("relative and non-normalized paths resolve before comparison", () => { + const cwd = process.cwd(); + expect(outermostManifests(["elide.pkl", `${cwd}/sub/./elide.pkl`])).toEqual(["elide.pkl"]); + }); +}); diff --git a/packages/vscode/CHANGELOG.md b/packages/vscode/CHANGELOG.md index d5f23aa..44b9dac 100644 --- a/packages/vscode/CHANGELOG.md +++ b/packages/vscode/CHANGELOG.md @@ -6,6 +6,12 @@ All notable changes to the Elide extension are documented here. The format follo ## [Unreleased] +### Changed + +- Manifests nested inside another Elide project (vendored checkouts, samples, fixtures) are no longer imported as + projects: only the outermost `elide.pkl` of each directory tree is synced, and edits to nested manifests no longer + mark the folder out of date. Deleting an enclosing manifest promotes the manifests it was shadowing. + ## [0.1.0] - 2026-09-06 First release. diff --git a/packages/vscode/README.md b/packages/vscode/README.md index 08a12b3..e0dd346 100644 --- a/packages/vscode/README.md +++ b/packages/vscode/README.md @@ -11,7 +11,8 @@ Elide's build, run, test, and debug commands are available from the editor. ## Features - **Project sync.** Opening a folder with `elide.pkl` resolves the manifest, installs dependencies when the lockfile is - stale, and reads the compile classpath of every source set. + stale, and reads the compile classpath of every source set. Manifests nested inside another project (vendored + checkouts, samples) are separate builds and are not imported. - **Kotlin/Java code intelligence.** The project model is written as a `workspace.json` the Kotlin LSP imports — modules per source set, libraries with attached sources and javadoc, the selected JDK, and the manifest's Kotlin compiler options. diff --git a/packages/vscode/src/extension.ts b/packages/vscode/src/extension.ts index 15fc35d..32d1d16 100644 --- a/packages/vscode/src/extension.ts +++ b/packages/vscode/src/extension.ts @@ -51,9 +51,15 @@ function registerWatchers(context: vscode.ExtensionContext, workspace: ElideWork ); }; - const onStale = (uri: vscode.Uri, what: string) => { - const folder = workspace.locate(uri)?.folder; - if (!folder || workspace.projectsIn(folder).length === 0 || workspace.isSelfInflicted(folder)) return; + /** + * React to a change under a project root. `rootOf` maps the changed file to the directory whose manifest owns it; + * a path that is not a tracked project root belongs to a nested (ignored) manifest and is not a reason to resync. + */ + const onStale = (uri: vscode.Uri, what: string, rootOf: (fsPath: string) => string) => { + const located = workspace.locate(uri); + if (!located) return; + const folder = located.folder; + if (!workspace.projectAt(rootOf(located.fsPath)) || workspace.isSelfInflicted(folder)) return; workspace.markStale(folder); ui.log(`${what} changed: ${uri.fsPath}`); const policy = readConfig(folder).onManifestChange; @@ -62,7 +68,7 @@ function registerWatchers(context: vscode.ExtensionContext, workspace: ElideWork }; const manifests = vscode.workspace.createFileSystemWatcher(`**/${MANIFEST_NAME}`); - manifests.onDidChange((uri) => onStale(uri, MANIFEST_NAME)); + manifests.onDidChange((uri) => onStale(uri, MANIFEST_NAME, path.dirname)); manifests.onDidCreate((uri) => { const project = workspace.addProject(uri); if (!project) return; @@ -70,17 +76,20 @@ function registerWatchers(context: vscode.ExtensionContext, workspace: ElideWork ui.setStatus("stale"); schedule(project.folder, "project-added"); }); - manifests.onDidDelete((uri) => { + manifests.onDidDelete(async (uri) => { const project = workspace.removeProject(uri); if (!project) return; ui.log(`project removed: ${project.root}`); + // Manifests that were nested inside the deleted project become projects of their own. + await workspace.discover(project.folder); if (workspace.projectsIn(project.folder).length > 0) void workspace.syncFolder(project.folder, "project-removed"); else ui.setStatus("none"); }); const lockfiles = vscode.workspace.createFileSystemWatcher("**/.dev/elide.lock*"); const onLock = (uri: vscode.Uri) => { - if (isLockfileName(path.basename(uri.fsPath))) onStale(uri, "lockfile"); + // `/.dev/elide.lock*.bin`: two levels up from the lockfile. + if (isLockfileName(path.basename(uri.fsPath))) onStale(uri, "lockfile", (p) => path.dirname(path.dirname(p))); }; lockfiles.onDidChange(onLock); lockfiles.onDidCreate(onLock); diff --git a/packages/vscode/src/projects.ts b/packages/vscode/src/projects.ts index 3e1856f..70be3a7 100644 --- a/packages/vscode/src/projects.ts +++ b/packages/vscode/src/projects.ts @@ -9,6 +9,8 @@ import { ManifestParseError, WORKSPACE_JSON, buildProjectModel, + isNestedUnder, + outermostManifests, resolveElideDistribution, writeKotlinLspWorkspace, type ElideDistribution, @@ -78,14 +80,33 @@ export class ElideWorkspace implements vscode.Disposable { return [...(this.folders.get(folder.uri.toString())?.projects.values() ?? [])]; } + /** The tracked project rooted exactly at `root`; `undefined` for a directory whose manifest is nested and ignored. */ + projectAt(root: string): ElideProject | undefined { + const abs = path.resolve(root); + for (const state of this.folders.values()) { + const project = state.projects.get(abs); + if (project) return project; + } + return undefined; + } + + /** + * Find the projects of `folder`: every `elide.pkl` outside `.dev/` and `node_modules/`, minus the manifests nested + * inside another project's directory, which are separate builds this one does not include. + */ async discover(folder: vscode.WorkspaceFolder): Promise { const found = await vscode.workspace.findFiles(new vscode.RelativePattern(folder, `**/${MANIFEST_NAME}`), DISCOVERY_EXCLUDE); + const manifests = outermostManifests(found.map((uri) => uri.fsPath)); const state = this.folderState(folder); const seen = new Set(); - for (const uri of found) { - const root = path.dirname(uri.fsPath); + for (const manifestPath of manifests) { + const root = path.dirname(manifestPath); seen.add(root); - if (!state.projects.has(root)) state.projects.set(root, { root, manifestPath: uri.fsPath, folder }); + if (!state.projects.has(root)) state.projects.set(root, { root, manifestPath, folder }); + } + if (manifests.length < found.length) { + const kept = new Set(manifests); + for (const uri of found) if (!kept.has(uri.fsPath)) this.ui.log(`ignoring nested manifest: ${uri.fsPath}`); } for (const root of [...state.projects.keys()]) if (!seen.has(root)) state.projects.delete(root); this.changed.fire(); @@ -111,17 +132,30 @@ export class ElideWorkspace implements vscode.Disposable { return undefined; } + /** + * Track a manifest a watcher just reported. Returns `undefined` when the manifest sits inside an existing project + * and is therefore not imported; a manifest that encloses tracked projects takes their trees over. + */ addProject(manifestUri: vscode.Uri): ElideProject | undefined { const located = this.locate(manifestUri); if (!located) return undefined; const state = this.folderState(located.folder); const root = path.dirname(located.fsPath); - let project = state.projects.get(root); - if (!project) { - project = { root, manifestPath: located.fsPath, folder: located.folder }; - state.projects.set(root, project); - this.changed.fire(); + const existing = state.projects.get(root); + if (existing) return existing; + const outer = [...state.projects.keys()].find((other) => isNestedUnder(root, other)); + if (outer) { + this.ui.log(`ignoring nested manifest: ${located.fsPath} (inside ${outer})`); + return undefined; + } + for (const inner of [...state.projects.keys()]) { + if (!isNestedUnder(inner, root)) continue; + state.projects.delete(inner); + this.ui.log(`project dropped: ${inner} is now nested inside ${root}`); } + const project: ElideProject = { root, manifestPath: located.fsPath, folder: located.folder }; + state.projects.set(root, project); + this.changed.fire(); return project; } diff --git a/packages/vscode/test/integration/runner.ts b/packages/vscode/test/integration/runner.ts index 63a9010..7cf7b28 100644 --- a/packages/vscode/test/integration/runner.ts +++ b/packages/vscode/test/integration/runner.ts @@ -44,6 +44,27 @@ writeFileSync( const sample = mkdtempSync(path.join(realpathSync(tmpdir()), "elide-ktjvm-")); cpSync(path.join(repoRoot, "samples", "ktjvm"), sample, { recursive: true, filter: (src) => !src.includes(`${path.sep}.dev`) && !src.endsWith("workspace.json") }); +// A vendored checkout with its own manifest, nested inside the project: a separate build the sample never invokes, +// so it must not appear in workspace.json (the module assertion in index.ts covers it). +mkdirSync(path.join(sample, "vendored", "src", "main", "nested"), { recursive: true }); +writeFileSync(path.join(sample, "vendored", "src", "main", "nested", "Nested.kt"), "package nested\n\nfun vendored() = 1\n"); +writeFileSync( + path.join(sample, "vendored", "elide.pkl"), + `amends "elide:project.pkl" +import "elide:Sources.pkl" as Sources + +name = "vendored-sample" + +sources { + ["main"] = new Sources.SourceSetSpec { + paths { + "src/main/**/*.kt" + } + } +} +`, +); + // A checked-in `.idea` (team members on IntelliJ) must not divert the Kotlin LSP away from workspace.json: the // server's auto-detection picks JPS whenever `.idea/modules.xml` exists, so the extension has to pin the importer. mkdirSync(path.join(sample, ".idea", "modules"), { recursive: true }); From 4a1ea812833818fa7f8ef37a8e85b3ff1aff39ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Sep 2026 00:23:11 +0000 Subject: [PATCH 2/2] chore: Bump the actions group with 3 updates Bumps the actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/upload-artifact](https://github.com/actions/upload-artifact) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release). Updates `actions/checkout` from 4 to 7 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v7) Updates `actions/upload-artifact` from 4 to 7 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v7) Updates `softprops/action-gh-release` from 2 to 3 - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: softprops/action-gh-release dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- .github/workflows/commitlint.yml | 2 +- .github/workflows/release.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5895fee..b15aa7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup Bun uses: oven-sh/setup-bun@v2 @@ -44,7 +44,7 @@ jobs: run: bun run --filter elide package - name: Upload extension artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: extension-vsix path: packages/vscode/*.vsix diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 7865fdd..96e3b9c 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -12,7 +12,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: fetch-depth: 0 - uses: wagoid/commitlint-github-action@v6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c06b895..c0d0ed2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup Bun uses: oven-sh/setup-bun@v2 @@ -56,7 +56,7 @@ jobs: bunx @vscode/vsce publish --no-dependencies --packagePath "packages/vscode/elide-${version}.vsix" - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 with: files: packages/vscode/*.vsix generate_release_notes: true