From 34959a197e318405805cb8a9a8e4fe6c7ac4ff47 Mon Sep 17 00:00:00 2001 From: "yongen.loong" Date: Wed, 24 Jul 2024 13:40:11 +0800 Subject: [PATCH 1/6] ci: build docker for kubernetes --- .github/workflows/kubernetes.yml | 88 ++++++++++++++++++++++++++ Dockerfile | 6 ++ app/admin/page.tsx | 25 -------- app/api/revalidate/route.ts | 30 --------- app/api/token/route.ts | 96 ----------------------------- app/layout.tsx | 10 +-- app/loading.tsx | 8 +-- app/node/[id]/page.tsx | 24 -------- app/not-found.tsx | 2 - app/redirect/page.tsx | 31 ---------- app/sitemap.ts | 3 +- app/wiki/[...id]/layout.tsx | 6 +- app/wiki/[...id]/page.tsx | 71 +-------------------- components/Header/index.tsx | 11 ++-- components/aside.tsx | 53 ++++++++++++++++ components/blocks/child-pages.tsx | 4 +- components/sidebar/index.tsx | 18 +++--- environment.ts | 27 ++++++++ lib/isMobile.ts | 16 ++++- next.config.mjs | 2 + services/get-child-nodes.ts | 3 +- services/get-search-config.ts | 2 - services/get-tenant-access-token.ts | 6 +- services/larkServices.ts | 7 ++- services/list-footer-links.ts | 15 +++-- 25 files changed, 236 insertions(+), 328 deletions(-) create mode 100644 .github/workflows/kubernetes.yml create mode 100644 Dockerfile delete mode 100644 app/admin/page.tsx delete mode 100644 app/api/revalidate/route.ts delete mode 100644 app/api/token/route.ts delete mode 100644 app/node/[id]/page.tsx delete mode 100644 app/redirect/page.tsx create mode 100644 components/aside.tsx create mode 100644 environment.ts diff --git a/.github/workflows/kubernetes.yml b/.github/workflows/kubernetes.yml new file mode 100644 index 0000000..cef1b47 --- /dev/null +++ b/.github/workflows/kubernetes.yml @@ -0,0 +1,88 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +name: Publish Docker image + +on: + workflow_dispatch: + +jobs: + build: + name: Build and Push Docker image to Docker Hub + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: 'npm' + + - run: npm install + + - name: create env file + run: | + touch .env + echo APP_ID=${{ secrets.APP_ID }} >> .env + echo APP_SECRET=${{ secrets.APP_SECRET }} >> .env + echo SPACE_ID=${{ vars.SPACE_ID }} >> .env + echo NEXT_PUBLIC_SITE_URL=${{ vars.SITE_URL }} >> .env + + - run: npm run build + + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }} + tags: | + type=sha + # set latest tag for default branch + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Set short git commit SHA + id: vars + run: | + calculatedSha=$(git rev-parse --short ${{ github.sha }}) + echo "short_sha=$calculatedSha" >> "$GITHUB_OUTPUT" + + - name: Deploy + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.WORKFLOW_DISPATCH }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: 'poc-aaa', + repo: 'devops', + workflow_id: 'docs-cms.yaml', + ref: 'main', + inputs: { + project: '${{ vars.PROJECT }}', + commit_sha: 'sha-${{ steps.vars.outputs.short_sha }}', + } + }) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c889f59 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM cgr.dev/chainguard/nginx:latest + +WORKDIR /usr/share/nginx/html +COPY out . + +EXPOSE 8080 \ No newline at end of file diff --git a/app/admin/page.tsx b/app/admin/page.tsx deleted file mode 100644 index 53c8a91..0000000 --- a/app/admin/page.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import Link from "next/link"; - -export default function Admin() { - return ( - <> - - - ); -} - -async function SignIn() { - "use client"; - - return ( - - sign in - - ); -} diff --git a/app/api/revalidate/route.ts b/app/api/revalidate/route.ts deleted file mode 100644 index d843d26..0000000 --- a/app/api/revalidate/route.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { revalidatePath, revalidateTag } from "next/cache"; -import { NextRequest } from "next/server"; - -function getType(path: string) { - if (path === "/" || path.endsWith("]")) return "layout"; - return "page"; -} - -// https://nextjs.org/docs/app/api-reference/functions/revalidatePath#route-handler -export async function GET(request: NextRequest) { - const path = request.nextUrl.searchParams.get("path"); - - if (path) { - revalidatePath(path, getType(path)); - return Response.json({ revalidated: true, now: Date.now() }); - } - - const tag = request.nextUrl.searchParams.get("tag"); - - if (tag) { - revalidateTag(tag); - return Response.json({ revalidated: true, now: Date.now() }); - } - - return Response.json({ - revalidated: false, - now: Date.now(), - message: "Missing path/tag to revalidate", - }); -} \ No newline at end of file diff --git a/app/api/token/route.ts b/app/api/token/route.ts deleted file mode 100644 index 48a3a87..0000000 --- a/app/api/token/route.ts +++ /dev/null @@ -1,96 +0,0 @@ -"use server"; - -import { getIronSession } from "iron-session"; -import { cookies } from "next/headers"; - -async function getAppAccessToken() { - const res = await fetch( - `https://open.larksuite.com/open-apis/auth/v3/app_access_token/internal`, - { - method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - body: JSON.stringify({ - app_id: process.env.APP_ID, - app_secret: process.env.APP_SECRET, - }), - } - ); - - const data: { - code: number; - msg: string; - app_access_token: string; - expire: number; - } = await res.json(); - - if (data.code !== 0) { - throw new Error("Unable to get app access token."); - } - - return data.app_access_token; -} -async function getUserAccessToken(code: string) { - const res = await fetch( - `https://open.larksuite.com/open-apis/authen/v1/oidc/access_token`, - { - method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - Authorization: `Bearer ${await getAppAccessToken()}`, - }, - body: JSON.stringify({ - grant_type: "authorization_code", - code, - }), - } - ); - - const data: { - code: number; - msg: string; - data: { - access_token: string; - refresh_token: string; - token_type: "Bearer"; - expires_in: number; - refresh_expires_in: number; - scope: string; - }; - } = await res.json(); - - if (data.code !== 0) { - throw new Error("Unable to get user access token."); - } - - return data.data.access_token; -} - -type SessionTokenData = { - token: string; -}; - -async function getIronSessionData() { - const session = await getIronSession(cookies(), { - password: `${process.env.COOKIE_PASSWORD}`, - cookieName: `${process.env.COOKIE_NAME}`, - }); - return session; -} - -export async function GET(request: Request) { - const { searchParams } = new URL(request.url); - const code = searchParams.get("code"); - - if (!code) { - throw new Error("no code in search params"); - } - // get user token by code - const data = await getUserAccessToken(code); - // save in session - const session = await getIronSessionData(); - session.token = data; - await session.save(); - return Response.json({ token: data }); -} diff --git a/app/layout.tsx b/app/layout.tsx index fb5c7fc..9e6b526 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -6,9 +6,7 @@ import { Poppins as FontSans } from "next/font/google"; import { Footer } from "@/components/footer"; import Header from "@/components/Header"; import { Suspense } from "react"; -import { headers } from "next/headers"; import Loading from "./loading"; -import { isMobile } from "../lib/isMobile"; import { getNodeToken, NodesItem } from "../services/larkServices"; const fontSans = FontSans({ @@ -28,8 +26,6 @@ export default async function RootLayout({ children: React.ReactNode; }>) { const menu = await getMenu(); - const userAgent = headers().get("user-agent") || ""; - const isMobileDevice = isMobile(userAgent); const nodes = await getNodeToken(); const appToken = nodes.items.find((ele: NodesItem) => { return ele.title === "Configurations" && ele.obj_type === "bitable"; @@ -46,11 +42,7 @@ export default async function RootLayout({ )} > -
+
}>{children}