Skip to content

Commit 51cfcfd

Browse files
committed
package.json整理、dockerfileとciでrevisionチェックを実行
1 parent 50ab7a2 commit 51cfcfd

File tree

6 files changed

+168
-108
lines changed

6 files changed

+168
-108
lines changed

.github/workflows/node.js.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ jobs:
3333
- run: npm ci
3434
- run: npm run tsc
3535

36+
check-docs:
37+
runs-on: ubuntu-latest
38+
strategy:
39+
matrix:
40+
node-version: [22.x]
41+
steps:
42+
- uses: actions/checkout@v4
43+
- uses: actions/setup-node@v4
44+
with:
45+
node-version: ${{ matrix.node-version }}
46+
cache: 'npm'
47+
- run: npm ci
48+
- run: npm run checkDocs
49+
3650
test-js-eval:
3751
runs-on: ubuntu-latest
3852
strategy:

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ COPY --from=dependencies /app/node_modules ./node_modules
2121
# Copy application source code
2222
COPY . .
2323

24-
ENV NODE_ENV=production
24+
# Stop if documentation has any change that is not reflected to revisions.yml and database.
25+
RUN npx tsx ./scripts/checkDocs.ts --check-diff
2526

2627
# Next.js collects completely anonymous telemetry data about general usage.
2728
# Learn more here: https://nextjs.org/telemetry

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ npm run lint
5454
```
5555
でコードをチェックします。出てくるwarningやerrorはできるだけ直しましょう。
5656

57+
### データベースのスキーマ
58+
5759
* データベースのスキーマ(./app/schema/hoge.ts)を編集した場合、 `npx drizzle-kit generate` でmigrationファイルを作成し、 `npx drizzle-kit migrate` でデータベースに反映します。
5860
* また、mainにマージする際に本番環境のデータベースにもmigrateをする必要があります
5961
* スキーマのファイルを追加した場合は app/lib/drizzle.ts でimportを追加する必要があります(たぶん)
@@ -72,6 +74,11 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
7274

7375
## ドキュメント
7476

77+
```bash
78+
npm run checkDocs
79+
```
80+
でドキュメントの読み込み時にエラーにならないか確認できます (index.ymlの間違いなど)
81+
7582
* ドキュメントはセクション(見出し)ごとにわけ、 public/docs/言語id/ページid/並び替え用連番-セクション名.md に置く。
7683
* ページはディレクトリの名前によらず 言語id/index.yml に書かれている順で表示される。
7784
* セクションはセクションIDによらずファイル名順で表示される。
@@ -111,6 +118,7 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
111118
* REPLのコード例は1セクションに最大1つまで。
112119
* コードエディターとコード実行ブロックはいくつでも置けます。
113120
* ページ0以外の各ページの最後はレベル2見出し「この章のまとめ」と、レベル3見出し「練習問題n」を置く
121+
* ドキュメントに変更を加えたものをmainブランチにpushした際、public/docs/revisions.ymlが更新されます。基本的には手動でこのファイルを編集する必要はありません。
114122

115123
### ベースとなるドキュメントの作り方
116124

@@ -141,18 +149,17 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
141149
- Canvasを使われた場合はやり直す。(Canvasはファイル名付きコードブロックで壊れる)
142150
- 太字がなぜか `**キーワード**` の代わりに `\*\*キーワード\*\*` となっている場合がある。 `\*\*` → `**` の置き換えで対応
143151
- 見出しの前に `-----` (水平線)が入る場合がある。my.code();は水平線の表示に対応しているが、消す方向で統一
144-
- `言語名-repl` にはページ内で一意なIDを追加する (例: `言語名-repl:1`)
145152
- REPLの出力部分に書かれたコメントは消えるので修正する
146153
- ダメな例
147154
````
148-
```js-repl:1
155+
```js-repl
149156
> console.log("Hello")
150157
Hello // 文字列を表示する
151158
```
152159
````
153160
- 以下のようにすればok
154161
````
155-
```js-repl:1
162+
```js-repl
156163
> console.log("Hello") // 文字列を表示する
157164
Hello
158165
@@ -162,7 +169,6 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
162169
```
163170
````
164171
- 練習問題のファイル名は不都合がなければ `practice(章番号)_(問題番号).拡張子` で統一。空でもよいのでファイルコードブロックとexecコードブロックを置く
165-
- 1章にはたぶん練習問題要らない。
166172

167173
## markdown仕様
168174

package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
"packages/*"
88
],
99
"scripts": {
10-
"dev": "npm run cf-typegen && npm run generateDocsMeta && npm run copyAllDTSFiles && npm run removeHinting && next dev",
11-
"build": "npm run cf-typegen && npm run generateDocsMeta && npm run copyAllDTSFiles && npm run removeHinting && next build",
10+
"prebuild": "npm run cf-typegen && tsx ./scripts/checkDocs.ts && tsx ./scripts/generateDocsMeta.ts && tsx ./scripts/copyAllDTSFiles.ts && tsx ./scripts/removeHinting.ts",
11+
"dev": "npm run prebuild && next dev",
12+
"build": "next build",
1213
"start": "next start",
1314
"lint": "npm run cf-typegen && next lint",
1415
"tsc": "npm run cf-typegen && tsc",
15-
"format": "prettier --write app/",
16-
"generateDocsMeta": "tsx ./scripts/generateDocsMeta.ts",
17-
"copyAllDTSFiles": "tsx ./scripts/copyAllDTSFiles.ts",
18-
"removeHinting": "tsx ./scripts/removeHinting.ts",
16+
"format": "prettier --write app/ packages/",
17+
"checkDocs": "tsx ./scripts/checkDocs.ts",
1918
"cf-preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview --port 3000",
2019
"cf-deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
2120
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"

scripts/checkDocs.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
mainブランチにpushされた際にGitHub Actionが --write 引数をつけて実行し、
3+
その場合は public/docs/ 以下のドキュメントの各セクションについて、
4+
現在のパス、md5ハッシュ、コミットIDなどを ./public/docs/revisions.yml に追記
5+
セクションIDとページパスの対応関係をデータベースに反映
6+
7+
過去に存在したページが削除されている場合、エラーになります。
8+
その場合は手動でrevisions.ymlを編集し、古いページ名の記述を新しいページ名に置き換える必要がある
9+
(できれば自動化したいが、いい方法が思いつかない)
10+
11+
Dockerfile内で --check-diff 引数をつけて実行され、
12+
revisions.ymlが最新の状態でないならexit(1)をし、dockerのビルドを停止します
13+
14+
なにも引数をつけずに実行した場合(npm run checkDocs)、
15+
変更があってもなにもせず正常終了します
16+
エラーなく全ドキュメントを取得できるかどうかの確認に使います
17+
*/
18+
19+
import { readFile, writeFile } from "node:fs/promises";
20+
import { join } from "node:path";
21+
import {
22+
getMarkdownSections,
23+
getPagesList,
24+
RevisionYmlEntry,
25+
} from "@/lib/docs";
26+
import yaml from "js-yaml";
27+
import { execFileSync } from "node:child_process";
28+
import { existsSync } from "node:fs";
29+
import { getDrizzle } from "@/lib/drizzle";
30+
import { section as sectionTable } from "@/schema/chat";
31+
import "dotenv/config";
32+
33+
let doWrite = false;
34+
let doCheckDiff = false;
35+
if (process.argv[2] === "--write") {
36+
doWrite = true;
37+
} else if (process.argv[2] === "--check-diff") {
38+
doCheckDiff = true;
39+
} else if (process.argv[2]) {
40+
throw new Error(`Unknown arg: ${process.argv[2]}`);
41+
}
42+
43+
const docsDir = join(process.cwd(), "public", "docs");
44+
45+
const commit = execFileSync("git", ["rev-parse", "--short", "HEAD"], {
46+
encoding: "utf8",
47+
}).trim();
48+
49+
const langEntries = await getPagesList();
50+
51+
const revisionsPrevYml = existsSync(join(docsDir, "revisions.yml"))
52+
? await readFile(join(docsDir, "revisions.yml"), "utf-8")
53+
: "{}";
54+
const revisions = yaml.load(revisionsPrevYml) as Record<
55+
string,
56+
RevisionYmlEntry
57+
>;
58+
59+
for (const lang of langEntries) {
60+
for (const page of lang.pages) {
61+
const sections = await getMarkdownSections(lang.id, page.slug);
62+
for (const section of sections) {
63+
if (section.id in revisions) {
64+
revisions[section.id].page = `${lang.id}/${page.slug}`;
65+
if (!revisions[section.id].rev.some((r) => r.md5 === section.md5)) {
66+
// ドキュメントが変更された場合
67+
console.warn(`${section.id} has new md5: ${section.md5}`);
68+
if (doWrite) {
69+
revisions[section.id].rev.push({
70+
md5: section.md5,
71+
git: commit,
72+
path: `public/docs/${lang.id}/${page.slug}/${section.file}`,
73+
});
74+
} else if (doCheckDiff) {
75+
process.exit(1);
76+
}
77+
}
78+
} else {
79+
// ドキュメントが新規追加された場合
80+
console.warn(`${section.id} is new section`);
81+
if (doWrite) {
82+
revisions[section.id] = {
83+
rev: [
84+
{
85+
md5: section.md5,
86+
git: commit,
87+
path: `public/docs/${lang.id}/${page.slug}/${section.file}`,
88+
},
89+
],
90+
page: `${lang.id}/${page.slug}`,
91+
};
92+
} else if (doCheckDiff) {
93+
process.exit(1);
94+
}
95+
}
96+
}
97+
}
98+
}
99+
100+
for (const id in revisions) {
101+
if (!existsSync(join(docsDir, revisions[id].page))) {
102+
console.warn(
103+
`The page slug ${revisions[id].page} previously used by section ${id} does not exist. ` +
104+
`Please replace 'page: ${revisions[id].page}' in public/docs/revisions.yml with new page path manually.`
105+
);
106+
if (doWrite || doCheckDiff) {
107+
process.exit(1);
108+
}
109+
}
110+
}
111+
112+
if (doWrite) {
113+
const drizzle = await getDrizzle();
114+
for (const id in revisions) {
115+
await drizzle
116+
.insert(sectionTable)
117+
.values({
118+
sectionId: id,
119+
pagePath: revisions[id].page,
120+
})
121+
.onConflictDoUpdate({
122+
target: sectionTable.sectionId,
123+
set: { pagePath: revisions[id].page },
124+
});
125+
}
126+
127+
const revisionsYml = yaml.dump(revisions, {
128+
sortKeys: true,
129+
noArrayIndent: true,
130+
});
131+
await writeFile(
132+
join(docsDir, "revisions.yml"),
133+
"# This file will be updated by CI. Do not edit manually, unless CI failed.\n" +
134+
revisionsYml,
135+
"utf-8"
136+
);
137+
}

scripts/updateDocsRevisions.ts

Lines changed: 0 additions & 97 deletions
This file was deleted.

0 commit comments

Comments
 (0)