コンテンツにスキップ

[2/5] GiteaでCI/CDパイプラインを構築する アプリケーション構築編

はじめに

この記事はGiteaを使ったCI/CDパイプラインの構築方法を展開する連載の一つである。

連載の各記事へは以下からジャンプできる。

  1. Giteaインストール編
  2. アプリケーション構築編
  3. テスト編
  4. ビルド編
  5. デプロイ編

サンプルアプリケーションとテストコードを用意する

この記事では以下の赤枠部であるサンプルアプリケーションとテストコードのプッシュをやってみよう。

サンプルアプリケーションとして、Honoでバックエンドアプリケーションを作成してみる。

Giteaの画面右上からNew Repositoryを選択する。

Repository Nameにリポジトリ名を設定する。(今回はcicd-exampleとしている。)

開発環境上でプロジェクトを作成する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ npm create hono@latest cicd-example

> npx
> "create-hono" cicd-example

create-hono version 0.19.4
✔ Using target directory  cicd-example
✔ Which template do you want to use? nodejs
✔ Do you want to install project dependencies? Yes
✔ Which package manager do you want to use? npm
✔ Cloning the template
✔ Installing project dependencies
🎉 Copied project files
Get started with: cd cicd-example

作成したプロジェクトをGiteaへプッシュする。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 作成したプロジェクトのディレクトリに移動する
$ cd cicd-example/

# gitを初期化する
$ git init

# リモートリポジトリとしてGiteaで作成したリポジトリを設定する
$ git remote add origin http://${Giteaホスト}/kkawaharanet/cicd-example.git

# 現時点のファイル全てをステージに追加する
$ git add -A

# コミットする
$ git commit -m "initial commit"

# プッシュする
$ git push --set-upstream origin main

以下のようにファイルの一覧を見ることができればプッシュに成功している。

サンプルアプリケーションを実装する

サンプルアプリケーションは1+1の結果をユーザーへ返すことにする。

本当はもっと面白いアプリケーションを作っても良いが、今回はCI/CDパイプライン構築の実践が目的なので超単純化している。

CI/CDパイプラインによる自動テストを実現したいので、テストのしやすい設計を行う。

1+1の結果をユーザーに返すという処理の責務を以下のように分けることにする。

  • 足し算をする
  • 計算結果をユーザーに返す

足し算をする

src/sum.tsに足し算の処理を実装する。

src/sum.ts
1
2
3
4
5
6
7
8
9
/**
 * 足し算をする
 * @param a オペランド
 * @param b オペランド
 * @returns 足し算の結果
 */
export function sum(a: number, b: number): number {
  return a + b;
}

計算結果をユーザーに返す

src/app.tsに足し算APIを実装する。

src/app.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { Hono } from "hono";
import { sum } from "./sum.js";

export const app = new Hono();

/**
 * 足し算API
 */
app.get("/sum", (c) => {
  return c.json({ result: sum(1, 1) });
});

src/index.tsで外部にAPIを公開する。

src/index.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { serve } from "@hono/node-server";
import { app } from "./app.js";

serve(
  {
    fetch: app.fetch,
    port: 3000,
  },
  (info) => {
    console.log(`Server is running on http://localhost:${info.port}`);
  },
);

ビルドチェックを行う

TypeScriptでの開発なので、ビルドエラーを確認できるようにしておく。package.jsonに以下をマージする。

package.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
  "name": "cicd-example",
  "type": "module",
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "typecheck": "tsc --noemit"
  },
  "dependencies": {
    "@hono/node-server": "^1.19.14",
    "hono": "^4.12.17"
  },
  "devDependencies": {
    "@types/node": "^20.11.17",
    "tsx": "^4.7.1",
    "typescript": "^5.8.3"
  }
}

npm run typecheckを実行し、以下のように何もエラーメッセージが出力されなければビルドは問題ない。

1
2
3
4
5
6
$ npm run typecheck

> typecheck
> tsc --noemit

$

動作確認する

npm run devでサーバーを起動する。

1
2
3
4
5
6
$ npm run dev

> dev
> tsx watch src/index.ts

Server is running on http://localhost:3000

Webブラウザでhttp://localhost:3000/sumにアクセスすると、以下のように1+1の結果が返ってくるはずだ。

1
{ "result": 2 }

ここまでのディレクトリ構成は以下のようになっている。

1
2
3
4
5
6
7
8
9
.
├── README.md
├── package-lock.json
├── package.json
├── src
│   ├── app.ts
│   ├── index.ts
│   └── sum.ts
└── tsconfig.json

テストコードを作成する

テストフレームワークにはVitestを使う。Vitestをインストールする。

1
$ npm i -D vitest

vitest.config.tsを作成する。

vitest.config.ts
1
2
3
4
5
6
7
8
/// <reference types="vitest" />
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    exclude: ["dist/**", "node_modules/**"],
  },
});

package.jsonに以下をマージし、アプリケーションにバージョンを設定する。またスクリプトからテストを実行できるようにする。

```json title="package.json" hl_lines="4,10" { "name": "cicd-example", "type": "module", "version": "1.0.0", "scripts": { "dev": "tsx watch src/index.ts", "build": "tsc", "start": "node dist/index.js", "typecheck": "tsc --noemit", "test": "vitest" }, "dependencies": { "@hono/node-server": "^1.19.14", "hono": "^4.12.17" }, "devDependencies": { "@types/node": "^20.11.17", "tsx": "^4.7.1", "typescript": "^5.8.3", "vitest": "^4.1.5" } }

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
テストコードを作成していく。

### 足し算をする処理のテストコードを作成する

`src/sum.test.ts`に`src/sum.ts`のテストコードを作成する。

```ts title="src/sum.test.ts"
import { describe, expect, test } from "vitest";
import { sum } from "./sum.js";

describe("sum", () => {
  test("足し算ができること", () => {
    expect(sum(1, 1)).toBe(2);
  });
});

計算結果をユーザーに返すテストコードを作成する

src/app.test.tssrc/app.tsのテストコードを作成する。

src/app.test.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { describe, expect, test } from "vitest";
import { app } from "./app.js";

describe("足し算API", () => {
  test("正しい足し算の結果を得られること", async () => {
    const response = await app.request("/sum");

    // HTTPステータスコードが200であること
    expect(response.status).toBe(200);

    // 足し算の結果が期待値と一致すること
    const body = await response.json();
    expect(body).toEqual({ result: 2 });
  });
});

ここまでのディレクトリ構成は以下となる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.
├── README.md
├── package-lock.json
├── package.json
├── src
│   ├── app.test.ts
│   ├── app.ts
│   ├── index.ts
│   ├── sum.test.ts
│   └── sum.ts
├── tsconfig.json
└── vitest.config.ts

テストを実行する

npm run testを実行し、テストが成功することを確認する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$ npm run test

> test
> vitest


 DEV  v4.1.2 /path/to/cicd-example

  src/sum.test.ts (1 test) 2ms
  src/app.test.ts (1 test) 15ms

 Test Files  2 passed (2)
      Tests  2 passed (2)
   Start at  14:02:42
   Duration  129ms (transform 33ms, setup 0ms, import 58ms, tests 17ms, environment 0ms)

 PASS  Waiting for file changes...
       press h to show help, press q to quit

tsconfig.jsonを設定する

今後アプリケーションをビルドするときのためにtsconfig.jsonを設定しておく。

```json title="tsconfig.json" hl_lines="12,14" { "compilerOptions": { "target": "ESNext", "module": "NodeNext", "strict": true, "verbatimModuleSyntax": true, "skipLibCheck": true, "types": ["node"], "jsx": "react-jsx", "jsxImportSource": "hono/jsx", "outDir": "./dist", "rootDir": "./src" }, "exclude": ["node_modules", "vitest.config.ts"] }

1
2
3
4
5
6
7
8
### Giteaへプッシュする

テストが通ったらコミットし、Giteaへプッシュしておこう。

```bash
$ git add -A
$ git commit -m "1+1の結果をユーザーに返す処理を作成した"
$ git push

振り返り

今回は結構いろいろなことを行った。

  • サンプルアプリケーションを実装することができた
  • サンプルアプリケーションのテストを実装することができた
  • サンプルアプリケーションをGiteaへプッシュすることができた

次回

次回はいよいよGitea Actionsを使ってCI/CDパイプラインを構築する。

[3/5] GiteaでCI/CDパイプラインを構築する テスト編