diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 890c549..0227646 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,54 +2,53 @@ name: CI on: push: - branches: [master] + branches: + - master pull_request: - branches: [master] + branches: + - master jobs: - lint-and-test: + validate: + name: Lint, Typecheck and Test runs-on: ubuntu-latest - strategy: - matrix: - package: - - '@nexus-notes/crypto' - - '@nexus-notes/firebase' - - '@nexus-notes/core-logic' - - '@nexus-notes/ui' + steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + - name: Setup Node 24 + uses: actions/setup-node@v4 with: - version: 11 + node-version: 24 - - uses: actions/setup-node@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v3 with: - node-version: 22 - cache: 'pnpm' - - - run: pnpm install --frozen-lockfile - - - run: pnpm --filter ${{ matrix.package }} typecheck - continue-on-error: true - - - run: pnpm --filter ${{ matrix.package }} test + version: 9 - build-web: - runs-on: ubuntu-latest - needs: lint-and-test - steps: - - uses: actions/checkout@v4 + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - - uses: pnpm/action-setup@v4 + - name: Setup pnpm cache + uses: actions/cache@v4 with: - version: 11 + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- - - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'pnpm' + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run Linting + run: pnpm lint:all - - run: pnpm install --frozen-lockfile + - name: Run Typechecking + run: pnpm typecheck:all - - run: pnpm --filter @nexus-notes/web build + - name: Run Unit Tests + run: pnpm test:all diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml new file mode 100644 index 0000000..ae3e6d7 --- /dev/null +++ b/.github/workflows/deploy-web.yml @@ -0,0 +1,52 @@ +name: Deploy WebApp to Firebase + +on: + release: + types: [published] + +jobs: + deploy: + name: Build and Deploy Nuxt to Firebase Hosting + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node 24 + uses: actions/setup-node@v4 + with: + node-version: 24 + + - name: Setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 9 + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build Web App + run: pnpm --filter @nexus-notes/web generate + + - name: Deploy to Firebase + uses: FirebaseExtended/action-hosting-deploy@v0 + with: + repoToken: ${{ secrets.GITHUB_TOKEN }} + firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }} + projectId: markdown-notes # Deberás configurar este valor o extraerlo del Service Account + channelId: live diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml new file mode 100644 index 0000000..1d637a1 --- /dev/null +++ b/.github/workflows/release-desktop.yml @@ -0,0 +1,74 @@ +name: Release Desktop App + +on: + release: + types: [published] + +jobs: + release: + name: Build Tauri on ${{ matrix.platform }} + runs-on: ${{ matrix.platform }} + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest, windows-latest] + # Eliminado macos-latest según la preferencia de evitar ecosistema Apple + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node 24 + uses: actions/setup-node@v4 + with: + node-version: 24 + + - name: Setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 9 + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies (Ubuntu only) + if: matrix.platform == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.platform == 'ubuntu-latest' && 'x86_64-unknown-linux-gnu' || 'x86_64-pc-windows-msvc' }} + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: apps/desktop/src-tauri -> target + + - name: Install project dependencies + run: pnpm install --frozen-lockfile + + - name: Build Desktop App + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tagName: ${{ github.ref_name }} + releaseName: Nexus Notes Desktop v__VERSION__ + releaseBody: 'Para descargar la app, revisa los assets al final de esta nota.' + releaseDraft: false + prerelease: false + projectPath: apps/desktop diff --git a/.github/workflows/release-mobile.yml b/.github/workflows/release-mobile.yml new file mode 100644 index 0000000..b7a9ba9 --- /dev/null +++ b/.github/workflows/release-mobile.yml @@ -0,0 +1,62 @@ +name: Release Mobile App (Android) + +on: + release: + types: [published] + +jobs: + build: + name: Build Android APK + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node 24 + uses: actions/setup-node@v4 + with: + node-version: 24 + + - name: Setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 9 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: '17' + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build Web App + run: pnpm --filter @nexus-notes/web generate + + - name: Sync Capacitor + run: pnpm --filter @nexus-notes/mobile exec cap sync android + + - name: Build APK + working-directory: apps/mobile/android + run: ./gradlew assembleDebug # Cambiar a assembleRelease cuando se tengan llaves de firma + + - name: Upload APK to Release + uses: softprops/action-gh-release@v1 + with: + files: apps/mobile/android/app/build/outputs/apk/debug/app-debug.apk diff --git a/.gitignore b/.gitignore index 0cb15b6..43c56a8 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,6 @@ coverage/ # Cache .cache/ *.tsbuildinfo + +# firebase +.firebaserc \ No newline at end of file diff --git a/apps/desktop/package.json b/apps/desktop/package.json index e190c24..0358a9c 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,13 +1,12 @@ { "name": "@nexus-notes/desktop", + "type": "module", "version": "0.0.0", "private": true, - "type": "module", "scripts": { "dev": "tauri dev", "build": "tauri build", - "lint": "eslint .", - "typecheck": "tsc --noEmit" + "lint": "eslint ." }, "dependencies": { "@nexus-notes/web": "workspace:*", diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 7b41f4b..77843b2 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -2,21 +2,25 @@ name = "nexus-notes-desktop" version = "0.0.0" description = "Desktop client for NexusNotes - Markdown Vault" -authors = ["vladzur"] +authors = [ "vladzur" ] edition = "2021" [lib] name = "nexus_notes_desktop_lib" -crate-type = ["lib", "cdylib", "staticlib"] +crate-type = [ + "lib", + "cdylib", + "staticlib" +] [build-dependencies] tauri-build = { version = "2", features = [] } [dependencies] tauri = { version = "2", features = [] } -serde = { version = "1", features = ["derive"] } +serde = { version = "1", features = [ "derive" ] } serde_json = "1" [features] -default = ["custom-protocol"] -custom-protocol = ["tauri/custom-protocol"] +default = [ "custom-protocol" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 1d35e18..a797d44 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -1,21 +1,20 @@ { "name": "@nexus-notes/mobile", + "type": "module", "version": "0.0.0", "private": true, - "type": "module", "scripts": { "dev": "pnpm --filter @nexus-notes/web generate && npx cap sync && npx cap open", "build": "[ -f ../web/.output/public/index.html ] || pnpm --filter @nexus-notes/web generate; npx cap sync", "add:android": "npx cap add android", "add:ios": "npx cap add ios", - "lint": "eslint .", - "typecheck": "tsc --noEmit" + "lint": "eslint ." }, "dependencies": { - "@nexus-notes/web": "workspace:*", "@capacitor/core": "^6.0.0", "@capacitor/filesystem": "^6.0.0", - "@capacitor/keyboard": "^6.0.0" + "@capacitor/keyboard": "^6.0.0", + "@nexus-notes/web": "workspace:*" }, "devDependencies": { "@capacitor/cli": "^6.0.0", diff --git a/apps/server/package.json b/apps/server/package.json index ece1e79..d10dc02 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,13 +1,12 @@ { "name": "@nexus-notes/server", + "type": "module", "version": "0.0.0", "private": true, - "type": "module", "scripts": { "dev": "tsx watch src/index.ts", "build": "tsc", "start": "node dist/index.js", - "test": "vitest run", "lint": "eslint src/", "typecheck": "tsc --noEmit" }, @@ -19,8 +18,8 @@ "devDependencies": { "@nexus-notes/config": "workspace:*", "@types/node": "^22.0.0", - "typescript": "^5.7.0", "tsx": "^4.19.0", + "typescript": "^5.7.0", "vitest": "^3.0.0" } } diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index 1b697ca..9e98025 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -1,5 +1,5 @@ -import { createApp, createRouter, defineEventHandler, toNodeListener } from 'h3' import { createServer } from 'node:http' +import { createApp, createRouter, defineEventHandler, toNodeListener } from 'h3' const app = createApp() const router = createRouter() diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index a9b4996..db6f3d4 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -1,9 +1,9 @@ { "extends": "@nexus-notes/config/tsconfig.base.json", "compilerOptions": { - "outDir": "./dist", + "lib": ["ES2022"], "rootDir": "./src", - "lib": ["ES2022"] + "outDir": "./dist" }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/apps/web/app.vue b/apps/web/app.vue index 32e96e9..f7ba092 100644 --- a/apps/web/app.vue +++ b/apps/web/app.vue @@ -8,9 +8,13 @@ const { isAuthReady } = useAuth() diff --git a/apps/web/composables/useAuth.ts b/apps/web/composables/useAuth.ts index 43e99dd..17c2f51 100644 --- a/apps/web/composables/useAuth.ts +++ b/apps/web/composables/useAuth.ts @@ -1,11 +1,12 @@ -import { ref, computed, readonly } from 'vue' +import type { User } from '@nexus-notes/firebase' import { signInWithEmail, - signUpWithEmail, signInWithGoogle, signOutUser, - type User, + signUpWithEmail, + } from '@nexus-notes/firebase' +import { computed, readonly, ref } from 'vue' /** Datos mínimos del usuario en el estado reactivo. */ export interface AuthUser { @@ -22,7 +23,8 @@ const isAuthenticated = computed(() => user.value !== null) /** Mapea un User de Firebase al shape local. */ function mapUser(firebaseUser: User | null): AuthUser | null { - if (!firebaseUser) return null + if (!firebaseUser) + return null return { uid: firebaseUser.uid, email: firebaseUser.email, diff --git a/apps/web/layouts/default.vue b/apps/web/layouts/default.vue index c6a9f12..ad0c022 100644 --- a/apps/web/layouts/default.vue +++ b/apps/web/layouts/default.vue @@ -1,21 +1,21 @@