以前作った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万回問い合わせした時、何回正解できたかをスコアにしています。


