From 7711a7e12495826d7927a58d85aa60eecdd9da0b Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Fri, 12 Aug 2022 17:49:06 +0200 Subject: [PATCH 01/13] Clean up server from old logic --- server/{app.js => index.js} | 3 --- server/test/{app.test.js => index.test.js} | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) rename server/{app.js => index.js} (85%) rename server/test/{app.test.js => index.test.js} (98%) diff --git a/server/app.js b/server/index.js similarity index 85% rename from server/app.js rename to server/index.js index 9ae77e08..5894145b 100644 --- a/server/app.js +++ b/server/index.js @@ -19,9 +19,6 @@ const App = http.createServer(async (req, res) => { handleAPIBrowsers(req, res) break - // TODO Add endpoint /api/social - // handleAPISocial(req, res) : { githubStars: number, twitterFollowers: number } - default: handleStatic(req, res) break diff --git a/server/test/app.test.js b/server/test/index.test.js similarity index 98% rename from server/test/app.test.js rename to server/test/index.test.js index 63069cde..6301bac6 100644 --- a/server/test/app.test.js +++ b/server/test/index.test.js @@ -2,7 +2,7 @@ import { equal, match } from 'node:assert' import { URL } from 'node:url' import test from 'node:test' -import App from '../app.js' +import App from '../index.js' const base = `http://localhost:${App.address().port}/` From 31e4a305c15fa3f81b039580989810d168b3564f Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Fri, 12 Aug 2022 17:50:09 +0200 Subject: [PATCH 02/13] Typo --- server/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/test/index.test.js b/server/test/index.test.js index 6301bac6..9c726706 100644 --- a/server/test/index.test.js +++ b/server/test/index.test.js @@ -8,7 +8,7 @@ const base = `http://localhost:${App.address().port}/` test('Integration tests', async t => { await t.test( - 'responses `defauts` query for `/browsers` route without `q` param', + 'responses `defaults` query for `/browsers` route without `q` param', async () => { let url = new URL(`api/browsers`, base) let response = await fetch(url) From e611051f1f1eb948f117214db51280c4e747be9e Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 01:57:58 +0200 Subject: [PATCH 03/13] Clean up scripts for future ssdeploy CLI --- package.json | 2 +- server/package.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c35082a4..079008e6 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "scripts": { "start": "pnpm -r start", - "production": "pnpm -r build && NODE_ENV=production pnpm -r serve", + "build": "pnpm -r build", "lint": "eslint . && stylelint **/*.css", "test": "pnpm audit --prod && pnpm lint && pnpm -r test" }, diff --git a/server/package.json b/server/package.json index 42783a33..3e46a7b9 100644 --- a/server/package.json +++ b/server/package.json @@ -3,8 +3,7 @@ "private": true, "type": "module", "scripts": { - "start": "pnpm serve", - "serve": "node app.js", + "start": "node index.js", "test": "pnpm -r build && node --test test/*.test.js" }, "dependencies": { From b6f0901169e0385eeb643dcb9b6fcaa57831e909 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:44:19 +0200 Subject: [PATCH 04/13] Dockernize application --- .dockerignore | 12 ++++++++++++ Dockerfile | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..4a6ee7aa --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules/ + +server/test/ +client/ +!client/dist/ + +.* +README.md +LICENSE +nano-staged.json +simple-git-hooks.json +Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..16dd14a2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM node:18-alpine + +ENV NODE_ENV production +WORKDIR /var/www +COPY --chown=node:node . /var/www + +RUN corepack enable +RUN corepack prepare pnpm@7.9.1 --activate +COPY ./pnpm-workspace.yaml /var/www/ +COPY ./package.json /var/www/ +COPY ./pnpm-lock.yaml /var/www/ +COPY ./server/ /var/www/server/ +RUN pnpm install --filter ./server --prod --frozen-lockfile --ignore-scripts +COPY ./client/dist/ /var/www/client/dist/ + +CMD "node" "server/index.js" From 87a43c0d05e93995ded119d368424b457434e37f Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:44:25 +0200 Subject: [PATCH 05/13] Add ssdeploy --- .github/workflows/close.yml | 50 +++++++++++++++ .github/workflows/preview.yml | 66 +++++++++++++++++++ README.md | 6 +- client/package.json | 2 +- package.json | 3 + pnpm-lock.yaml | 115 ++++++++++++++++++++++++++++++---- 6 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/close.yml create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/close.yml b/.github/workflows/close.yml new file mode 100644 index 00000000..3c303695 --- /dev/null +++ b/.github/workflows/close.yml @@ -0,0 +1,50 @@ +name: Clean Preview +on: + pull_request: + types: [ closed ] +jobs: + close: + runs-on: ubuntu-latest + steps: + - name: Clean from GitHub + uses: bobheadxi/deployments@v1 + with: + step: delete-env + token: ${{ secrets.GITHUB_TOKEN }} + env: preview-${{ github.event.number }} + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Install asdf tools + if: steps.asdf-cache.outputs.cache-hit != 'true' + uses: asdf-vm/actions/install@v1 + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install dependencies + run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Auth Google Cloud + uses: google-github-actions/auth@v0 + with: + credentials_json: ${{ secrets.GCLOUD_AUTH }} + - name: Install Google Cloud + uses: google-github-actions/setup-gcloud@v0 + - name: Clean from Google Cloud + run: ./node_modules/.bin/ssdeploy close $PR --verbose + env: + PR: ${{ github.event.number }} + GCLOUD_APP: ${{ secrets.GCLOUD_APP }} + GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 00000000..d84bb319 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,66 @@ +name: Preview +on: + pull_request: +env: + FORCE_COLOR: 2 +jobs: + preview: + runs-on: ubuntu-latest + if: github.ref != 'refs/heads/main' + steps: + - name: Notify about new deployment + uses: bobheadxi/deployments@v1 + id: deployment + with: + step: start + token: ${{ secrets.GITHUB_TOKEN }} + ref: ${{ github.head_ref }} + env: preview-${{ github.event.number }} + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Install asdf tools + if: steps.asdf-cache.outputs.cache-hit != 'true' + uses: asdf-vm/actions/install@v1 + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install production dependencies + run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Build static files + run: npm build + - name: Auth Google Cloud + uses: google-github-actions/auth@v0 + with: + credentials_json: ${{ secrets.GCLOUD_AUTH }} + - name: Install Google Cloud + uses: google-github-actions/setup-gcloud@v0 + - name: Deploy files + id: deploy + run: ./node_modules/.bin/ssdeploy preview $PR --verbose + env: + PR: ${{ github.event.number }} + GCLOUD_APP: ${{ secrets.GCLOUD_APP }} + GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} + - name: Update deployment status + uses: bobheadxi/deployments@v1 + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ job.status }} + env: ${{ steps.deployment.outputs.env }} + env_url: ${{ steps.deploy.outputs.url }} + deployment_id: ${{ steps.deployment.outputs.deployment_id }} diff --git a/README.md b/README.md index 9be14361..2e903b5c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ the compatible browsers for a browsers query. ## Development -Can I Use + To run a local copy for development: 1. Install correct versions of Node.js and pnpm. There are two ways: @@ -36,8 +36,8 @@ To run a local copy for development: ``` - Server production mode - ``` - pnpm production + ```sh + pnpm ssdeploy run ``` We recommend to install Prettier and EditorConfig plugins to your text editor. diff --git a/client/package.json b/client/package.json index bf8dfd1b..a42b90a6 100644 --- a/client/package.json +++ b/client/package.json @@ -17,7 +17,7 @@ "postcss-media-minmax": "^5.0.0", "postcss-nesting": "^10.1.10", "postcss-opacity-percentage": "^1.1.2", - "vite": "^3.0.6", + "vite": "^3.0.7", "vite-plugin-pug-transformer": "^1.0.2" }, "devDependencies": { diff --git a/package.json b/package.json index 079008e6..266d8569 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ "lint": "eslint . && stylelint **/*.css", "test": "pnpm audit --prod && pnpm lint && pnpm -r test" }, + "dependencies": { + "ssdeploy": "^0.9.1" + }, "devDependencies": { "@logux/eslint-config": "^47.2.0", "@logux/stylelint-config": "^0.10.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index feec8bea..8a042e2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,9 +20,12 @@ importers: nano-staged: ^0.8.0 prettier: ^2.7.1 simple-git-hooks: ^2.8.0 + ssdeploy: ^0.9.1 stylelint: ^14.10.0 svgo: ^2.8.0 typescript: ^4.7.4 + dependencies: + ssdeploy: 0.9.1 devDependencies: '@logux/eslint-config': 47.2.0_7hz3xvmviof7onfgk6hpedqcom '@logux/stylelint-config': 0.10.1_stylelint@14.10.0 @@ -53,7 +56,7 @@ importers: postcss-nesting: ^10.1.10 postcss-opacity-percentage: ^1.1.2 size-limit: ^8.0.1 - vite: ^3.0.6 + vite: ^3.0.7 vite-plugin-pug-transformer: ^1.0.2 dependencies: '@csstools/postcss-oklab-function': 1.1.1_postcss@8.4.16 @@ -63,8 +66,8 @@ importers: postcss-media-minmax: 5.0.0_postcss@8.4.16 postcss-nesting: 10.1.10_postcss@8.4.16 postcss-opacity-percentage: 1.1.2 - vite: 3.0.6 - vite-plugin-pug-transformer: 1.0.2_vite@3.0.6 + vite: 3.0.7 + vite-plugin-pug-transformer: 1.0.2_vite@3.0.7 devDependencies: '@size-limit/file': 8.0.1_size-limit@8.0.1 caniuse-lite: 1.0.30001375 @@ -547,7 +550,6 @@ packages: /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true /balanced-match/2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} @@ -569,6 +571,12 @@ packages: concat-map: 0.0.1 dev: true + /brace-expansion/2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + /braces/3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -598,6 +606,11 @@ packages: engines: {node: '>= 0.8'} dev: true + /bytes/3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: false + /call-bind/1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: @@ -801,7 +814,6 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true /decamelize-keys/1.1.0: resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} @@ -820,6 +832,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /define-lazy-prop/2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: false + /define-properties/1.1.4: resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} engines: {node: '>= 0.4'} @@ -880,6 +897,11 @@ packages: domhandler: 4.3.1 dev: true + /dotenv/16.0.1: + resolution: {integrity: sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==} + engines: {node: '>=12'} + dev: false + /electron-to-chromium/1.4.217: resolution: {integrity: sha512-iX8GbAMij7cOtJPZo02CClpaPMWjvN5meqXiJXkBgwvraNWTNH0Z7F9tkznI34JRPtWASoPM/xWamq3oNb49GA==} dev: false @@ -1508,6 +1530,18 @@ packages: resolution: {integrity: sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==} dev: true + /folder-hash/4.0.2: + resolution: {integrity: sha512-Iw9GCqdA+zHfDVvk90TSAV66jq0IwiZaPvPgUiW+DHRwnaPOeZomzlgutx9QclinsQGz/XcVIGlDEJbFhCV5wA==} + engines: {node: '>=10.10.0'} + hasBin: true + dependencies: + debug: 4.3.4 + graceful-fs: 4.2.10 + minimatch: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: false + /fraction.js/4.2.0: resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} dev: false @@ -1623,6 +1657,10 @@ packages: resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} dev: true + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: false + /grapheme-splitter/1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true @@ -1668,6 +1706,14 @@ packages: dependencies: function-bind: 1.1.1 + /hasha/5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + dev: false + /hosted-git-info/2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true @@ -1778,6 +1824,12 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: false + /is-expression/4.0.0: resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} dependencies: @@ -1846,6 +1898,11 @@ packages: call-bind: 1.0.2 dev: true + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + /is-string/1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -1866,6 +1923,13 @@ packages: call-bind: 1.0.2 dev: true + /is-wsl/2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: false + /isexe/2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -2058,6 +2122,13 @@ packages: brace-expansion: 1.1.11 dev: true + /minimatch/5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: false + /minimist-options/4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -2083,7 +2154,6 @@ packages: /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2190,6 +2260,15 @@ packages: wrappy: 1.0.2 dev: true + /open/8.4.0: + resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: false + /optionator/0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} @@ -2678,6 +2757,21 @@ packages: resolution: {integrity: sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==} dev: true + /ssdeploy/0.9.1: + resolution: {integrity: sha512-4jfgSGlpKGBLQcva72Vo33CSW9VlHmEaAZ4WV8hgTEL8mnOsdxOYYZlxq2+hwtHrmPVdML4A0cOHAy6bmhGI9w==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + bytes: 3.1.2 + dotenv: 16.0.1 + folder-hash: 4.0.2 + hasha: 5.2.2 + open: 8.4.0 + picocolors: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false + /stable/0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' @@ -2947,7 +3041,6 @@ packages: /type-fest/0.8.1: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - dev: true /typescript/4.7.4: resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} @@ -2999,7 +3092,7 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-plugin-pug-transformer/1.0.2_vite@3.0.6: + /vite-plugin-pug-transformer/1.0.2_vite@3.0.7: resolution: {integrity: sha512-RtXEYaEgQoy5ttNjuuNMWRzZwfJz+cjePSdQzmNJTteIzUamVb8xvAlwNouMt189V2mk6HxyfTGfAGKUQ6KGig==} engines: {node: '>=12.22.0'} peerDependencies: @@ -3007,11 +3100,11 @@ packages: dependencies: picocolors: 1.0.0 pug: 3.0.2 - vite: 3.0.6 + vite: 3.0.7 dev: false - /vite/3.0.6: - resolution: {integrity: sha512-pjfsWIzfUlQME/VAmU6SsjdHkTt6WAHysuqPkHDcjzNu6IGtxDSZ/VfRYOwHaCqX4M3Ivz0kxuSfAPM6gAIX+w==} + /vite/3.0.7: + resolution: {integrity: sha512-dILhvKba1mbP1wCezVQx/qhEK7/+jVn9ciadEcyKMMhZpsuAi/eWZfJRMkmYlkSFG7Qq9NvJbgFq4XOBxugJsA==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: From d02576c2030bf8b4bb2ef48bf7a0c4c4cca97369 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:46:06 +0200 Subject: [PATCH 06/13] Fix CI --- .github/workflows/{preview.yml => ci.yml} | 39 ++++++++++++++++++++-- .github/workflows/test.yml | 40 ----------------------- 2 files changed, 37 insertions(+), 42 deletions(-) rename .github/workflows/{preview.yml => ci.yml} (68%) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/preview.yml b/.github/workflows/ci.yml similarity index 68% rename from .github/workflows/preview.yml rename to .github/workflows/ci.yml index d84bb319..81bf463b 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,44 @@ -name: Preview +name: CI on: + push: + branches: + - main pull_request: env: FORCE_COLOR: 2 jobs: + + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Install asdf tools + if: steps.asdf-cache.outputs.cache-hit != 'true' + uses: asdf-vm/actions/install@v1 + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + - name: Build regions data for the client + run: pnpm -r build:regions + - name: Run tests + run: pnpm test + preview: runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' @@ -39,7 +74,7 @@ jobs: - name: Install production dependencies run: pnpm install --prod --frozen-lockfile --ignore-scripts - name: Build static files - run: npm build + run: pnpm build - name: Auth Google Cloud uses: google-github-actions/auth@v0 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 3490ab05..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: CI -on: - push: - branches: - - main - pull_request: -jobs: - - test: - name: Test - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - name: Install asdf - uses: asdf-vm/actions/setup@v1 - - name: Cache asdf - id: asdf-cache - uses: actions/cache@v3 - with: - path: ~/.asdf - key: asdf-${{ hashFiles('**/.tool-versions') }} - - name: Install asdf tools - if: steps.asdf-cache.outputs.cache-hit != 'true' - uses: asdf-vm/actions/install@v1 - - name: Cache pnpm modules - uses: actions/cache@v3 - env: - cache-name: cache-pnpm-modules - with: - path: ~/.local/share/pnpm/ - key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install dependencies - run: pnpm install --frozen-lockfile --ignore-scripts - - name: Build regions data for the client - run: pnpm -r build:regions - - name: Run tests - run: pnpm test - env: - FORCE_COLOR: 2 From c921643358e82ffd84fe369984ac5c804e0f9d4b Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:48:25 +0200 Subject: [PATCH 07/13] Fix regions on preview --- .github/workflows/ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81bf463b..ae6f2152 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,12 +34,13 @@ jobs: key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} - name: Install dependencies run: pnpm install --frozen-lockfile --ignore-scripts - - name: Build regions data for the client + - name: Build regions run: pnpm -r build:regions - name: Run tests run: pnpm test preview: + name: Preview runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' steps: @@ -73,6 +74,8 @@ jobs: key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} - name: Install production dependencies run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Build regions + run: pnpm -r build:regions - name: Build static files run: pnpm build - name: Auth Google Cloud @@ -92,6 +95,7 @@ jobs: CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} - name: Update deployment status uses: bobheadxi/deployments@v1 + if: always() with: step: finish token: ${{ secrets.GITHUB_TOKEN }} From 6caec11d2d734e299ae0bbf936f01139f3895ea3 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:52:33 +0200 Subject: [PATCH 08/13] Try to fix region build --- client/scripts/build-regions.js | 2 +- server/lib/get-browsers.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/scripts/build-regions.js b/client/scripts/build-regions.js index dd512fd8..b0420753 100644 --- a/client/scripts/build-regions.js +++ b/client/scripts/build-regions.js @@ -1,7 +1,7 @@ import fs from 'fs' const DATA_REGION_FILE = 'data/regions.json' -const REGIONS_LIST_PATH = 'node_modules/caniuse-lite/data/regions' +const REGIONS_LIST_PATH = './node_modules/caniuse-lite/data/regions' const regions = { continents: { diff --git a/server/lib/get-browsers.js b/server/lib/get-browsers.js index 84b253fe..27d53cb5 100644 --- a/server/lib/get-browsers.js +++ b/server/lib/get-browsers.js @@ -115,7 +115,7 @@ async function getRegionCoverage(id, version, region) { } let { default: regionData } = await import( - `../node_modules/caniuse-lite/data/regions/${region}.js` + `caniuse-lite/data/regions/${region}.js` ) return getCoverage(caniuseRegion(regionData)[id], version) } catch (e) { From 402a21c1c69a3af4d5b6c760713551261fe33289 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:58:35 +0200 Subject: [PATCH 09/13] Fix client dependencies --- client/package.json | 2 +- pnpm-lock.yaml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/package.json b/client/package.json index a42b90a6..14946161 100644 --- a/client/package.json +++ b/client/package.json @@ -12,6 +12,7 @@ "dependencies": { "@csstools/postcss-oklab-function": "^1.1.1", "autoprefixer": "^10.4.8", + "caniuse-lite": "^1.0.30001375", "jstransformer-markdown-it": "^3.0.0", "postcss": "^8.4.16", "postcss-media-minmax": "^5.0.0", @@ -22,7 +23,6 @@ }, "devDependencies": { "@size-limit/file": "^8.0.1", - "caniuse-lite": "^1.0.30001375", "size-limit": "^8.0.1" }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a042e2f..0c7d81ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,6 +61,7 @@ importers: dependencies: '@csstools/postcss-oklab-function': 1.1.1_postcss@8.4.16 autoprefixer: 10.4.8_postcss@8.4.16 + caniuse-lite: 1.0.30001375 jstransformer-markdown-it: 3.0.0 postcss: 8.4.16 postcss-media-minmax: 5.0.0_postcss@8.4.16 @@ -70,7 +71,6 @@ importers: vite-plugin-pug-transformer: 1.0.2_vite@3.0.7 devDependencies: '@size-limit/file': 8.0.1_size-limit@8.0.1 - caniuse-lite: 1.0.30001375 size-limit: 8.0.1 server: @@ -638,6 +638,7 @@ packages: /caniuse-lite/1.0.30001375: resolution: {integrity: sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==} + dev: false /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} From 761154f877fb15c98195af755641fbebcfdecb06 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 02:58:38 +0200 Subject: [PATCH 10/13] Fix imports --- client/scripts/build-regions.js | 8 +++----- server/lib/get-file-data.js | 10 +++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/client/scripts/build-regions.js b/client/scripts/build-regions.js index b0420753..4e7e4bff 100644 --- a/client/scripts/build-regions.js +++ b/client/scripts/build-regions.js @@ -1,4 +1,4 @@ -import fs from 'fs' +import { writeFileSync, readdirSync } from 'node:fs' const DATA_REGION_FILE = 'data/regions.json' const REGIONS_LIST_PATH = './node_modules/caniuse-lite/data/regions' @@ -17,15 +17,13 @@ const regions = { countryCodes: getCaniuseCountries() } -fs.writeFileSync(DATA_REGION_FILE, JSON.stringify(regions)) +writeFileSync(DATA_REGION_FILE, JSON.stringify(regions)) process.stdout.write( `A file "client/${DATA_REGION_FILE}" with regions has been created\n` ) function getCaniuseCountries() { - let regionCodes = fs - .readdirSync(REGIONS_LIST_PATH) - .map(file => file.split('.js')[0]) + let regionCodes = readdirSync(REGIONS_LIST_PATH).map(f => f.split('.js')[0]) return regionCodes .filter(regionCode => { diff --git a/server/lib/get-file-data.js b/server/lib/get-file-data.js index 4e701b1a..d9460433 100644 --- a/server/lib/get-file-data.js +++ b/server/lib/get-file-data.js @@ -1,6 +1,6 @@ -import path from 'node:path' -import fs from 'node:fs/promises' +import { readFile, stat } from 'node:fs/promises' import { existsSync } from 'node:fs' +import { parse } from 'node:path' const IS_PRODUCTION = process.env.NODE_ENV === 'production' const CACHE = {} @@ -18,9 +18,9 @@ export default async function getFileData(filePath, shouldBeCached = false) { throw error } - let { name, ext } = path.parse(filePath.pathname) - let { size } = await fs.stat(filePath) - let data = await fs.readFile(filePath) + let { name, ext } = parse(filePath.pathname) + let { size } = await stat(filePath) + let data = await readFile(filePath) let fileData = { name, From 772f1fcefdf6c228cc2883b531954deaee0e813b Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 03:04:01 +0200 Subject: [PATCH 11/13] Add deploy script --- .github/workflows/ci.yml | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae6f2152..cf14f53c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,66 @@ jobs: - name: Run tests run: pnpm test + deploy: + name: Deploy + runs-on: ubuntu-latest + if: github.ref -== 'refs/heads/main' + steps: + - name: Notify about new deployment + uses: bobheadxi/deployments@v1 + id: deployment + with: + step: start + token: ${{ secrets.GITHUB_TOKEN }} + env: production + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install production dependencies + run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Build regions + run: pnpm -r build:regions + - name: Build static files + run: pnpm build + - name: Auth Google Cloud + uses: google-github-actions/auth@v0 + with: + credentials_json: ${{ secrets.GCLOUD_AUTH }} + - name: Install Google Cloud + uses: google-github-actions/setup-gcloud@v0 + - name: Deploy files + id: deploy + run: ./node_modules/.bin/ssdeploy deploy --verbose + env: + GCLOUD_APP: ${{ secrets.GCLOUD_APP }} + GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} + - name: Update deployment status + uses: bobheadxi/deployments@v1 + if: always() + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ job.status }} + env: ${{ steps.deployment.outputs.env }} + env_url: ${{ steps.deploy.outputs.url }} + deployment_id: ${{ steps.deployment.outputs.deployment_id }} + preview: name: Preview runs-on: ubuntu-latest From 67ae63d13379fcc246aa2add54792ecd77b97750 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 03:04:44 +0200 Subject: [PATCH 12/13] Typo --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf14f53c..0ee30b10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: deploy: name: Deploy runs-on: ubuntu-latest - if: github.ref -== 'refs/heads/main' + if: github.ref == 'refs/heads/main' steps: - name: Notify about new deployment uses: bobheadxi/deployments@v1 From 196250b9c65ecf1073f04f931c4675c574922f0a Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 13 Aug 2022 03:08:18 +0200 Subject: [PATCH 13/13] Simplify API url --- client/view/Form/form.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/view/Form/form.js b/client/view/Form/form.js index 8dc57b72..eec7012a 100644 --- a/client/view/Form/form.js +++ b/client/view/Form/form.js @@ -7,8 +7,6 @@ import { showStats } from '../BrowserStats/browserStats.js' -const API_HOST = 'http://localhost:5000/api/' - const form = document.querySelector('[data-id=query_form]') const textarea = document.querySelector('[data-id=query_text_area]') const regionCoverage = document.querySelector('[data-id=region_coverage]') @@ -134,8 +132,7 @@ async function updateStatsView(query, region) { try { form.classList.add('Form--loaded') let urlParams = new URLSearchParams({ q: query, region }) - let url = new URL(`browsers?${urlParams}`, `${API_HOST}`) - response = await fetch(url) + response = await fetch(`/api/browsers?${urlParams}`) } catch (error) { renderError(`Network error. Check that you are online.`) form.classList.remove('Form--loaded')