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
49 changes: 49 additions & 0 deletions .github/workflows/pull-request-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CI

on:
push:
pull_request:

permissions: {}

jobs:
build-and-test:
name: Lint, Build, Test
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # 6.4.0
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Build
run: npm run build

- name: Test
run: xvfb-run -a npm run test

- name: Package VSIX
run: npx @vscode/vsce package --out turtle-pr-${{ github.run_number }}.vsix

- name: Upload packaged VSIX artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f #v6.0.0
with:
name: turtle-vsix
path: turtle-pr-${{ github.run_number }}.vsix
if-no-files-found: error
97 changes: 97 additions & 0 deletions .github/workflows/release-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Publish VS Code Extension

on:
workflow_dispatch:
inputs:
release_version:
description: 'Release version (semantic versioning, e.g. 1.2.3)'
required: true
type: string

permissions: {}

env:
RELEASE_VERSION: ${{ github.event.inputs.release_version }}

jobs:
publish:
name: Package and Publish to Marketplace
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
issues: write
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
with:
persist-credentials: true

- name: Validate version input
run: |
if [[ ! "${RELEASE_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: '${RELEASE_VERSION}' is not a valid semantic version (expected format: X.Y.Z)"
exit 1
fi
echo "Version '${RELEASE_VERSION}' is valid."

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # 6.4.0
with:
node-version: 22
package-manager-cache: false

- name: Set version in package.json
run: |
npm version --no-git-tag-version -- "${RELEASE_VERSION}"

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Build
run: npm run build

- name: Test
run: xvfb-run -a npm run test

- name: Package VSIX
run: |
npx @vscode/vsce package --out "turtle-${RELEASE_VERSION}.vsix"

- name: Upload VSIX artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f #v6.0.0
with:
name: turtle-vsix
path: turtle-${{ env.RELEASE_VERSION }}.vsix
if-no-files-found: error

# Disabled until https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/work_items/7565 is resolved
# - name: Publish to VS Code Marketplace
# run: npx @vscode/vsce publish --pat "${{ secrets.VS_MARKETPLACE_TOKEN }}"

- name: Commit version changes and push to upstream repository
uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
with:
branch: ${{ env.release_branch_name }}
commit_user_name: github-actions
commit_user_email: github-actions@github.com
commit_author: Author <actions@github.com>
file_pattern: 'package.json, package-lock.json'

- name: Create Github release (full)
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
with:
body: "Release version ${{ env.RELEASE_VERSION }}."
tag_name: v${{ env.RELEASE_VERSION }}
target_commitish: ${{ env.release_branch_name }}
draft: false
prerelease: false
files: |
turtle-${{ env.RELEASE_VERSION }}.vsix
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 changes: 35 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Copyright (c) 2026 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
#
name: GitHub Actions SAST (zizmor)

on:
pull_request:
branches:
- main
push:
branches:
- main

permissions: {}

jobs:
zizmor:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
with:
persist-credentials: false

- name: Run zizmor (PR annotations)
uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0
with:
advanced-security: false
version: v1.22.0
annotations: true
persona: auditor
min-severity: medium
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
.idea
out
dist
node_modules
.vscode-test/
*.vsix
logs
.npm/
File renamed without changes.
File renamed without changes.
22 changes: 22 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/extension/out/**/*.js"
],
"resolveSourceMapLocations": [
"${workspaceFolder}/extension/out/**/*.js",
"!**/node_modules/**"
],
"preLaunchTask": "extension: build"
}
]
}
File renamed without changes.
17 changes: 17 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "extension: build",
"type": "shell",
"command": "npm",
"args": [
"--prefix",
"${workspaceFolder}",
"run",
"build"
],
"problemMatcher": []
}
]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
108 changes: 107 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,107 @@
# esmf-vs-code-plugin
# RDF/Turtle and SAMM Aspect Models

VS Code extension for the ESMF SDK Turtle language server. The extension supports prefix `Go to Definition`, fast syntax feedback while typing, and server-driven heavy Aspect validation for SAMM-style Turtle models.

## Configuration

- `turtle.languageServerSettings.activateEmbeddedLanguageServer` (boolean, default: `true`)
- When enabled, the extension starts the SAMM CLI language server process. When disabled, an external language server must be started manually.
- `turtle.languageServerSettings.automaticUpdateCheck` (boolean, default: `true`)
- Automatically check for updates of the SAMM CLI language server and notify when a new version is available.
- `turtle.languageServerSettings.sammCliPath` (string)
- Path to the SAMM CLI executable or jar file to use as the language server. Can be downloaded / set via the 'Select SAMM CLI Executable' command.
- `turtle.languageServerSettings.serverPort` (number, default: `1846`)
- TCP port used to connect to the Turtle/SAMM language server.
- `turtle.languageServerSettings.traceLevel` (string, default: `off`)
- Controls the verbosity of language client protocol tracing. Options: `off`, `messages`, `verbose`.

Use the command `Turtle: Select SAMM CLI Executable` to choose either:
- one of the latest SAMM CLI GitHub releases, or
- a custom executable path from your local file system.

## Features

- Prefix `Go to Definition` inside Turtle files.
- Two-level validation:
- Fast feedback on type from the regular Turtle parser diagnostics provided by the server (appear in the editor and `Problems`).
- Heavy Aspect validation from the server for model-level issues (results shown in notifications and status bar).
- Manual validation command:
- `Turtle: Validate document now`

## Run The Server And Extension Together

1. In this extension project, install dependencies with `npm install`.
2. Compile the extension with `npm run build`.
3. Press `F5` in VS Code to open an Extension Development Host.
4. Open a Turtle file such as [samples/valid.ttl](samples/valid.ttl) or your Aspect model file.

If the server cannot be downloaded or started, the extension shows an error and leaves a detailed message in the Turtle LSP output channel.

## Validation Behavior

Fast feedback on type:

- Driven by the server's regular Turtle parsing diagnostics.
- Results appear in the editor and `Problems` panel.
- Intended for quick editor feedback while you type.

Heavy Aspect validation:

- Runs on the server, not in the extension.
- Results are displayed in notification messages (for manual validation) or status bar (for save-triggered validation).
- Always uses detailed server validation messaging when the server returns report text.
- Always shows visible progress for long-running validation.
- Runs automatically on save and can also be triggered manually.

When each validation runs:

- On type: fast syntax feedback only.
- On save: heavy Aspect validation for Turtle documents.
- Manual: `Turtle: Validate document now` for the active Turtle document.

## Commands

- `Turtle: Validate document now`
- Sends a server request for the active Turtle document.
- `Turtle: Select SAMM CLI Executable`
- Opens a quick pick with the latest 10 GitHub releases and a custom-path option.
- `Turtle: Restart and reconnect to Language Server`
- Restarts the language server and reconnects the client.

## UX During Long-Running Validation

- Manual validation shows a progress notification while the request is running.
- Save-triggered validation always uses a short status-bar progress indicator instead of repeated popups.
- After completion, the user gets a summary message with validation results.
- Automatic save validation keeps progress and completion feedback in the status bar.

## Verify Go To Definition

Use [samples/valid.ttl](samples/valid.ttl):

1. Open `samples/valid.ttl`.
2. Place the cursor on `foaf:Person`, `foaf:name`, or another prefixed name.
3. Run `Go to Definition`.
4. Confirm that VS Code jumps to the matching `@prefix` declaration.

Expected behavior:

- `foaf:*` resolves to `@prefix foaf: ...`.
- `ex:*` resolves to `@prefix ex: ...`.

## Verify Aspect Validation

Use [samples/org.eclipse.esmf.test/1.0.0/Aspect.ttl](samples/org.eclipse.esmf.test/1.0.0/Aspect.ttl) or [samples/invalid.ttl](samples/invalid.ttl).

Manual check:

1. Open an Aspect model file.
2. Run `Turtle: Validate document now`.
3. Wait for the progress indicator to finish.
4. Confirm that validation results appear in a notification message.

On-save check:

1. Save the model file.
2. Confirm that the status bar shows validation progress.
3. Confirm that a summary message appears in the status bar after completion.
File renamed without changes.
6 changes: 0 additions & 6 deletions extension/.gitignore

This file was deleted.

8 changes: 0 additions & 8 deletions extension/.vscode/extensions.json

This file was deleted.

21 changes: 0 additions & 21 deletions extension/.vscode/launch.json

This file was deleted.

Loading
Loading