From f5d9bac7e33f64f3287814190cf3e6561f51b9fe Mon Sep 17 00:00:00 2001 From: root Date: Tue, 2 Apr 2024 11:21:57 +0800 Subject: [PATCH] fix: add web and tauri ci --- .github/workflows/tauri2_ci.yaml | 113 ++++++++++++++++++ .github/workflows/web2_ci.yaml | 61 ++++++++++ frontend/appflowy_web_app/README.md | 3 +- frontend/appflowy_web_app/package.json | 8 +- frontend/appflowy_web_app/src/AppConfig.tsx | 24 +--- .../services/js-services/document.service.ts | 2 +- .../services/js-services/http/utils.ts | 18 ++- .../services/wasm-services/cloud.service.ts | 4 +- .../appflowy_web_app/src/stores/app/slice.ts | 36 ++++++ frontend/appflowy_web_app/src/stores/store.ts | 2 + frontend/appflowy_web_app/tsconfig.web.json | 12 ++ 11 files changed, 251 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/tauri2_ci.yaml create mode 100644 .github/workflows/web2_ci.yaml create mode 100644 frontend/appflowy_web_app/src/stores/app/slice.ts create mode 100644 frontend/appflowy_web_app/tsconfig.web.json diff --git a/.github/workflows/tauri2_ci.yaml b/.github/workflows/tauri2_ci.yaml new file mode 100644 index 0000000000000..b9a764bbd33fb --- /dev/null +++ b/.github/workflows/tauri2_ci.yaml @@ -0,0 +1,113 @@ +name: Tauri2-CI +on: + pull_request: + paths: + - ".github/workflows/tauri2_ci.yaml" + - "frontend/rust-lib/**" + - "frontend/appflowy_web_app/**" + - "frontend/resources/**" + +env: + NODE_VERSION: "18.16.0" + PNPM_VERSION: "8.5.0" + RUST_TOOLCHAIN: "1.75" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + tauri-build: + if: github.event.pull_request.draft != true + strategy: + fail-fast: false + matrix: + platform: [ubuntu-20.04] + + runs-on: ${{ matrix.platform }} + + env: + CI: true + steps: + - uses: actions/checkout@v4 + + - name: Maximize build space (ubuntu only) + if: matrix.platform == 'ubuntu-20.04' + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo docker image prune --all --force + sudo rm -rf /opt/hostedtoolcache/codeQL + sudo rm -rf ${GITHUB_WORKSPACE}/.git + sudo rm -rf $ANDROID_HOME/ndk + + - name: setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: setup pnpm + uses: pnpm/action-setup@v2 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Install Rust toolchain + id: rust_toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + override: true + profile: minimal + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: "./frontend/appflowy_web_app/src-tauri -> target" + + - name: Node_modules cache + uses: actions/cache@v2 + with: + path: frontend/appflowy_web_app/node_modules + key: node-modules-${{ runner.os }} + + - name: install dependencies (windows only) + if: matrix.platform == 'windows-latest' + working-directory: frontend + run: | + cargo install --force duckscript_cli + vcpkg integrate install + + - name: install dependencies (ubuntu only) + if: matrix.platform == 'ubuntu-20.04' + working-directory: frontend + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf + + - name: install cargo-make + working-directory: frontend + run: | + cargo install --force cargo-make + cargo make appflowy-tauri-deps-tools + + - name: install frontend dependencies + working-directory: frontend/appflowy_web_app + run: | + mkdir dist + pnpm install + cd src-tauri && cargo build + + - name: test and lint + working-directory: frontend/appflowy_web_app + run: | + pnpm run lint:tauri + + - uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tauriScript: pnpm tauri + projectPath: frontend/appflowy_web_app + args: "--debug" \ No newline at end of file diff --git a/.github/workflows/web2_ci.yaml b/.github/workflows/web2_ci.yaml new file mode 100644 index 0000000000000..21048d6e72b94 --- /dev/null +++ b/.github/workflows/web2_ci.yaml @@ -0,0 +1,61 @@ +name: Web2-CI +on: + pull_request: + paths: + - ".github/workflows/web2_ci.yaml" + - "frontend/appflowy_web_app/**" + - "frontend/resources/**" +env: + NODE_VERSION: "18.16.0" + PNPM_VERSION: "8.5.0" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + tauri-build: + if: github.event.pull_request.draft != true + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest] + + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v4 + - name: Maximize build space (ubuntu only) + if: matrix.platform == 'ubuntu-latest' + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo docker image prune --all --force + sudo rm -rf /opt/hostedtoolcache/codeQL + sudo rm -rf ${GITHUB_WORKSPACE}/.git + sudo rm -rf $ANDROID_HOME/ndk + - name: setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ env.NODE_VERSION }} + - name: setup pnpm + uses: pnpm/action-setup@v2 + with: + version: ${{ env.PNPM_VERSION }} + - name: Node_modules cache + uses: actions/cache@v2 + with: + path: frontend/appflowy_web_app/node_modules + key: node-modules-${{ runner.os }} + - name: install frontend dependencies + working-directory: frontend/appflowy_web_app + run: | + pnpm install + - name: test and lint + working-directory: frontend/appflowy_web_app + run: | + pnpm run lint + - name: build + working-directory: frontend/appflowy_web_app + run: | + pnpm run build \ No newline at end of file diff --git a/frontend/appflowy_web_app/README.md b/frontend/appflowy_web_app/README.md index 8a88e0efcbdb7..9aba86216e017 100644 --- a/frontend/appflowy_web_app/README.md +++ b/frontend/appflowy_web_app/README.md @@ -93,7 +93,8 @@ Before you begin, ensure you have the following installed: # make sure you are in the root directory of the project cd frontend/appflowy_web_app mkdir dist - cargo make --cwd .. tauri_build + cd src-tauri + cargo build ``` ### 🚀 Running the Application diff --git a/frontend/appflowy_web_app/package.json b/frontend/appflowy_web_app/package.json index 111c05a292b0c..870e8a5939ea3 100644 --- a/frontend/appflowy_web_app/package.json +++ b/frontend/appflowy_web_app/package.json @@ -6,10 +6,10 @@ "scripts": { "dev": "pnpm run sync:i18n && vite", "dev:tauri": "TAURI_MODE=true pnpm run sync:i18n && tauri dev", - "build": "pnpm run sync:i18n && pnpm run lint:web && vite build", - "build:tauri": "TAURI_MODE=true pnpm run sync:i18n && pnpm run lint && vite build", - "lint:tauri": "TAURI_MODE=true tsc --noEmit && eslint --ext .js,.ts,.tsx . --ignore-path .eslintigore", - "lint": "tsc --noEmit && eslint --ext .js,.ts,.tsx . --ignore-path .eslintigore.web", + "build": "pnpm run lint:web && vite build", + "build:tauri": "TAURI_MODE=true pnpm run lint && vite build", + "lint:tauri": "TAURI_MODE=true pnpm run sync:i18n && tsc --noEmit && eslint --ext .js,.ts,.tsx . --ignore-path .eslintigore", + "lint": "pnpm run sync:i18n && tsc --noEmit --project tsconfig.web.json && eslint --ext .js,.ts,.tsx . --ignore-path .eslintigore.web", "preview": "vite preview", "tauri:dev": "tauri dev", "css:variables": "node style-dictionary/config.cjs", diff --git a/frontend/appflowy_web_app/src/AppConfig.tsx b/frontend/appflowy_web_app/src/AppConfig.tsx index c950b110d41a9..452d88e593d41 100644 --- a/frontend/appflowy_web_app/src/AppConfig.tsx +++ b/frontend/appflowy_web_app/src/AppConfig.tsx @@ -1,6 +1,7 @@ import React, { createContext, useEffect, useMemo, useState } from 'react'; -import { AFServiceConfig, AFService } from '@/application/services/services.type'; +import { AFService } from '@/application/services/services.type'; import { getService } from '@/application/services'; +import { useAppSelector } from '@/stores/store'; export const AFConfigContext = createContext< | { @@ -9,30 +10,17 @@ export const AFConfigContext = createContext< | undefined >(undefined); -const defaultConfig: AFServiceConfig = { - cloudConfig: { - baseURL: import.meta.env.DEV - ? import.meta.env.AF_BASE_URL || 'https://test.appflowy.cloud' - : 'https://beta.appflowy.cloud', - gotrueURL: import.meta.env.DEV - ? import.meta.env.AF_GOTRUE_URL || 'https://test.appflowy.cloud/gotrue' - : 'https://beta.appflowy.cloud/gotrue', - wsURL: import.meta.env.DEV - ? import.meta.env.AF_WS_URL || 'wss://test.appflowy.cloud/ws/v1' - : 'wss://beta.appflowy.cloud/ws/v1', - }, -}; function AppConfig({ children }: { children: React.ReactNode }) { - const [serviceConfig, setServiceConfig] = useState(defaultConfig); + const appConfig = useAppSelector((state) => state.app.appConfig); const [service, setService] = useState(); useEffect(() => { void (async () => { - if (!serviceConfig) return; - setService(await getService(serviceConfig)); + if (!appConfig) return; + setService(await getService(appConfig)); })(); - }, [serviceConfig]); + }, [appConfig]); const config = useMemo( () => ({ diff --git a/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts b/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts index 2031fca175653..d55ad1771e2d5 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts @@ -10,7 +10,7 @@ export class JSDocumentService implements DocumentService { const docId = '26d5c8c1-1c66-459c-bc6c-f4da1a663348'; const data = await this.httpClient.getObject(workspaceId, docId, CollabType.Document); - console.log(data); + console.log(docID, data); return; } diff --git a/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts b/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts index ab57147acd708..7c420a11e604a 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/http/utils.ts @@ -1,6 +1,6 @@ import { UserProfilePB, WorkspacePB } from '@/application/services/js-services/http/http.type'; import { Authenticator, UserProfile, Workspace } from '@/application/services/user.type'; -import axios, { AxiosInstance } from 'axios'; +import axios, { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse, AxiosRequestConfig } from 'axios'; import { ACCESS_TOKEN_NAME, AUTHORIZATION_NAME, @@ -43,7 +43,7 @@ export function getAxiosInstances(baseURL: string, gotrueURL: string) { }, }); - const requestInterceptor = async (config: any) => { + const requestInterceptor = async (config: InternalAxiosRequestConfig) => { const accessToken = sessionStorage.getItem(ACCESS_TOKEN_NAME); const tokenType = sessionStorage.getItem(TOKEN_TYPE_NAME) || 'Bearer'; @@ -54,15 +54,21 @@ export function getAxiosInstances(baseURL: string, gotrueURL: string) { return config; }; - const errorInterceptor = async (error: any) => { - if (error.response?.status === 401 && !error.config.url.includes(gotrueHttpUrls[URL_NAME.LOGOUT])) { + const errorInterceptor = async (error: { + response?: AxiosResponse; + config: AxiosRequestConfig; + }) => { + if (error.response?.status === 401 && !error.config.url?.includes(gotrueHttpUrls[URL_NAME.LOGOUT])) { try { const tokenType = sessionStorage.getItem(TOKEN_TYPE_NAME) || 'Bearer'; const accessToken = await refreshToken(gotrueInstance); - error.config.headers[AUTHORIZATION_NAME] = `${tokenType} ${accessToken}`; + const config = { + ...error.config, + [AUTHORIZATION_NAME]: `${tokenType} ${accessToken}`, + } - return gotrueInstance.request(error.config); + return gotrueInstance.request(config); } catch (e) { // do nothing } diff --git a/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts b/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts index 83db07f9b0404..5eb4032f47fcb 100644 --- a/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts +++ b/frontend/appflowy_web_app/src/application/services/wasm-services/cloud.service.ts @@ -27,9 +27,9 @@ export class CloudService { try { const res = await this.client?.sign_in_password(email, password); - // console.log(res); + console.log(res); } catch (error) { - // console.error(error); + console.error(error); } } } diff --git a/frontend/appflowy_web_app/src/stores/app/slice.ts b/frontend/appflowy_web_app/src/stores/app/slice.ts new file mode 100644 index 0000000000000..2aac422b83119 --- /dev/null +++ b/frontend/appflowy_web_app/src/stores/app/slice.ts @@ -0,0 +1,36 @@ +import { AFServiceConfig } from '@/application/services/services.type'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +const defaultConfig: AFServiceConfig = { + cloudConfig: { + baseURL: import.meta.env.DEV + ? import.meta.env.AF_BASE_URL || 'https://test.appflowy.cloud' + : 'https://beta.appflowy.cloud', + gotrueURL: import.meta.env.DEV + ? import.meta.env.AF_GOTRUE_URL || 'https://test.appflowy.cloud/gotrue' + : 'https://beta.appflowy.cloud/gotrue', + wsURL: import.meta.env.DEV + ? import.meta.env.AF_WS_URL || 'wss://test.appflowy.cloud/ws/v1' + : 'wss://beta.appflowy.cloud/ws/v1', + }, +}; + +export interface AppState { + appConfig: AFServiceConfig; +} + +const initialState: AppState = { + appConfig: defaultConfig, +}; + +export const slice = createSlice({ + name: 'app', + initialState, + reducers: { + setAppConfig: (state, action: PayloadAction) => { + state.appConfig = action.payload; + }, + }, +}); + +export const { setAppConfig } = slice.actions; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/stores/store.ts b/frontend/appflowy_web_app/src/stores/store.ts index 7ae42c9beb755..b75363e911628 100644 --- a/frontend/appflowy_web_app/src/stores/store.ts +++ b/frontend/appflowy_web_app/src/stores/store.ts @@ -9,6 +9,7 @@ import { } from '@reduxjs/toolkit'; import { errorSlice } from '@/stores/error/slice'; import { currentUserSlice } from '@/stores/currentUser/slice'; +import { slice as appSlice } from '@/stores/app/slice'; const listenerMiddlewareInstance = createListenerMiddleware({ onError: () => console.error, @@ -16,6 +17,7 @@ const listenerMiddlewareInstance = createListenerMiddleware({ const store = configureStore({ reducer: { + [appSlice.name]: appSlice.reducer, [errorSlice.name]: errorSlice.reducer, [currentUserSlice.name]: currentUserSlice.reducer, }, diff --git a/frontend/appflowy_web_app/tsconfig.web.json b/frontend/appflowy_web_app/tsconfig.web.json new file mode 100644 index 0000000000000..f6c24c1512fa0 --- /dev/null +++ b/frontend/appflowy_web_app/tsconfig.web.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "exclude": [ + "node_modules", + "src/application/services/tauri-services" + ], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +}