From e176f2a70b8e25ccba802ddf5edc135a9023ab31 Mon Sep 17 00:00:00 2001 From: Daniel Eshkeri Date: Fri, 6 Dec 2024 10:15:57 +0000 Subject: [PATCH] Added action --- .env.example | 59 ----------- .github/workflows/ci.yml | 4 - CODEOWNERS | 3 - action.yml | 56 ++++++++-- package-lock.json | 213 ++++++++++++++++++++++++++++++++++---- package.json | 25 +++-- src/main.ts | 72 ++++++++++--- src/scripts/analyze.ts | 21 ++++ src/scripts/coverage.ts | 95 +++++++++++++++++ src/scripts/formatting.ts | 15 +++ src/scripts/testing.ts | 18 ++++ src/wait.ts | 14 --- 12 files changed, 461 insertions(+), 134 deletions(-) delete mode 100644 .env.example delete mode 100644 CODEOWNERS create mode 100644 src/scripts/analyze.ts create mode 100644 src/scripts/coverage.ts create mode 100644 src/scripts/formatting.ts create mode 100644 src/scripts/testing.ts delete mode 100644 src/wait.ts diff --git a/.env.example b/.env.example deleted file mode 100644 index 633dad2..0000000 --- a/.env.example +++ /dev/null @@ -1,59 +0,0 @@ -# Do not commit your actual .env file to Git! This may contain secrets or other -# private information. - -# Enable/disable step debug logging (default: `false`). For local debugging, it -# may be useful to set it to `true`. -ACTIONS_STEP_DEBUG=true - -# GitHub Actions inputs should follow `INPUT_` format (case-sensitive). -# Hyphens should not be converted to underscores! -INPUT_MILLISECONDS=2400 - -# GitHub Actions default environment variables. These are set for every run of a -# workflow and can be used in your actions. Setting the value here will override -# any value set by the local-action tool. -# https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables - -# CI="true" -# GITHUB_ACTION="" -# GITHUB_ACTION_PATH="" -# GITHUB_ACTION_REPOSITORY="" -# GITHUB_ACTIONS="" -# GITHUB_ACTOR="" -# GITHUB_ACTOR_ID="" -# GITHUB_API_URL="" -# GITHUB_BASE_REF="" -# GITHUB_ENV="" -# GITHUB_EVENT_NAME="" -# GITHUB_EVENT_PATH="" -# GITHUB_GRAPHQL_URL="" -# GITHUB_HEAD_REF="" -# GITHUB_JOB="" -# GITHUB_OUTPUT="" -# GITHUB_PATH="" -# GITHUB_REF="" -# GITHUB_REF_NAME="" -# GITHUB_REF_PROTECTED="" -# GITHUB_REF_TYPE="" -# GITHUB_REPOSITORY="" -# GITHUB_REPOSITORY_ID="" -# GITHUB_REPOSITORY_OWNER="" -# GITHUB_REPOSITORY_OWNER_ID="" -# GITHUB_RETENTION_DAYS="" -# GITHUB_RUN_ATTEMPT="" -# GITHUB_RUN_ID="" -# GITHUB_RUN_NUMBER="" -# GITHUB_SERVER_URL="" -# GITHUB_SHA="" -# GITHUB_STEP_SUMMARY="" -# GITHUB_TRIGGERING_ACTOR="" -# GITHUB_WORKFLOW="" -# GITHUB_WORKFLOW_REF="" -# GITHUB_WORKFLOW_SHA="" -# GITHUB_WORKSPACE="" -# RUNNER_ARCH="" -# RUNNER_DEBUG="" -# RUNNER_NAME="" -# RUNNER_OS="" -# RUNNER_TEMP="" -# RUNNER_TOOL_CACHE="" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6d2861..9b3cdf8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,3 @@ jobs: uses: ./ with: milliseconds: 2000 - - - name: Print Output - id: output - run: echo "${{ steps.test-action.outputs.time }}" diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 2e08bd2..0000000 --- a/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# Repository CODEOWNERS - -* @actions/actions-oss-maintainers diff --git a/action.yml b/action.yml index 101186a..16f248b 100644 --- a/action.yml +++ b/action.yml @@ -1,23 +1,57 @@ -name: 'The name of your action here' -description: 'Provide a description here' -author: 'Your name or organization here' +name: 'Web Components Code Quality' +description: + 'This action is designed to format and test Web Component repositories on pull + requests. It helps ensure that your code meets the required quality standards.' +author: 'Zebra Technologies' # Add your action's branding here. This will appear on the GitHub Marketplace. branding: - icon: 'heart' - color: 'red' + icon: compass + color: 'blue' # Define your inputs here. inputs: - milliseconds: - description: 'Your input description here' + token: + description: 'Token used for pushing fixes and commenting on PRs' required: true - default: '1000' + + working-directory: + description: 'The working directory' + required: false + default: '.' + + run-static-analysis: + description: 'Whether to run static analysis' + required: false + default: 'true' + + run-code-formatting: + description: 'Whether to run code formatting' + required: false + default: 'true' + + run-tests: + description: 'Whether to run tests' + required: false + default: 'true' + + run-coverage: + description: 'Whether to run coverage' + required: false + default: 'true' + + create-comment: + description: 'Whether to create a comment on the PR' + required: false + default: 'true' + + coverage-pass-score: + description: 'The minimum coverage score required to pass' + required: false + default: '80' # Define your outputs here. -outputs: - time: - description: 'Your output description here' +# outputs: runs: using: node20 diff --git a/package-lock.json b/package-lock.json index bca91dc..8772a1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,23 @@ { - "name": "typescript-action", - "version": "0.0.0", + "name": "web-components-code-quality", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "typescript-action", - "version": "0.0.0", + "name": "web-components-code-quality", + "version": "0.0.1", "license": "MIT", "dependencies": { - "@actions/core": "^1.11.1" + "@actions/core": "^1.11.1", + "@actions/github": "^6.0.0", + "parse-lcov": "^1.0.4" }, "devDependencies": { "@github/local-action": "^2.2.0", "@jest/globals": "^29.7.0", "@types/jest": "^29.5.14", - "@types/node": "^22.9.0", + "@types/node": "^22.10.1", "@typescript-eslint/eslint-plugin": "^8.14.0", "@typescript-eslint/parser": "^8.14.0", "@vercel/ncc": "^0.38.3", @@ -60,6 +62,167 @@ "@actions/io": "^1.0.1" } }, + "node_modules/@actions/github": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz", + "integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==", + "license": "MIT", + "dependencies": { + "@actions/http-client": "^2.2.0", + "@octokit/core": "^5.0.1", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + } + }, + "node_modules/@actions/github/node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@actions/github/node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@actions/github/node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@actions/github/node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@actions/github/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "license": "MIT" + }, + "node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", + "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@actions/github/node_modules/@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@actions/github/node_modules/@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@actions/github/node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "license": "Apache-2.0" + }, + "node_modules/@actions/github/node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "license": "ISC" + }, "node_modules/@actions/http-client": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz", @@ -1824,8 +1987,7 @@ "node_modules/@octokit/openapi-types": { "version": "22.2.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "dev": true + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" }, "node_modules/@octokit/request": { "version": "9.1.3", @@ -1858,7 +2020,6 @@ "version": "13.5.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", - "dev": true, "dependencies": { "@octokit/openapi-types": "^22.2.0" } @@ -1984,12 +2145,13 @@ } }, "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, "node_modules/@types/stack-utils": { @@ -2798,6 +2960,12 @@ "node": ">=0.10.0" } }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "license": "ISC" + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -4988,7 +5156,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -5094,6 +5261,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-lcov": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/parse-lcov/-/parse-lcov-1.0.4.tgz", + "integrity": "sha512-jE72M66VFyZJ0KYKnmaV70U/Y6FZyPoBCtJ6we5rDIVpWFR/GEkdCSLJn/R3UHJWZ3e3Qf3jAm2AUrmkaso+wA==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6086,10 +6259,11 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" }, "node_modules/universal-user-agent": { "version": "7.0.2", @@ -6218,8 +6392,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.2", diff --git a/package.json b/package.json index e36645b..009c38d 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,22 @@ { - "name": "typescript-action", - "description": "GitHub Actions TypeScript template", - "version": "0.0.0", - "author": "", - "private": true, - "homepage": "https://github.com/actions/typescript-action", + "name": "web-components-code-quality", + "description": "This action is designed to format and test Web Component repositories on pull requests. It helps ensure that your code meets the required quality standards.", + "version": "0.0.1", + "author": "Zebra Technologies", + "private": false, + "homepage": "https://github.com/ZebraDevs/web-components-code-quality", "repository": { "type": "git", - "url": "git+https://github.com/actions/typescript-action.git" + "url": "git+https://github.com/ZebraDevs/web-components-code-quality.git" }, "bugs": { - "url": "https://github.com/actions/typescript-action/issues" + "url": "https://github.com/ZebraDevs/web-components-code-quality/issues" }, "keywords": [ "actions", "node", - "setup" + "web components", + "code quality" ], "exports": { ".": "./dist/index.js" @@ -67,13 +68,15 @@ ] }, "dependencies": { - "@actions/core": "^1.11.1" + "@actions/core": "^1.11.1", + "@actions/github": "^6.0.0", + "parse-lcov": "^1.0.4" }, "devDependencies": { "@github/local-action": "^2.2.0", "@jest/globals": "^29.7.0", "@types/jest": "^29.5.14", - "@types/node": "^22.9.0", + "@types/node": "^22.10.1", "@typescript-eslint/eslint-plugin": "^8.14.0", "@typescript-eslint/parser": "^8.14.0", "@vercel/ncc": "^0.38.3", diff --git a/src/main.ts b/src/main.ts index c804f90..70c357f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,12 @@ -import * as core from '@actions/core' -import { wait } from './wait' +import { getBooleanInput, getInput, setFailed } from '@actions/core' +import { exec } from '@actions/exec' +import { getOctokit, context } from '@actions/github' +import { analyze } from './scripts/analyze' +import { formatting } from './scripts/formatting' +import { testing } from './scripts/testing' +import { coverage } from './scripts/coverage' + +export type stepResponse = { output: string; error: boolean } /** * The main function for the action. @@ -7,20 +14,61 @@ import { wait } from './wait' */ export async function run(): Promise { try { - const ms: string = core.getInput('milliseconds') + await exec('npm ci') + } catch (error) { + if (error instanceof Error) setFailed(error.message) + } + + try { + const workingDirectory: string = getInput('working-directory') + // Check if the working directory is different from the current directory + if (workingDirectory && workingDirectory !== process.cwd()) { + process.chdir(workingDirectory) + } + + const token: string = getInput('token') + const octokit = getOctokit(token) + const runStaticAnalysis: boolean = getBooleanInput('run-static-analysis') + const runCodeFormatting: boolean = getBooleanInput('run-code-formatting') + const runTests: boolean = getBooleanInput('run-tests') + const runCoverage: boolean = getBooleanInput('run-coverage') + // const coveragePassScore: string = getInput('coverage-pass-score') + // const createComment: boolean = getBooleanInput('create-comment') + + // if (runStaticAnalysis) { then run static analysis script } + const analyzeStr: stepResponse | undefined = runStaticAnalysis + ? await analyze() + : undefined + + // if (runCodeFormatting) { then run code formatting script } + const runCodeFormattingStr: stepResponse | undefined = runCodeFormatting + ? await formatting() + : undefined + + // if (runTests) { then run tests script, passing in the coveragePassScore } + const testingStr: stepResponse | undefined = runTests + ? await testing() + : undefined + + const coverageStr: stepResponse | undefined = runCoverage + ? await coverage() + : undefined - // Debug logs are only output if the `ACTIONS_STEP_DEBUG` secret is true - core.debug(`Waiting ${ms} milliseconds ...`) + const commentBody = `## Static Analysis = ${analyzeStr?.output}\n + ## Code Formatting = ${runCodeFormattingStr?.output}\n + ## Testing = ${testingStr?.output}\n + ## Coverage = ${coverageStr?.output}\n` - // Log the current timestamp, wait, then log the new timestamp - core.debug(new Date().toTimeString()) - await wait(parseInt(ms, 10)) - core.debug(new Date().toTimeString()) + await octokit.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }) - // Set outputs for other workflow steps to use - core.setOutput('time', new Date().toTimeString()) + // if (createComment) { then create a comment on the PR with the results of the actions } } catch (error) { // Fail the workflow run if an error occurs - if (error instanceof Error) core.setFailed(error.message) + if (error instanceof Error) setFailed(error.message) } } diff --git a/src/scripts/analyze.ts b/src/scripts/analyze.ts new file mode 100644 index 0000000..b58dfe6 --- /dev/null +++ b/src/scripts/analyze.ts @@ -0,0 +1,21 @@ +import { exec } from '@actions/exec' +import { setFailed } from '@actions/core' +import { stepResponse } from 'src/main' + +export const analyze = async (): Promise => { + try { + // Run custom elements manifest analyzer + await exec('npm run analyze') + + // Run eslint + await exec('npm run lint') + + // Run lit-analyzer + await exec('npm run lint:lit-analyzer') + + return { output: 'Static analysis complete', error: false } + } catch (error) { + if (error instanceof Error) setFailed(error.message) + return { output: 'Static analysis failed', error: true } + } +} diff --git a/src/scripts/coverage.ts b/src/scripts/coverage.ts new file mode 100644 index 0000000..871312d --- /dev/null +++ b/src/scripts/coverage.ts @@ -0,0 +1,95 @@ +import { setFailed } from '@actions/core' +import parseLCOV from 'parse-lcov' +import { stepResponse } from 'src/main' + +// TODO: Adapt the step to use parseLCOV +// +// + +export const coverage = async (): Promise => { + try { + return { output: 'RETURN COVERAGE', error: false } + } catch (error) { + if (error instanceof Error) setFailed(error.message) + return { output: 'Coverage failed', error: true } + } +} + +// import { readFileSync } from 'node:fs' +// import { endGroup, startGroup } from '@actions/core' +// import { stepResponse } from '../main' +// import { debug } from '@actions/core' +// import { getLcovLines } from './utils' + +// export const COV_FAILURE = '⚠️ - Coverage check failed' + +// /** +// * Get the coverage report and compare with the previous coverage +// * @param prevCoverage - Previous coverage report +// * @param coverageDirectory - Directory to store coverage report +// * @returns Coverage report as a stepResponse object +// */ +// export const coverage = ( +// prevCoverage: Lcov | undefined, +// coverageDirectory: string, +// scoreStr: string +// ): stepResponse => { +// startGroup('Checking test coverage') +// let response: stepResponse | undefined +// let score = 90 + +// try { +// score = parseInt(scoreStr) +// } catch (error) { +// console.error('Error parsing score', 'Will default to 90', error) +// } + +// try { +// const contents = readFileSync(`${coverageDirectory}/lcov.info`, 'utf8') +// const lcov: Lcov = parse(contents) +// debug('Parsed lcov.info') +// const digest: LcovDigest = sum(lcov) +// const totalPercent: number = digest.lines +// let percentOutput: string + +// const arr = Object.values(lcov).map(e => { +// const fileName = e.sf +// const percent = Math.round((e.lh / e.lf) * 1000) / 10 +// const passing = percent > score ? '✅' : '⛔️' +// return `${fileName}${percent}%${passing}` +// }) +// debug(`Coverage at ${totalPercent}%`) +// if (prevCoverage != undefined) { +// debug('Comparing with previous coverage') +// const prevPercent = getLcovLines(prevCoverage) +// if (prevPercent > totalPercent) { +// debug('Coverage decreased') +// percentOutput = totalPercent + `% (🔻 down from ` + prevPercent + `%)` +// } else if (prevPercent < totalPercent) { +// debug('Coverage increased') +// percentOutput = totalPercent + `% (⬆️ up from ` + prevPercent + `%)` +// } else { +// debug('Coverage unchanged') +// percentOutput = totalPercent + `% (no change)` +// } +// } else { +// percentOutput = totalPercent + '%' +// } + +// const str = `📈 - Code coverage: ${percentOutput} +//
+//
See details +// +// +// ${arr.join('')} +//
File Name%Passing?
+//
` +// response = { output: str, error: false } +// } catch (error) { +// console.error('Error checking coverage', error) +// response = { output: COV_FAILURE, error: true } +// } +// debug('Finished checking coverage; generated response') +// endGroup() +// return response +// } diff --git a/src/scripts/formatting.ts b/src/scripts/formatting.ts new file mode 100644 index 0000000..3330ef8 --- /dev/null +++ b/src/scripts/formatting.ts @@ -0,0 +1,15 @@ +import { exec } from '@actions/exec' +import { setFailed } from '@actions/core' +import { stepResponse } from 'src/main' + +export const formatting = async (): Promise => { + try { + // Run prettier + await exec('npm run prettier') + + return { output: 'Formatting complete', error: false } + } catch (error) { + if (error instanceof Error) setFailed(error.message) + return { output: 'Formatting failed', error: true } + } +} diff --git a/src/scripts/testing.ts b/src/scripts/testing.ts new file mode 100644 index 0000000..6f8a2b3 --- /dev/null +++ b/src/scripts/testing.ts @@ -0,0 +1,18 @@ +import { exec } from '@actions/exec' +import { setFailed } from '@actions/core' +import { stepResponse } from 'src/main' + +export const testing = async (): Promise => { + try { + // Run tests and generate coverage + await exec('npm run test -- --coverage --debug') + + // Test tsdoc + await exec('npm run docs') + + return { output: 'Testing complete', error: false } + } catch (error) { + if (error instanceof Error) setFailed(error.message) + return { output: 'Testing failed', error: true } + } +} diff --git a/src/wait.ts b/src/wait.ts deleted file mode 100644 index 0ddf692..0000000 --- a/src/wait.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Wait for a number of milliseconds. - * @param milliseconds The number of milliseconds to wait. - * @returns {Promise} Resolves with 'done!' after the wait is over. - */ -export async function wait(milliseconds: number): Promise { - return new Promise(resolve => { - if (isNaN(milliseconds)) { - throw new Error('milliseconds not a number') - } - - setTimeout(() => resolve('done!'), milliseconds) - }) -}