Jenkins ジョブを GitHub Actions 上で動かせるようになりました
概要
Jenkins を GitHub Actions 上で動かすアクションを作りました。
まだ動かない機能もあると思いますが Jenkins から GitHub Actions へ移行する際の選択肢になるといいのかなと思っています。
作ったアクション
設計
CI を移行する際に何が大変かというと異なる言語で書かれた設定ファイルの移植です。
なのでそもそも移植をしなくて済むように Jenkins そのものを Docker Compose で構築して GitHub Actions ランナー上で走らせています。
覚えることを増やさないように独自の機能はほとんど入れていませんので Jenkins の知識があれば大体のことはできるのではないかと思います。
セットアップウィザードをスキップするため認証機能はオフになっています。
操作は Jenkins CLI で行うのが楽です。
Remote Access API も使えますが認証がないので Crumb の発行が必要です。
使い方
既存ジョブ
既存ジョブがある場合は $JENKINS_HOME/jobs/*/config.xml
をコピーしリポジトリにコミットしておきます。
steps:
- uses: actions/checkout@v3
- uses: snow-actions/setup-jenkins@v1.0.0
- run: wget $JENKINS_URL/jnlpJars/jenkins-cli.jar
- run: java -jar jenkins-cli.jar -webSocket install-plugin http_request -deploy
- run: java -jar jenkins-cli.jar -webSocket create-job job-1 < path/to/config.xml
- run: java -jar jenkins-cli.jar -webSocket build job-1 -f -v -p param_1=p1
Credentials 等が必要な場合は後述する JCasC や Remote Access API で設定できます。
Jenkins Configuration as Code (JCasC)
従来の Jenkins は GUI で設定を行い JENKINS_HOME
配下に設定ファイルが保存されてきました。(前項で使用した config.xml
もこれです)
これらの設定を人が読みやすいコードで管理する (as Code) ためのプラグインです。
JCasC で管理する場合はリポジトリに jenkins.yaml
をコミットしておき、そのディレクトリへのパスを jenkins_home
に指定します。
拡張子は .yaml であることに注意してください。
jobs:
- script: |
pipelineJob('job-2') {
definition {
cpsScm {
scm {
git {
remote {
url('https://github.com/jenkinsci/job-dsl-plugin.git')
}
branch('*/master')
}
}
lightweight()
}
}
}
steps:
- uses: actions/checkout@v3
- uses: snow-actions/setup-jenkins@v1.0.0
with:
jenkins_home: ./jenkins_home
- run: java -jar jenkins-cli.jar -webSocket build job-2 -f -v
Jenkins コンテナにアクセス
Docker Compose で起動している Jenkins コンテナにもアクセスできます。
COMPOSE_FILE
環境変数が設定されるようになっているのでそのまま docker compose
コマンドが使用できます。
コンテナ名は jenkins
です。
環境変数を取得したりミドルウェアをインストールしたり。
steps:
- uses: snow-actions/setup-jenkins@v1.0.0
- run: docker compose exec jenkins printenv
- run: docker compose exec -u root jenkins apt-get update
- run: docker compose exec -u root jenkins apt-get install -y awscli
Credentials
GitHub Actions では秘匿情報は Secrets に保存します。
一度ファイルに出力して env_file
に指定することで Docker Compose の env_file 経由でコンテナへ環境変数を渡せます。
その環境変数を jenkins.yaml
で使用することができます。
steps:
- uses: actions/checkout@v3
- run: echo "PAT=${{ secrets.PAT }}" >> .env
- uses: snow-actions/setup-jenkins@v1.0.0
with:
jenkins_home: ./jenkins_home
env_file: .env
- run: java -jar jenkins-cli.jar -webSocket build job-3 -f -v
credentials:
system:
domainCredentials:
- credentials:
- usernamePassword:
id: pat
scope: GLOBAL
username: "SnowCait"
password: "${PAT}"
jenkins:
globalNodeProperties:
- envVars:
env:
- key: BRANCH
value: main
jobs:
- script: |
pipelineJob('job-3') {
definition {
cps {
script('''\
pipeline {
agent any
stages {
stage('checkout') {
steps {
checkout scm: [
$class: 'GitSCM',
branches: [[ name: "${env.BRANCH}" ]],
userRemoteConfigs: [
[
url: 'https://github.com/SnowCait/private-repository.git',
credentialsId: 'pat'
]
]
]
}
}
}
}
'''.stripIndent())
sandbox()
}
}
}
Jenkinsfile の Lint
Jenkins には Declarative Pipeline の Linter があります。
steps:
- uses: actions/checkout@v3
- uses: snow-actions/setup-jenkins@v1.0.0
- run: java -jar jenkins-cli.jar -webSocket declarative-linter < path/to/Jenkinsfile
Jenkins の機能
先にコードは紹介してしまいましたがジョブを実行するには Jenkins CLI や Remote Access API が使用できます。
Jenkins CLI
ジョブの実行には Jenkins CLI が便利です。基本的にはこちらを使うのをおすすめします。
$JENKINS_URL/cli/
にアクセスすると詳しいドキュメントがあります。
立ち上げた Jenkins から Jenkins CLI クライアント (jenkins-cli.jar
) をダウンロードします。
Jenkins の URL は JENKINS_URL
環境変数にセットされています。
steps:
- uses: actions/checkout@v3
- uses: snow-actions/setup-jenkins@v1.0.0
with:
jenkins_home: jenkins_home
- run: wget $JENKINS_URL/jnlpJars/jenkins-cli.jar
- run: java -jar jenkins-cli.jar -webSocket help
- run: java -jar jenkins-cli.jar -webSocket build job-1 -f -v -p param_1=p1
Remote Access API
認証がないので Crumb の発行が必要ですが REST API としてアクセスできます。
steps:
- uses: actions/checkout@v3
- uses: snow-actions/setup-jenkins@v1.0.0
with:
jenkins_home: jenkins_home
- run: |
crumb=$(curl -s -c cookie $JENKINS_URL/crumbIssuer/api/json)
echo "CRUMB_HEADER=$(echo $crumb | jq -r '.crumbRequestField'): $(echo $crumb | jq -r '.crumb')" >> $GITHUB_ENV
- run: curl -X POST -H "$CRUMB_HEADER" -b cookie $JENKINS_URL/api/json | jq '.jobs'
- run: curl -X POST -H "$CRUMB_HEADER" -b cookie $JENKINS_URL/job/job-1/build
実行速度
推奨プラグインのインストールを含めても1分以内で立ち上がるのでそこそこ現実的なのではないでしょうか。
プラグインを最小限にできるようになるともうちょっと速くなりそうです。
どこまで動く?
現時点で把握している動作しない(と思われる)機能としては Docker です。
これは Jenkins を Docker で立ち上げているため Docker in Docker (DinD) になってしまうことが原因です。
何かしら対応はできるのかもしれませんが、Docker で動いているものは GitHub Actions へ移植する難易度も低いと思うので対応優先度は低めです。
まだ最低限の確認しかしていないので他にも色々と動かないと思いますが追々対応していきます。
正直どこまで動くか分からないので試した方がいればここのコメントか Discussion にでも気軽に報告いただけると助かります。
感想
Discussion