※サーバー版はこの手順の対象外。サーバー版はこちらを参照。
Atlassianのデベロッパーサイトに情報はある。
しかし、基本部分だけがまとまっている情報源があまりないので、最低限の簡単なアドオンをつくる流れをメモします。
Node.js + Expressでのアプリ開発知識が前提。
1. 環境準備
テスト環境
公式サイト: Development Setup
簡単には、次のとおり。
テスト環境の取得:http://go.atlassian.com/cloud-dev
開発モードの設定:"Manage add-ons"の"Setting"で"Enable development mode"を有効に
アドオンのインストール確認:"Manage add-ons"の"Upload add-on"で"https://ac-static-tutorial.aerobatic.io/atlassian-connect.json" を入力
ローカルデプロイ環境
公式サイト: Developing locally
Node.jsのインストール
Mac
brew install node
Windows
http://nodejs.org/download/
ngrokのインストール
npm install -g ngrok
2. スケルトン作成
公式サイト: Tutorial: Display your projects in JIRA
ACE(Atlassian-Connect-Express)のインストール
npm install -g atlas-connect
スケルトン作成
atlas-connect new -t [name]
cd [name]
npm install
3. Hello World作成
公式サイト: Tutorial: Display your projects in JIRA
設定ファイル(atlassian-connect.json)の変更
[xxx]の部分は入力。
"system.top.navigation.bar"
は画面上部のメニューバーにメニューがでる設定。
"condition": "user_is_logged_in"
はログインしたときだけアクセスできる設定。
"authentication"
はアドオンとJIRAの連携の際の認証。例えば、JIRAのIssueをAPIで取得して利用するアドオンの場合は認証が必要(この記事では対象外。使う場合はTutorial: Display your projects in JIRA参照)。
{
"key": "[key]",
"name": "[name]",
"description": "[description]",
"vendor": {
"name": "[vendor name]",
"url": "[vendor url]"
},
"baseUrl": "{{localBaseUrl}}",
"links": {
"self": "{{localBaseUrl}}/atlassian-connect.json",
"homepage": "{{localBaseUrl}}/atlassian-connect.json"
},
"authentication": {
"type": "none"
},
"modules": {
"generalPages": [
{
"key": "[page key]",
"location": "system.top.navigation.bar",
"name": {
"value": "[page name]"
},
"url": "/[ページの相対パス]",
"conditions": [{
"condition": "user_is_logged_in"
}]
}
]
}
}
メニューをドロップダウンして表示する場合は、modules
部分を次のようにするとよい。
"modules":{
"webItems":[
{
"name":{
"value":"Main"
},
"location":"system.top.navigation.bar",
"url":"/abc",
"key":"jira-dropdown"
}
],
"generalPages":[
{
"name":{
"value":"Action A"
},
"url":"/actiona",
"key":"jira-actiona",
"location":"jira-dropdown/jira-section",
"weight":1
},
{
"name":{
"value":"Action B"
},
"url":"/actionb",
"key":"jira-help",
"location":"jira-dropdown/jira-section",
"weight":2
}
],
"webSections":[
{
"name":{
"value":"Main Section"
},
"location":"jira-dropdown",
"key":"jira-section"
}
]
}
node.jsのルーティング設定(index.js)
1つめのapp.get
はルートにアクセスするとatlassian-connect.json
を返す設定。
2つめのapp.get
は/hello-world
にアクセスするとhello-world.hbs
を返す設定(atlas-connect new
はhtmlテンプレートにhbsが設定される)。
module.exports = function (app, addon) {
app.get('/', function (req, res) {
res.format({
'text/html': function () {
res.redirect('/atlassian-connect.json');
},
'application/json': function () {
res.redirect('/atlassian-connect.json');
}
});
});
app.get('/hello-world', addon.authenticate(), function (req, res) {
res.render('hello-world');
}
);
};
hbsの作成
layout.hbs
をみるとわかるが、AUI(Atlassian User Interface)が読み込まれているので、画面の装飾はAUIを使うのが基本。
もちろん、Bootstrapなどを入れてもよいが、AUIの方がAtlassian製品に組み込んだときに違和感がない。
{{!< layout}}
<h1>{{title}}</h1>
4. 動作確認
ローカル
node app.js
次のURLで動作確認
http://localhost:3000
http://localhost:3000/hello-world
テスト環境で確認
ngrok http 3000
このときに出力されるhttpsのForwardingのURLをメモする。
https://xxxxxxxx.ngrok.io -> localhost:3000
メモしたURLをconfig.jsonの"localBaseUrl"に設定する
"localBaseUrl": "https://xxxxxxxx.ngrok.io"
はじめに作成した「テスト環境」で"Manage add-ons"の"Upload add-on"で"https://xxxxxxxx.ngrok.io" を入力
5. Herokuへのデプロイ
ローカルで動作確認ができたら、Herokuなどにデプロイする。
Herokuの場合はProcfileが作成されているので、後はatlassian-connect.json
のbaseUrl
をherokuのデプロイ先URLにして、herokuにデプロイすればよい。
heroku login
heroku create [name]
git checkout -b heroku
atlassian-connect.json
のbaseUrl
をhttp://[name].herokuapp.com
に変更。
git add .
git commit -m "Change baseUrl for heroku"
git remote add heroku https://git.heroku.com/[name].git
git push heroku heroku:master
6. DBの利用
Atlassian-connectでは、次の制限があるが、少量のデータは自前でDBを用意しなくても使うことができる。自前でDBを用意する場合は、セキュリティ設定などが必要で手間がかかるので、簡単なアプリを作る場合には便利だ。
- 他のアドオンとデータの共有はできない
- データは100個までで、各データ32KBまで
- データ形式はJSONのみ
- ログインされている場合だけ、AP.requestによってAPIアクセスできる
- 同時更新時の対応はなく、その場合は後勝ち
API
まず、アドオンがホストされるAtlassian CloudのURL(baseUrl)を取得する。
var baseUrl;
$( function() {
// Get parameters from query string
// and stick them in an object
function getQueryParams( qs ) {
qs = qs.split( "+" ).join( " " );
var params = {},
tokens,
re = /[?&]?([^=]+)=([^&]*)/g;
while ( tokens = re.exec( qs ) ) {
params[ decodeURIComponent( tokens[ 1 ] ) ] =
decodeURIComponent( tokens[ 2 ] );
}
return params;
}
var params = getQueryParams( document.location.search );
baseUrl = params.xdm_e + params.cp;
console.log( 'baseUrl', baseUrl );
} );
次のこのbaseUrlにAP.request
を使ってREST APIをたたく。
- [baseUrl]/rest/atlassian-connect/1/addons/{addonKey} [GET]
- [baseUrl]/rest/atlassian-connect/1/addons/{addonKey}/properties [GET]
- [baseUrl]/rest/atlassian-connect/1/addons/{addonKey}/properties/{propertyKey} [GET, PUT, DELETE]
var getX = function() {
AP.request( baseUrl + '/rest/atlassian-connect/1/addons/T4T/properties/x', {
success: function( d ) {
console.log( 'get done', d );
},
error: function( d ) {
console.log( 'get error', d );
}
} );
}