From 26a36b197e07452e3a3cc448c2b030c0aa4cc975 Mon Sep 17 00:00:00 2001 From: Weng JinPeng Date: Sun, 10 Aug 2025 01:43:28 +0800 Subject: [PATCH] Update readme.md to include project overview, setup instructions, directory structure, and usage with Docker for Node + TypeScript project. --- .gitea/workflows/ci.yml | 40 ++++++++++++++++++++++++++++++++ .gitignore | 7 ++++++ .idea/hello-world.iml | 9 ++++++++ .idea/misc.xml | 6 +++++ .idea/modules.xml | 8 +++++++ .idea/vcs.xml | 6 +++++ Dockerfile | 14 +++++++++++ package.json | 22 ++++++++++++++++++ readme.md | 51 +++++++++++++++++++++++++++++++++++++++++ src/core/Greeter.ts | 14 +++++++++++ src/index.ts | 12 ++++++++++ tests/Greeter.test.ts | 16 +++++++++++++ tsconfig.json | 15 ++++++++++++ 13 files changed, 220 insertions(+) create mode 100644 .gitea/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .idea/hello-world.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 Dockerfile create mode 100644 package.json create mode 100644 src/core/Greeter.ts create mode 100644 src/index.ts create mode 100644 tests/Greeter.test.ts create mode 100644 tsconfig.json diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..839ed18 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,40 @@ +name: ci + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + +jobs: + build-test-pack: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: npm + + - name: Install dependencies + run: npm ci || npm i + + - name: Run tests + run: npm test + + - name: Build + run: npm run build + + - name: Pack + run: npm pack + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: npm-package + path: "*.tgz" + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9813f7f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +node_modules +dist +*.tgz +npm-debug.log* +.DS_Store + + diff --git a/.idea/hello-world.iml b/.idea/hello-world.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/hello-world.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7d862fb --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c0f6ad1 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..63010cd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM node:20-alpine + +WORKDIR /app + +COPY package.json package-lock.json* tsconfig.json ./ +RUN npm install --no-audit --progress=false + +COPY src ./src + +RUN npm run build && npm pack + +CMD ["node", "dist/index.js"] + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..d4098e4 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "hello-world", + "version": "0.1.0", + "private": false, + "description": "Node + TypeScript OOP test environment for Gitea build and pack", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && tsc -p tsconfig.json", + "test": "vitest run" + }, + "files": [ + "dist", + "README.md" + ], + "engines": { + "node": ">=20" + }, + "license": "MIT" +} + diff --git a/readme.md b/readme.md index e69de29..4bf1362 100644 --- a/readme.md +++ b/readme.md @@ -0,0 +1,51 @@ +项目:用于在 Gitea 中测试 Node + TypeScript 项目的构建与打包(含 OOP 示例、CI、Docker)。 + +### 快速开始 + +1) 安装 Node 20(建议使用 nvm) + +```bash +nvm use || nvm install +``` + +2) 安装依赖并运行测试、构建与打包 + +```bash +npm i +npm test +npm run build +npm pack +``` + +生成的 npm 包形如:`hello-world-0.1.0.tgz`。 + +### 目录结构 + +- `src/`:TypeScript 源码,OOP 风格示例位于 `src/core/Greeter.ts` +- `tests/`:Vitest 单元测试 +- `.gitea/workflows/ci.yml`:Gitea Actions 工作流(安装、测试、构建、打包、上传构件) +- `Dockerfile`:容器内构建与打包 + +### 本地使用(Docker) + +```bash +docker build -t node-oop-ci . +docker run --rm node-oop-ci +``` + +镜像在构建阶段会运行 `npm run build && npm pack`,启动时会执行编译产物 `dist/index.js`。 + +### 在 Gitea 上运行 + +将仓库推送到 Gitea,确保实例启用了 Actions,并且 Runner 提供了 `ubuntu-latest` 或兼容标签。 +工作流位于 `.gitea/workflows/ci.yml`,包含以下阶段: + +- Checkout 代码 +- 安装 Node 20 与依赖 +- 运行测试(Vitest) +- 构建(TypeScript 到 `dist/`) +- 打包(`npm pack`) +- 上传构件(若实例提供 `actions/upload-artifact` 镜像) + +如你的 Runner 标签不同,可调整 `runs-on`。 + diff --git a/src/core/Greeter.ts b/src/core/Greeter.ts new file mode 100644 index 0000000..aaf2096 --- /dev/null +++ b/src/core/Greeter.ts @@ -0,0 +1,14 @@ +export class Greeter { + private readonly greetingPrefix: string; + + constructor(greetingPrefix: string = "Hello") { + this.greetingPrefix = greetingPrefix; + } + + public greet(name: string): string { + const sanitizedName = (name ?? "").trim() || "World"; + return `${this.greetingPrefix}, ${sanitizedName}!`; + } +} + + diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6813302 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,12 @@ +import { Greeter } from "./core/Greeter"; + +export { Greeter }; + +if (require.main === module) { + const greeter = new Greeter(); + // Example run output + // eslint-disable-next-line no-console + console.log(greeter.greet("Gitea")); +} + + diff --git a/tests/Greeter.test.ts b/tests/Greeter.test.ts new file mode 100644 index 0000000..5bf9033 --- /dev/null +++ b/tests/Greeter.test.ts @@ -0,0 +1,16 @@ +import { describe, it, expect } from "vitest"; +import { Greeter } from "../src/core/Greeter"; + +describe("Greeter", () => { + it("greets with default prefix", () => { + const greeter = new Greeter(); + expect(greeter.greet("Alice")).toBe("Hello, Alice!"); + }); + + it("trims name and handles empty name", () => { + const greeter = new Greeter("Hi"); + expect(greeter.greet(" ")).toBe("Hi, World!"); + }); +}); + + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7f29eda --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "CommonJS", + "moduleResolution": "Node", + "declaration": true, + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src"] +} +