diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b60fa2d..16c6886 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,11 +2,31 @@ name: ci on: pull_request: - types: [opened, reopened, synchronize, edited] + types: [opened, reopened, synchronize] workflow_call: workflow_dispatch: jobs: + checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + run_install: false + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "pnpm" + - name: Install dependencies + run: pnpm install + - name: Astro check + run: pnpm astro check + - name: Prettier check + run: pnpm exec prettier --check . build-test: runs-on: ubuntu-latest steps: diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 0000000..31354ec --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..06485b2 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +npx lint-staged +pnpm astro check diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 2ee8aa9..cc7f2c1 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -11,8 +11,11 @@ For basic installation of backend repo see [backend repo](https://github.com/gat 1. Clone this repo 2. Make sure you have the correct node version installed (`nvm use` then `nvm install`) 3. Run `pnpm install` -4. Run `pnpm dev` -5. Frontend should now be available on `localhost:4321` serving content from `https://dev.tg.no` +4. Run `pnpm prepare` # Setup Husky for pre-commit +5. Run `pnpm dev` +6. Frontend should now be available on `localhost:4321` serving content from `https://dev.tg.no` + +We use [husky](https://typicode.github.io/husky/) pre-commit for making sure all code conforms to the same formatting. This happens automatically on commit after this first time setup, if it doesn't work try a fresh `pnpm install` ## Using local backend @@ -24,7 +27,7 @@ Same procedure as above, but with a few extra steps: ## Using production backend -Identical to using local backend section above, but use `https://prod.tg.no/`/`https://tg.no/` instead of `http://localhost:8000/` +Identical to using local backend section above, but use `https://www.tg.no/` instead of `http://localhost:8000/` ## Common issues diff --git a/Dockerfile b/Dockerfile index 7cf33d9..e4bf6a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,8 @@ ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable COPY package.json pnpm-lock.yaml /app/ WORKDIR /app -RUN pnpm install --prod +# --ignore-scripts is used to prevent https://github.com/pnpm/pnpm/issues/7068 +RUN pnpm install --prod --ignore-scripts COPY . /app RUN pnpm build diff --git a/package.json b/package.json index c7b66ef..4c015c3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "start": "astro dev", "build": "astro check && export $(grep -v '^\\s*$\\|^\\s*\\#' .env.runtime) && astro build", "preview": "astro preview", - "astro": "astro" + "astro": "astro", + "prepare": "husky" }, "dependencies": { "@astrojs/check": "^0.9.4", @@ -22,7 +23,12 @@ }, "devDependencies": { "@types/dompurify": "^3.0.5", + "husky": ">=7", + "lint-staged": ">=10", "prettier": "^3.3.3", "prettier-plugin-astro": "^0.14.1" + }, + "lint-staged": { + "*.{js,ts,mjs,css,md,astro,yaml,json}": "prettier --write" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09eca2a..13acad9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,12 @@ importers: "@types/dompurify": specifier: ^3.0.5 version: 3.0.5 + husky: + specifier: ">=7" + version: 9.1.6 + lint-staged: + specifier: ">=10" + version: 15.2.10 prettier: specifier: ^3.3.3 version: 3.3.3 @@ -1129,6 +1135,13 @@ packages: integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==, } + ansi-escapes@7.0.0: + resolution: + { + integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==, + } + engines: { node: ">=18" } + ansi-regex@5.0.1: resolution: { @@ -1393,6 +1406,13 @@ packages: } engines: { node: ">=6" } + cli-truncate@4.0.0: + resolution: + { + integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==, + } + engines: { node: ">=18" } + cliui@8.0.1: resolution: { @@ -1445,6 +1465,12 @@ packages: } engines: { node: ">=12.5.0" } + colorette@2.0.20: + resolution: + { + integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, + } + combined-stream@1.0.8: resolution: { @@ -1458,6 +1484,13 @@ packages: integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, } + commander@12.1.0: + resolution: + { + integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==, + } + engines: { node: ">=18" } + commander@4.1.1: resolution: { @@ -1690,6 +1723,13 @@ packages: } engines: { node: ">=0.12" } + environment@1.1.0: + resolution: + { + integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==, + } + engines: { node: ">=18" } + es-module-lexer@1.5.4: resolution: { @@ -1764,6 +1804,13 @@ packages: integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==, } + execa@8.0.1: + resolution: + { + integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==, + } + engines: { node: ">=16.17" } + extend-shallow@2.0.1: resolution: { @@ -1898,6 +1945,13 @@ packages: } engines: { node: ">=18" } + get-stream@8.0.1: + resolution: + { + integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==, + } + engines: { node: ">=16" } + github-slugger@2.0.0: resolution: { @@ -2065,6 +2119,21 @@ packages: } engines: { node: ">= 14" } + human-signals@5.0.0: + resolution: + { + integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==, + } + engines: { node: ">=16.17.0" } + + husky@9.1.6: + resolution: + { + integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==, + } + engines: { node: ">=18" } + hasBin: true + iconv-lite@0.6.3: resolution: { @@ -2133,6 +2202,20 @@ packages: } engines: { node: ">=8" } + is-fullwidth-code-point@4.0.0: + resolution: + { + integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==, + } + engines: { node: ">=12" } + + is-fullwidth-code-point@5.0.0: + resolution: + { + integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==, + } + engines: { node: ">=18" } + is-glob@4.0.3: resolution: { @@ -2175,6 +2258,13 @@ packages: integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, } + is-stream@3.0.0: + resolution: + { + integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + is-unicode-supported@1.3.0: resolution: { @@ -2322,6 +2412,21 @@ packages: integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, } + lint-staged@15.2.10: + resolution: + { + integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==, + } + engines: { node: ">=18.12.0" } + hasBin: true + + listr2@8.2.5: + resolution: + { + integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==, + } + engines: { node: ">=18.0.0" } + load-yaml-file@0.2.0: resolution: { @@ -2367,6 +2472,13 @@ packages: } engines: { node: ">=18" } + log-update@6.1.0: + resolution: + { + integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==, + } + engines: { node: ">=18" } + longest-streak@3.1.0: resolution: { @@ -2481,6 +2593,12 @@ packages: integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==, } + merge-stream@2.0.0: + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } + merge2@1.4.1: resolution: { @@ -2685,6 +2803,13 @@ packages: engines: { node: ">=4" } hasBin: true + mimic-fn@4.0.0: + resolution: + { + integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, + } + engines: { node: ">=12" } + mimic-function@5.0.1: resolution: { @@ -2778,6 +2903,13 @@ packages: } engines: { node: ">=0.10.0" } + npm-run-path@5.3.0: + resolution: + { + integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + nwsapi@2.2.13: resolution: { @@ -2805,6 +2937,13 @@ packages: } engines: { node: ">= 0.8" } + onetime@6.0.0: + resolution: + { + integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, + } + engines: { node: ">=12" } + onetime@7.0.0: resolution: { @@ -2905,6 +3044,13 @@ packages: } engines: { node: ">=8" } + path-key@4.0.0: + resolution: + { + integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, + } + engines: { node: ">=12" } + path-parse@1.0.7: resolution: { @@ -2931,6 +3077,14 @@ packages: } engines: { node: ">=8.6" } + pidtree@0.6.0: + resolution: + { + integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==, + } + engines: { node: ">=0.10" } + hasBin: true + pify@2.3.0: resolution: { @@ -3250,6 +3404,12 @@ packages: } engines: { iojs: ">=1.0.0", node: ">=0.10.0" } + rfdc@1.4.1: + resolution: + { + integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, + } + rollup@4.24.0: resolution: { @@ -3382,6 +3542,20 @@ packages: integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, } + slice-ansi@5.0.0: + resolution: + { + integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==, + } + engines: { node: ">=12" } + + slice-ansi@7.1.0: + resolution: + { + integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==, + } + engines: { node: ">=18" } + source-map-js@1.2.1: resolution: { @@ -3415,6 +3589,13 @@ packages: } engines: { node: ">=18" } + string-argv@0.3.2: + resolution: + { + integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==, + } + engines: { node: ">=0.6.19" } + string-width@4.2.3: resolution: { @@ -3470,6 +3651,13 @@ packages: } engines: { node: ">=4" } + strip-final-newline@3.0.0: + resolution: + { + integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, + } + engines: { node: ">=12" } + sucrase@3.35.0: resolution: { @@ -4838,6 +5026,10 @@ snapshots: dependencies: string-width: 4.2.3 + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} @@ -5048,6 +5240,11 @@ snapshots: cli-spinners@2.9.2: {} + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -5080,12 +5277,16 @@ snapshots: color-string: 1.9.1 optional: true + colorette@2.0.20: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 comma-separated-tokens@2.0.3: {} + commander@12.1.0: {} + commander@4.1.1: {} common-ancestor-path@1.0.1: {} @@ -5177,6 +5378,8 @@ snapshots: entities@4.5.0: {} + environment@1.1.0: {} + es-module-lexer@1.5.4: {} esbuild@0.21.5: @@ -5225,6 +5428,18 @@ snapshots: eventemitter3@5.0.1: {} + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + extend-shallow@2.0.1: dependencies: is-extendable: 0.1.1 @@ -5291,6 +5506,8 @@ snapshots: get-east-asian-width@1.2.0: {} + get-stream@8.0.1: {} + github-slugger@2.0.0: {} glob-parent@5.1.2: @@ -5446,6 +5663,10 @@ snapshots: transitivePeerDependencies: - supports-color + human-signals@5.0.0: {} + + husky@9.1.6: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -5473,6 +5694,12 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -5489,6 +5716,8 @@ snapshots: is-potential-custom-element-name@1.0.1: {} + is-stream@3.0.0: {} + is-unicode-supported@1.3.0: {} is-unicode-supported@2.1.0: {} @@ -5568,6 +5797,30 @@ snapshots: lines-and-columns@1.2.4: {} + lint-staged@15.2.10: + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + debug: 4.3.7 + execa: 8.0.1 + lilconfig: 3.1.2 + listr2: 8.2.5 + micromatch: 4.0.8 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.5.1 + transitivePeerDependencies: + - supports-color + + listr2@8.2.5: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 + load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.11 @@ -5592,6 +5845,14 @@ snapshots: chalk: 5.3.0 is-unicode-supported: 1.3.0 + log-update@6.1.0: + dependencies: + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + longest-streak@3.1.0: {} lru-cache@10.4.3: {} @@ -5731,6 +5992,8 @@ snapshots: dependencies: "@types/mdast": 4.0.4 + merge-stream@2.0.0: {} + merge2@1.4.1: {} micromark-core-commonmark@2.0.1: @@ -5937,6 +6200,8 @@ snapshots: mime@1.6.0: {} + mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} minimatch@9.0.5: @@ -5973,6 +6238,10 @@ snapshots: normalize-range@0.1.2: {} + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + nwsapi@2.2.13: {} object-assign@4.1.1: {} @@ -5983,6 +6252,10 @@ snapshots: dependencies: ee-first: 1.1.1 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -6045,6 +6318,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -6056,6 +6331,8 @@ snapshots: picomatch@2.3.1: {} + pidtree@0.6.0: {} + pify@2.3.0: {} pify@4.0.1: {} @@ -6264,6 +6541,8 @@ snapshots: reusify@1.0.4: {} + rfdc@1.4.1: {} + rollup@4.24.0: dependencies: "@types/estree": 1.0.6 @@ -6386,6 +6665,16 @@ snapshots: sisteransi@1.0.5: {} + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + source-map-js@1.2.1: {} space-separated-tokens@2.0.2: {} @@ -6396,6 +6685,8 @@ snapshots: stdin-discarder@0.2.2: {} + string-argv@0.3.2: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -6431,6 +6722,8 @@ snapshots: strip-bom@3.0.0: {} + strip-final-newline@3.0.0: {} + sucrase@3.35.0: dependencies: "@jridgewell/gen-mapping": 0.3.5 diff --git a/tsconfig.json b/tsconfig.json index bcbf8b5..0845431 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,3 +1,5 @@ { - "extends": "astro/tsconfigs/strict" + "extends": "astro/tsconfigs/strict", + "include": ["**/*", ".astro/types.d.ts"], + "exclude": ["dist"] }