动作/语言服务器
actions-languageserver 主机 actions-languageservice 并且通过 语言服务器协议 (LSP)作为一个独立的语言服务器.
安装
这个 软件包 包含TypeScript类型并编译了ECMAScript模块.
npm install @actions/languageserver
要将语言服务器安装为独立的 CLI :
npm install -g @actions/languageserver
这使得 actions-languageserver 命令可在全球范围使用.
使用量
使用基本使用情况 vscode-languageserver-node
对于服务器,请导入模块. 它检测它是在节点.js环境中运行,还是在网络工人中运行,并初始化适当的连接.
server.ts数字 :
import "@actions/languageserver";
为客户端创建新 LanguageClient 指向服务器模块.
client.ts数字 :
import {LanguageClient, ServerOptions, TransportKind} from "vscode-languageclient/node";
const debugOptions = {execArgv: ["--nolazy", "--inspect=6010"]};
const clientOptions: LanguageClientOptions = {
documentSelector: [{
pattern: "**/.github/workflows/*.{yaml,yml}"
}]
};
const serverModule = context.asAbsolutePath(path.join("dist", "server.js"));
const serverOptions: ServerOptions = {
run: {module: serverModule, transport: TransportKind.ipc},
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
};
const client = new LanguageClient("actions-language", "GitHub Actions Language Server", serverOptions, clientOptions);
从网络工人那里
见 .../浏览器游戏场 例如,将语言服务器托管在网络工人中的执行.
提供高级功能
语言服务器接受初始化选项,可用于配置额外的功能. 如果你通过一个github.com sessionToken,语言服务将使用 github.com 的数据进行额外的验证,并提供额外的自动补全建议.
export interface InitializationOptions {
/**
* GitHub token that will be used to retrieve additional information from github.com
*
* Requires the `repo` and `workflow` scopes
*/
sessionToken?: string;
/**
* List of repositories that the language server should be aware of
*/
repos?: RepositoryContext[];
/**
* Desired log level
*/
logLevel?: LogLevel;
/**
* Experimental features that are opt-in
*/
experimentalFeatures?: ExperimentalFeatures;
}
通过 initializationOptions 页:1 LanguageClient 在建立连接时:
const clientOptions: LanguageClientOptions = {
documentSelector: [{
pattern: "**/.github/workflows/*.{yaml,yml}"
}],
initializationOptions: initializationOptions
};
const client = new LanguageClient("actions-language", "GitHub Actions Language Server", serverOptions, clientOptions);
实验特征
语言服务器通过 experimentalFeatures 初始化选项。 这些特性可能在释放之间改变或去除.
initializationOptions: {
experimentalFeatures: {
// Enable all experimental features
all: true,
// Or enable specific features
missingInputsQuickfix: true,
}
}
可用的实验特性 :
| 特性 | 说明 |
|---|---|
missingInputsQuickfix | 添加缺少的行动所需输入的代码动作 |
blockScalarChompingWarning | 区块分级时警告(| 或者说 >) 使用隐含的剪接,这增加了一条可能无意中出现的后遗症新线 |
allowBackgroundSteps | 启用背景工作流程步骤和相关等/取消步骤 |
单个特征旗帜优先 all。例如, { all: true, missingInputsQuickfix: false } 允许所有实验特性,但 missingInputsQuickfix。 。 。 .
当一个特性毕业生稳定下来时,它的旗帜就会变成不开放的,无论配置值如何,特性都会被启用.
独立的CLI
在全球安装后, 您可以直接运行语言服务器 :
actions-languageserver --stdio
这开始语言服务器使用stdio transport,这是编辑器与语言服务器通信的标准方式.
在尼奥维姆
1. 安装语言服务器
npm install -g @actions/languageserver
2. 设置文件类型检测
将此添加到您的 init.lua 检测 GitHub 动作工作流程文件 :
vim.filetype.add({
pattern = {
[".*/%.github/workflows/.*%.ya?ml"] = "yaml.ghactions",
},
})
此设置文件类型为 yaml.ghactions 用于 YAML 文件 .github/workflows/,允许您在需要时保留单独的YAML LSP配置.
3. 创建LSP配置
截至 Neovim 011+ 您可以在 ~/.config/nvim/lsp/actionsls.lua数字 :
local function get_github_token()
local handle = io.popen("gh auth token 2>/dev/null")
if not handle then return nil end
local token = handle: read("*a"):gsub("%s+", "")
handle:close()
return token ~= "" and token or nil
end
local function parse_github_remote(url)
if not url or url == "" then return nil end
-- SSH format: [email protected]:owner/repo.git
local owner, repo = url:match("git@github%.com:([^/]+)/([^/%.]+)")
if owner and repo then
return owner, repo: gsub("%.git$", "")
end
-- HTTPS format: https://github.com/owner/repo.git
owner, repo = url:match("github%.com/([^/]+)/([^/%.]+)")
if owner and repo then
return owner, repo:gsub("%.git$", "")
end
return nil
end
local function get_repo_info(owner, repo)
local cmd = string.format(
"gh repo view %s/%s --json id,owner --template '{{.id}}\t{{.owner.type}}' 2>/dev/null",
owner,
repo
)
local handle = io.popen(cmd)
if not handle then return nil end
local result = handle: read("*a"):gsub("%s+$", "")
handle:close()
local id, owner_type = result:match("^(%d+)\t(.+)$")
if id then
return {
id = tonumber(id),
organizationOwned = owner_type == "Organization",
}
end
return nil
end
local function get_repos_config()
local handle = io.popen("git rev-parse --show-toplevel 2>/dev/null")
if not handle then return nil end
local git_root = handle: read("*a"):gsub("%s+", "")
handle:close()
if git_root == "" then return nil end
handle = io.popen("git remote get-url origin 2>/dev/null")
if not handle then return nil end
local remote_url = handle:read("*a"):gsub("%s+", "")
handle:close()
local owner, name = parse_github_remote(remote_url)
if not owner or not name then return nil end
local info = get_repo_info(owner, name)
return {
{
id = info and info.id or 0,
owner = owner,
name = name,
organizationOwned = info and info.organizationOwned or false,
workspaceUri = "file://" .. git_root,
},
}
end
return {
cmd = { "actions-languageserver", "--stdio" },
filetypes = { "yaml.ghactions" },
-- `root_dir` ensures that the LSP does not attach to all yaml files
root_dir = function(bufnr, on_dir)
local parent = vim.fs.dirname(vim.api.nvim_buf_get_name(bufnr))
if
vim.endswith(parent, '/.github/workflows')
or vim.endswith(parent, '/.forgejo/workflows')
or vim.endswith(parent, '/.gitea/workflows')
then
on_dir(parent)
end
end,
init_options = {
-- Optional: provide a GitHub token and repo context for added functionality
-- (e.g., repository-specific completions)
sessionToken = get_github_token(),
repos = get_repos_config(),
},
-- allow the lsp to register capabilities on demand
capabilities = {
workspace = {
didChangeWorkspaceFolders = {
dynamicRegistration = true,
},
},
},
-- given a file:// protocol path as built using the workspaceUri above,
-- resolve path to disk path and provide filecontents when lsp requests this
-- action https://github.com/actions/languageservices/blob/main/languageserver/src/request.ts#L2
-- taken from https://github.com/neovim/nvim-lspconfig/blob/75e49cfa588a89ca667d767c0afef3ceac205faa/lsp/gh_actions_ls.lua#L33-L48
handlers = {
["actions/readFile"] = function(_, result)
if type(result.path) ~= "string" then
return nil, nil
end
local file_path = vim.uri_to_fname(result.path)
if vim.fn.filereadable(file_path) == 1 then
local f = assert(io.open(file_path, "r"))
local text = f:read("*a")
f:close()
return text, nil
end
return nil, nil
end,
},
}
4. 启用LSP
添加到您的 init.lua数字 :
vim.lsp.enable('actionsls')
5. 核实它是否有效
打开任意 .github/workflows/*.yml 文件并运行 :
:checkhealth vim.lsp
你应该看看 actionsls 在所附客户列表中.
捐款
见 捐款额 作为一般准则和建议存放处的基础.
如果你想捐款,请跑 更美丽 用于格式化您的代码,并在提交您的PR前酌情添加单位测试.
构建
npm run build
或监视更改
npm run watch
本地运行语言服务器
运行后
npm run build:cli
npm link
actions-languageserver 将在全球范围内提供。 你可以从以下开始:
actions-languageserver --stdio
一旦链接,您也可以观看更改并自动重建:
npm run watch:cli
测试
npm test
或监视更改和运行测试:
npm run test-watch
林特
npm run format-check
许可证
这个项目根据麻省理工学院开源许可证的规定获得许可. 请参考 麻省理工学院 全部条件.