diff --git a/browser-playground/package.json b/browser-playground/package.json index 498b79e..8e3a6bf 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.173", + "version": "0.1.174", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.173", + "@github/actions-languageserver": "^0.1.174", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/expressions/package.json b/expressions/package.json index 2a5a7a9..516946a 100755 --- a/expressions/package.json +++ b/expressions/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-expressions", - "version": "0.1.173", + "version": "0.1.174", "license": "MIT", "type": "module", "source": "./src/index.ts", diff --git a/languageserver/package.json b/languageserver/package.json index db4d5ec..0d2f426 100644 --- a/languageserver/package.json +++ b/languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.173", + "version": "0.1.174", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -40,8 +40,8 @@ "watch": "tsc --build tsconfig.build.json --watch" }, "dependencies": { - "@github/actions-languageservice": "^0.1.173", - "@github/actions-workflow-parser": "^0.1.173", + "@github/actions-languageservice": "^0.1.174", + "@github/actions-workflow-parser": "^0.1.174", "@octokit/rest": "^19.0.7", "@octokit/types": "^9.0.0", "vscode-languageserver": "^8.0.2", diff --git a/languageserver/src/connection.ts b/languageserver/src/connection.ts index 84b69bf..6188335 100644 --- a/languageserver/src/connection.ts +++ b/languageserver/src/connection.ts @@ -1,5 +1,6 @@ import {documentLinks, hover, validate, ValidationConfig} from "@github/actions-languageservice"; import {registerLogger, setLogLevel} from "@github/actions-languageservice/log"; +import {clearCache, clearCacheEntry} from "@github/actions-languageservice/utils/workflow-cache"; import {Octokit} from "@octokit/rest"; import { CompletionItem, @@ -28,7 +29,6 @@ import {fetchActionMetadata} from "./utils/action-metadata"; import {TTLCache} from "./utils/cache"; import {timeOperation} from "./utils/timer"; import {valueProviders} from "./value-providers"; -import {clearCacheEntry, clearCache} from "@github/actions-languageservice/utils/workflow-cache"; export function initConnection(connection: Connection) { const documents: TextDocuments = new TextDocuments(TextDocument); @@ -165,7 +165,8 @@ export function initConnection(connection: Connection) { }); connection.onDocumentLinks(async ({textDocument}: DocumentLinkParams): Promise => { - return documentLinks(documents.get(textDocument.uri)!); + const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)); + return documentLinks(documents.get(textDocument.uri)!, repoContext?.workspaceUri); }); // Make the text document manager listen on the connection diff --git a/languageservice/package.json b/languageservice/package.json index 441c756..aec147b 100644 --- a/languageservice/package.json +++ b/languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.173", + "version": "0.1.174", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", @@ -41,10 +41,11 @@ "watch": "tsc --build tsconfig.build.json --watch" }, "dependencies": { - "@github/actions-expressions": "^0.1.173", - "@github/actions-workflow-parser": "^0.1.173", + "@github/actions-expressions": "^0.1.174", + "@github/actions-workflow-parser": "^0.1.174", "vscode-languageserver-textdocument": "^1.0.7", "vscode-languageserver-types": "^3.17.2", + "vscode-uri": "^3.0.7", "yaml": "^2.1.1" }, "engines": { diff --git a/languageservice/src/document-links.test.ts b/languageservice/src/document-links.test.ts index 65d249c..4a41a36 100644 --- a/languageservice/src/document-links.test.ts +++ b/languageservice/src/document-links.test.ts @@ -14,7 +14,7 @@ jobs: runs-on: [self-hosted] steps: - run: echo "Hello World"`; - const result = await documentLinks(createDocument("test.yaml", input)); + const result = await documentLinks(createDocument("test.yaml", input), undefined); expect(result).toHaveLength(0); }); @@ -23,7 +23,7 @@ jobs: jobs: build: runs-on: [self-hosted]`; - const result = await documentLinks(createDocument("test.yaml", input)); + const result = await documentLinks(createDocument("test.yaml", input), undefined); expect(result).toHaveLength(0); }); @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/checkout@v3 - uses: github/codeql-action/init@v2`; - const result = await documentLinks(createDocument("test.yaml", input)); + const result = await documentLinks(createDocument("test.yaml", input), undefined); expect(result).toEqual([ { range: { @@ -82,4 +82,51 @@ jobs: } ]); }); + + it("links for reusable local workflow", async () => { + const input = `on: push +jobs: + build: + uses: ./.github/workflows/reusable-workflow.yml`; + const result = await documentLinks(createDocument("test.yaml", input), "file:///workspace/"); + expect(result).toEqual([ + { + range: { + end: { + character: 51, + line: 3 + }, + start: { + character: 10, + line: 3 + } + }, + target: "file:///workspace/.github/workflows/reusable-workflow.yml" + } + ]); + }); + + it("links for reusable remote workflow", async () => { + const input = `on: push +jobs: + build: + uses: seismis-rainier/workflows/reusable-workflow.yml@main`; + const result = await documentLinks(createDocument("test.yaml", input), "file:///workspace/"); + expect(result).toEqual([ + { + range: { + end: { + character: 62, + line: 3 + }, + start: { + character: 10, + line: 3 + } + }, + target: "https://www.github.com/seismis-rainier/workflows/tree/main/reusable-workflow.yml", + tooltip: "Open reusable workflow on GitHub" + } + ]); + }); }); diff --git a/languageservice/src/document-links.ts b/languageservice/src/document-links.ts index 4eff46f..6341cae 100644 --- a/languageservice/src/document-links.ts +++ b/languageservice/src/document-links.ts @@ -1,13 +1,15 @@ import {ErrorPolicy} from "@github/actions-workflow-parser/model/convert"; -import {isJob} from "@github/actions-workflow-parser/model/type-guards"; +import {isJob, isReusableWorkflowJob} from "@github/actions-workflow-parser/model/type-guards"; import {File} from "@github/actions-workflow-parser/workflows/file"; +import {parseFileReference} from "@github/actions-workflow-parser/workflows/file-reference"; import {TextDocument} from "vscode-languageserver-textdocument"; import {DocumentLink} from "vscode-languageserver-types"; +import vscodeURI from "vscode-uri/lib/umd"; // work around issues with the vscode-uri package import {actionUrl, parseActionReference} from "./action"; import {mapRange} from "./utils/range"; -import {fetchOrParseWorkflow, fetchOrConvertWorkflowTemplate} from "./utils/workflow-cache"; +import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache"; -export async function documentLinks(document: TextDocument): Promise { +export async function documentLinks(document: TextDocument, workspace: string | undefined): Promise { const file: File = { name: document.uri, content: document.getText() @@ -22,30 +24,61 @@ export async function documentLinks(document: TextDocument): Promise