This is a high-level overview of the Visual Studio Code Extension. The intended audience is someone interested in contributing the extension.
Visual Studio Code provides an API for implementing language-specific editing features in an extension. In VS Code, a language editor extension has two main components:
- a language client which is a normal VS Code extension that listens to different editor events and sends the payloads of these events to a language server
- a language server which is performs language analysis on the code written within VSCode (this runs in a separate process for performance reasons)
The language client and server communicate via the Language Server Protocol. The Language Server Protocol defines a standardized communication protocol between an editor (in our case Visual Studio Code) and a language server that implements features like autocomplete and syntax checking.
By making the language server implementation LSP compliant we have set ourselves up to integrate with other text editors in the future.
Fundamentally, the extension takes in a string of text (YAML specifying a GitHub Actions workflow) and needs to make sense of the text. Conceptually, what this extension does is similar to what other compilers and interpreters (e.g., LLVM) do. The basic steps form a pipeline, with the output of one step serving as the input to the next step. Broadly speaking the steps involved are:
- A lexer takes in a stream of text (in this case a workflow file) and breaks the text into the atomic chunks of the language called tokens
- Next, the tokens are fed into the parser which constructs a tree representation of the program
- Lastly, the tree is evaluated. This step takes the syntax tree as input and produces a literal value.
Crafting Interpreters - which can be read freely online here - goes into much greater depth about compiler/interpreter development.
The VS Code extension integrates with Visual Studio code and uses open-source libraries in order to provide its full functionality. The extension initializes the language server and performs other non-language related tasks like adding functionality to the VS Code sidebar.
The open-source language libraries that the extension uses are:
- The language server library is a wrapper around the language service
- it handles the connection with VS Code via the Language Service Protocol
- makes API calls to GitHub (e.g., requesting Action secrets) for repository and workflow information
- The language service library uses the workflow parser and expression engine (described below) to implement the core functionality of the extension
- it calls into the language server for any data that requires an API call
- the workflow-parser library parses GitHub Actions workflows into an intermediate representation and validates that the workflow file is syntactically valid
- the workflow parser uses a schema to parse the workflow file
- the schema defines the list of valid tokens and their arguments
- the expressions engine is used to parse and evaluate GitHub Actions expressions
- actions/languageservices is the monorepo where all language services code for GitHub Actions can be found
- GitHub Actions Expression Language Documentation