Compare commits

..

3 Commits

Author SHA1 Message Date
Francesco Renzi de148476d4 Add actions-languageserver executable 2025-12-09 10:55:07 +00:00
github-actions[bot] 742b36d6b7 Release extension version 0.3.25 (#248)
Co-authored-by: GitHub Actions <github-actions@github.com>
2025-12-08 13:51:17 -06:00
eric sciple 8507419ebf Add missing activity types for pull_request and pull_request_target (#242)
Fixes #51

Added the following activity types to pull_request and pull_request_target:
- milestoned
- demilestoned
- enqueued
- dequeued

These types were missing from workflow-v1.0.json but are valid workflow
triggers per GitHub docs.

Also added schema-sync.test.ts to ensure activity types in workflow-v1.0.json
stay in sync with webhooks.json. The test:
- Checks both directions (webhooks→schema and schema→webhooks)
- Has WEBHOOK_ONLY for types not valid as workflow triggers:
  - check_suite: requested, rerequested
  - registry_package: default
- Has SCHEMA_ONLY for types valid in workflows but not in webhooks:
  - registry_package: updated
- Has NAME_MAPPINGS for naming differences:
  - project_column: edited (webhook) ↔ updated (schema)
- Provides actionable error messages when mismatches are found
2025-12-08 13:44:56 -06:00
11 changed files with 784 additions and 60 deletions
+47
View File
@@ -148,3 +148,50 @@ Only `name`, `description`, and `childParamsGroups` are kept — these are used
To compare all fields vs stripped, run `npm run update-webhooks -- --all` and diff the `.all.json` files against the regular ones.
See `EVENT_ACTION_FIELDS` and `BODY_PARAM_FIELDS` in `script/webhooks/index.ts` to modify what gets stripped.
## Schema Synchronization
The `workflow-v1.0.json` schema defines which activity types are valid for each workflow trigger event. A test in `workflow-parser/src/schema-sync.test.ts` verifies these stay in sync with `webhooks.json`.
### When the Test Fails
If the schema-sync test fails, you'll see an error like:
```
Event "pull_request" is missing activity type "new_activity" in workflow-v1.0.json
```
**To resolve:**
1. Check [Events that trigger workflows](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows) to verify the activity type is a valid workflow trigger:
- Find the event section (e.g., "pull_request")
- Look at the "Activity types" table — it lists which types can be used in `on.<event>.types`
- If the type is listed there, it's a valid workflow trigger
- If the type only appears in webhook docs but NOT in the workflow trigger docs, it's webhook-only
2. If it IS a valid workflow trigger:
- Edit `workflow-parser/src/workflow-v1.0.json`
- Find the `<event>-activity-type` definition (e.g., `pull-request-activity-type`)
- Add the new activity type to `allowed-values`
- Update the `description` in `<event>-activity` to list all types
- Run `npm test` to regenerate the minified JSON
3. If it is NOT a valid workflow trigger (webhook-only):
- Edit `workflow-parser/src/schema-sync.test.ts`
- Add the type to `WEBHOOK_ONLY` for that event
### Known Discrepancies
The test tracks several types of known discrepancies:
| Category | Purpose | Example |
|----------|---------|---------|
| `WEBHOOK_ONLY` | Types in webhooks that aren't valid workflow triggers | `check_suite.requested` |
| `SCHEMA_ONLY` | Types valid for workflows but missing from webhooks | `registry_package.updated` |
| `NAME_MAPPINGS` | Different names for the same concept | `project_column`: webhook uses `edited`, schema uses `updated` |
### Bidirectional Checking
The test checks both directions:
- **webhooks → schema**: Ensures all webhook activity types are in the schema (or listed in `WEBHOOK_ONLY`)
- **schema → webhooks**: Ensures the schema doesn't have types that don't exist in webhooks (or listed in `SCHEMA_ONLY` or `NAME_MAPPINGS`)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/expressions",
"version": "0.3.24",
"version": "0.3.25",
"license": "MIT",
"type": "module",
"source": "./src/index.ts",
@@ -0,0 +1,2 @@
#!/usr/bin/env node
import "../dist/cli.bundle.cjs";
+8 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/languageserver",
"version": "0.3.24",
"version": "0.4.0",
"description": "Language server for GitHub Actions",
"license": "MIT",
"type": "module",
@@ -32,6 +32,7 @@
},
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:cli": "esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/cli.bundle.cjs",
"clean": "rimraf dist",
"format": "prettier --write '**/*.ts'",
"format-check": "prettier --check '**/*.ts'",
@@ -42,9 +43,12 @@
"test-watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch",
"watch": "tsc --build tsconfig.build.json --watch"
},
"bin": {
"actions-languageserver": "./bin/actions-languageserver"
},
"dependencies": {
"@actions/languageservice": "^0.3.24",
"@actions/workflow-parser": "^0.3.24",
"@actions/languageservice": "^0.3.25",
"@actions/workflow-parser": "^0.3.25",
"@octokit/rest": "^21.1.1",
"@octokit/types": "^9.0.0",
"vscode-languageserver": "^8.0.2",
@@ -61,6 +65,7 @@
"@types/jest": "^29.0.3",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"esbuild": "^0.27.1",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/languageservice",
"version": "0.3.24",
"version": "0.3.25",
"description": "Language service for GitHub Actions",
"license": "MIT",
"type": "module",
@@ -47,8 +47,8 @@
"watch": "tsc --build tsconfig.build.json --watch"
},
"dependencies": {
"@actions/expressions": "^0.3.24",
"@actions/workflow-parser": "^0.3.24",
"@actions/expressions": "^0.3.25",
"@actions/workflow-parser": "^0.3.25",
"vscode-languageserver-textdocument": "^1.0.7",
"vscode-languageserver-types": "^3.17.2",
"vscode-uri": "^3.0.8",
+1 -1
View File
@@ -6,5 +6,5 @@
"languageservice",
"languageserver"
],
"version": "0.3.24"
"version": "0.3.25"
}
+509 -46
View File
@@ -135,7 +135,7 @@
},
"expressions": {
"name": "@actions/expressions",
"version": "0.3.24",
"version": "0.3.25",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.0.3",
@@ -395,21 +395,25 @@
},
"languageserver": {
"name": "@actions/languageserver",
"version": "0.3.24",
"version": "0.4.0",
"license": "MIT",
"dependencies": {
"@actions/languageservice": "^0.3.24",
"@actions/workflow-parser": "^0.3.24",
"@actions/languageservice": "^0.3.25",
"@actions/workflow-parser": "^0.3.25",
"@octokit/rest": "^21.1.1",
"@octokit/types": "^9.0.0",
"vscode-languageserver": "^8.0.2",
"vscode-languageserver-textdocument": "^1.0.7",
"yaml": "^2.1.3"
},
"bin": {
"actions-languageserver": "bin/actions-languageserver"
},
"devDependencies": {
"@types/jest": "^29.0.3",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"esbuild": "^0.27.1",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
@@ -475,6 +479,7 @@
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.5.tgz",
"integrity": "sha512-vvmsN0r7rguA+FySiCsbaTTobSftpIDIpPW81trAmsv9TGxg3YCujAxRYp/Uy8xmDgYCzzgulG62H7KYUFmeIg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/auth-token": "^5.0.0",
"@octokit/graphql": "^8.2.2",
@@ -921,11 +926,11 @@
},
"languageservice": {
"name": "@actions/languageservice",
"version": "0.3.24",
"version": "0.3.25",
"license": "MIT",
"dependencies": {
"@actions/expressions": "^0.3.24",
"@actions/workflow-parser": "^0.3.24",
"@actions/expressions": "^0.3.25",
"@actions/workflow-parser": "^0.3.25",
"vscode-languageserver-textdocument": "^1.0.7",
"vscode-languageserver-types": "^3.17.2",
"vscode-uri": "^3.0.8",
@@ -1243,6 +1248,7 @@
"version": "7.20.2",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
@@ -1822,6 +1828,448 @@
"tslib": "^2.4.0"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz",
"integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz",
"integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz",
"integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz",
"integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz",
"integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz",
"integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz",
"integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz",
"integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz",
"integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz",
"integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz",
"integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz",
"integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz",
"integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz",
"integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz",
"integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz",
"integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz",
"integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz",
"integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz",
"integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz",
"integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz",
"integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz",
"integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz",
"integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz",
"integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz",
"integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz",
"integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz",
@@ -2726,22 +3174,6 @@
"node": ">=10"
}
},
"node_modules/@lerna/create/node_modules/typescript": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/@lerna/create/node_modules/write-file-atomic": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
@@ -3655,6 +4087,7 @@
"integrity": "sha512-dKYCMuPO1bmrpuogcjQ8z7ICCH3FP6WmxpwC03yjzGfZhj9fTJg6+bS1+UAplekbN2C+M61UNllGOOoAfGCrdQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^7.1.0",
@@ -4180,6 +4613,7 @@
"integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.56.0",
"@typescript-eslint/types": "5.56.0",
@@ -4414,6 +4848,7 @@
"version": "8.8.1",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -4838,6 +5273,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001400",
"electron-to-chromium": "^1.4.251",
@@ -5858,27 +6294,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/encoding": {
"version": "0.1.13",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"iconv-lite": "^0.6.2"
}
},
"node_modules/encoding/node_modules/iconv-lite": {
"version": "0.6.3",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -5987,6 +6402,48 @@
"node": ">= 0.4"
}
},
"node_modules/esbuild": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz",
"integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.1",
"@esbuild/android-arm": "0.27.1",
"@esbuild/android-arm64": "0.27.1",
"@esbuild/android-x64": "0.27.1",
"@esbuild/darwin-arm64": "0.27.1",
"@esbuild/darwin-x64": "0.27.1",
"@esbuild/freebsd-arm64": "0.27.1",
"@esbuild/freebsd-x64": "0.27.1",
"@esbuild/linux-arm": "0.27.1",
"@esbuild/linux-arm64": "0.27.1",
"@esbuild/linux-ia32": "0.27.1",
"@esbuild/linux-loong64": "0.27.1",
"@esbuild/linux-mips64el": "0.27.1",
"@esbuild/linux-ppc64": "0.27.1",
"@esbuild/linux-riscv64": "0.27.1",
"@esbuild/linux-s390x": "0.27.1",
"@esbuild/linux-x64": "0.27.1",
"@esbuild/netbsd-arm64": "0.27.1",
"@esbuild/netbsd-x64": "0.27.1",
"@esbuild/openbsd-arm64": "0.27.1",
"@esbuild/openbsd-x64": "0.27.1",
"@esbuild/openharmony-arm64": "0.27.1",
"@esbuild/sunos-x64": "0.27.1",
"@esbuild/win32-arm64": "0.27.1",
"@esbuild/win32-ia32": "0.27.1",
"@esbuild/win32-x64": "0.27.1"
}
},
"node_modules/escalade": {
"version": "3.1.1",
"dev": true,
@@ -6007,6 +6464,7 @@
"version": "7.32.0",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "7.12.11",
"@eslint/eslintrc": "^0.4.3",
@@ -7875,6 +8333,7 @@
"version": "29.3.1",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "^29.3.1",
"@jest/types": "^29.3.1",
@@ -8948,6 +9407,7 @@
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -9769,6 +10229,7 @@
"version": "2.6.7",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -10122,6 +10583,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@napi-rs/wasm-runtime": "0.2.4",
"@yarnpkg/lockfile": "^1.1.0",
@@ -10759,6 +11221,7 @@
"version": "2.8.3",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"prettier": "bin-prettier.js"
},
@@ -12834,10 +13297,10 @@
},
"workflow-parser": {
"name": "@actions/workflow-parser",
"version": "0.3.24",
"version": "0.3.25",
"license": "MIT",
"dependencies": {
"@actions/expressions": "^0.3.24",
"@actions/expressions": "^0.3.25",
"cronstrue": "^2.21.0",
"yaml": "^2.0.0-8"
},
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@actions/workflow-parser",
"version": "0.3.24",
"version": "0.3.25",
"license": "MIT",
"type": "module",
"source": "./src/index.ts",
@@ -48,7 +48,7 @@
"watch": "tsc --build tsconfig.build.json --watch"
},
"dependencies": {
"@actions/expressions": "^0.3.24",
"@actions/expressions": "^0.3.25",
"cronstrue": "^2.21.0",
"yaml": "^2.0.0-8"
},
+183
View File
@@ -0,0 +1,183 @@
import * as fs from "fs";
/**
* This test ensures that activity types in workflow-v1.0.json stay in sync with
* the webhooks.json file from the languageservice package.
*
* When this test fails, it means new activity types were added to webhooks.json
* that need to be handled. See docs/json-data-files.md for detailed instructions.
*
* Quick reference for fixing failures:
* 1. Check https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows
* Find the event and look at its "Activity types" table to see if the type is a valid workflow trigger.
* 2. If the activity type IS a valid workflow trigger:
* → Add it to the corresponding *-activity-type definition in workflow-v1.0.json
* 3. If the activity type is webhook-only (not in workflow docs):
* → Add it to the WEBHOOK_ONLY list below
* 4. If there's a naming difference between webhook and schema:
* → Add it to the NAME_MAPPINGS list below
* 5. If the schema has a type not in webhooks.json:
* → Add it to the SCHEMA_ONLY list below
*/
describe("schema-sync", () => {
// Activity types that exist in webhooks.json but are intentionally NOT
// supported as workflow triggers. These will be ignored when checking
// webhooks → schema direction.
const WEBHOOK_ONLY: Record<string, string[]> = {
// check_suite: requested and rerequested are webhook-only, not valid workflow triggers
// See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#check_suite
check_suite: ["requested", "rerequested"],
// registry_package: "default" is a webhook concept, not a workflow trigger type
registry_package: ["default"]
};
// Activity types that exist in workflow schema but are intentionally NOT
// in webhooks.json (schema-only types). These will be ignored when checking
// schema → webhooks direction.
const SCHEMA_ONLY: Record<string, string[]> = {
// registry_package: "updated" is a valid workflow trigger per GitHub docs
// but doesn't exist in webhooks.json (webhooks only has "published" and "default")
// See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#registry_package
registry_package: ["updated"]
};
// Known naming differences between webhooks.json and workflow-v1.0.json.
// Key: event name, Value: { webhook: "webhookName", schema: "schemaName" }
// These are treated as equivalent when comparing in both directions.
const NAME_MAPPINGS: Record<string, Array<{webhook: string; schema: string}>> = {
// project_column: webhooks.json uses "edited" but workflow triggers use "updated"
// This is a known naming difference - they represent the same action
project_column: [{webhook: "edited", schema: "updated"}]
};
it("activity types in workflow-v1.0.json match webhooks.json", () => {
// Load webhooks.json (relative path from the test runner CWD which is the package root)
const webhooksPath = "../languageservice/src/context-providers/events/webhooks.json";
const webhooks = JSON.parse(fs.readFileSync(webhooksPath, "utf-8")) as Record<string, Record<string, unknown>>;
// Load workflow-v1.0.json
const schemaPath = "./src/workflow-v1.0.json";
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf-8")) as {
definitions: Record<string, {"allowed-values"?: string[]; description?: string}>;
};
const mismatches: string[] = [];
// Build mapping helpers for each event
const getWebhookToSchemaMapping = (eventName: string): Map<string, string> => {
const map = new Map<string, string>();
for (const mapping of NAME_MAPPINGS[eventName] || []) {
map.set(mapping.webhook, mapping.schema);
}
return map;
};
const getSchemaToWebhookMapping = (eventName: string): Map<string, string> => {
const map = new Map<string, string>();
for (const mapping of NAME_MAPPINGS[eventName] || []) {
map.set(mapping.schema, mapping.webhook);
}
return map;
};
// Check both directions for each event
for (const [eventName, eventData] of Object.entries(webhooks)) {
const webhookTypes = Object.keys(eventData);
if (webhookTypes.length === 0) continue;
const schemaTypeName = `${eventName.replace(/_/g, "-")}-activity-type`;
const schemaDef = schema.definitions[schemaTypeName];
// If there's no activity type definition in the schema, this event
// doesn't support activity types in workflows (e.g., push, pull)
if (!schemaDef || !schemaDef["allowed-values"]) continue;
const schemaTypes = new Set(schemaDef["allowed-values"]);
const webhookOnly = new Set(WEBHOOK_ONLY[eventName] || []);
const schemaOnly = new Set(SCHEMA_ONLY[eventName] || []);
const webhookToSchema = getWebhookToSchemaMapping(eventName);
const schemaToWebhook = getSchemaToWebhookMapping(eventName);
// Direction 1: webhooks → schema
// Check that each webhook type exists in schema (or has a mapping, or is webhook-only)
for (const webhookType of webhookTypes) {
if (webhookOnly.has(webhookType)) continue;
const mappedSchemaType = webhookToSchema.get(webhookType);
if (mappedSchemaType) {
// Has a mapping - check the mapped name exists in schema
if (!schemaTypes.has(mappedSchemaType)) {
mismatches.push(
`Event "${eventName}": webhook type "${webhookType}" maps to "${mappedSchemaType}" but "${mappedSchemaType}" not found in schema`
);
}
} else {
// No mapping - check the type exists directly
if (!schemaTypes.has(webhookType)) {
mismatches.push(
`Event "${eventName}": missing activity type "${webhookType}" in workflow-v1.0.json (exists in webhooks.json)`
);
}
}
}
// Direction 2: schema → webhooks
// Check that each schema type exists in webhooks (or has a mapping, or is schema-only)
const webhookTypesSet = new Set(webhookTypes);
for (const schemaType of schemaTypes) {
if (schemaOnly.has(schemaType)) continue;
const mappedWebhookType = schemaToWebhook.get(schemaType);
if (mappedWebhookType) {
// Has a mapping - check the mapped name exists in webhooks
if (!webhookTypesSet.has(mappedWebhookType)) {
mismatches.push(
`Event "${eventName}": schema type "${schemaType}" maps to "${mappedWebhookType}" but "${mappedWebhookType}" not found in webhooks.json`
);
}
} else {
// No mapping - check the type exists directly
if (!webhookTypesSet.has(schemaType)) {
mismatches.push(
`Event "${eventName}": extra activity type "${schemaType}" in workflow-v1.0.json (not in webhooks.json)`
);
}
}
}
// Check that the description mentions all allowed values
const activityDefName = `${eventName.replace(/_/g, "-")}-activity`;
const activityDef = schema.definitions[activityDefName];
if (activityDef?.description) {
for (const schemaType of schemaTypes) {
if (!activityDef.description.includes(`\`${schemaType}\``)) {
mismatches.push(
`Event "${eventName}": description in "${activityDefName}" is missing activity type \`${schemaType}\``
);
}
}
}
}
if (mismatches.length > 0) {
const errorMessage = [
"Activity type mismatches found between webhooks.json and workflow-v1.0.json:",
"",
...mismatches,
"",
"To fix these mismatches:",
"1. Check GitHub docs: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows",
"2. Verify the activity type is valid for workflow triggers",
"3. Update the *-activity-type definition in workflow-parser/src/workflow-v1.0.json",
"4. Update the description to list all supported activity types",
"5. If there's a naming difference, add it to NAME_MAPPINGS in schema-sync.test.ts",
"6. If the type is webhook-only, add it to WEBHOOK_ONLY",
"7. If the type is schema-only, add it to SCHEMA_ONLY"
].join("\n");
throw new Error(errorMessage);
}
});
});
+12 -4
View File
@@ -856,7 +856,7 @@
}
},
"pull-request-activity": {
"description": "The types of pull request activity that trigger the workflow. Supported activity types: `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `closed`, `reopened`, `synchronize`, `converted_to_draft`, `ready_for_review`, `locked`, `unlocked`, `review_requested`, `review_request_removed`, `auto_merge_enabled`, `auto_merge_disabled`.",
"description": "The types of pull request activity that trigger the workflow. Supported activity types: `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `closed`, `reopened`, `synchronize`, `converted_to_draft`, `locked`, `unlocked`, `enqueued`, `dequeued`, `milestoned`, `demilestoned`, `ready_for_review`, `review_requested`, `review_request_removed`, `auto_merge_enabled`, `auto_merge_disabled`.",
"one-of": [
"pull-request-activity-type",
"pull-request-activity-types"
@@ -879,9 +879,13 @@
"reopened",
"synchronize",
"converted_to_draft",
"ready_for_review",
"locked",
"unlocked",
"enqueued",
"dequeued",
"milestoned",
"demilestoned",
"ready_for_review",
"review_requested",
"review_request_removed",
"auto_merge_enabled",
@@ -1004,7 +1008,7 @@
}
},
"pull-request-target-activity": {
"description": "The types of pull request activity that trigger the workflow. Supported activity types: `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `closed`, `reopened`, `synchronize`, `converted_to_draft`, `ready_for_review`, `locked`, `unlocked`, `review_requested`, `review_request_removed`, `auto_merge_enabled`, `auto_merge_disabled`.",
"description": "The types of pull request activity that trigger the workflow. Supported activity types: `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `closed`, `reopened`, `synchronize`, `converted_to_draft`, `locked`, `unlocked`, `enqueued`, `dequeued`, `milestoned`, `demilestoned`, `ready_for_review`, `review_requested`, `review_request_removed`, `auto_merge_enabled`, `auto_merge_disabled`.",
"one-of": [
"pull-request-target-activity-type",
"pull-request-target-activity-types"
@@ -1027,9 +1031,13 @@
"reopened",
"synchronize",
"converted_to_draft",
"ready_for_review",
"locked",
"unlocked",
"enqueued",
"dequeued",
"milestoned",
"demilestoned",
"ready_for_review",
"review_requested",
"review_request_removed",
"auto_merge_enabled",
+16
View File
@@ -120,6 +120,8 @@ on:
- unassigned
- labeled
- unlabeled
- milestoned
- demilestoned
- opened
- edited
- closed
@@ -129,6 +131,8 @@ on:
- ready_for_review
- locked
- unlocked
- enqueued
- dequeued
- review_requested
- review_request_removed
- auto_merge_enabled
@@ -160,6 +164,8 @@ on:
- unassigned
- labeled
- unlabeled
- milestoned
- demilestoned
- opened
- edited
- closed
@@ -169,6 +175,8 @@ on:
- ready_for_review
- locked
- unlocked
- enqueued
- dequeued
- review_requested
- review_request_removed
- auto_merge_enabled
@@ -386,6 +394,8 @@ jobs:
"unassigned",
"labeled",
"unlabeled",
"milestoned",
"demilestoned",
"opened",
"edited",
"closed",
@@ -395,6 +405,8 @@ jobs:
"ready_for_review",
"locked",
"unlocked",
"enqueued",
"dequeued",
"review_requested",
"review_request_removed",
"auto_merge_enabled",
@@ -441,6 +453,8 @@ jobs:
"unassigned",
"labeled",
"unlabeled",
"milestoned",
"demilestoned",
"opened",
"edited",
"closed",
@@ -450,6 +464,8 @@ jobs:
"ready_for_review",
"locked",
"unlocked",
"enqueued",
"dequeued",
"review_requested",
"review_request_removed",
"auto_merge_enabled",