LoginSignup
2
2

More than 5 years have passed since last update.

JenkinsでGitのWebhookの情報をシェルの引数として渡すときは"で囲む

Last updated at Posted at 2018-01-17

TL;DR

  • payloadを引数として渡して外部シェルを呼ぶときには${payload}ではなく"${payload}"にする。

 はじめに

GitのWebhookで設定しておくと、Gitにpushがされた時1にJenkinsのJobを走らせることが出来ます。
その時の各種情報はJenkinsのJobではpayloadという名前で取得できます。

このpayloadを外部シェルの引数として渡すときの注意点です。
(外部シェルを呼ぶとき全般に通じる話ですが、今回は私がハマったところということでピンポイントで書いています)

環境

動作環境は以下のとおりです。

  • MacBookAir 10.13.2 HighSierra
  • GitBucket 4.13.0
  • Jenkins 2.101

payload

Gitから渡ってくるpayloadはどんなものかというと、次のようなものになります。
注意)値は書き換えました

payload
'{"pusher":{"name":"","email":"**@**.**"},"sender":{"login":"","email":"**@**.**","type":"**","site_admin":true,"created_at":"20**-**-**T**:**:**Z","url":"http://**/**","html_url":"http://**/**","avatar_url":"http://**/**"}, "ref":"refs/heads/**", "before":"****************************************", "after":"****************************************", "commits":[{"id":"****************************************","message":"hello' world\n","timestamp":"20**-**-**T**:**:**Z","added":[],"removed":[],"modified":["package.json"],"author":{"name":"","email":"**@**.**","date":"20**-**-**T**:**:**Z"},"committer":{"name":"","email":"**@**.**","date":"20**-**-**T**:**:**Z"},"url":"http://**/**"}], "repository":{"name":"**","full_name":"**/**","description":"","watchers":0,"forks":0,"private":true,"default_branch":"**","owner":{"login":"**","email":"**@**","type":"**","site_admin":true,"created_at":"20**-**-**T**:**:**Z","url":"http://**/**","html_url":"http://**/**","avatar_url":"http://**/**"},"forks_count":0,"watchers_count":0,"url":"http://**/**","http_url":"http://**/**","clone_url":"http://**/**","html_url":"http://**/**"}, "compare":"http://**/**", "head_commit":{"id":"****************************************","message":"hello' world\n","timestamp":"20**-**-**T**:**:**Z","added":[],"removed":[],"modified":["package.json"],"author":{"name":"","email":"**@**.**","date":"20**-**-**T**:**:**Z"},"committer":{"name":"","email":"**@**.**","date":"20**-**-**T**:**:**Z"},"url":"http://**/**"}}'

上記のpayloadをjson形式で整形すると次のようになっています。

payload.json
{
  "pusher": {
    "name": "",
    "email": "**@**.**"
  },
  "sender": {
    "login": "",
    "email": "**@**.**",
    "type": "**",
    "site_admin": true,
    "created_at": "20**-**-**T**:**:**Z",
    "url": "http://**/**",
    "html_url": "http://**/**",
    "avatar_url": "http://**/**"
  },
  "ref": "refs/heads/**",
  "before": "****************************************",
  "after": "****************************************",
  "commits": [
    {
      "id": "****************************************",
      "message": "hello' world\n",
      "timestamp": "20**-**-**T**:**:**Z",
      "added": [],
      "removed": [],
      "modified": [
        "package.json"
      ],
      "author": {
        "name": "",
        "email": "**@**.**",
        "date": "20**-**-**T**:**:**Z"
      },
      "committer": {
        "name": "",
        "email": "**@**.**",
        "date": "20**-**-**T**:**:**Z"
      },
      "url": "http://**/**"
    }
  ],
  "repository": {
    "name": "**",
    "full_name": "**/**",
    "description": "",
    "watchers": 0,
    "forks": 0,
    "private": true,
    "default_branch": "**",
    "owner": {
      "login": "**",
      "email": "**@**",
      "type": "**",
      "site_admin": true,
      "created_at": "20**-**-**T**:**:**Z",
      "url": "http://**/**",
      "html_url": "http://**/**",
      "avatar_url": "http://**/**"
    },
    "forks_count": 0,
    "watchers_count": 0,
    "url": "http://**/**",
    "http_url": "http://**/**",
    "clone_url": "http://**/**",
    "html_url": "http://**/**"
  },
  "compare": "http://**/**",
  "head_commit": {
    "id": "****************************************",
    "message": "hello' world\n",
    "timestamp": "20**-**-**T**:**:**Z",
    "added": [],
    "removed": [],
    "modified": [
      "package.json"
    ],
    "author": {
      "name": "",
      "email": "**@**.**",
      "date": "20**-**-**T**:**:**Z"
    },
    "committer": {
      "name": "",
      "email": "**@**.**",
      "date": "20**-**-**T**:**:**Z"
    },
    "url": "http://**/**"
  }
}

JenkinsのPipelineから外部シェルを呼ぶときの引数で使う

ジョブの方でパラメータとして設定したら、Pipelineでも使えます。

Jenkins_ビルドのパラメータ化.png

この時payloadをダブルクォーテーションで囲むようにします。

jenkins.groovy
stage("パブリッシュ") {
sh '''export TOOLS_DIR
export payload
hoge="HOGE"

RUNNING=`./fuga.sh "${payload}" ${hoge}`

echo RUNNING'''
}

出力結果

上述のコードで呼び出されるfuga.shは次のコードです。

fuga.sh
payload=$1
hoge=$2

echo "${payload}"
echo "${hoge}"

payloadが長すぎるので省略しますが、意図したとおりの出力結果になります。

'{"pusher":・・・
HOGE

"(ダブルクォーテーション)で囲まない場合

payloadの途中に半角スペースとかが入っていると、渡される値が変わります。
具体的には、半角スペースの位置で切れて渡ってしまうので、次の様になります。

'{"pusher":・・・
world\n",・・・

上述のpayloadcommits.messagehello' world\nとなっており、worldの前で途切れました。
HOGEがほしかったのに、違う値が入ってきてしまいました。

おわりに

個人的な背景としては、昔作ったシェル2を使いまわしたかったのでそのままpayloadを渡しました。
でも、必要な値が決まっているなら、payloadをパースして必要な値だけ渡すようにした方がいいと思います。

ただし、結局必要な値に半角スペースが挟まっているのならダブルクォーテーションで囲む必要はあるので、どうせなら囲んでおいたほうが良いと思います。


  1. 設定によります。私はpushの時のみにしていることが多いです。 

  2. payloadをそのまま受け取って、正規表現で色々と判定しています。 

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2