diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3ac34bbb..e28a50dc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,6 +8,10 @@ on: workflow_call: pull_request: +permissions: + checks: write + contents: read + jobs: ci: name: CI @@ -37,22 +41,22 @@ jobs: run: npm run lint - name: Unit tests (common) - run: npx zenfs-test -pfw --common + run: npx zenfs-test -pfw --common --ci "Unit tests (common)" - name: Unit tests (InMemory) - run: npx zenfs-test -pfw tests/setup/memory.ts + run: npx zenfs-test -pfw tests/setup/memory.ts --ci "Unit tests (InMemory)" - name: Unit tests (contexts) - run: npx zenfs-test -pfw tests/setup/context.ts + run: npx zenfs-test -pfw tests/setup/context.ts --ci "Unit tests (contexts)" - name: Unit tests (Index) - run: npx zenfs-test -pfw tests/setup/index.ts + run: npx zenfs-test -pfw tests/setup/index.ts --ci "Unit tests (Index)" - name: Unit tests (Port) - run: npx zenfs-test -pfw tests/setup/port.ts + run: npx zenfs-test -pfw tests/setup/port.ts --ci "Unit tests (Port)" - name: Unit tests (Overlay+Fetch) - run: tests/fetch/run.sh -w + run: tests/fetch/run.sh -w --ci "Unit tests (Overlay+Fetch)" - name: Report coverage run: npx zenfs-test --report diff --git a/package-lock.json b/package-lock.json index d15c9f21..cffddafc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ }, "devDependencies": { "@eslint/js": "^9.8.0", + "@octokit/action": "^7.0.0", "@types/eslint__js": "^8.42.3", "c8": "^10.1.2", "eslint": "^9.15.0", @@ -441,6 +442,175 @@ "node": ">= 8" } }, + "node_modules/@octokit/action": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/action/-/action-7.0.0.tgz", + "integrity": "sha512-YVstbUS7vbW0frVGAGtYpSqjbgCwQW1OO0WS+sc/fx0RnW0PP4kPgMCmkgkLAm51WyYTWOOQRA1HuaGTSFgyfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-action": "^5.1.1", + "@octokit/core": "^6.1.2", + "@octokit/plugin-paginate-rest": "^11.1.1", + "@octokit/plugin-rest-endpoint-methods": "^13.0.1", + "@octokit/types": "^13.0.0", + "undici": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-action": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-5.1.1.tgz", + "integrity": "sha512-JE2gbAZcwwVuww88YY7oB97P6eVAPgKZk2US9Uyz+ZUw5ubeRkZqog7G/gUEAjayIFt8s0UX3qNntP1agVcB0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^5.0.0", + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-token": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz", + "integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.3.tgz", + "integrity": "sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^5.0.0", + "@octokit/graphql": "^8.1.2", + "@octokit/request": "^9.1.4", + "@octokit/request-error": "^6.1.6", + "@octokit/types": "^13.6.2", + "before-after-hook": "^3.0.2", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.2.tgz", + "integrity": "sha512-XybpFv9Ms4hX5OCHMZqyODYqGTZ3H6K6Vva+M9LR7ib/xr1y1ZnlChYv9H680y77Vd/i/k+thXApeRASBQkzhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.6.2", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.2.tgz", + "integrity": "sha512-bdlj/CJVjpaz06NBpfHhp4kGJaRZfz7AzC+6EwUImRtrwIw8dIgJ63Xg0OzV9pRn3rIzrt5c2sa++BL0JJ8GLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^9.1.4", + "@octokit/types": "^13.6.2", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz", + "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.0.tgz", + "integrity": "sha512-ttpGck5AYWkwMkMazNCZMqxKqIq1fJBNxBfsFwwfyYKTf914jKkLF0POMS3YkPBwp5g1c2Y4L79gDz01GhSr1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.0.tgz", + "integrity": "sha512-LUm44shlmkp/6VC+qQgHl3W5vzUP99ZM54zH6BuqkJK4DqfFLhegANd+fM4YRLapTvPm4049iG7F3haANKMYvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/request": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.0.tgz", + "integrity": "sha512-kXLfcxhC4ozCnAXy2ff+cSxpcF0A1UqxjvYMqNuPIeOAzJbVWQ+dy5G2fTylofB/gTbObT8O6JORab+5XtA1Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.6.2", + "fast-content-type-parse": "^2.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.6.tgz", + "integrity": "sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.6.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.7.0.tgz", + "integrity": "sha512-BXfRP+3P3IN6fd4uF3SniaHKOO4UXWBfkdR3vA8mIvaoO/wLjGN5qivUtW0QRitBHHMcfC41SLhNVYIZZE+wkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^23.0.1" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -886,6 +1056,13 @@ } ] }, + "node_modules/before-after-hook": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", + "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -1432,6 +1609,23 @@ "node": ">=0.8.x" } }, + "node_modules/fast-content-type-parse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz", + "integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3106,12 +3300,29 @@ "dev": true, "license": "MIT" }, + "node_modules/undici": { + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "license": "MIT" }, + "node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", + "dev": true, + "license": "ISC" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3618,6 +3829,127 @@ "fastq": "^1.6.0" } }, + "@octokit/action": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/action/-/action-7.0.0.tgz", + "integrity": "sha512-YVstbUS7vbW0frVGAGtYpSqjbgCwQW1OO0WS+sc/fx0RnW0PP4kPgMCmkgkLAm51WyYTWOOQRA1HuaGTSFgyfQ==", + "dev": true, + "requires": { + "@octokit/auth-action": "^5.1.1", + "@octokit/core": "^6.1.2", + "@octokit/plugin-paginate-rest": "^11.1.1", + "@octokit/plugin-rest-endpoint-methods": "^13.0.1", + "@octokit/types": "^13.0.0", + "undici": "^6.0.0" + } + }, + "@octokit/auth-action": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-5.1.1.tgz", + "integrity": "sha512-JE2gbAZcwwVuww88YY7oB97P6eVAPgKZk2US9Uyz+ZUw5ubeRkZqog7G/gUEAjayIFt8s0UX3qNntP1agVcB0g==", + "dev": true, + "requires": { + "@octokit/auth-token": "^5.0.0", + "@octokit/types": "^13.0.0" + } + }, + "@octokit/auth-token": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz", + "integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==", + "dev": true + }, + "@octokit/core": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.3.tgz", + "integrity": "sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==", + "dev": true, + "requires": { + "@octokit/auth-token": "^5.0.0", + "@octokit/graphql": "^8.1.2", + "@octokit/request": "^9.1.4", + "@octokit/request-error": "^6.1.6", + "@octokit/types": "^13.6.2", + "before-after-hook": "^3.0.2", + "universal-user-agent": "^7.0.0" + } + }, + "@octokit/endpoint": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.2.tgz", + "integrity": "sha512-XybpFv9Ms4hX5OCHMZqyODYqGTZ3H6K6Vva+M9LR7ib/xr1y1ZnlChYv9H680y77Vd/i/k+thXApeRASBQkzhA==", + "dev": true, + "requires": { + "@octokit/types": "^13.6.2", + "universal-user-agent": "^7.0.2" + } + }, + "@octokit/graphql": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.2.tgz", + "integrity": "sha512-bdlj/CJVjpaz06NBpfHhp4kGJaRZfz7AzC+6EwUImRtrwIw8dIgJ63Xg0OzV9pRn3rIzrt5c2sa++BL0JJ8GLw==", + "dev": true, + "requires": { + "@octokit/request": "^9.1.4", + "@octokit/types": "^13.6.2", + "universal-user-agent": "^7.0.0" + } + }, + "@octokit/openapi-types": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz", + "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==", + "dev": true + }, + "@octokit/plugin-paginate-rest": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.0.tgz", + "integrity": "sha512-ttpGck5AYWkwMkMazNCZMqxKqIq1fJBNxBfsFwwfyYKTf914jKkLF0POMS3YkPBwp5g1c2Y4L79gDz01GhSr1g==", + "dev": true, + "requires": { + "@octokit/types": "^13.7.0" + } + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.0.tgz", + "integrity": "sha512-LUm44shlmkp/6VC+qQgHl3W5vzUP99ZM54zH6BuqkJK4DqfFLhegANd+fM4YRLapTvPm4049iG7F3haANKMYvQ==", + "dev": true, + "requires": { + "@octokit/types": "^13.7.0" + } + }, + "@octokit/request": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.0.tgz", + "integrity": "sha512-kXLfcxhC4ozCnAXy2ff+cSxpcF0A1UqxjvYMqNuPIeOAzJbVWQ+dy5G2fTylofB/gTbObT8O6JORab+5XtA1Kw==", + "dev": true, + "requires": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.6.2", + "fast-content-type-parse": "^2.0.0", + "universal-user-agent": "^7.0.2" + } + }, + "@octokit/request-error": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.6.tgz", + "integrity": "sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==", + "dev": true, + "requires": { + "@octokit/types": "^13.6.2" + } + }, + "@octokit/types": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.7.0.tgz", + "integrity": "sha512-BXfRP+3P3IN6fd4uF3SniaHKOO4UXWBfkdR3vA8mIvaoO/wLjGN5qivUtW0QRitBHHMcfC41SLhNVYIZZE+wkA==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^23.0.1" + } + }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3899,6 +4231,12 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "before-after-hook": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", + "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", + "dev": true + }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -4263,6 +4601,12 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" }, + "fast-content-type-parse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz", + "integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5260,11 +5604,23 @@ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, + "undici": { + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "dev": true + }, "undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, + "universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index dd3119dc..05ca38df 100644 --- a/package.json +++ b/package.json @@ -73,14 +73,15 @@ }, "devDependencies": { "@eslint/js": "^9.8.0", + "@octokit/action": "^7.0.0", "@types/eslint__js": "^8.42.3", + "c8": "^10.1.2", "eslint": "^9.15.0", "globals": "^15.9.0", "prettier": "^3.2.5", "tsx": "^4.19.1", "typedoc": "^0.27.1", "typescript": "^5.7.2", - "typescript-eslint": "^8.16.0", - "c8": "^10.1.2" + "typescript-eslint": "^8.16.0" } } diff --git a/scripts/ci.js b/scripts/ci.js new file mode 100644 index 00000000..6fa61c35 --- /dev/null +++ b/scripts/ci.js @@ -0,0 +1,35 @@ +import { Octokit } from '@octokit/action'; + +const octokit = new Octokit(); + +const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); +const head_sha = process.env.GITHUB_SHA; + +let check_run_id; + +/** Create a new GitHub check run */ +export async function createCheck(name) { + const response = await octokit.request('POST /repos/{owner}/{repo}/check-runs', { + owner, + repo, + name, + head_sha, + status: 'in_progress', + started_at: new Date().toISOString(), + }); + + check_run_id = response.data.id; +} + +/** Complete a check run */ +export async function completeCheck(conclusion, title = '', summary = '') { + await octokit.request('PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}', { + owner, + repo, + check_run_id, + status: 'completed', + completed_at: new Date().toISOString(), + conclusion, + output: { title, summary }, + }); +} diff --git a/scripts/test.js b/scripts/test.js index e0148ef0..b1e557b1 100755 --- a/scripts/test.js +++ b/scripts/test.js @@ -17,6 +17,7 @@ const { values: options, positionals } = parseArgs({ common: { short: 'c', type: 'boolean', default: false }, inspect: { short: 'I', type: 'boolean', default: false }, 'exit-on-fail': { short: 'e', type: 'boolean' }, + ci: { type: 'string' }, // Coverage coverage: { type: 'string', default: 'tests/.coverage' }, preserve: { short: 'p', type: 'boolean' }, @@ -42,11 +43,12 @@ Options: -t, --test Which FS test suite(s) to run -f, --force Whether to use --test-force-exit -I, --inspect Use the inspector for debugging + --ci Continuous integration (CI) mode. This interacts with the Github Checks API for better test status Coverage: --coverage Override the default coverage data directory -p,--preserve Do not delete or report coverage data - --report ONLY report coverage + --report ONLY report coverage --clean ONLY clean up coverage directory`); process.exit(); } @@ -69,6 +71,9 @@ if (options.report) { process.exit(); } +let ci; +if (options.ci) ci = await import('./ci.js'); + options.verbose && options.force && console.debug('Forcing tests to exit (--test-force-exit)'); if (options.build) { @@ -107,9 +112,11 @@ function color(text, code) { return `\x1b[${code}m${text}\x1b[0m`; } -function status(name) { +async function status(name) { const start = performance.now(); + if (options.ci) await ci.createCheck(options.ci); + const time = () => { let delta = Math.round(performance.now() - start), unit = 'ms'; @@ -123,11 +130,13 @@ function status(name) { }; return { - pass() { + async pass() { if (!options.quiet) console.log(`${color('passed', 32)}: ${name} ${time()}`); + if (options.ci) await ci.completeCheck('success'); }, - fail() { + async fail() { console.error(`${color('failed', '1;31')}: ${name} ${time()}`); + if (options.ci) await ci.completeCheck('failure'); process.exitCode = 1; if (options['exit-on-fail']) process.exit(); }, @@ -139,14 +148,14 @@ mkdirSync(options.coverage, { recursive: true }); if (options.common) { !options.quiet && console.log('Running common tests...'); - const { pass, fail } = status('Common tests'); + const { pass, fail } = await status('Common tests'); try { execSync(`tsx ${options.inspect ? 'inspect' : ''} --test --experimental-test-coverage 'tests/*.test.ts' 'tests/**/!(fs)/*.test.ts'`, { stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'], }); - pass(); + await pass(); } catch { - fail(); + await fail(); } }