バグ発生を仮定して
RDiでGitを活用
それでは、RDiとGitを使用した開発の手順を追って見てみよう。ここでは、すでに稼働しているシステムでバグが発生したという想定で作業の流れを見る。
以下のバグが報告されたとする。
●ある日を境にslack にメッセージを送信できなくなった
バグの発生が報告されると、通常はバグ報告書などが作成され、報告書番号が割り振られる。報告書はWordで作成され、共有される場合もあれば、バグトラッキング・システムのチケットとして発行される場合もある。
●バグ報告書番号として108 が発行された
プロジェクト内でバグの影響度や緊急度などを検討したうえで、期限や重要度などが設定されて担当者が割り当てられる。
●担当者がogawaに決定した
担当者はRDiを起動し、masterブランチをチェックアウトする(今回はまだブランチは masterのみ)。必要に応じてリモートの最新コミットをpullしておく。
続いて、バグ修正のためのブランチをmasterブランチから作成する。ブランチ名には、バグ報告書番号を含めて関連付けておく(例:hotfix-108)。
iプロジェクト・パースペクティブを開き、プロジェクトcontoslackで右クリックし、チーム→切り替え→新規ブランチをクリックする。表示されたウィンドウで作成するブランチ名を入力して、「終了」をクリックする(図表30)。
作成したブランチがチェックアウトされていることを確認する(図表31)。
報告書(もしくはチケット)を参照し、バグを理解し、再現したうえで、原因を特定する。今回の問題は、slackにアクセスする際に使用するアクセス・トークンが変更されたため、プログラム内で記述しているアクセス・トークンではアクセス不能になったことが原因だった。
これらを踏まえて修正対象となるプログラムなどを特定し、ソースコードを修正する。不要なコードはコメントアウトせずに削除し、修正コードはどんどん上書きしていく。
修正したソースコードを保管(Ctrl+S)すると、リモート・リコンサイラーによって自動的にIBM iにソースがプッシュされる。ソースのコンパイルは RDi からでも、あるいは 5250 画面からでもどちらでも構わない。
コンパイル後は実行してテストし、修正が不足していれば RDi に戻ってソースを再度修正・保存して、コンパイルおよびテストを繰り返す。
テストが完了したら、いったん修正前と修正後のソースを比較し、修正に問題がないかどうかをコードレベルで確認する。
修正したソースコード(今回はSLACK01.SQLRPGLE)で右クリックし、比較→HEADリビジョンをクリックする。今回の原因となったソースコード内のアクセス・トークンが修正されているのがわかる。図表32の右が修正前、左が修正後のコード。変数AccessTokenの値が変わっていること、変更点はその行のみであることを確認できる)。
修正したコードをGitリポジトリにコミットする。コミット前のリポジトリ内は、図表33のとおりである。
Gitパースペクティブを表示し、Gitステージング・ビューを表示すると、修正したソースコードがまだ未ステージ状態であるとわかる(図表34)。
修正したコードをステージ済みの変更にドラッグ&ドロップし、コメントに必ず報告書番号(もしくはチケット番号)を記載する(あとから報告書番号で参照できるように)。
今回はローカルのリポジトリにコミットすると同時に、リモート・リポジトリにも修正をプッシュするので、コミットしてプッシュをクリックする(図表35)。
プッシュ先およびプッシュ内容の確認画面で、「終了」をクリックする(図表36、図表37)。
プッシュ結果が表示されるので確認する(図表38)。
チェックアウト
Gitではコミットするごとに修正されたファイルがリポジトリに保存されていくが、ブランチ名を指定して、ワークツリーをそのブランチの最終修正ファイルの状態にできる。これを「チェックアウト」という。
今回はブランチが2つあり(masterとhotfix-108)、現在はhotfix-108がチェックアウトされているので、masterブランチをチェックアウトしてみよう。
まず現在の状態を履歴ビューで確認する(図表39)。
メッセージ欄にhotfix-108と表示されているが、HEAD も同一行に表示されているので、現在のワークツリーはhotfix-108であることがわかる。
次に、masterと表示されている行で右クリックし、チェックアウトをクリックする。すると履歴ビューの表示が、図表40のようになる。
masterの行にHEADも表示されているので、現在のワークツリーはhotfix-108の修正前の状態に戻っている。
上記の履歴表示ではhotfix-108の行が表示されていないが、すべてを表示するには履歴ビューの右側のすべてのブランチとタグの表示アイコンをクリックする(図表41)。
ブランチ戦略
ブランチ戦略とは、Gitを使用して開発する場合にブランチをどのように構成して利用するかという取り決めのことである。
あらかじめ決められた名称のブランチを定義して役割をもたせ、開発者が守るべきルールを決めておく。開発者は、必ずそのルールに基づいて作業を実行する必要がある。共通のルールを守って開発することで、不要なコンフリクトが起こるのを防いだり、マージ・ミスを回避できる。
有名なブランチ戦略としては、以下がよく知られている。
Git-flow
Git-flow は、以下に示す5種類のブランチを中心に運用するブランチ戦略として最も有名である。ブランチ戦略といえばGit-flowと言われるぐらい、よく利用されている。
1. master
2. release
3. feature
4. develop
5. hot-fix
Git-flow は多種多様な開発プロジェクトを想定しており、優れた仕組みであるが、その反面、複雑になっている感は否めない。とくにIBM iの基幹システム開発プロジェクトには少し複雑すぎるように思う。
Git-flowの詳細は、「A successful Git branching model」を参考にされたい。
GitHub Flow
GitHub Flow は、使用するブランチの種類を厳選し、リリースすることを前提に考えられたブランチ戦略である。ブランチはmasterブランチと、作業(修正)チケットに関連付けられたブランチの2種類で構成される。
master(main)ブランチは本番環境で稼働しているコードで、このブランチに直接コミットされないように運用する。
修正ブランチはプログラムにバグが発生したり、新しい機能の開発が発生するたびに、バグ報告書や開発設計書、あるいはチケット発行で発生する番号を元に作成されるブランチで、常にmasterブランチから生成される。
GitHub Flow を使用した開発手順は、以下のとおりである(図表42)。
①ローカルでmasterブランチをチェックアウトし、リモートの最新状態をプルする
② バグ報告書やチケット等が発行されると、その番号を使用したブランチをmasterから作成する
③ 担当者は、作成したブランチ上でコード修正などを行う(masterブランチとは異なるので本番稼働のコードには一切影響しない)
④ テストが完了して対応が終了すると、リモート・ブランチ上でmasterへのPR/MR を出す
⑤管理者はコード・レビュー、コンフリクトの有無などをチェックして、masterにマージする(その際、マージ元のブランチは削除する)
⑥master ブランチへのマージ・コミットに対してバージョン番号のタグを作成する
⑦管理者がmasterの最新コードを本番環境にリリースする
masterがBの状態のときにバグが発生し、hotfix-xxxブランチが作成されて修正が行われている。その途中で新機能要望があり、同じmasterのB(hotfix-xxxの修正は反映されていない)から 、feature-xxxブランチが作成されてその作業が行われる。
バグ修正が完了したら、hotfix-xxxブランチをmasterブランチにマージして、そのコードが本番環境にリリースされる。
hotfix-xxxの修正のないfeature-xxxの機能追加が完了すると、このブランチもmaster ブランチにマージする。マージするmasterブランチにはバグ修正のコードがすでに反映されている(E)ので、マージ結果(F)には、hotfix-xxx および feature-xxx の両方が反映される。
上記の例でコンフリクトが発生する可能性があるのは、feature-xxxをmasterにマージするタイミングだろう。しかし、マージは常にリモート・リポジトリ上のプル・リクエスト/マージ・リクエストを前提とするルールに則れば、その段階でコンフリクトの可能性のあるコードはマージ実行前に発覚する。
その場合は、hotfix-xxxの担当者とfeature-xxx の担当者でコンフリクトしたコードを互いに検証し、どう修正すべきかを検討したうえで、hotfix-xxx側でそのコードを修正してから、再度 PR/MR を実施してマージすることになるだろう。
ここまで、Gitを使ったIBM iのソースコード管理について解説してきた。SEUを使用した開発では難しい「ソースコードの見える化」が実現できることを理解いただけたであろうか。
冒頭に記したように、本稿では以下を最終目標に掲げた。
❶SEU からの脱却(RDi で説明)
❷コードの修正履歴をいつでも確認可能にする
❸バグや新機能追加作業を、チームの他メンバーの作業に影響することなくいつでも自由に実行可能にする
❹作業途中でも他メンバーに引き継げるようにする
❺開発途中のコードと現在本稼働しているコードをそれぞれ管理可能にする
❻修正箇所を客観的に他メンバーに見てもらえるようにする
❼リリース記録をリリース番号で管理する
❶は、RDi を使うことで24×80の画面制約から解放され、Gitとの連携も可能になるので、SEU では難しいことが数多く実現できる。
❷はGitそのものの機能になるが、過去のコミットと比較してどこを変更したか、追加あるいは削除したかを確認できる。RDiとEGitを使用することで、履歴もビジュアルに確認することが可能だ。
❸は、ブランチを個別に分けることで実現可能である。
❹はリモート・ブランチを経由して、開発および修正途中のブランチを共有できるので、関連仕様書(チケット)と合わせて他のメンバーにスムーズに仕事を引き継げる(前の担当者がコードのどこを変更したかは、ブランチの修正履歴を見ればすぐにわかる)。
❺は、共通のブランチ戦略(本番環境のコードはmasterで管理し、修正および新機能は個別のブランチを作成してそこで作業する)のルールを守ることで実現できることも理解いただけたと思う。
❻は、リモート・リポジトリを管理するサーバー上で PR/MR を要求することで、リリース前に確認可能であることにも触れた。
❼は、master ブランチにリリース・タグをつけることで実現できる。これにより、「現在本稼働しているバージョンは v1.23.45677」などと表現できるようになる。
今回は RDi を使用して解説したが、FF RPGに限定すれば Microsoft Visual Studio Code(以下、VSCode)とGit+sftpの組み合わせでも同様のことが実現できるので、興味のある人はぜひ挑戦してほしい。
以上、ごく基本的な内容についてRDiを中心に解説してきたが、実際の開発現場で実践するには、これだけではやはり心もとない。Gitについては、Gitの解説書「Pro Git」が「Git 公式サイト」(https://git-scm.com/book/ja/v2)で公開されているので、ぜひ参考にしてほしい。
IBM iというOSやRPG は確かに特殊かもしれないが、言語レベルで考えれば開発方法や開発環境は共通であるべきだし、それが可能だということがおわかりいただけたと思う。
EclipseやVSCode などの開発環境・エディタと、Gitなどのバージョン管理システムを使用した開発が、1日も早くIBM iの世界でも当たり前になってほしいと願ってやまない。
著者|
小川 誠氏
ティアンドトラスト株式会社
常務取締役
1989年、エス・イー・ラボ入社。その後、1993年にティアンドトラストに入社。システム/38 から IBM i まで、さまざまな開発プロジェクトに参加。またAS/400 、IBM i の機能拡張に伴い、他プラットフォームとの連携機能開発も手掛ける。IBM i 関連の多彩な教育コンテンツの作成や研修、セミナーなども担当。2021年6月から現職。
[i Magazine・IS magazine]