diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..1225235 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,37 @@ +name: Build + +on: + push: + branches: + - main + +jobs: + setup: + name: Setup + runs-on: ubuntu-latest + steps: + - name: Cancel previous + uses: styfle/cancel-workflow-action@0.11.0 + with: + access_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: '20.x' + cache: 'npm' + - name: Install deps 🧶 + run: npm ci + + build: + needs: setup + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: '20.x' + cache: 'npm' + - run: npm ci + - name: Build lib 👷‍♂️ + run: npm run build \ No newline at end of file diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml new file mode 100644 index 0000000..008b589 --- /dev/null +++ b/.github/workflows/coverage.yaml @@ -0,0 +1,47 @@ +name: Coverage + +on: + push: + branches: [ main ] + +jobs: + coverage-badge: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v3 + with: + node-version: '20.x' + cache: 'npm' + - name: Install deps 🧶 + run: npm ci + - name: Build + run: npm run build + - name: Test + run: npm run test:badge + + # Only run the coverage once + - name: Get Coverage for badge + run: | + SUMMARY="$(npm run test:badge | tail -2 | head -1)" + TOKENS=($SUMMARY) + echo "COVERAGE=$(echo ${TOKENS[2]})" >> $GITHUB_ENV + + REF=${{ github.ref }} + echo "github.ref: $REF" + IFS='/' read -ra PATHS <<< "$REF" + BRANCH_NAME="${PATHS[1]}_${PATHS[2]}" + echo $BRANCH_NAME + echo "BRANCH=$(echo ${BRANCH_NAME})" >> $GITHUB_ENV + + - name: Create the Badge + uses: schneegans/dynamic-badges-action@v1.0.0 + with: + auth: ${{ secrets.GIST_SECRET }} + gistID: f3a173e87a763056b73438f503680993 + filename: pdap-design-system__${{ env.BRANCH }}.json + label: Test Coverage + message: ${{ env.COVERAGE }} + color: green + namedLogo: vitest + style: for-the-badge \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index ed3dc62..d3d2b7d 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,6 @@ { - "recommendations": ["tailwind.tailwindcss", "vue.volar", "vue.vscode-typescript-vue-plugin"] -} + "recommendations": [ + "tailwind.tailwindcss", + "vue.volar" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index d8bb9db..0a15bc2 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ _A `Vue` component library, styling system, and image asset repository for PDAP-branded client apps._ [![Current npm release](https://img.shields.io/npm/v/pdap-design-system?style=for-the-badge)](https://www.npmjs.com/package/pdap-design-system) -![Build status](./badges/build.svg) -![Test coverage](./badges/coverage.svg) +![Build status](https://img.shields.io/github/actions/workflow/status/Police-Data-Accessibility-Project/design-system/build.yaml?branch=main&style=for-the-badge) +![Coverage Badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/joshuagraber/f3a173e87a763056b73438f503680993/raw/c849e80481d329e6a4176699d52b7ad70d12d829/pdap-design-system__heads_main.json) ![License](https://img.shields.io/github/license/Police-Data-Accessibility-Project/design-system.svg?style=for-the-badge&color=green) @@ -88,24 +88,6 @@ Or, if you need them all, you can import all images at the app level. Just remem import `pdap-design-system/images`; ``` -### Using the CLI to copy assets to your local project directory - -If you want either styles or images copied to a local directory, you can do so from the root directory of your project. - -Assets can be copied using the `pdap-design-system` command line method exposed by this package. - -One of the following arguments is required: -`--copy-assets`: Copies all images and styles. -`--copy-images`: Copies all images. -`--copy-styles`: Copies all styles. - -The following argument is optional: -`--to={path}`: Path to directory where assets should be copied. Defaults to `assets` - -``` - pdap-design-system --copy-images --to=image-assets -``` - ## Development Setup 1. Clone the repo diff --git a/badges/build.svg b/badges/build.svg deleted file mode 100644 index 40b78d2..0000000 --- a/badges/build.svg +++ /dev/null @@ -1 +0,0 @@ -BUILD: PASSINGBUILDPASSING \ No newline at end of file diff --git a/badges/coverage.svg b/badges/coverage.svg deleted file mode 100644 index 1997f07..0000000 --- a/badges/coverage.svg +++ /dev/null @@ -1 +0,0 @@ -COVERAGE: 100%COVERAGE100% \ No newline at end of file diff --git a/bin/pdap-design-system-cli.js b/bin/pdap-design-system-cli.js deleted file mode 100755 index 741a69c..0000000 --- a/bin/pdap-design-system-cli.js +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env node -import minimist from 'minimist'; -import cli from '../cli'; -import process from 'process'; - -// Convert argv to object keyed by argName where --argName is what is passed to CLI -const args = minimist(process.argv); - -switch (true) { - case args['copy-assets']: - cli.copyAllAssets(args); - break; - case args['copy-images']: - cli.copyImageAssets(args); - break; - case args['copy-styles']: - cli.copyStyleAssets(args); - break; - default: - console.log( - 'No option argument was passed to pdap-design-system CLI.', - '\n Current options are:', - '\n --copy-assets: Copy all assets to assets/ (default) or custom path passed to optional --to argument.', - '\n --copy-images: Copy only image assets to assets/ (default) or custom path passed to optional --to argument.', - '\n --copy-styles: Copy only CSS assets to assets/ (default) or custom path passed to optional --to argument.' - ); - break; -} diff --git a/cli/index.js b/cli/index.js deleted file mode 100644 index 6c6b09b..0000000 --- a/cli/index.js +++ /dev/null @@ -1,45 +0,0 @@ -import fs from 'fs-extra'; -import process from 'process'; - -function copyImageAssets(args) { - const packageImagesPath = - process.cwd() + '/node_modules/pdap-design-system/dist/images'; - const destinationSubPath = (args.to ?? 'assets') + '/images'; - const destinationPath = process.cwd() + '/' + destinationSubPath; - - console.log(`Copying PDAP image assets to ${destinationPath}`); - - fs.copy(packageImagesPath, destinationPath, function onComplete(err) { - if (err) { - console.error(err); - } else { - console.log('PDAP image assets successfully copied.'); - } - }); -} - -function copyStyleAssets(args) { - const packageStylesPath = process.cwd() + '/node_modules/pdap-design-system/'; - const destinationSubPath = (args.to ?? 'assets') + '/styles'; - const destinationPath = process.cwd() + '/' + destinationSubPath; - - console.log(`Copying PDAP Style assets to ${destinationPath}`); - - fs.copy(packageStylesPath, destinationPath, function onComplete(err) { - if (err) { - console.error(err); - } else { - console.log('PDAP Style assets successfully copied.'); - } - }); -} - -export default { - copyAllAssets: function copyAllAssets(args) { - return Object.values(this).forEach((handler) => { - if (handler.name !== this.copyAllAssets.name) handler(args); - }); - }, - copyImageAssets, - copyStyleAssets, -}; diff --git a/package-lock.json b/package-lock.json index cce6f68..15a142c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,6 @@ "vue": "^3.3.7", "vue-router": "^4.2.5" }, - "bin": { - "pdap-design-system": "bin/pdap-design-system-cli.js" - }, "devDependencies": { "@commitlint/cli": "^18.4.3", "@commitlint/config-conventional": "^18.4.3", @@ -39,7 +36,6 @@ "@vue/eslint-config-typescript": "^12.0.0", "@vue/test-utils": "^2.4.1", "autoprefixer": "^10.4.16", - "badge-maker": "^3.3.1", "cheerio": "1.0.0-rc.12", "conventional-changelog-angular": "^7.0.0", "cross-env": "^7.0.3", @@ -3392,15 +3388,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/anafanafo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anafanafo/-/anafanafo-2.0.0.tgz", - "integrity": "sha512-Nlfq7NC4AOkTJerWRIZcOAiMNtIDVIGWGvQ98O7Jl6Kr2Dk0dX5u4MqN778kSRTy5KRqchpLdF2RtLFEz9FVkQ==", - "dev": true, - "dependencies": { - "char-width-table-consumer": "^1.0.0" - } - }, "node_modules/ansi-escapes": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", @@ -3638,23 +3625,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/badge-maker": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/badge-maker/-/badge-maker-3.3.1.tgz", - "integrity": "sha512-OO/PS7Zg2E6qaUWzHEHt21Q5VjcFBAJVA8ztgT/fIdSZFBUwoyeo0ZhA6V5tUM8Vcjq8DJl6jfGhpjESssyqMQ==", - "dev": true, - "dependencies": { - "anafanafo": "2.0.0", - "css-color-converter": "^2.0.0" - }, - "bin": { - "badge": "lib/badge-cli.js" - }, - "engines": { - "node": ">= 10", - "npm": ">= 5" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3704,12 +3674,6 @@ "node": ">=8" } }, - "node_modules/binary-search": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.6.tgz", - "integrity": "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==", - "dev": true - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -4051,15 +4015,6 @@ "node": ">=10" } }, - "node_modules/char-width-table-consumer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/char-width-table-consumer/-/char-width-table-consumer-1.0.0.tgz", - "integrity": "sha512-Fz4UD0LBpxPgL9i29CJ5O4KANwaMnX/OhhbxzvNa332h+9+nRKyeuLw4wA51lt/ex67+/AdsoBQJF3kgX2feYQ==", - "dev": true, - "dependencies": { - "binary-search": "^1.3.5" - } - }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -4943,23 +4898,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/css-color-converter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-color-converter/-/css-color-converter-2.0.0.tgz", - "integrity": "sha512-oLIG2soZz3wcC3aAl/7Us5RS8Hvvc6I8G8LniF/qfMmrm7fIKQ8RIDDRZeKyGL2SrWfNqYspuLShbnjBMVWm8g==", - "dev": true, - "dependencies": { - "color-convert": "^0.5.2", - "color-name": "^1.1.4", - "css-unit-converter": "^1.1.2" - } - }, - "node_modules/css-color-converter/node_modules/color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==", - "dev": true - }, "node_modules/css-functions-list": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", @@ -4982,12 +4920,6 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/css-unit-converter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", - "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==", - "dev": true - }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -19565,15 +19497,6 @@ "uri-js": "^4.2.2" } }, - "anafanafo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anafanafo/-/anafanafo-2.0.0.tgz", - "integrity": "sha512-Nlfq7NC4AOkTJerWRIZcOAiMNtIDVIGWGvQ98O7Jl6Kr2Dk0dX5u4MqN778kSRTy5KRqchpLdF2RtLFEz9FVkQ==", - "dev": true, - "requires": { - "char-width-table-consumer": "^1.0.0" - } - }, "ansi-escapes": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", @@ -19733,16 +19656,6 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "badge-maker": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/badge-maker/-/badge-maker-3.3.1.tgz", - "integrity": "sha512-OO/PS7Zg2E6qaUWzHEHt21Q5VjcFBAJVA8ztgT/fIdSZFBUwoyeo0ZhA6V5tUM8Vcjq8DJl6jfGhpjESssyqMQ==", - "dev": true, - "requires": { - "anafanafo": "2.0.0", - "css-color-converter": "^2.0.0" - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -19772,12 +19685,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "binary-search": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.6.tgz", - "integrity": "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==", - "dev": true - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -20014,15 +19921,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "char-width-table-consumer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/char-width-table-consumer/-/char-width-table-consumer-1.0.0.tgz", - "integrity": "sha512-Fz4UD0LBpxPgL9i29CJ5O4KANwaMnX/OhhbxzvNa332h+9+nRKyeuLw4wA51lt/ex67+/AdsoBQJF3kgX2feYQ==", - "dev": true, - "requires": { - "binary-search": "^1.3.5" - } - }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -20664,25 +20562,6 @@ } } }, - "css-color-converter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-color-converter/-/css-color-converter-2.0.0.tgz", - "integrity": "sha512-oLIG2soZz3wcC3aAl/7Us5RS8Hvvc6I8G8LniF/qfMmrm7fIKQ8RIDDRZeKyGL2SrWfNqYspuLShbnjBMVWm8g==", - "dev": true, - "requires": { - "color-convert": "^0.5.2", - "color-name": "^1.1.4", - "css-unit-converter": "^1.1.2" - }, - "dependencies": { - "color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==", - "dev": true - } - } - }, "css-functions-list": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", @@ -20699,12 +20578,6 @@ "source-map-js": "^1.0.1" } }, - "css-unit-converter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", - "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==", - "dev": true - }, "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", diff --git a/package.json b/package.json index aa56834..5769ed8 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "@vue/eslint-config-typescript": "^12.0.0", "@vue/test-utils": "^2.4.1", "autoprefixer": "^10.4.16", - "badge-maker": "^3.3.1", "cheerio": "1.0.0-rc.12", "conventional-changelog-angular": "^7.0.0", "cross-env": "^7.0.3", @@ -96,37 +95,28 @@ }, "scripts": { "_commit": "cz", - "build": "vite build && vue-tsc && npm run badges:build", + "build": "vite build && vue-tsc", "build:watch": "vite build && vue-tsc --watch", "ci": "npm run clean && npm ci", "clean": "run-p clean:*", "clean:deps": "rimraf node_modules", - "clean:build": "rimraf coverage test/report dist", - "clean:test": "rimraf coverage test/report", + "clean:test": "rimraf coverage", "lint": "run-p lint:*", "lint:css": "stylelint 'src/**/*.{css,vue}'", "lint:es": "eslint src --ext .ts .", "lint:ts": "vue-tsc", - "postbuild": "run-p clean:test && rimraf dist/{config,utils}", - "posttest": "npm run badges:coverage", + "postbuild": "rimraf dist/{config,utils}", + "posttest": "npm run clean:test", "prepare": "husky install", "test": "vitest --dom --run --coverage", "test:changed": "npm run test -- --changed", + "test:badge": "vitest run --coverage.enabled --coverage.reporter='text-summary'", "test:ci": "npm run test -- --silent", - "typecheck": "vue-tsc", - "badges": "run-p badges:*", - "badges:build": "node ./tools/generateBuildBadge.js", - "badges:coverage": "node ./tools/generateCoverageBadge.js" + "typecheck": "vue-tsc" }, "workspaces": [ "eslint-config" ], - "bin": { - "pdap-design-system": "./bin/pdap-design-system-cli.js" - }, - "keywords": [ - "pdap-design-system" - ], "files": [ "bin", "dist", diff --git a/tools/generateBuildBadge.js b/tools/generateBuildBadge.js deleted file mode 100644 index 849f284..0000000 --- a/tools/generateBuildBadge.js +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable no-undef */ -import fs from 'fs'; -import path from 'path'; -import url from 'url'; -import { makeBadge } from 'badge-maker'; -import { exec } from 'child_process'; - -// Shim -const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); - -let isError = false; - -exec('npm run build', (error) => { - if (error) { - isError = true; - } -}); - -const badge = makeBadge({ - label: 'build', - message: isError ? 'failing' : 'passing', - color: isError ? 'red' : 'brightgreen', - style: 'for-the-badge', -}); - -fs.writeFile(path.join(__dirname, '../badges/build.svg'), badge, (err) => { - if (err) console.log(err); - else { - console.log('Build badge written successfully with contents:\n'); - console.log(fs.readFileSync('badges/build.svg', 'utf8')); - } - - if (typeof fs.readFileSync('badges/build.svg', 'utf8') !== 'undefined') { - process.exit(0); - } -}); diff --git a/tools/generateCoverageBadge.js b/tools/generateCoverageBadge.js deleted file mode 100644 index 12bd712..0000000 --- a/tools/generateCoverageBadge.js +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env node -import { load } from 'cheerio'; -import fs from 'fs'; -import path from 'path'; -import url from 'url'; -import { makeBadge } from 'badge-maker'; - -const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); - -const $coverage = load( - fs.readFileSync( - path.join(__dirname, '../coverage/index.html'), - 'utf8', - (err, data) => { - if (err) { - console.error(err); - return; - } - console.log(data); - } - ) -); - -const totalCoverageElements = $coverage('.pad1').find('.strong'); - -// Get elements that report total coverage. -const coveragePercentage = - totalCoverageElements - .map(function () { - // Convert text content, strip % character, and convert to number - return Number($coverage(this).text().replace(/%/, '').trim()); - }) - .toArray() - // Add up - .reduce((acc, cur) => acc + cur, 0) / - // Divide by total - totalCoverageElements.length; - -fs.writeFile( - path.join(__dirname, '../badges/coverage.svg'), - getCoverageBadge(coveragePercentage), - (err) => { - if (err) console.log(err); - else { - console.log('Coverage badge written successfully with contents:\n'); - console.log(fs.readFileSync('badges/coverage.svg', 'utf8')); - } - } -); - -function getCoverageBadge(coveragePercentage) { - const level = - coveragePercentage > 98 - ? 'high' - : coveragePercentage > 90 - ? 'medium' - : 'low'; - - const colors = new Map([ - ['low', 'red'], - ['medium', 'yellow'], - ['high', 'brightgreen'], - ]); - - const format = { - label: 'coverage', - message: `${coveragePercentage}%`, - color: colors.get(level), - style: 'for-the-badge', - }; - - return makeBadge(format); -}