diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80167da..27ac4b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,18 @@ jobs: - name: Run tests run: npx vitest run + audit: + runs-on: runners-cartsnitch + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: npm + - run: npm ci + - name: Check for vulnerabilities + run: npm audit --audit-level=high + e2e: runs-on: runners-cartsnitch steps: @@ -87,6 +99,7 @@ jobs: build-and-push: runs-on: runners-cartsnitch + if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [lint, test, e2e] outputs: calver_tag: ${{ steps.calver.outputs.version }} @@ -112,6 +125,13 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "CalVer tag: $VERSION" + - name: Log in to Docker Hub + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Log in to GHCR if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: docker/login-action@v3 @@ -149,6 +169,7 @@ jobs: build-and-push-auth: runs-on: runners-cartsnitch + if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [lint, test, e2e] outputs: calver_tag: ${{ steps.calver.outputs.version }} @@ -173,6 +194,13 @@ jobs: fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Log in to Docker Hub + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Log in to GHCR if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: docker/login-action@v3 @@ -202,6 +230,7 @@ jobs: build-and-push-receiptwitness: runs-on: runners-cartsnitch + if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [lint, test] outputs: calver_tag: ${{ steps.calver.outputs.version }} @@ -221,6 +250,13 @@ jobs: else BUILD_NUM=$(echo "$EXISTING" | sed "s/v${DATE_TAG}\.//"); VERSION="${DATE_TAG}.$((BUILD_NUM + 1))"; fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Log in to Docker Hub + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Log in to GHCR if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: docker/login-action@v3 @@ -250,6 +286,7 @@ jobs: build-and-push-api: runs-on: runners-cartsnitch + if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [lint, test] outputs: calver_tag: ${{ steps.calver.outputs.version }} @@ -269,6 +306,13 @@ jobs: else BUILD_NUM=$(echo "$EXISTING" | sed "s/v${DATE_TAG}\.//"); VERSION="${DATE_TAG}.$((BUILD_NUM + 1))"; fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Log in to Docker Hub + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Log in to GHCR if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: docker/login-action@v3 @@ -299,7 +343,7 @@ jobs: deploy-dev: runs-on: runners-cartsnitch needs: [build-and-push, build-and-push-auth, build-and-push-receiptwitness, build-and-push-api] - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: always() && !cancelled() && github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - name: Generate GitHub App token id: app-token @@ -324,12 +368,28 @@ jobs: - name: Install kustomize uses: imranismail/setup-kustomize@v2 - - name: Update dev overlay image tags + - name: Update frontend image tag + if: needs.build-and-push.result == 'success' run: | cd infra/apps/overlays/dev kustomize edit set image ghcr.io/cartsnitch/cartsnitch:${{ needs.build-and-push.outputs.calver_tag }} + + - name: Update auth image tag + if: needs.build-and-push-auth.result == 'success' + run: | + cd infra/apps/overlays/dev kustomize edit set image ghcr.io/cartsnitch/auth:${{ needs.build-and-push-auth.outputs.calver_tag }} + + - name: Update receiptwitness image tag + if: needs.build-and-push-receiptwitness.result == 'success' + run: | + cd infra/apps/overlays/dev kustomize edit set image ghcr.io/cartsnitch/receiptwitness:${{ needs.build-and-push-receiptwitness.outputs.calver_tag }} + + - name: Update api image tag + if: needs.build-and-push-api.result == 'success' + run: | + cd infra/apps/overlays/dev kustomize edit set image ghcr.io/cartsnitch/api:${{ needs.build-and-push-api.outputs.calver_tag }} - name: Commit and push to infra diff --git a/package-lock.json b/package-lock.json index 0b14235..3083888 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@tanstack/react-query": "^5.0.0", "better-auth": "^1.2.0", + "picomatch": "4.0.4", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^7.0.0", @@ -25,7 +26,7 @@ "@types/node": "^24.12.0", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", - "@vitejs/plugin-react": "^4.5.2", + "@vitejs/plugin-react": "^4.7.0", "eslint": "^9.39.4", "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", @@ -6052,9 +6053,9 @@ } }, "node_modules/flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -8177,10 +8178,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "devOptional": true, + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" @@ -8338,16 +8338,6 @@ "node": ">=6" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -8754,27 +8744,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -8850,13 +8819,13 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "dev": true, "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" + "engines": { + "node": ">=20.0.0" } }, "node_modules/set-cookie-parser": { @@ -10446,31 +10415,6 @@ "rollup": "^1.20.0 || ^2.0.0" } }, - "node_modules/workbox-build/node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/workbox-build/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true, - "license": "MIT" - }, "node_modules/workbox-build/node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", @@ -10488,13 +10432,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/workbox-build/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true, - "license": "MIT" - }, "node_modules/workbox-build/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -10512,19 +10449,6 @@ "sourcemap-codec": "^1.4.8" } }, - "node_modules/workbox-build/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/workbox-build/node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", diff --git a/package.json b/package.json index ef2cea6..bc63f25 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "@tanstack/react-query": "^5.0.0", "better-auth": "^1.2.0", + "picomatch": "4.0.4", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^7.0.0", @@ -23,17 +24,17 @@ }, "devDependencies": { "@eslint/js": "^9.39.4", + "@playwright/test": "^1.49.0", "@tailwindcss/vite": "^4.0.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.2", "@types/node": "^24.12.0", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", - "@vitejs/plugin-react": "^4.5.2", + "@vitejs/plugin-react": "^4.7.0", "eslint": "^9.39.4", "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", - "@playwright/test": "^1.49.0", "globals": "^17.4.0", "jsdom": "^25.0.1", "msw": "^2.12.14", @@ -43,5 +44,10 @@ "vite": "^6.3.5", "vite-plugin-pwa": "^0.21.2", "vitest": "^3.2.4" + }, + "overrides": { + "@rollup/pluginutils": "5.3.0", + "flatted": "^3.4.2", + "serialize-javascript": "7.0.5" } -} +} \ No newline at end of file