以前作ったCI環境に一手間加えて、自社の社員が楽しみながらJavaを学べるような環境を整えてみた。
できるだけ手軽にJavaのプログラムを体験できるように準備しました。
構成
今回のシステムの構成はこのような感じ。
- 生徒がgitlabにソースコードをプッシュする
- gitlab-ci.yamlにジョブを登録しておき、適当な環境でコードをコンパイル、実行する
- 実行結果をslackに投稿
パイプライン設定
前回ci環境を整えた後色々調べた所、gitlabのrunnerの設定を変更すればプリインストールされているpowershellを使えることがわかった。
それも踏まえて、下記のようなパイプラインを構築してみた。
下記のパイプラインを参考にする場合、絶対に不特定多数がアクセスできるようにはしないでください
gitlab-ci.yamlのサンプル
variables:
CHAT_SCRIPT: 'C:\GitLab-Runner\local_scripts\chat.py'
CHECK_SCRIPT: 'C:\GitLab-Runner\local_scripts\score.py'
VENV_PATH: 'C:\GitLab-Runner\local_scripts\venv\Scripts\activate.ps1'
JAVAC_HOME: 'C:\gitlab-runner\jdk-17.0.2\bin\'
default:
before_script:
- CHCP 65001
stages: # List of stages for jobs, and their order of execution
- build
- run
cache:
untracked: true
build-job: # This job runs in the build stage, which runs first.
stage: build
tags:
- windows
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
script:
- $PSDefaultParameterValues['Out-File:Encoding'] = 'ascii'
- gci *.java -Recurse | Get-ItemPropertyValue -Name FullName > files.log
- '& "$($env:JAVAC_HOME)javac.exe" "@files.log" -encoding UTF-8'
after_script:
- '& "$env:VENV_PATH"'
- $player_name = git log --pretty=format:"%an" -1
- python "$env:CHAT_SCRIPT" "$player_name" "$env:CI_JOB_STATUS"
calc-score-job: # This job runs in the test stage.
stage: run # It only starts when the job in the build stage completes successfully.
tags:
- windows
script:
- '& "$($env:JAVAC_HOME)java.exe" -cp ./src/main/java com.practice.numberguesser.Main > result.log'
- '& "$env:VENV_PATH"'
- $player_name = git log --pretty=format:"%an" -1
- python "$env:CHECK_SCRIPT" "$player_name"
artifacts:
paths:
- result.log
expire_in: 1 day
パイプライン解説
パイプラインと言うよりpowershellの解説って言ったほうが近いかも。
- variablesにJavaのパスを登録してある理由
- 環境の再現性を取りやすいという建前、ユーザを指定してのgitlabサービスを何故か建てれなかったってのが本音
-
CHCP 65001
- powershellの使用する文字コードをUTF-8に変更する。gitlab上での表示を文字化けさせないようにするために必要。
-
$PSDefaultParameterValues['Out-File:Encoding'] = 'ascii'
- PowershellのパイプラインはUTF-16という圧倒的な取り回しの悪さなのでUTF-8で読み込めるように設定
-
gci *.java -Recurse | Get-ItemPropertyValue -Name FullName > files.log
- コンパイル対象のコードを一覧取得してファイルに格納する。
-
'& "$($env:JAVAC_HOME)javac.exe" "@files.log" -encoding UTF-8'
- 上で書いた対象ファイルをコンパイルする。gitのエンコーディングは基本的にUTF-8となる。
-
$player_name = git log --pretty=format:"%an" -1
- 最後にコミットした人物名を出力するコマンド(git log以降)をプレイヤー名として記録
-
'& "$($env:JAVAC_HOME)java.exe" -cp ./src/main/java com.practice.numberguesser.Main > result.log'
- コンパイルされたバイナリを実行する場合、クラスパスのルートを指定しなければきちんと動かないので注意。
pythonのコードはslackにメッセージを送るためのコードでした。公式のAPIにメッセージの送り方までコードが載っているので読んで参考にしました。
ちなみに今回使ったコードはここで見れるようにしています。
大雑把に説明するとハイアンドロー形式で数字を当てるときの効率の良さを競う感じにしています。
その結果を標準出力経由でファイルに出力して、点数をslackに乗せています。
投稿サンプル
slackの様子はこんな感じ。
100までの数字のハイアンドローの数あてゲームで10万回問い合わせした時、何回正解できたかをスコアにしています。