diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1b1cc07 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +.github +.next +node_modules +npm-debug.log +README.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e6f7dd..966acb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,11 @@ on: - 'package.json' - 'package-lock.json' - 'next.config.*' + - 'postcss.config.*' - 'tsconfig.json' - 'eslint.config.*' + - 'Dockerfile' + - '.dockerignore' - '.github/workflows/ci.yml' pull_request: paths: @@ -21,8 +24,11 @@ on: - 'package.json' - 'package-lock.json' - 'next.config.*' + - 'postcss.config.*' - 'tsconfig.json' - 'eslint.config.*' + - 'Dockerfile' + - '.dockerignore' - '.github/workflows/ci.yml' workflow_dispatch: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..51fb43d --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,76 @@ +name: CodeQL + +on: + push: + branches: + - main + - master + paths: + - 'src/**' + - 'public/**' + - 'package.json' + - 'package-lock.json' + - 'next.config.*' + - 'postcss.config.*' + - 'tsconfig.json' + - 'eslint.config.*' + - '.github/workflows/codeql.yml' + pull_request: + paths: + - 'src/**' + - 'public/**' + - 'package.json' + - 'package-lock.json' + - 'next.config.*' + - 'postcss.config.*' + - 'tsconfig.json' + - 'eslint.config.*' + - '.github/workflows/codeql.yml' + schedule: + - cron: '30 3 * * 1' + workflow_dispatch: + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: + - javascript-typescript + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: package-lock.json + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: none + + - name: Install dependencies + run: npm ci + + - name: Analyze + uses: github/codeql-action/analyze@v3 + diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml new file mode 100644 index 0000000..52cdea6 --- /dev/null +++ b/.github/workflows/container.yml @@ -0,0 +1,104 @@ +name: Container + +on: + push: + branches: + - main + - master + tags: + - 'v*' + paths: + - 'src/**' + - 'public/**' + - 'package.json' + - 'package-lock.json' + - 'next.config.*' + - 'postcss.config.*' + - 'tsconfig.json' + - 'Dockerfile' + - '.dockerignore' + - '.github/workflows/container.yml' + pull_request: + paths: + - 'src/**' + - 'public/**' + - 'package.json' + - 'package-lock.json' + - 'next.config.*' + - 'postcss.config.*' + - 'tsconfig.json' + - 'Dockerfile' + - '.dockerignore' + - '.github/workflows/container.yml' + workflow_dispatch: + +permissions: + contents: read + packages: write + +jobs: + docker-build: + name: Docker Build + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: false + tags: neurolab-docs:ci + cache-from: type=gha + cache-to: type=gha,mode=max + + ghcr-publish: + name: Build And Push GHCR Image + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: docker-build + if: github.event_name != 'pull_request' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8bf11be --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +FROM node:22-bookworm-slim AS deps +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm ci + +FROM node:22-bookworm-slim AS builder +WORKDIR /app + +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN npm run build + +FROM node:22-bookworm-slim AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 + +COPY package.json package-lock.json ./ +RUN npm ci --omit=dev && npm cache clean --force + +COPY --from=builder /app/.next ./.next +COPY --from=builder /app/public ./public +COPY --from=builder /app/next.config.ts ./next.config.ts + +EXPOSE 3000 + +CMD ["npm", "run", "start"] + diff --git a/src/components/site-header.tsx b/src/components/site-header.tsx index 99413af..b69ecc5 100644 --- a/src/components/site-header.tsx +++ b/src/components/site-header.tsx @@ -7,6 +7,7 @@ import { docsConfig } from '@/config/docs' import { MobileNav } from '@/components/mobile-nav' import { ThemeToggle } from '@/components/theme-toggle' import { Search } from '@/components/search' +import { LucideGithub } from 'lucide-react' export function SiteHeader() { const pathname = usePathname() @@ -44,12 +45,15 @@ export function SiteHeader() {
+
+ +
- +
diff --git a/src/components/theme-toggle.tsx b/src/components/theme-toggle.tsx index 5aa7492..586e17d 100644 --- a/src/components/theme-toggle.tsx +++ b/src/components/theme-toggle.tsx @@ -10,13 +10,12 @@ export function ThemeToggle() { return ( ) diff --git a/src/config/docs.ts b/src/config/docs.ts index 1325e90..8fdc93f 100644 --- a/src/config/docs.ts +++ b/src/config/docs.ts @@ -27,14 +27,9 @@ export const docsConfig: DocsConfig = { href: '/docs/architecture', }, { - title: 'AI API', + title: 'AI/ML Services', href: '/docs/api/ai-service', - }, - { - title: 'GitHub', - href: 'https://github.com/neurolab', - external: true, - }, + } ], sidebarNav: [ {