コピペでつくるGitサーバーとCI/CD環境（Gitea＋Jenkins）

# 追記
実例サンプルつくりました
**[GiteaとJenkinsによるCI/CDの実例サンプル（Python / PHP / Perl でテストとデプロイを自動化する）](https://qiita.com/bashaway/items/16ef713fdbd30ecbcab8)**

# はじめに
「いまあるリポジトリからブランチきって進めてくれればいいよ」
よくある会話なんですよね？これって。

やりかたが分からずコマンドレベルで教えてもらいました。ずびばぜん。。。
ナウでヤングな開発をしたかったのでGitのべんきょうをしようとおもいました。

ついでにテストとかデプロイとかの自動化をしたかったので、環境を構築してみました。
手段の目的化ばんざい！
べろべろーとコピペすると、VPSやらオンプレ環境でGitサーバ＋CIツールが使えるようになります。

# このエントリを読むとできること
以下のような処理を自動的に行えるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/8d62ce71-e5ab-5702-a966-4decd1a9207a.png)

1. orginizationという組織のrepo-Aリポジトリにpushすると、、、
2. GiteaからSlackおよびJenkinsのwebhookをたたく
3. Jenkinsではrepo-Aにpushがあったという通知をGiteaプラグインが受ける
4. pushされたrepo-AにJenkinsfileがあるかチェックする
5. Jenkinsfileがあればそれをもとにpipeline処理を行う
6. pipeline処理の結果を判別し
7. JenkinsからSlackのwebhookをたたく

ということができる。

「CI/CDする」までは解説できていませんので、「CI/CDができる環境を作る」です（よね？）
この環境を構築したうえで、ちゃんとテスト自動化できるようなコードを書いたりpipeline処理を書いたり、デプロイを自動化するための処理を書いたりすることで、「CI/CDする」んだと思います。


本エントリの解説では、組織単位で発生する全イベントでwebhookをたたくようになっているので、

* リポジトリごとに設定したり
* ブランチ毎に設定したり
* マージされた場合だけという設定をしたり

とやっていくと、必要なことができるようになるんではないかとおもいます。

あと、pipeline処理の結果はマークダウン形式で常時確認できるので、リポジトリのREADME.mdに書いておけば、そのリポジトリ（のブランチ）の状態がわかるようになる。

こんな感じで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/f3e6f867-118a-0083-adc5-ba8b0227d0c9.png)



# 対象機器および環境

## 検証環境
* CentOS8 (8.2.2004)
* Gitea (1.13.0+dev-389-ge17e3f71f)←記事作成時点のMasterブランチものです
* Jenkins (2.251)


## 構築パラメータ

私用環境で検証しています。
FQDNやらポート番号やらは、必要に応じて修正してください。
（あとで紹介するコピペコマンドを修正する必要があります）

|項目|Gitリポジトリマネージャ|CI/CDツール|
|:-:|:-:|:-:|
|Software|Gitea|Jenkins|
|Path|/opt/gitea|/opt/jenkins|
|Port|3000|8080|
|User|gitea|gitea|
|FQDN(A)|vmnetserv03.prosper2.net|vmnetserv03.prosper2.net|
|FQDN(CNAME)|gitea.prosper2.net|jenkins.prosper2.net|


また、GiteaとJenkinsを動作させるために、以下のユーザを新規作成します。
適当なユーザがいれば、それを利用してもOKですが、シェルが必要なので、nobodyなどの `/sbin/nologin` や `/bin/false` ではダメです。

|項目|値|
|:-:|:-:|
|ユーザ名|gitea|
|グループ名|gitea|
|Shell|/bin/bash|
|Home|/opt/gitea|

## 注意事項

すべてHTTPでつくっています。（GitはSSHですけど）
HTTPSでやるなら証明書発行したり、Nginxでsslをかぶせたりしてください。
プライベートPKIを利用するなら、JenkinsがJAVAなのでkeytoolでルートとか中間のCAをトラストストアに追加するか、チェーン済み証明書をNginxに配置するなど工夫してください。


# 作業内容

## CentOS8の準備
CentOS8をクリーンインストールしておく。（最小構成でOK）
[ESXi6.7にCentOS8を最小構成で構築](https://qiita.com/bashaway/items/ed9997629d5b02cfca05) 


## サーバ構築

さぁ、コピペの時間だ。

あ、コピペコマンドが長くなるのがイヤだったので、 `sudo` してません。
すべて `root` で作業してください。

### 事前準備

* タイムゾーンの修正
* SELinuxを無効
* 動作に必要なソフトウェアのインストール
* nginxのサービス登録と起動
* Giteaユーザの追加

```
timedatectl set-timezone Asia/Tokyo
sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
shutdown -r now

firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload
dnf install -y nginx
systemctl enable nginx
systemctl start nginx
useradd --user-group --shell /bin/bash --home-dir /opt/gitea gitea

```

### Giteaの構築

* gitのインストール
* 必要なディレクトリを作成
* Giteaのバイナリを取得
* GiteaのServiceファイルを作成し、サービス登録と起動
* Nginx設定ファイルを作成し、サービス再起動

```
dnf install -y git
mkdir -p /opt/gitea/{gitea-repositories,data,custom,log}
curl -L https://dl.gitea.io/gitea/master/gitea-master-linux-amd64 -o /opt/gitea/gitea
chmod 755 /opt/gitea/gitea
chown -R gitea.gitea /opt/gitea

cat <<EOF > /usr/lib/systemd/system/gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target

[Service]
RestartSec=2s
Type=simple
User=gitea
Group=gitea
WorkingDirectory=/opt/gitea/
ExecStart=/opt/gitea/gitea web --config /opt/gitea/custom/conf/app.ini -p 3000
Restart=always
Environment=USER=gitea HOME=/opt/gitea GITEA_WORK_DIR=/opt/gitea

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start gitea
systemctl enable gitea


cat <<'EOF' > /etc/nginx/conf.d/gitea.conf
server {
    listen 80;
    server_name gitea.prosper2.net;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}
EOF
systemctl restart nginx

```

### Jenkinsの構築

* javaのインストール
* 必要なディレクトリを作成
* Jenkinsのwarファイルを取得し展開
* JenkinsのServiceファイルを作成し、サービス登録と起動
* Nginx設定ファイルを作成し、サービス再起動

```
dnf install -y java-11-openjdk-devel java-11-openjdk

mkdir -p /opt/jenkins/{data,web} /var/log/jenkins
curl -L https://updates.jenkins-ci.org/latest/jenkins.war -o /opt/jenkins/jenkins.war
cd /opt/jenkins/web
jar -xf /opt/jenkins/jenkins.war
chown -R gitea.gitea /opt/jenkins /var/log/jenkins

cat <<EOF > /usr/lib/systemd/system/jenkins.service
[Unit]
Description=Jenkins Automation Server
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/usr/bin/java -jar /opt/jenkins/jenkins.war --webroot=/opt/jenkins/web --httpPort=8080 --logfile=/var/log/jenkins/jenkins.log
User=gitea
Restart=always
RestartSec=300s
Environment="JENKINS_HOME=/opt/jenkins/data"

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start jenkins
systemctl enable jenkins

cat <<'EOF' > /etc/nginx/conf.d/jenkins.conf
server {
    listen 80;
    server_name jenkins.prosper2.net;

    location / {
      proxy_set_header        Host $host:$server_port;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      # Fix the "It appears that your reverse proxy set up is broken" error.
      proxy_pass          http://127.0.0.1:8080;
      proxy_read_timeout  90;

      proxy_redirect      http://127.0.0.1:8080 jenkins.prosper2.net;

      # Required for new HTTP-based CLI
      proxy_http_version 1.1;
      proxy_request_buffering off;
      # workaround for https://issues.jenkins-ci.org/browse/JENKINS-45651
      add_header 'X-SSH-Endpoint' 'jenkins.prosper2.net:50022' always;
    }
  }
EOF
systemctl restart nginx

```

## 各サーバの初期設定

### Giteaのセットアップとユーザ追加

Giteaに設定したFQDNへブラウザでHTTPでアクセスする（今回の例では http://gitea.prosper2.net/ ）

登録アイコンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/fea82863-edc8-b6bc-5268-39005fedb8b3.png)

設定していく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d42b09fa-db62-eba4-6ac3-11b51039915c.png)

以下のように変更して、画面下部の「Giteaをインストール」をクリック

|項目|値|
|:-:|:-:|
|データベースのタイプ|SQLite3|
|SSHサーバーのドメイン|gitea.prosper2.net|
|GiteaのベースURL|http://gitea.prosper2.net/|

インストール後はこんな画面なので、
「アカウントが必要ですか？ 今すぐ登録しましょう。」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d51567c4-5faf-b83d-5fdb-2205b04d0ad1.png)

ユーザ名 `gitadmin` を登録する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/7cf9656e-0d12-1c7a-aaa4-1b319c8e5529.png)

こうなればとりあえずOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/51e6cd27-c57d-5f51-f6e6-46518abb5b00.png)

組織を作成するので、画面右上の「＋」のアイコンから「新しい組織」を選択して、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/e714f35a-9524-8190-9242-0aeaec512b09.png)

test_org として組織を作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/f4692f84-59e5-1dde-6610-b27d704622fd.png)



### Giteaの設定ファイルのチューニング

Giteaの設定ファイルは `/opt/gitea/custom/conf/app.ini` にあります。

ここに以下を追加することで、リポジトリ内のファイルやIssueの検索ができるようになります。

```:/opt/gitea/custom/conf/app.ini
----8<----(snip)----8<----
[indexer]
ISSUE_INDEXER_TYPE   = bleve
ISSUE_INDEXER_PATH   = indexers/issues.bleve
REPO_INDEXER_ENABLED = true
REPO_INDEXER_PATH    = indexer/repos.bleve
UPDATE_BUFFER_LEN    = 20
MAX_FILE_SIZE        = 1048576
----8<----(snip)----8<----
```

ここに以下を追加することで、OpenID利用の停止と、ユーザが自由に登録することができなくなります。
（つまり、ユーザを追加するには、最初に作成したユーザで追加するようになります）

```:/opt/gitea/custom/conf/app.ini
以下を変更する
----8<----(snip)----8<----
[openid]
;ENABLE_OPENID_SIGNIN = true
;ENABLE_OPENID_SIGNUP = true
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[service]
;DISABLE_REGISTRATION = false
DISABLE_REGISTRATION = true
----8<----(snip)----8<----
```



こうしてからGiteaを再起動します。

```
systemctl restart gitea
```


### Giteaに公開鍵を登録

もし自分の秘密鍵を生成していない場合には、`ssh-keygen -t rsa -b 4096`などで生成しておく。

```
# cat ~/.ssh/id_rsa.pub
ssh-rsa AAAA（うんちゃらかんちゃら）7iQ== root@vmnetserv01.prosper2.net
```
これをコピーしておく。

SSH鍵の登録は、画面右上のアイコンから「設定」を選択して、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/081168bf-b210-696e-19ef-61c45573e17b.png)

上部メニュのSSH/GPGキーから「キーを追加」を選択して、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/2e28e5fe-b5d9-1919-f1c1-9627a8d5c824.png)

ここに先ほどの公開鍵をはりつけて「キーを追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/0d4c7971-a625-770a-722e-23bc84e3d464.png)

これでキーが追加できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/65472b4b-6b41-c061-d6df-4a52bd12d51c.png)


### GiteaにSlackのwebhookを登録する（組織単位）

ここでは特定の組織に対して共通のwebhookを設定します。

Slack投稿用のチャネルを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/01da0331-d2e6-81da-c1b7-3fc9b5c46aeb.png)

適当に入力して「作成」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d39876d7-9ca6-54ae-9056-c7d9dad8b16f.png)

Slackアプリ管理画面（ https://api.slack.com/apps ）の「Create New App」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/9f8ba0c5-bacb-2f27-81c9-3e761a913f96.png)

アプリ名と自分のワークスペースを選択して「Create App」する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/6568e573-0a36-81a6-db69-8dabf1a71319.png)

Basic Information → Building Apps for Slack → Add features and functionality → Incoming Webhooks
 を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/9fe25cd4-2254-5779-12d7-31e27c9405d2.png)

作成したては「Off」になっているので、これを「On」にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/c61e793d-84e5-d528-5ce5-f6fd133b8150.png)

スクロールして下部の「Add New Webhook to Workspace」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/b2a7eb5b-e174-1100-9b3f-9ca019a1d79e.png)

先ほど作成したチャネルを指定して「許可する」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/90dc1f1e-4e3c-c466-e097-acdb75a0235c.png)

Slackアプリから「App」を選択して、giteaがいるか確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d5c507aa-0073-fb90-1551-d2278c60fd8f.png)

以下のように追加されたら、curlコマンドをコピペしてターミナルから発行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/7d2c8112-aac5-503e-e793-d9546c74fcdb.png)

通知がくれば成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/ff8aa9c6-7644-c7e9-0d04-6a15f3473d91.png)

組織のwebhookを設定するので、先ほど作成して「test_org」を表示させ、組織名の横にある歯車マークをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/9dbb41a4-24d3-baa9-1727-052c588478ec.png)

設定メニュの「webhook」から「webhookを追加」の「Slack」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/7bf13b8c-3fff-79f5-515d-7d652c815a8c.png)

ターゲットURLに先ほど作成したSlackのURL（curlじゃないほう）を、チャネルにSlackアプリを追加したチャネル（#gitea）を設定し、最下部の「有効」にチェックをいれ、「webhookを追加」します。
（テストなので、すべてのイベント、すべてのブランチとしています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/95772615-02c7-fe07-db56-cdd8a0b8198a.png)

これで、この組織に関連するイベントはすべてSlackに投稿されることになります。
ためしにリポジトリを作成するので、画面右上のプラスマークから「新しいリポジトリ」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/1ff71c14-2eb5-f359-c9f9-c93531eaab61.png)

オーナーを「test_org」リポジトリ名を「sample」として作成する。（それ以外は空欄でOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d30d9a3c-ec71-491e-ab2c-33a72a76a567.png)

すると、おなじみの指示が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/97810e25-a4ad-88dd-2609-3232a8a0124f.png)

同時にSlackにも通知がくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/6a56f6e6-101e-4ea4-25e8-6fe32610a3ce.png)

なんか通知が２通きてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/c6b6c220-5b58-5210-509d-ecbb43a95aec.png)

これのような気もしますが、closeしてるしなぁ。。。
https://github.com/go-gitea/gitea/issues/9183



### GiteaにJenkinsのwebhookを登録する

GiteaのイベントをJenkinsに通知するためのwebhookを設定します。Slackのwebhookとだいたい同じです。

組織の設定メニュからwebhookを追加します（webhookの種別は「gitea」を選択します。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/a18c818b-0b3e-94bc-42a6-745dd6de2a0e.png)

ターゲットURLは http://jenkins.prosper2.net/gitea-webhook/post のように設定し、最下部の「有効」にチェックをいれ、「webhookを追加」します。
（テストなので、すべてのイベント、すべてのブランチとしています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/9a826f42-0972-3d77-96e2-f53373f5d7b1.png)


### Jenkinsのセットアップとユーザ追加

Jenkinsに設定したFQDNへブラウザでHTTPでアクセスする（今回の例では http://jenkins.prosper2.net/ ）

こんな画面になっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/16275bac-8abe-d3d1-e576-f18d121fdf10.png)

初期パスワードはJenkinsをインストールしたサーバにあるので、これを入力

```
# cat /opt/jenkins/data/secrets/initialAdminPassword
b2546555f9184c4a8a28266b4cac7628
```

インターネット接続環境があれば、「Install Suggested plugins」を選ぶと勝手によさげなものをダウンロードしてくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/01ec706f-e438-3367-f3c1-6a7d6fec60ba.png)

プラグインのインストール完了を待つ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/47b2d827-6f9d-82c3-76a8-6f7327e6caf4.png)

ユーザ名 `gitadmin` を登録する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d5bc6efa-32e4-1519-00ba-fac39235b222.png)

このままでOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/3f1fac95-c726-c5a3-7362-30f75408b2b3.png)

「Start Using Jenkins」をクリックすると完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/7d6fc5c8-c250-c988-484a-42362f801120.png)

こうなってればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/81ef2011-85e6-1071-40d6-8acb1f621d66.png)


### Jenkinsにプラグインを追加

ひとまず、以下のプラグインを導入しておく

* Gitea
* Global Slack Notifier
* Embeddable Build Status（ビルド状態のバッヂを追加する）

サイドメニュの「Jenkinsの管理」の「プラグインの管理」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/86a0cd20-9848-02c0-a707-9ffc550486ff.png)

「利用可能」タブを選択してプラグインを検索してインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/00e63f7f-dc20-258b-780d-1539e2ce1392.png)

こんな感じで Global Slack Notifier と Embeddable Build Status もインストールしておく。

### Jenkinsのslackアプリを追加

Slackアプリ管理画面（ https://api.slack.com/apps ）の画面上部の検索窓に「jenkins」と入力して検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/fb418cbf-dd42-45a6-1a80-1013cbee28eb.png)

「Jenkins CI」の部分がリンクになっているので、これをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/a1b5e0a9-acd4-72b1-6f7a-28beac4954d8.png)

「Slackに追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/42e60dd7-2e9e-18aa-25df-1e7b67c74bf1.png)

投稿先は先ほど作成した #gitea とし、「Jenkins CI インテグレーションの追加」をして、画面に従って設定していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/7b0fe03c-c949-2d33-12ea-2c6f83e9f466.png)

Step3にある、「チームサブドメイン」と「インテグレーション用トークン認証情報 ID」があとで必要なので、控えておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/db49ee68-e539-595c-8055-00583d633e7c.png)

「Jenkinsの設定」→「システムの設定」の最下部にSlackがあるので、workspaceとチャネルを入力
（workspaceは先ほどの「チームサブドメイン」もしくは https://[workspace].slack.com/ のworkspaceの部分です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/bef1d3de-1f30-67e9-9fd9-ddd3a76261a9.png)

クレデンシャル情報を追加するために、「追加」→「jenkins」を選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/fcc719ac-162c-9cc4-7f8d-676ec051230e.png)

「種類」を「Secret Text」にして、先ほどの「インテグレーション用トークン認証情報 ID」として登録する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/ea027de8-7bb2-9515-3861-7224467a4f8c.png)

もとの設定画面でクレデンシャル情報を選択して、TestConnectionをクリックする。（成功するとSuccessと表示される）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/43557cf4-94d5-f6ea-5555-3e4a0ef1bf0e.png)


TestConnectionが成功すると、Slackにはこんな通知がくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/3c4bd589-480a-57b3-1bd8-1d324ef7c846.png)

テストのため、ビルド結果のすべてをSlack通知するため、「Jenkinsの設定」→「システムの設定」の中央付近にGlobal Slack Messagesがのすべての欄にチェックをいれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/3c4c20f2-0acf-28ba-1ca5-e19033982540.png)


### Jenkinsのslackアプリが追加できない場合

なんらかの理由でSlackアプリが導入できない場合には、GiteaのSlack設定したときと同じような、
`https://hooks.slack.com/services/（～～なんだかながいやつ～～）` を利用する。

クレデンシャル情報を追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/64464867-31b0-f466-23b3-1225726fda02.png)

「種類」を「Secret Text」にして、`https://hooks.slack.com/services/（～～なんだかながいやつ～～）` の `（～～なんだかながいやつ～～）` を登録する。
（スラッシュが入ったディレクトリ構造になってても、そっくりそのまま全部入れる。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/4e1e7616-10c1-df4e-254c-e20939c02d77.png)

「高度な設定」をクリックして展開する。
「Override url」に `https://hooks.slack.com/services/（～～なんだかながいやつ～～）` の `https://hooks.slack.com/services/` を入力する。
もとの設定画面でクレデンシャル情報を選択して、TestConnectionをクリックする。（成功するとSuccessと表示される）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/2c43a234-e528-75c9-65dd-077f90f40f4d.png)

Slackの通知はこんなかんじ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/442d5998-ffed-78cd-fae8-459237ae6357.png)

Gitea→Slackの通知とまざってよくわからん状態ですが、緑の部分がJenkins→Slack通知のビルド成功、赤の部分がJenkins→Slack通知のビルド失敗です。
Slackアプリでなくても動作できてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/7ad1127a-2b57-808d-2939-4bae1a08147c.png)

以下のようなGroovyスクリプトを JENKINS_HOME/init.groovy.d/slack.groovy においてもよさそうです。

```
// https://javadoc.jenkins.io/plugin/slack/jenkins/plugins/slack/SlackNotifier.DescriptorImpl.html
import jenkins.model.Jenkins
import com.cloudbees.plugins.credentials.domains.Domain
import org.jenkinsci.plugins.plaincredentials.impl.*
import hudson.util.Secret
import com.cloudbees.plugins.credentials.CredentialsScope

def jenkins = Jenkins.getInstance()

def domain = Domain.global()
def store = jenkins.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()

def slackCredentialParameters = [
  description:  'prosper2 slack credential',
  id:           'slack-token',
  secret:       '（ここになんだか長いやつをいれる）'
]

def secretText = new StringCredentialsImpl(
  CredentialsScope.GLOBAL,
  slackCredentialParameters.id,
  slackCredentialParameters.description,
  Secret.fromString(slackCredentialParameters.secret)
)

store.addCredentials(domain, secretText)


def slack = jenkins.getDescriptorByType(jenkins.plugins.slack.SlackNotifier.DescriptorImpl.class)
//slack.setTeamDomain('')
slack.setTokenCredentialId(slackCredentialParameters.id)
slack.setRoom('#gitea')
slack.setBotUser(false)
slack.setSendAsText(false)
slack.setBaseUrl('https://hooks.slack.com/services/')
slack.save()

jenkins.save()
```


## 動作確認してみよう

### README.mdをpushする

先ほど作成した test_org 配下の sample リポジトリに対して、以下のように`README.md`を作成してcommit -> pushする
Giteaではmermaid.jsが利用できるので、この書式を試してみます。

    mkdir -p ~/gitea/sample
    cd ~/gitea/sample
    
    git init
    
    cat <<'EOF' > README.md
    # Markdown Rendering
    
    ## mermaid.js
    
    ```mermaid
    graph TD;
        A(stuff)-->B[one];
        A-->C[two];
        A-->D[three];
    ```
    
    EOF
    
    git add README.md
    git commit -m "first commit"
    git remote add origin gitea@gitea.prosper2.net:test_org/sample.git
    git push -u origin master

すると、Slackに通知がくる（また２通きてる。。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/8b317c76-7d1d-a3d0-d2b5-97bf33d1c57d.png)


webUIからみると、以下のようにみえるはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/c77938da-2e93-e940-dfc6-de8ee5f46604.png)


### リポジトリのpushを検知してJenkinsで自動ビルドさせる

JenkinsがGiteaにアクセスできるようにGiteaでトークンを発行しておく。
右上メニュの「設定」をクリックして、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d3d3bd95-11e5-1dec-e400-b9c2f7a1461b.png)

上部メニュの「アプリケーション」でトークン名を入力して、「トークンを生成」する。
やべぇトークンがゲシュタルト崩壊してきた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/f0d62cdd-0fd8-0384-cc1b-3e0700cf9475.png)

生成されたトークンをひかえておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/d2c50cdc-d33a-2f03-9a8d-3a47a9ed54ab.png)


JenkinsにGiteaサーバを登録するので、「Jenkinsの管理」から「システムの設定」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/75790c69-fb59-f721-1837-1bee0772510e.png)

システム設定の中央付近にある「Gitea Servers」にURLを入力し、設定を保存する。
（きちんと認識されれば、Giteaのバージョン名が表示される。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/b1a6c967-ec94-1f55-df5a-1359c53d20dc.png)

もしくは、Jenkinsの設定ファイルを直接編集します。

```:JENKINS_HOME/org.jenkinsci.plugin.gitea.servers.GiteaServers.xml
<?xml version='1.1' encoding='UTF-8'?>
<org.jenkinsci.plugin.gitea.servers.GiteaServers plugin="gitea@1.2.1">
  <servers/>
</org.jenkinsci.plugin.gitea.servers.GiteaServers>
```

これを

```:JENKINS_HOME/org.jenkinsci.plugin.gitea.servers.GiteaServers.xml
<?xml version='1.1' encoding='UTF-8'?>
<org.jenkinsci.plugin.gitea.servers.GiteaServers plugin="gitea@1.2.1">
  <servers>
    <org.jenkinsci.plugin.gitea.servers.GiteaServer>
      <displayName>test gitea server</displayName>
      <serverUrl>https://www.prosper2.net/gitea</serverUrl>
      <manageHooks>false</manageHooks>
    </org.jenkinsci.plugin.gitea.servers.GiteaServer>
  </servers>
</org.jenkinsci.plugin.gitea.servers.GiteaServers>
```

にします。

新規ジョブを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/dc923b93-ec44-3a3f-8edd-41f6ede047c1.png)

「Enter an item name」に適当な名称を入力し、「Gitea Organization」を選択してOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/f890c6e8-9951-17ae-85a3-d3a35016604a.png)

上部メニュの「Projects」→「Gitea Organization」→「Creadential」→「追加」から先ほど作成したプロジェクト名を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/e06b16a7-c7ca-2b12-52be-48064d000665.png)

トークン入力画面が表示されるので、「種類」を「Gitea Personal Access Token」にして、先ほどGiteaで生成したトークンを「追加」する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/317a3a2f-5837-dee7-4871-fc16c07dd025.png)

Credentialとして追加したトークンを選択し、「Owner」には対象の組織名を入力する。で、保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/12d02536-ec6b-0dc6-91af-ac55795af950.png)

すると勝手に組織内のリポジトリを走査してくれる。
現時点ではsampleというリポジトリが見つかり、そこにJenkinsfileがない、と言われている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/715becd0-82d6-d776-b8d6-7609864c3dbe.png)

なので、このリポジトリにJenkinsfileをpushしてやればよい。

```
cd ~/gitea/sample
    
cat <<'EOF' > Jenkinsfile
pipeline {
  agent any 
  stages {
    stage('First Stage') { 
      steps {
        echo "Build pipeline : First Stage"
      }
    }
  }
}
EOF
    
git add Jenkinsfile
git commit -m "add Jenkinsfile"
git push -u origin master
```

すると、Slackに通知がくる
通知はGiteaにpushされたトリガーでGitea→Slackのwebhookがひとつ（のはずだが、また２通きてる。。。）
もうひとつは、GiteaにpushされたトリガーでGitea→Jenkinsのwebhookを叩いた結果、Jenkinsfileが見つかったので、自動的にビルドされ、その結果をJenkins→Slackのwebhookで通知したもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/9da2de05-a3b4-e863-371b-af751014f776.png)


Jenkinsのビルド履歴にビルドされたログが表示されるので、右端にあるターミナルアイコンをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/ea1541e3-b8da-e15e-ea52-264bfcee4a28.png)


こんな感じでビルド履歴がみれる。
今回は文字列表示のみなので、ログにその文字列が出力されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/3e9b8d7c-5861-cb3a-d518-9abbd4a55a1b.png)


### ビルド状態をGiteaのREADME.mdにバッヂで表示させてみる

画面上部のメニュのネスト表示があり、現在は「#1」のビルド履歴が表示されているが、「master」をクリックして、masterブランチの状態を表示させる。
このときのサイドメニュのEmbeddable Build Statusをクリックすると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/fab0bb34-129a-d255-c3fc-9a3dd6d220e5.png)


こんな感じでいろいろな書き方でバッヂステータスが表現できる。
ので、このなかからMarkdownを見つけて、README.mdに追記してpushしてみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/04a91cd2-2dff-28a0-a9ee-750e9ef34aac.png)

```
cd ~/gitea/sample

vi README.md
（以下を先頭に追記）
----8<----(snip)----8<----    
[![Build Status](http://jenkins.prosper2.net/job/gitea%20build%20test/job/sample/job/master/badge/icon)](http://jenkins.prosper2.net/job/gitea%20build%20test/job/sample/job/master/)
----8<----(snip)----8<----    

git add README.md
git commit -m "add Badge Status"
git push -u origin master
```

ビルド履歴を見るとビルドが走ったことがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/ae89b383-cfd8-b170-9134-e1cbc6337add.png)

Giteaのリポジトリを見ると、バッジが追加されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/c90b9acd-3a3d-e880-a5e5-2954f2ce7ae2.png)



以下のようにJenkinsfileを修正して、ビルドが失敗するようにして、再度pushしてみる。
（echoで文字列を表示させる代わりに、シェルを走らせようとしている。この場合、そんなコマンドは存在しない。）

```
sed -i -e 's/echo/sh/' ./Jenkinsfile
git add Jenkinsfile
git commit -m "mod Jenkinsfile"
git push -u origin master
```

自動的にビルドされるが、失敗している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/79faf830-6ff6-66e8-db0c-525913162f3a.png)

理由はコマンドがみつからないため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/15587f2a-2a93-f57a-fe9d-25e3e0b3d24d.png)


Giteaのステータスもfailingになっている。このバッヂ部分はJenkinsのビルドログへのリンクになっているので、クリックすると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/72a1126c-104b-bd07-125d-56006a32b720.png)

こんな感じでビルド結果がみれるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/2fe586d3-a0ed-ef54-2cd4-da51d8339dbe.png)

SlackにはGiteaにpushされた通知と、ビルドが失敗した通知がきている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334782/bd4bfbd0-7982-a43a-d5c7-fbffb60c09b9.png)



# さいごに
テストとかデプロイの自動化とか、いろいろやりたいことがありすぎてなんなら自前でたてちまえ。ということで全部を足元においてみました。
AnsibleやDockerでも良かったのですが、クリーンインストール直後でもすぐ使えるように、コピペでまとめました。
それに公式のDockerfileならまだしも、個人が作成したDockerfileとかdocker-composeとかって、実は何してんだかよくわかんないなぁ、と思ったりもしました。ので、危険な処理してないよ。という意味も含めてです。

検証をやり直しながら進めたのでスクリーンショットの時系列が一部入れ替わってる部分があります。ごめんなさい。
さて、環境がつくれたので、つぎはテストコードを含めたホントのCIをやるぞぉー。


# 出典
https://docs.gitea.io/en-us/reverse-proxies/
https://wiki.jenkins.io/display/JENKINS/Jenkins+behind+an+nginx+reverse+proxy
https://www.eclipse.org/jetty/documentation/9.4.31.v20200723/startup-unix-service.html
https://gcube.wiki.gcube-system.org/gcube/Gitea/Jenkins:_Setting_up_Webhooks
https://plugins.jenkins.io/slack/