読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

TypeScriptのプロジェクトをAzure Web Appにgitデプロイする

TypeScriptのプロジェクトをgit使ってdeployしたいなぁと思います。

問題点

TypeScriptのプロジェクトではgitにJSが含まれてない。でもAzureにはJSをpushしないといけない。

とった対策

デプロイ用ブランチを作って、そこでJS追加してデプロイした。

デプロイするプロジェクト

yoコマンドでExpress TSで作られたプロジェクトにします。

blog.okazuki.jp

プロジェクトの作成

AzureYoっていう名前でyoコマンドでプロジェクトを作りました。作ったら、gulp, gulp-typescriptを--save-devで追加して、以下のgulpfile.jsを追加してビルドできるようにしておきます。

var gulp = require('gulp');
var ts = require('gulp-typescript');

gulp.task('build', function() {
    var p = ts.createProject('./tsconfig.json');
    return gulp.src('./src/**/*.ts')
        .pipe(ts(p))
        .js
        .pipe(gulp.dest('./app'));
});

tsd installしてビルドして成功することを確認します。

F5を押して実行してみて、http://localhost:3000/にアクセスして起動することも確認しましょう。

gitの準備

リポジトリを作ります。

git init
git add .
git commit -m "init"

Azure WebAppの作成

適当に作ります。ここら辺はぐぐって。

Deployment credentials(英語設定でポータル使ってまるのでそれっぽい日本語のやつで)を設定して、Continuous deploymentでLocal Git Repositoryを選択しておきます。

gitの準備 その2

git clone urlをコピーして以下のコマンドでリモートを登録します。

git remote add azure コピーしたURL

deploy用ブランチを作って、そっちに移動します。

git branch deploy
git checkout deploy

appフォルダに移動して強制的に(.gitignoreされててもおかまいなし)*.jsをコミットします。

cd app
git add *.js -f
git commit -m 'add js'
cd ..

デプロイ

最後にデプロイします。

git push azure deploy:master

package.jsonから起動するjsファイルを勝手に見つけてくれたり、web.configを空気を読んで作ってくれたりします。こんな感じのログが出ます。

PS > git push azure deploy:master
Password for リポジトリのURL:443':
Counting objects: 30, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (24/24), done.
Writing objects: 100% (30/30), 5.42 KiB | 0 bytes/s, done.
Total 30 (delta 1), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '82478efd87'.
remote: Generating deployment script.
remote: Generating deployment script for node.js Web Site
remote: Generated deployment script files
remote: Running deployment command...
remote: Handling node.js deployment.
remote: KuduSync.NET from: 'D:\home\site\repository' to: 'D:\home\site\wwwroot'
remote: Deleting file: 'hostingstart.html'
remote: Copying file: '.gitignore'
remote: Copying file: 'bower.json'
remote: Copying file: 'gulpfile.js'
remote: Copying file: 'package.json'
remote: Copying file: 'tsconfig.json'
remote: Copying file: 'tsd.json'
remote: Copying file: '.vscode\launch.json'
remote: Copying file: 'app\app.js'
remote: Copying file: 'app\bin\www.js'
remote: Copying file: 'app\routes\index.js'
remote: Copying file: 'app\views\error.jade'
remote: Copying file: 'app\views\index.jade'
remote: Copying file: 'app\views\layout.jade'
remote: Copying file: 'src\app.ts'
remote: Copying file: 'src\tsd.d.ts'
remote: Copying file: 'src\bin\www.ts'
remote: Copying file: 'src\routes\index.ts'
remote: Using start-up script app/bin/www.js from package.json.
remote: Generated web.config.
remote: The package.json file does not specify node.js engine version constraints.
remote: The node.js application will run with the default node.js version 4.2.3.
remote: .....................
remote: app@0.1.0 D:\home\site\wwwroot
remote: +-- body-parser@1.14.2
remote: ¦ +-- bytes@2.2.0
remote: ¦ +-- content-type@1.0.1
remote: ¦ +-- depd@1.1.0
remote: ¦ +-- http-errors@1.3.1
remote: ¦ ¦ +-- inherits@2.0.1
remote: ¦ ¦ +-- statuses@1.2.1
remote: ¦ +-- iconv-lite@0.4.13
remote: ¦ +-- on-finished@2.3.0
remote: ¦ ¦ +-- ee-first@1.1.1
remote: ¦ +-- qs@5.2.0
remote: ¦ +-- raw-body@2.1.5
remote: ¦ ¦ +-- unpipe@1.0.0
remote: ¦ +-- type-is@1.6.10
remote: ¦   +-- media-typer@0.3.0
remote: ¦   +-- mime-types@2.1.9
remote: ¦     +-- mime-db@1.21.0
remote: +-- cookie-parser@1.4.0
remote: ¦ +-- cookie@0.2.2
remote: ¦ +-- cookie-signature@1.0.6
remote: +-- debug@2.2.0
remote: ¦ +-- ms@0.7.1
remote: +-- express@4.13.3
remote: ¦ +-- accepts@1.2.13
remote: ¦ ¦ +-- negotiator@0.5.3
remote: ¦ +-- array-flatten@1.1.1
remote: ¦ +-- content-disposition@0.5.0
remote: ¦ +-- cookie@0.1.3
remote: ¦ +-- depd@1.0.1
remote: ¦ +-- escape-html@1.0.2
remote: ¦ +-- etag@1.7.0
remote: ¦ +-- finalhandler@0.4.0
remote: ¦ +-- fresh@0.3.0
remote: ¦ +-- merge-descriptors@1.0.0
remote: ¦ +-- methods@1.1.1
remote: ¦ +-- parseurl@1.3.0
remote: ¦ +-- path-to-regexp@0.1.7
remote: ¦ +-- proxy-addr@1.0.10
remote: ¦ ¦ +-- forwarded@0.1.0
remote: ¦ ¦ +-- ipaddr.js@1.0.5
remote: ¦ +-- qs@4.0.0
remote: ¦ +-- range-parser@1.0.3
remote: ¦ +-- send@0.13.0
remote: ¦ ¦ +-- depd@1.0.1
remote: ¦ ¦ +-- destroy@1.0.3
remote: ¦ ¦ +-- mime@1.3.4
remote: ¦ +-- serve-static@1.10.0
remote: ¦ +-- utils-merge@1.0.0
remote: ¦ +-- vary@1.0.1
remote: +-- jade@1.11.0
remote: ¦ +-- character-parser@1.2.1
remote: ¦ +-- clean-css@3.4.9
remote: ¦ ¦ +-- commander@2.8.1
remote: ¦ ¦ ¦ +-- graceful-readlink@1.0.1
remote: ¦ ¦ +-- source-map@0.4.4
remote: ¦ ¦   +-- amdefine@1.0.0
remote: ¦ +-- commander@2.6.0
remote: ¦ +-- constantinople@3.0.2
remote: ¦ ¦ +-- acorn@2.7.0
remote: ¦ +-- jstransformer@0.0.2
remote: ¦ ¦ +-- is-promise@2.1.0
remote: ¦ ¦ +-- promise@6.1.0
remote: ¦ ¦   +-- asap@1.0.0
remote: ¦ ???-- mkdirp@0.5.1
remote: ¦ ¦ +-- minimist@0.0.8
remote: ¦ +-- transformers@2.1.0
remote: ¦ ¦ +-- css@1.0.8
remote: ¦ ¦ ¦ +-- css-parse@1.0.4
remote: ¦ ¦ ¦ +-- css-stringify@1.0.5
remote: ¦ ¦ +-- promise@2.0.0
remote: ¦ ¦ ¦ +-- is-promise@1.0.1
remote: ¦ ¦ +-- uglify-js@2.2.5
remote: ¦ ¦   +-- optimist@0.3.7
remote: ¦ ¦   ¦ +-- wordwrap@0.0.3
remote: ¦ ¦   +-- source-map@0.1.43
remote: ¦ +-- uglify-js@2.6.1
remote: ¦ ¦ +-- async@0.2.10
remote: ¦ ¦ +-- source-map@0.5.3
remote: ¦ ¦ +-- uglify-to-browserify@1.0.2
remote: ¦ ¦ +-- yargs@3.10.0
remote: ¦ ¦   +-- camelcase@1.2.1
remote: ¦ ¦   +-- cliui@2.1.0
remote: ¦ ¦   ¦ +-- center-align@0.1.2
remote: ¦ ¦   ¦ ¦ +-- align-text@0.1.3
remote: ¦ ¦   ¦ ¦ ¦ +-- kind-of@2.0.1
remote: ¦ ¦   ¦ ¦ ¦ ¦ +-- is-buffer@1.1.1
remote: ¦ ¦   ¦ ¦ ¦ +-- longest@1.0.1
remote: ¦ ¦   ¦ ¦ ¦ +-- repeat-string@1.5.2
remote: ¦ ¦   ¦ ¦ +-- lazy-cache@0.2.7
remote: ¦ ¦   ¦ ??-- right-align@0.1.3
remote: ¦ ¦   ¦ +-- wordwrap@0.0.2
remote: ¦ ¦   +-- decamelize@1.1.2
remote: ¦ ¦   ¦ +-- escape-string-regexp@1.0.4
remote: ¦ ¦   +-- window-size@0.1.0
remote: ¦ +-- void-elements@2.0.1
remote: ¦ +-- with@4.0.3
remote: ¦   +-- acorn@1.2.2
remote: ¦   +-- acorn-globals@1.0.9
remote: +-- morgan@1.6.1
remote: ¦ +-- basic-auth@1.0.3
remote: ¦ +-- depd@1.0.1
remote: ¦ +-- on-headers@1.0.1
remote: +-- serve-favicon@2.3.0
remote:
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
To https://okazuki@okazukinode.scm.azurewebsites.net:443/okazukinode.git
 * [new branch]      deploy -> master

アクセスして動作確認

URLにアクセスすると、動いてます。ちゃんとできてますね。

f:id:okazuki:20160111134031p:plain

運用どうするの?

masterの変更をdeployにマージしてappフォルダで毎回git add *.js -fしてcommitしてpushという流れになるのかなぁ。個人的にはもっといい感じにやりたい。

実際にやってみます。

一旦masterブランチに移動します。

git checkout master

そして、src/routes/index.tsをちょっと改造します。

import * as express from 'express';
const router = express.Router();

/* GET home page. */
router.get('/',(req,res,next) => {
  res.render('index', {title: 'Express'});
});

// 追加
router.get('/hoge', (req, res, next) => {
    res.send(200, 'Hello world');
});

export default router;

F5を押してローカルでhttp://localhost:3000/hogeにアクセスしてHello worldと出るか確認をします。

コミットをします。

git add .
git commit -m 'change index.ts'

deployブランチにマージします。

git checkout deploy
git merge deploy master

ビルドしてコミットします。

cd app
git add *.js -f
git commit -m 'change'

pushします。

git push azure deploy:master

/hogeにアクセスしてHello worldと出れば更新成功。

f:id:okazuki:20160111134914p:plain

まとめ

もっといいやり方募集。