Compare commits

...

26 Commits

Author SHA1 Message Date
eric sciple 6f63074d43 Merge pull request #204 from actions/release/0.3.18
Release version 0.3.18
2025-09-10 09:00:30 -05:00
GitHub Actions 7504f49ab6 Release extension version 0.3.18 2025-09-10 13:58:01 +00:00
eric sciple 629c9e23da Merge pull request #201 from lawrencegripper/lg/snapshot-keyword
Snapshot support
2025-09-09 12:40:55 -05:00
Lawrence Gripper 9838063a4e Fix up test for new limited context 2025-09-09 11:20:19 +00:00
Lawrence Gripper 01c3723641 fixup completion tests now we have new keywords 2025-09-09 11:09:05 +00:00
Lawrence Gripper 7cf82aa761 review: only add snapshot for factory job. remove context which isn't applicable 2025-09-09 10:31:20 +00:00
eric sciple 028715d071 Merge pull request #193 from actions/dependabot/npm_and_yarn/form-data-4.0.4
Bump form-data from 4.0.2 to 4.0.4
2025-09-04 14:12:17 -05:00
lawrencegripper cec59d9a4d More version bumping 🤦 2025-09-04 15:48:30 +00:00
lawrencegripper f316d205a9 chore: bump versions 2025-09-04 15:45:24 +00:00
Lawrence Gripper dd8308d7f9 Update workflow-parser/src/workflow-v1.0.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-04 16:37:04 +01:00
lawrencegripper 17f511bb6e chore(lint): Run prettier 2025-09-04 15:34:52 +00:00
lawrencegripper fca6e0aec1 Bump the version of relevant packages 2025-09-04 15:27:11 +00:00
lawrencegripper 4faa096820 Add support for new snapshot keyword and object into workflow parser 2025-09-04 15:25:36 +00:00
lawrencegripper ce274ee2ce 🐛 Add types to avoid npm run test failing with Cannot find module
Example error:

> src/templates/template-context.ts:1:28 - error TS2307: Cannot find module '@actions/expressions/funcs/info' or its corresponding type declarations.

related:

- https://github.com/actions/languageservices/issues/146
2025-09-04 15:02:25 +00:00
dependabot[bot] a13e5cd088 Bump form-data from 4.0.2 to 4.0.4
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.2 to 4.0.4.
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.2...v4.0.4)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-22 07:47:53 +00:00
Anthony Zavala 1f3436c3ca Merge pull request #192 from actions/anthonyzavala/bump-webpack-dev-server
Bump `webpack-dev-server: >=5.2.1`
2025-06-16 15:24:40 -07:00
Anthony Zavala 880d3e4109 Bump webpack-dev-server: >=5.2.1 2025-06-16 22:19:01 +00:00
Ben De St Paer-Gotch 09fd00ed88 Merge pull request #191 from actions/nebuk89-patch-1
Update README.md
2025-06-06 11:44:46 +01:00
Ben De St Paer-Gotch 435a10d9b6 Update README.md 2025-06-02 10:40:25 +01:00
Anthony Zavala 311a948ff0 Merge pull request #182 from actions/release/0.3.17
Release version 0.3.17
2025-05-07 14:06:00 -07:00
GitHub Actions b0fd29ab60 Release extension version 0.3.17 2025-05-07 21:04:23 +00:00
Anthony Zavala ccf95ef540 Merge pull request #181 from actions/anthonyzavala/bump-octokit-rest-and-lerna
Bump `@octokit/rest` from 19.0.7 to 21.1.1 & `lerna` from 8.2.1 to 8.2.2
2025-05-07 12:55:40 -07:00
Anthony Zavala e597a0c800 update env secret and vars parameters 2025-05-07 19:43:30 +00:00
Anthony Zavala 80c99e6e38 Bump @octokit/rest from 19.0.7 to 21.1.1 & lerna from 8.2.1 to 8.2.2 2025-05-07 18:11:36 +00:00
Anthony Zavala 655d268694 Merge pull request #180 from actions/alert-autofix-2
Potential fix for code scanning alert no. 2: Workflow does not contain permissions
2025-05-07 10:34:45 -07:00
Anthony Zavala 756ce20db2 Potential fix for code scanning alert no. 2: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-05-07 10:24:31 -07:00
18 changed files with 732 additions and 594 deletions
+2
View File
@@ -1,4 +1,6 @@
name: Build & Test
permissions:
contents: read
on:
push:
+16 -2
View File
@@ -8,6 +8,20 @@ This repository contains multiple npm packages for working with GitHub Actions w
- [languageserver](./languageserver) - Language Server for GitHub Actions, hosting the language service for LSP-compatible editors
- [browser-playground](./browser-playground) - Browser-based playground for the language service
## Contributing
### Note
See [CONTRIBUTING.md](./CONTRIBUTING.md)
Thank you for your interest in this GitHub repo, however, right now we are not taking contributions.
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features were working on and what stage theyre in.
We are taking the following steps to better direct requests related to GitHub Actions, including:
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
3. Security Issues should be handled as per our [security.md](security.md)
We will still provide security updates for this project and fix major breaking changes during this time.
You are welcome to still raise bugs in this repo.
+1 -1
View File
@@ -34,6 +34,6 @@
"typescript": "^4.9.4",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
"webpack-dev-server": ">=5.2.1"
}
}
+5 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/expressions",
"version": "0.3.16",
"version": "0.3.18",
"license": "MIT",
"type": "module",
"source": "./src/index.ts",
@@ -9,10 +9,12 @@
},
"exports": {
".": {
"import": "./dist/index.js"
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./*": {
"import": "./dist/*.js"
"import": "./dist/*.js",
"types": "./dist/*.d.ts"
}
},
"typesVersions": {
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/languageserver",
"version": "0.3.16",
"version": "0.3.18",
"description": "Language server for GitHub Actions",
"license": "MIT",
"type": "module",
@@ -43,9 +43,9 @@
"watch": "tsc --build tsconfig.build.json --watch"
},
"dependencies": {
"@actions/languageservice": "^0.3.16",
"@actions/workflow-parser": "^0.3.16",
"@octokit/rest": "^19.0.7",
"@actions/languageservice": "^0.3.18",
"@actions/workflow-parser": "^0.3.18",
"@octokit/rest": "^21.1.1",
"@octokit/types": "^9.0.0",
"vscode-languageserver": "^8.0.2",
"vscode-languageserver-textdocument": "^1.0.7",
@@ -125,7 +125,7 @@ async function getRemoteSecrets(
environmentSecrets:
(environmentName &&
(await cache.get(`${repo.owner}/${repo.name}/secrets/environment/${environmentName}`, undefined, () =>
fetchEnvironmentSecrets(octokit, repo.id, environmentName)
fetchEnvironmentSecrets(octokit, repo.owner, repo.name, environmentName)
))) ||
[],
orgSecrets: await cache.get(`${repo.owner}/secrets`, undefined, () => fetchOrganizationSecrets(octokit, repo))
@@ -151,14 +151,16 @@ async function fetchSecrets(octokit: Octokit, owner: string, name: string): Prom
async function fetchEnvironmentSecrets(
octokit: Octokit,
repositoryId: number,
owner: string,
name: string,
environmentName: string
): Promise<StringData[]> {
try {
return await octokit.paginate(
octokit.actions.listEnvironmentSecrets,
{
repository_id: repositoryId,
owner,
repo: name,
environment_name: environmentName,
per_page: 100
},
@@ -115,7 +115,7 @@ export async function getRemoteVariables(
environmentVariables:
(environmentName &&
(await cache.get(`${repo.owner}/${repo.name}/vars/environment/${environmentName}`, undefined, () =>
fetchEnvironmentVariables(octokit, repo.id, environmentName)
fetchEnvironmentVariables(octokit, repo.owner, repo.name, environmentName)
))) ||
[],
organizationVariables: await cache.get(`${repo.owner}/vars`, undefined, () =>
@@ -146,14 +146,16 @@ async function fetchVariables(octokit: Octokit, owner: string, name: string): Pr
async function fetchEnvironmentVariables(
octokit: Octokit,
repositoryId: number,
owner: string,
name: string,
environmentName: string
): Promise<Pair[]> {
try {
return await octokit.paginate(
octokit.actions.listEnvironmentVariables,
{
repository_id: repositoryId,
owner: owner,
repo: name,
environment_name: environmentName,
per_page: 100
},
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/languageservice",
"version": "0.3.16",
"version": "0.3.18",
"description": "Language service for GitHub Actions",
"license": "MIT",
"type": "module",
@@ -44,8 +44,8 @@
"watch": "tsc --build tsconfig.build.json --watch"
},
"dependencies": {
"@actions/expressions": "^0.3.16",
"@actions/workflow-parser": "^0.3.16",
"@actions/expressions": "^0.3.18",
"@actions/workflow-parser": "^0.3.18",
"vscode-languageserver-textdocument": "^1.0.7",
"vscode-languageserver-types": "^3.17.2",
"vscode-uri": "^3.0.8",
+6 -6
View File
@@ -70,7 +70,7 @@ jobs:
|`;
const result = await complete(...getPositionFromCursor(input));
expect(result).not.toBeUndefined();
expect(result.length).toEqual(20);
expect(result.length).toEqual(21);
});
it("string definition completion in sequence", async () => {
@@ -243,7 +243,7 @@ jobs:
runs-|`;
const result = await complete(...getPositionFromCursor(input));
expect(result).not.toBeUndefined();
expect(result).toHaveLength(20);
expect(result).toHaveLength(21);
});
it("job key with comment afterwards", async () => {
@@ -254,7 +254,7 @@ jobs:
#`;
const result = await complete(...getPositionFromCursor(input));
expect(result).not.toBeUndefined();
expect(result).toHaveLength(20);
expect(result).toHaveLength(21);
});
it("job key with other values afterwards", async () => {
@@ -266,7 +266,7 @@ jobs:
concurrency: 'group-name'`;
const result = await complete(...getPositionFromCursor(input));
expect(result).not.toBeUndefined();
expect(result).toHaveLength(19);
expect(result).toHaveLength(20);
});
it("step key without space after colon", async () => {
@@ -335,7 +335,7 @@ jobs:
- uses: actions/checkout@v2
`;
const result = await complete(...getPositionFromCursor(input));
expect(result).toHaveLength(16);
expect(result).toHaveLength(17);
});
it("complete from behind a colon will replace it", async () => {
@@ -348,7 +348,7 @@ jobs:
- uses: actions/checkout@v2
`;
const result = await complete(...getPositionFromCursor(input));
expect(result).toHaveLength(16);
expect(result).toHaveLength(17);
const textEdit = result[0].textEdit as TextEdit;
expect(textEdit.range).toEqual({
start: {line: 5, character: 4},
+1 -1
View File
@@ -6,5 +6,5 @@
"languageservice",
"languageserver"
],
"version": "0.3.16"
"version": "0.3.18"
}
+521 -560
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -8,6 +8,6 @@
"./languageserver"
],
"devDependencies": {
"lerna": "^8.2.1"
"lerna": "^8.2.2"
}
}
+6 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/workflow-parser",
"version": "0.3.16",
"version": "0.3.18",
"license": "MIT",
"type": "module",
"source": "./src/index.ts",
@@ -9,10 +9,12 @@
},
"exports": {
".": {
"import": "./dist/index.js"
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./*": {
"import": "./dist/*.js"
"import": "./dist/*.js",
"types": "./dist/*.d.ts"
}
},
"typesVersions": {
@@ -43,7 +45,7 @@
"watch": "tsc --build tsconfig.build.json --watch"
},
"dependencies": {
"@actions/expressions": "^0.3.16",
"@actions/expressions": "^0.3.18",
"cronstrue": "^2.21.0",
"yaml": "^2.0.0-8"
},
+16 -2
View File
@@ -16,7 +16,16 @@ export function convertJob(context: TemplateContext, jobKey: StringToken, token:
context.error(jobKey, error);
}
let concurrency, container, env, environment, name, outputs, runsOn, services, strategy: TemplateToken | undefined;
let concurrency,
container,
env,
environment,
name,
outputs,
runsOn,
services,
strategy,
snapshot: TemplateToken | undefined;
let needs: StringToken[] | undefined = undefined;
let steps: Step[] = [];
let workflowJobRef: StringToken | undefined;
@@ -86,6 +95,10 @@ export function convertJob(context: TemplateContext, jobKey: StringToken, token:
services = item.value;
break;
case "snapshot":
snapshot = item.value;
break;
case "steps":
steps = convertSteps(context, item.value);
break;
@@ -147,7 +160,8 @@ export function convertJob(context: TemplateContext, jobKey: StringToken, token:
container,
services,
outputs,
steps
steps,
snapshot
};
}
}
@@ -41,6 +41,7 @@ export type BaseJob = {
concurrency?: TemplateToken;
strategy?: TemplateToken;
outputs?: MappingToken;
snapshot?: TemplateToken;
};
// `job-factory` in the schema
+39 -1
View File
@@ -1710,7 +1710,8 @@
"concurrency": "job-concurrency",
"outputs": "job-outputs",
"defaults": "job-defaults",
"steps": "steps"
"steps": "steps",
"snapshot": "snapshot"
}
}
},
@@ -1854,6 +1855,43 @@
"loose-value-type": "any"
}
},
"snapshot": {
"description": "Use `snapshot` to define a custom image you want to create or update after your job succeeds by taking a snapshot of your runner.",
"one-of": [
"non-empty-string",
"snapshot-mapping"
]
},
"snapshot-mapping": {
"mapping": {
"properties": {
"image-name": {
"description": "The desired name of the custom image you want to create or update.",
"type": "non-empty-string",
"required": true
},
"if": "snapshot-if",
"version": {
"description": "The desired major version updates upon a new custom image version creation.",
"type": "non-empty-string"
}
}
}
},
"snapshot-if": {
"context": [
"github",
"inputs",
"vars",
"needs",
"strategy",
"matrix"
],
"description": "Use the if conditional to prevent a snapshot from being taken unless a condition is met. Any supported context and expression can be used to create a conditional. Expressions in an `if` conditional do not require the bracketed expression syntax. When you use expressions in an `if` conditional, you may omit the expression syntax because GitHub automatically evaluates the `if` conditional as an expression.",
"string": {
"is-expression": true
}
},
"runs-on": {
"description": "Use `runs-on` to define the type of machine to run the job on.\n* The destination machine can be either a GitHub-hosted runner, larger runner, or a self-hosted runner.\n* You can target runners based on the labels assigned to them, or their group membership, or a combination of these.\n* You can provide `runs-on` as a single string or as an array of strings.\n* If you specify an array of strings, your workflow will execute on any runner that matches all of the specified `runs-on` values.\n* If you would like to run your workflow on multiple machines, use `jobs.<job_id>.strategy`.",
"context": [
@@ -0,0 +1,58 @@
include-source: false # Drop file/line/col from output
---
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo hi
snapshot:
image-name: custom-image
version: 1.*
if: ${{ github.event_name == 'something' }}
---
{
"jobs": [
{
"type": "job",
"id": "build",
"name": "build",
"if": {
"type": 3,
"expr": "success()"
},
"runs-on": "ubuntu-latest",
"steps": [
{
"id": "__run",
"if": {
"type": 3,
"expr": "success()"
},
"run": "echo hi"
}
],
"snapshot": {
"type": 2,
"map": [
{
"Key": "image-name",
"Value": "custom-image"
},
{
"Key": "version",
"Value": "1.*"
},
{
"Key": "if",
"Value": {
"type": 3,
"expr": "github.event_name == 'something'"
}
}
]
}
}
]
}
+42
View File
@@ -0,0 +1,42 @@
include-source: false # Drop file/line/col from output
---
# on: push
# jobs:
# job1:
# runs-on: windows-2019
# snapshot: custom-image
# steps:
# - run: echo 1
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo hi
snapshot: custom-image
---
{
"jobs": [
{
"type": "job",
"id": "build",
"name": "build",
"if": {
"type": 3,
"expr": "success()"
},
"runs-on": "ubuntu-latest",
"steps": [
{
"id": "__run",
"if": {
"type": 3,
"expr": "success()"
},
"run": "echo hi"
}
],
"snapshot": "custom-image"
}
]
}