Skip to content

Commit b87e2fc

Browse files
committed
release: Implement environment isolation via dependency vendoring
This commit introduces a release process that isolates JETLS's dependencies from packages being analyzed by vendoring them with rewritten UUIDs. The vendor-deps.jl script automates the entire release process: 1. Fetches clean Project.toml from the development branch 2. Updates and vendors all non-stdlib, non-JLL dependencies 3. Rewrites UUIDs deterministically using uuid5 4. Updates Project.toml with vendored dependencies and `[sources]` entries This approach ensures JETLS's dependencies never conflict with packages users are analyzing, resolving issues where version conflicts between JETLS and analyzed packages would prevent analysis. --- The following describes the current release process using the above script (at least until JETLS has an official release process). Fow now, we employ the following branch strategy: - Development branch (`master`): Regular development with normal UUIDs - Release branch (`release`): Vendored dependencies with rewritten UUIDs Then the `release` branch is managed as follows: 1. Check out the `release` branch 2. Merge (not rebase) changes from the development branch: `git merge -X theirs master` [^merge-strategy] 3. Vendor dependency packages: `julia vendor-deps.jl --source-branch=master` 4. Commit changes 5. Push to remote `release` [^merge-strategy]: The `-X theirs` option automatically resolves merge conflicts by preferring the `master` branch version. This is necessary because `Project.toml` files are always modified on the `release` branch (with vendored UUIDs), causing conflicts when merging. Since `vendor-deps.jl` fetches and overwrites `Project.toml` from `master` anyway in step 3, these conflicts can be safely resolved by taking the `master` version. Using `git merge` (rather than `git rebase`) keeps the commit history linear for users who update via `git pull`. This means users would manually run `git pull origin release` followed by `Pkg.update()` to install and update JETLS (this is almost the same as the current process, except that we're pulling from `master`). However, I may change this distribution method to make it easier using Pkg apps. For detailed consideration of this vendor approach and release process, refer to: - https://publish.obsidian.md/jetls/work/JETLS/JETLS+release+process - https://publish.obsidian.md/jetls/work/JETLS/LS+environment+isolation
1 parent 1e82106 commit b87e2fc

File tree

4 files changed

+502
-0
lines changed

4 files changed

+502
-0
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vendor/** linguist-generated

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
node_modules
22
out
3+
Project.toml.bak
34
Manifest.toml
45
Manifest-*.toml
56
.envrc
67
**/.JETLSConfig.toml
78
*.vsix
89
docs/build/
10+
11+
# The following line is negated on release branches
12+
/vendor

DEVELOPMENT.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,60 @@ supports dynamic/static registration, and if it does, actively opt-in to use it.
209209
That is, register it via the `client/registerCapability` request in response to
210210
notifications sent from the client, most likely `InitializedNotification`.
211211
The `JETLS.register` utility is especially useful for this purpose.
212+
213+
## Release process
214+
215+
JETLS avoids dependency conflicts with packages being analyzed by rewriting the
216+
UUIDs of its dependencies and vendoring them. This allows JETLS to have its own
217+
isolated copies of dependencies that won't conflict with the packages users are
218+
analyzing.
219+
220+
### Branch strategy
221+
222+
- Development branch: `master`
223+
- Regular development happens here
224+
- Dependencies keep their original UUIDs
225+
- Release branch: `release`
226+
- Distribution branch for users
227+
- Dependencies are vendored with rewritten UUIDs
228+
- Includes copies of dependency packages in the `vendor/` directory
229+
230+
### Release procedure
231+
232+
1. Check out the `release` branch
233+
```bash
234+
git checkout release
235+
```
236+
237+
2. Merge changes from the development branch
238+
```bash
239+
git merge -X theirs master
240+
```
241+
242+
3. Vendor dependency packages
243+
```bash
244+
julia vendor-deps.jl --source-branch=master
245+
```
246+
This script performs the following:
247+
- Fetches the latest `Project.toml` from the `master` branch
248+
- Backs it up as `Project.toml.bak`
249+
- Cleans up `Manifest.toml`
250+
- Updates dependencies with `Pkg.update()`
251+
- Loads JETLS and collects dependency packages from `Base.loaded_modules`
252+
- Copies each package to `vendor/` and rewrites its UUID
253+
- Updates `Project.toml` with vendored UUIDs and `[sources]` entries
254+
255+
4. Commit changes
256+
```bash
257+
git add -A
258+
git commit -m 'release: 2025-11-23'
259+
```
260+
261+
5. Push to remote
262+
```bash
263+
git push origin release
264+
```
265+
266+
Note: `vendor-deps.jl` generates UUIDs using `uuid5(original_uuid, "JETLS-vendor")`.
267+
This is deterministic, so the same vendored UUID is always generated for the same
268+
original UUID, ensuring consistency across multiple vendoring operations.

0 commit comments

Comments
 (0)