diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml new file mode 100644 index 0000000..a1e59a8 --- /dev/null +++ b/.forgejo/workflows/build.yaml @@ -0,0 +1,121 @@ +on: [push] +jobs: + check-changes: + runs-on: docker + outputs: + all_changed_and_modified_files_count: ${{ steps.changed-files.outputs.all_changed_and_modified_files_count }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get changed files count + id: changed-files + uses: tj-actions/changed-files@v45 + with: + files_ignore: 'doc/**,README.md,Dockerfile,.*' + files_ignore_separator: ',' + - name: Print changed files count + run: > + echo "Changed files count: ${{ + steps.changed-files.outputs.all_changed_and_modified_files_count }}" + + build: + needs: check-changes + runs-on: docker + container: + image: ghcr.io/catthehacker/ubuntu:js-22.04 + if: ${{ needs.check-changes.outputs.all_changed_and_modified_files_count >= 1 }} + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: yarn + cache-dependency-path: '**/yarn.lock' + - uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/node_modules + key: ${{ runner.os }}-pio + - uses: actions/setup-python@v5 + with: + python-version: '>=3.10' + - name: Get current date + id: dateAndTime + run: echo "dateAndTime=$(date +'%Y-%m-%d-%H:%M')" >> $GITHUB_OUTPUT + - name: Install mklittlefs + run: > + git clone https://github.com/earlephilhower/mklittlefs.git /tmp/mklittlefs && + cd /tmp/mklittlefs && + git submodule update --init && + make dist + - name: Install yarn + run: yarn && yarn postinstall + - name: Run linter + run: yarn lint + - name: Run vitest tests + run: yarn vitest run + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - name: Build WebUI + run: yarn build + - name: Get current block + id: getBlockHeight + run: echo "blockHeight=$(curl -s https://mempool.space/api/blocks/tip/height)" >> $GITHUB_OUTPUT + - name: Write block height to file + env: + BLOCK_HEIGHT: ${{ steps.getBlockHeight.outputs.blockHeight }} + run: mkdir -p output && echo "$BLOCK_HEIGHT" > output/version.txt + - name: gzip build for LittleFS + run: find dist -type f ! -name ".*" -exec sh -c 'mkdir -p "build_gz/$(dirname "${1#dist/}")" && gzip -k "$1" -c > "build_gz/${1#dist/}".gz' _ {} \; + - name: Write git rev to file + run: echo "$GITHUB_SHA" > build_gz/fs_hash.txt && echo "$GITHUB_SHA" > output/commit.txt + - name: Check GZipped directory size + run: | + # Set the threshold size in bytes + THRESHOLD=410000 + + # Calculate the total size of files in the directory + DIRECTORY_SIZE=$(du -b -s build_gz | awk '{print $1}') + + # Fail the workflow if the size exceeds the threshold + if [ "$DIRECTORY_SIZE" -gt "$THRESHOLD" ]; then + echo "Directory size exceeds the threshold of $THRESHOLD bytes" + exit 1 + else + echo "Directory size is within the threshold $DIRECTORY_SIZE" + fi + - name: Create tarball + run: tar czf webui.tgz --strip-components=1 dist + - name: Build LittleFS + run: | + set -e + /tmp/mklittlefs/mklittlefs -c build_gz -s 410000 output/littlefs.bin + - name: Upload artifacts + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + with: + path: | + webui.tgz + output/littlefs.bin + - name: Create release + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 + with: + url: 'https://git.btclock.dev/' + repo: '${{ github.repository }}' + direction: upload + tag: ${{ steps.getBlockHeight.outputs.blockHeight }} + sha: '${{ github.sha }}' + release-dir: output + token: ${{ secrets.TOKEN }} + override: false + verbose: false + release-notes-assistant: false diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a5ca2ac..c44914e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,6 @@ updates: schedule: interval: 'daily' versioning-strategy: 'increase-if-necessary' + ignore: + - dependency-name: '*' + update-types: ['version-update:semver-major'] diff --git a/README.md b/README.md index 805bfa1..1e9dd3c 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,11 @@ Make sure the postinstall script is ran, because otherwise the filenames are to ## Deploying -To upload the firmware to the BTClock, you need to GZIP all the files. You can use the python script `gzip_build.py` for that. +To upload the firmware to the BTClock, you need to GZIP all the files. You can use the python script `gzip_build.py` for that: + +```bash +python3 gzip_build.py +``` Then you can make a `LittleFS.bin` with mklittlefs: diff --git a/package.json b/package.json index b84537e..44cc323 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "postinstall": "patch-package", "test": "npm run test:integration && npm run test:unit", "test:integration": "playwright test", + "test:screenshots": "playwright test -c playwright.screenshot.config.ts", "test:unit": "vitest" }, "devDependencies": { @@ -23,41 +24,43 @@ "@sveltejs/vite-plugin-svelte": "^3.0.1", "@testing-library/svelte": "^5.2.1", "@types/swagger-ui": "^3.52.4", - "@typescript-eslint/eslint-plugin": "^8.4.0", - "@typescript-eslint/parser": "^8.4.0", - "@vitest/ui": "^0.34.6", - "eslint": "^9.0.0", + "@typescript-eslint/eslint-plugin": "^8.7.0", + "@typescript-eslint/parser": "^8.7.0", + "@vitest/ui": "^2.0.5", + "eslint": "^9.11.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.36.0", "jsdom": "^25.0.0", - "prettier": "^3.1.1", - "prettier-plugin-svelte": "^3.1.2", - "sass": "^1.69.5", - "svelte": "^4.2.7", - "svelte-check": "^3.6.0", - "svelte-preprocess": "^5.1.1", - "tslib": "^2.4.1", + "prettier": "^3.3.3", + "prettier-plugin-svelte": "^3.2.6", + "sass": "^1.79.3", + "svelte": "^4.2.19", + "svelte-check": "^4.0.2", + "svelte-preprocess": "^6.0.2", + "tslib": "^2.7.0", "typescript": "^5.5.4", - "typescript-eslint": "^8.0.0", - "vite": "^5.4.2", - "vitest": "^2.0.5", + "typescript-eslint": "^8.7.0", + "vite": "^5.4.7", + "vitest": "^2.1.1", "vitest-github-actions-reporter": "^0.11.0" }, "type": "module", "dependencies": { - "@fontsource/antonio": "^5.0.17", - "@fontsource/oswald": "^5.0.17", - "@fontsource/ubuntu": "^5.0.8", + "@fontsource/antonio": "^5.1.0", + "@fontsource/oswald": "^5.1.0", + "@fontsource/ubuntu": "^5.1.0", "@noble/secp256k1": "^2.1.0", "@playwright/test": "^1.46.0", + "@popperjs/core": "^2.11.8", "@sveltestrap/sveltestrap": "^6.2.7", "@testing-library/jest-dom": "^6.5.0", - "bootstrap": "^5.3.2", + "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", + "msgpack-es": "^0.0.5", "nostr-tools": "^2.7.1", "patch-package": "^8.0.0", - "svelte-i18n": "^4.0.0", - "swagger-ui": "^5.10.0" + "svelte-bootstrap-icons": "^3.1.1", + "svelte-i18n": "^4.0.0" }, "resolutions": { "es5-ext": ">=0.10.64", diff --git a/patches/@sveltejs+kit+2.5.25.patch b/patches/@sveltejs+kit+2.7.5.patch similarity index 90% rename from patches/@sveltejs+kit+2.5.25.patch rename to patches/@sveltejs+kit+2.7.5.patch index 190b51f..e25e1e5 100644 --- a/patches/@sveltejs+kit+2.5.25.patch +++ b/patches/@sveltejs+kit+2.7.5.patch @@ -1,8 +1,8 @@ diff --git a/node_modules/@sveltejs/kit/src/exports/vite/index.js b/node_modules/@sveltejs/kit/src/exports/vite/index.js -index 2280025..cfbcfa9 100644 +index 40fa4c6..738cabf 100644 --- a/node_modules/@sveltejs/kit/src/exports/vite/index.js +++ b/node_modules/@sveltejs/kit/src/exports/vite/index.js -@@ -621,9 +621,9 @@ async function kit({ svelte_config }) { +@@ -655,9 +655,9 @@ async function kit({ svelte_config }) { input, output: { format: 'esm', diff --git a/patches/@sveltejs+kit+2.8.5.patch b/patches/@sveltejs+kit+2.8.5.patch new file mode 100644 index 0000000..80f5dba --- /dev/null +++ b/patches/@sveltejs+kit+2.8.5.patch @@ -0,0 +1,17 @@ +diff --git a/node_modules/@sveltejs/kit/src/exports/vite/index.js b/node_modules/@sveltejs/kit/src/exports/vite/index.js +index e6521e9..f31c28b 100644 +--- a/node_modules/@sveltejs/kit/src/exports/vite/index.js ++++ b/node_modules/@sveltejs/kit/src/exports/vite/index.js +@@ -639,9 +639,9 @@ async function kit({ svelte_config }) { + input, + output: { + format: 'esm', +- entryFileNames: ssr ? '[name].js' : `${prefix}/[name].[hash].${ext}`, +- chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name].[hash].${ext}`, +- assetFileNames: `${prefix}/assets/[name].[hash][extname]`, ++ entryFileNames: ssr ? '[name].js' : `${prefix}/[hash].${ext}`, ++ chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[hash].${ext}`, ++ assetFileNames: `${prefix}/assets/[hash][extname]`, + hoistTransitiveImports: false, + sourcemapIgnoreList + }, diff --git a/playwright.config.ts b/playwright.config.ts index d60d61c..bf148ce 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -10,7 +10,7 @@ const config: PlaywrightTestConfig = { port: 4173 }, reporter: process.env.CI ? 'github' : 'list', - testDir: 'tests', + testDir: 'tests/playwright', testMatch: /(.+\.)?(test|spec)\.[jt]s/ }; diff --git a/playwright.screenshot.config.ts b/playwright.screenshot.config.ts new file mode 100644 index 0000000..81264a4 --- /dev/null +++ b/playwright.screenshot.config.ts @@ -0,0 +1,51 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + reporter: 'html', + use: { + locale: 'en-GB', + timezoneId: 'Europe/Amsterdam' + }, + webServer: { + command: 'npm run build && npm run preview', + port: 4173 + }, + testDir: './tests/screenshots', + outputDir: './test-results/screenshots', + projects: [ + { + name: 'MacBook Air 13 inch', + use: { + viewport: { width: 1440, height: 900 } + } + }, + { + name: 'iPhone 14 Pro', + use: { ...devices['iPhone 14 Pro'] } + }, + { + name: 'iPhone 15 Pro Landscape', + use: { ...devices['iPhone 15 Pro Landscape'] } + }, + { + name: 'MacBook Pro 14 inch', + use: { + viewport: { width: 1512, height: 982 } + } + }, + { + name: 'MacBook Pro 14 inch', + use: { + viewport: { width: 1512, height: 982 } + } + }, + { + name: 'MacBook Pro 14 inch Firefox HiDPI', + use: { ...devices['Desktop Firefox HiDPI'], viewport: { width: 1512, height: 982 } } + }, + { + name: 'MacBook Pro 14 inch Safari', + use: { ...devices['Desktop Safari'], viewport: { width: 1512, height: 982 } } + } + ] +}); diff --git a/src/components/ColorSchemeSwitcher.svelte b/src/components/ColorSchemeSwitcher.svelte new file mode 100644 index 0000000..9d7e32a --- /dev/null +++ b/src/components/ColorSchemeSwitcher.svelte @@ -0,0 +1,53 @@ + + + + + {theme === 'auto' ? '🌗' : theme === 'dark' ? '🌙' : '☀️'} + + + setTheme('light')} + >☀️ Light + setTheme('dark')}>🌙 Dark + setTheme('auto')}>🌗 Auto + + diff --git a/src/components/ToggleHeader.svelte b/src/components/ToggleHeader.svelte new file mode 100644 index 0000000..acc8d3b --- /dev/null +++ b/src/components/ToggleHeader.svelte @@ -0,0 +1,28 @@ + + +