CI/CD ツールの一つである TeamCity のインストール手順等を記載します。
インストール
こちらからダウンロードします。.tar.gz
をダウンロードした場合は以下のように起動します。
Tomcat を起動するために Java8 が必要なため、インストールします。
sudo yum install java-1.8.0-openjdk-devel
export JAVA_HOME=/usr/lib/jvm/java-1.8.0
解凍して起動します。
tar zxvf TeamCity-2017.2.4.tar.gz
cd TeamCity/
bin/runAll.sh start
jps -m
ポート番号を確認して HTTP でアクセスします。
sudo netstat -ltnp
curl http://192.168.56.10:8111/
初回起動時
DB を選択します。動作確認等を目的としている場合は外部 DB を用意する必要はなく Java の HSQLDB が利用できます。
Administrator アカウントを作成します。あるいは、teamcity-server.log に記載されているトークンを用いて super user でログインすることもできます。
[username@localhost TeamCity]$ grep 'token' logs/teamcity-server.log | tail -1
[2018-06-11 14:26:12,393] INFO - jetbrains.buildServer.SERVER - Super user authentication token: "6809741467420593932". To login as Super user use an empty username and this token as a password on the login page.
ドキュメントの参照
Jenkins のプロジェクト (ジョブ) と異なり、TeamCity のプロジェクトは複数の Build Configuration を持ちます。ビルドで実行するシェルコマンド等は、Build Configuration 内の Build Step に記載します。
Build Configuration 内で TeamCity 記法を用いる
ビルド設定 (Build script) 内で TeamCity と連携することができます。標準出力に特定のフォーマットで連携用の文字列を出力します。例えば、Build step で Command Line
を選択している場合は以下のようにしてエラーメッセージを出力できます。
echo "-----"
echo "##teamcity[message text='Hello world' errorDetails='xxxx' status='ERROR']"
echo "-----"
Run した後に Build Log を確認すると以下のようなメッセージが確認できます。
[19:47:08]The build is removed from the queue to be prepared for the start
[19:47:08]Collecting changes in 1 VCS root
[19:47:08]Starting the build on the agent Default Agent
[19:47:08]Clearing temporary directory: /home/username/TeamCity/buildAgent/temp/buildTmp
[19:47:08]Free disk space requirement
[19:47:08]Publishing internal artifacts
[19:47:08]Using vcs information from agent file: c72794c3eb687f22.xml
[19:47:08]Checkout directory: /home/username/TeamCity/buildAgent/work/c72794c3eb687f22
[19:47:08]Updating sources: auto checkout (on server)
[19:47:09]Step 1/1: my-step-1 (Command Line)
[19:47:09][Step 1/1] Starting: /home/username/TeamCity/buildAgent/temp/agentTmp/custom_script8069562897406100923
[19:47:09][Step 1/1] in directory: /home/username/TeamCity/buildAgent/work/c72794c3eb687f22
[19:47:09][Step 1/1] -----
[19:47:09]
[Step 1/1] Hello world
xxxx
[19:47:09][Step 1/1] -----
[19:47:09][Step 1/1] Process exited with code 0
[19:47:09]Publishing internal artifacts
[19:47:09]Build finished
グラフを生成する
buildStatisticValue 用いて、グラフを生成できます。
echo "##teamcity[buildStatisticValue key='mykey1' value='123']"
Build Configuration の Statistics タブを開いて Add new chart することでグラフを追加できます。
以下はビルドを三回実行した後のグラフです。
また、ビルド結果詳細画面の Parameters タブ内の Reported statistic values から結果を確認できます。
REST API の利用
TeamCity の REST API が利用できます。基本的なドキュメントは存在しますが、詳細は /httpAuth/app/rest
以下のドキュメント用のエンドポイントから取得することになっています。
This documentation is not meant to be comprehensive, but just provide some initial knowledge useful for using the API.
https://confluence.jetbrains.com/display/TCD10/REST+API
TeamCity にログインした状態で、以下の URL を開きます。
http://192.168.56.10:8111/httpAuth/app/rest
http://192.168.56.10:8111/httpAuth/app/rest/server ←エンドポイントをhrefで辿ることができます
http://192.168.56.10:8111/httpAuth/app/rest/application.wadl ←指定可能なリクエストパラメータの情報 (分からないときはここを参照)
また、以下の情報は TeamCity10.x のドキュメント情報をもとにしています。9.x では存在しない機能もいくつか存在するため注意します。
- https://confluence.jetbrains.com/display/TCD10/REST+API
- https://confluence.jetbrains.com/display/TCD9/REST+API
例えば 10.x では Swagger 形式で上記エンドポイントの最後の情報を JSON で取得できます。
http://192.168.56.10:8111/httpAuth/app/rest/swagger.json
また、10.x では $help
を locator に指定することで適宜エンドポイントの使用方法のヘルプを得ることができます。例えば以下のようにヘルプを得ます。
$ curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/server' | jq . | grep 'agents' -A3
"agents": {
"href": "/httpAuth/app/rest/agents"
},
$ curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/agents' | jq .
{
"count": 1,
"href": "/httpAuth/app/rest/agents",
"agent": [
{
"id": 1,
"name": "Default Agent",
"typeId": 1,
"href": "/httpAuth/app/rest/agents/id:1",
"webUrl": "http://192.168.56.10:8111/agentDetails.html?id=1&realAgentName=Default%20Agent&agentTypeId=1"
}
]
}
$ curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/agents/$help'
Responding with error, status code: 400 (Bad Request).
Details: jetbrains.buildServer.server.rest.errors.LocatorProcessException: Locator help requested: Supported dimensions are: [id, name, connected, authorized, enabled, parameter, ip, pool, build, compatible, $singleValue, start, count]
Invalid request. Check locator is specified correctly.
認証方法について
個人的に都度利用する場合は TeamCity のログイン用 ID とパスワードを利用して認証することができます。そうではなく、ビルド時に API を利用するためには、以下のような記法を用います。
%system.teamcity.auth.userId%
ビルド時にのみ有効なユーザ ID に置換されます%system.teamcity.auth.password%
ビルド時にのみ有効なパスワードに置換されます
その他にも %
で利用可能な変数は存在しており、適宜組み合わせます。
%teamcity.serverUrl%
ビルドしている TeamCity の URL%teamcity.build.id%
ビルド番号
設定例
curl -sS -XGET -u '%system.teamcity.auth.userId%:%system.teamcity.auth.password%' -H 'Accept: application/json' '%teamcity.serverUrl%/httpAuth/app/rest/builds/id:%teamcity.build.id%'
locator の構造
dimension
というキーと value 値を :
で区切ります。複数指定する場合は ,
を利用します。()
で入れ子にすることもできます。
<dimension1>:<value1>,<dimension2>:<value2>,<dimension3>:(<dimension3.1>:<value3.1>,<dimension3.2>:<value3.2>)
value が ,
を含んでいる場合は ()
で囲むことで回避できます。
<dimension>:(xxx,yyy)
あるいは 10.x では base64 でエンコードすることでも回避できます。
$ curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/agents/id:1'
$ echo '1' | base64
MQ==
$ curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/agents/id:($base64:MQ==)'
JSON の取得
Accept: application/json
ヘッダーを指定することで JSON 形式で取得できます。既定値は XML です。
取得したいフィールドの指定
fields
パラメータを指定しない場合はエンドポイントに応じた形式で locator を指定するだけです。条件に合致する複数のビルド情報を取得する場合は以下のようになります。
curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/builds?locator=buildType:Myproject_Mybuildconfiguration'
既定の状態では含まれないフィールドが存在します。また、用途によっては不要なフィールドも存在します。将来的な TeamCity エンドポイントの仕様変更にも対応できるようにするために、必要なフィールドは明示的に指定します。
curl -sS -XGET -u myuser:mypass -H 'Accept: application/json' 'http://192.168.56.10:8111/httpAuth/app/rest/builds?locator=buildType:Myproject_Mybuildconfiguration&fields=build(id,statistics(property(name,value)))'
fields
には JSON の階層構造に対応した形式の文字列を指定します。上記 build(id,statistics(property(name,value)))
を指定すると以下のようなレスポンスが得られます。本ページで登録した mykey1
という統計情報も取得できていることが分かります。
{
"build": [
{
"id": 12,
"statistics": {
"property": [
{
"name": "ArtifactsSize",
"value": "13847"
},
{
"name": "BuildDuration",
"value": "1488"
},
{
"name": "BuildDurationNetTime",
"value": "150"
},
{
"name": "buildStageDuration:artifactsPublishing",
"value": "360"
},
{
"name": "buildStageDuration:buildFinishing",
"value": "53"
},
{
"name": "buildStageDuration:buildStepRUNNER_2",
"value": "150"
},
{
"name": "buildStageDuration:firstStepPreparation",
"value": "26"
},
{
"name": "buildStageDuration:sourcesUpdate",
"value": "618"
},
{
"name": "BuildTestStatus",
"value": "1"
},
{
"name": "mykey1",
"value": "123"
},
{
"name": "SuccessRate",
"value": "1"
},
{
"name": "TimeSpentInQueue",
"value": "17"
}
]
}
},
{
"id": 11,
"statistics": {
"property": [
{
"name": "ArtifactsSize",
"value": "13841"
},
{
"name": "BuildDuration",
"value": "1436"
},
{
"name": "BuildDurationNetTime",
"value": "170"
},
{
"name": "buildStageDuration:artifactsPublishing",
"value": "361"
},
{
"name": "buildStageDuration:buildFinishing",
"value": "44"
},
{
"name": "buildStageDuration:buildStepRUNNER_2",
"value": "170"
},
{
"name": "buildStageDuration:firstStepPreparation",
"value": "25"
},
{
"name": "buildStageDuration:sourcesUpdate",
"value": "540"
},
{
"name": "BuildTestStatus",
"value": "1"
},
{
"name": "mykey1",
"value": "123"
},
{
"name": "SuccessRate",
"value": "1"
},
{
"name": "TimeSpentInQueue",
"value": "33"
}
]
}
},
{
"id": 10,
"statistics": {
"property": [
{
"name": "ArtifactsSize",
"value": "13662"
},
{
"name": "BuildDuration",
"value": "1310"
},
{
"name": "BuildDurationNetTime",
"value": "143"
},
{
"name": "buildStageDuration:artifactsPublishing",
"value": "402"
},
{
"name": "buildStageDuration:buildFinishing",
"value": "51"
},
{
"name": "buildStageDuration:buildStepRUNNER_2",
"value": "143"
},
{
"name": "buildStageDuration:firstStepPreparation",
"value": "28"
},
{
"name": "buildStageDuration:sourcesUpdate",
"value": "438"
},
{
"name": "BuildTestStatus",
"value": "1"
},
{
"name": "mykey1",
"value": "123"
},
{
"name": "SuccessRate",
"value": "1"
},
{
"name": "TimeSpentInQueue",
"value": "36"
}
]
}
}
]
}