diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d820c31 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Type check + run: npx tsc --noEmit + + - name: Lint + run: npx eslint . --quiet + + - name: Test + run: npm test -- --runInBand + + - name: Build + run: npm run build diff --git a/package-lock.json b/package-lock.json index 044b664..883b65c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,11 @@ "name": "blog", "version": "0.1.0", "dependencies": { - "gray-matter": "latest", + "gray-matter": "4.0.3", "next": "^15.0.3", "prism-react-renderer": "^2.4.0", - "react": "latest", - "react-dom": "latest", + "react": "18.3.1", + "react-dom": "18.3.1", "rehype": "^13.0.2", "rehype-katex": "^7.0.1", "rehype-sanitize": "^6.0.0", @@ -20,32 +20,32 @@ "remark": "^15.0.1", "remark-emoji": "^5.0.1", "remark-gfm": "^4.0.0", - "remark-html": "latest", - "remark-math": "latest", - "remark-rehype": "latest", - "unified": "latest" + "remark-html": "16.0.1", + "remark-math": "6.0.0", + "remark-rehype": "11.1.1", + "unified": "11.0.5" }, "devDependencies": { - "@tailwindcss/typography": "latest", + "@tailwindcss/typography": "0.5.15", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", - "@types/node": "latest", - "@types/react": "latest", - "@types/react-dom": "latest", - "autoprefixer": "latest", - "eslint": "latest", - "eslint-config-next": "latest", + "@types/node": "20.17.6", + "@types/react": "18.3.12", + "@types/react-dom": "18.3.1", + "autoprefixer": "10.4.20", + "eslint": "8.57.1", + "eslint-config-next": "14.0.4", "jest": "^30.4.2", "jest-environment-jsdom": "^30.4.1", "node-mocks-http": "^1.17.2", - "postcss": "latest", - "rimraf": "latest", - "tailwindcss": "latest", + "postcss": "8.4.49", + "rimraf": "5.0.10", + "tailwindcss": "3.4.15", "ts-jest": "^29.4.11", "ts-node": "^10.9.2", - "typescript": "latest" + "typescript": "5.6.3" }, "engines": { "node": "22.x" diff --git a/package.json b/package.json index 44ed218..be1d49d 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,11 @@ "clean": "rimraf .next node_modules" }, "dependencies": { - "gray-matter": "latest", + "gray-matter": "4.0.3", "next": "^15.0.3", "prism-react-renderer": "^2.4.0", - "react": "latest", - "react-dom": "latest", + "react": "18.3.1", + "react-dom": "18.3.1", "rehype": "^13.0.2", "rehype-katex": "^7.0.1", "rehype-sanitize": "^6.0.0", @@ -25,32 +25,32 @@ "remark": "^15.0.1", "remark-emoji": "^5.0.1", "remark-gfm": "^4.0.0", - "remark-html": "latest", - "remark-math": "latest", - "remark-rehype": "latest", - "unified": "latest" + "remark-html": "16.0.1", + "remark-math": "6.0.0", + "remark-rehype": "11.1.1", + "unified": "11.0.5" }, "devDependencies": { - "@tailwindcss/typography": "latest", + "@tailwindcss/typography": "0.5.15", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", - "@types/node": "latest", - "@types/react": "latest", - "@types/react-dom": "latest", - "autoprefixer": "latest", - "eslint": "latest", - "eslint-config-next": "latest", + "@types/node": "20.17.6", + "@types/react": "18.3.12", + "@types/react-dom": "18.3.1", + "autoprefixer": "10.4.20", + "eslint": "8.57.1", + "eslint-config-next": "14.0.4", "jest": "^30.4.2", "jest-environment-jsdom": "^30.4.1", "node-mocks-http": "^1.17.2", - "postcss": "latest", - "rimraf": "latest", - "tailwindcss": "latest", + "postcss": "8.4.49", + "rimraf": "5.0.10", + "tailwindcss": "3.4.15", "ts-jest": "^29.4.11", "ts-node": "^10.9.2", - "typescript": "latest" + "typescript": "5.6.3" }, "engines": { "node": "22.x" diff --git a/src/pages/api/__tests__/content.test.ts b/src/__tests__/api/content.test.ts similarity index 98% rename from src/pages/api/__tests__/content.test.ts rename to src/__tests__/api/content.test.ts index 6d0057e..ae76712 100644 --- a/src/pages/api/__tests__/content.test.ts +++ b/src/__tests__/api/content.test.ts @@ -7,7 +7,7 @@ jest.mock('fs/promises', () => ({ })) import * as fs from 'fs/promises' -import handler from '../content/[...path]' +import handler from '../../pages/api/content/[...path]' const mockStat = fs.stat as jest.Mock const mockReadFile = fs.readFile as jest.Mock diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..9843d26 --- /dev/null +++ b/vercel.json @@ -0,0 +1,5 @@ +{ + "framework": "nextjs", + "installCommand": "npm ci", + "buildCommand": "npm run build" +}